Skip to content

Commit

Permalink
Merge pull request #8 from fohristiwhirl/remake
Browse files Browse the repository at this point in the history
Remake
  • Loading branch information
fohristiwhirl authored Jun 7, 2019
2 parents 834c813 + 0b7530a commit c74153d
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 364 deletions.
2 changes: 1 addition & 1 deletion 1_globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ let scanner = null;
let err_scanner = null;
let readyok_required = 0;

let __decoder = new TextDecoder("utf8");
let decoder = new TextDecoder("utf8");

let total_moves_made = 0; // For debugging / info
let total_positions_made = 0; // For debugging / info
15 changes: 15 additions & 0 deletions 2_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ function CompareArrays(a, b) {
return true;
}

function ArrayStartsWith(a, b) {

if (b.length > a.length) {
return false;
}

for (let n = 0; n < b.length; n++) {
if (a[n] !== b[n]) {
return false;
}
}

return true;
}

function OppositeColour(s) {
if (s === "w" || s === "W") return "b";
if (s === "b" || s === "B") return "w";
Expand Down
36 changes: 21 additions & 15 deletions 4_position.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const position_prototype = {
let ret = this.copy();
ret.parent = this;

let promotion = s.length > 4 ? s[4] : "q";
let promotion_char = s.length > 4 ? s[4].toLowerCase() : "q";

let white_flag = this.is_white(Point(x1, y1));
let pawn_flag = "Pp".includes(ret.state[x1][y1]);
Expand Down Expand Up @@ -143,12 +143,12 @@ const position_prototype = {
let promotion_flag;

if (y2 === 0 && pawn_flag) {
ret.state[x2][y2] = promotion.toUpperCase();
ret.state[x2][y2] = promotion_char.toUpperCase();
promotion_flag = true;
}

if (y2 === 7 && pawn_flag) {
ret.state[x2][y2] = promotion.toLowerCase();
ret.state[x2][y2] = promotion_char; // Always lowercase.
promotion_flag = true;
}

Expand All @@ -158,7 +158,7 @@ const position_prototype = {
ret.lastmove = s;

if (ret.lastmove.length === 4 && promotion_flag) {
ret.lastmove += promotion.toLowerCase();
ret.lastmove += promotion_char;
}

return ret;
Expand Down Expand Up @@ -714,7 +714,7 @@ const position_prototype = {
return "??";
}

if (this.nice_lastmove_cache === undefined) {
if (!this.nice_lastmove_cache) {
this.nice_lastmove_cache = this.parent.nice_string(this.lastmove);
}

Expand Down Expand Up @@ -896,6 +896,7 @@ const position_prototype = {
},

history: function() {
// Note, if this ever returns a cached list, it should return Array.from(cache) instead.
let list = [];
let node = this;
while (node.parent) { // no parent implies no lastmove
Expand All @@ -907,6 +908,7 @@ const position_prototype = {
},

position_list: function() {
// Note, if this ever returns a cached list, it should return Array.from(cache) instead.
let list = [];
let node = this;
while (node) {
Expand Down Expand Up @@ -934,18 +936,22 @@ const position_prototype = {
return false;
},

initial_fen: function() {

// When sending the engine the position, the UCI specs involve sending the initial FEN
// and then a list of moves. This method finds the initial FEN.

let node = this;

while (node.parent) {
node = node.parent;
compare: function(other) {
if (this.active !== other.active) return false;
if (this.enpassant !== other.enpassant) return false;
if (this.castling !== other.castling) return false;
if (this.halfmove !== other.halfmove) return false;
if (this.fullmove !== other.fullmove) return false;
if (this.lastmove !== other.lastmove) return false;
for (let x = 0; x < 8; x++) {
for (let y = 0; y < 8; y++) {
if (this.state[x][y] !== other.state[x][y]) {
return false;
}
}
}

return node.fen();
return true;
}
};

Expand Down
6 changes: 3 additions & 3 deletions 6_pgn.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ function new_byte_pusher() {
},

string: function() {
return __decoder.decode(this.bytes());
return decoder.decode(this.bytes());
}
};
}

function pre_parse_pgn(buf) {
function PreParsePGN(buf) {

// Returns an array of the pgn_record objects, of at least length 1.

Expand Down Expand Up @@ -153,7 +153,7 @@ function pre_parse_pgn(buf) {

// Parse the tag line...

let line = __decoder.decode(rawline).trim();
let line = decoder.decode(rawline).trim();

if (line.endsWith("]")) {

Expand Down
76 changes: 32 additions & 44 deletions 7_infotable.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,56 @@
"use strict";

function new_info() {
function new_info(board, move) {

return {
board: board,
cp: -999999,
move: "??",
move: move,
multipv: 999,
n: 0, // The draw logic will only ever draw things with non-negative n, so make this 0
p: "?",
pv: [],
nice_pv_cache: null,
nice_pv_string_cache: null,
// nice_pv_string_cache: null, // Can't have this because the pv_string changes as the sort order does.
winrate: null,

nice_pv: function(board) {
nice_pv: function() {

// Given the board for which this info is valid, generate a list of
// human readable moves. Since there's no real guarantee that our
// Human readable moves. Since there's no real guarantee that our
// moves list is legal, we legality check them. We at least know
// the initial move is legal, since it's checked on receipt.

if (this.nice_pv_cache) {
return this.nice_pv_cache;
}

let tmp_board = this.board;

if (!this.pv || this.pv.length === 0) {
return [board.nice_string(this.move)];
return [tmp_board.nice_string(this.move)];
}

let ret = [];

for (let move of this.pv) {
if (board.illegal(move) !== "") {
if (tmp_board.illegal(move) !== "") {
break;
}
ret.push(board.nice_string(move));
board = board.move(move);
ret.push(tmp_board.nice_string(move));
tmp_board = tmp_board.move(move);
}

this.nice_pv_cache = ret;
return this.nice_pv_cache;
},

nice_pv_string: function(board, options, i) {
nice_pv_string: function(options, i) {

// The caller should ensure that i is unique for each move in the moves list,
// then we can use i to ensure that each move has a unique way of calling
// renderer.pv_click()

if (this.nice_pv_string_cache) {
return this.nice_pv_string_cache;
}
// renderer.pv_click().

let nice_pv_list = this.nice_pv(board);
let nice_pv_list = this.nice_pv();

let blobs = [];

Expand All @@ -78,7 +76,7 @@ function new_info() {

// -------------------------------------------------

let colour = board.active;
let colour = this.board.active;

let n = 0;
for (let move of nice_pv_list) {
Expand Down Expand Up @@ -109,30 +107,26 @@ function new_info() {
blobs.push(`<span class="blue">(${tech_elements.join(" ")})</span>`);
}

this.nice_pv_string_cache = blobs.join(" ");
return this.nice_pv_string_cache;
return blobs.join(" ");
}
};
}

function NewInfoTable() { // There's only ever going to be one of these made.
function NewInfoTable() { // There's only ever going to be one of these made I guess.

return {

clears: 0,
table: Object.create(null),

clear: function() {
this.table = Object.create(null);
Log(`------------------------- info cleared (${++this.clears}) -------------------------`);
},

receive: function(s, board) {

// The current board is sent just so we can check the move is valid.
// Although the renderer tries to avoid sending invalid moves by
// syncing with "isready" "readyok" an engine like Stockfish doesn't
// behave properly, IMO.
// behave properly, IMO. So we use the board to check legality.

if (s.startsWith("info") && s.indexOf(" pv ") !== -1) {

Expand All @@ -142,27 +136,25 @@ function NewInfoTable() { // There's only ever going to be one of these made.
let move = InfoVal(s, "pv");
let move_info;

if (this.table[move]) { // We already have move info for this move.
if (this.table[move]) { // We already have move info for this move.
move_info = this.table[move];
} else { // We don't.
} else { // We don't.
if (board.illegal(move) !== "") {
Log(`... Nibbler: invalid move received!: ${move}`);
return;
}
move_info = new_info();
move_info = new_info(board, move);
this.table[move] = move_info;
}

move_info.move = move;

let tmp;

tmp = parseInt(InfoVal(s, "cp"), 10); // Score in centipawns
tmp = parseInt(InfoVal(s, "cp"), 10); // Score in centipawns
if (Number.isNaN(tmp) === false) {
move_info.cp = tmp;
}

tmp = parseInt(InfoVal(s, "multipv"), 10); // Leela's ranking of the move, starting at 1
tmp = parseInt(InfoVal(s, "multipv"), 10); // Leela's ranking of the move, starting at 1
if (Number.isNaN(tmp) === false) {
move_info.multipv = tmp;
}
Expand All @@ -171,7 +163,6 @@ function NewInfoTable() { // There's only ever going to be one of these made.

if (new_pv.length > 0) {
if (CompareArrays(new_pv, move_info.pv) === false) {
move_info.nice_pv_string_cache = null;
move_info.nice_pv_cache = null;
move_info.pv = new_pv;
}
Expand All @@ -183,28 +174,25 @@ function NewInfoTable() { // There's only ever going to be one of these made.

let move = InfoVal(s, "string");

if (board.illegal(move) !== "") {
Log(`... Nibbler: invalid move received!: ${move}`);
return;
}

let move_info;

if (this.table[move]) {
if (this.table[move]) { // We already have move info for this move.
move_info = this.table[move];
} else {
move_info = new_info();
} else { // We don't.
if (board.illegal(move) !== "") {
Log(`... Nibbler: invalid move received!: ${move}`);
return;
}
move_info = new_info(board, move);
this.table[move] = move_info;
}

move_info.move = move;

let tmp = parseInt(InfoVal(s, "N:"), 10);
if (Number.isNaN(tmp) === false) {
move_info.n = tmp;
}

move_info.p = InfoVal(s, "(P:"); // Worse case here is just empty string, which is OK.
move_info.p = InfoVal(s, "(P:"); // Worst case here is just empty string, which is OK.

tmp = InfoVal(s, "(Q:");
tmp = parseFloat(tmp);
Expand Down
Loading

0 comments on commit c74153d

Please sign in to comment.