Before starting to tinker, ran clang-format on files that seem like relevant starting...
[sgk-go] / interface / play_gmp.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#include "liberty.h"
26
c150f57c 27#include <assert.h>
7eeb782e
AT
28#include <stdio.h>
29#include <stdlib.h>
7eeb782e 30
c150f57c 31#include "gg_utils.h"
7eeb782e 32#include "gmp.h"
c150f57c 33#include "interface.h"
7eeb782e 34#include "sgftree.h"
7eeb782e
AT
35
36/* --------------------------------------------------------------*/
37/* Play a game against a go-modem-protocol (GMP) client. */
38/* --------------------------------------------------------------*/
c150f57c 39void play_gmp(Gameinfo* gameinfo, int simplified)
7eeb782e 40{
c150f57c
AT
41 SGFTree sgftree;
42
43 Gmp* ge;
44 GmpResult message;
45 const char* error;
7eeb782e 46
c150f57c
AT
47 int i, j;
48 int passes = 0; /* two passes and its over */
49 int to_move; /* who's turn is next ? */
7eeb782e 50
c150f57c
AT
51 int mycolor = -1; /* who has which color */
52 int yourcolor;
7eeb782e 53
c150f57c
AT
54 if (gameinfo->computer_player == WHITE)
55 mycolor = 1;
56 else if (gameinfo->computer_player == BLACK)
57 mycolor = 0;
7eeb782e 58
c150f57c
AT
59 sgftree_clear(&sgftree);
60 sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap);
7eeb782e 61
c150f57c
AT
62 ge = gmp_create(0, 1);
63 TRACE("board size=%d\n", board_size);
7eeb782e 64
c150f57c 65 /*
7eeb782e
AT
66 * The specification of the go modem protocol doesn't even discuss
67 * komi. So we have to guess the komi. If the komi is set on the
68 * command line, keep it. Otherwise, its value will be 0.0 and we
69 * use 5.5 in an even game, 0.5 otherwise.
70 */
c150f57c
AT
71 if (komi == 0.0) {
72 if (gameinfo->handicap == 0)
73 komi = 5.5;
74 else
75 komi = 0.5;
76 }
7eeb782e 77
c150f57c
AT
78 if (!simplified) {
79 /* Leave all the -1's so the client can negotiate the game parameters. */
80 if (chinese_rules)
81 gmp_startGame(ge, -1, -1, 5.5, -1, mycolor, 0);
82 else
83 gmp_startGame(ge, -1, -1, 5.5, 0, mycolor, 0);
84 } else {
85 gmp_startGame(ge, board_size, gameinfo->handicap,
86 komi, chinese_rules, mycolor, 1);
87 }
88
89 do {
90 message = gmp_check(ge, 1, NULL, NULL, &error);
91 } while (message == gmp_nothing || message == gmp_reset);
92
93 if (message == gmp_err) {
94 fprintf(stderr, "gnugo-gmp: Error \"%s\" occurred.\n", error);
95 exit(EXIT_FAILURE);
96 } else if (message != gmp_newGame) {
97 fprintf(stderr, "gnugo-gmp: Expecting a newGame, got %s\n",
98 gmp_resultString(message));
99 exit(EXIT_FAILURE);
100 }
101
102 gameinfo->handicap = gmp_handicap(ge);
103 if (!check_boardsize(gmp_size(ge), stderr))
104 exit(EXIT_FAILURE);
105
106 gnugo_clear_board(gmp_size(ge));
107
108 /* Let's pretend GMP knows about komi in case something will ever change. */
109 komi = gmp_komi(ge);
7eeb782e
AT
110
111#if ORACLE
c150f57c
AT
112 if (metamachine && oracle_exists)
113 oracle_clear_board(board_size);
7eeb782e
AT
114#endif
115
c150f57c
AT
116 sgfOverwritePropertyInt(sgftree.root, "SZ", board_size);
117
118 TRACE("size=%d, handicap=%d, komi=%f\n", board_size,
119 gameinfo->handicap, komi);
7eeb782e 120
c150f57c
AT
121 if (gameinfo->handicap)
122 to_move = WHITE;
123 else
124 to_move = BLACK;
125
126 if (gmp_iAmWhite(ge)) {
127 mycolor = WHITE; /* computer white */
128 yourcolor = BLACK; /* human black */
129 } else {
130 mycolor = BLACK;
131 yourcolor = WHITE;
7eeb782e 132 }
c150f57c
AT
133
134 gameinfo->computer_player = mycolor;
135 sgf_write_header(sgftree.root, 1, get_random_seed(), komi,
136 gameinfo->handicap, get_level(), chinese_rules);
137 gameinfo->handicap = gnugo_sethand(gameinfo->handicap, sgftree.root);
138 sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap);
139
140 /* main GMP loop */
141 while (passes < 2) {
142
143 if (to_move == yourcolor) {
144 int move;
145 /* Get opponent's move from gmp client. */
146 message = gmp_check(ge, 1, &j, &i, &error);
147
148 if (message == gmp_err) {
149 fprintf(stderr, "GNU Go: Sorry, error from gmp client\n");
150 sgftreeAddComment(&sgftree, "got error from gmp client");
151 sgffile_output(&sgftree);
152 return;
153 }
154
155 if (message == gmp_undo) {
156 int k;
157 assert(j > 0);
158
159 for (k = 0; k < j; k++) {
160 if (!undo_move(1)) {
161 fprintf(stderr, "GNU Go: play_gmp UNDO: can't undo %d moves\n",
162 j - k);
163 break;
164 }
165 sgftreeAddComment(&sgftree, "undone");
166 sgftreeBack(&sgftree);
167 to_move = OTHER_COLOR(to_move);
168 }
169 continue;
170 }
171
172 if (message == gmp_pass) {
173 passes++;
174 move = PASS_MOVE;
175 } else {
176 passes = 0;
177 move = POS(i, j);
178 }
179
180 TRACE("\nyour move: %1m\n\n", move);
181 sgftreeAddPlay(&sgftree, to_move, I(move), J(move));
182 gnugo_play_move(move, yourcolor);
183 sgffile_output(&sgftree);
184
185 } else {
186 /* Generate my next move. */
187 float move_value;
188 int move;
189 if (autolevel_on)
190 adjust_level_offset(mycolor);
191 move = genmove(mycolor, &move_value, NULL);
192 gnugo_play_move(move, mycolor);
193 sgffile_add_debuginfo(sgftree.lastnode, move_value);
194
195 if (is_pass(move)) {
196 /* pass */
197 sgftreeAddPlay(&sgftree, to_move, -1, -1);
198 gmp_sendPass(ge);
199 ++passes;
200 } else {
201 /* not pass */
202 sgftreeAddPlay(&sgftree, to_move, I(move), J(move));
203 gmp_sendMove(ge, J(move), I(move));
204 passes = 0;
205 TRACE("\nmy move: %1m\n\n", move);
206 }
207 sgffile_add_debuginfo(sgftree.lastnode, 0.0);
208 sgffile_output(&sgftree);
209 }
210
211 to_move = OTHER_COLOR(to_move);
7eeb782e 212 }
c150f57c
AT
213
214 /* two passes: game over */
215 gmp_sendPass(ge);
216
217 if (!quiet)
218 fprintf(stderr, "Game over - waiting for client to shut us down\n");
219 who_wins(mycolor, stderr);
220
221 if (showtime) {
222 gprintf("\nSLOWEST MOVE: %d at %1m ", slowest_movenum, slowest_move);
223 fprintf(stderr, "(%.2f seconds)\n", slowest_time);
224 fprintf(stderr, "\nAVERAGE TIME: %.2f seconds per move\n",
225 total_time / movenum);
226 fprintf(stderr, "\nTOTAL TIME: %.2f seconds\n",
227 total_time);
228 }
229
230 /* play_gmp() does not return to main(), therefore the score
7eeb782e
AT
231 * writing code is here.
232 */
c150f57c
AT
233 {
234 float score = gnugo_estimate_score(NULL, NULL);
235 sgfWriteResult(sgftree.root, score, 1);
236 }
237 sgffile_output(&sgftree);
238
239 if (!simplified) {
240 /* We hang around here until cgoban asks us to go, since
7eeb782e
AT
241 * sometimes cgoban crashes if we exit first.
242 *
243 * FIXME: Check if this is still needed. I made it dependand on
244 * `simplifed' just to avoid changes in GMP mode.
245 */
c150f57c
AT
246 while (1) {
247 message = gmp_check(ge, 1, &j, &i, &error);
248 if (!quiet)
249 fprintf(stderr, "Message %d from gmp\n", message);
250 if (message == gmp_err)
251 break;
252 }
7eeb782e 253 }
7eeb782e
AT
254
255#if ORACLE
c150f57c
AT
256 if (metamachine && oracle_exists)
257 dismiss_oracle();
7eeb782e
AT
258#endif
259
c150f57c
AT
260 if (!quiet)
261 fprintf(stderr, "gnugo going down\n");
7eeb782e
AT
262}
263
264/*
265 * Local Variables:
c150f57c
AT
266 * tab-width: 4
267 * c-basic-offset: 4
7eeb782e
AT
268 * End:
269 */