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 <assert.h>
25 
26 #include "gg_utils.h"
27 #include "sgftree.h"
28 
29 void
sgftree_clear(SGFTree * tree)30 sgftree_clear(SGFTree *tree)
31 {
32   tree->root = NULL;
33   tree->lastnode = NULL;
34 }
35 
36 int
sgftree_readfile(SGFTree * tree,const char * infilename)37 sgftree_readfile(SGFTree *tree, const char *infilename)
38 {
39   SGFNode *savetree = tree->root;
40 
41   tree->root = readsgffile(infilename);
42   if (tree->root == NULL) {
43     tree->root = savetree;
44     return 0;
45   }
46 
47   sgfFreeNode(savetree);
48   tree->lastnode = NULL;
49   return 1;
50 }
51 
52 
53 /* Go back one node in the tree. If lastnode is NULL, go to the last
54  * node (the one in main variant which has no children).
55  */
56 
57 int
sgftreeBack(SGFTree * tree)58 sgftreeBack(SGFTree *tree)
59 {
60   if (tree->lastnode) {
61     if (tree->lastnode->parent)
62       tree->lastnode = tree->lastnode->parent;
63     else
64       return 0;
65   }
66   else
67     while (sgftreeForward(tree))
68       ;
69 
70   return 1;
71 }
72 
73 
74 /* Go forward one node in the tree. If lastnode is NULL, go to the
75  * tree root.
76  */
77 
78 int
sgftreeForward(SGFTree * tree)79 sgftreeForward(SGFTree *tree)
80 {
81   if (tree->lastnode) {
82     if (tree->lastnode->child)
83       tree->lastnode = tree->lastnode->child;
84     else
85       return 0;
86   }
87   else
88     tree->lastnode = tree->root;
89 
90   return 1;
91 }
92 
93 
94 /* ================================================================ */
95 /*                        High level functions                      */
96 /* ================================================================ */
97 
98 /*
99  * Returns the node to modify. Use lastnode if available, otherwise
100  * follow the main variation to the current end of the game.
101  */
102 
103 SGFNode *
sgftreeNodeCheck(SGFTree * tree)104 sgftreeNodeCheck(SGFTree *tree)
105 {
106   SGFNode *node = NULL;
107   assert(tree->root);
108 
109   if (tree->lastnode)
110     node = tree->lastnode;
111   else {
112     node = tree->root;
113     while (node->child)
114       node = node->child;
115   }
116 
117   return node;
118 }
119 
120 
121 /*
122  * Add a stone to the current or the given node.
123  * Return the node where the stone was added.
124  */
125 
126 void
sgftreeAddStone(SGFTree * tree,int color,int movex,int movey)127 sgftreeAddStone(SGFTree *tree, int color, int movex, int movey)
128 {
129   SGFNode *node = sgftreeNodeCheck(tree);
130   sgfAddStone(node, color, movex, movey);
131 }
132 
133 
134 /*
135  * Add a move to the gametree.
136  */
137 
138 void
sgftreeAddPlay(SGFTree * tree,int color,int movex,int movey)139 sgftreeAddPlay(SGFTree *tree, int color, int movex, int movey)
140 {
141   SGFNode *node = sgftreeNodeCheck(tree);
142   tree->lastnode = sgfAddPlay(node, color, movex, movey);
143 }
144 
145 
146 /*
147  * Add a move to the gametree. New variations are added after the old
148  * ones rather than before.
149  */
150 
151 void
sgftreeAddPlayLast(SGFTree * tree,int color,int movex,int movey)152 sgftreeAddPlayLast(SGFTree *tree, int color, int movex, int movey)
153 {
154   SGFNode *node = sgftreeNodeCheck(tree);
155   tree->lastnode = sgfAddPlayLast(node, color, movex, movey);
156 }
157 
158 
159 void
sgftreeCreateHeaderNode(SGFTree * tree,int boardsize,float komi,int handicap)160 sgftreeCreateHeaderNode(SGFTree *tree, int boardsize, float komi, int handicap)
161 {
162   SGFNode *root = sgfNewNode();
163 
164   sgfAddPropertyInt(root, "SZ", boardsize);
165   sgfAddPropertyFloat(root, "KM", komi);
166   sgfAddPropertyInt(root, "HA", handicap);
167   tree->root = root;
168   tree->lastnode = root;
169 }
170 
171 
172 /*
173  * Add a comment to a gametree.
174  */
175 
176 void
sgftreeAddComment(SGFTree * tree,const char * comment)177 sgftreeAddComment(SGFTree *tree, const char *comment)
178 {
179   SGFNode *node;
180   assert(tree && tree->root);
181 
182   node = sgftreeNodeCheck(tree);
183   sgfAddComment(node, comment);
184 }
185 
186 
187 /*
188  * Place text on the board at position (i, j).
189  */
190 
191 void
sgftreeBoardText(SGFTree * tree,int i,int j,const char * text)192 sgftreeBoardText(SGFTree *tree, int i, int j, const char *text)
193 {
194   SGFNode *node;
195   assert(tree->root);
196 
197   node = sgftreeNodeCheck(tree);
198   sgfBoardText(node, i, j, text);
199 }
200 
201 
202 /*
203  * Place a character on the board at position (i, j).
204  */
205 
206 void
sgftreeBoardChar(SGFTree * tree,int i,int j,char c)207 sgftreeBoardChar(SGFTree *tree, int i, int j, char c)
208 {
209   SGFNode *node;
210   assert(tree->root);
211 
212   node = sgftreeNodeCheck(tree);
213   sgfBoardChar(node, i, j, c);
214 }
215 
216 
217 /*
218  * Place a number on the board at position (i, j).
219  */
220 
221 void
sgftreeBoardNumber(SGFTree * tree,int i,int j,int number)222 sgftreeBoardNumber(SGFTree *tree, int i, int j, int number)
223 {
224   SGFNode *node = sgftreeNodeCheck(tree);
225   sgfBoardNumber(node, i, j, number);
226 }
227 
228 
229 /*
230  * Place a circle mark on the board at position (i, j).
231  */
232 
233 void
sgftreeTriangle(SGFTree * tree,int i,int j)234 sgftreeTriangle(SGFTree *tree, int i, int j)
235 {
236   SGFNode *node = sgftreeNodeCheck(tree);
237   sgfTriangle(node, i, j);
238 }
239 
240 
241 /*
242  * Place a circle mark on the board at position (i, j).
243  */
244 
245 void
sgftreeCircle(SGFTree * tree,int i,int j)246 sgftreeCircle(SGFTree *tree, int i, int j)
247 {
248   SGFNode *node = sgftreeNodeCheck(tree);
249   sgfCircle(node, i, j);
250 }
251 
252 
253 /*
254  * Place a square mark on the board at position (i, j).
255  */
256 
257 void
sgftreeSquare(SGFTree * tree,int i,int j)258 sgftreeSquare(SGFTree *tree, int i, int j)
259 {
260   SGFNode *node = sgftreeNodeCheck(tree);
261   sgfSquare(node, i, j);
262 }
263 
264 
265 /*
266  * Place a (square) mark on the board at position (i, j).
267  */
268 
269 void
sgftreeMark(SGFTree * tree,int i,int j)270 sgftreeMark(SGFTree *tree, int i, int j)
271 {
272   SGFNode *node = sgftreeNodeCheck(tree);
273   sgfMark(node, i, j);
274 }
275 
276 
277 /*
278  * Start a new variant.
279  */
280 
281 void
sgftreeStartVariant(SGFTree * tree)282 sgftreeStartVariant(SGFTree *tree)
283 {
284   SGFNode *node = sgftreeNodeCheck(tree);
285   tree->lastnode = sgfStartVariant(node);
286 }
287 
288 
289 /*
290  * Start a new variant as first child.
291  */
292 
293 void
sgftreeStartVariantFirst(SGFTree * tree)294 sgftreeStartVariantFirst(SGFTree *tree)
295 {
296   SGFNode *node = sgftreeNodeCheck(tree);
297   tree->lastnode = sgfStartVariantFirst(node);
298 }
299 
300 
301 /*
302  * Write result of the game to the game tree.
303  */
304 
305 void
sgftreeWriteResult(SGFTree * tree,float score,int overwrite)306 sgftreeWriteResult(SGFTree *tree, float score, int overwrite)
307 {
308   assert(tree->root);
309 
310   sgfWriteResult(tree->root, score, overwrite);
311 }
312 
313 
314 void
sgftreeSetLastNode(SGFTree * tree,SGFNode * last_node)315 sgftreeSetLastNode(SGFTree *tree, SGFNode *last_node)
316 {
317   tree->lastnode = last_node;
318 }
319 
320 
321 /*
322  * Local Variables:
323  * tab-width: 8
324  * c-basic-offset: 2
325  * End:
326  */
327 
328