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