From: Steinar H. Gunderson Date: Tue, 29 Dec 2020 20:16:00 +0000 (+0100) Subject: Mark TB-extended lines as such. X-Git-Url: https://git.sesse.net/?p=remoteglot;a=commitdiff_plain;h=9dbe80127346dce1003c423a118321a3eb1a0b59 Mark TB-extended lines as such. 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. --- diff --git a/remoteglot.pl b/remoteglot.pl index 97003ac..9742a5a 100755 --- a/remoteglot.pl +++ b/remoteglot.pl @@ -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})) { diff --git a/www/js/remoteglot.js b/www/js/remoteglot.js index be95b1a..e111bc6 100644 --- a/www/js/remoteglot.js +++ b/www/js/remoteglot.js @@ -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 = "" + pv[0] + ""; + var move = ""; + if (splicepos === 0) { + move += "(TB: "; + in_tb = true; + } + move += "" + pv[0] + ""; 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 = "" + pv[i] + ""; + 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( '(collapse) ' + - 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];