Use standalone tablebase probes to convert +123.xx scores to mates. It causes some...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 24 Jan 2016 21:53:17 +0000 (22:53 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 24 Jan 2016 21:53:17 +0000 (22:53 +0100)
Position.pm
config.pm
remoteglot.pl

index 6840e7f..c3dbcca 100644 (file)
@@ -38,6 +38,7 @@ sub new {
        }
        $pos->{'last_move'} = $x[29];
        $pos->{'prettyprint_cache'} = {};
+       $pos->{'tbprobe_cache'} = {};
 
        bless $pos, $class;
        return $pos;
@@ -78,6 +79,7 @@ sub from_fen {
        $pos->{'last_move_uci'} = undef;
        $pos->{'last_move'} = undef;
        $pos->{'prettyprint_cache'} = {};
+       $pos->{'tbprobe_cache'} = {};
        
        bless $pos, $class;
        return $pos;
@@ -164,6 +166,7 @@ sub to_json_hash {
        my $json = { %$pos, fen => $pos->fen() };
        delete $json->{'board'};
        delete $json->{'prettyprint_cache'};
+       delete $json->{'tbprobe_cache'};
        delete $json->{'black_castle_k'};
        delete $json->{'black_castle_q'};
        delete $json->{'white_castle_k'};
index 77fa74e..55f6d35 100644 (file)
--- a/config.pm
+++ b/config.pm
@@ -61,6 +61,10 @@ our @masters = (
        'Sesse',
 );
 
+# Command line to run the Fathom tablebase lookup program, if installed,
+# including the --path= argument.
+our $fathom_cmdline = undef;
+
 # ChessOK serial key (of the form NNNNN-NNNNN-NNNNN-NNNNN-NNNNN-NNNNN)
 # for looking up 7-man tablebases; undef means no lookup. Note that
 # you probably need specific prior permission to use this.
index 9f0ac3f..ca5263c 100755 (executable)
@@ -530,6 +530,61 @@ sub prettyprint_pv {
        }
 }
 
+sub complete_using_tbprobe {
+       my ($pos, $info, $mpv) = @_;
+
+       # We need Fathom installed to do standalone TB probes.
+       return if (!defined($remoteglotconf::fathom_cmdline));
+
+       # If we already have a mate, don't bother; in some cases, it would even be
+       # better than a tablebase┬áscore.
+       return if defined($info->{'score_mate' . $mpv});
+
+       # If we have a draw or near-draw score, there's also not much interesting
+       # we could add from a tablebase. We only really want mates.
+       return if ($info->{'score_cp' . $mpv} >= -12250 && $info->{'score_cp' . $mpv} <= 12250);
+
+       # Run through the PV until we are at a 6-man position.
+       # TODO: We could in theory only have 5-man data.
+       my @pv = @{$info->{'pv' . $mpv}};
+       my $key = join('', @pv);
+       my @moves = ();
+       if (exists($pos->{'tbprobe_cache'}{$key})) {
+               @moves = $pos->{'tbprobe_cache'}{$key};
+       } else {
+               while ($pos->num_pieces() > 6 && $#pv > -1) {
+                       my $move = shift @pv;
+                       push @moves, $move;
+                       $pos = $pos->make_move(parse_uci_move($move));
+               }
+
+               return if ($pos->num_pieces() > 6);
+
+               my $fen = $pos->fen();
+               my $pgn_text = `fathom --path=/srv/syzygy "$fen"`;
+               my $pgn = Chess::PGN::Parse->new(undef, $pgn_text);
+               return if (!defined($pgn) || !$pgn->read_game() || ($pgn->result ne '0-1' && $pgn->result ne '1-0'));
+               $pgn->quick_parse_game;
+               $info->{'pv' . $mpv} = \@moves;
+
+               # Splice the PV from the tablebase onto what we have so far.
+               for my $move (@{$pgn->moves}) {
+                       my $uci_move;
+                       ($pos, $uci_move) = $pos->make_pretty_move($move);
+                       push @moves, $uci_move;
+               }
+       }
+
+       $info->{'pv' . $mpv} = \@moves;
+
+       my $matelen = int((1 + scalar @moves) / 2);
+       if ((scalar @moves) % 2 == 0) {
+               $info->{'score_mate' . $mpv} = -$matelen;
+       } else {
+               $info->{'score_mate' . $mpv} = $matelen;
+       }
+}
+
 sub output {
        #return;
 
@@ -622,6 +677,17 @@ sub output {
                return;
        }
 
+       # Now do our own Syzygy tablebase probes to convert scores like +123.45 to mate.
+       if (exists($info->{'pv'})) {
+               complete_using_tbprobe($pos_calculating, $info, '');
+       }
+
+       my $mpv = 1;
+       while (exists($info->{'pv' . $mpv})) {
+               complete_using_tbprobe($pos_calculating, $info, $mpv);
+               ++$mpv;
+       }
+
        output_screen();
        output_json(0);
        $latest_update = [Time::HiRes::gettimeofday];
@@ -710,8 +776,8 @@ sub output_screen {
                        my $info = $engine2->{'info'};
                        last if (!exists($info->{'pv' . $mpv}));
                        eval {
+                               complete_using_tbprobe($pos_calculating_second_engine, $info, $mpv);
                                my $pv = $info->{'pv' . $mpv};
-
                                my $pretty_move = join('', prettyprint_pv($pos_calculating_second_engine, $pv->[0]));
                                my @pretty_pv = prettyprint_pv($pos_calculating_second_engine, @$pv);
                                if (scalar @pretty_pv > 5) {
@@ -788,6 +854,7 @@ sub output_json {
                        last if (!exists($info->{'pv' . $mpv}));
 
                        eval {
+                               complete_using_tbprobe($pos_calculating, $info, $mpv);
                                my $pv = $info->{'pv' . $mpv};
                                my $pretty_move = join('', prettyprint_pv($pos_calculating, $pv->[0]));
                                my @pretty_pv = prettyprint_pv($pos_calculating, @$pv);