package DDG::GoodieRole::Chess; # ABSTRACT: Helper function to parse a FEN string and draw a chessboard. # We could in principle use Chess::PGN::EPD, but that module does not provide # the HTML output, so we just implement what we need and don't add a dependecny. use strict; use Scalar::Util qw(looks_like_number); use Moo::Role; # Parse the FEN string into an array of length 64. sub parse_position { my ($i) = 0; my ($position) = @_; $position =~ s/^\s+|\s+$//g; my (@cases) = (); for (my $char = 0 ; $char < length($position) ; $char++ ) { my $fenchar = substr($position, $char, 1); if ($fenchar eq ' ') { return @cases; } if (looks_like_number($fenchar)) { for ($i = 0; $i < $fenchar; $i++){ push(@cases, 'e'); } } elsif ($fenchar ne '/') { push(@cases, $fenchar); } } return @cases; } # Generate a chessboard as a HTML table. sub draw_chessboard_html { my (@position) = @_; my ($i) = 0; my ($j) = 0; my ($counter) = 0; my (@arr) = ("A".."Z"); my (%class_dict) = ( 'r' => 'black rook', 'n' => 'black knight', 'b' => 'black bishop', 'q' => 'black queen', 'k' => 'black king', 'p' => 'black pawn', 'e' => 'empty', 'R' => 'white rook', 'N' => 'white knight', 'B' => 'white bishop', 'Q' => 'white queen', 'K' => 'white king', 'P' => 'white pawn', ); my (%unicode_dict) = ( 'r' => '♜', 'n' => '♞', 'b' => '♝', 'q' => '♛', 'k' => '♚', 'p' => '♟', 'e' => '', 'R' => '♖', 'N' => '♘', 'B' => '♗', 'Q' => '♕', 'K' => '♔', 'P' => '♙', ); my ($html_chessboard) = '
'; for ($i = 0; $i < 8; $i++){ # Rows $html_chessboard .= ''; for ($j = 0; $j < 8; $j++){ # Columns $html_chessboard .= ''; $counter++; } $html_chessboard .= ''; } $html_chessboard .= '
'; $html_chessboard .= ''.$unicode_dict{$position[$counter]}.''; $html_chessboard .= '
'; return $html_chessboard; } # Generate a chessboard in ASCII, with the same format as # 'text output from Chess::PGN::EPD sub draw_chessboard_ascii { my (@position) = @_; my ($i) = 0; my ($j) = 0; my ($counter) = 0; my ($ascii_chessboard) = ""; for ($i = 0; $i < 8; $i++){ # Rows for ($j = 0; $j < 8; $j++){ # Columns if ($position[$counter] ne 'e') { # Occupied square $ascii_chessboard .= $position[$counter]; } elsif ($j % 2 != $i % 2) { # Black square $ascii_chessboard .= '-'; } else { # White square $ascii_chessboard .= ' '; } $counter++; } if($counter < 63) { $ascii_chessboard .= "\n"; } } return $ascii_chessboard; }; 1;