static int gtp_set_free_handicap(char *s) { int i, j; int n; int handicap = 0; if (!board_empty()) return gtp_failure("board not empty"); while ((n = gtp_decode_coord(s, &i, &j)) > 0) { s += n; if (get_board(i, j) != EMPTY) { clear_board(); return gtp_failure("repeated vertex"); } play_move(i, j, BLACK); handicap++; } if (sscanf(s, "%*s") != EOF) { clear_board(); return gtp_failure("invalid coordinate"); } if (handicap < 2 || handicap >= board_size * board_size) { clear_board(); return gtp_failure("invalid handicap"); } return gtp_success(""); }
static void pick_random_last_move(struct board *b, enum stone to_play) { if (board_empty(b)) return; int base = fast_random(board_size2(b)); for (int i = base; i < base + board_size2(b); i++) { coord_t c = i % board_size2(b); if (board_at(b, c) == stone_other(to_play)) { b->last_move.coord = c; b->last_move.color = board_at(b, c); break; } } }
/* Common code for fixed_handicap and place_free_handicap. */ static int place_handicap(char *s, int fixed) { int handicap; int m, n; int first_stone = 1; if (!board_empty()) return gtp_failure("board not empty"); if (sscanf(s, "%d", &handicap) < 1) return gtp_failure("handicap not an integer"); if (handicap < 2) return gtp_failure("invalid handicap"); if (fixed && !valid_fixed_handicap(handicap)) return gtp_failure("invalid handicap"); if (fixed) place_fixed_handicap(handicap); else place_free_handicap(handicap); gtp_start_response(GTP_SUCCESS); for (m = 0; m < board_size; m++) for (n = 0; n < board_size; n++) if (get_board(m, n) != EMPTY) { if (first_stone) first_stone = 0; else gtp_printf(" "); gtp_mprintf("%m", m, n); } return gtp_finish_response(); }