]> git.sesse.net Git - remoteglot/commitdiff
Mark TB-extended lines as such.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 29 Dec 2020 20:16:00 +0000 (21:16 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 29 Dec 2020 20:16:00 +0000 (21:16 +0100)
We now distinguish between “wins in M moves” (ie., reaches a tablebase
position and has a displayed mate line, but the mate is not necessarily
optimal, due to the horizon effect and DTZ making funny mates) and
“mates in M moves”. We also mark the breakoff point in the PV.

remoteglot.pl
www/js/remoteglot.js

index 97003acd416b8660f936be325e098b634f8e79af..9742a5a09a8686e93270290961ac4fa3704a2dae 100755 (executable)
@@ -506,6 +506,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') {
@@ -601,8 +602,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 +628,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 +641,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 +655,7 @@ sub complete_using_tbprobe {
        } else {
                $info->{'score_mate' . $mpv} = $matelen;
        }
+       $info->{'splicepos' . $mpv} = $splicepos;
 }
 
 sub output {
@@ -688,7 +696,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 +736,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 {
@@ -956,6 +964,9 @@ sub output_json {
                                        move => $pretty_move,
                                        pv => \@pretty_pv,
                                };
+                               if (exists($info->{'splicepos' . $mpv})) {
+                                       $refutation_lines{$pretty_move}->{'splicepos'} = $info->{'splicepos' . $mpv};
+                               }
                        };
                }
        }
