X-Git-Url: https://git.sesse.net/?p=remoteglot;a=blobdiff_plain;f=www%2Fjs%2Fremoteglot.js;h=81612361feeefadfa122053c427972fbe133989b;hp=e7a0453fd90569488cb10a761a6ac7830e8967ab;hb=181097241ea4fe24cbea99a0a92736e39704e4a6;hpb=c17cb0c030ad2b4eb8493fbbc6aba34b68afacb6 diff --git a/www/js/remoteglot.js b/www/js/remoteglot.js index e7a0453..8161236 100644 --- a/www/js/remoteglot.js +++ b/www/js/remoteglot.js @@ -3,9 +3,6 @@ /** @type {window.ChessBoard} @private */ var board = null; -/** @type {window.ChessBoard} @private */ -var hiddenboard = null; - /** @type {Array.<{ * from_col: number, * from_row: number, @@ -48,8 +45,8 @@ var highlight_to = undefined; /** @type {?jQuery} @private */ var highlighted_move = null; -/** @type {!number} @private */ -var unique = Math.random(); +/** @type {?number} @private */ +var unique = null; /** The current position on the board, represented as a FEN string. * @type {?string} @@ -76,10 +73,31 @@ var current_display_line = null; /** @type {?number} @private */ var current_display_move = null; +var supports_html5_storage = function() { + try { + return 'localStorage' in window && window['localStorage'] !== null; + } catch (e) { + return false; + } +} + +// Make the unique token persistent so people refreshing the page won't count twice. +// Of course, you can never fully protect against people deliberately wanting to spam. +var get_unique = function() { + var use_local_storage = supports_html5_storage(); + if (use_local_storage && localStorage['unique']) { + return localStorage['unique']; + } + var unique = Math.random(); + if (use_local_storage) { + localStorage['unique'] = unique; + } + return unique; +} + var request_update = function() { $.ajax({ - url: "http://analysis.sesse.net/analysis.pl?ims=" + ims + "&unique=" + unique - //url: "http://analysis.sesse.net:5000/analysis.pl?ims=" + ims + "&unique=" + unique + url: "/analysis.pl?ims=" + ims + "&unique=" + unique }).done(function(data, textstatus, xhr) { ims = xhr.getResponseHeader('X-Remoteglot-Last-Modified'); var num_viewers = xhr.getResponseHeader('X-Remoteglot-Num-Viewers'); @@ -380,13 +398,19 @@ var thousands = function(x) { /** * @param {!string} fen * @param {Array.} uci_pv - * @param {Array.} pretty_pv * @param {number} move_num * @param {!string} toplay * @param {number=} opt_limit * @param {boolean=} opt_showlast */ -var add_pv = function(fen, uci_pv, pretty_pv, move_num, toplay, opt_limit, opt_showlast) { +var add_pv = function(fen, uci_pv, move_num, toplay, opt_limit, opt_showlast) { + var hiddenboard = new Chess(); + hiddenboard.load(fen); + for (var i = 0; i < uci_pv.length; ++i) { + hiddenboard.move(ucimove_to_chessjs_move(uci_pv[i])); + } + var pretty_pv = hiddenboard.history(); + display_lines.push({ start_fen: fen, uci_pv: uci_pv, @@ -407,21 +431,18 @@ var add_pv = function(fen, uci_pv, pretty_pv, move_num, toplay, opt_limit, opt_s var print_pv = function(line_num, pretty_pv, move_num, toplay, opt_limit, opt_showlast) { var pv = ''; var i = 0; - if (opt_limit && opt_showlast) { + if (opt_limit && opt_showlast && pretty_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 // opt_showlast is set, then it is the history, and thus, // the UI should be to expand the history. pv = '(…) '; i = pretty_pv.length - opt_limit; - if (i < 0) { - i = 0; - } if (i % 2 == 1) { ++i; } move_num += i / 2; - } else if (toplay == 'B') { + } else if (toplay == 'B' && pretty_pv.length > 0) { var move = "" + pretty_pv[0] + ""; pv = move_num + '. … ' + move; toplay = 'W'; @@ -523,7 +544,7 @@ var update_refutation_lines = function() { var pv_td = document.createElement("td"); tr.appendChild(pv_td); $(pv_td).addClass("pv"); - $(pv_td).html(add_pv(fen, line['pv_uci'], line['pv_pretty'], move_num, toplay, 10)); + $(pv_td).html(add_pv(fen, line['pv_uci'], move_num, toplay, 10)); tbl.append(tr); } @@ -553,14 +574,18 @@ var update_board = function(data, num_viewers) { } else { headline = 'Analysis'; } + var last_move; if (data['position']['last_move'] !== 'none') { - headline += ' after ' if (data['position']['toplay'] == 'W') { - headline += (data['position']['move_num']-1) + '… '; + last_move = (data['position']['move_num']-1) + '… '; } else { - headline += data['position']['move_num'] + '. '; + last_move = data['position']['move_num'] + '. '; } - headline += data['position']['last_move']; + last_move += data['position']['last_move']; + + headline += ' after ' + last_move; + } else { + last_move = null; } $("#headline").text(headline); @@ -583,8 +608,24 @@ var update_board = function(data, num_viewers) { $("#score").text(data['score']); } + var title_elems = []; + if (data['short_score'] !== undefined && data['short_score'] !== null) { + title_elems.push(data['short_score']); + } + if (last_move !== null) { + title_elems.push(last_move); + } + + if (title_elems.length != 0) { + document.title = '(' + title_elems.join(', ') + ') analysis.sesse.net'; + } else { + document.title = 'analysis.sesse.net'; + } + // The search stats. - if (data['nodes'] && data['nps'] && data['depth']) { + if (data['tablebase'] == 1) { + $("#searchstats").text("Tablebase result"); + } else if (data['nodes'] && data['nps'] && data['depth']) { var stats = thousands(data['nodes']) + ' nodes, ' + thousands(data['nps']) + ' nodes/sec, depth ' + data['depth'] + ' ply'; if (data['seldepth']) { stats += ' (' + data['seldepth'] + ' selective)'; @@ -598,6 +639,8 @@ var update_board = function(data, num_viewers) { } $("#searchstats").text(stats); + } else { + $("#searchstats").text(""); } // Update the board itself. @@ -614,14 +657,14 @@ var update_board = function(data, num_viewers) { // Print the history. if (data['position']['history']) { - add_pv('start', data['position']['history'], data['position']['pretty_history'], 1, 'W', 8, true); + add_pv('start', data['position']['history'], 1, 'W', 8, true); } else { display_lines.push(null); } update_history(); // Print the PV. - $("#pv").html(add_pv(data['position']['fen'], data['pv_uci'], data['pv_pretty'], data['position']['move_num'], data['position']['toplay'])); + $("#pv").html(add_pv(data['position']['fen'], data['pv_uci'], data['position']['move_num'], data['position']['toplay'])); // Update the PV arrow. clear_arrows(); @@ -763,58 +806,35 @@ var update_displayed_line = function() { $("#nextmove").html("Next"); } - hiddenboard.position(current_display_line.start_fen, false); + var hiddenboard = new Chess(); + hiddenboard.load(current_display_line.start_fen); for (var i = 0; i <= current_display_move; ++i) { - var pos = hiddenboard.position(); - var move = current_display_line.uci_pv[i]; - var source = move.substr(0, 2); - var target = move.substr(2, 2); - var promo = move.substr(4, 1); - - // Check if we need to do en passant. - var piece = pos[source]; - if (piece == "wP" || piece == "bP") { - if (source.substr(0, 1) != target.substr(0, 1) && - pos[target] === undefined) { - var ep_square = target.substr(0, 1) + source.substr(1, 1); - delete pos[ep_square]; - hiddenboard.position(pos, false); - } - } - - move = source + "-" + target; - hiddenboard.move(move, false); - pos = hiddenboard.position(); - - // Do promotion if needed. - if (promo != "") { - pos[target] = pos[target].substr(0, 1) + promo.toUpperCase(); - hiddenboard.position(pos, false); - } - - // chessboard.js does not automatically move the rook on castling - // (issue #51; marked as won't fix), so update it ourselves. - if (move == "e1-g1" && hiddenboard.position().g1 == "wK") { // white O-O - hiddenboard.move("h1-f1", false); - } else if (move == "e1-c1" && hiddenboard.position().c1 == "wK") { // white O-O-O - hiddenboard.move("a1-d1", false); - } else if (move == "e8-g8" && hiddenboard.position().g8 == "bK") { // black O-O - hiddenboard.move("h8-f8", false); - } else if (move == "e8-c8" && hiddenboard.position().c8 == "bK") { // black O-O-O - hiddenboard.move("a8-d8", false); - } + hiddenboard.move(ucimove_to_chessjs_move(current_display_line.uci_pv[i])); } highlighted_move = $("#automove" + current_display_line.line_number + "-" + current_display_move); highlighted_move.addClass('highlight'); - board.position(hiddenboard.position()); + board.position(hiddenboard.fen()); +} + +var ucimove_to_chessjs_move = function(move) { + var source = move.substr(0, 2); + var target = move.substr(2, 2); + var promo = move.substr(4, 1); + + if (promo === '') { + return { from: source, to: target }; + } else { + return { from: source, to: target, promotion: promo }; + } } var init = function() { + unique = get_unique(); + // Create board. board = new window.ChessBoard('board', 'start'); - hiddenboard = new window.ChessBoard('hiddenboard', 'start'); request_update(); $(window).resize(function() {