Provided by: sgf2dg_4.252-1_amd64 bug


       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->label($coords, 'a');
        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


       my $diagram = Games::Go::Sgf2Dg::Diagram->new (?options?)

       A new Games::Go::Sgf2Dg::Diagram can take the following 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.

       coord_style => 'normal' | 'sgf' | numeric
               Defines the coordinate translation system.  Note that while
               Games::Go::Sgf2Dg::Diagram doesn't use this coordinate system directly, sgf2dg
               converters may call the coordinate translator methods xcoord and ycoord, which
               rely on coord_style and boardSizeX/Y (below).

               Legal values are:

                   This is the standard coordinate system used for drawing diagrams: the vertical
                   coordinates start with 1 at the bottom and increase towards the top edge.  The
                   horizontal coordinates are letters starting with A on the left, and increasing
                   towards the right, but skipping over 'I'.  This is the default coordinate

                   Coordinates within SGF files are single letters, lower case first, then upper
                   case.  The origin (aa) is the top left corner.  'A' follows 'z', so the point
                   at (26, 27) translates to (zA).

               numeric: '++' | '+-' | '-+' | '--'
                   Number coordinates can be either increasing or decreasing.  '++' starts with
                   (0, 0) in the upper left corner, '-+' has (0, 0) in the upper right corner,

       boardSizeX => number
       boardSizeY => number
               boardSizeX/Y are used by the coordinate translation methods (xcoord and ycoord to
               calculate the appropriate coordinate string.

       callback => \&user_defined_callback
               A reference to a user defined callback function.  The user callback is called
               (with a reference to the Diagram as the only argument) when node is called after
               conflict is detected.

               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).

       enable_overstones => true | false
               If true (default), overstones are enabled and may be created by the Diagram during
               a call to the put method.  The user must be prepared to deal with overstones
               information in response to a call to the get method.


           Clears the Diagram.  All marks, labels, and numbers are removed from the stones and
           intersections.  All captured stones are removed, and all overstones are deleted (at
           which point, the Diagram is in the same state as a new Diagram).  Pending actions that
           were not applied due to conflicts are now applied to the cleared Diagram.

           The following options are preserved:

           ·   node    (gets incremented)

           ·   callback

           ·   enable_overstones

       $diagram->force_conflict(? $msg ?)
           Set the conflict flag to force pending actions to be flushed and a new $diagram
           created.  It's a good idea to pass a short $msg explaining the conflict is being
           created.  $msg is printed in -verbose mode of sgf2dg.  If no $msg is defined, a
           generic (and probably not very helpful) message is produced.

       my $pending_count = $diagram->actions_pending
           Returns the number of actions that would be executed if node were called.

       my $done_count = $diagram->actions_done
           Returns the number of actions that have been done for the current $diagram.

       my $nextDiagram = $diagram->next
           Creates a new Diagram object starting from the current Diagram.  $nextDiagram is the
           starting point for the next Diagram in a series, or for a variation.

           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:

           ·   node    (gets incremented)

           ·   callback

           ·   enable_overstones


           Adds the coords listed in @hoshi_coords to 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.

           All actions (put, mark, label and property) are provisional until node is called.
           This makes a collection of actions atomic.  A Diagram node is analogous to a Smart Go
           Format (SGF) node.  If there are no conflicts with the collected provisional actions,
           node incorporates them into the Diagram and returns non-zero (the current node

           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:

           ·   flush the current Diagram and call $diagram->clear to continue working with the
               current Diagram, or:

           ·   save the current Diagram (and call $diagram->next to create a new Diagram to
               continue working with)

           Calling either next or clear causes the pending collection of conflicting actions to
           be incorporated into the resulting Diagram.

       $diagram->put ('coords', 'black' | 'white',  ? number ? )
           put a black or white stone on the Diagram at coords.  The stone color is must be
           'black' or 'white' (case insensitive, 'b' and 'w' also work).  Optional number is the
           number on the stone.  If not defined, the stone is un-numbered (which is probably a
           mistake except at the very start of a Diagram.

           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), 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:

           ·   a stone of the same color as the underlying stone has already been converted
               elsewhere in the Diagram, or

           ·   a mark of the same color as the underlying stone exists elsewhere in the Diagram.

           See the get method 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_num must match
           the existing color and number for the stone at $coords ($old_num or $new_num may 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

           ·   $color or $old_num don't match, or

           ·   $new_num is already used, or

           ·   a property item exists for $old_num and $new_num is undef

           If none of the above, renumber sets the new number and returns 1.

       my $offset = $diagram->offset($new_offset);
           Set a new offset for the diagram if $new_offset is defined.  Returns the current value
           of the offset, or 0 if no offset has been set.

           Note that Diagram doesn't use the offset for anything, but external programs (like a
           converter) can use it to adjust the numbering.

       $diagram->label('coords', 'text');
           Place a label on an intersection.  text may be any text, but notice that long strings
           may overflow a stone or intersection.  If 'text' is empty ('') any existing label is

           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.

       $diagram->mark('coords', ? 'mark_type' ?);
           Place a mark on a stone or intersection.  The 'mark_type' can be any text, but is
           usually the SGF property:

           CR  circle
           MA  an X mark
           SQ  square
           TR  triangle

           If 'mark_type' is not supplied (or undef), MA is assumed.

           The mark raises a conflict if:

           ·   the intersection is already labelled or numbered, or

           ·   the same color and 'mark_type' already exists in the Diagram for a previous node
               (possibly from creating an understone).

       my $diagram->territory ($propID, $coords);
           $propID should be one of 'TB', 'TW', or undef.  territory marks the intersection
           $coords as being white or black territory (see 'TB', 'TW' in the get method below).
           If $number is undef, any previous territory marking is removed.

       my $diagram->view ($coords);
           If $coords is defined, then the game-level VW property is set, and the intersection at
           $coords is marked as viewable (hash key is 'VW').  If $coords is '' or undef, then the
           game-level VW property is deleted, and the VW mark is removed from all intersections.

       my $nameListRef = $diagram->name (? name, ... ?)
           Adds name(s) to the current Diagram.  Names accumulate by getting pushed onto a list.

           In array context, name returns the current name list.  In scalar context, name returns
           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 $propName and $propVal are defined, pushes them onto the collection of properties
           associated with move $number.

           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

       @title_lines = $diagram->gameProps_to_title (\&emph_sub)
           gameProps_to_title converts game (node 0) properties extracted from the SGF file.  The
           properties are scanned in the order listed here:

           GN GameName
           EV EVent
           RO ROund (joined to EVent)
           DT DaTe
           PC PlaCe
           PW PlayerWhite "White:"
           WR WhiteRank (joined to PW)
           PB PlayerBlack "Black"
           BR BlackRank (joined to PB)
           KM KoMi "Komi:"
           RU RUles "Rules:"
           TM TiMe "Time:"
           OT OverTime (byo-yomi) "Byo-yomi:"
           RE REsult "Result:"
           AN ANnotator "Annotated by:"
           SO Source "Source:"
           US USer "Entered by:"
           CP CoPyright
           GC GameComment

           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.

       $diagram->capture ('coords')
           Captures the stone at the intersection.

           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.

       $diagram->remove ('coords')
           Removes the stone at the intersection.

           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

       my $stone = $diagram->game_stone(coords | $intersection);
           Returns 'black' or 'white' if there is a stone currently on the coords or intersection
           (a reference to an intersection, such as is returned by $diagram->get) , otherwise
           returns undef.

           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.

       $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

           The hash keys can be any of:

               This intersection is a hoshi point.  Note that since hoshi points are determined
               at new time, the value of this hash entry is always 0.  This key is returned even
               if a stone has been placed on the intersection.

               The color of a stone at this intersection.

               The color of a stone at this intersection.

               The hash value is the number on the stone.  The node for number is found in the
               'black' or 'white' hash value.

               The stone on this intersection has been captured, the intersection is currently
               empty from the perspective of the game.

               The intersection or stone is marked.  The value indicates the type of mark,
               usually the SGF property:

               CR  circle
               MA  an X mark
               SQ  square
               TR  triangle
               The intersection has been labeled.  The value indicates the text of the label.

               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 put method which decided to convert the stone into an

               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],

           'TB' or 'TW'
               Intersection has been marked as black or white territory with a TB or TW property.

               Set when the intersection is marked with a VW view property.  Relates to the VW
               game property:

                   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.

       my $coord_string = $diagram->xcoord($x)
       my $coord_string = $diagram->ycoord($y)
           Returns a string to display for a given $x or $y coordinate.  The string returned
           depends not only on the $x or $y value, but also on the coords_style and boardSizeX/Y
           configuration options,

       my $first_number = $diagram->first_number
           Returns the lowest number put on the Diagram, or 0 if no numbered stones have been

       my $last_number = $diagram->last_number
           Returns the highest number put on the Diagram, or 0 if no numbered stones have been

       my $parentDiagram = $diagram->parent (? $parent ?)
           If $parent is defined, sets the parent for this diagram.

           Always returns the current value of parent (possibly undef).

       my $move_number = $diagram->var_on_move (? $new_number ?)
           If $new_number is defined, sets the var_on_move for this diagram.  This is intended to
           be used in conjunction with the <Bparent> information to title diagrams such as

               my $title = "Variation 2 on move " .
                           $diagram->var_on_move .
                           " in " .

           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 get method.

           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.

       my $user = $diagram->user ( ? $new_user ? )
           If $new_user is defined, sets the user value for the Diagram.  Note that the user is
           not used within Diagram, but can be used by external code for any purpose.  Most
           useful is probably if $new_user is a reference to a hash of user-defined items of

           Returns the current user value (default is undef).


           Script to convert SGF format files to Go diagrams


       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.