void load_and_analyze_sgf_file(Gameinfo *gameinfo) { SGFTree sgftree; int move; int next; float move_value; next = gameinfo->to_move; sgftree = gameinfo->game_record; if (metamachine) sgffile_begindump(&sgftree); move = genmove(next, &move_value, NULL); gprintf("%s move %1m\n", next == WHITE ? "white (O)" : "black (X)", move); if (metamachine) sgffile_enddump(outfilename); else { gnugo_play_move(move, next); sgftreeAddPlay(&sgftree, next, I(move), J(move)); sgftreeAddComment(&sgftree, "load and analyze mode"); sgffile_add_debuginfo(sgftree.lastnode, move_value); sgffile_output(&sgftree); } }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void move_generator_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); nextply(SLICE_STARTER(si)); genmove(); pipe_solve_delegate(si); finply(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static int computer_move(Gameinfo *gameinfo, int *passes) { int move; float move_value; int resign; int resignation_declined = 0; float upper_bound, lower_bound; init_sgf(gameinfo); /* Generate computer move. */ if (autolevel_on) adjust_level_offset(gameinfo->to_move); move = genmove(gameinfo->to_move, &move_value, &resign); if (resignation_allowed && resign) { int state = ascii_endgame(gameinfo, 2); if (state != -1) return state; /* The opponent declined resignation. Remember not to resign again. */ resignation_allowed = 0; resignation_declined = 1; } if (showscore) { gnugo_estimate_score(&upper_bound, &lower_bound); current_score_estimate = (int) ((lower_bound + upper_bound) / 2.0); } mprintf("%s(%d): %1m\n", color_to_string(gameinfo->to_move), movenum + 1, move); if (is_pass(move)) (*passes)++; else *passes = 0; gnugo_play_move(move, gameinfo->to_move); sgffile_add_debuginfo(sgftree.lastnode, move_value); sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); if (resignation_declined) sgftreeAddComment(&sgftree, "GNU Go resignation was declined"); sgffile_output(&sgftree); gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); return 0; }
void Flame::act() { // if collides with a ship, stick to it // dies in some 200 frames genmove(); }
/* --------------------------------------------------------------*/ void play_gmp(Gameinfo *gameinfo, int simplified) { SGFTree sgftree; Gmp *ge; GmpResult message; const char *error; int i, j; int passes = 0; /* two passes and its over */ int to_move; /* who's turn is next ? */ int mycolor = -1; /* who has which color */ int yourcolor; if (gameinfo->computer_player == WHITE) mycolor = 1; else if (gameinfo->computer_player == BLACK) mycolor = 0; sgftree_clear(&sgftree); sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap); ge = gmp_create(0, 1); TRACE("board size=%d\n", board_size); /* * The specification of the go modem protocol doesn't even discuss * komi. So we have to guess the komi. If the komi is set on the * command line, keep it. Otherwise, its value will be 0.0 and we * use 5.5 in an even game, 0.5 otherwise. */ if (komi == 0.0) { if (gameinfo->handicap == 0) komi = 5.5; else komi = 0.5; } if (!simplified) { /* Leave all the -1's so the client can negotiate the game parameters. */ if (chinese_rules) gmp_startGame(ge, -1, -1, 5.5, -1, mycolor, 0); else gmp_startGame(ge, -1, -1, 5.5, 0, mycolor, 0); } else { gmp_startGame(ge, board_size, gameinfo->handicap, komi, chinese_rules, mycolor, 1); } do { message = gmp_check(ge, 1, NULL, NULL, &error); } while (message == gmp_nothing || message == gmp_reset); if (message == gmp_err) { fprintf(stderr, "gnugo-gmp: Error \"%s\" occurred.\n", error); exit(EXIT_FAILURE); } else if (message != gmp_newGame) { fprintf(stderr, "gnugo-gmp: Expecting a newGame, got %s\n", gmp_resultString(message)); exit(EXIT_FAILURE); } gameinfo->handicap = gmp_handicap(ge); if (!check_boardsize(gmp_size(ge), stderr)) exit(EXIT_FAILURE); gnugo_clear_board(gmp_size(ge)); /* Let's pretend GMP knows about komi in case something will ever change. */ komi = gmp_komi(ge); #if ORACLE if (metamachine && oracle_exists) oracle_clear_board(board_size); #endif sgfOverwritePropertyInt(sgftree.root, "SZ", board_size); TRACE("size=%d, handicap=%d, komi=%f\n", board_size, gameinfo->handicap, komi); if (gameinfo->handicap) to_move = WHITE; else to_move = BLACK; if (gmp_iAmWhite(ge)) { mycolor = WHITE; /* computer white */ yourcolor = BLACK; /* human black */ } else { mycolor = BLACK; yourcolor = WHITE; } gameinfo->computer_player = mycolor; sgf_write_header(sgftree.root, 1, get_random_seed(), komi, gameinfo->handicap, get_level(), chinese_rules); gameinfo->handicap = gnugo_sethand(gameinfo->handicap, sgftree.root); sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); /* main GMP loop */ while (passes < 2) { if (to_move == yourcolor) { int move; /* Get opponent's move from gmp client. */ message = gmp_check(ge, 1, &j, &i, &error); if (message == gmp_err) { fprintf(stderr, "GNU Go: Sorry, error from gmp client\n"); sgftreeAddComment(&sgftree, "got error from gmp client"); sgffile_output(&sgftree); return; } if (message == gmp_undo) { int k; assert(j > 0); for (k = 0; k < j; k++) { if (!undo_move(1)) { fprintf(stderr, "GNU Go: play_gmp UNDO: can't undo %d moves\n", j - k); break; } sgftreeAddComment(&sgftree, "undone"); sgftreeBack(&sgftree); to_move = OTHER_COLOR(to_move); } continue; } if (message == gmp_pass) { passes++; move = PASS_MOVE; } else { passes = 0; move = POS(i, j); } TRACE("\nyour move: %1m\n\n", move); sgftreeAddPlay(&sgftree, to_move, I(move), J(move)); gnugo_play_move(move, yourcolor); sgffile_output(&sgftree); } else { /* Generate my next move. */ float move_value; int move; if (autolevel_on) adjust_level_offset(mycolor); move = genmove(mycolor, &move_value, NULL); gnugo_play_move(move, mycolor); sgffile_add_debuginfo(sgftree.lastnode, move_value); if (is_pass(move)) { /* pass */ sgftreeAddPlay(&sgftree, to_move, -1, -1); gmp_sendPass(ge); ++passes; } else { /* not pass */ sgftreeAddPlay(&sgftree, to_move, I(move), J(move)); gmp_sendMove(ge, J(move), I(move)); passes = 0; TRACE("\nmy move: %1m\n\n", move); } sgffile_add_debuginfo(sgftree.lastnode, 0.0); sgffile_output(&sgftree); } to_move = OTHER_COLOR(to_move); } /* two passes: game over */ gmp_sendPass(ge); if (!quiet) fprintf(stderr, "Game over - waiting for client to shut us down\n"); who_wins(mycolor, stderr); if (showtime) { gprintf("\nSLOWEST MOVE: %d at %1m ", slowest_movenum, slowest_move); fprintf(stderr, "(%.2f seconds)\n", slowest_time); fprintf(stderr, "\nAVERAGE TIME: %.2f seconds per move\n", total_time / movenum); fprintf(stderr, "\nTOTAL TIME: %.2f seconds\n", total_time); } /* play_gmp() does not return to main(), therefore the score * writing code is here. */ { float score = gnugo_estimate_score(NULL, NULL); sgfWriteResult(sgftree.root, score, 1); } sgffile_output(&sgftree); if (!simplified) { /* We hang around here until cgoban asks us to go, since * sometimes cgoban crashes if we exit first. * * FIXME: Check if this is still needed. I made it dependand on * `simplifed' just to avoid changes in GMP mode. */ while (1) { message = gmp_check(ge, 1, &j, &i, &error); if (!quiet) fprintf(stderr, "Message %d from gmp\n", message); if (message == gmp_err) break; } } #if ORACLE if (metamachine && oracle_exists) dismiss_oracle(); #endif if (!quiet) fprintf(stderr, "gnugo going down\n"); }
static void replay_node(SGFNode *node, int color_to_replay, float *replay_score, float *total_score) { SGFProperty *sgf_prop; /* iterate over properties of the node */ SGFProperty *move_prop = NULL; /* remember if we see a move property */ int color; /* color of move to be made at this node. */ int old_move; /* The move played in the file. */ int new_move; /* The move generated by GNU Go. */ char buf[BUFSIZE]; /* Handle any AB / AW properties, and note presence * of move properties. */ for (sgf_prop = node->props; sgf_prop; sgf_prop = sgf_prop->next) { switch (sgf_prop->name) { case SGFAB: /* add black */ add_stone(get_sgfmove(sgf_prop), BLACK); break; case SGFAW: /* add white */ add_stone(get_sgfmove(sgf_prop), WHITE); break; case SGFB: case SGFW: move_prop = sgf_prop; /* remember it for later */ break; } } /* Only generate moves at move nodes. */ if (!move_prop) return; old_move = get_sgfmove(move_prop); color = (move_prop->name == SGFW) ? WHITE : BLACK; if (color == color_to_replay || color_to_replay == GRAY) { float new_move_value = 0.0; float old_move_value = 0.0; /* Get a move from the engine for color. */ int resign; new_move = genmove(color, NULL, &resign); /* Pick up the relevant values from the potential_moves[] array. */ if (new_move != PASS_MOVE) new_move_value = potential_moves[new_move]; if (old_move != PASS_MOVE) old_move_value = potential_moves[old_move]; /* Now report on how well the computer generated the move. */ if (new_move != old_move || !quiet) { mprintf("Move %d (%C): ", movenum + 1, color); if (resign) printf("GNU Go resigns "); else { mprintf("GNU Go plays %1m ", new_move); if (new_move != PASS_MOVE) printf("(%.2f) ", new_move_value); } mprintf("- Game move %1m ", old_move); if (new_move != PASS_MOVE && old_move_value > 0.0) printf("(%.2f) ", old_move_value); printf("\n"); *replay_score += new_move_value - old_move_value; *total_score += new_move_value; } if (new_move != old_move) { if (resign) gg_snprintf(buf, BUFSIZE, "GNU Go resigns - Game move %s (%.2f)", location_to_string(old_move), old_move_value); else { gg_snprintf(buf, BUFSIZE, "GNU Go plays %s (%.2f) - Game move %s (%.2f)", location_to_string(new_move), new_move_value, location_to_string(old_move), old_move_value); if (new_move != PASS_MOVE) sgfCircle(node, I(new_move), J(new_move)); } } else gg_snprintf(buf, BUFSIZE, "GNU Go plays the same move %s (%.2f)", location_to_string(new_move), new_move_value); sgfAddComment(node, buf); sgffile_add_debuginfo(node, 0.0); } /* Finally, do play the move from the file. */ play_move(old_move, color); }
void GTP::kgs_genmove_cleanup() { early_pass = false; genmove(); early_pass = true; }
void play_solo(Gameinfo *gameinfo, int moves) { SGFTree sgftree; int passes = 0; /* num. consecutive passes */ float move_value; double t1, t2; int save_moves = moves; struct stats_data totalstats; int total_owl_count = 0; /* It tends not to be very imaginative in the opening, * so we scatter a few stones randomly to start with. * We add two random numbers to reduce the probability * of playing stones near the edge. */ int n = 6 + 2*gg_rand()%5; int i, j; komi = 5.5; sgftree_clear(&sgftree); sgftreeCreateHeaderNode(&sgftree, board_size, komi, handicap); sgf_write_header(sgftree.root, 1, get_random_seed(), 5.5, handicap, get_level(), chinese_rules); /* Generate some random moves. */ if (board_size > 6) { do { do { i = (gg_rand() % 4) + (gg_rand() % (board_size - 4)); j = (gg_rand() % 4) + (gg_rand() % (board_size - 4)); } while (!is_allowed_move(POS(i, j), gameinfo->to_move)); gnugo_play_move(POS(i, j), gameinfo->to_move); sgftreeAddPlay(&sgftree, gameinfo->to_move, i, j); sgftreeAddComment(&sgftree, "random move"); gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); } while (--n > 0); } t1 = gg_cputime(); memset(&totalstats, '\0', sizeof(totalstats)); while (passes < 2 && --moves >= 0) { int move; reset_owl_node_counter(); move = genmove(gameinfo->to_move, &move_value, NULL); gnugo_play_move(move, gameinfo->to_move); sgffile_add_debuginfo(sgftree.lastnode, move_value); sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); sgffile_output(&sgftree); gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); if (move == PASS_MOVE) { passes++; printf("%s(%d): Pass\n", gameinfo->to_move == BLACK ? "Black" : "White", movenum); } else { passes = 0; gprintf("%s(%d): %1m\n", gameinfo->to_move == BLACK ? "Black" : "White", movenum, move); } totalstats.nodes += stats.nodes; totalstats.read_result_entered += stats.read_result_entered; totalstats.read_result_hits += stats.read_result_hits; totalstats.trusted_read_result_hits += stats.trusted_read_result_hits; total_owl_count += get_owl_node_counter(); } t2 = gg_cputime(); /* Two passes and it's over. (EMPTY == BOTH) */ who_wins(EMPTY, stdout); { float score = gnugo_estimate_score(NULL, NULL); sgfWriteResult(sgftree.root, score, 1); } sgffile_output(&sgftree); printf("%10d moves played in %0.3f seconds\n", save_moves-moves, t2-t1); if (save_moves != moves) printf("%10.3f seconds/move\n", (t2-t1)/(save_moves-moves)); printf("%10d nodes\n", totalstats.nodes); printf("%10d read results entered\n", totalstats.read_result_entered); printf("%10d read result hits\n", totalstats.read_result_hits); printf("%10d trusted read result hits\n", totalstats.trusted_read_result_hits); printf("%10d owl nodes\n", total_owl_count); }