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