From 0a124edc28c716548327826127a9145da091a3d0 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Wed, 3 Dec 2014 23:38:50 +0100 Subject: [PATCH] Add board/position output to a bitpacked format. --- Board.pm | 39 +++++++++++++++++++++++++++++++++++++++ Position.pm | 29 +++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/Board.pm b/Board.pm index 39c8134..d2a6e0e 100644 --- a/Board.pm +++ b/Board.pm @@ -221,6 +221,45 @@ sub fen { return join('/', @rows); } +# Returns a compact bit string describing the same data as fen(). +# This is encoded using a Huffman-like encoding, and should be +# typically about 1/3 the number of bytes. +sub bitpacked_fen { + my ($board) = @_; + my $bits = ""; + + for my $row (0..7) { + for my $col (0..7) { + my $piece = $board->[$row][$col]; + if ($piece eq '-') { + $bits .= "0"; + next; + } + + my $color = (lc($piece) eq $piece) ? 0 : 1; + $bits .= "1" . $color; + + if (lc($piece) eq 'p') { + $bits .= "0"; + } elsif (lc($piece) eq 'n') { + $bits .= "100"; + } elsif (lc($piece) eq 'b') { + $bits .= "101"; + } elsif (lc($piece) eq 'r') { + $bits .= "1110"; + } elsif (lc($piece) eq 'q') { + $bits .= "11110"; + } elsif (lc($piece) eq 'k') { + $bits .= "11111"; + } else { + die "Unknown piece $piece"; + } + } + } + + return pack('b*', $bits); +} + sub can_reach { my ($board, $piece, $from_row, $from_col, $to_row, $to_col) = @_; diff --git a/Position.pm b/Position.pm index 807b003..9d90cfc 100644 --- a/Position.pm +++ b/Position.pm @@ -97,6 +97,35 @@ sub fen { return $fen; } +# Returns a compact bit string describing the same data as fen(), +# except for the half-move and full-move clock. +sub bitpacked_fen { + my $pos = shift; + my $board = $pos->{'board'}->bitpacked_fen(); + + my $bits = ""; + if ($pos->{'toplay'} eq 'W') { + $bits .= "0"; + } else { + $bits .= "1"; + } + + $bits .= $pos->{'white_castle_k'}; + $bits .= $pos->{'white_castle_q'}; + $bits .= $pos->{'black_castle_k'}; + $bits .= $pos->{'black_castle_q'}; + + my $col = $pos->{'ep_file_num'}; + if ($col == -1) { + $bits .= "0"; + } else { + $bits .= "1"; + $bits .= (qw(000 001 010 011 100 101 110 111))[$col]; + } + + return $board . pack('b*', $bits); +} + sub to_json_hash { my $pos = shift; my $json = { %$pos, fen => $pos->fen() }; -- 2.39.2