X-Git-Url: http://git.subgeniuskitty.com/sgk-go/.git/blobdiff_plain/c82ca61cf5e0994e080619e826b51d8a0ba96d51..c150f57c2a3b22ee777104daa7243e2ede38c87e:/interface/play_gmp.c diff --git a/interface/play_gmp.c b/interface/play_gmp.c index 9099525..270038e 100644 --- a/interface/play_gmp.c +++ b/interface/play_gmp.c @@ -24,254 +24,246 @@ #include "gnugo.h" #include "liberty.h" +#include #include #include -#include -#include "interface.h" +#include "gg_utils.h" #include "gmp.h" +#include "interface.h" #include "sgftree.h" -#include "gg_utils.h" /* --------------------------------------------------------------*/ /* Play a game against a go-modem-protocol (GMP) client. */ /* --------------------------------------------------------------*/ -void -play_gmp(Gameinfo *gameinfo, int simplified) +void play_gmp(Gameinfo* gameinfo, int simplified) { - SGFTree sgftree; + SGFTree sgftree; + + Gmp* ge; + GmpResult message; + const char* error; - 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 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; + int mycolor = -1; /* who has which color */ + int yourcolor; - if (gameinfo->computer_player == WHITE) - mycolor = 1; - else if (gameinfo->computer_player == BLACK) - mycolor = 0; + 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); + sgftree_clear(&sgftree); + sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap); - ge = gmp_create(0, 1); - TRACE("board size=%d\n", board_size); + 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 (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 (!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); + 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); + 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; } - 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); + + 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); } - - 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 + + /* 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 + { + 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; + 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(); + if (metamachine && oracle_exists) + dismiss_oracle(); #endif - if (!quiet) - fprintf(stderr, "gnugo going down\n"); + if (!quiet) + fprintf(stderr, "gnugo going down\n"); } /* * Local Variables: - * tab-width: 8 - * c-basic-offset: 2 + * tab-width: 4 + * c-basic-offset: 4 * End: */