}
}
+ my $prev_depth = $info->{'depth1'} // $info->{'depth'};
+
while (scalar @x > 0) {
if ($x[0] eq 'multipv') {
# Dealt with above
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') {
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.
+ my $cp = $info->{'score_cp1'} // $info->{'score_cp'};
+ my $mate = $info->{'score_mate1'} // $info->{'score_mate'};
+ push @{$info->{'lowdepth'}}, [ $d, $cp, $mate ];
+ }
}
sub parse_ids {
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.
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';
push @moves, $uci_move;
}
- $tbprobe_cache{$key} = \@moves;
+ $tbprobe_cache{$key} = {
+ moves => \@moves,
+ splicepos => $splicepos
+ };
}
$info->{'pv' . $mpv} = \@moves;
} else {
$info->{'score_mate' . $mpv} = $matelen;
}
+ $info->{'splicepos' . $mpv} = $splicepos;
}
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};
}
# 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 {
$json->{'tablebase'} = $info->{'tablebase'};
$json->{'pv'} = [ prettyprint_pv($pos_calculating, @{$info->{'pv'}}) ];
+ $json->{'lowdepth'} = {};
+ if (exists($info->{'lowdepth'})) {
+ for my $ld (@{$info->{'lowdepth'}}) {
+ $json->{'lowdepth'}{$ld->[0]} = score_digest_inner($ld->[1], $ld->[2], undef, 0, $pos_calculating);
+ }
+ }
+
my %refutation_lines = ();
my @refutation_lines = ();
if (defined($engine2)) {
move => $pretty_move,
pv => \@pretty_pv,
};
+ if (exists($info->{'splicepos' . $mpv})) {
+ $refutation_lines{$pretty_move}->{'splicepos'} = $info->{'splicepos' . $mpv};
+ }
};
}
}
# (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)];
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})) {