ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Games-Go-SGF-Grove/Grove.pm
Revision: 1.10
Committed: Mon Jul 21 18:52:13 2008 UTC (15 years, 11 months ago) by elmex
Branch: MAIN
Changes since 1.9: +1 -4 lines
Log Message:
schaden => ?

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