/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* 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. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void replay_node(SGFNode
*node
, int color_to_test
, float *replay_score
,
/* --------------------------------------------------------------*/
/* --------------------------------------------------------------*/
play_replay(SGFTree
*tree
, int color_to_replay
)
float replay_score
= 0.0;
SGFNode
*node
= tree
->root
;
/* Board size and komi are already set up correctly since the game
* has already been loaded before this function is called. Now we
* only have to clear the board before starting over.
printf("Board Size: %d\n", board_size
);
if (sgfGetCharProperty(node
, "HA", &tmpc
))
printf("Handicap: %s\n", tmpc
);
printf("Komi: %.1f\n", komi
);
if (sgfGetCharProperty(node
, "RU", &tmpc
))
printf("Ruleset: %s\n", tmpc
);
if (sgfGetCharProperty(node
, "GN", &tmpc
))
printf("Game Name: %s\n", tmpc
);
if (sgfGetCharProperty(node
, "DT", &tmpc
))
printf("Game Date: %s\n", tmpc
);
if (sgfGetCharProperty(node
, "GC", &tmpc
))
printf("Game Comment: %s\n", tmpc
);
if (sgfGetCharProperty(node
, "US", &tmpc
))
printf("Game User: %s\n", tmpc
);
if (sgfGetCharProperty(node
, "PB", &tmpc
))
printf("Black Player: %s\n", tmpc
);
if (sgfGetCharProperty(node
, "PW", &tmpc
))
printf("White Player: %s\n", tmpc
);
if (sgfGetCharProperty(node
, "RE", &tmpc
))
printf("Result: %s\n", tmpc
);
* Now actually run through the file. This is the interesting part.
* We need to traverse the SGF tree, and every time we encounter a node
* we need to check what move GNU Go would make, and see if it is OK.
replay_node(node
, color_to_replay
, &replay_score
, &total_score
);
printf("Global score: %.2f / %.2f\n", replay_score
, total_score
);
gprintf("SLOWEST MOVE: %d at %1m ", slowest_movenum
, slowest_move
);
fprintf(stderr
, "(%.2f seconds)\n", slowest_time
);
fprintf(stderr
, "AVERAGE TIME: %.2f seconds per move\n",
fprintf(stderr
, "TOTAL TIME: %.2f seconds\n",
replay_node(SGFNode
*node
, int color_to_replay
, float *replay_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. */
/* Handle any AB / AW properties, and note presence
for (sgf_prop
= node
->props
; sgf_prop
; sgf_prop
= sgf_prop
->next
) {
switch (sgf_prop
->name
) {
add_stone(get_sgfmove(sgf_prop
), BLACK
);
add_stone(get_sgfmove(sgf_prop
), WHITE
);
move_prop
= sgf_prop
; /* remember it for later */
/* Only generate moves at move nodes. */
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. */
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
);
printf("GNU Go resigns ");
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
);
*replay_score
+= new_move_value
- old_move_value
;
*total_score
+= new_move_value
;
if (new_move
!= old_move
) {
gg_snprintf(buf
, BUFSIZE
, "GNU Go resigns - Game move %s (%.2f)",
location_to_string(old_move
), old_move_value
);
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
));
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
);