TEST(gogame_move_check, blank_board_passes) { uint8_t board_size = 3; GoGame test(board_size); GoMove pass_move(test.get_board()); test.make_move(pass_move, 0); test.make_move(pass_move, 1); GoBoard expected_board(board_size); EXPECT_EQ(expected_board, test.get_board()); }
static void benchmark(int num_games_per_point) { int i, j; unsigned int random_seed = 1U; board_size = 9; komi = 0.5; init_brown(random_seed); for (i = 0; i < board_size; i++) { for (j = 0; j < board_size; j++) { int white_wins = 0; int black_wins = 0; int k; for (k = 0; k < num_games_per_point; k++) { int passes = 0; int num_moves = 1; int color = WHITE; clear_board(); play_move(i, j, BLACK); while (passes < 3 && num_moves < 600) { int m, n; generate_move(&m, &n, color); play_move(m, n, color); if (pass_move(m, n)) { passes++; } else { passes = 0; } num_moves++; color = OTHER_COLOR(color); } if (passes == 3) { if (compute_score() > 0) { white_wins++; } else { black_wins++; } } } /* printf("%d %d %f\n", i, j, (float) black_wins / (float) (black_wins + white_wins)); */ } } }
static int legal_move(int i, int j, int color) { int other = OTHER_COLOR(color); /* Pass is always legal. */ if (pass_move(i, j)) return 1; /* Already occupied. */ if (get_board(i, j) != EMPTY) return 0; /* Illegal ko recapture. It is not illegal to fill the ko so we must * check the color of at least one neighbor. */ if (i == ko_i && j == ko_j && ((on_board(i - 1, j) && get_board(i - 1, j) == other) || (on_board(i + 1, j) && get_board(i + 1, j) == other))) return 0; return 1; }
char* do_play(Game *game, Color c, Point pt) // Play the move (updating the Game struct) { char *ret; Color to_play_before; int played=0; Info m = 0; Position *pos = game->pos; to_play_before = board_color_to_play(pos); board_set_color_to_play(pos, c); if (point_color(pos,pt) == EMPTY) { ret = play_move(pos, pt); if (ret[0] == 0) { m = pt + (board_captured_neighbors(pos) << 9) + (board_ko_old(pos) << 13) + ((to_play_before) << 22); played = 1; } // else illegal move: nothing played } else if(pt == PASS_MOVE) { ret = pass_move(pos); m = pt + (board_captured_neighbors(pos) << 9) + (board_ko_old(pos) << 13) + ((to_play_before) << 22); played = 1; } else ret ="Error Illegal move: point not EMPTY\n"; if (played) { c2++; slist_push(game->moves, m); } return ret; }
/* Play at (i, j) for color. No legality check is done here. We need * to properly update the board array, the next_stone array, and the * ko point. */ static void play_move(int i, int j, int color) { int pos = POS(i, j); int captured_stones = 0; int k; /* Reset the ko point. */ ko_i = -1; ko_j = -1; /* Nothing more happens if the move was a pass. */ if (pass_move(i, j)) return; /* If the move is a suicide we only need to remove the adjacent * friendly stones. */ if (suicide(i, j, color)) { for (k = 0; k < 4; k++) { int ai = i + deltai[k]; int aj = j + deltaj[k]; if (on_board(ai, aj) && get_board(ai, aj) == color) remove_string(ai, aj); } return; } /* Not suicide. Remove captured opponent strings. */ for (k = 0; k < 4; k++) { int ai = i + deltai[k]; int aj = j + deltaj[k]; if (on_board(ai, aj) && get_board(ai, aj) == OTHER_COLOR(color) && !has_additional_liberty(ai, aj, i, j)) captured_stones += remove_string(ai, aj); } /* Put down the new stone. Initially build a single stone string by * setting next_stone[pos] pointing to itself. */ board[pos] = color; next_stone[pos] = pos; /* If we have friendly neighbor strings we need to link the strings * together. */ for (k = 0; k < 4; k++) { int ai = i + deltai[k]; int aj = j + deltaj[k]; int pos2 = POS(ai, aj); /* Make sure that the stones are not already linked together. This * may happen if the same string neighbors the new stone in more * than one direction. */ if (on_board(ai, aj) && board[pos2] == color && !same_string(pos, pos2)) { /* The strings are linked together simply by swapping the the * next_stone pointers. */ int tmp = next_stone[pos2]; next_stone[pos2] = next_stone[pos]; next_stone[pos] = tmp; } } /* If we have captured exactly one stone and the new string is a * single stone it may have been a ko capture. */ if (captured_stones == 1 && next_stone[pos] == pos) { int ai, aj; /* Check whether the new string has exactly one liberty. If so it * would be an illegal ko capture to play there immediately. We * know that there must be a liberty immediately adjacent to the * new stone since we captured one stone. */ for (k = 0; k < 4; k++) { ai = i + deltai[k]; aj = j + deltaj[k]; if (on_board(ai, aj) && get_board(ai, aj) == EMPTY) break; } if (!has_additional_liberty(i, j, ai, aj)) { ko_i = ai; ko_j = aj; } } }