/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* --------------------------------------------------------------*/
/* Play a game against a go-modem-protocol (GMP) client. */
/* --------------------------------------------------------------*/
play_gmp(Gameinfo
*gameinfo
, int simplified
)
int passes
= 0; /* two passes and its over */
int to_move
; /* who's turn is next ? */
int mycolor
= -1; /* who has which color */
if (gameinfo
->computer_player
== WHITE
)
else if (gameinfo
->computer_player
== BLACK
)
sgftreeCreateHeaderNode(&sgftree
, board_size
, komi
, gameinfo
->handicap
);
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 (gameinfo
->handicap
== 0)
/* Leave all the -1's so the client can negotiate the game parameters. */
gmp_startGame(ge
, -1, -1, 5.5, -1, mycolor
, 0);
gmp_startGame(ge
, -1, -1, 5.5, 0, mycolor
, 0);
gmp_startGame(ge
, board_size
, gameinfo
->handicap
,
komi
, chinese_rules
, mycolor
, 1);
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
);
else if (message
!= gmp_newGame
) {
fprintf(stderr
, "gnugo-gmp: Expecting a newGame, got %s\n",
gmp_resultString(message
));
gameinfo
->handicap
= gmp_handicap(ge
);
if (!check_boardsize(gmp_size(ge
), stderr
))
gnugo_clear_board(gmp_size(ge
));
/* Let's pretend GMP knows about komi in case something will ever change. */
if (metamachine
&& oracle_exists
)
oracle_clear_board(board_size
);
sgfOverwritePropertyInt(sgftree
.root
, "SZ", board_size
);
TRACE("size=%d, handicap=%d, komi=%f\n", board_size
,
gameinfo
->handicap
, komi
);
mycolor
= WHITE
; /* computer white */
yourcolor
= BLACK
; /* human black */
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
);
if (to_move
== yourcolor
) {
/* 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
);
if (message
== gmp_undo
) {
for (k
= 0; k
< j
; k
++) {
fprintf(stderr
, "GNU Go: play_gmp UNDO: can't undo %d moves\n",
sgftreeAddComment(&sgftree
, "undone");
to_move
= OTHER_COLOR(to_move
);
if (message
== gmp_pass
) {
TRACE("\nyour move: %1m\n\n", move
);
sgftreeAddPlay(&sgftree
, to_move
, I(move
), J(move
));
gnugo_play_move(move
, yourcolor
);
sgffile_output(&sgftree
);
/* Generate my next move. */
adjust_level_offset(mycolor
);
move
= genmove(mycolor
, &move_value
, NULL
);
gnugo_play_move(move
, mycolor
);
sgffile_add_debuginfo(sgftree
.lastnode
, move_value
);
sgftreeAddPlay(&sgftree
, to_move
, -1, -1);
sgftreeAddPlay(&sgftree
, to_move
, I(move
), J(move
));
gmp_sendMove(ge
, J(move
), I(move
));
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 */
fprintf(stderr
, "Game over - waiting for client to shut us down\n");
who_wins(mycolor
, stderr
);
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",
fprintf(stderr
, "\nTOTAL TIME: %.2f seconds\n",
/* play_gmp() does not return to main(), therefore the score
float score
= gnugo_estimate_score(NULL
, NULL
);
sgfWriteResult(sgftree
.root
, score
, 1);
sgffile_output(&sgftree
);
/* 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.
message
= gmp_check(ge
, 1, &j
, &i
, &error
);
fprintf(stderr
, "Message %d from gmp\n", message
);
if (metamachine
&& oracle_exists
)
fprintf(stderr
, "gnugo going down\n");