X-Git-Url: https://git.sesse.net/?p=remoteglot;a=blobdiff_plain;f=remoteglot.pl;h=abbbd983a7127abf317ef1c61916d2038db70c76;hp=97003acd416b8660f936be325e098b634f8e79af;hb=b827590935f10fd11c664e513f4daf94c52cce2a;hpb=dc3d19f5d7977bfa3eda1af4aa5696a10a4aebf1 diff --git a/remoteglot.pl b/remoteglot.pl index 97003ac..abbbd98 100755 --- a/remoteglot.pl +++ b/remoteglot.pl @@ -480,6 +480,8 @@ sub parse_infos { } } + my $prev_depth = $info->{'depth1'} // $info->{'depth'}; + while (scalar @x > 0) { if ($x[0] eq 'multipv') { # Dealt with above @@ -506,6 +508,7 @@ sub parse_infos { delete $info->{'score_cp' . $mpv}; delete $info->{'score_mate' . $mpv}; + delete $info->{'splicepos' . $mpv}; while ($x[0] eq 'cp' || $x[0] eq 'mate') { if ($x[0] eq 'cp') { @@ -533,6 +536,22 @@ sub parse_infos { die "Unknown info '" . join(',', @x) . "'"; } + + my $now_depth = $info->{'depth1'} // $info->{'depth'}; + if (defined($prev_depth) && POSIX::floor($now_depth / 10) > POSIX::floor($prev_depth / 10)) { + my $d = POSIX::floor($now_depth / 10) * 10; # In case we skipped some. + complete_using_tbprobe($pos_calculating, $info, exists($info->{'depth1'}) ? '1' : ''); + my $cp = $info->{'score_cp1'} // $info->{'score_cp'}; + my $mate = $info->{'score_mate1'} // $info->{'score_mate'}; + my $splicepos = $info->{'splicepos1'} // $info->{'splicepos'}; + my $bestmove; + if (defined($info->{'pv1'})) { # Avoid autovivification. + $bestmove = $info->{'pv1'}[0]; + } else { + $bestmove = $info->{'pv'}[0]; + } + push @{$info->{'lowdepth'}}, [ $d, $cp, $mate, $splicepos, $bestmove ]; + } } sub parse_ids { @@ -601,8 +620,11 @@ sub complete_using_tbprobe { my @pv = @{$info->{'pv' . $mpv}}; my $key = $pos->fen() . " " . join('', @pv); my @moves = (); + my $splicepos; if (exists($tbprobe_cache{$key})) { - @moves = @{$tbprobe_cache{$key}}; + my $c = $tbprobe_cache{$key}; + @moves = @{$c->{'moves'}}; + $splicepos = $c->{'splicepos'}; } else { if ($mpv ne '') { # Force doing at least one move of the PV. @@ -624,9 +646,9 @@ sub complete_using_tbprobe { 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. + $splicepos = scalar @moves; for my $move (@{$pgn->moves}) { last if $move eq '#'; last if $move eq '1-0'; @@ -637,7 +659,10 @@ sub complete_using_tbprobe { push @moves, $uci_move; } - $tbprobe_cache{$key} = \@moves; + $tbprobe_cache{$key} = { + moves => \@moves, + splicepos => $splicepos + }; } $info->{'pv' . $mpv} = \@moves; @@ -648,6 +673,7 @@ sub complete_using_tbprobe { } else { $info->{'score_mate' . $mpv} = $matelen; } + $info->{'splicepos' . $mpv} = $splicepos; } sub output { @@ -688,7 +714,7 @@ sub output { # my $fen = $pos_calculating->fen(); if (exists($tb_cache{$fen})) { - for my $key (qw(pv score_cp score_mate nodes nps depth seldepth tbhits)) { + for my $key (qw(pv score_cp score_mate nodes nps depth seldepth tbhits splicepos)) { delete $info->{$key . '1'}; delete $info->{$key}; } @@ -728,7 +754,7 @@ sub output { # specified. # if (exists($info->{'pv1'}) && !exists($info->{'pv2'})) { - for my $key (qw(pv score_cp score_mate nodes nps depth seldepth tbhits)) { + for my $key (qw(pv score_cp score_mate nodes nps depth seldepth tbhits splicepos)) { if (exists($info->{$key . '1'})) { $info->{$key} = $info->{$key . '1'}; } else { @@ -936,6 +962,15 @@ sub output_json { $json->{'tablebase'} = $info->{'tablebase'}; $json->{'pv'} = [ prettyprint_pv($pos_calculating, @{$info->{'pv'}}) ]; + $json->{'lowdepth'} = {}; + if (exists($info->{'lowdepth'})) { + for my $ld (@{$info->{'lowdepth'}}) { + my $score = score_digest_inner($ld->[1], $ld->[2], $ld->[3], 0, $pos_calculating); + push @$score, prettyprint_pv($pos_calculating, $ld->[4]); + $json->{'lowdepth'}{$ld->[0]} = $score; + } + } + my %refutation_lines = (); my @refutation_lines = (); if (defined($engine2)) { @@ -956,6 +991,9 @@ sub output_json { move => $pretty_move, pv => \@pretty_pv, }; + if (exists($info->{'splicepos' . $mpv})) { + $refutation_lines{$pretty_move}->{'splicepos'} = $info->{'splicepos' . $mpv}; + } }; } } @@ -1161,20 +1199,43 @@ sub short_score { # (with side-to-play information) score_sort_key. sub score_digest { my ($info, $pos, $mpv) = @_; + return score_digest_inner( + $info->{'score_cp' . $mpv}, + $info->{'score_mate' . $mpv}, + $info->{'splicepos' . $mpv}, + $info->{'tablebase'}, + $pos); +} - if (defined($info->{'score_mate' . $mpv})) { - my $mate = $info->{'score_mate' . $mpv}; +sub score_digest_inner { + my ($score, $mate, $sp, $tablebase, $pos) = @_; + if (defined($mate)) { if ($pos->{'toplay'} eq 'B') { $mate = -$mate; } - return ['m', $mate]; + if (defined($sp)) { + if ($mate > 0) { + return ['T', $sp]; + } else { + return ['t', $sp]; + } + } else { + if ($mate > 0) { + return ['M', $mate]; + } elsif ($mate < 0) { + return ['m', -$mate]; + } elsif ($pos->{'toplay'} eq 'B') { + return ['M', 0]; + } else { + return ['m', 0]; + } + } } else { - if (exists($info->{'score_cp' . $mpv})) { - my $score = $info->{'score_cp' . $mpv}; + if (defined($score)) { if ($pos->{'toplay'} eq 'B') { $score = -$score; } - if ($score == 0 && $info->{'tablebase'}) { + if ($score == 0 && $tablebase) { return ['d', undef]; } else { return ['cp', int($score)]; @@ -1193,10 +1254,19 @@ sub long_score { if ($pos->{'toplay'} eq 'B') { $mate = -$mate; } - if ($mate > 0) { - return sprintf "White mates in %u", $mate; + if (exists($info->{'splicepos' . $mpv})) { + my $sp = $info->{'splicepos' . $mpv}; + if ($mate > 0) { + return sprintf "White wins in %u", int(($sp + 1) * 0.5); + } else { + return sprintf "Black wins in %u", int(($sp + 1) * 0.5); + } } else { - return sprintf "Black mates in %u", -$mate; + if ($mate > 0) { + return sprintf "White mates in %u", $mate; + } else { + return sprintf "Black mates in %u", -$mate; + } } } else { if (exists($info->{'score_cp' . $mpv})) {