Modified colors for compatibility with Tektronix 4107 terminal in ANSI mode.
[sgk-go] / interface / play_test.c
CommitLineData
7eeb782e
AT
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
3 * http://www.gnu.org/software/gnugo/ for more information. *
4 * *
5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
6 * 2008 and 2009 by the Free Software Foundation. *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation - version 3 or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License in file COPYING for more details. *
17 * *
18 * You should have received a copy of the GNU General Public *
19 * License along with this program; if not, write to the Free *
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
21 * Boston, MA 02111, USA. *
22\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23
24#include "gnugo.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30
31#include "interface.h"
32#include "sgftree.h"
33#include "gg_utils.h"
34#include "liberty.h"
35
36static void replay_node(SGFNode *node, int color_to_test, float *replay_score,
37 float *total_score);
38
39
40/* --------------------------------------------------------------*/
41/* replay a game */
42/* --------------------------------------------------------------*/
43
44void
45play_replay(SGFTree *tree, int color_to_replay)
46{
47 char *tmpc = NULL;
48 float replay_score = 0.0;
49 float total_score = 0.0;
50
51 SGFNode *node = tree->root;
52
53 /* Board size and komi are already set up correctly since the game
54 * has already been loaded before this function is called. Now we
55 * only have to clear the board before starting over.
56 */
57 clear_board();
58
59 if (!quiet) {
60 printf("Board Size: %d\n", board_size);
61 if (sgfGetCharProperty(node, "HA", &tmpc))
62 printf("Handicap: %s\n", tmpc);
63 printf("Komi: %.1f\n", komi);
64 if (sgfGetCharProperty(node, "RU", &tmpc))
65 printf("Ruleset: %s\n", tmpc);
66 if (sgfGetCharProperty(node, "GN", &tmpc))
67 printf("Game Name: %s\n", tmpc);
68 if (sgfGetCharProperty(node, "DT", &tmpc))
69 printf("Game Date: %s\n", tmpc);
70 if (sgfGetCharProperty(node, "GC", &tmpc))
71 printf("Game Comment: %s\n", tmpc);
72 if (sgfGetCharProperty(node, "US", &tmpc))
73 printf("Game User: %s\n", tmpc);
74 if (sgfGetCharProperty(node, "PB", &tmpc))
75 printf("Black Player: %s\n", tmpc);
76 if (sgfGetCharProperty(node, "PW", &tmpc))
77 printf("White Player: %s\n", tmpc);
78 if (sgfGetCharProperty(node, "RE", &tmpc))
79 printf("Result: %s\n", tmpc);
80 }
81
82 /*
83 * Now actually run through the file. This is the interesting part.
84 * We need to traverse the SGF tree, and every time we encounter a node
85 * we need to check what move GNU Go would make, and see if it is OK.
86 */
87 while (node) {
88 replay_node(node, color_to_replay, &replay_score, &total_score);
89 sgffile_output(tree);
90 node = node->child;
91 }
92
93 if (!quiet)
94 printf("Global score: %.2f / %.2f\n", replay_score, total_score);
95
96 if (showtime) {
97 gprintf("SLOWEST MOVE: %d at %1m ", slowest_movenum, slowest_move);
98 fprintf(stderr, "(%.2f seconds)\n", slowest_time);
99 fprintf(stderr, "AVERAGE TIME: %.2f seconds per move\n",
100 total_time / movenum);
101 fprintf(stderr, "TOTAL TIME: %.2f seconds\n",
102 total_time);
103 }
104}
105
106
107#define BUFSIZE 128
108
109/*
110 * Handle this node.
111 */
112
113static void
114replay_node(SGFNode *node, int color_to_replay, float *replay_score,
115 float *total_score)
116{
117 SGFProperty *sgf_prop; /* iterate over properties of the node */
118 SGFProperty *move_prop = NULL; /* remember if we see a move property */
119 int color; /* color of move to be made at this node. */
120
121 int old_move; /* The move played in the file. */
122 int new_move; /* The move generated by GNU Go. */
123
124 char buf[BUFSIZE];
125
126 /* Handle any AB / AW properties, and note presence
127 * of move properties.
128 */
129
130 for (sgf_prop = node->props; sgf_prop; sgf_prop = sgf_prop->next) {
131 switch (sgf_prop->name) {
132 case SGFAB:
133 /* add black */
134 add_stone(get_sgfmove(sgf_prop), BLACK);
135 break;
136 case SGFAW:
137 /* add white */
138 add_stone(get_sgfmove(sgf_prop), WHITE);
139 break;
140 case SGFB:
141 case SGFW:
142 move_prop = sgf_prop; /* remember it for later */
143 break;
144 }
145 }
146
147 /* Only generate moves at move nodes. */
148 if (!move_prop)
149 return;
150
151 old_move = get_sgfmove(move_prop);
152 color = (move_prop->name == SGFW) ? WHITE : BLACK;
153
154 if (color == color_to_replay || color_to_replay == GRAY) {
155 float new_move_value = 0.0;
156 float old_move_value = 0.0;
157
158 /* Get a move from the engine for color. */
159 int resign;
160 new_move = genmove(color, NULL, &resign);
161
162 /* Pick up the relevant values from the potential_moves[] array. */
163 if (new_move != PASS_MOVE)
164 new_move_value = potential_moves[new_move];
165 if (old_move != PASS_MOVE)
166 old_move_value = potential_moves[old_move];
167
168 /* Now report on how well the computer generated the move. */
169 if (new_move != old_move || !quiet) {
170 mprintf("Move %d (%C): ", movenum + 1, color);
171
172 if (resign)
173 printf("GNU Go resigns ");
174 else {
175 mprintf("GNU Go plays %1m ", new_move);
176 if (new_move != PASS_MOVE)
177 printf("(%.2f) ", new_move_value);
178 }
179
180 mprintf("- Game move %1m ", old_move);
181 if (new_move != PASS_MOVE && old_move_value > 0.0)
182 printf("(%.2f) ", old_move_value);
183 printf("\n");
184
185 *replay_score += new_move_value - old_move_value;
186 *total_score += new_move_value;
187 }
188
189 if (new_move != old_move) {
190 if (resign)
191 gg_snprintf(buf, BUFSIZE, "GNU Go resigns - Game move %s (%.2f)",
192 location_to_string(old_move), old_move_value);
193 else {
194 gg_snprintf(buf, BUFSIZE,
195 "GNU Go plays %s (%.2f) - Game move %s (%.2f)",
196 location_to_string(new_move), new_move_value,
197 location_to_string(old_move), old_move_value);
198 if (new_move != PASS_MOVE)
199 sgfCircle(node, I(new_move), J(new_move));
200 }
201 }
202 else
203 gg_snprintf(buf, BUFSIZE, "GNU Go plays the same move %s (%.2f)",
204 location_to_string(new_move), new_move_value);
205
206 sgfAddComment(node, buf);
207 sgffile_add_debuginfo(node, 0.0);
208 }
209
210 /* Finally, do play the move from the file. */
211 play_move(old_move, color);
212}
213
214
215/*
216 * Local Variables:
217 * tab-width: 8
218 * c-basic-offset: 2
219 * End:
220 */