Games::Go::Sgf2Dg::Diagram(3pm) | User Contributed Perl Documentation | Games::Go::Sgf2Dg::Diagram(3pm) |
Games::Go::Sgf2Dg::Diagram - Encapsulate a go diagram
use Games::Go::Sgf2Dg::Diagram my $diagram = Games::Go::Sgf2Dg::Diagram->new (options); $diagram->put($coords, 'white' | 'black', ? number ?); $diagram->mark($coords); $diagram->label($coords, 'a'); $diagram->get($coords); my $new_diagram = $diagram->next;
A Games::Go::Sgf2Dg::Diagram object represents a diagram similar to those seen in go textbooks and magazines. Most of the properties defined in SGF FF[4] are supported.
The caller puts 'white' or 'black' stones (possibly numbered), on the intersection selected by $coords. The caller may mark and label intersections and stones.
put, mark, label and property are 'actions'. Actions are provisional until the node method is called. If any provisioanl actions cause a conflict, none of the actions associated with the node are applied, and the node method either calls a user-defined callback function, or returns an error.
When a conflict occurs, the caller should dispose of the current Diagram by getting the information from each intersection and doing something (like printing it). Then the caller converts the Diagram to the starting point of the next diagram by calling the clear method. Alternatively, the caller may save the current Diagram and create the starting point for the next diagram by calling the next method. clear and next may also be called at arbitrary times (for example, to launch a variation diagram).
'coords' may be any unique identifier for the intersection. For example:
my $coords = 'qd'; # SGF format my $coords = 'a4'; # NNGS / IGS style coordinates my $coords = "$x,$y"; # real coordinates my $coords = 'George'; # as long as there's only one George
A new Games::Go::Sgf2Dg::Diagram can take the following options:
Legal values are:
The user callback should either save the current Diagram and call <next>, or flush the Diagram (by printing for example) and call <clear>.
If the user callback is defined, a call to node always returns non-zero (the current node number).
The following options are preserved:
As with the clear method, all captured stones are removed, and all overstones are deleted. Pending actions that were not applied due to conflicts are now applied to the next Diagram.
The following options are preserved:
If there is a conflict and a user callback is defined, node calls the callback with a reference to the Diagram ($diagram) as the only argument. The user callback should either flush the Diagram and call clear (to reuse the Diagram) or save the current Diagram, and call next (to generate a new Diagram).
If there is a conflict and no user callback is defined, node returns 0. The user should either:
Calling either next or clear causes the pending collection of conflicting actions to be incorporated into the resulting Diagram.
putting can cause any of the following conflicts:
In certain situations, (notably ko and snapbacks but also some other capturing situations), put stones may become overstones. overstones are stones played on an intersection that contains a stone that has been captured, but not yet removed from the Diagram. There are two kinds of overstones: normal and marked, depending on the state of the underlying (captured but not yet removed) stone.
If the underlying stone is numbered, B>mark>ed or labeled, the overstone is normal and there will be no conflicts (unless the number is already used!).
If the underlying stone is un-numbered and un-labeled, the Diagram attempts to convert it into a marked stone. If the conversion succeeds, the overstone becomes a marked overstone, and there is no conflict.
The conversion of the underlying stone causes a conflict if:
See the get method for details of how overstone information is returned.
Fails and returns 0 if:
If none of the above, renumber sets the new number and returns 1.
Note that Diagram doesn't use the offset for anything, but external programs (like a converter) can use it to adjust the numbering.
The same label can be applied to several intersections only if they are all labeled within a single node.
If the intersection or stone is already labeled, or occupied by a marked, or numbered stone, or if the label has already been used outside the labeling group, label causes a conflict.
If 'mark_type' is not supplied (or undef), MA is assumed.
The mark raises a conflict if:
In array context, name returns the current name list. In scalar context, name returns a reference to the list of names.
Note that renumbering a move also renumbers the properties.
If $number and $propName are defined and $propValue is not ( or is empty), the $propName property is removed.
If $number is defined and $propName/$propValue are not, property returns a reference to the (possibly empty) hash of property IDs and property Values associated with the move number:
my $prop_ref = $diagram->property($number); my $prop_value = $prop_ref->{$propID}->[$idx];
If $number is not defined, returns a reference to the (possibly empty) hash of properties stored in the Diagram. Hash keys are the move number, and each hash value is in turn a hash. The keys of the property hashes are (short) property IDs and the hash values are lists of property values for each property ID:
my $all_prop_ref = $diagram->property(); my $prop_value = $all_props_ref->{$moveNumber}->{$propID}->[$idx]
property (when $propName and $propValue are defined) is an action (it is provisional until node is called) because properties are associated with a node in the SGF. However, property never causes a conflict.
Note that sgf2dg stores the following properties:
propID number propVal comment ------ ------ ------- Move properties W[] or W[tt] move 'pass' white pass B[] or B[tt] move 'pass' black pass KO move '' force move PL[W|B] move 'W' | 'B' set player Node annotation properties C[text] move text move comment DM[dbl] move 0 | 1 Even position GB[dbl] move 0 | 1 Good for black GW[dbl] move 0 | 1 Good for white HO[dbl] move 0 | 1 Hotspot UC[dbl] move 0 | 1 Unclear N[stxt] move simple_text Name (node name) V[real] move real Value (estimated game score) Move annotation properties BM[dbl] move 0 | 1 Bad move DO move '' Doubtful move IT move '' Interesting move TE[dbl] move 0 | 1 Tesuji (good move) Markup properties AR[c_pt] move 'pt:pt' Arrow DD[elst] move 'pt?' Dim points: DD[] clears LN[c_pt] move 'pt:pt' Line SL[lst] move 'pt' Select points (markup unknown) Root properties AP[stxt:stxt] 0 'stxt:stxt' Application_name:version CA[stxt] 0 'charset' character set FF[1-4] 0 0 - 4 FileFormat GM[1-16] 0 0 - 16 Game ST[0-3] 0 0 - 3 How to show variations (style?) Game info properties AN[stxt] 0 simple_text Annotater (name) BT[stxt] 0 simple_text Black team WT[stxt] 0 simple_text White team CP[stxt] 0 simple_text Copyright ON[stxt] 0 simple_text Opening information OT[stxt] 0 simple_text Overtime description (byo-yomi) PC[stxt] 0 simple_text Place game was played RE[stxt] 0 simple_text Result RO[stxt] 0 simple_text Round RU[stxt] 0 simple_text Rules SO[stxt] 0 simple_text Source US[stxt] 0 simple_text User/program who entered the game GC[text] 0 text Game comment TM[real] 0 real_number Time limits Timing properties BL[real] move real_number BlackLeft (time) WL[real] move real_number WhiteLeft (time) OB[num] move number Black moves left (after this move) OW[num] move number White moves left Go-specific properties HA[num] 0 number Handicap KM[real] 0 real_number Komi Misc. properties PM[num] move number Print mode - see FF4 spec BS[stext] move stext BlackSpecies (deprecated) WS[stext] move stext WhiteSpecies (deprecated) FG[pt:stext] move bitmask:stext Figure: see FF4 spec
For each property that is found, a line is added to the @title_lines return array. If the property has a string in double-quotes in the list above, that string (plus one space) is prefixed to the property text. In addition, if \&emph_sub is defined, the prefix is passed to &$emph_sub to make those portions appear emphasized in the title lines. Example:
my @title = $diagram->gameProps_to_title(sub { "{\\bf $_[0]}" });
wraps portions of the title line in TeX's bold-face (bf) style.
Note that capture has no visible affect on the diagram. Rather, it marks the stone so that it is removed when creating the next Diagram.
capture is not considered an action because it cannot cause a conflict or change the visible status of the board.
Unlike capture, remove changes the visible status of the Diagram: the stone is deleted, along with all marks and letters (only the 'hoshi', if any, is retained).
remove is typically used at the start of a variation to remove any stones that are improperly placed for the variation. It is closely related to the AddEmpty (AE) SGF property.
Note that the return value is determined by the game perspective, not the diagram perspective. If a stone is put and later captured, game_stone returns undef even though the diagram should still show the original stone. If a white stone is put and later captured, and then a black stone is put, game_stone returns 'black', and get indicates that a white stone should be displayed on the diagram.
Note also that since put is provisional until node is called. If you use game_stone to check for liberties and captures, it must be done after the call to node that realizes the put.
Only keys that have been applied are returned - an empty hash means an empty intersection.
The hash keys can be any of:
The hash value is a reference to an array of color/number pairs. The colors and numbers were passed to the put method which decided to convert the stone into an overstone.
This is typically seen as notes to the side of the diagram saying something like "black 33 was played at the marked white stone". In this example. the information returned by get describes 'the marked white stone', while 'black' will be the first item in the 'overstones' array, and '33' will be the second:
$diagram->get($coords) == {white => node_number, overstones => ['black', 33], ...}
if ((not $diagram->property(0)->VW) or # no game-level VieW property $intersection->{view}) { # this intersection is viewable # display this intersection }
The hash reference returned by get points to the data in the Diagram object - don't change it unless you know what you are doing.
Always returns the current value of parent (possibly undef).
my $title = "Variation 2 on move " . $diagram->var_on_move . " in " . $diagram->parent->name;
Always returns the current value of var_on_move (possibly undef).
The list is sorted by the order the intersections first had an overstone put on. If there are no intersections with overstones, returns a reference to an empty list.
Returns the current user value (default is undef).
With the current architecture, conflicts within a node are not detected. I think this would probably be malformed SGF. This deficiency could be fixed by adding a 'shadow' diagram to which provisional actions are applied.
2019-10-27 | perl v5.30.0 |