Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / sgf / sgf_utils.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 - either version 3 *
11 * or (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 <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <assert.h>
28#include <ctype.h>
29
30#include "sgftree.h"
31
32/*
33 * Return the integer X move.
34 */
35
36int
37get_moveX(SGFProperty *property, int boardsize)
38{
39 int i;
40 if (strlen(property->value) < 2)
41 return -1;
42
43 i = toupper((int) property->value[1]) - 'A';
44 if (i >= boardsize)
45 return -1;
46
47 return i;
48}
49
50/*
51 * Return the integer Y move.
52 */
53
54int
55get_moveY(SGFProperty *property, int boardsize)
56{
57 int j;
58 if (strlen(property->value) < 2)
59 return -1;
60
61 j = toupper((int) property->value[0]) - 'A';
62 if (j >= boardsize)
63 return -1;
64
65 return j;
66}
67
68
69/* Fills (*i, *j) from the property value, in GNU Go co-ords.
70 * Note that GNU Go uses different conventions from sgf for
71 * co-ordinates been called.
72 *
73 * Returns 1 for a move, 0 for a pass.
74 */
75
76int
77get_moveXY(SGFProperty *property, int *i, int *j, int boardsize)
78{
79 *i = get_moveX(property, boardsize);
80 *j = get_moveY(property, boardsize);
81
82 if (*i == -1 && *j == -1)
83 return 0;
84
85 return 1;
86}
87
88
89/*
90 * Debugging function to print properties as they are traversed.
91 */
92
93int
94show_sgf_properties(SGFNode *node)
95{
96 SGFProperty *sgf_prop;
97 int propcount;
98
99 propcount = 0;
100
101 printf("P: ");
102 if (!node->props) {
103 printf("None\n");
104 return propcount;
105 }
106 else {
107 sgf_prop = node->props;
108 while (sgf_prop) {
109 printf("%c%c ", sgf_prop->name & 0x00FF, (sgf_prop->name & 0xFF00)>>8);
110 sgf_prop = sgf_prop->next;
111 propcount++;
112 }
113
114 printf("(%d) ", propcount);
115 if (node->next)
116 printf("n");
117 if (node->child)
118 printf("c");
119 printf("\n");
120 }
121
122 return propcount;
123}
124
125
126/*
127 * Recursively traverse each node showing all properties.
128 */
129
130int
131show_sgf_tree(SGFNode *node)
132{
133 int n = 0; /* number of nodes */
134
135 n++;
136 show_sgf_properties(node);
137
138 /* must search depth first- siblings are equal! */
139 if (node->child)
140 n += show_sgf_tree(node->child);
141
142 if (node->next)
143 n += show_sgf_tree(node->next);
144
145 return n;
146}
147
148
149/*
150 * Determine if a node has a mark property in it.
151 */
152
153int
154is_markup_node(SGFNode *node)
155{
156 SGFProperty *sgf_prop;
157
158 /* If the node has no properties, there's nothing to do.
159 This should have been checked by the caller, but it can't hurt. */
160 if (!node->props)
161 return 0;
162
163 sgf_prop = node->props;
164 while (sgf_prop) {
165 switch (sgf_prop->name) {
166 case SGFCR:
167 case SGFSQ: /* Square */
168 case SGFTR: /* Triangle */
169 case SGFMA: /* Mark */
170 case SGFBM: /* bad move */
171 case SGFDO: /* doubtful move */
172 case SGFIT: /* interesting move */
173 case SGFTE: /* good move */
174 return 1;
175 break;
176 default:
177 break;
178 }
179 sgf_prop = sgf_prop->next;
180 }
181
182 /* No markup property found. */
183 return 0;
184}
185
186
187/*
188 * Determine if the node has a move in it.
189 */
190
191int
192is_move_node(SGFNode *node)
193{
194 SGFProperty *sgf_prop;
195
196 /* If the node has no properties, there's nothing to do.
197 This should have been checked by the caller, but it can't hurt. */
198 if (!node->props)
199 return 0;
200
201 sgf_prop = node->props;
202 while (sgf_prop) {
203 switch (sgf_prop->name) {
204 case SGFB:
205 case SGFW:
206 return 1;
207 break;
208 default:
209 break;
210 }
211 sgf_prop = sgf_prop->next;
212 }
213
214 return 0;
215}
216
217
218/*
219 * Determine if the node has a pass move in it.
220 */
221
222int
223is_pass_node(SGFNode *node, int boardsize)
224{
225 SGFProperty *sgf_prop;
226 int i, j;
227
228 /* If the node has no properties, there's nothing to do.
229 This should have been checked by the caller, but it can't hurt. */
230 if (!node->props)
231 return 0;
232
233 sgf_prop = node->props;
234 while (sgf_prop) {
235 switch (sgf_prop->name) {
236 case SGFB:
237 case SGFW:
238 return !get_moveXY(sgf_prop, &i, &j, boardsize);
239 break;
240 default:
241 break;
242 }
243 sgf_prop = sgf_prop->next;
244 }
245
246 return 0;
247}
248
249
250/*
251 * Determine whose move is in the node.
252 */
253
254int
255find_move(SGFNode *node)
256{
257 SGFProperty *sgf_prop;
258
259 /* If the node has no properties, there's nothing to do.
260 This should have been checked by the caller, but it can't hurt. */
261 if (!node->props)
262 return 0;
263
264 sgf_prop = node->props;
265 while (sgf_prop) {
266 switch (sgf_prop->name) {
267 case SGFB:
268 return BLACK;
269 break;
270 case SGFW:
271 return WHITE;
272 break;
273 default:
274 break;
275 }
276 sgf_prop = sgf_prop->next;
277 }
278
279 return EMPTY;
280}
281
282
283/*
284 * Local Variables:
285 * tab-width: 8
286 * c-basic-offset: 2
287 * End:
288 */