let clear_arrows = function() {
for (let i = 0; i < arrows.length; ++i) {
if (arrows[i].svg) {
- if (arrows[i].svg.parentElement) {
- arrows[i].svg.parentElement.removeChild(arrows[i].svg);
- }
+ arrows[i].svg.remove();
delete arrows[i].svg;
}
}
return;
}
- let zoom_factor = document.getElementById("board").getBoundingClientRect().width / 400.0;
+ let board_width = parseInt(document.querySelector(".board-b72b1").style.width, 10);
+ let zoom_factor = board_width / 400.0;
let line_width = arrow.line_width * zoom_factor;
let arrow_size = arrow.arrow_size * zoom_factor;
- let square_width = document.querySelector(".square-a8").getBoundingClientRect().width;
+ let square_width = board_width / 8;
let from_y, to_y, from_x, to_x;
if (board.orientation() === 'black') {
from_y = (arrow.from_row + 0.5)*square_width;
let SVG_NS = "http://www.w3.org/2000/svg";
let XHTML_NS = "http://www.w3.org/1999/xhtml";
let svg = document.createElementNS(SVG_NS, "svg");
- svg.setAttribute("width", /** @type{number} */ (document.getElementById("board").getBoundingClientRect().width));
- svg.setAttribute("height", /** @type{number} */ (document.getElementById("board").getBoundingClientRect().height));
+ svg.setAttribute("width", board_width);
+ svg.setAttribute("height", board_width);
svg.setAttribute("style", "position: absolute");
svg.setAttribute("position", "absolute");
svg.setAttribute("version", "1.1");
let pv_score = undefined;
for (let move in data['refutation_lines']) {
let line = data['refutation_lines'][move];
- let score = compute_score_sort_key(line['score'], line['depth'], invert, false);
+ let score = compute_score_sort_key(line['score'], line['depth'], invert);
if (move == data['pv'][0]) {
pv_score = score;
}
}
}
- let ret = '';
+ let ret = document.createDocumentFragment();
let i = 0;
let in_tb = false;
+ let link = document.createElement('a');
+ link.className = 'move';
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
// opt_showlast is set, then it is the history, and thus,
// the UI should be to expand the history.
- ret = '(<a class="move" href="javascript:collapse_history(false)">…</a>) ';
+ ret.appendChild(document.createTextNode('('));
+ link.href = 'javascript:collapse_history(false)';
+ link.textContent = '…';
+ ret.appendChild(link);
+ ret.appendChild(document.createTextNode(') '));
i = pv.length - opt_limit;
if (i % 2 == 1) {
++i;
}
move_num += i / 2;
} else if (toplay == 'B' && pv.length > 0) {
+ ret.appendChild(document.createTextNode(move_num + '. … '));
let move = "";
if (splicepos === 0) {
- move += "(TB: ";
+ ret.appendChild(document.createTextNode('(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;
+ link.setAttribute('id', 'automove' + line_num + '-0');
+ link.href = 'javascript:show_line(' + line_num + ', ' + 0 + ');';
+ link.textContent = pv[0];
+ ret.appendChild(link);
toplay = 'W';
++i;
++move_num;
}
for ( ; i < pv.length; ++i) {
- let move = "<a class=\"move\" id=\"automove" + line_num + "-" + i + "\" href=\"javascript:show_line(" + line_num + ", " + i + ");\">" + pv[i] + "</a>";
+ link = document.createElement('a');
+ link.className = 'move';
+ link.setAttribute('id', 'automove' + line_num + '-' + i);
+ link.textContent = pv[i];
+ link.href = 'javascript:show_line(' + line_num + ', ' + i + ');';
if (splicepos === i) {
- ret += " (TB: ";
+ ret.appendChild(document.createTextNode('(TB: '));
in_tb = true;
}
if (toplay == 'W') {
if (i > opt_limit && !opt_showlast) {
if (in_tb) {
- ret += ")";
+ ret.appendChild(document.createTextNode(')'));
}
- return ret + ' (…)';
+ ret.appendChild(document.createTextNode(' (…)'));
+ return ret;
}
if (ret != '') {
- ret += ' ';
+ ret.appendChild(document.createTextNode(' '));
}
- ret += move_num + '. ' + move;
+ ret.appendChild(document.createTextNode(move_num + '. '));
++move_num;
toplay = 'B';
} else {
- ret += ' ' + move;
+ ret.appendChild(document.createTextNode(' '));
toplay = 'W';
}
+ ret.appendChild(link);
}
if (in_tb) {
- ret += ")";
+ ret.appendChild(document.createTextNode(')'));
}
return ret;
}
}
let update_history = function() {
+ let history = document.getElementById('history');
if (display_lines[0] === null || display_lines[0].pv.length == 0) {
- document.getElementById("history").innerHTML = "No history";
+ history.textContent = 'No history';
} else if (truncate_display_history) {
- document.getElementById("history").innerHTML = print_pv(0, null, 8, true);
+ history.replaceChildren(print_pv(0, null, 8, true));
} else {
- document.getElementById("history").innerHTML =
- '(<a class="move" href="javascript:collapse_history(true)">collapse</a>) ' +
- print_pv(0, null);
+ history.textContent = '(';
+ let link = document.createElement('a');
+ link.className = 'move';
+ link.href = 'javascript:collapse_history(true)';
+ link.textContent = 'collapse';
+ history.appendChild(link);
+ history.appendChild(document.createTextNode(') '));
+ history.append(print_pv(0, null));
}
}
if (line['pv'].length == 0) {
// Not found, so just make a one-move PV.
- let move = "<a class=\"move\" href=\"javascript:show_line(" + display_lines.length + ", " + 0 + ");\">" + line['move'] + "</a>";
- move_td.innerHTML = move;
- let score_td = document.createElement("td");
+ let link = document.createElement('a');
+ link.className = 'move';
+ link.href = 'javascript:show_line(' + display_lines.length + ', ' + 0 + ')';
+ link.textContent = line['move'];
+ move_td.replaceChildren(link);
+ let score_td = document.createElement("td");
score_td.classList.add("score");
score_td.textContent = "—";
tr.appendChild(score_td);
let pv_td = document.createElement("td");
tr.appendChild(pv_td);
pv_td.classList.add("pv");
- pv_td.innerHTML = add_pv(base_fen, base_line.concat([ line['move'] ]), move_num, toplay, scores, start_display_move_num);
+ pv_td.append(add_pv(base_fen, base_line.concat([ line['move'] ]), move_num, toplay, scores, start_display_move_num));
tbl.append(tr);
continue;
let pv_td = document.createElement("td");
tr.appendChild(pv_td);
pv_td.classList.add("pv");
- pv_td.innerHTML = add_pv(base_fen, base_line.concat(line['pv']), move_num, toplay, scores, start_display_move_num, 10);
+ pv_td.append(add_pv(base_fen, base_line.concat(line['pv']), move_num, toplay, scores, start_display_move_num, 10));
tbl.append(tr);
}
document.getElementById("score").textContent = "No analysis for this move";
document.getElementById("pvtitle").textContent = "PV:";
document.getElementById("pv").replaceChildren();
- document.getElementById("searchstats").innerHTML = " ";
+ document.getElementById("searchstats").textContent = " ";
document.getElementById("refutationlines").replaceChildren();
document.getElementById("whiteclock").replaceChildren();
document.getElementById("blackclock").replaceChildren();
// The search stats.
if (data['searchstats']) {
- document.getElementById("searchstats").innerHTML = data['searchstats'];
+ document.getElementById("searchstats").textContent = data['searchstats'];
} else if (data['tablebase'] == 1) {
document.getElementById("searchstats").textContent = "Tablebase result";
} else if (data['nodes'] && data['nps'] && data['depth']) {
document.getElementById("pvtitle").textContent = "PV:";
let scores = [{ first_move: -1, score: data['score'] }];
- document.getElementById("pv").innerHTML = add_pv(data['position']['fen'], data['pv'], data['position']['move_num'], data['position']['toplay'], scores, 0);
+ document.getElementById("pv").replaceChildren(add_pv(data['position']['fen'], data['pv'], data['position']['move_num'], data['position']['toplay'], scores, 0));
// Update the PV arrow.
clear_arrows();
if (score < min_score) min_score = score;
if (score > max_score) max_score = score;
}
+ if (max_score - min_score < 100) {
+ if (Math.abs(max_score) >= Math.abs(min_score)) {
+ max_score = min_score + 100;
+ } else {
+ min_score = max_score - 100;
+ }
+ }
const h = scorespark.getBoundingClientRect().height;
* @param {string} fen
*/
let update_imbalance = function(fen) {
- let hiddenboard = new Chess(fen);
let imbalance = {'k': 0, 'q': 0, 'r': 0, 'b': 0, 'n': 0, 'p': 0};
- for (let row = 0; row < 8; ++row) {
- for (let col = 0; col < 8; ++col) {
- let col_text = String.fromCharCode('a1'.charCodeAt(0) + col);
- let row_text = String.fromCharCode('a1'.charCodeAt(1) + row);
- let square = col_text + row_text;
- let contents = hiddenboard.get(square);
- if (contents !== null) {
- if (contents.color === 'w') {
- ++imbalance[contents.type];
- } else {
- --imbalance[contents.type];
- }
- }
+ for (const c of fen) {
+ if (c === ' ') {
+ // End of board
+ break;
+ }
+ if (c != c.toUpperCase()) {
+ --imbalance[c];
+ } else if (c != c.toLowerCase()) {
+ ++imbalance[c.toLowerCase()];
}
}
+
let white_imbalance = document.getElementById('whiteimbalance');
let black_imbalance = document.getElementById('blackimbalance');
white_imbalance.textContent = '';
document.getElementById("pvtitle").textContent = "Exploring:";
current_display_line.start_display_move_num = 0;
display_lines.push(current_display_line);
- document.getElementById("pv").innerHTML = print_pv(display_lines.length - 1, null); // FIXME
+ document.getElementById("pv").append(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.
document.getElementById("linemsg").style.display = 'none';
if (current_display_move <= 0) {
- document.getElementById("prevmove").innerHTML = "Previous";
+ document.getElementById("prevmove").textContent = "Previous";
} else {
document.getElementById("prevmove").innerHTML = "<a href=\"javascript:prev_move();\">Previous</a></span>";
}
if (current_display_move == current_display_line.pv.length - 1) {
- document.getElementById("nextmove").innerHTML = "Next";
+ document.getElementById("nextmove").textContent = "Next";
} else {
document.getElementById("nextmove").innerHTML = "<a href=\"javascript:next_move();\">Next</a></span>";
}
// Shouldn't really be here if we have hash probes, but there's really
// nothing we can do.
+ // FIXME: Just make a new line, probably (even if we don't have hash moves).
+ // As it is, we can actually drag (but not click) such a move in the UI,
+ // but it has no effect on what we're probing.
}
// End of dragging-related code.
* @param score The score digest tuple.
* @param {?number} depth Depth the move has been computed to, or null.
* @param {boolean} invert Whether black is to play.
- * @param {boolean=} depth_secondary_key
* @return {number}
*/
-let compute_score_sort_key = function(score, depth, invert, depth_secondary_key) {
+let compute_score_sort_key = function(score, depth, invert) {
let s;
if (!score) {
return -10000000;
}
if (s) {
if (invert) s = -s;
- if (depth_secondary_key) {
- return s * 200 + (depth || 0);
- } else {
- return s;
- }
+ return s;
} else {
return null;
}