Games::Go::Diagram3pm
Perl extension to make go diagrams similar to printed diagrams
Usage
use Games::Go::Diagrammy $diagram = Games::Go::Diagram->new (options);$diagram->put($coords, 'white' | 'black', ? number ?);$diagram->mark($coords);$diagram->label($coords, 'a');$diagram->get($coords);my $new_diagram = $diagram->next;
Overview
A Games::Go::Diagram object represents a diagram similar to those seen in go textbooks and magazines. The caller puts 'white' or 'black' stones (possibly numbered), on the intersection selected by $coords. The caller may also mark and label intersections and stones.
putting, marking, labeling and propertying 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 formatmy $coords = 'a4'; # NNGS / IGS style coordinatesmy $coords = "$x,$y"; # real coordinatesmy $coords = 'George'; # as long as there's only one George
Methods
- my $diagram = Games::Go::Diagram->
new(?options?) -
A
newGames::Go::Diagram can take the following options:Options:
hoshi=> ['coords', ...]-
A reference to a list of coordinates where the Diagram should place hoshi points.
black=> ['coords', ...]-
A reference to a list of coordinates where the Diagram should start with black stones already in place.
white=> ['coords', ...]-
A reference to a list of coordinates where the Diagram should start with white stones already in place.
callback=> \&user_defined_callback-
A reference to a user defined callback function. The user callback is called (with a reference to the
Diagramas the only argument) whennodeis called after conflict is detected.The user callback should either save the current
Diagramand call <next>, or flush theDiagram(by printing for example) and call <clear>.If the user callback is defined, a call to
nodealways returns non-zero (the current node number).
enable_overstones=> true | false-
If true (default), overstones are enabled and may be created by the
Diagramduring a call to theputmethod. The user must be prepared to deal with overstones information in response to a call to thegetmethod.
overstone_eq_mark=> true | false-
If true (default), overstones are assumed to be indistinguishable from
marks which means there can be conflicts betweenmarks and overstones. If false,marksand overstones are assumed to use different symbols and there are no conflicts between them.
- $diagram->
clear -
Clears the
Diagram. Allmarks,labels, andnumbers are removed from the stones and intersections. Allcaptured stones are removed, and all overstones are deleted (at which point, theDiagramis in the same state as anewDiagram). Pending actions that were not applied due to conflicts are now applied to theclearedDiagram.The following options are preserved:
- •
-
node (gets incremented)
- •
-
callback
- •
-
enable_overstones
- •
-
overstone_eq_mark
- my $nextDiagram = $diagram->
next -
Creates a new
Diagramobject starting from the currentDiagram.$nextDiagramis the starting point for the nextDiagramin a series, or for a variation.As with the
clearmethod, allcaptured stones are removed, and all overstones are deleted. Pending actions that were not applied due to conflicts are now applied to thenextDiagram.The following options are preserved:
- •
-
node (gets incremented)
- •
-
callback
- •
-
enable_overstones
- •
-
overstone_eq_mark
- $diagram->
hoshi(@hoshi_coords) -
Adds the coords listed in
@hoshi_coordsto any existing hoshi points. In array context, returns the list of coords that are hoshi points. In scalar context, returns a reference to the list.
- $diagram->
node -
All actions (
put,mark,labelandproperty) are provisional untilnodeis called. This makes a collection of actions atomic. ADiagramnode is analogous to a Smart Go Format (SGF) node. If there are no conflicts with the collected provisional actions,nodeincorporates them into theDiagramand returns non-zero (the current node number).If there is a conflict and a user
callbackis defined,nodecalls the callback with a reference to theDiagram($diagram) as the only argument. The user callback should either flush theDiagramand callclear(to reuse theDiagram) or save the currentDiagram, and callnext(to generate a newDiagram).If there is a conflict and no user
callbackis defined,nodereturns 0. The user should either:- •
-
flush the current
Diagramand call$diagram->clearto continue working with the currentDiagram, or:
- •
-
save the current
Diagram(and call$diagram->nextto create a newDiagramto continue working with)
Calling either
nextorclearcauses the pending collection of conflicting actions to be incorporated into the resultingDiagram.
- $diagram->
put('coords', 'black' | 'white', ? number ? ) -
puta black or white stone on theDiagramatcoords. The stone color is must be 'black' or 'white' (case insensitive, 'b' and 'w' also work). Optionalnumberis the number on the stone. If not defined, the stone is un-numbered (which is probably a mistake except at the very start of aDiagram.putting can cause any of the following conflicts:- •
-
stone is numbered and number is already used
- •
-
stone is numbered and the intersection is already labeled
In certain situations, (notably ko and snapbacks but also some other capturing situations),
putstones may become overstones. overstones are stones played on an intersection that contains a stone that has beencaptured, but not yet removed from theDiagram. There are two kinds of overstones: normal andmarked, depending on the state of the underlying (captured but not yet removed) stone.If the underlying stone is
numbered orlabeled, 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, theDiagramattempts to convert it into amarked 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:
- •
-
a stone of the same color as the underlying stone has already been converted elsewhere in the
Diagram, or
- •
-
overstone_eq_markis true and a mark of the same color as the underlying stone exists elsewhere in theDiagram.
See the
getmethod for details of how overstone information is returned.
- $diagram->
renumber($coords, $color, $old_num, $new_num); -
Changes the number of a stone already on the board.
$color, and$old_nummust match the existing color and number for the stone at$coords($old_num or$new_nummay be undef for an un-numbered stone). Only the displayed stone is compared for the match, overstones (game_stones) are not considered.Fails and returns 0 if:
- •
-
there is no diagram stone on the intersection, or
- •
-
$coloror$old_numdon't match, or
- •
-
$new_numis already used, or
- •
-
a
propertyitem exists for$old_numand$new_numis undef
If none of the above,
renumbersets the new number and returns 1.
- my $offset = $diagram->
offset($new_offset); -
Set a new offset for the diagram if
$new_offsetis defined. Returns the current value of the offset, or 0 if no offset has been set.Note that
Diagramdoesn't use the offset for anything, but external programs (like a converter) can use it to adjust the numbering.
- $diagram->
label('coords', 'char'); -
Place a label on an intersection.
charmust be a single letter from A to Z or from a to z.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,
labelcauses a conflict.
- $diagram->
mark('coords'); -
Place a mark on a stone (empty intersections cannot be marked).
The mark can be applied to several stones only if they are either:
- •
-
different color stones (black, white)
- •
-
all marked within one
node.
The
markcauses a conflict if:- •
-
the stone is a
labelled or numbered stone, or
- •
-
the same color mark already exists in the
Diagramfor a differentmarking group, or
- •
-
overstone_eq_markis true and there is already an overstone of the same color in theDiagram.
- my $nameListRef = $diagram->
name(? name, ... ?) -
Adds
name(s) to the currentDiagram. Names accumulate by getting pushed onto a list.In array context,
namereturns the current name list. In scalar context,namereturns a reference to the list of names.
- $diagram->
property($number, $propName, $propValue, ? $propValue... ?);
- my $prop_ref = $diagram->
property($number);
- my $all_props_ref = $diagram->
property(); -
If
$propNameand$propValare defined, pushes them onto the collection of properties associated with move$number.Note that
renumbering a move alsorenumbers the properties.If
$numberis defined and$propName/$propValue are not,propertyreturns a reference to the (possibly empty) hash of property IDs and property Values associated with the move number:my $prop_value = $prop_ref->{$propID}->[$idx].If
$numberis not defined, returns a reference to the (possibly empty) hash of properties stored in theDiagram. 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 $prop_value = $all_props_ref->{$moveNumber}->{$propID}->[$idx]property(when$propNameand$propValueare defined) is an action (it is provisional untilnodeis called) because properties are associated with a node in the SGF. However,propertynever causes a conflict.
- $diagram->
capture('coords') -
Captures the stone at the intersection.
Note that
capturehas no visible affect on the diagram. Rather, it marks the stone so that it is removed when creating thenextDiagram.captureis not considered an action because it cannot cause a conflict or change the visible status of the board.
- $diagram->
remove('coords') -
Removes the stone at the intersection.
Unlike
capture,removechanges the visible status of theDiagram: the stone is deleted, along with all marks and letters (only the 'hoshi', if any, is retained).removeis 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.
- my $stone = $diagram->
game_stone(coords); -
Returns 'black' or 'white' if there is a stone currently on the intersection, otherwise returns undef.
Note that the return value is determined by the game perspective, not the diagram perspective. If a stone is
putand latercaptured,game_stonereturns undef even though the diagram should still show the original stone. If a white stone isputand latercaptured, and then a black stone isput,game_stonereturns 'black', andgetindicates that a white stone should be displayed on the diagram.Note also that since
putis provisional untilnodeis called. If you usegame_stoneto check for liberties and captures, it must be done after the call tonodethat realizes theput.
- $diagram->
get('coords') -
Return the current status of the intersection. Status is returned as a reference to a hash. The keys of the hash indicate the items of interest, and the values of the hash are the indices where the item was applied, except where noted below.
Only keys that have been applied are returned - an empty hash means an empty intersection.
The hash keys can be any of:
- 'hoshi'
-
This intersection is a hoshi point. Note that since hoshi points are determined at
newtime, the value of this hash entry is always 0. This key is returned even if a stone has been placed on the intersection.
- 'white'
-
The color of a stone at this intersection.
- 'black'
-
The color of a stone at this intersection.
- 'number'
-
The hash value is the number on the stone. The node for
numberis found in the 'black' or 'white' hash value.
- 'capture'
-
The stone on this intersection has been
captured, the intersection is currently empty from the perspective of the game.
- 'mark'
-
The intersection or stone is marked.
- 'overstone'
-
If
overstone_eq_markis false, this hash entry gets the current node when an un-numbered, un-labeled stone is converted to an overstone. Ifoverstone_eq_markis false, this hash entry is never set (under the same circumstances, the intersection is 'mark'ed instead).
- 'label'
-
The hash key is the word 'label', and the value is the single character passed to the
labelmethod. Note that the node can be retrieved with:my $intersection = $diagram->get;my $label = $intersection->{label};my $label_node = $intersection->{$label};
- label
-
The hash key is the single character a-z or A-Z that is the
labelfor this intersection or stone. The hash value is the node.
- 'overstones'
-
If this hash entry exists it means that one or more stones were overlayed on the stone that is currently displayed on this intersection of the
Diagram.The hash value is a reference to an array of color/number pairs. The colors and numbers were passed to the
putmethod 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
getdescribes 'the marked white stone', while 'black' will be the first item in the 'overstones' array, and '33' will be the second.
The hash reference returned by
getpoints to the data in theDiagramobject - don't change it unless you know what you are doing.
- my $first_number = $diagram->
first_number -
Returns the lowest number
puton theDiagram, or 0 if no numbered stones have beenput.
- my $last_number = $diagram->
last_number -
Returns the highest number
puton theDiagram, or 0 if no numbered stones have beenput.
- my $parentDiagram = $diagram->
parent(? $parent ?) -
If
$parentis defined, sets theparentfor this diagram.Always returns the current value of
parent(possibly undef).
- my $move_number = $diagram->
var_on_move(? $new_number ?) -
If
$new_numberis defined, sets thevar_on_movefor this diagram. This is intended to be used in conjunction with the <Bparent> information to title diagrams such asmy $title = "Variation 2 on move " .$diagram->var_on_move ." in " .$diagram->parent->name;Always returns the current value of
var_on_move(possibly undef).
- my $overListRef = $diagram->
getoverlist -
Returns a reference to the list of intersections with overstones. The list members are the same intersection hash references returned by the
getmethod.The list is sorted by the order the intersections first had an overstone
puton. If there are no intersections with overstones, returns a reference to an empty list.
- my $user = $diagram->
user( ? $new_user ? ) -
If
$new_useris defined, sets theuservalue for theDiagram. Note that theuseris not used withinDiagram, but can be used by external code for any purpose. Most useful is probably if$new_useris a reference to a hash of user-defined items of interest.Returns the current
uservalue (default is undef).
Copyright and license
Copyright (C) 2005 by Reid Augustin
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.5 or, at your option, any later version of Perl 5 you may have available.
Releases
7 releases since Debian 4.0 (Etch); the text changed 3 times.