X-Git-Url: http://git.subgeniuskitty.com/sgk-go/.git/blobdiff_plain/c82ca61cf5e0994e080619e826b51d8a0ba96d51..c150f57c2a3b22ee777104daa7243e2ede38c87e:/interface/play_solo.c diff --git a/interface/play_solo.c b/interface/play_solo.c index cf210c6..8a1265a 100644 --- a/interface/play_solo.c +++ b/interface/play_solo.c @@ -23,152 +23,146 @@ #include "gnugo.h" +#include #include #include #include -#include #include "interface.h" #include "liberty.h" /* to get to the stats */ -#include "sgftree.h" -#include "random.h" #include "gg_utils.h" +#include "random.h" +#include "sgftree.h" -void -play_solo(Gameinfo *gameinfo, int moves) +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; + 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; + struct stats_data totalstats; + int total_owl_count = 0; - /* It tends not to be very imaginative in the opening, + /* 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); + 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); + } - if (move == PASS_MOVE) { - passes++; - printf("%s(%d): Pass\n", gameinfo->to_move == BLACK ? "Black" : "White", - movenum); + 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(); } - else { - passes = 0; - gprintf("%s(%d): %1m\n", gameinfo->to_move == BLACK ? "Black" : "White", - movenum, move); + 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); - 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); -} + 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); +} /* ================================================================ */ - /* * Load SGF file and run genmove(). */ -void -load_and_analyze_sgf_file(Gameinfo *gameinfo) +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); - } -} + 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); + } +} /* * Load SGF file and score the game @@ -179,103 +173,99 @@ load_and_analyze_sgf_file(Gameinfo *gameinfo) * get an accurate score */ -#define ESTIMATE 0 -#define FINISH 1 +#define ESTIMATE 0 +#define FINISH 1 #define AFTERMATH 2 -void -load_and_score_sgf_file(SGFTree *tree, Gameinfo *gameinfo, - const char *scoringmode) +void load_and_score_sgf_file(SGFTree* tree, Gameinfo* gameinfo, + const char* scoringmode) { - int move; - float move_value; - char *tempc = NULL; - char text[250]; - char winner; - int next; - int pass = 0; - int method; - float score; - SGFTree local_tree; - SGFTree *score_tree = tree; - - /* Default scoring method is ESTIMATE since it's fastest. */ - method = ESTIMATE; - if (strcmp(scoringmode, "finish") == 0) - method = FINISH; - else if (strcmp(scoringmode, "aftermath") == 0) - method = AFTERMATH; - - /* For aftermath scoring we compress the previous moves to a static + int move; + float move_value; + char* tempc = NULL; + char text[250]; + char winner; + int next; + int pass = 0; + int method; + float score; + SGFTree local_tree; + SGFTree* score_tree = tree; + + /* Default scoring method is ESTIMATE since it's fastest. */ + method = ESTIMATE; + if (strcmp(scoringmode, "finish") == 0) + method = FINISH; + else if (strcmp(scoringmode, "aftermath") == 0) + method = AFTERMATH; + + /* For aftermath scoring we compress the previous moves to a static * board position in the output sgf. This helps a lot when debugging * scoring mistakes. We don't do this for the finish method, * however, since users may be better served by having GNU Go's * selfplay added to the original game record. */ - if (method == AFTERMATH) { - sgftree_clear(&local_tree); - /* Modify komi to compensate for captured stones. We start at a + if (method == AFTERMATH) { + sgftree_clear(&local_tree); + /* Modify komi to compensate for captured stones. We start at a * setup position and since there is no standard sgf property to * tell the number of captured stones, a modified komi is the best * available solution. */ - sgftreeCreateHeaderNode(&local_tree, board_size, - komi + black_captured - white_captured, handicap); - sgffile_printboard(&local_tree); - sgfAddProperty(local_tree.lastnode, "PL", - gameinfo->to_move == WHITE ? "W" : "B"); - score_tree = &local_tree; - } - - next = gameinfo->to_move; - reset_engine(); - - /* Complete the game by selfplay for the finish and aftermath methods. */ - if (method != ESTIMATE) { - doing_scoring = 1; - while (pass < 2) { - move = genmove_conservative(next, &move_value); - if (move != PASS_MOVE) { - pass = 0; - gprintf("%d %s move %1m\n", movenum, - next == WHITE ? "white (O)" : "black (X)", move); - } - else { - pass++; - gprintf("%d %s move PASS\n", movenum, - next == WHITE ? "white (O)" : "black (X)"); - } - play_move(move, next); - sgffile_add_debuginfo(score_tree->lastnode, move_value); - sgftreeAddPlay(score_tree, next, I(move), J(move)); - sgffile_output(score_tree); - next = OTHER_COLOR(next); + sgftreeCreateHeaderNode(&local_tree, board_size, + komi + black_captured - white_captured, handicap); + sgffile_printboard(&local_tree); + sgfAddProperty(local_tree.lastnode, "PL", + gameinfo->to_move == WHITE ? "W" : "B"); + score_tree = &local_tree; } - doing_scoring = 0; - } - - /* Calculate the score. */ - if (method == AFTERMATH) - score = aftermath_compute_score(next, score_tree); - else - score = gnugo_estimate_score(NULL, NULL); - - if (score < 0.0) { - sprintf(text, "Black wins by %1.1f points\n", -score); - winner = 'B'; - } - else if (score > 0.0) { - sprintf(text, "White wins by %1.1f points\n", score); - winner = 'W'; - } - else { - sprintf(text, "Jigo\n"); - winner = '0'; - } - fputs(text, stdout); - sgftreeAddComment(score_tree, text); - - /* For the finish and aftermath methods we compare the score with + + next = gameinfo->to_move; + reset_engine(); + + /* Complete the game by selfplay for the finish and aftermath methods. */ + if (method != ESTIMATE) { + doing_scoring = 1; + while (pass < 2) { + move = genmove_conservative(next, &move_value); + if (move != PASS_MOVE) { + pass = 0; + gprintf("%d %s move %1m\n", movenum, + next == WHITE ? "white (O)" : "black (X)", move); + } else { + pass++; + gprintf("%d %s move PASS\n", movenum, + next == WHITE ? "white (O)" : "black (X)"); + } + play_move(move, next); + sgffile_add_debuginfo(score_tree->lastnode, move_value); + sgftreeAddPlay(score_tree, next, I(move), J(move)); + sgffile_output(score_tree); + next = OTHER_COLOR(next); + } + doing_scoring = 0; + } + + /* Calculate the score. */ + if (method == AFTERMATH) + score = aftermath_compute_score(next, score_tree); + else + score = gnugo_estimate_score(NULL, NULL); + + if (score < 0.0) { + sprintf(text, "Black wins by %1.1f points\n", -score); + winner = 'B'; + } else if (score > 0.0) { + sprintf(text, "White wins by %1.1f points\n", score); + winner = 'W'; + } else { + sprintf(text, "Jigo\n"); + winner = '0'; + } + fputs(text, stdout); + sgftreeAddComment(score_tree, text); + + /* For the finish and aftermath methods we compare the score with * what's stored in the game record. * * FIXME: No comparison is made if the stored result was 0. Wins by @@ -284,40 +274,38 @@ load_and_score_sgf_file(SGFTree *tree, Gameinfo *gameinfo, * FIXME: Does anybody actually care about this information? Just * removing this piece of code is a tempting alternative. */ - if (method != ESTIMATE && sgfGetCharProperty(tree->root, "RE", &tempc)) { - char dummy; - float result; - if (sscanf(tempc, "%1c%f", &dummy, &result) == 2) { - fprintf(stdout, "Result from file: %c+%1.1f\n", dummy, result); - fputs("GNU Go result and result from file are ", stdout); - if (result == fabs(score) && winner == dummy) - fputs("identical\n", stdout); - else - fputs("different\n", stdout); - + if (method != ESTIMATE && sgfGetCharProperty(tree->root, "RE", &tempc)) { + char dummy; + float result; + if (sscanf(tempc, "%1c%f", &dummy, &result) == 2) { + fprintf(stdout, "Result from file: %c+%1.1f\n", dummy, result); + fputs("GNU Go result and result from file are ", stdout); + if (result == fabs(score) && winner == dummy) + fputs("identical\n", stdout); + else + fputs("different\n", stdout); + + } else { + if (tempc[2] == 'R') { + fprintf(stdout, "Result from file: Resign\n"); + fputs("GNU Go result and result from file are ", stdout); + if (tempc[0] == winner) + fputs("identical\n", stdout); + else + fputs("different\n", stdout); + } + } } - else { - if (tempc[2] == 'R') { - fprintf(stdout, "Result from file: Resign\n"); - fputs("GNU Go result and result from file are ", stdout); - if (tempc[0] == winner) - fputs("identical\n", stdout); - else - fputs("different\n", stdout); - } - } - } - if (method != ESTIMATE) - sgfWriteResult(score_tree->root, score, 1); - - sgffile_output(score_tree); -} + if (method != ESTIMATE) + sgfWriteResult(score_tree->root, score, 1); + sgffile_output(score_tree); +} /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */