[Event "Cutthroat Classic 97"]
[Site "Sun Valley (ID)"]
[Date "1997.05.17"]
[Round "01"]
[White "Richardson Tom (ID)"]
[WhiteElo ""]
[Black "Myers Hugh S (ID)"]
[BlackElo ""]
[Result "0-1"]
[Annotator "Crafty v18.5"]
{annotating both black and white moves.}
{using a scoring margin of -1.00 pawns.}
{search time limit is 30.00}
1. e4 d5
2. exd5 Nf6
3. Nc3 Nxd5
4. d3
({12:-0.35} 4. d3 Nxc3 5. bxc3 e6 6. Nf3 Bd6 7. Be2 Qf6 8. Bd2 O-O 9. O-O Nc6 $15)
({0:+0.00} 4. Bc4 Nb6 $10)
4. ... e5
({12:-0.11} 4. ... e5 5. Qh5 Nc6 6. Bg5 Qd6 7. Nge2 Nxc3 8. Nxc3 Qb4 9. Rb1 Bg4 10. Qh4 $10)
({12:-0.19} 4. ... Nxc3 5. bxc3 e5 6. Be2 Bc5 7. Nf3 Nc6 8. Bg5 f6 9. Be3 $10)
.
.
.
####
#!/perl/bin/perl
#
# craftysvg.pl -- script to generate .svg file from Crafty .pgn analysis.
use strict;
use warnings;
use diagnostics;
my @scores;
my @allscores;
my @bestblack;
my @bestwhite;
my $black;
my $level;
my $score;
my $value;
my $previous_level = 0;
while (<>) {
if (/^\s/) {
if (/^\s+(\d+)\./) {
$level = 1;
$black = ( /\.\.\./ ? '1' : '0' );
s/^\s+//;
my @temp = split (/\s+/);
unless ( scalar(@temp) == 2 ) {
unless ($black) {
push ( @allscores, '0,1,0:+0.00' );
push ( @allscores, '0,2,0:+0.00' );
push ( @allscores, '1,1,0:+0.00' );
push ( @allscores, '1,2,0:+0.00' );
}
}
}
elsif (/^\s+\(\{/) {
/{(.*?)}/;
push ( @allscores, "$black,$level,$1" );
$level++;
}
}
}
foreach (@allscores) {
( $black, $level, $score ) = split /,/;
$score =~ /:([-+]\d+\.\d+)/;
$value = $1;
if ( $level == 1 ) {
if ( $previous_level == 1 ) {
push ( @bestblack, undef );
push ( @bestwhite, undef );
}
if ($value) {
push ( @scores, $value );
}
else {
push ( @scores, undef );
}
}
else {
if ($black) {
push ( @bestblack, $value );
push ( @bestwhite, undef );
}
else {
push ( @bestblack, undef );
push ( @bestwhite, $value );
}
}
$previous_level = $level;
}
####
my @data = (
[0..scalar(@scores) - 1],
[@scores[0..scalar(@scores) - 1]],
[@bestwhite[0..scalar(@scores) - 1]],
[@bestblack[0..scalar(@scores) - 1]],
);
my $graph = GD::Graph::mixed->new(800, 700);
$graph->set(
x_label => 'Performance By Half-move',
y_label => 'Scoring By Centipawn',
title => 'Game Performance Graph',
y_max_value => 15,
y_min_value => -15,
y_tick_number => 30,
y_label_skip => 2,
zero_axis => 1,
dclrs => [qw(lgray red green)],
types => [qw(bars linespoints linespoints)],
);
my $gd = $graph->plot(\@data);
open(IMAGE,'>image.png') or die "Couldn't open image.png:$!\n";
binmode IMAGE;
print IMAGE $gd->png();
close IMAGE;
####
openSVG( 450, 450 );
openG( transform => 'translate(10,85) scale(1,-1)' );
openG( transform => 'scale(5)' );
foreach ( -15 .. 15 ) {
hline( 0, 80, $_ );
}
foreach ( 0 .. 80 ) {
vline( -15, 15, $_ );
}
path(
d => 'M -1 0 H 81',
style => 'stroke: red; stroke-opacity: .25; stroke-width: .1'
);
graphline( 'black', 0.1, @scores );
graphline( 'green', 0.1, @bestblack );
graphline( 'red', 0.1, @bestwhite );
closeG();
closeG();
closeSVG();
sub path {
openTAG( 'path', @_ );
closeTAG();
}
sub openTAG {
my $tag = shift;
my %attributes = @_;
print "<$tag";
foreach ( keys %attributes ) {
print " $_=\"$attributes{$_}\"";
}
}
sub closeTAG {
my $s = shift;
if ($s) {
print "$s>\n";
}
else {
print "/>\n";
}
}
sub openG {
openTAG( 'g', @_ );
print ">\n";
}
sub closeG {
closeTAG('g');
}
sub openSVG {
my $height = shift;
my $width = shift;
print "\n";
print "\n";
print
"