ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Games-Go-SGF-Grove/Grove.pm
Revision: 1.3
Committed: Sun Jul 20 19:54:00 2008 UTC (15 years, 11 months ago) by root
Branch: MAIN
Changes since 1.2: +20 -15 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.2 Games::Go::SGF::Grove - SGF the Perl way
4 root 1.1
5     =head1 SYNOPSIS
6    
7     use Games::Go::SGF::Grove;
8 root 1.2
9     $game = load_sgf $path;
10     save_sgf $path, $game;
11    
12     $game = decode_sgf $sgf_data;
13     $sgf_data = encode_sgf $game;
14 root 1.1
15     =head1 DESCRIPTION
16    
17 root 1.2 This module loads and saves Go SGF files. Unlike other modules, it doesn't
18     build a very fancy data structure with lot's of java-like accessors
19     but instead returns a simple Perl data structure you can inspect with
20     Data::Dumper and modify easily. The structure follows the SGF file format
21     very closely.
22    
23     The SGF format is documented here: L<http://www.red-bean.com/sgf/>.
24    
25     All the functions below use a common data format and throw exceptions on
26     any errors.
27 root 1.1
28     =over 4
29    
30     =cut
31    
32     package Games::Go::SGF::Grove;
33    
34     use base Exporter;
35    
36 root 1.2 use strict;
37     no warnings;
38    
39     our $VERSION = 0.1;
40     our @EXPORT = qw(load_sgf save_sgf encode_sgf decode_sgf);
41    
42     =item $game = load_sgf $path
43    
44     Tries to read the file given by C<$path> and parses it as an SGF file,
45     returning the parsed data structure.
46    
47     =item save_sgf $path, $game
48    
49     Saves the SGF data to the specified file.
50    
51     =item $game = decode_sgf $sgf_data
52    
53     Tries to parse the given string into a Pelr data structure and returns it.
54    
55     =item $sgf_data = encode_sgf $game
56    
57     Takes a Perl data structure and serialises it into an SGF file. Anything
58     stored in the structure that isn't understood by this module will be
59     silently ignored.
60    
61     =cut
62    
63     sub decode_sgf($) {
64     my ($sgf_data) = @_;
65 root 1.3
66     Games::Go::SGF::Grove::Parser::->new->parse ($sgf_data)
67 root 1.2 }
68    
69     sub encode_sgf($) {
70     my ($game) = @_;
71     }
72    
73     sub load_sgf($) {
74     my ($path) = @_;
75    
76     open my $fh, "<:perlio", $path
77     or die "$path: $!";
78    
79     local $/;
80 root 1.3 decode_sgf <$fh>
81 root 1.2 }
82    
83     sub save_sgf($$) {
84     my ($path, $game) = @_;
85    
86     open my $fh, "<:perlio", $path
87     or die "$path: $!";
88    
89     print $fh encode_sgf $game;
90     }
91    
92     =back
93    
94     =head2 The Game Data structure
95    
96     The SGF game is represented by a linked Perl data structure consisting of
97     unblessed hashes and arrays.
98    
99 root 1.3 The game itself is a hash reference #TODO#
100 root 1.2
101     =cut
102    
103 root 1.1
104 root 1.2 package Games::Go::SGF::Grove::Parser;
105 root 1.1
106     no warnings;
107 root 1.2 use strict;
108 root 1.1
109     my $ws = qr{[\x00-\x20]*}s;
110     my $property; # property => propertyinfo
111    
112     sub new {
113     my $class = shift;
114     bless { @_ }, $class;
115     }
116    
117     sub error {
118     my ($self, $error) = @_;
119    
120     my $tail = substr $self->{sgf}, pos $self->{sgf}, 32;
121     $tail =~ s/[\x00-\x1f]+/ /g;
122    
123     die "$error (at '$tail')";
124     }
125    
126     sub parse {
127     my ($self, $sgf) = @_;
128    
129     # correct lines
130     if ($sgf =~ /[^\015\012]\015/) {
131     $sgf =~ s/\015\012?/\n/g;
132     } else {
133     $sgf =~ s/\012\015?/\n/g;
134     }
135    
136     $self->{sgf} = $sgf;
137    
138     $self->{FF} = 1;
139     $self->{CA} = 'ISO-8859-1';
140     $self->{GM} = 1;
141    
142     my @trees;
143    
144     eval {
145     while ($self->{sgf} =~ /\G$ws(?=\()/sgoc) {
146     push @trees, $self->GameTree;
147     }
148     };
149    
150     die $@ if $@;
151    
152     \@trees
153     }
154    
155     sub GameTree {
156     my ($self) = @_;
157    
158     $self->{sgf} =~ /\G$ws\(/sgoc
159     or $self->error ("GameTree does not start with '('");
160    
161     my $nodes = $self->Sequence;
162    
163     while ($self->{sgf} =~ /\G$ws(?=\()/sgoc) {
164     push @{$nodes->[-1]{children}}, $self->GameTree;
165     }
166     $self->{sgf} =~ /\G$ws\)/sgoc
167     or $self->error ("GameTree does not end with ')'");
168    
169     $nodes
170     }
171    
172     sub Sequence {
173     my ($self) = @_;
174    
175     my (@nodes, $node, $name, $value);
176    
177     while ($self->{sgf} =~ /\G$ws;/goc) {
178     push @nodes, $node = {};
179     # Node
180     while ($self->{sgf} =~ /\G$ws([A-Z]+)/goc) {
181     # Property
182     $name = $1;
183    
184     while ($self->{sgf} =~ /\G$ws\[((?:[^\\\]]*|\\.)*)\]/sgoc) {
185     # PropValue
186     $value = $1;
187     if (defined (my $prop = $property->{$name})) {
188     my (@val) = $prop->{in}->($self, $value, $prop);
189    
190     if ($prop->{is_list}) {
191     push @{$node->{$name}}, @val
192     } else {
193     $node->{$name} = $val[0];
194     }
195     } else {
196 root 1.3 #warn "unknown property '$name', will be saved unchanged.";#d#
197 root 1.1 $node->{$name} = $value;
198     }
199     }
200     }
201     }
202    
203     \@nodes
204     }
205    
206     #############################################################################
207    
208     =head2 Property Type Structure
209    
210     A property type is a hash like this:
211    
212     {
213     name => "SQ",
214     group => {
215     name => "Markup properties",
216     restrictions => "CR, MA, SL, SQ and TR points must be unique, ...",
217     },
218     related => "TR, CR, LB, SL, AR, MA, LN",
219     function => "Marks the given points with a square.\nPoints must be unique.",
220     propertytype => "-",
221     propvalue => "list of point"
222     is_list => 1,
223     }
224    
225     =cut
226    
227    
228     {
229 root 1.3 use Encode ();
230    
231 root 1.1 my ($group, $name, $value, $prop);
232    
233     my (%char2coord, %coord2char);
234    
235     {
236     my @coord = ("a" .. "z", "A" .. "Z");
237     for (0.. $#coord) {
238     $char2coord{ $coord[$_] } = $_;
239     $coord2char{ $_ } = $coord[$_];
240     }
241     }
242    
243 root 1.3 sub _parsetype($);
244 root 1.1 sub _parsetype {
245     for (shift) {
246     if (s/e?list of //) {
247     $prop->{is_list} = 1;
248 root 1.3 return _parsetype $_;
249 root 1.1 } elsif (s/composed (\S+)\s+(?:':'\s+)?(\S+)//) {
250     my ($i, $o) = ($1, $2);
251 root 1.3 my ($i1, $o1, $i2, $o2) = (_parsetype $i, _parsetype $o);
252 root 1.1 return (
253     sub {
254     if ($_[1] =~ /^((?:[^\\:]+|\\.)*)(?::(.*))$/s) {
255     # or $_[0]->error ("'Compose' ($i:$o) expected, got '$_[1]'");
256     my ($l, $r) = ($1, $2);
257    
258 root 1.3 warn "$i1,$o1,$i2,$o2 ($i,$o)\n";#d#
259 root 1.1 [
260     $i1->($_[0], $l),
261     defined $r ? $i2->($_[0], $r) : undef,
262     ],
263     } else {
264 root 1.3 # yes, this is not according to standard, but let's handle it somehow anyway
265     #[ $i1->($_[0], $l) ] #d# #TODO#
266 root 1.1 }
267     },
268     sub {
269     $o1->($_[0], $_[1][0])
270     . (defined $_[1][1]
271     ? ":" . $o1->($_[0], $_[1][0])
272     : ""),
273     },
274     );
275     } elsif (s/double//) {
276     return (
277     sub {
278     $_[1] =~ /^[12]$/
279 root 1.3 or $_[0]->error ("'Double' (1|2) expected, got '$_[1]'");
280 root 1.1 $_[1]
281     },
282     sub {
283     $_[1]
284     },
285     );
286     } elsif (s/color//) {
287     return (
288     sub {
289     $_[1] =~ /^[BW]$/i
290 root 1.3 or $_[0]->error ("'Color' (B|W) expected, got '$_[1]'");
291 root 1.1 lc $_[1]
292     },
293     sub {
294     uc $_[1]
295     },
296     );
297     } elsif (s/none//) {
298     return (
299     sub {
300     $_[1] =~ /^$/i
301 root 1.3 or $_[0]->error ("'None' expected, got '$_[1]'");
302 root 1.1 undef
303     },
304     sub {
305     "",
306     },
307     );
308     } elsif (s/point// || s/move// || s/stone//) {
309     return (
310     sub {
311     if ($_[2]->{is_list}) {
312     if ($_[1] =~ /^([^:]+):(.*)$/) {
313     my ($ul, $dr) = ($1, $2);
314     my ($x1, $y1) = map $char2coord{$_}, split //, $ul;
315     my ($x2, $y2) = map $char2coord{$_}, split //, $dr;
316     my @stones;
317     for (my $d = $x1; $d < $x2; $d++) {
318     for (my $i = $y1; $i < $y2; $i++) {
319     push @stones, [$d, $i];
320     }
321     }
322     return @stones;
323     }
324     }
325     $_[1] =~ /^(.)(.)$/
326     ? [ $char2coord{$1}, $char2coord{$2} ]
327     : []
328     },
329     sub {
330     die;
331     },
332     );
333     } elsif (s/real//) {
334     return (
335     sub {
336     $_[1] =~ /^[+-]?[0-9]*\.?[0-9]*$/i
337 root 1.3 or $_[0]->error ("'Real' expected, got '$_[1]'");
338 root 1.1 $_[1]+0,
339     },
340     sub {
341     $_[1]+0,
342     },
343     );
344     } elsif (s/number//) {
345     return (
346     sub {
347     $_[1] =~ /^[+-]?[0-9]*$/i
348 root 1.3 or $_[0]->error ("'Number' expected, got '$_[1]'");
349 root 1.1 $_[1]+0,
350     },
351     sub {
352     int $_[1],
353     },
354     );
355     } elsif (s/text//) {
356     return (
357     sub {
358 root 1.3 warn "$_[0]{CA}<-CA\n";#d#
359     eval { Encode::decode $_[0]{CA}, $_[1] } || $_[1],
360 root 1.1 },
361     sub {
362     die;
363     },
364     );
365     } elsif (s/simpletext//i) {
366     return (
367     sub {
368     $_[1],
369     },
370     sub {
371     die;
372     },
373     );
374     } else {
375     die "FATAL: garbled DATA section, unknown type '$_'";
376    
377     }
378     }
379     }
380    
381     while (<DATA>) {
382     if (/^(\S+):\t(.*)/) {
383     if ($name eq "Restrictions") {
384     $group->{restrictions} = $value;
385     } elsif ($name eq "Property") {
386     $property->{$value} =
387     $prop = {
388     name => $value,
389     group => $group,
390     };
391     } elsif ($name ne "") {
392     $prop->{lc $name} = $value;
393     if ($name eq "Propvalue") {
394     ($prop->{in}, $prop->{out}) = _parsetype $value;
395     }
396     }
397     $name = $1;
398     $value = $2;
399     } elsif (/^\t\t(.*)/) {
400     $value .= "\n$1";
401     } elsif (/(\S.*)/) {
402     $group = {
403     name => $1,
404     };
405     } elsif (/^$/) {
406     # nop
407     } else {
408     die "FATAL: DATA section garbled\n";
409     }
410     }
411     }
412    
413     1;
414    
415     =head1 AUTHOR
416    
417     Marc Lehmann <schmorp@schmorp.de>
418     Robin Redeker <elmex@ta-sa.org>
419    
420     =cut
421    
422     # now node descriptions follow
423    
424     __DATA__
425     Move properties
426    
427     Property: B
428     Propvalue: move
429     Propertytype: move
430     Function: Execute a black move. This is one of the most used properties
431     in actual collections. As long as
432     the given move is syntactically correct it should be executed.
433     It doesn't matter if the move itself is illegal
434     (e.g. recapturing a ko in a Go game).
435     Have a look at how to execute a Go-move.
436     B and W properties must not be mixed within a node.
437     Related: W, KO
438    
439     Property: KO
440     Propvalue: none
441     Propertytype: move
442     Function: Execute a given move (B or W) even it's illegal. This is
443     an optional property, SGF viewers themselves should execute
444     ALL moves. It's purpose is to make it easier for other
445     applications (e.g. computer-players) to deal with illegal
446     moves. A KO property without a black or white move within
447     the same node is illegal.
448     Related: W, B
449    
450     Property: MN
451     Propvalue: number
452     Propertytype: move
453     Function: Sets the move number to the given value, i.e. a move
454     specified in this node has exactly this move-number. This
455     can be useful for variations or printing.
456     Related: B, W, FG, PM
457    
458     Property: W
459     Propvalue: move
460     Propertytype: move
461     Function: Execute a white move. This is one of the most used properties
462     in actual collections. As long as
463     the given move is syntactically correct it should be executed.
464     It doesn't matter if the move itself is illegal
465     (e.g. recapturing a ko in a Go game).
466     Have a look at how to execute a Go-move.
467     B and W properties must not be mixed within a node.
468     Related: B, KO
469    
470     Setup properties
471     Restrictions: AB, AW and AE must have unique points, i.e. it is illegal to place different colors on the same point within one node.
472     AB, AW and AE values which don't change the board, e.g. placing a black stone with AB[] over a black stone that's already there, is bad style. Applications may want to delete these values and issue a warning.
473    
474     Property: AB
475     Propvalue: list of stone
476     Propertytype: setup
477     Function: Add black stones to the board. This can be used to set up
478     positions or problems. Adding is done by 'overwriting' the
479     given point with black stones. It doesn't matter what
480     was there before. Adding a stone doesn't make any prisoners
481     nor any other captures (e.g. suicide). Thus it's possible
482     to create illegal board positions.
483     Points used in stone type must be unique.
484     Related: AW, AE, PL
485    
486     Property: AE
487     Propvalue: list of point
488     Propertytype: setup
489     Function: Clear the given points on the board. This can be used
490     to set up positions or problems. Clearing is done by
491     'overwriting' the given points, so that they contain no
492     stones. It doesn't matter what was there before.
493     Clearing doesn't count as taking prisoners.
494     Points must be unique.
495     Related: AB, AW, PL
496    
497     Property: AW
498     Propvalue: list of stone
499     Propertytype: setup
500     Function: Add white stones to the board. This can be used to set up
501     positions or problems. Adding is done by 'overwriting' the
502     given points with white stones. It doesn't matter what
503     was there before. Adding a stone doesn't make any prisoners
504     nor any other captures (e.g. suicide). Thus it's possible
505     to create illegal board positions.
506     Points used in stone type must be unique.
507     Related: AB, AE, PL
508    
509     Property: PL
510     Propvalue: color
511     Propertytype: setup
512     Function: PL tells whose turn it is to play. This can be used when
513     setting up positions or problems.
514     Related: AE, AB, AW
515    
516     Node annotation properties
517    
518     Property: C
519     Propvalue: text
520     Propertytype: -
521     Function: Provides a comment text for the given node. The purpose of
522     providing both a node name and a comment is to have a short
523     identifier like "doesn't work" or "Dia. 15" that can be
524     displayed directly with the properties of the node, even if
525     the comment is turned off or shown in a separate window.
526     See text-type for more info.
527     Related: N, ST, V, UC, DM, HO
528    
529     Property: DM
530     Propvalue: double
531     Propertytype: -
532     Function: The position is even. SGF viewers should display a
533     message. This property may indicate main variations in
534     opening libraries (joseki) too. Thus DM[2] indicates an
535     even result for both players and that this is a main
536     variation of this joseki/opening.
537     This property must not be mixed with UC, GB or GW
538     within a node.
539     Related: UC, GW, GB
540    
541     Property: GB
542     Propvalue: double
543     Propertytype: -
544     Function: Something good for black. SGF viewers should display a
545     message. The property is not related to any specific place
546     on the board, but marks the whole node instead.
547     GB must not be mixed with GW, DM or UC within a node.
548     Related: GW, C, UC, DM
549    
550     Property: GW
551     Propvalue: double
552     Propertytype: -
553     Function: Something good for white. SGF viewers should display a
554     message. The property is not related to any specific place
555     on the board, but marks the whole node instead.
556     GW must not be mixed with GB, DM or UC within a node.
557     Related: GB, C, UC, DM
558    
559     Property: HO
560     Propvalue: double
561     Propertytype: -
562     Function: Node is a 'hotspot', i.e. something interesting (e.g.
563     node contains a game-deciding move).
564     SGF viewers should display a message.
565     The property is not related to any specific place
566     on the board, but marks the whole node instead.
567     Sophisticated applications could implement the navigation
568     command next/previous hotspot.
569     Related: GB, GW, C, UC, DM
570    
571     Property: N
572     Propvalue: simpletext
573     Propertytype: -
574     Function: Provides a name for the node. For more info have a look at
575     the C-property.
576     Related: C, ST, V
577    
578     Property: UC
579     Propvalue: double
580     Propertytype: -
581     Function: The position is unclear. SGF viewers should display a
582     message. This property must not be mixed with DM, GB or GW
583     within a node.
584     Related: DM, GW, GB
585    
586     Property: V
587     Propvalue: real
588     Propertytype: -
589     Function: Define a value for the node. Positive values are good for
590     black, negative values are good for white.
591     The interpretation of particular values is game-specific.
592     In Go, this is the estimated score.
593     Related: C, N, RE
594    
595     Move annotation properties
596     Restrictions: Move annotation properties without a move (B[] or W[]) within the same node are senseless and therefore illegal. Applications should delete such properties and issue a warning.
597     BM, TE, DO and IT are mutual exclusive, i.e. they must not be mixed within a single node.
598    
599     Property: BM
600     Propvalue: double
601     Propertytype: move
602     Function: The played move is bad.
603     Viewers should display a message.
604     Related: TE, DO, IT
605    
606     Property: DO
607     Propvalue: none
608     Propertytype: move
609     Function: The played move is doubtful.
610     Viewers should display a message.
611     Related: BM, TE, IT
612    
613     Property: IT
614     Propvalue: none
615     Propertytype: move
616     Function: The played move is interesting.
617     Viewers should display a message.
618     Related: BM, DO, TE
619    
620     Property: TE
621     Propvalue: double
622     Propertytype: move
623     Function: The played move is a tesuji (good move).
624     Viewers should display a message.
625     Related: BM, DO, IT
626    
627     Markup properties
628     Restrictions: CR, MA, SL, SQ and TR points must be unique, i.e. it's illegal to have two or more of these markups on the same point within a node.
629    
630     Property: AR
631     Propvalue: list of composed point point
632     Propertytype: -
633     Function: Viewers should draw an arrow pointing FROM the first point
634     TO the second point.
635     It's illegal to specify the same arrow twice,
636     e.g. (Go) AR[aa:bb][aa:bb]. Different arrows may have the same
637     starting or ending point though.
638     It's illegal to specify a one point arrow, e.g. AR[cc:cc]
639     as it's impossible to tell into which direction the
640     arrow points.
641     Related: TR, CR, LB, SL, MA, SQ, LN
642    
643     Property: CR
644     Propvalue: list of point
645     Propertytype: -
646     Function: Marks the given points with a circle.
647     Points must be unique.
648     Related: TR, MA, LB, SL, AR, SQ, LN
649    
650     Property: DD
651     Propvalue: elist of point
652     Propertytype: inherit
653     Function: Dim (grey out) the given points.
654     DD[] clears any setting, i.e. it undims everything.
655     Related: VW
656    
657     Property: LB
658     Propvalue: list of composed point simpletext
659     Propertytype: -
660     Function: Writes the given text on the board. The text should be
661     centered around the given point. Note: there's no longer
662     a restriction to the length of the text to be displayed.
663     Have a look at the FF4 example file on possibilities
664     to display long labels (pictures five and six).
665     Points must be unique.
666     Related: TR, CR, MA, SL, AR, SQ, LN
667    
668     Property: LN
669     Propvalue: list of composed point point
670     Propertytype: -
671     Function: Applications should draw a simple line form one point
672     to the other.
673     It's illegal to specify the same line twice,
674     e.g. (Go) LN[aa:bb][aa:bb]. Different lines may have the same
675     starting or ending point though.
676     It's illegal to specify a one point line, e.g. LN[cc:cc].
677     Related: TR, CR, MA, SL, AR, SQ, LB
678    
679    
680     Property: MA
681     Propvalue: list of point
682     Propertytype: -
683     Function: Marks the given points with an 'X'.
684     Points must be unique.
685     Related: TR, CR, LB, SL, AR, SQ, LN
686    
687     Property: SL
688     Propvalue: list of point
689     Propertytype: -
690     Function: Selected points. Type of markup unknown
691     (though SGB inverts the colors of the given points).
692     Points must be unique.
693     Related: TR, CR, LB, MA, AR, LN
694    
695     Property: SQ
696     Propvalue: list of point
697     Propertytype: -
698     Function: Marks the given points with a square.
699     Points must be unique.
700     Related: TR, CR, LB, SL, AR, MA, LN
701    
702     Property: TR
703     Propvalue: list of point
704     Propertytype: -
705     Function: Marks the given points with a triangle.
706     Points must be unique.
707     Related: MA, CR, LB, SL, AR, LN
708    
709     Root properties
710    
711     Property: AP
712     Propvalue: composed simpletext simpletext
713     Propertytype: root
714     Function: Provides the name and version number of the application used
715     to create this gametree.
716     The name should be unique and must not be changed for
717     different versions of the same program.
718     The version number itself may be of any kind, but the format
719     used must ensure that by using an ordinary string-compare,
720     one is able to tell if the version is lower or higher
721     than another version number.
722     Here's the list of known applications and their names:
723    
724     Application System Name
725     --------------------------- ----------- --------------------
726     [CGoban:1.6.2] Unix CGoban
727     [Hibiscus:2.1] Windows 95 Hibiscus Go Editor
728     [IGS:5.0] Internet Go Server
729     [Many Faces of Go:10.0] Windows 95 The Many Faces of Go
730     [MGT:?] DOS/Unix MGT
731     [NNGS:?] Unix No Name Go Server
732     [Primiview:3.0] Amiga OS3.0 Primiview
733     [SGB:?] Macintosh Smart Game Board
734     [SmartGo:1.0] Windows SmartGo
735    
736     Related: FF, GM, SZ, ST, CA
737    
738     Property: CA
739     Propvalue: simpletext
740     Propertytype: root
741     Function: Provides the used charset for SimpleText and Text type.
742     Default value is 'ISO-8859-1' aka 'Latin1'.
743     Only charset names (or their aliases) as specified in RFC 1345
744     (or updates thereof) are allowed.
745     Basically this field uses the same names as MIME messages in
746     their 'charset=' field (in Content-Type).
747     RFC's can be obtained via FTP from DS.INTERNIC.NET,
748     NIS.NSF.NET, WUARCHIVE.WUSTL.EDU, SRC.DOC.IC.AC.UK
749     or FTP.IMAG.FR.
750     Related: FF, C, text type
751    
752     Property: FF
753     Propvalue: number (range: 1-4)
754     Propertytype: root
755     Function: Defines the used file format. For difference between those
756     formats have a look at the history of SGF.
757     Default value: 1
758     Applications must be able to deal with different file formats
759     within a collection.
760     Related: GM, SZ, ST, AP, CA
761    
762     Property: GM
763     Propvalue: number (range: 1-16)
764     Propertytype: root
765     Function: Defines the type of game, which is stored in the current
766     gametree. The property should help applications
767     to reject games, they cannot handle.
768     Valid numbers are: Go = 1, Othello = 2, chess = 3,
769     Gomoku+Renju = 4, Nine Men's Morris = 5, Backgammon = 6,
770     Chinese chess = 7, Shogi = 8, Lines of Action = 9,
771     Ataxx = 10, Hex = 11, Jungle = 12, Neutron = 13,
772     Philosopher's Football = 14, Quadrature = 15, Trax = 16,
773     Tantrix = 17, Amazons = 18, Octi = 19, Gess = 20.
774     Default value: 1
775     Different kind of games may appear within a collection.
776     Related: FF, SZ, ST, AP, CA
777    
778     Property: ST
779     Propvalue: number (range: 0-3)
780     Propertytype: root
781     Function: Defines how variations should be shown (this is needed to
782     synchronize the comments with the variations). If ST is omitted
783     viewers should offer the possibility to change the mode online.
784     Basically most programs show variations in two ways:
785     as markup on the board (if the variation contains a move)
786     and/or as a list (in a separate window).
787     The style number consists two options.
788     1) show variations of successor node (children) (value: 0)
789     show variations of current node (siblings) (value: 1)
790     affects markup & list
791     2) do board markup (value: 0)
792     no (auto-) board markup (value: 2)
793     affects markup only.
794     Using no board markup could be used in problem collections
795     or if variations are marked by subsequent properties.
796     Viewers should take care, that the automatic variation
797     board markup DOESN'T overwrite any markup of other
798     properties.
799     The final number is calculated by adding the values of each
800     option. Example: 3 = no board markup/variations of current node
801     1 = board markup/variations of current node
802     Default value: 0
803     Related: C, FF, GM, SZ, AP, CA
804    
805     Property: SZ
806     Propvalue: composed number number
807     Propertytype: root
808     Function: Defines the size of the board. If only a single value
809     is given, the board is a square; with two numbers given,
810     rectangular boards are possible.
811     If a rectangular board is specified, the first number specifies
812     the number of columns, the second provides the number of rows.
813     Square boards must not be defined using the compose type
814     value: e.g. SZ[19:19] is illegal.
815     The valid range for SZ is any size greater or equal to 1x1.
816     For Go games the maximum size is limited to 52x52.
817     Default value: game specific
818     for Go: 19 (square board)
819     for Chess: 8 (square board)
820     Different board sizes may appear within a collection.
821     See move-/point-type for more info.
822     Related: FF, GM, ST, AP, CA
823    
824     Game info properties
825    
826     Property: AN
827     Propvalue: simpletext
828     Propertytype: game-info
829     Function: Provides the name of the person, who made the annotations
830     to the game.
831     Related: US, SO, CP
832    
833     Property: BR
834     Propvalue: simpletext
835     Propertytype: game-info
836     Function: Provides the rank of the black player.
837     For Go (GM[1]) the following format is recommended:
838     "..k" or "..kyu" for kyu ranks and
839     "..d" or "..dan" for dan ranks.
840     Go servers may want to add '?' for an uncertain rating and
841     '*' for an established rating.
842     Related: PB, BT, WR
843    
844     Property: BT
845     Propvalue: simpletext
846     Propertytype: game-info
847     Function: Provides the name of the black team, if game was part of a
848     team-match (e.g. China-Japan Supermatch).
849     Related: PB, PW, WT
850    
851     Property: CP
852     Propvalue: simpletext
853     Propertytype: game-info
854     Function: Any copyright information (e.g. for the annotations) should
855     be included here.
856     Related: US, SO, AN
857    
858     Property: DT
859     Propvalue: simpletext
860     Propertytype: game-info
861     Function: Provides the date when the game was played.
862     It is MANDATORY to use the ISO-standard format for DT.
863     Note: ISO format implies usage of the Gregorian calendar.
864     Syntax:
865     "YYYY-MM-DD" year (4 digits), month (2 digits), day (2 digits)
866     Do not use other separators such as "/", " ", "," or ".".
867     Partial dates are allowed:
868     "YYYY" - game was played in YYYY
869     "YYYY-MM" - game was played in YYYY, month MM
870     For games that last more than one day: separate other dates
871     by a comma (no spaces!); following shortcuts may be used:
872     "MM-DD" - if preceded by YYYY-MM-DD, YYYY-MM, MM-DD, MM or DD
873     "MM" - if preceded by YYYY-MM or MM
874     "DD" - if preceded by YYYY-MM-DD, MM-DD or DD
875     Shortcuts acquire the last preceding YYYY and MM (if
876     necessary).
877     Note: interpretation is done from left to right.
878     Examples:
879     1996-05,06 = played in May,June 1996
880     1996-05-06,07,08 = played on 6th,7th,8th May 1996
881     1996,1997 = played in 1996 and 1997
882     1996-12-27,28,1997-01-03,04 = played on 27th,28th
883     of December 1996 and on 3rd,4th January 1997
884     Note: it's recommended to use shortcuts whenever possible,
885     e.g. 1997-05-05,06 instead of 1997-05-05,1997-05-06
886     Related: EV, RO, PC, RU, RE, TM
887    
888     Property: EV
889     Propvalue: simpletext
890     Propertytype: game-info
891     Function: Provides the name of the event (e.g. tournament).
892     Additional information (e.g. final, playoff, ..)
893     shouldn't be included (see RO).
894     Related: GC, RO, DT, PC, RU, RE, TM
895    
896     Property: GN
897     Propvalue: simpletext
898     Propertytype: game-info
899     Function: Provides a name for the game. The name is used to
900     easily find games within a collection.
901     The name should therefore contain some helpful information
902     for identifying the game. 'GameName' could also be used
903     as the file-name, if a collection is split into
904     single files.
905     Related: GC, EV, DT, PC, RO, ID
906    
907     Property: GC
908     Propvalue: text
909     Propertytype: game-info
910     Function: Provides some extra information about the following game.
911     The intend of GC is to provide some background information
912     and/or to summarize the game itself.
913     Related: GN, ON, AN, CP
914    
915     Property: ON
916     Propvalue: simpletext
917     Propertytype: game-info
918     Function: Provides some information about the opening played
919     (e.g. san-ren-sei, Chinese fuseki, etc.).
920     Related: GN, GC
921    
922     Property: OT
923     Propvalue: simpletext
924     Propertytype: game-info
925     Function: Describes the method used for overtime (byo-yomi).
926     Examples: "5 mins Japanese style, 1 move / min",
927     "25 moves / 10 min".
928     Related: TM, BL, WL, OB, OW
929    
930     Property: PB
931     Propvalue: simpletext
932     Propertytype: game-info
933     Function: Provides the name of the black player.
934     Related: PW, BT, WT
935    
936     Property: PC
937     Propvalue: simpletext
938     Propertytype: game-info
939     Function: Provides the place where the games was played.
940     Related: EV, DT, RO, RU, RE, TM
941    
942     Property: PW
943     Propvalue: simpletext
944     Propertytype: game-info
945     Function: Provides the name of the white player.
946     Related: PB, BT, WT
947    
948     Property: RE
949     Propvalue: simpletext
950     Propertytype: game-info
951     Function: Provides the result of the game. It is MANDATORY to use the
952     following format:
953     "0" (zero) or "Draw" for a draw (jigo),
954     "B+" ["score"] for a black win and
955     "W+" ["score"] for a white win
956     Score is optional (some games don't have a score e.g. chess).
957     If the score is given it has to be given as a real value,
958     e.g. "B+0.5", "W+64", "B+12.5"
959     Use "B+R" or "B+Resign" and "W+R" or "W+Resign" for a win by
960     resignation. Applications must not write "Black resigns".
961     Use "B+T" or "B+Time" and "W+T" or "W+Time" for a win on time,
962     "B+F" or "B+Forfeit" and "W+F" or "W+Forfeit" for a win by
963     forfeit,
964     "Void" for no result or suspended play and
965     "?" for an unknown result.
966    
967     Related: EV, DT, PC, RO, RU, TM
968    
969     Property: RO
970     Propvalue: simpletext
971     Propertytype: game-info
972     Function: Provides round-number and type of round. It should be
973     written in the following way: RO[xx (tt)], where xx is the
974     number of the round and (tt) the type:
975     final, playoff, league, ...
976     Related: EV, DT, PC, RU, RE, TM
977    
978     Property: RU
979     Propvalue: simpletext
980     Propertytype: game-info
981     Function: Provides the used rules for this game.
982     Because there are many different rules, SGF requires
983     mandatory names only for a small set of well known rule sets.
984     Note: it's beyond the scope of this specification to give an
985     exact specification of these rule sets.
986     Mandatory names for Go (GM[1]):
987     "AGA" (rules of the American Go Association)
988     "GOE" (the Ing rules of Goe)
989     "Japanese" (the Nihon-Kiin rule set)
990     "NZ" (New Zealand rules)
991    
992     Related: EV, DT, PC, RO, RE, TM
993    
994     Property: SO
995     Propvalue: simpletext
996     Propertytype: game-info
997     Function: Provides the name of the source (e.g. book, journal, ...).
998     Related: US, AN, CP
999    
1000     Property: TM
1001     Propvalue: real
1002     Propertytype: game-info
1003     Function: Provides the time limits of the game.
1004     The time limit is given in seconds.
1005     Related: EV, DT, PC, RO, RU, RE
1006    
1007     Property: US
1008     Propvalue: simpletext
1009     Propertytype: game-info
1010     Function: Provides the name of the user (or program), who entered
1011     the game.
1012     Related: SO, AN, CP
1013    
1014     Property: WR
1015     Propvalue: simpletext
1016     Propertytype: game-info
1017     Function: Provides the rank of the white player. For recommended
1018     format see BR.
1019     Related: PW, WT, BR
1020    
1021     Property: WT
1022     Propvalue: simpletext
1023     Propertytype: game-info
1024     Function: Provide the name of the white team, if game was part of a
1025     team-match (e.g. China-Japan Supermatch).
1026     Related: PB, PW, BT
1027    
1028     Timing properties
1029    
1030     Property: BL
1031     Propvalue: real
1032     Propertytype: move
1033     Function: Time left for black, after the move was made.
1034     Value is given in seconds.
1035     Related: TM, OT, WL, OB, OW
1036    
1037     Property: OB
1038     Propvalue: number
1039     Propertytype: move
1040     Function: Number of black moves left (after the move of this node was
1041     played) to play in this byo-yomi period.
1042     Related: TM, OT, BL, WL, OW
1043    
1044     Property: OW
1045     Propvalue: number
1046     Propertytype: move
1047     Function: Number of white moves left (after the move of this node was
1048     played) to play in this byo-yomi period.
1049     Related: TM, OT, BL, WL, OB
1050    
1051     Property: WL
1052     Propvalue: real
1053     Propertytype: move
1054     Function: Time left for white after the move was made.
1055     Value is given in seconds.
1056     Related: TM, OT, BL, OB, OW
1057    
1058     Miscellaneous properties
1059    
1060     Property: FG
1061     Propvalue: composed number SimpleText
1062     Propertytype: -
1063     Function: The figure property is used to divide a game into
1064     different figures for printing: a new figure starts at the
1065     node containing a figure property.
1066     If the value is not empty then
1067     - Simpletext provides a name for the diagram
1068     - Number specifies some flags (for printing).
1069     These flags are:
1070     - coordinates on/off (value: 0/1)
1071     - diagram name on/off (value: 0/2)
1072     - list moves not shown in figure on/off (value: 0/4)
1073     Some moves can't be shown in a diagram (e.g. ko
1074     captures in Go) - these moves may be listed as text.
1075     - remove captured stones on/off (value: 0/256)
1076     'remove off' means: keep captured stones in the
1077     diagram and don't overwrite stones played earlier -
1078     this is the way diagrams are printed in books.
1079     'remove on' means: capture and remove the stones from
1080     the display - this is the usual viewer mode.
1081     This flag is specific to Go (GM[1]).
1082     - hoshi dots on/off (value: 0/512)
1083     This flag is specific to Go (GM[1]).
1084     - Ignore flags on/off (value: 32768)
1085     If on, then all other flags should be ignored and
1086     the application should use its own defaults.
1087     The final number is calculated by summing up all flag values.
1088     E.g. 515 = coordinates and diagram name off, remove captured
1089     stones, list unshown moves, hoshi dots off;
1090     257 = coordinates off, diagram name on, list unshown moves,
1091     don't remove captured stones, hoshi dots on.
1092     (this is how diagrams are printed in e.g. Go World)
1093     Note: FG combined with VW, MN and PM are mighty tools to print
1094     and compile diagrams.
1095     Related: MN, PM, VW
1096    
1097     Property: PM
1098     Propvalue: number
1099     Propertytype: inherit
1100     Function: This property is used for printing.
1101     It specifies how move numbers should be printed.
1102     0 ... don't print move numbers
1103     1 ... print move numbers as they are
1104     2 ... print 'modulo 100' move numbers
1105     This mode is usually used in books or magazines.
1106     Note: Only the first move number is calculated
1107     'modulo 100' and the obtained number is increased
1108     for each move in the diagram.
1109     E.g. A figure containing moves
1110     32-78 is printed as moves 32-78
1111     102-177 is printed as moves 2-77
1112     67-117 is printed as moves 67-117
1113     154-213 is printed as moves 54-113
1114     Default value: 1
1115     Related: MN, FG
1116    
1117     Property: VW
1118     Propvalue: elist of point
1119     Propertytype: inherit
1120     Function: View only part of the board. The points listed are
1121     visible, all other points are invisible.
1122     Note: usually the point list is given in compressed
1123     format (see 'point' type)!
1124     Points have to be unique.
1125     Have a look at the picture to get an idea.
1126     VW[] clears any setting, i.e. the whole board is
1127     visible again.
1128     Related: DD, PM, FG
1129    
1130     Go properties
1131     Restrictions: TW and TB points must be unique, i.e. it's illegal to list the same point in TB and TW within the same node.
1132     Gametype: 1
1133    
1134     Property: HA
1135     Propvalue: number
1136     Propertytype: game-info
1137     Function: Defines the number of handicap stones (>=2).
1138     If there is a handicap, the position should be set up with
1139     AB within the same node.
1140     HA itself doesn't add any stones to the board, nor does
1141     it imply any particular way of placing the handicap stones.
1142     Related: KM, RE, RU
1143    
1144     Property: KM
1145     Propvalue: real
1146     Propertytype: game-info
1147     Function: Defines the komi.
1148     Related: HA, RE, RU
1149    
1150     Property: TB
1151     Propvalue: elist of point
1152     Propertytype: -
1153     Function: Specifies the black territory or area (depends on
1154     rule set used).
1155     Points must be unique.
1156     Related: TW
1157    
1158     Property: TW
1159     Propvalue: elist of point
1160     Propertytype: -
1161     Function: Specifies the white territory or area (depends on
1162     rule set used).
1163     Points must be unique.
1164     Related: TB
1165    
1166     Octi properties
1167     Gametype: 19
1168    
1169     Property: RU (rules)
1170     Propvalue: simpletext
1171     Propertytype: game-info
1172     Function: Valid values are one major variation ("full", "fast",
1173     or "kids") followed by a colon and a comma separated
1174     elist of variations ("edgeless", "superprong", etc.).
1175    
1176     The colon may be omitted if either side is empty.
1177     The default is 2-player full, no variations.
1178     The 4-player game is not currently available.
1179    
1180     Property: BO (black octisquares)
1181     Propvalue: list of point
1182     Propertytype: game-info
1183     Function: The position of Black's octi squares. Black will be
1184     setup with one empty pod on each of these points.
1185     It is illegal to list the same point twice.
1186     Traditionally, Black sits at the south end of the board.
1187     Related: WO
1188    
1189     Property: WO (white octisquares)
1190     Propvalue: list of point
1191     Propertytype: game-info
1192     Function: The position of White's octi squares. White will be
1193     setup with one empty pod on each of these points.
1194     It is illegal to list the same point twice.
1195     Traditionally, White sits at the north end of the board.
1196     Related: BO
1197    
1198     Property: NP (number of prongs)
1199     Propvalue: number
1200     Propertytype: game-info
1201     Function: This is the number of prongs each players has at the
1202     start of the game.
1203     The default will be derived from the rules.
1204     Related: NR
1205    
1206     Property: NR (number of reserve)
1207     Propvalue: number
1208     Propertytype: game-info
1209     Function: This is the number of pods in each players reserve at
1210     the start of the game.
1211     The default will be derived from the rules.
1212     Related: NP, NS
1213    
1214     Property: NS (number of superprongs)
1215     Propvalue: number
1216     Propertytype: game-info
1217     Function: This is the number of superprongs each players has at
1218     the start of the game.
1219     The default will be derived from the rules.
1220     Related: NR
1221    
1222     Property: AS (arrow stone)
1223     Propvalue: list of composed stone ':' point
1224     Propertytype: -
1225     Function: Most of the same restriction from AR apply.
1226     The same arrow must not occur twice; however, two arrows
1227     from different stones at the same point may have arrows
1228     to the same destination. Single point arrows are also
1229     illegal.
1230     Related: AR
1231    
1232     Property: CS (circle stone)
1233     Propvalue: list of stone
1234     Propertytype: -
1235     Function: Marks the given stones, each with a circle.
1236     Related: CR
1237    
1238     Property: MS (mark stone)
1239     Propvalue: list of stone
1240     Propertytype: -
1241     Function: Marks the given stones, each with an ex.
1242     Related: MA
1243    
1244     Property: SS (square stone)
1245     Propvalue: list of stone
1246     Propertytype: -
1247     Function: Marks the given stones, each with a square.
1248     Related: SQ
1249    
1250     Property: TS (triangle stone)
1251     Propvalue: list of stone
1252     Propertytype: -
1253     Function: Marks the given stones, each with a triangle.
1254     Related: TR
1255    
1256     Property: RP (remove pod)
1257     Propvalue: list of stone
1258     Propertytype: setup
1259     Function: Removes a stone from the board.
1260     More selective than AddEmpty.
1261     Related: AE
1262    
1263     Backgammon properties
1264     Gametype: 6
1265    
1266     Property: CO
1267     Propvalue: simpletext
1268     Propertytype: setup
1269     Function: Set the position of the doubling cube. The value
1270     should be `b' (black), `w' (white), `c' (centred), or `n'
1271     (none -- for cubeless or Crawford games).
1272     Related: CV
1273    
1274     Property: CV
1275     Propvalue: number
1276     Propertytype: setup
1277     Function: Set the value of the doubling cube. This value
1278     defaults to 1 at the beginning of the game, but a CV property
1279     should be added when setting up a position where a double has
1280     been made, or at the beginning of a money game if automatic
1281     doubles occur.
1282     Related: CP
1283    
1284     Property: DI
1285     Propvalue: number
1286     Propertytype: setup
1287     Function: Set the dice without moving (this could be useful for
1288     creating problem positions, e.g. DI[31])
1289     Related: CO
1290    
1291     Property: MI
1292     Propvalue: list of composed simpletext ':' simpletext
1293     Propertytype: game-info
1294     Function: Specifies information about the match the game belongs to.
1295     This property should specify a list of tag/value pairs, where
1296     the allowable tags are case-insensitive, and include:
1297    
1298     length - the match length (number of points); value should
1299     be a number
1300     game - the number of this game within the match (the
1301     first game is 1); value should be a number
1302     bs - the score for Black at the start of the game;
1303     value should be a number
1304     ws - the score for White at the start of the game;
1305     value should be a number
1306    
1307     Unknown tags should be ignored (a warning may be produced).
1308     The order of tags in the list is not significant. An example
1309     MI property is:
1310     MI[length:7][game:3][ws:2][bs:1]
1311     Related: EV, GN, RE, RO
1312    
1313     Property: RE
1314     Propvalue: simpletext
1315     Propertytype: game-info
1316     Function: The general RE property has the following
1317     modification in backgammon games: in the case of a
1318     resignation, the value should also specify the number of
1319     points before the R(esign). Here are three example RE
1320     properties:
1321    
1322     RE[B+6R] -- White resigns a backgammon on a 2
1323     cube (worth 6 points).
1324     RE[W+2Resign] -- Black resigns a gammon on a 1 cube
1325     (worth 2 points).
1326     RE[W+4] -- Black drops a redouble to 8 (note
1327     this is considered a normal loss, not
1328     a resignation).
1329     Related: RE
1330    
1331     Property: RU
1332     Propvalue: simpletext
1333     Propertytype: game-info
1334     Function: Backgammon-specific values for the general RU property
1335     include the following:
1336    
1337     [Crawford] -- the Crawford rule is being used in this match,
1338     although this is not the Crawford game.
1339     [Crawford:CrawfordGame] -- this IS the Crawford game.
1340     [Jacoby] -- the Jacoby rule is in use for this game.
1341     Related: RU
1342    
1343     Lines of Action properties
1344     Gametype: 9
1345    
1346     Property: AS
1347     Propvalue: SimpleText
1348     Propertytype: -
1349     Function: Adding stones - the color of the player who is adding
1350     stones to the board. The valid strings are 'Black', 'White'
1351     or 'None'. The puropse of this property is to define a
1352     board position where the human is expected to continue placing
1353     stones on the board through some user interface.
1354    
1355     Property: IP
1356     Propvalue: SimpleText
1357     Propertytype: game-info
1358     Function: Designates the initial position in the game to be
1359     displayed by the viewer.
1360     The only value currently supported is 'End', which causes
1361     the viewer to initially display the final position of the game.
1362     The default is to display the position after setup but before
1363     any moves.
1364    
1365     Property: IY
1366     Propvalue: SimpleText
1367     Propertytype: game-info
1368     Function: Invert Y axis. Values are 'true' or 'false'.
1369     If 'true', the board should be displayed with numbers
1370     increasing in value from bottom to top of the screen.
1371     Default: 'false'
1372    
1373     Property: SE
1374     Propvalue: point
1375     Propertytype: -
1376     Function: Mark the given point and up to 8 additional points,
1377     depending on where the provided point (stone) could legally
1378     move.
1379    
1380     Property: SU
1381     Propvalue: SimpleText
1382     Propertytype: game-info
1383     Function: Setup type - designates the intial placement of pieces,
1384     and also the implicitly the variation on the basic rules to be
1385     employed. The currently valid values include the following
1386     strings:
1387     'Standard', 'Scrambled-eggs', 'Parachute', 'Gemma' and 'Custom'
1388     (the initial board is empty, AB and AW properties
1389     will be used to establish the starting position).
1390     Default: 'Standard'
1391     For details on the setups and rule variations, consult the
1392     LOA home pages.
1393    
1394     Hex properties
1395     Gametype: 11
1396    
1397     Property: IS
1398     Propvalue: list of composed SimpleText ':' SimpleText
1399     Propertytype: root
1400     Function: This property allows applications to store and read
1401     an initial viewer setting. The property value is a list of
1402     "keyword followed by ':' followed by either 'on' or 'off'".
1403     Valid keywords are:
1404     'tried' - identify future moves that have been tried?
1405     'marked' - show good/bad move markings?
1406     'lastmove' - identify the last cell played?
1407     'headings' - display column/row headings (a b.., 1 2..)?
1408     'lock' - lock the game against new moves (for analysis)?
1409     This property is allowed in the root node only.
1410     Example: IS[tried:on][lock:off][marked:off]
1411    
1412     Property: IP
1413     Propvalue: SimpleText
1414     Propertytype: game-info
1415     Function: Designates the initial position that the viewer
1416     should display. It will most frequently indicate the
1417     current position of play in the game. This is necessary
1418     because future possible moves may have been explored,
1419     and the user must be able to distinguish real moves
1420     actually made from exploratory moves. More than one IP[]
1421     property in a game is illegal, and the behaviour undefined.
1422     The property value should be empty (""); it is specified
1423     as SimpleText for compatibility.
1424    
1425     Amazons properties
1426     Gametype: 18
1427    
1428     Property: AA
1429     Propvalue: list of point
1430     Propertytype: setup
1431     Function: Adding arrows to the board. This can be used to set up
1432     positions or problems.
1433    
1434     End: this marks the end
1435