Why are you making it so complicated for yourself? All you want to do is build a string that corresponds to the move. This means that you're attempting to build a state representation by parsing another state representation, one character at a time. The following may or may not be complete, but it's a good start. (I didn't do castling, leaving that as an exercise for the reader. I'd probably special-case it.)
package ChessNot;
use strict;
use warnings;
$|++;
my %is_row = map { $_ => 1 } ( 1 .. 8 );
my %is_col = do {
my $i = 1;
map { $_ => $i++ } ( 'a' .. 'h' )
};
my %is_piece = (
P => 'Pawn',
B => 'Bishop',
N => 'Knight',
R => 'Rook',
Q => 'Queen',
K => 'King',
);
sub parse
{
my $move = shift;
my @parse = split //, $move;
my ($row, $col);
my $piece = 'Pawn';
my $action = 'moves to';
my $have_capture = 0;
my $start_row;
my $start_col;
my $check = '';
while (my $elem = pop @parse)
{
$is_row{ $elem } && do {
($row ? $start_row : $row) = $elem;
next;
};
$is_col{ $elem } && do {
($col ? $start_col : $col) = $is_col{ $elem };
next;
};
$is_piece{ $elem } && do {
$piece = $is_piece{ $elem };
next;
};
$elem eq 'x' && do {
$action = 'captures';
$have_capture = 1;
next;
};
$elem eq '+' && do {
$check .= $check ? 'mate' : ', check';
next;
};
}
my $start_piece = '';
if ($start_row || $start_col)
{
$start_piece = join ', ', map { $_ || '?' } $start_row, $start
+_col;
$start_piece = "($start_piece) ";
}
return "$piece ${start_piece}$action ($row, $col)$check";
}
1;
__END__
#!/usr/local/bin/perl
use strict;
use warnings;
$|++;
use Test::More no_plan => 1;
use_ok( 'ChessNot' );
my @tests = (
[ 'e4', "Pawn moves to (4, 5)" ],
[ 'Pe4', "Pawn moves to (4, 5)" ],
[ 'Be4', "Bishop moves to (4, 5)" ],
[ 'Re4', "Rook moves to (4, 5)" ],
[ 'Ne4', "Knight moves to (4, 5)" ],
[ 'Qe4', "Queen moves to (4, 5)" ],
[ 'Ke4', "King moves to (4, 5)" ],
[ 'Nxe4', "Knight captures (4, 5)" ],
[ 'dxe4', "Pawn (?, 4) captures (4, 5)" ],
[ 'Ndxe4', "Knight (?, 4) captures (4, 5)" ],
[ 'N5xe4', "Knight (5, ?) captures (4, 5)" ],
[ 'Nf5xe4', "Knight (5, 6) captures (4, 5)" ],
[ 'e4+', "Pawn moves to (4, 5), check" ],
[ 'e4++', "Pawn moves to (4, 5), checkmate" ],
[ 'dxe4++', "Pawn (?, 4) captures (4, 5), checkmate" ],
);
foreach my $test (@tests)
{
my ($move, $expectation) = @$test;
my $result = ChessNot::parse( $move );
ok( $result eq $expectation, "$move => $expectation ($result)" );
}
</reamore>
------
We are the carpenters and bricklayers of the Information Age.
Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose
I shouldn't have to say this, but any code, unless otherwise stated, is untested