@@ -1167,7 +1178,16 @@ sub score_digest {
                if ($pos->{'toplay'} eq 'B') {
                        $mate = -$mate;
                }
-               return ['m', $mate];
+               if (exists($info->{'splicepos' . $mpv})) {
+                       my $sp = $info->{'splicepos' . $mpv};
+                       if ($mate < 0) {
+                               return ['tb', -$sp];
+                       } else {
+                               return ['tb', $sp];
+                       }
+               } else {
+                       return ['m', $mate];
+               }
        } else {
                if (exists($info->{'score_cp' . $mpv})) {
                        my $score = $info->{'score_cp' . $mpv};
@@ -1193,10 +1213,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/%u", int(($sp + 1) * 0.5), $sp;
+                       } else {
+                               return sprintf "Black wins in %u/%u", int(($sp + 1) * 0.5), $sp;
+                       }
                } 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})) {
index be95b1a8449a1d4e8f86e442692a10eeea94f638..e111bc6d8a817cfb4f5aab0eb2a4a66878f971b1 100644 (file)
@@ -7,7 +7,7 @@
  * @type {Number}
  * @const
  * @private */
-var SCRIPT_VERSION = 2016113008;
+var SCRIPT_VERSION = 2020122900;
 
 /**
  * The current backend URL.
@@ -660,15 +660,23 @@ var add_pv = function(start_fen, pv, move_num, toplay, scores, start_display_mov
                scores: scores,
                start_display_move_num: start_display_move_num
        });
-       return print_pv(display_lines.length - 1, opt_limit, opt_showlast);
+       var splicepos = null;
+       if (scores !== null && scores.length >= 1 &&
+           scores[scores.length - 1].score !== undefined &&
+           scores[scores.length - 1].score !== null &&
+           scores[scores.length - 1].score[0] === "tb") {
+               splicepos = Math.abs(scores[scores.length - 1].score[1]);
+       }
+       return print_pv(display_lines.length - 1, splicepos, opt_limit, opt_showlast);
 }
 
 /**
  * @param {number} line_num
+ * @param {?number} splicepos If non-null, where the tablebase-spliced portion of the TB starts.
  * @param {number=} opt_limit If set, show at most this number of moves.
  * @param {boolean=} opt_showlast If limit is set, show the last moves instead of the first ones.
  */
-var print_pv = function(line_num, opt_limit, opt_showlast) {
+var print_pv = function(line_num, splicepos, opt_limit, opt_showlast) {
        var display_line = display_lines[line_num];
        var pv = display_line.pv;
        var move_num = display_line.move_num;
@@ -689,10 +697,14 @@ var print_pv = function(line_num, opt_limit, opt_showlast) {
                        --to_add;
                }
                move_num += to_add / 2;
+               if (splicepos !== null && splicepos > 0) {
+                       --splicepos;
+               }
        }
 
        var ret = '';
        var i = 0;
+       var in_tb = false;
        if (opt_limit && opt_showlast && pv.length > opt_limit) {
                // Truncate the PV at the beginning (instead of at the end).
                // We assume here that toplay is 'W'. We also assume that if
@@ -705,7 +717,12 @@ var print_pv = function(line_num, opt_limit, opt_showlast) {
                }
                move_num += i / 2;
        } else if (toplay == 'B' && pv.length > 0) {
-               var move = "<a class=\"move\" id=\"automove" + line_num + "-0\" href=\"javascript:show_line(" + line_num + ", " + 0 + ");\">" + pv[0] + "</a>";
+               var move = "";
+               if (splicepos === 0) {
+                       move += "(TB: ";
+                       in_tb = true;
+               }
+               move += "<a class=\"move\" id=\"automove" + line_num + "-0\" href=\"javascript:show_line(" + line_num + ", " + 0 + ");\">" + pv[0] + "</a>";
                ret = move_num + '. … ' + move;
                toplay = 'W';
                ++i;
@@ -713,9 +730,16 @@ var print_pv = function(line_num, opt_limit, opt_showlast) {
        }
        for ( ; i < pv.length; ++i) {
                var move = "<a class=\"move\" id=\"automove" + line_num + "-" + i + "\" href=\"javascript:show_line(" + line_num + ", " + i + ");\">" + pv[i] + "</a>";
+               if (splicepos === i) {
+                       ret += " (TB: ";
+                       in_tb = true;
+               }
 
                if (toplay == 'W') {
                        if (i > opt_limit && !opt_showlast) {
+                               if (in_tb) {
+                                       ret += ")";
+                               }
                                return ret + ' (…)';
                        }
                        if (ret != '') {
@@ -729,6 +753,9 @@ var print_pv = function(line_num, opt_limit, opt_showlast) {
                        toplay = 'W';
                }
        }
+       if (in_tb) {
+               ret += ")";
+       }
        return ret;
 }
 
@@ -748,11 +775,11 @@ var update_history = function() {
        if (display_lines[0] === null || display_lines[0].pv.length == 0) {
                $("#history").html("No history");
        } else if (truncate_display_history) {
-               $("#history").html(print_pv(0, 8, true));
+               $("#history").html(print_pv(0, null, 8, true));
        } else {
                $("#history").html(
                        '(<a class="move" href="javascript:collapse_history(true)">collapse</a>) ' +
-                       print_pv(0));
+                       print_pv(0, null));
        }
 }
 
@@ -1743,7 +1770,7 @@ var update_move_highlight = function() {
                        $("#pvtitle").text("Exploring:");
                        current_display_line.start_display_move_num = 0;
                        display_lines.push(current_display_line);
-                       $("#pv").html(print_pv(display_lines.length - 1));
+                       $("#pv").html(print_pv(display_lines.length - 1, null));  // FIXME
                        display_line_num = display_lines.length - 1;
 
                        // Clear out the PV, so it's not selected by anything later.
@@ -2089,7 +2116,17 @@ var format_short_score = function(score) {
        if (!score) {
                return "???";
        }
-       if (score[0] === 'm') {
+       if (score[0] === 'tb') {
+               var ret = "TB\u00a0";
+               if (score[2]) {  // Is a bound.
+                       ret = score[2] + "\u00a0TB\u00a0";
+               }
+               if (score[1] > 0) {
+                       return ret + Math.ceil(score[1] / 2);
+               } else {
+                       return ret + "-" + Math.ceil(-score[1] / 2);
+               }
+       } else if (score[0] === 'm') {
                if (score[2]) {  // Is a bound.
                        return score[2] + "\u00a0M " + score[1];
                } else {
@@ -2111,7 +2148,13 @@ var format_long_score = function(score) {
        if (!score) {
                return "???";
        }
-       if (score[0] === 'm') {
+       if (score[0] === 'tb') {
+               if (score[1] > 0) {
+                       return "White wins in " + Math.ceil(score[1] / 2);
+               } else {
+                       return "Black wins in " + Math.ceil(-score[1] / 2);
+               }
+       } else if (score[0] === 'm') {
                if (score[1] > 0) {
                        return "White mates in " + score[1];
                } else {
@@ -2126,7 +2169,7 @@ var format_long_score = function(score) {
 }
 
 var compute_plot_score = function(score) {
-       if (score[0] === 'm') {
+       if (score[0] === 'm' || score[0] === 'tb') {
                if (score[1] > 0) {
                        return 500;
                } else {
@@ -2158,7 +2201,15 @@ var compute_score_sort_key = function(score, depth, invert, depth_secondary_key)
        if (!score) {
                return -10000000;
        }
-       if (score[0] === 'm') {
+       if (score[0] === 'tb') {
+               if (score[1] > 0) {
+                       // White reaches TB win.
+                       s = 89999 - score[1];
+               } else {
+                       // Black reaches TB win (note the double negative for score[1]).
+                       s = -89999 - score[1];
+               }
+       } else if (score[0] === 'm') {
                if (score[1] > 0) {
                        // White mates.
                        s = 99999 - score[1];