NAME
Games::Go::SGF2misc - Reads SGF files and produces usable output in many formats
SYNOPSIS
use Games::Go::SGF2misc;
my $sgf = new Games::Go::SGF2misc;
for my $file (<*.sgf>) {
$sgf->parse($file);
# do things with the parsed sgf:
# the output options are listed below
}
nodelist
my $nodelist = $sgf->nodelist;
This returns a special list of node-id's (human readable $game_number.$variation-$move_no
node descriptors). example:
$nodelist = { 1 => [
[ '1.1-root', '1.1-1', '1.1-2', '1.1-3', '1.1-4', '1.1-5', ],
[ undef, undef, undef, undef, undef, '1.2-5', '1.2-6', '1.2-7', ],
[ undef, undef, undef, undef, undef, undef, undef, '1.3-7', '1.3-8' ],
] };
What do you do with them?
as_perl
my $game_info = $sgf->as_perl(1);
my $root_node = $sgf->as_perl('1.1-root');
my $move5_v2 = $sgf->as_perl('1.2-5');
my $s = $game_info->{game_properties}{SZ};
print "The board size is: ${s}x${s}!\n";
print my $c (@{ $move5_v2->{comments} }) {
print "Comment from 1.2-5: $c\n";
}
Tada!!
Oh, as_perl takes an optional second argument.
$sgf->as_perl("doesn't exist node"); # will die on the spot...
$sgf->as_perl("isn't there", 1) # will not
or print "yikes!!: " . $sgf->errstr;
as_text
This is pretty much just an example
use strict;
use Games::Go::SGF2misc;
my $sgf = new Games::Go::SGF2misc;
$sgf->parse("sgf/jettero-sixrusses-2004-03-18.sgf");
my $nl = $sgf->nodelist;
my $end = $nl->{1}[0][ $#{$nl->{1}[0]} ];
# 1st game 1st variation last node
my $caps = $sgf->as_perl( $end )->{captures};
print $sgf->as_text($end), "Captures: Black-$caps->{B} / White-$caps->{W}\n";
# Result:
# X O . . . O . . . . . . . . . O O O .
# . O O . O O X . X X O O X O O O X X X
# X O . . . O X . X O . O O . O X . . .
# O O . O O X O O O O O . . O X . X . .
# O O O O O X X X X O . O O X . . . . .
# O X X X O X . X . X O O X . X . . . .
# X X X O O . X . X . X X . . . . . . .
# X . . X O . . X . . . . . . . . X . .
# X . X X O O O X . . . . . . . . . . .
# X . X . X X O X O O O X . . . . . . .
# . X . . . X O O X X X X X . . . X . .
# . . . . X O O . O O O X . . . X X X X
# X X X . X X O O . O X X X . . X O O X
# X O O X . . X . O O O X X . X O O . O
# O O . O X X X X X O X X O X X X O . .
# . . O O O X . . X O O X O X O X O X .
# . . . . O O X X O O . O O O O O O X .
# . . . . . O X O . O . . . . O X X O O
# . . . . . O X O O . . . . . . . . . .
# Captures: Black-11 / White-16
as_html
This function works very much like the as_text function above, but instead prints out an html table full of images.
open my $out, ">", "example.html" or die $!;
print $out, $sgf->as_html( $end, "/image/dir/" );
The only real difference is the image-dir argument (which defaults to "./img"). This is the URL image dir (<img # src="$image_dir/moku.gif">), not the pysical image dir. There is a directory of images included with SGF2misc. They are from this page:
http://www.britgo.org/gopcres/gopcres1.html#ag-gifs
They are Andrew Grant's GIF images. I did NOT seek permission to re-distribute them. Perhaps I have no right to do so. I really don't know how to get ahold of him.
If anyone knows how who to ask, please tell me. If anyone knows it's a problem, please tell me.
3/22/04, Orien Vandenbergh made bc.gif, wc.gif, bq.gif and wq.gif for me.
NOTE: On marks, this as_html only shows circles, triangles, squares, and numbers where there are stones. It does not show letters at all. This is only because I don't have images for _everything_. :)
as_image
This uses the fantastic ::SGF2misc::GD package by Orien Vandenbergh that comes with this package. It is a separate package, and as you will see, the interfaces aren't totally compatable -- however, it _is_ intended to be used with this package.
You must install GD-2.15 (or so) in order to use it!! You will also need the bleeding edge versions of libpng and libgd. At the time of this writing, I used libgd-2.0.22 and got GD-2.12 to install and function normally.
Here's a calling example:
$sgf->as_image($node, {filename=>"html/$x->[$i].png", gobanColor=>[255, 255, 255]});
::SGF2misc::GD takes hash-like arguments. So, so does as_image(). filename=>"" and gobanColor=>[] are additions of mine, as they're actually used on separate calls in the ::SGF2misc::GD package. All other arguments are passed to the new() member function if ::SGF2misc::GD. Please read the Games::Go::SGF2misc::GD manpage; it contains much more information.
Some SGF writers will automatically add a CR (circle) property to the current move, which as_image will render as expected. However other SGF writers do not. To have as_image automatically render circles on the current moves add the hash argument auto_mark=>1. With auto_mark enabled, any nodes which already have _any_ form of markup will not receive _any_ circles on the current moves. This is to help ensure consistancy with SGFs where the markup has other (more important?) uses.*This could have undesirable results for nodes in which there are multiple stones placed.
Also, in the interests of making this as clumsy as possible, if the filename is a dash followed by a type extension,
my $image = $sgf->as_image($l, {filename=>"-.png"});
then the image will be returned as a string rather than written to a file.
Optionally, you can also install the ::SGF2misc::SVG package written by Orien. To specify use of the SVG module call as_image with the argument 'use' => 'Games::Go::SGF2misc::SVG'. Functionally the two rendering modules are equivalent, except SVG doesn't yet support returning the image as a string. Aesthetically, however, ::SVG seems to render a cleaner image (at all resolutions), and does so significantly faster.
as_freezerbag
What? Yeah, this is a special way to save the parsed sgf data such that you can interact with it without having to re-parse it. It seemed like it should be faster than re-parsing the SGF every time, but it isn't much of a speedup at all. Unless I can speed it up, or someone asks me to leave it in, it could get axed. I may leave it in anyway, because it's cute.
Try it yourself:
$sgf->as_freezerbag( "freezer.pl", # an export filename
# Some code to put in it. This argument is optional.
q/my @nodes = @{ $sgf->nodelist->{1}[0] };
for my $n (@nodes) {
my $board = $sgf->as_text($n) or die $sgf->errstr;
print "\e[1;1f$board";
}/,
# The location and/or switches for your perl
# I needed blib/lib (since I don't always install to test this
# stuff). This argument is optional.
"/usr/bin/perl -I blib/lib",
);
Board Postion Character Map
# This is how an empty 3x3 board would be stored:
$board = [
[ ' ', ' ', ' ' ],
[ ' ', ' ', ' ' ],
[ ' ', ' ', ' ' ],
];
# ' ' - an empty board position
# 'W' - a white stone
# 'B' - a black stone
Marks are not placed on the board! You'll just have to fetch the marks array from the $node.
Miscellaneous
is_node
print "There is a node called 1.1-root!\n" if $sgf->is_node('1.1-root');
BUGS
Besides the lack of documentation? Well, I'm sure there's a bunch. If you spot any bugs, please tell me.
ENV VARIABLES
DEBUG
Try setting $ENV{DEBUG}=1, $ENV{DEBUG}=2, or $ENV{DEBUG}=3 to see the internals.
Also, from your bash prompt you can 'DEBUG=1 perl ./myprog.pl' to enable debugging dynamically.
DEBUG of 31 or over will show the lexical trace. That's kinda fun.
AUTHOR
Please contact me with ANY suggestions, no matter how pedantic.
Paul Miller <jettero@cpan.org>
Some changes and patches provided by:
Orien Vandenbergh <orien@icecode.com>
COPYRIGHT
Copyright 2010 -- Paul Miller
LICENSE
GPL v3