[Pachi] Unsignedness

Petr Baudis pasky at ucw.cz
Mon Jul 25 18:26:50 CEST 2011


  Hi!

  For anyone interested, here is a patch I made two nights ago as part
of my most recent optimization efforts. However, it is buggy (reducing
play performance by maybe 20 Elo) so I'm not pushing it out, since I'm
too tired to find bugs in it and the performance improvement I have
hoped for is really underwhelming.

commit 4b15c55f516fc68bffe5c2760999fd2c53a15e9c
Author: Petr Baudis <pasky at ucw.cz>
Date:   Sun Jul 24 13:40:02 2011 +0200

    Convert many types to unsigned, most importantly coord_t
    
    The improvement is two-fold. First, the code is more efficient since
    keeping in sync Intel and C signedness semantics on overflows requires
    few etra instructions in many places, and some of the coord_t paths
    are very hot. Second, the semantics is more clear, and this has already
    helped me find some minor bugs.
    
    This is not completely thorough. There are probably some instances
    left where int should be unsigned int.

diff --git a/board.c b/board.c
index 895e6d4..48cab5d 100644
--- a/board.c
+++ b/board.c
@@ -142,7 +142,7 @@ board_done(struct board *board)
 }
 
 void
-board_resize(struct board *board, int size)
+board_resize(struct board *board, unsigned int size)
 {
 #ifdef BOARD_SIZE
 	assert(board_size(board) == size + 2);
@@ -152,7 +152,7 @@ board_resize(struct board *board, int size)
 	board->size2 = board_size(board) * board_size(board);
 
 	board->bits2 = 1;
-	while ((1 << board->bits2) < board->size2) board->bits2++;
+	while ((1U << board->bits2) < board->size2) board->bits2++;
 
 	if (board->b)
 		free(board->b);
@@ -164,7 +164,7 @@ board_resize(struct board *board, int size)
 static void
 board_init_data(struct board *board)
 {
-	int size = board_size(board);
+	unsigned int size = board_size(board);
 
 	board_setup(board);
 	board_resize(board, size - 2 /* S_OFFBOARD margin */);
@@ -205,8 +205,8 @@ board_init_data(struct board *board)
 	} foreach_point_end;
 
 	/* Draw the offboard margin */
-	int top_row = board_size2(board) - board_size(board);
-	int i;
+	unsigned int top_row = board_size2(board) - board_size(board);
+	unsigned int i;
 	for (i = 0; i < board_size(board); i++)
 		board->b[i] = board->b[top_row + i] = S_OFFBOARD;
 	for (i = 0; i <= top_row; i += board_size(board))
@@ -266,7 +266,7 @@ board_init_data(struct board *board)
 void
 board_clear(struct board *board)
 {
-	int size = board_size(board);
+	unsigned int size = board_size(board);
 	floating_t komi = board->komi;
 	char *fbookfile = board->fbookfile;
 
@@ -290,19 +290,19 @@ board_clear(struct board *board)
 }
 
 static char *
-board_print_top(struct board *board, char *s, char *end, int c)
+board_print_top(struct board *board, char *s, char *end, unsigned int c)
 {
-	for (int i = 0; i < c; i++) {
+	for (unsigned int i = 0; i < c; i++) {
 		char asdf[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
 		s += snprintf(s, end - s, "      ");
-		for (int x = 1; x < board_size(board) - 1; x++)
+		for (unsigned int x = 1; x < board_size(board) - 1; x++)
 			s += snprintf(s, end - s, "%c ", asdf[x - 1]);
 		s += snprintf(s, end -s, " ");
 	}
 	s += snprintf(s, end - s, "\n");
-	for (int i = 0; i < c; i++) {
+	for (unsigned int i = 0; i < c; i++) {
 		s += snprintf(s, end - s, "    +-");
-		for (int x = 1; x < board_size(board) - 1; x++)
+		for (unsigned int x = 1; x < board_size(board) - 1; x++)
 			s += snprintf(s, end - s, "--");
 		s += snprintf(s, end - s, "+");
 	}
@@ -311,11 +311,11 @@ board_print_top(struct board *board, char *s, char *end, int c)
 }
 
 static char *
-board_print_bottom(struct board *board, char *s, char *end, int c)
+board_print_bottom(struct board *board, char *s, char *end, unsigned int c)
 {
-	for (int i = 0; i < c; i++) {
+	for (unsigned int i = 0; i < c; i++) {
 		s += snprintf(s, end - s, "    +-");
-		for (int x = 1; x < board_size(board) - 1; x++)
+		for (unsigned int x = 1; x < board_size(board) - 1; x++)
 			s += snprintf(s, end - s, "--");
 		s += snprintf(s, end - s, "+");
 	}
@@ -324,11 +324,12 @@ board_print_bottom(struct board *board, char *s, char *end, int c)
 }
 
 static char *
-board_print_row(struct board *board, int y, char *s, char *end, board_cprint cprint)
+board_print_row(struct board *board, unsigned int y, char *s, char *end, board_cprint cprint)
 {
 	s += snprintf(s, end - s, " %2d | ", y);
-	for (int x = 1; x < board_size(board) - 1; x++) {
-		if (coord_x(board->last_move.coord, board) == x && coord_y(board->last_move.coord, board) == y)
+	for (unsigned int x = 1; x < board_size(board) - 1; x++) {
+		if (!is_pass(board->last_move.coord)
+		    && coord_x(board->last_move.coord, board) == x && coord_y(board->last_move.coord, board) == y)
 			s += snprintf(s, end - s, "%c)", stone2char(board_atxy(board, x, y)));
 		else
 			s += snprintf(s, end - s, "%c ", stone2char(board_atxy(board, x, y)));
@@ -336,7 +337,7 @@ board_print_row(struct board *board, int y, char *s, char *end, board_cprint cpr
 	s += snprintf(s, end - s, "|");
 	if (cprint) {
 		s += snprintf(s, end - s, " %2d | ", y);
-		for (int x = 1; x < board_size(board) - 1; x++) {
+		for (unsigned int x = 1; x < board_size(board) - 1; x++) {
 			s = cprint(board, coord_xy(board, x, y), s, end);
 		}
 		s += snprintf(s, end - s, "|");
@@ -355,7 +356,7 @@ board_print_custom(struct board *board, FILE *f, board_cprint cprint)
 		board->moves, board->komi, board->handicap,
 		board->captures[S_BLACK], board->captures[S_WHITE]);
 	s = board_print_top(board, s, end, 1 + !!cprint);
-	for (int y = board_size(board) - 2; y >= 1; y--)
+	for (unsigned int y = board_size(board) - 2; y >= 1; y--)
 		s = board_print_row(board, y, s, end, cprint);
 	board_print_bottom(board, s, end, 1 + !!cprint);
 	fprintf(f, "%s\n", buf);
@@ -414,7 +415,7 @@ static void
 board_traits_recompute(struct board *board)
 {
 #ifdef BOARD_TRAITS
-	for (int i = 0; i < board->tqlen; i++) {
+	for (unsigned int i = 0; i < board->tqlen; i++) {
 		coord_t coord = board->tq[i];
 		trait_at(board, coord, S_BLACK).dirty = false;
 		if (board_at(board, coord) != S_NONE)
@@ -512,8 +513,8 @@ board_symmetry_update(struct board *b, struct board_symmetry *symmetry, coord_t
 		return;
 	}
 
-	int x = coord_x(c, b), y = coord_y(c, b), t = board_size(b) / 2;
-	int dx = board_size(b) - 1 - x; /* for SYM_DOWN */
+	unsigned int x = coord_x(c, b), y = coord_y(c, b), t = board_size(b) / 2;
+	unsigned int dx = board_size(b) - 1 - x; /* for SYM_DOWN */
 	if (DEBUGL(6)) {
 		fprintf(stderr, "SYMMETRY [%d,%d,%d,%d|%d=%d] update for %d,%d\n",
 			symmetry->x1, symmetry->y1, symmetry->x2, symmetry->y2,
@@ -586,7 +587,7 @@ break_symmetry:
 
 
 void
-board_handicap_stone(struct board *board, int x, int y, FILE *f)
+board_handicap_stone(struct board *board, unsigned int x, unsigned int y, FILE *f)
 {
 	struct move m;
 	m.color = S_BLACK; m.coord = coord_xy(board, x, y);
@@ -604,13 +605,13 @@ board_handicap_stone(struct board *board, int x, int y, FILE *f)
 }
 
 void
-board_handicap(struct board *board, int stones, FILE *f)
+board_handicap(struct board *board, unsigned int stones, FILE *f)
 {
-	int margin = 3 + (board_size(board) >= 13);
-	int min = margin;
-	int mid = board_size(board) / 2;
-	int max = board_size(board) - 1 - margin;
-	const int places[][2] = {
+	unsigned int margin = 3 + (board_size(board) >= 13);
+	unsigned int min = margin;
+	unsigned int mid = board_size(board) / 2;
+	unsigned int max = board_size(board) - 1 - margin;
+	const unsigned int places[][2] = {
 		{ min, min }, { max, max }, { min, max }, { max, min },
 		{ min, mid }, { max, mid },
 		{ mid, min }, { mid, max },
@@ -624,7 +625,7 @@ board_handicap(struct board *board, int stones, FILE *f)
 		stones--;
 	}
 
-	int i;
+	unsigned int i;
 	for (i = 0; i < stones; i++)
 		board_handicap_stone(board, places[i][0], places[i][1], f);
 }
@@ -636,7 +637,7 @@ check_libs_consistency(struct board *board, group_t g)
 #ifdef DEBUG
 	if (!g) return;
 	struct group *gi = &board_group_info(board, g);
-	for (int i = 0; i < GROUP_KEEP_LIBS; i++)
+	for (unsigned int i = 0; i < GROUP_KEEP_LIBS; i++)
 		if (gi->lib[i] && board_at(board, gi->lib[i]) != S_NONE) {
 			fprintf(stderr, "BOGUS LIBERTY %s of group %d[%s]\n", coord2sstr(gi->lib[i], board), g, coord2sstr(group_base(g), board));
 			assert(0);
@@ -676,7 +677,7 @@ board_capturable_add(struct board *board, group_t group, coord_t lib, bool onest
 #endif
 
 #ifdef BOARD_PAT3
-	int fn__i = 0;
+	unsigned int fn__i = 0;
 	foreach_neighbor(board, lib, {
 		board->pat3[lib] |= (group_at(board, c) == group) << (16 + 3 - fn__i);
 		fn__i++;
@@ -708,7 +709,7 @@ board_capturable_rm(struct board *board, group_t group, coord_t lib, bool onesto
 #endif
 
 #ifdef BOARD_PAT3
-	int fn__i = 0;
+	unsigned int fn__i = 0;
 	foreach_neighbor(board, lib, {
 		board->pat3[lib] &= ~((group_at(board, c) == group) << (16 + 3 - fn__i));
 		fn__i++;
@@ -717,7 +718,7 @@ board_capturable_rm(struct board *board, group_t group, coord_t lib, bool onesto
 
 #ifdef WANT_BOARD_C
 	/* Update the list of capturable groups. */
-	for (int i = 0; i < board->clen; i++) {
+	for (unsigned int i = 0; i < board->clen; i++) {
 		if (unlikely(board->c[i] == group)) {
 			board->c[i] = board->c[--board->clen];
 			return;
@@ -759,7 +760,7 @@ board_group_addlib(struct board *board, group_t group, coord_t coord)
 	struct group *gi = &board_group_info(board, group);
 	bool onestone = group_is_onestone(board, group);
 	if (gi->libs < GROUP_KEEP_LIBS) {
-		for (int i = 0; i < GROUP_KEEP_LIBS; i++) {
+		for (unsigned int i = 0; i < GROUP_KEEP_LIBS; i++) {
 #if 0
 			/* Seems extra branch just slows it down */
 			if (!gi->lib[i])
@@ -791,7 +792,7 @@ board_group_find_extra_libs(struct board *board, group_t group, struct group *gi
 #define watermark_get(c)	(watermark[c >> 3] & (1 << (c & 7)))
 #define watermark_set(c)	watermark[c >> 3] |= (1 << (c & 7))
 
-	for (int i = 0; i < GROUP_KEEP_LIBS - 1; i++)
+	for (unsigned int i = 0; i < GROUP_KEEP_LIBS - 1; i++)
 		watermark_set(gi->lib[i]);
 	watermark_set(avoid);
 
@@ -821,7 +822,7 @@ board_group_rmlib(struct board *board, group_t group, coord_t coord)
 
 	struct group *gi = &board_group_info(board, group);
 	bool onestone = group_is_onestone(board, group);
-	for (int i = 0; i < GROUP_KEEP_LIBS; i++) {
+	for (unsigned int i = 0; i < GROUP_KEEP_LIBS; i++) {
 #if 0
 		/* Seems extra branch just slows it down */
 		if (!gi->lib[i])
@@ -898,10 +899,10 @@ board_remove_stone(struct board *board, group_t group, coord_t c)
 	board->f[board->flen++] = c;
 }
 
-static int profiling_noinline
+static unsigned int profiling_noinline
 board_group_capture(struct board *board, group_t group)
 {
-	int stones = 0;
+	unsigned int stones = 0;
 
 	foreach_in_group(board, group) {
 		board->captures[stone_other(board_at(board, c))]++;
@@ -990,8 +991,8 @@ merge_groups(struct board *board, group_t group_to, group_t group_from)
 		fprintf(stderr,"---- (froml %d, tol %d)\n", gi_from->libs, gi_to->libs);
 
 	if (gi_to->libs < GROUP_KEEP_LIBS) {
-		for (int i = 0; i < gi_from->libs; i++) {
-			for (int j = 0; j < gi_to->libs; j++)
+		for (unsigned int i = 0; i < gi_from->libs; i++) {
+			for (unsigned int j = 0; j < gi_to->libs; j++)
 				if (gi_to->lib[j] == gi_from->lib[i])
 					goto next_from_lib;
 			if (gi_to->libs == 0) {
@@ -1042,7 +1043,7 @@ next_from_lib:;
 			 * therefore switching the atari flag off.
 			 * We need to set it again since group_to is also
 			 * capturable. */
-			int fn__i = 0;
+			unsigned int fn__i = 0;
 			foreach_neighbor(board, lib, {
 				board->pat3[lib] |= (group_at(board, c) == group_from) << (16 + 3 - fn__i);
 				fn__i++;
@@ -1128,7 +1129,7 @@ play_one_neighbor(struct board *board,
 		if (DEBUGL(8)) {
 			struct group *gi = &board_group_info(board, ngroup);
 			fprintf(stderr, "testing captured group %d[%s]: ", group_base(ngroup), coord2sstr(group_base(ngroup), board));
-			for (int i = 0; i < GROUP_KEEP_LIBS; i++)
+			for (unsigned int i = 0; i < GROUP_KEEP_LIBS; i++)
 				fprintf(stderr, "%s ", coord2sstr(gi->lib[i], board));
 			fprintf(stderr, "\n");
 		}
@@ -1141,7 +1142,7 @@ play_one_neighbor(struct board *board,
 /* We played on a place with at least one liberty. We will become a member of
  * some group for sure. */
 static group_t profiling_noinline
-board_play_outside(struct board *board, struct move *m, int f)
+board_play_outside(struct board *board, struct move *m, unsigned int f)
 {
 	coord_t coord = m->coord;
 	enum stone color = m->color;
@@ -1155,7 +1156,7 @@ board_play_outside(struct board *board, struct move *m, int f)
 #if defined(BOARD_TRAITS) && defined(DEBUG)
 	/* Sanity check that cap matches reality. */
 	{
-		int a = 0, b = 0;
+		unsigned int a = 0, b = 0;
 		foreach_neighbor(board, coord, {
 			group_t g = group_at(board, c);
 			a += g && (board_at(board, c) == other_color && board_group_info(board, g).libs == 1);
@@ -1192,7 +1193,7 @@ board_play_outside(struct board *board, struct move *m, int f)
 /* We played in an eye-like shape. Either we capture at least one of the eye
  * sides in the process of playing, or return -1. */
 static int profiling_noinline
-board_play_in_eye(struct board *board, struct move *m, int f)
+board_play_in_eye(struct board *board, struct move *m, unsigned int f)
 {
 	coord_t coord = m->coord;
 	enum stone color = m->color;
@@ -1209,7 +1210,7 @@ board_play_in_eye(struct board *board, struct move *m, int f)
 
 	struct move ko = { pass, S_NONE };
 
-	int captured_groups = 0;
+	unsigned int captured_groups = 0;
 
 	foreach_neighbor(board, coord, {
 		group_t g = group_at(board, c);
@@ -1289,7 +1290,7 @@ board_play_in_eye(struct board *board, struct move *m, int f)
 }
 
 static int __attribute__((flatten))
-board_play_f(struct board *board, struct move *m, int f)
+board_play_f(struct board *board, struct move *m, unsigned int f)
 {
 	if (DEBUGL(7)) {
 		fprintf(stderr, "board_play(%s): ---- Playing %d,%d\n", coord2sstr(m->coord, board), coord_x(m->coord, board), coord_y(m->coord, board));
@@ -1323,7 +1324,7 @@ board_play(struct board *board, struct move *m)
 		return 0;
 	}
 
-	int f;
+	unsigned int f;
 	for (f = 0; f < board->flen; f++)
 		if (board->f[f] == m->coord)
 			return board_play_f(board, m, f);
@@ -1349,7 +1350,7 @@ int board_undo(struct board *board)
 }
 
 static inline bool
-board_try_random_move(struct board *b, enum stone color, coord_t *coord, int f, ppr_permit permit, void *permit_data)
+board_try_random_move(struct board *b, enum stone color, coord_t *coord, unsigned int f, ppr_permit permit, void *permit_data)
 {
 	*coord = b->f[f];
 	struct move m = { *coord, color };
@@ -1373,7 +1374,7 @@ board_play_random(struct board *b, enum stone color, coord_t *coord, ppr_permit
 	if (unlikely(b->flen == 0))
 		goto pass;
 
-	int base = fast_random(b->flen), f;
+	unsigned int base = fast_random(b->flen), f;
 	for (f = base; f < b->flen; f++)
 		if (board_try_random_move(b, color, coord, f, permit, permit_data))
 			return;
@@ -1428,7 +1429,7 @@ board_get_one_point_eye(struct board *board, coord_t coord)
 floating_t
 board_fast_score(struct board *board)
 {
-	int scores[S_MAX];
+	unsigned int scores[S_MAX];
 	memset(scores, 0, sizeof(scores));
 
 	foreach_point(board) {
@@ -1447,7 +1448,7 @@ board_fast_score(struct board *board)
 /* One flood-fill iteration; returns true if next iteration
  * is required. */
 static bool
-board_tromp_taylor_iter(struct board *board, int *ownermap)
+board_tromp_taylor_iter(struct board *board, unsigned int *ownermap)
 {
 	bool needs_update = false;
 	foreach_free_point(board) {
@@ -1456,7 +1457,7 @@ board_tromp_taylor_iter(struct board *board, int *ownermap)
 		if (ownermap[c] == 3)
 			continue;
 		/* Count neighbors. */
-		int nei[4] = {0};
+		unsigned int nei[4] = {0};
 		foreach_neighbor(board, c, {
 			nei[ownermap[c]]++;
 		});
@@ -1475,7 +1476,7 @@ board_tromp_taylor_iter(struct board *board, int *ownermap)
 		/* If we have neighbors of one color, we are owned
 		 * by that color, too. */
 		if (!ownermap[c] && (nei[1] || nei[2])) {
-			int newowner = nei[1] ? 1 : 2;
+			unsigned int newowner = nei[1] ? 1 : 2;
 			ownermap[c] = newowner;
 			/* Speed up the propagation. */
 			foreach_neighbor(board, c, {
@@ -1501,9 +1502,9 @@ board_official_score(struct board *board, struct move_queue *q)
 	 * A player's score is the number of points of her color, plus the
 	 * number of empty points that reach only her color. */
 
-	int ownermap[board_size2(board)];
-	int s[4] = {0};
-	const int o[4] = {0, 1, 2, 0};
+	unsigned int ownermap[board_size2(board)];
+	unsigned int s[4] = {0};
+	const unsigned int o[4] = {0, 1, 2, 0};
 	foreach_point(board) {
 		ownermap[c] = o[board_at(board, c)];
 		s[board_at(board, c)]++;
@@ -1527,7 +1528,7 @@ board_official_score(struct board *board, struct move_queue *q)
 	while (board_tromp_taylor_iter(board, ownermap))
 		/* Flood-fill... */;
 
-	int scores[S_MAX];
+	unsigned int scores[S_MAX];
 	memset(scores, 0, sizeof(scores));
 
 	foreach_point(board) {
diff --git a/board.h b/board.h
index 27735d3..2760b95 100644
--- a/board.h
+++ b/board.h
@@ -42,10 +42,10 @@ struct fbook;
  * moves. We will tell them how can they do it. */
 struct board_symmetry {
 	/* Playground is in this rectangle. */
-	int x1, x2, y1, y2;
+	unsigned int x1, x2, y1, y2;
 	/* d ==  0: Full rectangle
 	 * d ==  1: Top triangle */
-	int d;
+	unsigned int d;
 	/* General symmetry type. */
 	/* Note that the above is redundant to this, but just provided
 	 * for easier usage. */
@@ -85,7 +85,7 @@ struct group {
 	/* libs is only LOWER BOUND for the number of real liberties!!!
 	 * It denotes only number of items in lib[], thus you can rely
 	 * on it to store real liberties only up to <= GROUP_REFILL_LIBS. */
-	int libs;
+	unsigned int libs;
 };
 
 struct neighbor_colors {
@@ -119,12 +119,12 @@ struct btraits {
  * you want to change it. */
 
 struct board {
-	int size; /* Including S_OFFBOARD margin - see below. */
-	int size2; /* size^2 */
-	int bits2; /* ceiling(log2(size2)) */
-	int captures[S_MAX];
+	unsigned int size; /* Including S_OFFBOARD margin - see below. */
+	unsigned int size2; /* size^2 */
+	unsigned int bits2; /* ceiling(log2(size2)) */
+	unsigned int captures[S_MAX];
 	floating_t komi;
-	int handicap;
+	unsigned int handicap;
 	/* The ruleset is currently almost never taken into account;
 	 * the board implementation is basically Chinese rules (handicap
 	 * stones compensation) w/ suicide (or you can look at it as
@@ -143,7 +143,7 @@ struct board {
 	/* Iterator offsets for foreach_neighbor*() */
 	int nei8[8], dnei[4];
 
-	int moves;
+	unsigned int moves;
 	struct move last_move;
 	struct move last_move2; /* second-to-last move */
 	struct move last_move3; /* just before last_move2, only set if last_move is pass */
@@ -188,16 +188,16 @@ struct board {
 	/* Positions of free positions - queue (not map) */
 	/* Note that free position here is any valid move; including single-point eyes!
 	 * However, pass is not included. */
-	coord_t *f; int flen;
+	coord_t *f; unsigned int flen;
 
 #ifdef WANT_BOARD_C
 	/* Queue of capturable groups */
-	group_t *c; int clen;
+	group_t *c; unsigned int clen;
 #endif
 
 #ifdef BOARD_TRAITS
 	/* Queue of positions that need their traits updated */
-	coord_t *tq; int tqlen;
+	coord_t *tq; unsigned int tqlen;
 #endif
 
 	/* Symmetry information */
@@ -205,7 +205,7 @@ struct board {
 
 	/* Last ko played on the board. */
 	struct move last_ko;
-	int last_ko_age;
+	unsigned int last_ko_age;
 
 	/* Basic ko check */
 	struct move ko;
@@ -296,7 +296,7 @@ struct board *board_copy(struct board *board2, struct board *board1);
 void board_done_noalloc(struct board *board);
 void board_done(struct board *board);
 /* size here is without the S_OFFBOARD margin. */
-void board_resize(struct board *board, int size);
+void board_resize(struct board *board, unsigned int size);
 void board_clear(struct board *board);
 
 struct FILE;
@@ -305,7 +305,7 @@ void board_print(struct board *board, FILE *f);
 void board_print_custom(struct board *board, FILE *f, board_cprint cprint);
 
 /* Place given handicap on the board; coordinates are printed to f. */
-void board_handicap(struct board *board, int stones, FILE *f);
+void board_handicap(struct board *board, unsigned int stones, FILE *f);
 
 /* Returns group id, 0 on allowed suicide, pass or resign, -1 on error */
 int board_play(struct board *board, struct move *m);
@@ -331,7 +331,7 @@ static group_t board_get_atari_neighbor(struct board *b, coord_t coord, enum sto
 static bool board_safe_to_play(struct board *b, coord_t coord, enum stone color);
 
 /* Determine number of stones in a group, up to @max stones. */
-static int group_stone_count(struct board *b, group_t group, int max);
+static unsigned int group_stone_count(struct board *b, group_t group, unsigned int max);
 
 /* Adjust symmetry information as if given coordinate has been played. */
 void board_symmetry_update(struct board *b, struct board_symmetry *symmetry, coord_t c);
@@ -375,8 +375,8 @@ floating_t board_official_score(struct board *board, struct move_queue *mq);
 
 #define foreach_free_point(board_) \
 	do { \
-		int fmax__ = (board_)->flen; \
-		for (int f__ = 0; f__ < fmax__; f__++) { \
+		unsigned int fmax__ = (board_)->flen; \
+		for (unsigned int f__ = 0; f__ < fmax__; f__++) { \
 			coord_t c = (board_)->f[f__];
 #define foreach_free_point_end \
 		} \
@@ -408,7 +408,7 @@ floating_t board_official_score(struct board *board, struct move_queue *mq);
 
 #define foreach_8neighbor(board_, coord_) \
 	do { \
-		int fn__i; \
+		unsigned int fn__i; \
 		coord_t c = (coord_); \
 		for (fn__i = 0; fn__i < 8; fn__i++) { \
 			c += (board_)->nei8[fn__i];
@@ -418,7 +418,7 @@ floating_t board_official_score(struct board *board, struct move_queue *mq);
 
 #define foreach_diag_neighbor(board_, coord_) \
 	do { \
-		int fn__i; \
+		unsigned int fn__i; \
 		coord_t c = (coord_); \
 		for (fn__i = 0; fn__i < 4; fn__i++) { \
 			c += (board_)->dnei[fn__i];
@@ -448,7 +448,7 @@ board_is_valid_play(struct board *board, enum stone color, coord_t coord)
 	/* XXX: Disallows suicide. */
 	return trait_at(board, coord, color).cap > 0;
 #else
-	int groups_in_atari = 0;
+	unsigned int groups_in_atari = 0;
 	foreach_neighbor(board, coord, {
 		group_t g = group_at(board, c);
 		groups_in_atari += (board_group_info(board, g).libs == 1);
@@ -488,7 +488,7 @@ static inline bool
 board_safe_to_play(struct board *b, coord_t coord, enum stone color)
 {
 	/* number of free neighbors */
-	int libs = immediate_liberty_count(b, coord);
+	unsigned int libs = immediate_liberty_count(b, coord);
 	if (libs > 1)
 		return true;
 
@@ -497,7 +497,7 @@ board_safe_to_play(struct board *b, coord_t coord, enum stone color)
 	if (trait_at(b, coord, color).cap > 0)
 		return true; // XXX: We don't account for snapback.
 	/* number of non-capturable friendly groups */
-	int noncap_ours = neighbor_count_at(b, coord, color) - trait_at(b, coord, stone_other(color)).cap;
+	unsigned int noncap_ours = neighbor_count_at(b, coord, color) - trait_at(b, coord, stone_other(color)).cap;
 	if (noncap_ours < 1)
 		return false;
 /*#else see below */
@@ -529,10 +529,10 @@ board_safe_to_play(struct board *b, coord_t coord, enum stone color)
 	return false;
 }
 
-static inline int
-group_stone_count(struct board *b, group_t group, int max)
+static inline unsigned int
+group_stone_count(struct board *b, group_t group, unsigned int max)
 {
-	int n = 0;
+	unsigned int n = 0;
 	foreach_in_group(b, group) {
 		n++;
 		if (n >= max) return max;
@@ -548,7 +548,7 @@ board_coord_in_symmetry(struct board *b, coord_t c)
 	if (coord_x(c, b) < b->symmetry.x1 || coord_x(c, b) > b->symmetry.x2)
 		return false;
 	if (b->symmetry.d) {
-		int x = coord_x(c, b);
+		unsigned int x = coord_x(c, b);
 		if (b->symmetry.type == SYM_DIAG_DOWN)
 			x = board_size(b) - 1 - x;
 		if (x > coord_y(c, b))
diff --git a/debug.h b/debug.h
index 13916ee..7ba4125 100644
--- a/debug.h
+++ b/debug.h
@@ -11,7 +11,7 @@
 #define DEBUG_MODE (false)
 #endif
 
-extern int debug_level;
+extern unsigned int debug_level;
 extern bool debug_boardprint;
 
 #define DEBUGL(n) DEBUGL_(debug_level, n)
diff --git a/distributed/distributed.c b/distributed/distributed.c
index bcb528a..96b46d1 100644
--- a/distributed/distributed.c
+++ b/distributed/distributed.c
@@ -218,8 +218,8 @@ large_stats_add_result(struct large_stats *s, floating_t result, long playouts)
  * Keep this code in sync with uct/slave.c:report_stats().
  * slave_lock is held on entry and on return. */
 static coord_t
-select_best_move(struct board *b, struct large_stats *stats, int *played,
-		 int *total_playouts, int *total_threads, bool *keep_looking)
+select_best_move(struct board *b, struct large_stats *stats, unsigned int *played,
+		 unsigned int *total_playouts, unsigned int *total_threads, bool *keep_looking)
 {
 	assert(reply_count > 0);
 
@@ -273,7 +273,7 @@ select_best_move(struct board *b, struct large_stats *stats, int *played,
  * slave_lock is held on entry and on return but we don't
  * rely on the lock here. */
 static void
-genmoves_args(char *args, enum stone color, int played,
+genmoves_args(char *args, enum stone color, unsigned int played,
 	      struct time_info *ti, bool binary_args)
 {
 	char *end = args + CMDS_SIZE;
@@ -306,7 +306,7 @@ distributed_genmove(struct engine *e, struct board *b, struct time_info *ti,
 	char args[CMDS_SIZE];
 
 	coord_t best;
-	int played, playouts, threads;
+	unsigned int played, playouts, threads;
 
 	if (ti->period == TT_NULL) *ti = default_ti;
 	struct time_stop stop;
@@ -326,7 +326,7 @@ distributed_genmove(struct engine *e, struct board *b, struct time_info *ti,
 	new_cmd(b, cmd, args);
 
 	/* Loop until most slaves want to quit or time elapsed. */
-	int iterations;
+	unsigned int iterations;
 	for (iterations = 1; ; iterations++) {
 		double start = now;
 		/* Wait for just one slave to get stats as fresh as possible,
@@ -348,10 +348,10 @@ distributed_genmove(struct engine *e, struct board *b, struct time_info *ti,
 		if (DEBUGVV(2)) {
 			char *coord = coord2sstr(best, b);
 			snprintf(buf, sizeof(buf),
-				 "temp winner is %s %s with score %1.4f (%d/%d games)"
-				 " %d slaves %d threads\n",
+				 "temp winner is %s %s with score %1.4f (%ld/%u games)"
+				 " %d slaves %u threads\n",
 				 stone2str(color), coord, get_value(stats[best].value, color),
-				 (int)stats[best].playouts, playouts, reply_count, threads);
+				 stats[best].playouts, playouts, reply_count, threads);
 			logline(NULL, "* ", buf);
 		}
 		/* Send the command with the same gtp id, to avoid discarding
@@ -367,7 +367,7 @@ distributed_genmove(struct engine *e, struct board *b, struct time_info *ti,
 	dist->my_last_move.color = color;
 	dist->my_last_move.coord = best;
 	dist->my_last_stats.value = stats[best].value;
-	dist->my_last_stats.playouts = (int)stats[best].playouts;
+	dist->my_last_stats.playouts = stats[best].playouts;
 
 	/* Tell the slaves to commit to the selected move, overwriting
 	 * the last "pachi-genmoves" in the command history. */
@@ -381,11 +381,11 @@ distributed_genmove(struct engine *e, struct board *b, struct time_info *ti,
 	if (DEBUGL(1)) {
 		double time = now - first + 0.000001; /* avoid divide by zero */
 		snprintf(buf, sizeof(buf),
-			 "GLOBAL WINNER is %s %s with score %1.4f (%d/%d games)\n"
-			 "genmove %d games in %0.2fs %d slaves %d threads (%d games/s,"
+			 "GLOBAL WINNER is %s %s with score %1.4f (%ld/%u games)\n"
+			 "genmove %u games in %0.2fs %d slaves %u threads (%d games/s,"
 			 " %d games/s/slave, %d games/s/thread, %.3f ms/iter)\n",
 			 stone2str(color), coord, get_value(stats[best].value, color),
-			 (int)stats[best].playouts, playouts, played, time, replies, threads,
+			 stats[best].playouts, playouts, played, time, replies, threads,
 			 (int)(played/time), (int)(played/time/replies),
 			 (int)(played/time/threads), 1000*time/iterations);
 		logline(NULL, "* ", buf);
diff --git a/distributed/distributed.h b/distributed/distributed.h
index b7dbcf8..9b630bb 100644
--- a/distributed/distributed.h
+++ b/distributed/distributed.h
@@ -94,7 +94,7 @@ struct incr_stats {
 
 #define force_reply(id)    ((id) + DIST_GAMELEN)
 #define prevent_reply(id)  ((id) % DIST_GAMELEN)
-#define move_number(id)    ((id) % DIST_GAMELEN)
+#define move_number(id)    ((unsigned int) (id) % DIST_GAMELEN)
 #define reply_disabled(id) ((id) < DIST_GAMELEN)
 
 char *path2sstr(path_t path, struct board *b);
diff --git a/distributed/protocol.c b/distributed/protocol.c
index cd360d9..8d4a7e8 100644
--- a/distributed/protocol.c
+++ b/distributed/protocol.c
@@ -249,7 +249,7 @@ next_command(int cmd_id)
 	if (cmd_id == -1) return gtp_cmds;
 
 	int last_id = atoi(gtp_cmd);
-	int reply_move = move_number(cmd_id);
+	unsigned int reply_move = move_number(cmd_id);
 	if (reply_move > move_number(last_id)) return gtp_cmds;
 
 	int slot;
diff --git a/fbook.c b/fbook.c
index 5627854..2720492 100644
--- a/fbook.c
+++ b/fbook.c
@@ -12,7 +12,7 @@
 
 
 static coord_t
-coord_transform(struct board *b, coord_t coord, int i)
+coord_transform(struct board *b, coord_t coord, unsigned int i)
 {
 #define HASH_VMIRROR     1
 #define HASH_HMIRROR     2
@@ -79,7 +79,7 @@ fbook_init(char *filename, struct board *b)
 	fbook->handicap = b->handicap;
 	/* We do not set handicap=1 in case of too low komi on purpose;
 	 * we want to go with the no-handicap fbook for now. */
-	for (int i = 0; i < 1<<fbook_hash_bits; i++)
+	for (unsigned int i = 0; i < 1U<<fbook_hash_bits; i++)
 		fbook->moves[i] = pass;
 
 	if (DEBUGL(1))
@@ -88,7 +88,7 @@ fbook_init(char *filename, struct board *b)
 	/* Scratch board where we lay out the sequence;
 	 * one for each transposition. */
 	struct board *bs[8];
-	for (int i = 0; i < 8; i++) {
+	for (unsigned int i = 0; i < 8; i++) {
 		bs[i] = board_init(NULL);
 		board_resize(bs[i], fbook->bsize - 2);
 	}
@@ -104,10 +104,10 @@ fbook_init(char *filename, struct board *b)
 		 * We descend up to |, then add the new node
 		 * with value minimax(1000), forcing UCT to
 		 * always pick that node immediately. */
-		int bsize = strtol(line, &line, 10);
+		unsigned int bsize = strtol(line, &line, 10);
 		if (bsize != fbook->bsize - 2)
 			continue;
-		int handi = 0;
+		unsigned int handi = 0;
 		if (*line == '/') {
 			line++;
 			handi = strtol(line, &line, 10);
@@ -116,7 +116,7 @@ fbook_init(char *filename, struct board *b)
 			continue;
 		while (isspace(*line)) line++;
 
-		for (int i = 0; i < 8; i++) {
+		for (unsigned int i = 0; i < 8; i++) {
 			board_clear(bs[i]);
 			bs[i]->last_move.color = S_WHITE;
 		}
@@ -124,7 +124,7 @@ fbook_init(char *filename, struct board *b)
 		while (*line != '|') {
 			coord_t *c = str2coord(line, fbook->bsize);
 
-			for (int i = 0; i < 8; i++) {
+			for (unsigned int i = 0; i < 8; i++) {
 				coord_t coord = coord_transform(b, *c, i);
 				struct move m = { .coord = coord, .color = stone_other(bs[i]->last_move.color) };
 				int ret = board_play(bs[i], &m);
@@ -148,12 +148,12 @@ fbook_init(char *filename, struct board *b)
 		}
 
 		coord_t *c = str2coord(line, fbook->bsize);
-		for (int i = 0; i < 8; i++) {
+		for (unsigned int i = 0; i < 8; i++) {
 			coord_t coord = coord_transform(b, *c, i);
 #if 0
 			char conflict = is_pass(fbook->moves[bs[i]->hash & fbook_hash_mask]) ? '+' : 'C';
 			if (conflict == 'C')
-				for (int j = 0; j < i; j++)
+				for (unsigned int j = 0; j < i; j++)
 					if (bs[i]->hash == bs[j]->hash)
 						conflict = '+';
 			if (conflict == 'C') {
@@ -176,7 +176,7 @@ fbook_init(char *filename, struct board *b)
 		coord_done(c);
 	}
 
-	for (int i = 0; i < 8; i++) {
+	for (unsigned int i = 0; i < 8; i++) {
 		board_done(bs[i]);
 	}
 
diff --git a/fbook.h b/fbook.h
index 9e3db4d..202932f 100644
--- a/fbook.h
+++ b/fbook.h
@@ -9,10 +9,10 @@ struct board;
  * played unconditionally if found, or possibly "fuseki book"). */
 
 struct fbook {
-	int bsize;
-	int handicap;
+	unsigned int bsize;
+	unsigned int handicap;
 
-	int movecnt;
+	unsigned int movecnt;
 
 #define fbook_hash_bits 20 // 12M w/ 32-bit coord_t
 #define fbook_hash_mask ((1 << fbook_hash_bits) - 1)
diff --git a/montecarlo/internal.h b/montecarlo/internal.h
index cf77977..7250152 100644
--- a/montecarlo/internal.h
+++ b/montecarlo/internal.h
@@ -11,10 +11,10 @@ struct playout_policy;
 
 /* Internal engine state. */
 struct montecarlo {
-	int debug_level;
-	int gamelen;
+	unsigned int debug_level;
+	unsigned int gamelen;
 	floating_t resign_ratio;
-	int loss_threshold;
+	unsigned int loss_threshold;
 	struct playout_policy *playout;
 };
 
diff --git a/montecarlo/montecarlo.c b/montecarlo/montecarlo.c
index 7783613..797cf50 100644
--- a/montecarlo/montecarlo.c
+++ b/montecarlo/montecarlo.c
@@ -47,7 +47,7 @@ void
 board_stats_print(struct board *board, struct move_stat *moves, FILE *f)
 {
 	fprintf(f, "\n       ");
-	int x, y;
+	unsigned int x, y;
 	char asdf[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
 	for (x = 1; x < board_size(board) - 1; x++)
 		fprintf(f, "%c    ", asdf[x - 1]);
@@ -100,8 +100,8 @@ montecarlo_genmove(struct engine *e, struct board *b, struct time_info *ti, enum
 	struct move_stat moves[board_size2(b)];
 	memset(moves, 0, sizeof(moves));
 
-	int losses = 0;
-	int i, superko = 0, good_games = 0;
+	unsigned int losses = 0;
+	unsigned int i, superko = 0, good_games = 0;
 	for (i = 0; i < stop.desired.playouts; i++) {
 		assert(!b->superko_violation);
 
diff --git a/move.h b/move.h
index a2b6dc6..85e1ade 100644
--- a/move.h
+++ b/move.h
@@ -8,7 +8,7 @@
 #include "util.h"
 #include "stone.h"
 
-typedef int coord_t;
+typedef unsigned int coord_t;
 
 #define coord_xy(board, x, y) ((x) + (y) * board_size(board))
 #define coord_x(c, b) ((b)->coord[c][0])
@@ -17,8 +17,8 @@ typedef int coord_t;
 #define coord_dx(c1, c2, b) (coord_x(c1, b) - coord_x(c2, b))
 #define coord_dy(c1, c2, b) (coord_y(c1, b) - coord_y(c2, b))
 
-static coord_t pass = -1;
-static coord_t resign = -2;
+static coord_t pass = (unsigned int) -1;
+static coord_t resign = (unsigned int) -2;
 #define is_pass(c) (c == pass)
 #define is_resign(c) (c == resign)
 
@@ -29,7 +29,7 @@ static coord_t resign = -2;
  * 0 1
  * 2 3 (vertically reversed from board_print output, of course!)
  * Middle coordinates are included in lower-valued quadrants. */
-#define coord_quadrant(c, b) ((coord_x(c, b) > board_size(b) / 2) + 2 * (coord_y(c, b) > board_size(b) / 2))
+#define coord_quadrant(c, b) ((unsigned int) ((coord_x(c, b) > board_size(b) / 2) + 2 * (coord_y(c, b) > board_size(b) / 2)))
 
 /* dyn allocated */
 static coord_t *coord_init(int x, int y, int size);
diff --git a/ownermap.c b/ownermap.c
index 702f47b..1943215 100644
--- a/ownermap.c
+++ b/ownermap.c
@@ -22,11 +22,11 @@ board_ownermap_fill(struct board_ownermap *ownermap, struct board *b)
 }
 
 void
-board_ownermap_merge(int bsize2, struct board_ownermap *dst, struct board_ownermap *src)
+board_ownermap_merge(unsigned int bsize2, struct board_ownermap *dst, struct board_ownermap *src)
 {
 	dst->playouts += src->playouts;
-	for (int i = 0; i < bsize2; i++)
-		for (int j = 0; j < S_MAX; j++)
+	for (unsigned int i = 0; i < bsize2; i++)
+		for (unsigned int j = 0; j < S_MAX; j++)
 			dst->map[i][j] += src->map[i][j];
 }
 
@@ -34,10 +34,10 @@ enum point_judgement
 board_ownermap_judge_point(struct board_ownermap *ownermap, coord_t c, floating_t thres)
 {
 	assert(ownermap->map);
-	int n = ownermap->map[c][S_NONE];
-	int b = ownermap->map[c][S_BLACK];
-	int w = ownermap->map[c][S_WHITE];
-	int total = ownermap->playouts;
+	unsigned int n = ownermap->map[c][S_NONE];
+	unsigned int b = ownermap->map[c][S_BLACK];
+	unsigned int w = ownermap->map[c][S_WHITE];
+	unsigned int total = ownermap->playouts;
 	if (n >= total * thres)
 		return PJ_DAME;
 	else if (n + b >= total * thres)
diff --git a/ownermap.h b/ownermap.h
index b12d040..a6dea78 100644
--- a/ownermap.h
+++ b/ownermap.h
@@ -18,7 +18,7 @@ struct board_ownermap {
 };
 
 void board_ownermap_fill(struct board_ownermap *ownermap, struct board *b);
-void board_ownermap_merge(int bsize2, struct board_ownermap *dst, struct board_ownermap *src);
+void board_ownermap_merge(unsigned int bsize2, struct board_ownermap *dst, struct board_ownermap *src);
 
 
 /* Estimate coord ownership based on ownermap stats. */
diff --git a/pachi.c b/pachi.c
index 4188d58..74486a8 100644
--- a/pachi.c
+++ b/pachi.c
@@ -23,7 +23,7 @@
 #include "version.h"
 #include "network.h"
 
-int debug_level = 3;
+unsigned int debug_level = 3;
 bool debug_boardprint = true;
 long verbose_logs = 0;
 int seed;
diff --git a/playout.h b/playout.h
index 2182d4e..b3d13d3 100644
--- a/playout.h
+++ b/playout.h
@@ -30,7 +30,7 @@ typedef coord_t (*playoutp_choose)(struct playout_policy *playout_policy, struct
  * move (usually a proportion of @games); can leave some untouched
  * if policy has no opinion. The number must have proper parity;
  * just use uct/prior.h:add_prior_value(). */
-typedef void (*playoutp_assess)(struct playout_policy *playout_policy, struct prior_map *map, int games);
+typedef void (*playoutp_assess)(struct playout_policy *playout_policy, struct prior_map *map, unsigned int games);
 
 /* Allow play of randomly selected move. */
 typedef bool (*playoutp_permit)(struct playout_policy *playout_policy, struct board *b, struct move *m);
@@ -39,7 +39,7 @@ typedef bool (*playoutp_permit)(struct playout_policy *playout_policy, struct bo
 typedef void (*playoutp_done)(struct playout_policy *playout_policy);
 
 struct playout_policy {
-	int debug_level;
+	unsigned int debug_level;
 	/* We call setboard when we start new playout.
 	 * We call choose when we ask policy about next move.
 	 * We call assess when we ask policy about how good given move is.
@@ -91,7 +91,7 @@ struct playout_amafmap {
 	 * and ignore AMAF value after these. */
 #define amaf_nakade(item_) (item_ >> 8)
 #define amaf_op(item_, op_) do { \
-		int mi_ = item_; \
+		unsigned int mi_ = item_; \
 		item_ = (mi_ & 0xf) | ((amaf_nakade(mi_) op_ 1) << 8); \
 } while (0)
 
diff --git a/playout/moggy.c b/playout/moggy.c
index 797b855..827d41c 100644
--- a/playout/moggy.c
+++ b/playout/moggy.c
@@ -57,7 +57,7 @@ struct moggy_policy {
 	unsigned int lcapturerate, atarirate, nlibrate, ladderrate, capturerate, patternrate, korate, josekirate, nakaderate;
 	unsigned int selfatarirate, alwaysccaprate;
 	unsigned int fillboardtries;
-	int koage;
+	unsigned int koage;
 	/* Whether to look for patterns around second-to-last move. */
 	bool pattern2;
 	/* Whether, when self-atari attempt is detected, to play the other
@@ -70,15 +70,15 @@ struct moggy_policy {
 	bool capcheckall;
 	/* Prior stone weighting. Weight of each stone between
 	 * cap_stone_min and cap_stone_max is (assess*100)/cap_stone_denom. */
-	int cap_stone_min, cap_stone_max;
-	int cap_stone_denom;
+	unsigned int cap_stone_min, cap_stone_max;
+	unsigned int cap_stone_denom;
 
 	/* 2lib settings: */
 	bool atari_def_no_hopeless;
 	bool atari_miaisafe;
 
 	/* nlib settings: */
-	int nlib_count;
+	unsigned int nlib_count;
 
 	struct joseki_dict *jdict;
 	struct pattern3s patterns;
@@ -204,7 +204,9 @@ apply_pattern(struct playout_policy *p, struct board *b, struct move *m, struct
 		apply_pattern_here(p, b, c, stone_other(m->color), q);
 	} foreach_8neighbor_end;
 
-	if (mm) { /* Second move for pattern searching */
+	if (mm && !is_pass(mm->coord)
+	    && !(board_at(b, mm->coord) == S_NONE || board_at(b, mm->coord) == S_OFFBOARD)) {
+		/* Second move for pattern searching */
 		foreach_8neighbor(b, mm->coord) {
 			if (coord_is_8adjecent(m->coord, c, b))
 				continue;
@@ -224,7 +226,7 @@ joseki_check(struct playout_policy *p, struct board *b, enum stone to_play, stru
 	if (!pp->jdict)
 		return;
 
-	for (int i = 0; i < 4; i++) {
+	for (unsigned int i = 0; i < 4; i++) {
 		hash_t h = b->qhash[i] & joseki_hash_mask;
 		coord_t *cc = pp->jdict->patterns[h].moves[to_play];
 		if (!cc) continue;
@@ -247,15 +249,15 @@ global_atari_check(struct playout_policy *p, struct board *b, enum stone to_play
 
 	struct moggy_policy *pp = p->data;
 	if (pp->capcheckall) {
-		for (int g = 0; g < b->clen; g++)
+		for (unsigned int g = 0; g < b->clen; g++)
 			group_atari_check(pp->alwaysccaprate, b, group_at(b, group_base(b->c[g])), to_play, q, NULL, 1<<MQ_GATARI);
 		if (PLDEBUGL(5))
 			mq_print(q, b, "Global atari");
 		return;
 	}
 
-	int g_base = fast_random(b->clen);
-	for (int g = g_base; g < b->clen; g++) {
+	unsigned int g_base = fast_random(b->clen);
+	for (unsigned int g = g_base; g < b->clen; g++) {
 		group_atari_check(pp->alwaysccaprate, b, group_at(b, group_base(b->c[g])), to_play, q, NULL, 1<<MQ_GATARI);
 		if (q->moves > 0) {
 			/* XXX: Try carrying on. */
@@ -264,7 +266,7 @@ global_atari_check(struct playout_policy *p, struct board *b, enum stone to_play
 			return;
 		}
 	}
-	for (int g = 0; g < g_base; g++) {
+	for (unsigned int g = 0; g < g_base; g++) {
 		group_atari_check(pp->alwaysccaprate, b, group_at(b, group_base(b->c[g])), to_play, q, NULL, 1<<MQ_GATARI);
 		if (q->moves > 0) {
 			/* XXX: Try carrying on. */
@@ -306,7 +308,7 @@ local_ladder_check(struct playout_policy *p, struct board *b, struct move *m, st
 	if (board_group_info(b, group).libs != 2)
 		return;
 
-	for (int i = 0; i < 2; i++) {
+	for (unsigned int i = 0; i < 2; i++) {
 		coord_t chase = board_group_info(b, group).lib[i];
 		coord_t escape = board_group_info(b, group).lib[1 - i];
 		if (wouldbe_ladder(b, escape, chase, board_at(b, group)))
@@ -572,7 +574,7 @@ mq_tagged_choose(struct playout_policy *p, struct board *b, enum stone to_play,
 	for (unsigned int i = 0; i < q->moves; i++) {
 		double val = 1.0;
 		assert(q->tag[i] != 0);
-		for (int j = 0; j < MQ_MAX; j++)
+		for (unsigned int j = 0; j < MQ_MAX; j++)
 			if (q->tag[i] & (1<<j)) {
 				//fprintf(stderr, "%s(%x) %d %f *= %f\n", coord2sstr(q->move[i], b), q->tag[i], j, val, pp->mq_prob[j]);
 				val *= pp->mq_prob[j];
@@ -671,7 +673,7 @@ playout_moggy_fullchoose(struct playout_policy *p, struct playout_setup *s, stru
 
 
 void
-playout_moggy_assess_group(struct playout_policy *p, struct prior_map *map, group_t g, int games)
+playout_moggy_assess_group(struct playout_policy *p, struct prior_map *map, group_t g, unsigned int games)
 {
 	struct moggy_policy *pp = p->data;
 	struct board *b = map->b;
@@ -695,7 +697,7 @@ playout_moggy_assess_group(struct playout_policy *p, struct prior_map *map, grou
 			coord_t coord = q.move[q.moves];
 			if (PLDEBUGL(5))
 				fprintf(stderr, "1.0: nlib %s\n", coord2sstr(coord, b));
-			int assess = games / 2;
+			unsigned int assess = games / 2;
 			add_prior_value(map, coord, 1, assess);
 		}
 		return;
@@ -706,7 +708,7 @@ playout_moggy_assess_group(struct playout_policy *p, struct prior_map *map, grou
 			/* Make sure to play the correct liberty in case
 			 * this is a group that can be caught in a ladder. */
 			bool ladderable = false;
-			for (int i = 0; i < 2; i++) {
+			for (unsigned int i = 0; i < 2; i++) {
 				coord_t chase = board_group_info(b, g).lib[i];
 				coord_t escape = board_group_info(b, g).lib[1 - i];
 				if (wouldbe_ladder(b, escape, chase, board_at(b, g))) {
@@ -725,7 +727,7 @@ playout_moggy_assess_group(struct playout_policy *p, struct prior_map *map, grou
 			coord_t coord = q.move[q.moves];
 			if (PLDEBUGL(5))
 				fprintf(stderr, "1.0: 2lib %s\n", coord2sstr(coord, b));
-			int assess = games / 2;
+			unsigned int assess = games / 2;
 			add_prior_value(map, coord, 1, assess);
 		}
 		return;
@@ -759,7 +761,7 @@ playout_moggy_assess_group(struct playout_policy *p, struct prior_map *map, grou
 		if (!pp->capturerate && !pp->lcapturerate)
 			continue;
 
-		int assess = games * 2;
+		unsigned int assess = games * 2;
 		if (pp->cap_stone_denom > 0) {
 			int stones = group_stone_count(b, g, pp->cap_stone_max) - (pp->cap_stone_min-1);
 			assess += (stones > 0 ? stones : 0) * games * 100 / pp->cap_stone_denom;
@@ -771,7 +773,7 @@ playout_moggy_assess_group(struct playout_policy *p, struct prior_map *map, grou
 }
 
 void
-playout_moggy_assess_one(struct playout_policy *p, struct prior_map *map, coord_t coord, int games)
+playout_moggy_assess_one(struct playout_policy *p, struct prior_map *map, coord_t coord, unsigned int games)
 {
 	struct moggy_policy *pp = p->data;
 	struct board *b = map->b;
@@ -815,7 +817,7 @@ playout_moggy_assess_one(struct playout_policy *p, struct prior_map *map, coord_
 }
 
 void
-playout_moggy_assess(struct playout_policy *p, struct prior_map *map, int games)
+playout_moggy_assess(struct playout_policy *p, struct prior_map *map, unsigned int games)
 {
 	struct moggy_policy *pp = p->data;
 
@@ -981,7 +983,7 @@ playout_moggy_init(char *arg, struct board *b, struct joseki_dict *jdict)
 				p->choose = optval && *optval == '0' ? playout_moggy_seqchoose : playout_moggy_fullchoose;
 			} else if (!strcasecmp(optname, "mqprob") && optval) {
 				/* KO%LATARI%L2LIB%LNLIB%PAT3%GATARI%JOSEKI%NAKADE */
-				for (int i = 0; *optval && i < MQ_MAX; i++) {
+				for (unsigned int i = 0; *optval && i < MQ_MAX; i++) {
 					pp->mq_prob[i] = atof(optval);
 					optval += strcspn(optval, "%");
 					if (*optval) optval++;
diff --git a/probdist.c b/probdist.c
index 5e00b64..d871ade 100644
--- a/probdist.c
+++ b/probdist.c
@@ -18,7 +18,7 @@ probdist_pick(struct probdist *restrict pd, coord_t *restrict ignore)
 	if (DEBUGL(6))
 		fprintf(stderr, "stab %f / %f\n", fixp_to_double(stab), fixp_to_double(total));
 
-	int r = 1;
+	unsigned int r = 1;
 	coord_t c = board_size(pd->b) + 1;
 	while (stab > pd->rowtotals[r]) {
 		if (DEBUGL(6))
diff --git a/stats.h b/stats.h
index bcae0a0..a87e0a7 100644
--- a/stats.h
+++ b/stats.h
@@ -10,15 +10,15 @@
  * slightly wrong, but not drastically corrupted. */
 
 struct move_stats {
-	int playouts; // # of playouts
+	unsigned int playouts; // # of playouts
 	floating_t value; // BLACK wins/playouts
 };
 
 /* Add a result to the stats. */
-static void stats_add_result(struct move_stats *s, floating_t result, int playouts);
+static void stats_add_result(struct move_stats *s, floating_t result, unsigned int playouts);
 
 /* Remove a result from the stats. */
-static void stats_rm_result(struct move_stats *s, floating_t result, int playouts);
+static void stats_rm_result(struct move_stats *s, floating_t result, unsigned int playouts);
 
 /* Merge two stats together. THIS IS NOT ATOMIC! */
 static void stats_merge(struct move_stats *dest, struct move_stats *src);
@@ -37,9 +37,9 @@ static void stats_reverse_parity(struct move_stats *s);
  * current s->playouts is zero. */
 
 static inline void
-stats_add_result(struct move_stats *s, floating_t result, int playouts)
+stats_add_result(struct move_stats *s, floating_t result, unsigned int playouts)
 {
-	int s_playouts = s->playouts;
+	unsigned int s_playouts = s->playouts;
 	floating_t s_value = s->value;
 	/* Force the load, another thread can work on the
 	 * values in parallel. */
@@ -55,10 +55,10 @@ stats_add_result(struct move_stats *s, floating_t result, int playouts)
 }
 
 static inline void
-stats_rm_result(struct move_stats *s, floating_t result, int playouts)
+stats_rm_result(struct move_stats *s, floating_t result, unsigned int playouts)
 {
 	if (s->playouts > playouts) {
-		int s_playouts = s->playouts;
+		unsigned int s_playouts = s->playouts;
 		floating_t s_value = s->value;
 		/* Force the load, another thread can work on the
 		 * values in parallel. */
diff --git a/tactics/selfatari.c b/tactics/selfatari.c
index 8ea1e19..022fd2a 100644
--- a/tactics/selfatari.c
+++ b/tactics/selfatari.c
@@ -144,7 +144,7 @@ examine_friendly_groups(struct board *b, enum stone color, coord_t to, struct se
 		/* We need to have another liberty, and
 		 * it must not be the other liberty of
 		 * the group. */
-		int lib2 = board_group_other_lib(b, g, to);
+		coord_t lib2 = board_group_other_lib(b, g, to);
 		/* Maybe we already looked at another
 		 * group providing one liberty? */
 		if (s->needs_more_lib && s->needs_more_lib != g
diff --git a/tactics/util.c b/tactics/util.c
index d2f5d33..cb24a9f 100644
--- a/tactics/util.c
+++ b/tactics/util.c
@@ -9,21 +9,21 @@
 
 
 bool
-board_stone_radar(struct board *b, coord_t coord, int distance)
+board_stone_radar(struct board *b, coord_t coord, unsigned int distance)
 {
-	int bounds[4] = {
+	unsigned int bounds[4] = {
 		coord_x(coord, b) - distance,
 		coord_y(coord, b) - distance,
 		coord_x(coord, b) + distance,
 		coord_y(coord, b) + distance
 	};
-	for (int i = 0; i < 4; i++)
+	for (unsigned int i = 0; i < 4; i++)
 		if (bounds[i] < 1)
 			bounds[i] = 1;
 		else if (bounds[i] > board_size(b) - 2)
 			bounds[i] = board_size(b) - 2;
-	for (int x = bounds[0]; x <= bounds[2]; x++)
-		for (int y = bounds[1]; y <= bounds[3]; y++)
+	for (unsigned int x = bounds[0]; x <= bounds[2]; x++)
+		for (unsigned int y = bounds[1]; y <= bounds[3]; y++)
 			if (board_atxy(b, x, y) != S_NONE) {
 				/* fprintf(stderr, "radar %d,%d,%d: %d,%d (%d)\n",
 					coord_x(coord, b), coord_y(coord, b),
@@ -35,35 +35,35 @@ board_stone_radar(struct board *b, coord_t coord, int distance)
 
 
 void
-cfg_distances(struct board *b, coord_t start, int *distances, int maxdist)
+cfg_distances(struct board *b, coord_t start, unsigned int *distances, unsigned int maxdist)
 {
 	/* Queue for d+1 spots; no two spots of the same group
 	 * should appear in the queue. */
 #define qinc(x) (x = ((x + 1) >= board_size2(b) ? ((x) + 1 - board_size2(b)) : (x) + 1))
-	coord_t queue[board_size2(b)]; int qstart = 0, qstop = 0;
+	coord_t queue[board_size2(b)]; unsigned int qstart = 0, qstop = 0;
 
 	foreach_point(b) {
-		distances[c] = board_at(b, c) == S_OFFBOARD ? maxdist + 1 : -1;
+		distances[c] = board_at(b, c) == S_OFFBOARD ? maxdist + 1 : ~0U;
 	} foreach_point_end;
 
 	queue[qstop++] = start;
-	for (int d = 0; d <= maxdist; d++) {
+	for (unsigned int d = 0; d <= maxdist; d++) {
 		/* Process queued moves, while setting the queue
 		 * for new wave. */
-		int qa = qstart, qb = qstop;
+		unsigned int qa = qstart, qb = qstop;
 		qstart = qstop;
-		for (int q = qa; q < qb; qinc(q)) {
+		for (unsigned int q = qa; q < qb; qinc(q)) {
 #define cfg_one(coord, grp) do {\
 	distances[coord] = d; \
 	foreach_neighbor (b, coord, { \
-		if (distances[c] < 0 && (!grp || group_at(b, coord) != grp)) { \
+		if (distances[c] == ~0U && (!grp || group_at(b, coord) != grp)) { \
 			queue[qstop] = c; \
 			qinc(qstop); \
 		} \
 	}); \
 } while (0)
 			coord_t cq = queue[q];
-			if (distances[cq] >= 0)
+			if (distances[cq] != ~0U)
 				continue; /* We already looked here. */
 			if (board_at(b, cq) == S_NONE) {
 				cfg_one(cq, 0);
@@ -78,14 +78,14 @@ cfg_distances(struct board *b, coord_t start, int *distances, int maxdist)
 	}
 
 	foreach_point(b) {
-		if (distances[c] < 0)
+		if (distances[c] == ~0U)
 			distances[c] = maxdist + 1;
 	} foreach_point_end;
 }
 
 
 floating_t
-board_effective_handicap(struct board *b, int first_move_value)
+board_effective_handicap(struct board *b, unsigned int first_move_value)
 {
 	/* This can happen if the opponent passes during handicap
 	 * placing phase. */
@@ -115,10 +115,10 @@ pass_is_safe(struct board *b, enum stone color, struct move_queue *mq)
 #define EXPECTED_FINAL_EMPTY_PERCENT 25
 
 /* Returns estimated number of remaining moves for one player until end of game. */
-int
+unsigned int
 board_estimated_moves_left(struct board *b)
 {
-	int total_points = (board_size(b)-2)*(board_size(b)-2);
+	unsigned int total_points = (board_size(b)-2)*(board_size(b)-2);
 	int moves_left = (b->flen - total_points*EXPECTED_FINAL_EMPTY_PERCENT/100)/2;
 	return moves_left > MIN_MOVES_LEFT ? moves_left : MIN_MOVES_LEFT;
 }
diff --git a/tactics/util.h b/tactics/util.h
index ed94691..5a932ff 100644
--- a/tactics/util.h
+++ b/tactics/util.h
@@ -9,14 +9,14 @@
 struct move_queue;
 
 /* Checks if there are any stones in n-vincinity of coord. */
-bool board_stone_radar(struct board *b, coord_t coord, int distance);
+bool board_stone_radar(struct board *b, coord_t coord, unsigned int distance);
 
 /* Measure various distances on the board: */
 /* Distance from the edge; on edge returns 0. */
-static int coord_edge_distance(coord_t c, struct board *b);
+static unsigned int coord_edge_distance(coord_t c, struct board *b);
 /* Distance of two points in gridcular metric - this metric defines
  * circle-like structures on the square grid. */
-static int coord_gridcular_distance(coord_t c1, coord_t c2, struct board *b);
+static unsigned int coord_gridcular_distance(coord_t c1, coord_t c2, struct board *b);
 
 /* Construct a "common fate graph" from given coordinate; that is, a weighted
  * graph of intersections where edges between all neighbors have weight 1,
@@ -24,14 +24,14 @@ static int coord_gridcular_distance(coord_t c1, coord_t c2, struct board *b);
  * "stone chain" metric in a sense. */
 /* The output are distanes from start stored in given [board_size2()] array;
  * intersections further away than maxdist have all distance maxdist+1 set. */
-void cfg_distances(struct board *b, coord_t start, int *distances, int maxdist);
+void cfg_distances(struct board *b, coord_t start, unsigned int *distances, unsigned int maxdist);
 
 /* Compute an extra komi describing the "effective handicap" black receives
  * (returns 0 for even game with 7.5 komi). @stone_value is value of single
  * handicap stone, 7 is a good default. */
 /* This is just an approximation since in reality, handicap seems to be usually
  * non-linear. */
-floating_t board_effective_handicap(struct board *b, int first_move_value);
+floating_t board_effective_handicap(struct board *b, unsigned int first_move_value);
 
 /* Decide if the given player wins counting on the board, considering
  * that given groups are dead. (To get the list of dead groups, use
@@ -39,26 +39,26 @@ floating_t board_effective_handicap(struct board *b, int first_move_value);
 bool pass_is_safe(struct board *b, enum stone color, struct move_queue *mq);
 
 /* Returns estimated number of remaining moves for one player until end of game. */
-int board_estimated_moves_left(struct board *b);
+unsigned int board_estimated_moves_left(struct board *b);
 
 /* To avoid running out of time, assume we always have at least 30 more moves
  * to play if we don't have more precise information from gtp time_left: */
 #define MIN_MOVES_LEFT 30
 
 
-static inline int
+static inline unsigned int
 coord_edge_distance(coord_t c, struct board *b)
 {
-	int x = coord_x(c, b), y = coord_y(c, b);
-	int dx = x > board_size(b) / 2 ? board_size(b) - 1 - x : x;
-	int dy = y > board_size(b) / 2 ? board_size(b) - 1 - y : y;
+	unsigned int x = coord_x(c, b), y = coord_y(c, b);
+	unsigned int dx = x > board_size(b) / 2 ? board_size(b) - 1 - x : x;
+	unsigned int dy = y > board_size(b) / 2 ? board_size(b) - 1 - y : y;
 	return (dx < dy ? dx : dy) - 1 /* S_OFFBOARD */;
 }
 
-static inline int
+static inline unsigned int
 coord_gridcular_distance(coord_t c1, coord_t c2, struct board *b)
 {
-	int dx = abs(coord_dx(c1, c2, b)), dy = abs(coord_dy(c1, c2, b));
+	unsigned int dx = abs(coord_dx(c1, c2, b)), dy = abs(coord_dy(c1, c2, b));
 	return dx + dy + (dx > dy ? dx : dy);
 }
 
diff --git a/timeinfo.c b/timeinfo.c
index 71a45a7..69dffa2 100644
--- a/timeinfo.c
+++ b/timeinfo.c
@@ -288,9 +288,9 @@ time_stop_set_remaining(struct time_info *ti, struct board *b, double net_lag, s
  * We expect stop->worst to be total time available, stop->desired the current
  * per-move time allocation, and set stop->desired to adjusted per-move time. */
 static void
-time_stop_phase_adjust(struct board *b, int fuseki_end, int yose_start, struct time_stop *stop)
+time_stop_phase_adjust(struct board *b, unsigned int fuseki_end, unsigned int yose_start, struct time_stop *stop)
 {
-	int bsize = (board_size(b)-2)*(board_size(b)-2);
+	unsigned int bsize = (board_size(b)-2)*(board_size(b)-2);
 	fuseki_end = fuseki_end * bsize / 100; // move nb at fuseki end
 	yose_start = yose_start * bsize / 100; // move nb at yose start
 	assert(fuseki_end < yose_start);
@@ -335,7 +335,7 @@ lag_adjust(double *time, double net_lag)
 
 /* Pre-process time_info for search control and sets the desired stopping conditions. */
 void
-time_stop_conditions(struct time_info *ti, struct board *b, int fuseki_end, int yose_start,
+time_stop_conditions(struct time_info *ti, struct board *b, unsigned int fuseki_end, unsigned int yose_start,
 		     floating_t max_maintime_ratio, struct time_stop *stop)
 {
 	/* We must have _some_ limits by now, be it random default values! */
diff --git a/timeinfo.h b/timeinfo.h
index ff7e01f..d8538a0 100644
--- a/timeinfo.h
+++ b/timeinfo.h
@@ -26,7 +26,7 @@ struct time_info {
 	} dim;
 	/* The actual time count. */
 	union {
-		int games; // TD_GAMES
+		unsigned int games; // TD_GAMES
 		struct {   // TD_WALLTIME
 			/* Main thinking time. 0 if we are already completely
 			 * in byoyomi. */
@@ -100,17 +100,17 @@ struct time_stop {
 	/* spend this amount of time if possible */
 	union {
 		double time; // TD_WALLTIME
-		int playouts; // TD_GAMES
+		unsigned int playouts; // TD_GAMES
 	} desired;
 	/* spend no more than this time */
 	union {
 		double time; // TD_WALLTIME
-		int playouts; // TD_GAMES
+		unsigned int playouts; // TD_GAMES
 	} worst;
 };
 
 /* fuseki_end and yose_start are percentages of expected game length. */
-void time_stop_conditions(struct time_info *ti, struct board *b, int fuseki_end, int yose_start,
+void time_stop_conditions(struct time_info *ti, struct board *b, unsigned int fuseki_end, unsigned int yose_start,
 			  floating_t max_maintime_ratio, struct time_stop *stop);
 
 #endif
diff --git a/uct/dynkomi.c b/uct/dynkomi.c
index dce50c4..7cedba4 100644
--- a/uct/dynkomi.c
+++ b/uct/dynkomi.c
@@ -48,8 +48,8 @@ uct_dynkomi_init_none(struct uct *u, char *arg, struct board *b)
  * at @moves moves. */
 
 struct dynkomi_linear {
-	int handicap_value[S_MAX];
-	int moves[S_MAX];
+	unsigned int handicap_value[S_MAX];
+	unsigned int moves[S_MAX];
 	bool rootbased;
 };
 
@@ -58,7 +58,7 @@ linear_permove(struct uct_dynkomi *d, struct board *b, struct tree *tree)
 {
 	struct dynkomi_linear *l = d->data;
 	enum stone color = d->uct->pondering ? tree->root_color : stone_other(tree->root_color);
-	int lmoves = l->moves[color];
+	unsigned int lmoves = l->moves[color];
 	if (b->moves >= lmoves)
 		return 0;
 
@@ -121,7 +121,7 @@ uct_dynkomi_init_linear(struct uct *u, char *arg, struct board *b)
 				/* Dynamic komi in handicap game; linearly
 				 * decreases to basic settings until move
 				 * #optval. moves=blackmoves%whitemoves */
-				for (int i = S_BLACK; *optval && i <= S_WHITE; i++) {
+				for (unsigned int i = S_BLACK; *optval && i <= S_WHITE; i++) {
 					l->moves[i] = atoi(optval);
 					optval += strcspn(optval, "%");
 					if (*optval) optval++;
@@ -129,7 +129,7 @@ uct_dynkomi_init_linear(struct uct *u, char *arg, struct board *b)
 			} else if (!strcasecmp(optname, "handicap_value") && optval) {
 				/* Point value of single handicap stone,
 				 * for dynkomi computation. */
-				for (int i = S_BLACK; *optval && i <= S_WHITE; i++) {
+				for (unsigned int i = S_BLACK; *optval && i <= S_WHITE; i++) {
 					l->handicap_value[i] = atoi(optval);
 					optval += strcspn(optval, "%");
 					if (*optval) optval++;
@@ -169,7 +169,7 @@ struct dynkomi_adaptive {
 	 * first @lead_moves - the variance is just too much.
 	 * (Instead, we consider the handicap-based komi provided
 	 * by linear dynkomi.) */
-	int lead_moves;
+	unsigned int lead_moves;
 	/* Maximum komi to pretend the opponent to give. */
 	floating_t max_losing_komi;
 	/* Game portion at which losing komi is not allowed anymore. */
@@ -184,9 +184,9 @@ struct dynkomi_adaptive {
 	floating_t score_step_byavg; // use portion of average score as increment
 	bool use_komi_ratchet;
 	bool losing_komi_ratchet; // ratchet even losing komi
-	int komi_ratchet_maxage;
+	unsigned int komi_ratchet_maxage;
 	// runtime, not configuration:
-	int komi_ratchet_age;
+	unsigned int komi_ratchet_age;
 	floating_t komi_ratchet;
 
 	/* Score-based adaptation. */
@@ -196,7 +196,7 @@ struct dynkomi_adaptive {
 	floating_t adapt_phase; // [0,1]
 	floating_t adapt_rate; // [1,infty)
 	/* Linear adaptation rate parameter. */
-	int adapt_moves;
+	unsigned int adapt_moves;
 	floating_t adapt_dir; // [-1,1]
 };
 #define TRUSTWORTHY_KOMI_PLAYOUTS 200
@@ -205,10 +205,10 @@ static floating_t
 board_game_portion(struct dynkomi_adaptive *a, struct board *b)
 {
 	if (!a->adapt_aport) {
-		int total_moves = b->moves + 2 * board_estimated_moves_left(b);
+		unsigned int total_moves = b->moves + 2 * board_estimated_moves_left(b);
 		return (floating_t) b->moves / total_moves;
 	} else {
-		int brsize = board_size(b) - 2;
+		unsigned int brsize = board_size(b) - 2;
 		return 1.0 - (floating_t) b->flen / (brsize * brsize);
 	}
 }
diff --git a/uct/internal.h b/uct/internal.h
index 2aefd17..20671dd 100644
--- a/uct/internal.h
+++ b/uct/internal.h
@@ -25,52 +25,52 @@ struct joseki_dict;
 
 /* Internal engine state. */
 struct uct {
-	int debug_level;
-	int games, gamelen;
+	unsigned int debug_level;
+	unsigned int games, gamelen;
 	floating_t resign_threshold, sure_win_threshold;
 	double best2_ratio, bestr_ratio;
 	floating_t max_maintime_ratio;
 	bool pass_all_alive;
 	bool territory_scoring;
-	int expand_p;
+	unsigned int expand_p;
 	bool playout_amaf, playout_amaf_nakade;
 	bool amaf_prior;
-	int playout_amaf_cutoff;
+	unsigned int playout_amaf_cutoff;
 	int dumpthres;
-	int force_seed;
+	unsigned int force_seed;
 	bool no_tbook;
 	bool fast_alloc;
 	unsigned long max_tree_size;
 	unsigned long max_pruned_size;
 	unsigned long pruning_threshold;
-	int mercymin;
-	int significant_threshold;
+	unsigned int mercymin;
+	unsigned int significant_threshold;
 
-	int threads;
+	unsigned int threads;
 	enum uct_thread_model {
 		TM_TREE, /* Tree parallelization w/o virtual loss. */
 		TM_TREEVL, /* Tree parallelization with virtual loss. */
 	} thread_model;
-	int virtual_loss;
+	unsigned int virtual_loss;
 	bool pondering_opt; /* User wants pondering */
 	bool pondering; /* Actually pondering now */
 	bool slave; /* Act as slave in distributed engine. */
 	enum stone my_color;
 
-	int fuseki_end;
-	int yose_start;
+	unsigned int fuseki_end;
+	unsigned int yose_start;
 
-	int dynkomi_mask;
-	int dynkomi_interval;
+	unsigned int dynkomi_mask;
+	unsigned int dynkomi_interval;
 	struct uct_dynkomi *dynkomi;
 
 	floating_t val_scale;
-	int val_points;
+	unsigned int val_points;
 	bool val_extra;
 
-	int random_policy_chance;
+	unsigned int random_policy_chance;
 	bool local_tree;
-	int tenuki_d;
+	unsigned int tenuki_d;
 	floating_t local_tree_aging;
 #define LTREE_PLAYOUTS_MULTIPLIER 100
 	floating_t local_tree_depth_decay;
@@ -91,12 +91,12 @@ struct uct {
 	/* Used within frame of single genmove. */
 	struct board_ownermap ownermap;
 	/* Used for coordination among slaves of the distributed engine. */
-	int stats_hbits;
-	int shared_nodes;
-	int shared_levels;
+	unsigned int stats_hbits;
+	unsigned int shared_nodes;
+	unsigned int shared_levels;
 	double stats_delay; /* stored in seconds */
-	int played_own;
-	int played_all; /* games played by all slaves */
+	unsigned int played_own;
+	unsigned int played_all; /* games played by all slaves */
 
 	/* Game state - maintained by setup_state(), reset_state(). */
 	struct tree *t;
diff --git a/uct/policy/ucb1amaf.c b/uct/policy/ucb1amaf.c
index d7e8396..6af9c88 100644
--- a/uct/policy/ucb1amaf.c
+++ b/uct/policy/ucb1amaf.c
@@ -31,7 +31,7 @@ struct ucb1_policy_amaf {
 	floating_t ltree_rave;
 	/* Coefficient of criticality embedded in RAVE. */
 	floating_t crit_rave;
-	int crit_min_playouts;
+	unsigned int crit_min_playouts;
 	bool crit_negative;
 	bool crit_amaf;
 };
@@ -206,18 +206,18 @@ ucb1amaf_update(struct uct_policy *p, struct tree *tree, struct tree_node *node,
 			stats_add_result(&node->black_owner, board_at(final_board, node_coord(node)) == S_BLACK ? 1.0 : 0.0, 1);
 		}
 		stats_add_result(&node->u, result, 1);
-		if (!is_pass(node_coord(node)) && amaf_nakade(map->map[node_coord(node)]))
-			amaf_op(map->map[node_coord(node)], -);
+		if (!is_pass(node_coord(node)) && amaf_nakade(map->map[(int) node_coord(node)]))
+			amaf_op(map->map[(int) node_coord(node)], -);
 
 		/* This loop ignores symmetry considerations, but they should
 		 * matter only at a point when AMAF doesn't help much. */
 		assert(map->game_baselen >= 0);
 		for (struct tree_node *ni = node->children; ni; ni = ni->sibling) {
-			enum stone amaf_color = map->map[node_coord(ni)];
+			enum stone amaf_color = map->map[(int) node_coord(ni)];
 			assert(amaf_color != S_OFFBOARD);
 			if (amaf_color == S_NONE)
 				continue;
-			if (amaf_nakade(map->map[node_coord(ni)])) {
+			if (amaf_nakade(map->map[(int) node_coord(ni)])) {
 				if (!b->check_nakade)
 					continue;
 				unsigned int i;
diff --git a/uct/prior.c b/uct/prior.c
index 51409fa..857d939 100644
--- a/uct/prior.c
+++ b/uct/prior.c
@@ -82,7 +82,7 @@ uct_prior_b19(struct uct *u, struct tree_node *node, struct prior_map *map)
 	foreach_free_point(map->b) {
 		if (!map->consider[c])
 			continue;
-		int d = coord_edge_distance(c, map->b);
+		unsigned int d = coord_edge_distance(c, map->b);
 		if (d != 0 && d != 2)
 			continue;
 		/* The bonus applies only with no stones in immediate
@@ -115,7 +115,7 @@ uct_prior_cfgd(struct uct *u, struct tree_node *node, struct prior_map *map)
 	foreach_free_point(map->b) {
 		if (!map->consider[c])
 			continue;
-		if (map->distances[c] > u->prior->cfgdn)
+		if (map->distances[c] > (unsigned int) u->prior->cfgdn)
 			continue;
 		assert(map->distances[c] != 0);
 		int bonus = u->prior->cfgd_eqex[map->distances[c]];
@@ -129,7 +129,7 @@ uct_prior_joseki(struct uct *u, struct tree_node *node, struct prior_map *map)
 	/* Q_{joseki} */
 	if (!u->jdict)
 		return;
-	for (int i = 0; i < 4; i++) {
+	for (unsigned int i = 0; i < 4; i++) {
 		hash_t h = map->b->qhash[i] & joseki_hash_mask;
 		coord_t *cc = u->jdict->patterns[h].moves[map->to_play - 1];
 		if (!cc) continue;
diff --git a/uct/prior.h b/uct/prior.h
index e51fed3..7d55d20 100644
--- a/uct/prior.h
+++ b/uct/prior.h
@@ -21,11 +21,11 @@ struct prior_map {
 	 * prior for the given value. */
 	bool *consider;
 	/* [board_size2(b)] array from cfg_distances() */
-	int *distances;
+	unsigned int *distances;
 };
 
 /* @value is the value, @playouts is its weight. */
-static void add_prior_value(struct prior_map *map, coord_t c, floating_t value, int playouts);
+static void add_prior_value(struct prior_map *map, coord_t c, floating_t value, unsigned int playouts);
 
 void uct_prior(struct uct *u, struct tree_node *node, struct prior_map *map);
 
@@ -35,12 +35,12 @@ void uct_prior_done(struct uct_prior *p);
 
 
 static inline void
-add_prior_value(struct prior_map *map, coord_t c, floating_t value, int playouts)
+add_prior_value(struct prior_map *map, coord_t c, floating_t value, unsigned int playouts)
 {
 	floating_t v = map->parity > 0 ? value : 1 - value;
 	/* We don't need atomicity: */
 	struct move_stats s = { .playouts = playouts, .value = v };
-	stats_merge(&map->prior[c], &s);
+	stats_merge(&map->prior[(int) c], &s);
 }
 
 #endif
diff --git a/uct/search.c b/uct/search.c
index b0199fa..8bf2055 100644
--- a/uct/search.c
+++ b/uct/search.c
@@ -116,9 +116,9 @@ spawn_thread_manager(void *ctx_)
 	struct tree *t = mctx->t;
 	fast_srandom(mctx->seed);
 
-	int played_games = 0;
+	unsigned int played_games = 0;
 	pthread_t threads[u->threads];
-	int joined = 0;
+	unsigned int joined = 0;
 
 	uct_halt = 0;
 
@@ -128,7 +128,7 @@ spawn_thread_manager(void *ctx_)
 	}
 
 	/* Spawn threads... */
-	for (int ti = 0; ti < u->threads; ti++) {
+	for (unsigned int ti = 0; ti < u->threads; ti++) {
 		struct uct_thread_ctx *ctx = malloc2(sizeof(*ctx));
 		ctx->u = u; ctx->b = mctx->b; ctx->color = mctx->color;
 		mctx->t = ctx->t = t;
@@ -177,7 +177,7 @@ spawn_thread_manager(void *ctx_)
 /*** Search infrastructure: */
 
 
-int
+unsigned int
 uct_search_games(struct uct_search_state *s)
 {
 	return s->ctx->t->root->u.playouts;
@@ -233,12 +233,12 @@ uct_search_stop(void)
 void
 uct_search_progress(struct uct *u, struct board *b, enum stone color,
 		    struct tree *t, struct time_info *ti,
-		    struct uct_search_state *s, int i)
+		    struct uct_search_state *s, unsigned int i)
 {
 	struct uct_thread_ctx *ctx = s->ctx;
 
 	/* Adjust dynkomi? */
-	int di = u->dynkomi_interval * u->threads;
+	unsigned int di = u->dynkomi_interval * u->threads;
 	if (ctx->t->use_extra_komi && u->dynkomi->permove
 	    && !u->pondering && di
 	    && i > s->last_dynkomi + di) {
@@ -270,7 +270,7 @@ static bool
 uct_search_stop_early(struct uct *u, struct tree *t, struct board *b,
 		struct time_info *ti, struct time_stop *stop,
 		struct tree_node *best, struct tree_node *best2,
-		int played, bool fullmem)
+		unsigned int played, bool fullmem)
 {
 	/* If the memory is full, stop immediately. Since the tree
 	 * cannot grow anymore, some non-well-expanded nodes will
@@ -324,7 +324,7 @@ static bool
 uct_search_keep_looking(struct uct *u, struct tree *t, struct board *b,
 		struct time_info *ti, struct time_stop *stop,
 		struct tree_node *best, struct tree_node *best2,
-		struct tree_node *bestr, struct tree_node *winner, int i)
+		struct tree_node *bestr, struct tree_node *winner, unsigned int i)
 {
 	if (!best) {
 		if (UDEBUGL(2))
@@ -388,7 +388,7 @@ uct_search_keep_looking(struct uct *u, struct tree *t, struct board *b,
 bool
 uct_search_check_stop(struct uct *u, struct board *b, enum stone color,
 		      struct tree *t, struct time_info *ti,
-		      struct uct_search_state *s, int i)
+		      struct uct_search_state *s, unsigned int i)
 {
 	struct uct_thread_ctx *ctx = s->ctx;
 
@@ -449,7 +449,7 @@ uct_search_check_stop(struct uct *u, struct board *b, enum stone color,
 
 struct tree_node *
 uct_search_result(struct uct *u, struct board *b, enum stone color,
-		  bool pass_all_alive, int played_games, int base_playouts,
+		  bool pass_all_alive, unsigned int played_games, unsigned int base_playouts,
 		  coord_t *best_coord)
 {
 	/* Choose the best move from the tree. */
diff --git a/uct/search.h b/uct/search.h
index 6ee8178..ebade12 100644
--- a/uct/search.h
+++ b/uct/search.h
@@ -33,13 +33,13 @@ extern bool thread_manager_running;
 
 /* Search thread context */
 struct uct_thread_ctx {
-	int tid;
+	unsigned int tid;
 	struct uct *u;
 	struct board *b;
 	enum stone color;
 	struct tree *t;
 	unsigned long seed;
-	int games;
+	unsigned int games;
 	struct time_info *ti;
 };
 
@@ -49,13 +49,13 @@ struct uct_thread_ctx {
 struct uct_search_state {
 	/* Number of games simulated for this simulation before
 	 * we started the search. (We have simulated them earlier.) */
-	int base_playouts;
+	unsigned int base_playouts;
 	/* Number of last dynkomi adjustment. */
-	int last_dynkomi;
+	unsigned int last_dynkomi;
 	/* Number of last game with progress print. */
-	int last_print;
+	unsigned int last_print;
 	/* Number of simulations to wait before next print. */
-	int print_interval;
+	unsigned int print_interval;
 	/* Printed notification about full memory? */
 	bool fullmem;
 
@@ -63,15 +63,15 @@ struct uct_search_state {
 	struct uct_thread_ctx *ctx;
 };
 
-int uct_search_games(struct uct_search_state *s);
+unsigned int uct_search_games(struct uct_search_state *s);
 
 void uct_search_start(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti, struct uct_search_state *s);
 struct uct_thread_ctx *uct_search_stop(void);
 
-void uct_search_progress(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti, struct uct_search_state *s, int i);
+void uct_search_progress(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti, struct uct_search_state *s, unsigned int i);
 
-bool uct_search_check_stop(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti, struct uct_search_state *s, int i);
+bool uct_search_check_stop(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti, struct uct_search_state *s, unsigned int i);
 
-struct tree_node *uct_search_result(struct uct *u, struct board *b, enum stone color, bool pass_all_alive, int played_games, int base_playouts, coord_t *best_coord);
+struct tree_node *uct_search_result(struct uct *u, struct board *b, enum stone color, bool pass_all_alive, unsigned int played_games, unsigned int base_playouts, coord_t *best_coord);
 
 #endif
diff --git a/uct/slave.c b/uct/slave.c
index 3906121..d1f3b6f 100644
--- a/uct/slave.c
+++ b/uct/slave.c
@@ -397,7 +397,7 @@ report_incr_stats(struct uct *u, int *stats_size)
 	 * if we send too few nodes we just send shorter buffers
 	 * more frequently. */
 	static int min_increment = 1;
-	static int stats_count = 0;
+	static unsigned int stats_count = 0;
 	if (stats_count > 2 * u->shared_nodes) {
 		min_increment++;
 	} else if (stats_count < u->shared_nodes / 2 && min_increment > 1) {
@@ -438,8 +438,8 @@ report_stats(struct uct *u, struct board *b, coord_t c,
 	struct tree_node *root = u->t->root;
 	r += snprintf(r, end - r, "%d %d %d %d @%d", u->played_own, root->u.playouts,
 		      u->threads, keep_looking, bin_size);
-	int min_playouts = root->u.playouts / 100;
-	int max_playouts = 1;
+	unsigned int min_playouts = root->u.playouts / 100;
+	unsigned int max_playouts = 1;
 
 	/* We rely on the fact that root->children is set only
 	 * after all children are created. */
diff --git a/uct/tree.c b/uct/tree.c
index 510221c..22d556d 100644
--- a/uct/tree.c
+++ b/uct/tree.c
@@ -24,7 +24,7 @@
  * Returns NULL if not enough memory.
  * This function may be called by multiple threads in parallel. */
 static struct tree_node *
-tree_alloc_node(struct tree *t, int count, bool fast_alloc, hash_t *hash)
+tree_alloc_node(struct tree *t, unsigned int count, bool fast_alloc, hash_t *hash)
 {
 	struct tree_node *n = NULL;
 	size_t nsize = count * sizeof(*n);
@@ -51,7 +51,7 @@ tree_alloc_node(struct tree *t, int count, bool fast_alloc, hash_t *hash)
 /* Initialize a node at a given place in memory.
  * This function may be called by multiple threads in parallel. */
 static void
-tree_setup_node(struct tree *t, struct tree_node *n, coord_t coord, int depth, hash_t hash)
+tree_setup_node(struct tree *t, struct tree_node *n, coord_t coord, unsigned int depth, hash_t hash)
 {
 	n->coord = coord;
 	n->depth = depth;
@@ -64,7 +64,7 @@ tree_setup_node(struct tree *t, struct tree_node *n, coord_t coord, int depth, h
  * or exits the main program if not enough memory.
  * This function may be called by multiple threads in parallel. */
 static struct tree_node *
-tree_init_node(struct tree *t, coord_t coord, int depth, bool fast_alloc)
+tree_init_node(struct tree *t, coord_t coord, unsigned int depth, bool fast_alloc)
 {
 	struct tree_node *n;
 	hash_t hash;
@@ -77,7 +77,7 @@ tree_init_node(struct tree *t, coord_t coord, int depth, bool fast_alloc)
 /* Create a tree structure. Pre-allocate all nodes if max_tree_size is > 0. */
 struct tree *
 tree_init(struct board *board, enum stone color, unsigned long max_tree_size,
-	  unsigned long max_pruned_size, unsigned long pruning_threshold, floating_t ltree_aging, int hbits)
+	  unsigned long max_pruned_size, unsigned long pruning_threshold, floating_t ltree_aging, unsigned int hbits)
 {
 	struct tree *t = calloc2(1, sizeof(*t));
 	t->board = board;
@@ -187,10 +187,10 @@ tree_done(struct tree *t)
 
 
 static void
-tree_node_dump(struct tree *tree, struct tree_node *node, int treeparity, int l, int thres)
+tree_node_dump(struct tree *tree, struct tree_node *node, int treeparity, unsigned int l, int thres)
 {
-	for (int i = 0; i < l; i++) fputc(' ', stderr);
-	int children = 0;
+	for (unsigned int i = 0; i < l; i++) fputc(' ', stderr);
+	unsigned int children = 0;
 	for (struct tree_node *ni = node->children; ni; ni = ni->sibling)
 		children++;
 	/* We use 1 as parity, since for all nodes we want to know the
@@ -205,16 +205,16 @@ tree_node_dump(struct tree *tree, struct tree_node *node, int treeparity, int l,
 
 	/* Print nodes sorted by #playouts. */
 
-	struct tree_node *nbox[1000]; int nboxl = 0;
+	struct tree_node *nbox[1000]; unsigned int nboxl = 0;
 	for (struct tree_node *ni = node->children; ni; ni = ni->sibling)
-		if (ni->u.playouts > thres)
+		if ((int) ni->u.playouts > thres)
 			nbox[nboxl++] = ni;
 
 	while (true) {
 		int best = -1;
-		for (int i = 0; i < nboxl; i++)
+		for (unsigned int i = 0; i < nboxl; i++)
 			if (nbox[i] && (best < 0 || nbox[i]->u.playouts > nbox[best]->u.playouts))
-				best = i;
+				best = (int) i;
 		if (best < 0)
 			break;
 		tree_node_dump(tree, nbox[best], treeparity, l + 1, /* node->u.value < 0.1 ? 0 : */ thres);
@@ -259,7 +259,7 @@ tree_book_name(struct board *b)
 static void
 tree_node_save(FILE *f, struct tree_node *node, int thres)
 {
-	bool save_children = node->u.playouts >= thres;
+	bool save_children = (int) node->u.playouts >= thres;
 
 	if (!save_children)
 		node->is_expanded = 0;
@@ -296,7 +296,7 @@ tree_save(struct tree *tree, struct board *b, int thres)
 
 
 void
-tree_node_load(FILE *f, struct tree_node *node, int *num)
+tree_node_load(FILE *f, struct tree_node *node, unsigned int *num)
 {
 	(*num)++;
 
@@ -336,7 +336,7 @@ tree_load(struct tree *tree, struct board *b)
 
 	fprintf(stderr, "Loading opening tbook %s...\n", filename);
 
-	int num = 0;
+	unsigned int num = 0;
 	if (fgetc(f))
 		tree_node_load(f, tree->root, &num);
 	fprintf(stderr, "Loaded %d nodes.\n", num);
@@ -365,7 +365,7 @@ tree_prune(struct tree *dest, struct tree *src, struct tree_node *node,
 	n2->children = NULL;
 	n2->is_expanded = false;
 
-	if (node->depth >= depth && node->u.playouts < threshold)
+	if (node->depth >= depth && (int) node->u.playouts < threshold)
 		return n2;
 	/* For deep nodes with many playouts, we must copy all children,
 	 * even those with zero playouts, because partially expanded
@@ -525,7 +525,7 @@ tree_get_node(struct tree *t, struct tree_node *parent, coord_t c, bool create)
  * iterator @lni (which points either at the corresponding node, or at the
  * nearest local tree node after @ni). */
 struct tree_node *
-tree_lnode_for_node(struct tree *tree, struct tree_node *ni, struct tree_node *lni, int tenuki_d)
+tree_lnode_for_node(struct tree *tree, struct tree_node *ni, struct tree_node *lni, unsigned int tenuki_d)
 {
 	/* Now set up lnode, which is the actual local node
 	 * corresponding to ni - either lni if it is an
@@ -574,7 +574,7 @@ void
 tree_expand_node(struct tree *t, struct tree_node *node, struct board *b, enum stone color, struct uct *u, int parity)
 {
 	/* Get a Common Fate Graph distance map from parent node. */
-	int distances[board_size2(b)];
+	unsigned int distances[board_size2(b)];
 	if (!is_pass(b->last_move.coord) && !is_resign(b->last_move.coord)) {
 		cfg_distances(b, node_coord(node), distances, TREE_NODE_D_MAX);
 	} else {
@@ -594,7 +594,7 @@ tree_expand_node(struct tree *t, struct tree_node *node, struct board *b, enum s
 	bool map_consider[board_size2(b) + 1]; map.consider = &map_consider[1];
 	memset(map_prior, 0, sizeof(map_prior));
 	memset(map_consider, 0, sizeof(map_consider));
-	map.consider[pass] = true;
+	map.consider[(int) pass] = true;
 	foreach_free_point(b) {
 		assert(board_at(b, c) == S_NONE);
 		if (!board_is_valid_play(b, color, c))
@@ -612,7 +612,7 @@ tree_expand_node(struct tree *t, struct tree_node *node, struct board *b, enum s
 	}
 	struct tree_node *first_child = ni;
 	ni->parent = node;
-	ni->prior = map.prior[pass]; ni->d = TREE_NODE_D_MAX + 1;
+	ni->prior = map.prior[(int) pass]; ni->d = TREE_NODE_D_MAX + 1;
 
 	/* The loop considers only the symmetry playground. */
 	if (UDEBUGL(6)) {
@@ -622,10 +622,10 @@ tree_expand_node(struct tree *t, struct tree_node *node, struct board *b, enum s
 				b->symmetry.x2, b->symmetry.y2,
 				b->symmetry.type, b->symmetry.d);
 	}
-	for (int j = b->symmetry.y1; j <= b->symmetry.y2; j++) {
-		for (int i = b->symmetry.x1; i <= b->symmetry.x2; i++) {
+	for (unsigned int j = b->symmetry.y1; j <= b->symmetry.y2; j++) {
+		for (unsigned int i = b->symmetry.x1; i <= b->symmetry.x2; i++) {
 			if (b->symmetry.d) {
-				int x = b->symmetry.type == SYM_DIAG_DOWN ? board_size(b) - 1 - i : i;
+				unsigned int x = b->symmetry.type == SYM_DIAG_DOWN ? board_size(b) - 1 - i : i;
 				if (x > j) {
 					if (UDEBUGL(7))
 						fprintf(stderr, "drop %d,%d\n", i, j);
@@ -655,11 +655,11 @@ tree_expand_node(struct tree *t, struct tree_node *node, struct board *b, enum s
 
 static coord_t
 flip_coord(struct board *b, coord_t c,
-           bool flip_horiz, bool flip_vert, int flip_diag)
+           bool flip_horiz, bool flip_vert, bool flip_diag)
 {
-	int x = coord_x(c, b), y = coord_y(c, b);
+	unsigned int x = coord_x(c, b), y = coord_y(c, b);
 	if (flip_diag) {
-		int z = x; x = y; y = z;
+		unsigned int z = x; x = y; y = z;
 	}
 	if (flip_horiz) {
 		x = board_size(b) - 1 - x;
@@ -672,7 +672,7 @@ flip_coord(struct board *b, coord_t c,
 
 static void
 tree_fix_node_symmetry(struct board *b, struct tree_node *node,
-                       bool flip_horiz, bool flip_vert, int flip_diag)
+                       bool flip_horiz, bool flip_vert, bool flip_diag)
 {
 	if (!is_pass(node_coord(node)))
 		node->coord = flip_coord(b, node_coord(node), flip_horiz, flip_vert, flip_diag);
@@ -688,7 +688,7 @@ tree_fix_symmetry(struct tree *tree, struct board *b, coord_t c)
 		return;
 
 	struct board_symmetry *s = &tree->root_symmetry;
-	int cx = coord_x(c, b), cy = coord_y(c, b);
+	unsigned int cx = coord_x(c, b), cy = coord_y(c, b);
 
 	/* playground	X->h->v->d normalization
 	 * :::..	.d...
@@ -702,7 +702,7 @@ tree_fix_symmetry(struct tree *tree, struct board *b, coord_t c)
 	bool flip_diag = 0;
 	if (s->d) {
 		bool dir = (s->type == SYM_DIAG_DOWN);
-		int x = dir ^ flip_horiz ^ flip_vert ? board_size(b) - 1 - cx : cx;
+		unsigned int x = dir ^ flip_horiz ^ flip_vert ? board_size(b) - 1 - cx : cx;
 		if (flip_vert ? x < cy : x > cy) {
 			flip_diag = 1;
 		}
diff --git a/uct/tree.h b/uct/tree.h
index 37c1f12..b22e1cd 100644
--- a/uct/tree.h
+++ b/uct/tree.h
@@ -70,8 +70,8 @@ struct tree_node {
 	unsigned char hints;
 
 	/* coord is usually coord_t, but this is very space-sensitive. */
-#define node_coord(n) ((int) (n)->coord)
-	short coord;
+#define node_coord(n) ((unsigned int) (short) (n)->coord) // sign-extend
+	unsigned short coord;
 
 	/* In case multiple threads walk the tree, is_expanded is set
 	 * atomically. Only the first thread setting it expands the node.
@@ -126,10 +126,10 @@ struct tree {
 	/* Hash table used when working as slave for the distributed engine.
 	 * Maps coordinate path to tree node. */
 	struct tree_hash *htable;
-	int hbits;
+	unsigned int hbits;
 
 	// Statistics
-	int max_depth;
+	unsigned int max_depth;
 	volatile unsigned long nodes_size; // byte size of all allocated nodes
 	unsigned long max_tree_size; // maximum byte size for entire tree, > 0 only for fast_alloc
 	unsigned long max_pruned_size;
@@ -139,7 +139,7 @@ struct tree {
 
 /* Warning: all functions below except tree_expand_node & tree_leaf_node are THREAD-UNSAFE! */
 struct tree *tree_init(struct board *board, enum stone color, unsigned long max_tree_size,
-		       unsigned long max_pruned_size, unsigned long pruning_threshold, floating_t ltree_aging, int hbits);
+		       unsigned long max_pruned_size, unsigned long pruning_threshold, floating_t ltree_aging, unsigned int hbits);
 void tree_done(struct tree *tree);
 void tree_dump(struct tree *tree, int thres);
 void tree_save(struct tree *tree, struct board *b, int thres);
@@ -151,7 +151,7 @@ void tree_promote_node(struct tree *tree, struct tree_node **node);
 bool tree_promote_at(struct tree *tree, struct board *b, coord_t c);
 
 void tree_expand_node(struct tree *tree, struct tree_node *node, struct board *b, enum stone color, struct uct *u, int parity);
-struct tree_node *tree_lnode_for_node(struct tree *tree, struct tree_node *ni, struct tree_node *lni, int tenuki_d);
+struct tree_node *tree_lnode_for_node(struct tree *tree, struct tree_node *ni, struct tree_node *lni, unsigned int tenuki_d);
 
 static bool tree_leaf_node(struct tree_node *node);
 
diff --git a/uct/walk.c b/uct/walk.c
index 45f0bbf..e7f4d2a 100644
--- a/uct/walk.c
+++ b/uct/walk.c
@@ -24,7 +24,7 @@
 #define DESCENT_DLEN 512
 
 void
-uct_progress_status(struct uct *u, struct tree *t, enum stone color, int playouts)
+uct_progress_status(struct uct *u, struct tree *t, enum stone color, unsigned int playouts)
 {
 	if (!UDEBUGL(0))
 		return;
@@ -44,7 +44,7 @@ uct_progress_status(struct uct *u, struct tree *t, enum stone color, int playout
 
 	/* Best sequence */
 	fprintf(stderr, "| seq ");
-	for (int depth = 0; depth < 4; depth++) {
+	for (unsigned int depth = 0; depth < 4; depth++) {
 		if (best && best->u.playouts >= 25) {
 			fprintf(stderr, "%3s ", coord2sstr(node_coord(best), t->board));
 			best = u->policy->choose(u->policy, best, t->board, color, resign);
@@ -55,18 +55,18 @@ uct_progress_status(struct uct *u, struct tree *t, enum stone color, int playout
 
 	/* Best candidates */
 	fprintf(stderr, "| can ");
-	int cans = 4;
+	unsigned int cans = 4;
 	struct tree_node *can[cans];
 	memset(can, 0, sizeof(can));
 	best = t->root->children;
 	while (best) {
-		int c = 0;
+		unsigned int c = 0;
 		while ((!can[c] || best->u.playouts > can[c]->u.playouts) && ++c < cans);
-		for (int d = 0; d < c; d++) can[d] = can[d + 1];
+		for (unsigned int d = 0; d < c; d++) can[d] = can[d + 1];
 		if (c > 0) can[c - 1] = best;
 		best = best->sibling;
 	}
-	while (--cans >= 0) {
+	while (cans-- > 0) {
 		if (can[cans]) {
 			fprintf(stderr, "%3s(%.3f) ",
 			        coord2sstr(node_coord(can[cans]), t->board),
@@ -125,7 +125,7 @@ uct_playout_postpolicy(struct playout_policy *playout, struct playout_setup *set
 static int
 uct_leaf_node(struct uct *u, struct board *b, enum stone player_color,
               struct playout_amafmap *amaf,
-	      struct uct_descent *descent, int *dlen,
+	      struct uct_descent *descent, unsigned int *dlen,
 	      struct tree_node *significant[2],
               struct tree *t, struct tree_node *n, enum stone node_color,
 	      char *spaces)
@@ -172,7 +172,7 @@ scale_value(struct uct *u, struct board *b, int result)
 {
 	floating_t rval = result > 0 ? 1.0 : result < 0 ? 0.0 : 0.5;
 	if (u->val_scale && result != 0) {
-		int vp = u->val_points;
+		unsigned int vp = u->val_points;
 		if (!vp) {
 			vp = board_size(b) - 1; vp *= vp; vp *= 2;
 		}
@@ -199,7 +199,7 @@ local_value(struct uct *u, struct board *b, coord_t coord, enum stone color)
 	 * encourage taking off external liberties during a semeai. */
 	double val;
 	if (u->local_tree_neival) {
-		int friends = neighbor_count_at(b, coord, color) + neighbor_count_at(b, coord, S_OFFBOARD);
+		unsigned int friends = neighbor_count_at(b, coord, color) + neighbor_count_at(b, coord, S_OFFBOARD);
 		if (immediate_liberty_count(b, coord) > 0) {
 			foreach_neighbor(b, coord, {
 				friends += board_is_one_point_eye(b, coord, color);
@@ -214,7 +214,7 @@ local_value(struct uct *u, struct board *b, coord_t coord, enum stone color)
 
 static void
 record_local_sequence(struct uct *u, struct tree *t, struct board *endb,
-                      struct uct_descent *descent, int dlen, int di,
+                      struct uct_descent *descent, unsigned int dlen, unsigned int di,
 		      enum stone seq_color)
 {
 #define LTREE_DEBUG if (UDEBUGL(6))
@@ -228,7 +228,7 @@ record_local_sequence(struct uct *u, struct tree *t, struct board *endb,
 		stone2str(seq_color));
 
 	/* Sequences starting deeper are less relevant in general. */
-	int pval = LTREE_PLAYOUTS_MULTIPLIER;
+	unsigned int pval = LTREE_PLAYOUTS_MULTIPLIER;
 	if (u->local_tree && u->local_tree_depth_decay > 0)
 		pval = ((floating_t) pval) / pow(u->local_tree_depth_decay, di - 1);
 	if (!pval) {
@@ -249,7 +249,7 @@ record_local_sequence(struct uct *u, struct tree *t, struct board *endb,
 	}
 
 	/* ...and record the sequence. */
-	int di0 = di;
+	unsigned int di0 = di;
 	while (di < dlen && (di == di0 || descent[di].node->d < u->tenuki_d)) {
 		enum stone color = (di - di0) % 2 ? stone_other(seq_color) : seq_color;
 		double rval;
@@ -306,7 +306,7 @@ uct_playout(struct uct *u, struct board *b, enum stone player_color, struct tree
 	 * redundant. */
 	struct uct_descent descent[DESCENT_DLEN];
 	descent[0].node = n; descent[0].lnode = NULL;
-	int dlen = 1;
+	unsigned int dlen = 1;
 	/* Total value of the sequence. */
 	struct move_stats seq_value = { .playouts = 0 };
 	/* The last "significant" node along the descent (i.e. node
@@ -317,8 +317,8 @@ uct_playout(struct uct *u, struct board *b, enum stone player_color, struct tree
 		significant[node_color - 1] = n;
 
 	int result;
-	int pass_limit = (board_size(&b2) - 2) * (board_size(&b2) - 2) / 2;
-	int passes = is_pass(b->last_move.coord) && b->moves > 0;
+	unsigned int pass_limit = (board_size(&b2) - 2) * (board_size(&b2) - 2) / 2;
+	unsigned int passes = is_pass(b->last_move.coord) && b->moves > 0;
 
 	/* debug */
 	static char spaces[] = "\0                                                      ";
@@ -374,7 +374,7 @@ uct_playout(struct uct *u, struct board *b, enum stone player_color, struct tree
 		if (u->virtual_loss)
 			stats_add_result(&n->u, node_color == S_BLACK ? 0.0 : 1.0, u->virtual_loss);
 
-		assert(node_coord(n) >= -1);
+		assert((int) node_coord(n) >= -1);
 		if (amaf && !is_pass(node_coord(n)))
 			record_amaf_move(amaf, node_coord(n), node_color);
 
@@ -453,11 +453,11 @@ uct_playout(struct uct *u, struct board *b, enum stone player_color, struct tree
 		for (unsigned int i = 0; i < cutoff; i++) {
 			coord_t coord = amaf->game[i].coord;
 			enum stone color = amaf->game[i].color;
-			if (amaf->map[coord] == S_NONE || amaf->map[coord] == color) {
-				amaf->map[coord] = color;
+			if (amaf->map[(int) coord] == S_NONE || amaf->map[(int) coord] == color) {
+				amaf->map[(int) coord] = color;
 			/* Nakade always recorded for in-tree part */
 			} else if (amaf->record_nakade || i <= amaf->game_baselen) {
-				amaf_op(amaf->map[node_coord(n)], +);
+				amaf_op(amaf->map[(int) node_coord(n)], +);
 			}
 		}
 	}
@@ -484,7 +484,7 @@ uct_playout(struct uct *u, struct board *b, enum stone player_color, struct tree
 		/* First move always starts a sequence. */
 		record_local_sequence(u, t, &b2, descent, dlen, 1, seq_color);
 		seq_color = stone_other(seq_color);
-		for (int dseqi = 2; dseqi < dlen; dseqi++, seq_color = stone_other(seq_color)) {
+		for (unsigned int dseqi = 2; dseqi < dlen; dseqi++, seq_color = stone_other(seq_color)) {
 			if (u->local_tree_allseq) {
 				/* We are configured to record all subsequences. */
 				record_local_sequence(u, t, &b2, descent, dlen, dseqi, seq_color);
@@ -521,10 +521,10 @@ end:
 	return result;
 }
 
-int
+unsigned int
 uct_playouts(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti)
 {
-	int i;
+	unsigned int i;
 	if (ti && ti->dim == TD_GAMES) {
 		for (i = 0; t->root->u.playouts <= ti->len.games && !uct_halt; i++)
 			uct_playout(u, b, color, t);
diff --git a/uct/walk.h b/uct/walk.h
index e645f34..e4b9e04 100644
--- a/uct/walk.h
+++ b/uct/walk.h
@@ -7,9 +7,9 @@ struct tree;
 struct uct;
 struct board;
 
-void uct_progress_status(struct uct *u, struct tree *t, enum stone color, int playouts);
+void uct_progress_status(struct uct *u, struct tree *t, enum stone color, unsigned int playouts);
 
 int uct_playout(struct uct *u, struct board *b, enum stone player_color, struct tree *t);
-int uct_playouts(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti);
+unsigned int uct_playouts(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti);
 
 #endif

-- 
				Petr "Pasky" Baudis
UNIX is user friendly, it's just picky about who its friends are.


More information about the Pachi mailing list