Skip to content

Commit

Permalink
Merge pull request #189 from rooklift/graph_rework
Browse files Browse the repository at this point in the history
Graph rework
  • Loading branch information
rooklift authored Dec 13, 2021
2 parents f6fa4d6 + 729bcd4 commit 2e62566
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 48 deletions.
36 changes: 24 additions & 12 deletions src/50_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,35 @@ const table_prototype = {
this.nps = 0; // Stat sent by engine
this.tbhits = 0; // Stat sent by engine
this.time = 0; // Stat sent by engine
this.terminal = null; // null = unknown, "" = not terminal, "Non-empty string" = terminal reason
this.eval = null; // Used by grapher only, value from White's POV
this.eval_nodes = 0; // Number of search nodes used to generate the eval
this.eval_version = 0; // Which version (above) was used to generate the eval
this.already_autopopulated = false;
},

update_eval_from_move: function(move) {

// move should be the best move

let info = this.moveinfo[move];

if (!info || info.__ghost) return;

// if (info.uci_nodes < this.eval_nodes) return; // This can feel unintuitive.
get_eval: function() {
if (this.eval_version === this.version) {
return this.eval;
} else {
let info = SortedMoveInfoFromTable(this)[0];
if (info && !info.__ghost) {
this.eval = info.board.active === "w" ? info.value() : 1 - info.value();
} else {
this.eval = null;
}
this.eval_version = this.version;
return this.eval;
}
},

this.eval = info.board.active === "w" ? info.value() : 1 - info.value();
this.eval_nodes = info.uci_nodes;
set_terminal_info: function(reason, ev) { // ev is ignored if reason is "" (i.e. not a terminal position)
if (reason) {
this.terminal = reason;
this.eval = ev;
this.eval_version = this.version;
} else {
this.terminal = "";
}
},

autopopulate: function(node) {
Expand Down
28 changes: 10 additions & 18 deletions src/51_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ function NewNode(parent, move, board_for_root) { // move must be legal; board i
node.table = NewTable();
node.searchmoves = [];
node.__nice_move = null;
node.__terminal = null;
node.destroyed = false;
node.children = [];

Expand Down Expand Up @@ -132,7 +131,7 @@ const node_prototype = {
let node = this;

while (node) {
ret.push(node.table.eval);
ret.push(node.table.get_eval());
node = node.parent;
}

Expand Down Expand Up @@ -353,34 +352,29 @@ const node_prototype = {
// Returns "" if not a terminal position, otherwise returns the reason.
// Also updates table.eval (for the graph) if needed.

if (typeof this.__terminal === "string") {
return this.__terminal;
if (typeof this.table.terminal === "string") {
return this.table.terminal;
}

let board = this.board;

if (board.no_moves()) {
if (board.king_in_check()) {
this.__terminal = "Checkmate"; // The PGN writer checks for this exact string! (Lame...)
this.table.eval = board.active === "w" ? 0 : 1;
this.table.set_terminal_info("Checkmate", board.active === "w" ? 0 : 1); // The PGN writer checks for this exact string! (Lame...)
} else {
this.__terminal = "Stalemate";
this.table.eval = 0.5;
this.table.set_terminal_info("Stalemate", 0.5);
}
} else if (board.insufficient_material()) {
this.__terminal = "Insufficient Material";
this.table.eval = 0.5;
this.table.set_terminal_info("Insufficient Material", 0.5);
} else if (board.halfmove >= 100) {
this.__terminal = "50 Move Rule";
this.table.eval = 0.5;
this.table.set_terminal_info("50 Move Rule", 0.5);
} else if (this.is_triple_rep()) {
this.__terminal = "Triple Repetition";
this.table.eval = 0.5;
this.table.set_terminal_info("Triple Repetition", 0.5);
} else {
this.__terminal = "";
this.table.set_terminal_info("", null);
}

return this.__terminal;
return this.table.terminal;
},

validate_searchmoves: function(arr) {
Expand Down Expand Up @@ -488,15 +482,13 @@ function __clean_tree(node) {

while (node.children.length === 1) {
node.table.clear();
node.__terminal = null;
node.searchmoves = [];
node = node.children[0];
}

// Recursive when necessary...

node.table.clear();
node.__terminal = null;
node.searchmoves = [];

for (let child of node.children) {
Expand Down
15 changes: 10 additions & 5 deletions src/52_sorted_moves.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

function SortedMoveInfo(node) {

if (!node || node.destroyed) {
return [];
}

return SortedMoveInfoFromTable(node.table);
}

function SortedMoveInfoFromTable(table) {

// There are a lot of subtleties around sorting the moves...
//
// - We want to allow other engines than Lc0.
Expand All @@ -10,15 +19,11 @@ function SortedMoveInfo(node) {
// - We want to work with searchmoves, which is bound to leave stale info in the table.
// - We can try and track the age of the data by various means, but these are fallible.

if (!node || node.destroyed) {
return [];
}

let info_list = [];
let latest_cycle = 0;
let latest_subcycle = 0;

for (let o of Object.values(node.table.moveinfo)) {
for (let o of Object.values(table.moveinfo)) {
info_list.push(o);
if (o.cycle > latest_cycle) latest_cycle = o.cycle;
if (o.subcycle > latest_subcycle) latest_subcycle = o.subcycle;
Expand Down
13 changes: 0 additions & 13 deletions src/95_hub.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,6 @@ let hub_props = {
this.tick++;
this.draw();
this.purge_finished_loaders();
this.update_graph_eval(this.engine.search_running.node); // Possibly null.
this.maybe_save_window_size();
setTimeout(this.spin.bind(this), config.update_delay);
},
Expand All @@ -449,16 +448,6 @@ let hub_props = {
this.loaders = this.loaders.filter(o => o.callback);
},

update_graph_eval: function(node) {
if (!node || node.destroyed) {
return;
}
let info = SortedMoveInfo(node)[0]; // Possibly undefined.
if (info) {
node.table.update_eval_from_move(info.move);
}
},

maybe_save_window_size: function() {
if (this.window_resize_time && performance.now() - this.window_resize_time > 1000) {
this.window_resize_time = null;
Expand Down Expand Up @@ -883,8 +872,6 @@ let hub_props = {

receive_bestmove: function(s, relevant_node) {

this.update_graph_eval(relevant_node); // Now's the last chance to update our graph eval for this node.

let ok; // Could be used by 2 different parts of the switch (but not at time of writing...)

switch (config.behaviour) {
Expand Down

0 comments on commit 2e62566

Please sign in to comment.