diff --git a/.vscode/settings.json b/.vscode/settings.json
index 40b0f323415ef..b36ea2c786de3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -20,27 +20,27 @@
],
"[javascript]": {
- "editor.rulers": [80],
+ "editor.rulers": [120],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[javascriptreact]": {
- "editor.rulers": [80],
+ "editor.rulers": [120],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[typescript]": {
- "editor.rulers": [80],
+ "editor.rulers": [120],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[typescriptreact]": {
- "editor.rulers": [80],
+ "editor.rulers": [120],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[scss]": {
- "editor.rulers": [80],
+ "editor.rulers": [120],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
diff --git a/code/modules/arcade/page.css b/code/modules/arcade/page.css
index e3dfcac1cce8a..dbfd2bb43a6d2 100644
--- a/code/modules/arcade/page.css
+++ b/code/modules/arcade/page.css
@@ -1,10 +1,10 @@
body {
/* Disables scroll bars */
- overflow:hidden;
+ overflow: hidden;
}
#background {
- width:900px;
- height:406px;
+ width: 900px;
+ height: 406px;
position: absolute;
background: url(backgroundsprite.png) no-repeat;
background-position: 0 -166px;
@@ -22,17 +22,17 @@ body {
}
#foreground {
- width:900px;
- height:520px;
+ width: 900px;
+ height: 520px;
position: absolute;
background: url(backgroundsprite.png) no-repeat center;
background-position: 0 -575px;
- z-index:10;
+ z-index: 10;
}
#crane {
- width:100px;
- height:100px;
+ width: 100px;
+ height: 100px;
position: absolute;
top: 131px;
left: 100px;
@@ -43,13 +43,13 @@ body {
height: 83px;
position: absolute;
background: url('crane_top.png') repeat-y center;
- bottom: 86px;/*top: -69px;*/
+ bottom: 86px; /*top: -69px;*/
left: 47px;
}
#crane-handle-bottom {
- width:10px;
- height:8px;
+ width: 10px;
+ height: 8px;
position: absolute;
background: url('clawpieces.png') no-repeat center;
top: 14px;
@@ -57,7 +57,7 @@ body {
background-position: -198px -83px;
}
-#crane-center{
+#crane-center {
width: 26px;
height: 27px;
position: absolute;
diff --git a/html/browser/autocomplete.js b/html/browser/autocomplete.js
index 1ca11553b9985..63710c4d8cca2 100644
--- a/html/browser/autocomplete.js
+++ b/html/browser/autocomplete.js
@@ -4,50 +4,49 @@ var submitButton;
var optionsMap = {};
function updateTopic() {
- if (!input || !submitButton) {
- return;
- }
-
- var hrefList = submitButton.getAttribute('href').split(';');
- // Topic must come last in the submit button for this to work
- hrefList = hrefList.slice(0, hrefList.length - 1);
- hrefList.push(optionsMap[input.value] ? 'submit=' + optionsMap[input.value] : '');
- submitButton.setAttribute('href', hrefList.join(';'));
+ if (!input || !submitButton) {
+ return;
+ }
+
+ var hrefList = submitButton.getAttribute('href').split(';');
+ // Topic must come last in the submit button for this to work
+ hrefList = hrefList.slice(0, hrefList.length - 1);
+ hrefList.push(optionsMap[input.value] ? 'submit=' + optionsMap[input.value] : '');
+ submitButton.setAttribute('href', hrefList.join(';'));
}
function setElements() {
- input = $('#input');
- submitButton = $('#submit-button');
- var choices = $('#choices');
-
- if (!input || !submitButton || !choices) {
- return;
- }
-
-
- for (var i = 0; i < choices.options.length; i++) {
- var name = choices.options[i].value;
- var cleaned = decodeURI(name);
- optionsMap[cleaned] = name;
- choices.options[i].value = cleaned;
- }
-
- input.addEventListener('keyup', function(event) {
- if (event.key !== 'Enter') {
- return;
- }
-
- if (Object.keys(optionsMap).indexOf(input.value) === -1) {
- // Byond doesn't let you to use enter to select
- // so we need to prevent unintended submissions
- return
- }
-
- submitButton.click();
- event.preventDefault();
- });
-
- input.focus();
+ input = $('#input');
+ submitButton = $('#submit-button');
+ var choices = $('#choices');
+
+ if (!input || !submitButton || !choices) {
+ return;
+ }
+
+ for (var i = 0; i < choices.options.length; i++) {
+ var name = choices.options[i].value;
+ var cleaned = decodeURI(name);
+ optionsMap[cleaned] = name;
+ choices.options[i].value = cleaned;
+ }
+
+ input.addEventListener('keyup', function (event) {
+ if (event.key !== 'Enter') {
+ return;
+ }
+
+ if (Object.keys(optionsMap).indexOf(input.value) === -1) {
+ // Byond doesn't let you to use enter to select
+ // so we need to prevent unintended submissions
+ return;
+ }
+
+ submitButton.click();
+ event.preventDefault();
+ });
+
+ input.focus();
}
window.onload = setElements;
diff --git a/html/browser/boardui.js b/html/browser/boardui.js
index 68ee667a355a2..3dc410e3a7740 100644
--- a/html/browser/boardui.js
+++ b/html/browser/boardui.js
@@ -11,385 +11,395 @@ var g_uiBoard;
var g_cellSize = 45;
function UINewGame() {
- moveNumber = 1;
-
- var pgnTextBox = document.getElementById("PgnTextBox");
- pgnTextBox.value = "";
-
- EnsureAnalysisStopped();
- ResetGame();
- if (InitializeBackgroundEngine()) {
- g_backgroundEngine.postMessage("go");
- }
- g_allMoves = [];
- RedrawBoard();
-
- if (!g_playerWhite) {
- SearchAndRedraw();
- }
+ moveNumber = 1;
+
+ var pgnTextBox = document.getElementById('PgnTextBox');
+ pgnTextBox.value = '';
+
+ EnsureAnalysisStopped();
+ ResetGame();
+ if (InitializeBackgroundEngine()) {
+ g_backgroundEngine.postMessage('go');
+ }
+ g_allMoves = [];
+ RedrawBoard();
+
+ if (!g_playerWhite) {
+ SearchAndRedraw();
+ }
}
function UIClose() {
- window.location = "byond://?src=" + hSrc + ";close=1";
+ window.location = 'byond://?src=' + hSrc + ';close=1';
}
function EnsureAnalysisStopped() {
- if (g_analyzing && g_backgroundEngine != null) {
- g_backgroundEngine.terminate();
- g_backgroundEngine = null;
- }
+ if (g_analyzing && g_backgroundEngine != null) {
+ g_backgroundEngine.terminate();
+ g_backgroundEngine = null;
+ }
}
function UIAnalyzeToggle() {
- if (InitializeBackgroundEngine()) {
- if (!g_analyzing) {
- g_backgroundEngine.postMessage("analyze");
- } else {
- EnsureAnalysisStopped();
- }
- g_analyzing = !g_analyzing;
- document.getElementById("AnalysisToggleLink").innerText = g_analyzing ? "Analysis: On" : "Analysis: Off";
- } else {
- alert("Your browser must support web workers for analysis - (chrome4, ff4, safari)");
- }
+ if (InitializeBackgroundEngine()) {
+ if (!g_analyzing) {
+ g_backgroundEngine.postMessage('analyze');
+ } else {
+ EnsureAnalysisStopped();
+ }
+ g_analyzing = !g_analyzing;
+ document.getElementById('AnalysisToggleLink').innerText = g_analyzing ? 'Analysis: On' : 'Analysis: Off';
+ } else {
+ alert('Your browser must support web workers for analysis - (chrome4, ff4, safari)');
+ }
}
function UIChangeFEN() {
- if (!g_changingFen) {
- var fenTextBox = document.getElementById("FenTextBox");
- var result = InitializeFromFen(fenTextBox.value);
- if (result.length != 0) {
- UpdatePVDisplay(result);
- return;
- } else {
- UpdatePVDisplay('');
- }
- g_allMoves = [];
-
- EnsureAnalysisStopped();
- InitializeBackgroundEngine();
-
- g_playerWhite = !!g_toMove;
- g_backgroundEngine.postMessage("position " + GetFen());
-
- RedrawBoard();
- }
+ if (!g_changingFen) {
+ var fenTextBox = document.getElementById('FenTextBox');
+ var result = InitializeFromFen(fenTextBox.value);
+ if (result.length != 0) {
+ UpdatePVDisplay(result);
+ return;
+ } else {
+ UpdatePVDisplay('');
+ }
+ g_allMoves = [];
+
+ EnsureAnalysisStopped();
+ InitializeBackgroundEngine();
+
+ g_playerWhite = !!g_toMove;
+ g_backgroundEngine.postMessage('position ' + GetFen());
+
+ RedrawBoard();
+ }
}
function UIChangeStartPlayer() {
- g_playerWhite = !g_playerWhite;
- RedrawBoard();
+ g_playerWhite = !g_playerWhite;
+ RedrawBoard();
}
function UpdatePgnTextBox(move) {
- var pgnTextBox = document.getElementById("PgnTextBox");
- if (g_toMove != 0) {
- pgnTextBox.value += moveNumber + ". ";
- moveNumber++;
- }
- pgnTextBox.value += GetMoveSAN(move) + " ";
+ var pgnTextBox = document.getElementById('PgnTextBox');
+ if (g_toMove != 0) {
+ pgnTextBox.value += moveNumber + '. ';
+ moveNumber++;
+ }
+ pgnTextBox.value += GetMoveSAN(move) + ' ';
}
function UIChangeTimePerMove() {
- var timePerMove = document.getElementById("TimePerMove");
- g_timeout = parseInt(timePerMove.value, 10);
+ var timePerMove = document.getElementById('TimePerMove');
+ g_timeout = parseInt(timePerMove.value, 10);
}
function FinishMove(bestMove, value, timeTaken, ply) {
- if (bestMove != null) {
- UIPlayMove(bestMove, BuildPVMessage(bestMove, value, timeTaken, ply));
- } else {
- window.location = "byond://?src=" + hSrc + ";checkmate=1";
- }
+ if (bestMove != null) {
+ UIPlayMove(bestMove, BuildPVMessage(bestMove, value, timeTaken, ply));
+ } else {
+ window.location = 'byond://?src=' + hSrc + ';checkmate=1';
+ }
}
function UIPlayMove(move, pv) {
- UpdatePgnTextBox(move);
+ UpdatePgnTextBox(move);
- g_allMoves[g_allMoves.length] = move;
- MakeMove(move);
+ g_allMoves[g_allMoves.length] = move;
+ MakeMove(move);
- UpdatePVDisplay(pv);
+ UpdatePVDisplay(pv);
- UpdateFromMove(move);
+ UpdateFromMove(move);
}
function UIUndoMove() {
- if (g_allMoves.length == 0) {
- return;
- }
+ if (g_allMoves.length == 0) {
+ return;
+ }
- if (g_backgroundEngine != null) {
- g_backgroundEngine.terminate();
- g_backgroundEngine = null;
- }
+ if (g_backgroundEngine != null) {
+ g_backgroundEngine.terminate();
+ g_backgroundEngine = null;
+ }
- UnmakeMove(g_allMoves[g_allMoves.length - 1]);
- g_allMoves.pop();
+ UnmakeMove(g_allMoves[g_allMoves.length - 1]);
+ g_allMoves.pop();
- if (g_playerWhite != !!g_toMove && g_allMoves.length != 0) {
- UnmakeMove(g_allMoves[g_allMoves.length - 1]);
- g_allMoves.pop();
- }
+ if (g_playerWhite != !!g_toMove && g_allMoves.length != 0) {
+ UnmakeMove(g_allMoves[g_allMoves.length - 1]);
+ g_allMoves.pop();
+ }
- RedrawBoard();
+ RedrawBoard();
}
function UpdatePVDisplay(pv) {
- if (pv != null) {
- var outputDiv = document.getElementById("output");
- if (outputDiv.firstChild != null) {
- outputDiv.removeChild(outputDiv.firstChild);
- }
- outputDiv.appendChild(document.createTextNode(pv));
- }
+ if (pv != null) {
+ var outputDiv = document.getElementById('output');
+ if (outputDiv.firstChild != null) {
+ outputDiv.removeChild(outputDiv.firstChild);
+ }
+ outputDiv.appendChild(document.createTextNode(pv));
+ }
}
function SearchAndRedraw() {
- if (g_analyzing) {
- EnsureAnalysisStopped();
- InitializeBackgroundEngine();
- g_backgroundEngine.postMessage("position " + GetFen());
- g_backgroundEngine.postMessage("analyze");
- return;
- }
-
- if (InitializeBackgroundEngine()) {
- g_backgroundEngine.postMessage("search " + g_timeout);
- } else {
- Search(FinishMove, 99, null);
- }
+ if (g_analyzing) {
+ EnsureAnalysisStopped();
+ InitializeBackgroundEngine();
+ g_backgroundEngine.postMessage('position ' + GetFen());
+ g_backgroundEngine.postMessage('analyze');
+ return;
+ }
+
+ if (InitializeBackgroundEngine()) {
+ g_backgroundEngine.postMessage('search ' + g_timeout);
+ } else {
+ Search(FinishMove, 99, null);
+ }
}
var g_backgroundEngineValid = true;
var g_backgroundEngine;
function InitializeBackgroundEngine() {
- if (!g_backgroundEngineValid) {
- return false;
- }
-
- if (g_backgroundEngine == null) {
- g_backgroundEngineValid = true;
- try {
- g_backgroundEngine = new Worker("garbochess.js");
- g_backgroundEngine.onmessage = function (e) {
- if (e.data.match("^pv") == "pv") {
- UpdatePVDisplay(e.data.substr(3, e.data.length - 3));
- } else if (e.data.match("^message") == "message") {
- EnsureAnalysisStopped();
- UpdatePVDisplay(e.data.substr(8, e.data.length - 8));
- } else {
- UIPlayMove(GetMoveFromString(e.data), null);
- }
- }
- g_backgroundEngine.error = function (e) {
- alert("Error from background worker:" + e.message);
- }
- g_backgroundEngine.postMessage("position " + GetFen());
- } catch (error) {
- g_backgroundEngineValid = false;
- }
- }
-
- return g_backgroundEngineValid;
+ if (!g_backgroundEngineValid) {
+ return false;
+ }
+
+ if (g_backgroundEngine == null) {
+ g_backgroundEngineValid = true;
+ try {
+ g_backgroundEngine = new Worker('garbochess.js');
+ g_backgroundEngine.onmessage = function (e) {
+ if (e.data.match('^pv') == 'pv') {
+ UpdatePVDisplay(e.data.substr(3, e.data.length - 3));
+ } else if (e.data.match('^message') == 'message') {
+ EnsureAnalysisStopped();
+ UpdatePVDisplay(e.data.substr(8, e.data.length - 8));
+ } else {
+ UIPlayMove(GetMoveFromString(e.data), null);
+ }
+ };
+ g_backgroundEngine.error = function (e) {
+ alert('Error from background worker:' + e.message);
+ };
+ g_backgroundEngine.postMessage('position ' + GetFen());
+ } catch (error) {
+ g_backgroundEngineValid = false;
+ }
+ }
+
+ return g_backgroundEngineValid;
}
function UpdateFromMove(move) {
- var fromX = (move & 0xF) - 4;
- var fromY = ((move >> 4) & 0xF) - 2;
- var toX = ((move >> 8) & 0xF) - 4;
- var toY = ((move >> 12) & 0xF) - 2;
-
- if (!g_playerWhite) {
- fromY = 7 - fromY;
- toY = 7 - toY;
- fromX = 7 - fromX;
- toX = 7 - toX;
- }
-
- if ((move & moveflagCastleKing) ||
- (move & moveflagCastleQueen) ||
- (move & moveflagEPC) ||
- (move & moveflagPromotion)) {
- RedrawPieces();
- } else {
- var fromSquare = g_uiBoard[fromY * 8 + fromX];
- $(g_uiBoard[toY * 8 + toX])
- .empty()
- .append($(fromSquare).children());
- }
+ var fromX = (move & 0xf) - 4;
+ var fromY = ((move >> 4) & 0xf) - 2;
+ var toX = ((move >> 8) & 0xf) - 4;
+ var toY = ((move >> 12) & 0xf) - 2;
+
+ if (!g_playerWhite) {
+ fromY = 7 - fromY;
+ toY = 7 - toY;
+ fromX = 7 - fromX;
+ toX = 7 - toX;
+ }
+
+ if (move & moveflagCastleKing || move & moveflagCastleQueen || move & moveflagEPC || move & moveflagPromotion) {
+ RedrawPieces();
+ } else {
+ var fromSquare = g_uiBoard[fromY * 8 + fromX];
+ $(g_uiBoard[toY * 8 + toX])
+ .empty()
+ .append($(fromSquare).children());
+ }
}
function RedrawPieces() {
- for (y = 0; y < 8; ++y) {
- for (x = 0; x < 8; ++x) {
- var td = g_uiBoard[y * 8 + x];
- var pieceY = g_playerWhite ? y : 7 - y;
- var piece = g_board[((pieceY + 2) * 0x10) + (g_playerWhite ? x : 7 - x) + 4];
- var pieceName = null;
- switch (piece & 0x7) {
- case piecePawn: pieceName = "pawn"; break;
- case pieceKnight: pieceName = "knight"; break;
- case pieceBishop: pieceName = "bishop"; break;
- case pieceRook: pieceName = "rook"; break;
- case pieceQueen: pieceName = "queen"; break;
- case pieceKing: pieceName = "king"; break;
- }
- if (pieceName != null) {
- pieceName += "_";
- pieceName += (piece & 0x8) ? "white" : "black";
- }
-
- if (pieceName != null) {
- var img = document.createElement("div");
- $(img).addClass('sprite-' + pieceName);
- img.style.backgroundImage = "url('sprites.png')";
- img.width = g_cellSize;
- img.height = g_cellSize;
- var divimg = document.createElement("div");
- divimg.appendChild(img);
-
- $(divimg).draggable({ start: function (e, ui) {
- if (g_selectedPiece === null) {
- g_selectedPiece = this;
- var offset = $(this).closest('table').offset();
- g_startOffset = {
- left: e.pageX - offset.left,
- top: e.pageY - offset.top
- };
- } else {
- return g_selectedPiece == this;
- }
- }});
-
- $(divimg).mousedown(function(e) {
- if (g_selectedPiece === null) {
- var offset = $(this).closest('table').offset();
- g_startOffset = {
- left: e.pageX - offset.left,
- top: e.pageY - offset.top
- };
- e.stopPropagation();
- g_selectedPiece = this;
- g_selectedPiece.style.backgroundImage = "url('img/transpBlue50.png')";
- } else if (g_selectedPiece === this) {
- g_selectedPiece.style.backgroundImage = null;
- g_selectedPiece = null;
- }
- });
-
- $(td).empty().append(divimg);
- } else {
- $(td).empty();
- }
- }
- }
+ for (y = 0; y < 8; ++y) {
+ for (x = 0; x < 8; ++x) {
+ var td = g_uiBoard[y * 8 + x];
+ var pieceY = g_playerWhite ? y : 7 - y;
+ var piece = g_board[(pieceY + 2) * 0x10 + (g_playerWhite ? x : 7 - x) + 4];
+ var pieceName = null;
+ switch (piece & 0x7) {
+ case piecePawn:
+ pieceName = 'pawn';
+ break;
+ case pieceKnight:
+ pieceName = 'knight';
+ break;
+ case pieceBishop:
+ pieceName = 'bishop';
+ break;
+ case pieceRook:
+ pieceName = 'rook';
+ break;
+ case pieceQueen:
+ pieceName = 'queen';
+ break;
+ case pieceKing:
+ pieceName = 'king';
+ break;
+ }
+ if (pieceName != null) {
+ pieceName += '_';
+ pieceName += piece & 0x8 ? 'white' : 'black';
+ }
+
+ if (pieceName != null) {
+ var img = document.createElement('div');
+ $(img).addClass('sprite-' + pieceName);
+ img.style.backgroundImage = "url('sprites.png')";
+ img.width = g_cellSize;
+ img.height = g_cellSize;
+ var divimg = document.createElement('div');
+ divimg.appendChild(img);
+
+ $(divimg).draggable({
+ start: function (e, ui) {
+ if (g_selectedPiece === null) {
+ g_selectedPiece = this;
+ var offset = $(this).closest('table').offset();
+ g_startOffset = {
+ left: e.pageX - offset.left,
+ top: e.pageY - offset.top,
+ };
+ } else {
+ return g_selectedPiece == this;
+ }
+ },
+ });
+
+ $(divimg).mousedown(function (e) {
+ if (g_selectedPiece === null) {
+ var offset = $(this).closest('table').offset();
+ g_startOffset = {
+ left: e.pageX - offset.left,
+ top: e.pageY - offset.top,
+ };
+ e.stopPropagation();
+ g_selectedPiece = this;
+ g_selectedPiece.style.backgroundImage = "url('img/transpBlue50.png')";
+ } else if (g_selectedPiece === this) {
+ g_selectedPiece.style.backgroundImage = null;
+ g_selectedPiece = null;
+ }
+ });
+
+ $(td).empty().append(divimg);
+ } else {
+ $(td).empty();
+ }
+ }
+ }
}
function RedrawBoard() {
- var div = $("#board")[0];
+ var div = $('#board')[0];
- var table = document.createElement("table");
- table.cellPadding = "0px";
- table.cellSpacing = "0px";
- $(table).addClass('no-highlight');
-
- var tbody = document.createElement("tbody");
-
- g_uiBoard = [];
-
- var dropPiece = function (e, ui) {
- var endX = e.pageX - $(table).offset().left;
- var endY = e.pageY - $(table).offset().top;
-
- endX = Math.floor(endX / g_cellSize);
- endY = Math.floor(endY / g_cellSize);
-
- var startX = Math.floor(g_startOffset.left / g_cellSize);
- var startY = Math.floor(g_startOffset.top / g_cellSize);
-
- if (!g_playerWhite) {
- startY = 7 - startY;
- endY = 7 - endY;
- startX = 7 - startX;
- endX = 7 - endX;
- }
-
- var moves = GenerateValidMoves();
- var move = null;
- for (var i = 0; i < moves.length; i++) {
- if ((moves[i] & 0xFF) == MakeSquare(startY, startX) &&
- ((moves[i] >> 8) & 0xFF) == MakeSquare(endY, endX)) {
- move = moves[i];
- }
- }
-
- if (!g_playerWhite) {
- startY = 7 - startY;
- endY = 7 - endY;
- startX = 7 - startX;
- endX = 7 - endX;
- }
-
- g_selectedPiece.style.left = 0;
- g_selectedPiece.style.top = 0;
-
- if (!(startX == endX && startY == endY) && move != null) {
- UpdatePgnTextBox(move);
-
- if (InitializeBackgroundEngine()) {
- g_backgroundEngine.postMessage(FormatMove(move));
- }
-
- g_allMoves[g_allMoves.length] = move;
- MakeMove(move);
-
- UpdateFromMove(move);
-
- g_selectedPiece.style.backgroundImage = null;
- g_selectedPiece = null;
-
- var fen = GetFen();
- document.getElementById("FenTextBox").value = fen;
-
- setTimeout("SearchAndRedraw()", 0);
- } else {
- g_selectedPiece.style.backgroundImage = null;
- g_selectedPiece = null;
- }
- };
-
- for (y = 0; y < 8; ++y) {
- var tr = document.createElement("tr");
-
- for (x = 0; x < 8; ++x) {
- var td = document.createElement("td");
- td.style.width = g_cellSize + "px";
- td.style.height = g_cellSize + "px";
- td.style.backgroundColor = ((y ^ x) & 1) ? "#D18947" : "#FFCE9E";
- tr.appendChild(td);
- g_uiBoard[y * 8 + x] = td;
- }
-
- tbody.appendChild(tr);
- }
-
- table.appendChild(tbody);
-
- $('body').droppable({ drop: dropPiece });
- $(table).mousedown(function(e) {
- if (g_selectedPiece !== null) {
- dropPiece(e);
- }
- });
-
- RedrawPieces();
-
- $(div).empty();
- div.appendChild(table);
-
- g_changingFen = true;
- document.getElementById("FenTextBox").value = GetFen();
- g_changingFen = false;
+ var table = document.createElement('table');
+ table.cellPadding = '0px';
+ table.cellSpacing = '0px';
+ $(table).addClass('no-highlight');
+
+ var tbody = document.createElement('tbody');
+
+ g_uiBoard = [];
+
+ var dropPiece = function (e, ui) {
+ var endX = e.pageX - $(table).offset().left;
+ var endY = e.pageY - $(table).offset().top;
+
+ endX = Math.floor(endX / g_cellSize);
+ endY = Math.floor(endY / g_cellSize);
+
+ var startX = Math.floor(g_startOffset.left / g_cellSize);
+ var startY = Math.floor(g_startOffset.top / g_cellSize);
+
+ if (!g_playerWhite) {
+ startY = 7 - startY;
+ endY = 7 - endY;
+ startX = 7 - startX;
+ endX = 7 - endX;
+ }
+
+ var moves = GenerateValidMoves();
+ var move = null;
+ for (var i = 0; i < moves.length; i++) {
+ if ((moves[i] & 0xff) == MakeSquare(startY, startX) && ((moves[i] >> 8) & 0xff) == MakeSquare(endY, endX)) {
+ move = moves[i];
+ }
+ }
+
+ if (!g_playerWhite) {
+ startY = 7 - startY;
+ endY = 7 - endY;
+ startX = 7 - startX;
+ endX = 7 - endX;
+ }
+
+ g_selectedPiece.style.left = 0;
+ g_selectedPiece.style.top = 0;
+
+ if (!(startX == endX && startY == endY) && move != null) {
+ UpdatePgnTextBox(move);
+
+ if (InitializeBackgroundEngine()) {
+ g_backgroundEngine.postMessage(FormatMove(move));
+ }
+
+ g_allMoves[g_allMoves.length] = move;
+ MakeMove(move);
+
+ UpdateFromMove(move);
+
+ g_selectedPiece.style.backgroundImage = null;
+ g_selectedPiece = null;
+
+ var fen = GetFen();
+ document.getElementById('FenTextBox').value = fen;
+
+ setTimeout('SearchAndRedraw()', 0);
+ } else {
+ g_selectedPiece.style.backgroundImage = null;
+ g_selectedPiece = null;
+ }
+ };
+
+ for (y = 0; y < 8; ++y) {
+ var tr = document.createElement('tr');
+
+ for (x = 0; x < 8; ++x) {
+ var td = document.createElement('td');
+ td.style.width = g_cellSize + 'px';
+ td.style.height = g_cellSize + 'px';
+ td.style.backgroundColor = (y ^ x) & 1 ? '#D18947' : '#FFCE9E';
+ tr.appendChild(td);
+ g_uiBoard[y * 8 + x] = td;
+ }
+
+ tbody.appendChild(tr);
+ }
+
+ table.appendChild(tbody);
+
+ $('body').droppable({ drop: dropPiece });
+ $(table).mousedown(function (e) {
+ if (g_selectedPiece !== null) {
+ dropPiece(e);
+ }
+ });
+
+ RedrawPieces();
+
+ $(div).empty();
+ div.appendChild(table);
+
+ g_changingFen = true;
+ document.getElementById('FenTextBox').value = GetFen();
+ g_changingFen = false;
}
diff --git a/html/browser/chess.css b/html/browser/chess.css
index 43c61a04cf445..5835ca5491fd9 100644
--- a/html/browser/chess.css
+++ b/html/browser/chess.css
@@ -1,23 +1,71 @@
- #FenTextBox {
- width: 400px;
- }
- #TimePerMove {
- width: 50px;
- }
- .no-highlight {
- -webkit-tap-highlight-color: rgba(0,0,0,0);
- }
- .sprite-bishop_black{ background-position: 0 0; width: 45px; height: 45px; }
- .sprite-bishop_white{ background-position: 0 -95px; width: 45px; height: 45px; }
- .sprite-king_black{ background-position: 0 -190px; width: 45px; height: 45px; }
- .sprite-king_white{ background-position: 0 -285px; width: 45px; height: 45px; }
- .sprite-knight_black{ background-position: 0 -380px; width: 45px; height: 45px; }
- .sprite-knight_white{ background-position: 0 -475px; width: 45px; height: 45px; }
- .sprite-pawn_black{ background-position: 0 -570px; width: 45px; height: 45px; }
- .sprite-pawn_white{ background-position: 0 -665px; width: 45px; height: 45px; }
- .sprite-queen_black{ background-position: 0 -760px; width: 45px; height: 45px; }
- .sprite-queen_white{ background-position: 0 -855px; width: 45px; height: 45px; }
- .sprite-rook_black{ background-position: 0 -950px; width: 45px; height: 45px; }
- .sprite-rook_white{ background-position: 0 -1045px; width: 45px; height: 45px; }
- background-image:url(background.png) no-repeat center center fixed;
- background-size:cover;
\ No newline at end of file
+#FenTextBox {
+ width: 400px;
+}
+#TimePerMove {
+ width: 50px;
+}
+.no-highlight {
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+.sprite-bishop_black {
+ background-position: 0 0;
+ width: 45px;
+ height: 45px;
+}
+.sprite-bishop_white {
+ background-position: 0 -95px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-king_black {
+ background-position: 0 -190px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-king_white {
+ background-position: 0 -285px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-knight_black {
+ background-position: 0 -380px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-knight_white {
+ background-position: 0 -475px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-pawn_black {
+ background-position: 0 -570px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-pawn_white {
+ background-position: 0 -665px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-queen_black {
+ background-position: 0 -760px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-queen_white {
+ background-position: 0 -855px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-rook_black {
+ background-position: 0 -950px;
+ width: 45px;
+ height: 45px;
+}
+.sprite-rook_white {
+ background-position: 0 -1045px;
+ width: 45px;
+ height: 45px;
+}
+background-image: url(background.png) no-repeat center center fixed;
+background-size: cover;
diff --git a/html/browser/common.css b/html/browser/common.css
index 3332473586a58..669054092b4a2 100644
--- a/html/browser/common.css
+++ b/html/browser/common.css
@@ -1,5 +1,4 @@
-body
-{
+body {
padding: 0;
margin: 0;
background-color: #272727;
@@ -8,107 +7,113 @@ body
line-height: 170%;
}
-hr
-{
+hr {
background-color: #40628a;
height: 1px;
}
-a, a:link, a:visited, a:active, .linkOn, .linkOff
-{
+a,
+a:link,
+a:visited,
+a:active,
+.linkOn,
+.linkOff {
color: #ffffff;
text-decoration: none;
background: #40628a;
border: 1px solid #161616;
padding: 1px 4px 1px 4px;
margin: 0 2px 0 0;
- cursor:default;
+ cursor: default;
}
-a.nobg, a.nobg:link, a.nobg:visited, a.nobg:active
-{
+a.nobg,
+a.nobg:link,
+a.nobg:visited,
+a.nobg:active {
color: #ffffff;
text-decoration: none;
background: transparent;
border: none;
padding: 0px;
margin: 0px;
- cursor:default;
- font-weight:bold;
+ cursor: default;
+ font-weight: bold;
}
-a.nobg:hover
-{
- color:#40628a;
+a.nobg:hover {
+ color: #40628a;
}
-a:hover
-{
+a:hover {
color: #40628a;
background: #ffffff;
}
-
-a.red
-{
+a.red {
background: #b30000;
}
-a.red:hover
-{
+a.red:hover {
color: #ffffff;
background: #ff0000;
}
-a.green
-{
+a.green {
background: #408000;
}
-a.green:hover
-{
+a.green:hover {
color: #ffffff;
background: #59b300;
}
-a.white, a.white:link, a.white:visited, a.white:active
-{
+a.white,
+a.white:link,
+a.white:visited,
+a.white:active {
color: #40628a;
text-decoration: none;
background: #ffffff;
border: 1px solid #161616;
padding: 1px 4px 1px 4px;
margin: 0 2px 0 0;
- cursor:default;
+ cursor: default;
}
-a.white:hover
-{
+a.white:hover {
color: #ffffff;
background: #40628a;
}
-.linkOn, a.linkOn:link, a.linkOn:visited, a.linkOn:active, a.linkOn:hover
-{
+.linkOn,
+a.linkOn:link,
+a.linkOn:visited,
+a.linkOn:active,
+a.linkOn:hover {
color: #ffffff;
background: #2f943c;
border-color: #24722e;
}
-.linkOff, a.linkOff:link, a.linkOff:visited, a.linkOff:active, a.linkOff:hover
-{
+.linkOff,
+a.linkOff:link,
+a.linkOff:visited,
+a.linkOff:active,
+a.linkOff:hover {
color: #ffffff;
background: #999999;
border-color: #666666;
}
-a.icon, .linkOn.icon, .linkOff.icon
-{
+a.icon,
+.linkOn.icon,
+.linkOff.icon {
position: relative;
padding: 1px 4px 2px 20px;
}
-a.icon img, .linkOn.icon img
-{
+a.icon img,
+.linkOn.icon img {
position: absolute;
top: 0;
left: 0;
@@ -116,144 +121,126 @@ a.icon img, .linkOn.icon img
height: 18px;
}
-ul
-{
+ul {
padding: 4px 0 0 10px;
margin: 0;
list-style-type: none;
}
-li
-{
+li {
padding: 0 0 2px 0;
}
-img, a img
-{
- border-style:none;
+img,
+a img {
+ border-style: none;
}
-h1, h2, h3, h4, h5, h6
-{
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
margin: 0;
padding: 16px 0 8px 0;
color: #517087;
}
-h1
-{
+h1 {
font-size: 15px;
}
-h2
-{
+h2 {
font-size: 14px;
}
-h3
-{
+h3 {
font-size: 13px;
}
-h4
-{
+h4 {
font-size: 12px;
}
-.uiWrapper
-{
-
+.uiWrapper {
width: 100%;
height: 100%;
- padding-top:32px;
+ padding-top: 32px;
}
-.uiTitle
-{
+.uiTitle {
clear: both;
padding: 6px 8px 6px 8px;
border-bottom: 2px solid #161616;
background: #383838;
- color: #98B0C3;
+ color: #98b0c3;
font-size: 16px;
}
-.uiTitleWrapper
- {
- position:fixed;
- top:0px;
- left:0px;
- right:0px;
- z-index: 10
- }
-
- .uiTitleButtons
- {
- position:fixed;
- top:0px;
- right:0px;
- height:32px;
- z-index:11;
- }
+.uiTitleWrapper {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ z-index: 10;
+}
+.uiTitleButtons {
+ position: fixed;
+ top: 0px;
+ right: 0px;
+ height: 32px;
+ z-index: 11;
+}
-.uiTitle.icon
-{
+.uiTitle.icon {
padding: 6px 8px 6px 42px;
background-position: 2px 50%;
background-repeat: no-repeat;
}
-.uiContent
-{
+.uiContent {
clear: both;
padding: 8px;
font-family: Verdana, Geneva, sans-serif;
}
-.good
-{
+.good {
color: #00ff00;
}
-.average
-{
+.average {
color: #d09000;
}
-.bad
-{
+.bad {
color: #ff0000;
}
-.highlight
-{
- color: #8BA5C4;
+.highlight {
+ color: #8ba5c4;
}
-.dark
-{
+.dark {
color: #272727;
}
-.notice
-{
+.notice {
position: relative;
- background: #E9C183;
- color: #15345A;
+ background: #e9c183;
+ color: #15345a;
font-size: 10px;
font-style: italic;
padding: 2px 4px 0 4px;
margin: 4px;
}
-.notice.icon
-{
+.notice.icon {
padding: 2px 4px 0 20px;
}
-.notice img
-{
+.notice img {
position: absolute;
top: 0;
left: 0;
@@ -261,13 +248,11 @@ h4
height: 16px;
}
-div.notice
-{
+div.notice {
clear: both;
}
-.statusDisplay
-{
+.statusDisplay {
background: #000000;
color: #ffffff;
border: 1px solid #40628a;
@@ -275,34 +260,29 @@ div.notice
margin: 3px 0;
}
-.statusLabel
-{
+.statusLabel {
width: 138px;
float: left;
overflow: hidden;
- color: #98B0C3;
+ color: #98b0c3;
}
-.statusValue
-{
+.statusValue {
float: left;
}
-.block
-{
+.block {
padding: 8px;
margin: 10px 4px 4px 4px;
border: 1px solid #40628a;
background-color: #202020;
}
-.block h3
-{
+.block h3 {
padding: 0;
}
-.progressBar
-{
+.progressBar {
width: 240px;
height: 14px;
border: 1px solid #666666;
@@ -311,79 +291,66 @@ div.notice
overflow: hidden;
}
-.progressFill
-{
+.progressFill {
width: 100%;
height: 100%;
background: #40628a;
overflow: hidden;
}
-.progressFill.good
-{
+.progressFill.good {
color: #ffffff;
background: #00ff00;
}
-.progressFill.average
-{
+.progressFill.average {
color: #ffffff;
background: #d09000;
}
-.progressFill.bad
-{
+.progressFill.bad {
color: #ffffff;
background: #ff0000;
}
-.progressFill.highlight
-{
+.progressFill.highlight {
color: #ffffff;
- background: #8BA5C4;
+ background: #8ba5c4;
}
-.clearBoth
-{
+.clearBoth {
clear: both;
}
-.clearLeft
-{
+.clearLeft {
clear: left;
}
-.clearRight
-{
+.clearRight {
clear: right;
}
-.line
-{
+.line {
width: 100%;
clear: both;
}
-.charPreview
-{
+.charPreview {
-ms-interpolation-mode: nearest-neighbor;
width: 64px;
- height:64px;
+ height: 64px;
}
-.typing:after
-{
+.typing:after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
- animation: ellipsis steps(4,end) 900ms infinite;
- content: "\2026";
+ animation: ellipsis steps(4, end) 900ms infinite;
+ content: '\2026';
width: 0px;
}
-@keyframes ellipsis
-{
- to
- {
+@keyframes ellipsis {
+ to {
width: 1.25em;
}
}
diff --git a/html/browser/delay_interactivity.js b/html/browser/delay_interactivity.js
index f621906337b5a..bb6ff1084504e 100644
--- a/html/browser/delay_interactivity.js
+++ b/html/browser/delay_interactivity.js
@@ -1,26 +1,28 @@
// Disables all links for one second after the browser window opens.
-(function(){
- // If there's already an onload, let's not clobber it
- var oldonload = window.onload;
- window.onload = function(){
- if(typeof oldonload == 'function'){
- oldonload();
- }
- var onclicks = Array();
- var links = document.getElementsByTagName("a");
- var returnfalse = function(){return false;};
- for(var i = 0; i < links.length; i++){
- onclicks.push(links[i].onclick);
- links[i].onclick = returnfalse;
- }
- setTimeout(function(){
- for(var i = 0; i < links.length; i++){
- // Reset onclick, but only if something else hasn't already changed it
- if(links[i].onclick == returnfalse){
- links[i].onclick = onclicks[i];
- }
- }
- }, 1000);
- };
+(function () {
+ // If there's already an onload, let's not clobber it
+ var oldonload = window.onload;
+ window.onload = function () {
+ if (typeof oldonload == 'function') {
+ oldonload();
+ }
+ var onclicks = Array();
+ var links = document.getElementsByTagName('a');
+ var returnfalse = function () {
+ return false;
+ };
+ for (var i = 0; i < links.length; i++) {
+ onclicks.push(links[i].onclick);
+ links[i].onclick = returnfalse;
+ }
+ setTimeout(function () {
+ for (var i = 0; i < links.length; i++) {
+ // Reset onclick, but only if something else hasn't already changed it
+ if (links[i].onclick == returnfalse) {
+ links[i].onclick = onclicks[i];
+ }
+ }
+ }, 1000);
+ };
})();
diff --git a/html/browser/garbochess.js b/html/browser/garbochess.js
index 7e94bea53d96d..eeccb68df3ee2 100644
--- a/html/browser/garbochess.js
+++ b/html/browser/garbochess.js
@@ -1,4 +1,4 @@
-"use strict";
+'use strict';
// Perf TODO:
// Merge material updating with psq values
@@ -15,89 +15,80 @@
var g_debug = true;
var g_timeout = 40;
-function GetFen(){
- var result = "";
- for (var row = 0; row < 8; row++) {
- if (row != 0)
- result += '/';
- var empty = 0;
- for (var col = 0; col < 8; col++) {
- var piece = g_board[((row + 2) << 4) + col + 4];
- if (piece == 0) {
- empty++;
- }
- else {
- if (empty != 0)
- result += empty;
- empty = 0;
-
- var pieceChar = [" ", "p", "n", "b", "r", "q", "k", " "][(piece & 0x7)];
- result += ((piece & colorWhite) != 0) ? pieceChar.toUpperCase() : pieceChar;
- }
- }
- if (empty != 0) {
- result += empty;
- }
- }
-
- result += g_toMove == colorWhite ? " w" : " b";
- result += " ";
- if (g_castleRights == 0) {
- result += "-";
- }
- else {
- if ((g_castleRights & 1) != 0)
- result += "K";
- if ((g_castleRights & 2) != 0)
- result += "Q";
- if ((g_castleRights & 4) != 0)
- result += "k";
- if ((g_castleRights & 8) != 0)
- result += "q";
- }
-
- result += " ";
-
- if (g_enPassentSquare == -1) {
- result += '-';
- }
- else {
- result += FormatSquare(g_enPassentSquare);
- }
-
- return result;
+function GetFen() {
+ var result = '';
+ for (var row = 0; row < 8; row++) {
+ if (row != 0) result += '/';
+ var empty = 0;
+ for (var col = 0; col < 8; col++) {
+ var piece = g_board[((row + 2) << 4) + col + 4];
+ if (piece == 0) {
+ empty++;
+ } else {
+ if (empty != 0) result += empty;
+ empty = 0;
+
+ var pieceChar = [' ', 'p', 'n', 'b', 'r', 'q', 'k', ' '][piece & 0x7];
+ result += (piece & colorWhite) != 0 ? pieceChar.toUpperCase() : pieceChar;
+ }
+ }
+ if (empty != 0) {
+ result += empty;
+ }
+ }
+
+ result += g_toMove == colorWhite ? ' w' : ' b';
+ result += ' ';
+ if (g_castleRights == 0) {
+ result += '-';
+ } else {
+ if ((g_castleRights & 1) != 0) result += 'K';
+ if ((g_castleRights & 2) != 0) result += 'Q';
+ if ((g_castleRights & 4) != 0) result += 'k';
+ if ((g_castleRights & 8) != 0) result += 'q';
+ }
+
+ result += ' ';
+
+ if (g_enPassentSquare == -1) {
+ result += '-';
+ } else {
+ result += FormatSquare(g_enPassentSquare);
+ }
+
+ return result;
}
function GetMoveSAN(move, validMoves) {
- var from = move & 0xFF;
- var to = (move >> 8) & 0xFF;
-
- if (move & moveflagCastleKing) return "O-O";
- if (move & moveflagCastleQueen) return "O-O-O";
-
+ var from = move & 0xff;
+ var to = (move >> 8) & 0xff;
+
+ if (move & moveflagCastleKing) return 'O-O';
+ if (move & moveflagCastleQueen) return 'O-O-O';
+
var pieceType = g_board[from] & 0x7;
- var result = ["", "", "N", "B", "R", "Q", "K", ""][pieceType];
-
- var dupe = false, rowDiff = true, colDiff = true;
+ var result = ['', '', 'N', 'B', 'R', 'Q', 'K', ''][pieceType];
+
+ var dupe = false,
+ rowDiff = true,
+ colDiff = true;
if (validMoves == null) {
validMoves = GenerateValidMoves();
}
for (var i = 0; i < validMoves.length; i++) {
- var moveFrom = validMoves[i] & 0xFF;
- var moveTo = (validMoves[i] >> 8) & 0xFF;
- if (moveFrom != from &&
- moveTo == to &&
- (g_board[moveFrom] & 0x7) == pieceType) {
+ var moveFrom = validMoves[i] & 0xff;
+ var moveTo = (validMoves[i] >> 8) & 0xff;
+ if (moveFrom != from && moveTo == to && (g_board[moveFrom] & 0x7) == pieceType) {
dupe = true;
- if ((moveFrom & 0xF0) == (from & 0xF0)) {
+ if ((moveFrom & 0xf0) == (from & 0xf0)) {
rowDiff = false;
}
- if ((moveFrom & 0x0F) == (from & 0x0F)) {
+ if ((moveFrom & 0x0f) == (from & 0x0f)) {
colDiff = false;
}
}
}
-
+
if (dupe) {
if (colDiff) {
result += FormatSquare(from).charAt(0);
@@ -106,26 +97,26 @@ function GetMoveSAN(move, validMoves) {
} else {
result += FormatSquare(from);
}
- } else if (pieceType == piecePawn && (g_board[to] != 0 || (move & moveflagEPC))) {
+ } else if (pieceType == piecePawn && (g_board[to] != 0 || move & moveflagEPC)) {
result += FormatSquare(from).charAt(0);
}
-
- if (g_board[to] != 0 || (move & moveflagEPC)) {
- result += "x";
+
+ if (g_board[to] != 0 || move & moveflagEPC) {
+ result += 'x';
}
-
+
result += FormatSquare(to);
-
+
if (move & moveflagPromotion) {
- if (move & moveflagPromoteBishop) result += "=B";
- else if (move & moveflagPromoteKnight) result += "=N";
- else if (move & moveflagPromoteQueen) result += "=Q";
- else result += "=R";
+ if (move & moveflagPromoteBishop) result += '=B';
+ else if (move & moveflagPromoteKnight) result += '=N';
+ else if (move & moveflagPromoteQueen) result += '=Q';
+ else result += '=R';
}
MakeMove(move);
if (g_inCheck) {
- result += GenerateValidMoves().length == 0 ? "#" : "+";
+ result += GenerateValidMoves().length == 0 ? '#' : '+';
}
UnmakeMove(move);
@@ -133,51 +124,50 @@ function GetMoveSAN(move, validMoves) {
}
function FormatSquare(square) {
- var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
- return letters[(square & 0xF) - 4] + ((9 - (square >> 4)) + 1);
+ var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
+ return letters[(square & 0xf) - 4] + (9 - (square >> 4) + 1);
}
function FormatMove(move) {
- var result = FormatSquare(move & 0xFF) + FormatSquare((move >> 8) & 0xFF);
- if (move & moveflagPromotion) {
- if (move & moveflagPromoteBishop) result += "b";
- else if (move & moveflagPromoteKnight) result += "n";
- else if (move & moveflagPromoteQueen) result += "q";
- else result += "r";
- }
- return result;
+ var result = FormatSquare(move & 0xff) + FormatSquare((move >> 8) & 0xff);
+ if (move & moveflagPromotion) {
+ if (move & moveflagPromoteBishop) result += 'b';
+ else if (move & moveflagPromoteKnight) result += 'n';
+ else if (move & moveflagPromoteQueen) result += 'q';
+ else result += 'r';
+ }
+ return result;
}
function GetMoveFromString(moveString) {
- var moves = GenerateValidMoves();
- for (var i = 0; i < moves.length; i++) {
- if (FormatMove(moves[i]) == moveString) {
- return moves[i];
- }
- }
- alert("busted! ->" + moveString + " fen:" + GetFen());
+ var moves = GenerateValidMoves();
+ for (var i = 0; i < moves.length; i++) {
+ if (FormatMove(moves[i]) == moveString) {
+ return moves[i];
+ }
+ }
+ alert('busted! ->' + moveString + ' fen:' + GetFen());
}
function PVFromHash(move, ply) {
- if (ply == 0)
- return "";
+ if (ply == 0) return '';
- if (move == 0) {
- if (g_inCheck) return "checkmate";
- return "stalemate";
- }
-
- var pvString = " " + GetMoveSAN(move);
- MakeMove(move);
-
- var hashNode = g_hashTable[g_hashKeyLow & g_hashMask];
- if (hashNode != null && hashNode.lock == g_hashKeyHigh && hashNode.bestMove != null) {
- pvString += PVFromHash(hashNode.bestMove, ply - 1);
- }
-
- UnmakeMove(move);
-
- return pvString;
+ if (move == 0) {
+ if (g_inCheck) return 'checkmate';
+ return 'stalemate';
+ }
+
+ var pvString = ' ' + GetMoveSAN(move);
+ MakeMove(move);
+
+ var hashNode = g_hashTable[g_hashKeyLow & g_hashMask];
+ if (hashNode != null && hashNode.lock == g_hashKeyHigh && hashNode.bestMove != null) {
+ pvString += PVFromHash(hashNode.bestMove, ply - 1);
+ }
+
+ UnmakeMove(move);
+
+ return pvString;
}
//
@@ -192,51 +182,51 @@ var g_searchValid;
var g_globalPly = 0;
function Search(finishMoveCallback, maxPly, finishPlyCallback) {
- var lastEval;
- var alpha = minEval;
- var beta = maxEval;
-
+ var lastEval;
+ var alpha = minEval;
+ var beta = maxEval;
+
g_globalPly++;
- g_nodeCount = 0;
- g_qNodeCount = 0;
- g_searchValid = true;
-
- var bestMove = 0;
- var value;
-
- g_startTime = (new Date()).getTime();
-
- var i;
- for (i = 1; i <= maxPly && g_searchValid; i++) {
- var tmp = AlphaBeta(i, 0, alpha, beta);
- if (!g_searchValid) break;
-
- value = tmp;
-
- if (value > alpha && value < beta) {
- alpha = value - 500;
- beta = value + 500;
-
- if (alpha < minEval) alpha = minEval;
- if (beta > maxEval) beta = maxEval;
- } else if (alpha != minEval) {
- alpha = minEval;
- beta = maxEval;
- i--;
- }
+ g_nodeCount = 0;
+ g_qNodeCount = 0;
+ g_searchValid = true;
- if (g_hashTable[g_hashKeyLow & g_hashMask] != null) {
- bestMove = g_hashTable[g_hashKeyLow & g_hashMask].bestMove;
- }
+ var bestMove = 0;
+ var value;
- if (finishPlyCallback != null) {
- finishPlyCallback(bestMove, value, (new Date()).getTime() - g_startTime, i);
- }
- }
+ g_startTime = new Date().getTime();
- if (finishMoveCallback != null) {
- finishMoveCallback(bestMove, value, (new Date()).getTime() - g_startTime, i - 1);
- }
+ var i;
+ for (i = 1; i <= maxPly && g_searchValid; i++) {
+ var tmp = AlphaBeta(i, 0, alpha, beta);
+ if (!g_searchValid) break;
+
+ value = tmp;
+
+ if (value > alpha && value < beta) {
+ alpha = value - 500;
+ beta = value + 500;
+
+ if (alpha < minEval) alpha = minEval;
+ if (beta > maxEval) beta = maxEval;
+ } else if (alpha != minEval) {
+ alpha = minEval;
+ beta = maxEval;
+ i--;
+ }
+
+ if (g_hashTable[g_hashKeyLow & g_hashMask] != null) {
+ bestMove = g_hashTable[g_hashKeyLow & g_hashMask].bestMove;
+ }
+
+ if (finishPlyCallback != null) {
+ finishPlyCallback(bestMove, value, new Date().getTime() - g_startTime, i);
+ }
+ }
+
+ if (finishMoveCallback != null) {
+ finishMoveCallback(bestMove, value, new Date().getTime() - g_startTime, i - 1);
+ }
}
var minEval = -2000000;
@@ -247,72 +237,40 @@ var maxMateBuffer = maxEval - 2000;
var materialTable = [0, 800, 3350, 3450, 5000, 9750, 600000];
-var pawnAdj =
-[
- 0, 0, 0, 0, 0, 0, 0, 0,
- -25, 105, 135, 270, 270, 135, 105, -25,
- -80, 0, 30, 176, 176, 30, 0, -80,
- -85, -5, 25, 175, 175, 25, -5, -85,
- -90, -10, 20, 125, 125, 20, -10, -90,
- -95, -15, 15, 75, 75, 15, -15, -95,
- -100, -20, 10, 70, 70, 10, -20, -100,
- 0, 0, 0, 0, 0, 0, 0, 0
+var pawnAdj = [
+ 0, 0, 0, 0, 0, 0, 0, 0, -25, 105, 135, 270, 270, 135, 105, -25, -80, 0, 30, 176, 176, 30, 0, -80, -85, -5, 25, 175,
+ 175, 25, -5, -85, -90, -10, 20, 125, 125, 20, -10, -90, -95, -15, 15, 75, 75, 15, -15, -95, -100, -20, 10, 70, 70, 10,
+ -20, -100, 0, 0, 0, 0, 0, 0, 0, 0,
+];
+
+var knightAdj = [
+ -200, -100, -50, -50, -50, -50, -100, -200, -100, 0, 0, 0, 0, 0, 0, -100, -50, 0, 60, 60, 60, 60, 0, -50, -50, 0, 30,
+ 60, 60, 30, 0, -50, -50, 0, 30, 60, 60, 30, 0, -50, -50, 0, 30, 30, 30, 30, 0, -50, -100, 0, 0, 0, 0, 0, 0, -100,
+ -200, -50, -25, -25, -25, -25, -50, -200,
];
-var knightAdj =
- [-200, -100, -50, -50, -50, -50, -100, -200,
- -100, 0, 0, 0, 0, 0, 0, -100,
- -50, 0, 60, 60, 60, 60, 0, -50,
- -50, 0, 30, 60, 60, 30, 0, -50,
- -50, 0, 30, 60, 60, 30, 0, -50,
- -50, 0, 30, 30, 30, 30, 0, -50,
- -100, 0, 0, 0, 0, 0, 0, -100,
- -200, -50, -25, -25, -25, -25, -50, -200
- ];
-
-var bishopAdj =
- [ -50,-50,-25,-10,-10,-25,-50,-50,
- -50,-25,-10, 0, 0,-10,-25,-50,
- -25,-10, 0, 25, 25, 0,-10,-25,
- -10, 0, 25, 40, 40, 25, 0,-10,
- -10, 0, 25, 40, 40, 25, 0,-10,
- -25,-10, 0, 25, 25, 0,-10,-25,
- -50,-25,-10, 0, 0,-10,-25,-50,
- -50,-50,-25,-10,-10,-25,-50,-50
- ];
-
-var rookAdj =
- [ -60, -30, -10, 20, 20, -10, -30, -60,
- 40, 70, 90,120,120, 90, 70, 40,
- -60, -30, -10, 20, 20, -10, -30, -60,
- -60, -30, -10, 20, 20, -10, -30, -60,
- -60, -30, -10, 20, 20, -10, -30, -60,
- -60, -30, -10, 20, 20, -10, -30, -60,
- -60, -30, -10, 20, 20, -10, -30, -60,
- -60, -30, -10, 20, 20, -10, -30, -60
- ];
-
-var kingAdj =
- [ 50, 150, -25, -125, -125, -25, 150, 50,
- 50, 150, -25, -125, -125, -25, 150, 50,
- 50, 150, -25, -125, -125, -25, 150, 50,
- 50, 150, -25, -125, -125, -25, 150, 50,
- 50, 150, -25, -125, -125, -25, 150, 50,
- 50, 150, -25, -125, -125, -25, 150, 50,
- 50, 150, -25, -125, -125, -25, 150, 50,
- 150, 250, 75, -25, -25, 75, 250, 150
- ];
-
-var emptyAdj =
- [0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- ];
+var bishopAdj = [
+ -50, -50, -25, -10, -10, -25, -50, -50, -50, -25, -10, 0, 0, -10, -25, -50, -25, -10, 0, 25, 25, 0, -10, -25, -10, 0,
+ 25, 40, 40, 25, 0, -10, -10, 0, 25, 40, 40, 25, 0, -10, -25, -10, 0, 25, 25, 0, -10, -25, -50, -25, -10, 0, 0, -10,
+ -25, -50, -50, -50, -25, -10, -10, -25, -50, -50,
+];
+
+var rookAdj = [
+ -60, -30, -10, 20, 20, -10, -30, -60, 40, 70, 90, 120, 120, 90, 70, 40, -60, -30, -10, 20, 20, -10, -30, -60, -60,
+ -30, -10, 20, 20, -10, -30, -60, -60, -30, -10, 20, 20, -10, -30, -60, -60, -30, -10, 20, 20, -10, -30, -60, -60, -30,
+ -10, 20, 20, -10, -30, -60, -60, -30, -10, 20, 20, -10, -30, -60,
+];
+
+var kingAdj = [
+ 50, 150, -25, -125, -125, -25, 150, 50, 50, 150, -25, -125, -125, -25, 150, 50, 50, 150, -25, -125, -125, -25, 150,
+ 50, 50, 150, -25, -125, -125, -25, 150, 50, 50, 150, -25, -125, -125, -25, 150, 50, 50, 150, -25, -125, -125, -25,
+ 150, 50, 50, 150, -25, -125, -125, -25, 150, 50, 150, 250, 75, -25, -25, 75, 250, 150,
+];
+
+var emptyAdj = [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+];
var pieceSquareAdj = new Array(8);
@@ -320,236 +278,309 @@ var pieceSquareAdj = new Array(8);
var flipTable = new Array(256);
function PawnEval(color) {
- var pieceIdx = (color | 1) << 4;
- var from = g_pieceList[pieceIdx++];
- while (from != 0) {
- from = g_pieceList[pieceIdx++];
- }
+ var pieceIdx = (color | 1) << 4;
+ var from = g_pieceList[pieceIdx++];
+ while (from != 0) {
+ from = g_pieceList[pieceIdx++];
+ }
}
function Mobility(color) {
- var result = 0;
- var from, to, mob, pieceIdx;
- var enemy = color == 8 ? 0x10 : 0x8
- var mobUnit = color == 8 ? g_mobUnit[0] : g_mobUnit[1];
-
- // Knight mobility
- mob = -3;
- pieceIdx = (color | 2) << 4;
- from = g_pieceList[pieceIdx++];
- while (from != 0) {
- mob += mobUnit[g_board[from + 31]];
- mob += mobUnit[g_board[from + 33]];
- mob += mobUnit[g_board[from + 14]];
- mob += mobUnit[g_board[from - 14]];
- mob += mobUnit[g_board[from - 31]];
- mob += mobUnit[g_board[from - 33]];
- mob += mobUnit[g_board[from + 18]];
- mob += mobUnit[g_board[from - 18]];
- from = g_pieceList[pieceIdx++];
- }
- result += 65 * mob;
-
- // Bishop mobility
- mob = -4;
- pieceIdx = (color | 3) << 4;
- from = g_pieceList[pieceIdx++];
- while (from != 0) {
- to = from - 15; while (g_board[to] == 0) { to -= 15; mob++; }
- if (g_board[to] & enemy) {
- mob++;
- if (!(g_board[to] & piecePawn)) {
- to -= 15; while (g_board[to] == 0) to -= 15;
- mob += mobUnit[g_board[to]] << 2;
- }
- }
+ var result = 0;
+ var from, to, mob, pieceIdx;
+ var enemy = color == 8 ? 0x10 : 0x8;
+ var mobUnit = color == 8 ? g_mobUnit[0] : g_mobUnit[1];
+
+ // Knight mobility
+ mob = -3;
+ pieceIdx = (color | 2) << 4;
+ from = g_pieceList[pieceIdx++];
+ while (from != 0) {
+ mob += mobUnit[g_board[from + 31]];
+ mob += mobUnit[g_board[from + 33]];
+ mob += mobUnit[g_board[from + 14]];
+ mob += mobUnit[g_board[from - 14]];
+ mob += mobUnit[g_board[from - 31]];
+ mob += mobUnit[g_board[from - 33]];
+ mob += mobUnit[g_board[from + 18]];
+ mob += mobUnit[g_board[from - 18]];
+ from = g_pieceList[pieceIdx++];
+ }
+ result += 65 * mob;
- to = from - 17; while (g_board[to] == 0) { to -= 17; mob++; }
- if (g_board[to] & enemy) {
- mob++;
- if (!(g_board[to] & piecePawn)) {
- to -= 17; while (g_board[to] == 0) to -= 17;
- mob += mobUnit[g_board[to]] << 2;
- }
- }
+ // Bishop mobility
+ mob = -4;
+ pieceIdx = (color | 3) << 4;
+ from = g_pieceList[pieceIdx++];
+ while (from != 0) {
+ to = from - 15;
+ while (g_board[to] == 0) {
+ to -= 15;
+ mob++;
+ }
+ if (g_board[to] & enemy) {
+ mob++;
+ if (!(g_board[to] & piecePawn)) {
+ to -= 15;
+ while (g_board[to] == 0) to -= 15;
+ mob += mobUnit[g_board[to]] << 2;
+ }
+ }
- to = from + 15; while (g_board[to] == 0) { to += 15; mob++; }
- if (g_board[to] & enemy) {
- mob++;
- if (!(g_board[to] & piecePawn)) {
- to += 15; while (g_board[to] == 0) to += 15;
- mob += mobUnit[g_board[to]] << 2;
- }
- }
+ to = from - 17;
+ while (g_board[to] == 0) {
+ to -= 17;
+ mob++;
+ }
+ if (g_board[to] & enemy) {
+ mob++;
+ if (!(g_board[to] & piecePawn)) {
+ to -= 17;
+ while (g_board[to] == 0) to -= 17;
+ mob += mobUnit[g_board[to]] << 2;
+ }
+ }
- to = from + 17; while (g_board[to] == 0) { to += 17; mob++; }
- if (g_board[to] & enemy) {
- mob++;
- if (!(g_board[to] & piecePawn)) {
- to += 17; while (g_board[to] == 0) to += 17;
- mob += mobUnit[g_board[to]] << 2;
- }
- }
+ to = from + 15;
+ while (g_board[to] == 0) {
+ to += 15;
+ mob++;
+ }
+ if (g_board[to] & enemy) {
+ mob++;
+ if (!(g_board[to] & piecePawn)) {
+ to += 15;
+ while (g_board[to] == 0) to += 15;
+ mob += mobUnit[g_board[to]] << 2;
+ }
+ }
- from = g_pieceList[pieceIdx++];
- }
- result += 44 * mob;
-
- // Rook mobility
- mob = -4;
- pieceIdx = (color | 4) << 4;
- from = g_pieceList[pieceIdx++];
- while (from != 0) {
- to = from - 1; while (g_board[to] == 0) { to--; mob++;} if (g_board[to] & enemy) mob++;
- to = from + 1; while (g_board[to] == 0) { to++; mob++; } if (g_board[to] & enemy) mob++;
- to = from + 16; while (g_board[to] == 0) { to += 16; mob++; } if (g_board[to] & enemy) mob++;
- to = from - 16; while (g_board[to] == 0) { to -= 16; mob++; } if (g_board[to] & enemy) mob++;
- from = g_pieceList[pieceIdx++];
- }
- result += 25 * mob;
-
- // Queen mobility
- mob = -2;
- pieceIdx = (color | 5) << 4;
- from = g_pieceList[pieceIdx++];
- while (from != 0) {
- to = from - 15; while (g_board[to] == 0) { to -= 15; mob++; } if (g_board[to] & enemy) mob++;
- to = from - 17; while (g_board[to] == 0) { to -= 17; mob++; } if (g_board[to] & enemy) mob++;
- to = from + 15; while (g_board[to] == 0) { to += 15; mob++; } if (g_board[to] & enemy) mob++;
- to = from + 17; while (g_board[to] == 0) { to += 17; mob++; } if (g_board[to] & enemy) mob++;
- to = from - 1; while (g_board[to] == 0) { to--; mob++; } if (g_board[to] & enemy) mob++;
- to = from + 1; while (g_board[to] == 0) { to++; mob++; } if (g_board[to] & enemy) mob++;
- to = from + 16; while (g_board[to] == 0) { to += 16; mob++; } if (g_board[to] & enemy) mob++;
- to = from - 16; while (g_board[to] == 0) { to -= 16; mob++; } if (g_board[to] & enemy) mob++;
- from = g_pieceList[pieceIdx++];
- }
- result += 22 * mob;
+ to = from + 17;
+ while (g_board[to] == 0) {
+ to += 17;
+ mob++;
+ }
+ if (g_board[to] & enemy) {
+ mob++;
+ if (!(g_board[to] & piecePawn)) {
+ to += 17;
+ while (g_board[to] == 0) to += 17;
+ mob += mobUnit[g_board[to]] << 2;
+ }
+ }
+
+ from = g_pieceList[pieceIdx++];
+ }
+ result += 44 * mob;
+
+ // Rook mobility
+ mob = -4;
+ pieceIdx = (color | 4) << 4;
+ from = g_pieceList[pieceIdx++];
+ while (from != 0) {
+ to = from - 1;
+ while (g_board[to] == 0) {
+ to--;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from + 1;
+ while (g_board[to] == 0) {
+ to++;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from + 16;
+ while (g_board[to] == 0) {
+ to += 16;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from - 16;
+ while (g_board[to] == 0) {
+ to -= 16;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ from = g_pieceList[pieceIdx++];
+ }
+ result += 25 * mob;
+
+ // Queen mobility
+ mob = -2;
+ pieceIdx = (color | 5) << 4;
+ from = g_pieceList[pieceIdx++];
+ while (from != 0) {
+ to = from - 15;
+ while (g_board[to] == 0) {
+ to -= 15;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from - 17;
+ while (g_board[to] == 0) {
+ to -= 17;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from + 15;
+ while (g_board[to] == 0) {
+ to += 15;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from + 17;
+ while (g_board[to] == 0) {
+ to += 17;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from - 1;
+ while (g_board[to] == 0) {
+ to--;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from + 1;
+ while (g_board[to] == 0) {
+ to++;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from + 16;
+ while (g_board[to] == 0) {
+ to += 16;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ to = from - 16;
+ while (g_board[to] == 0) {
+ to -= 16;
+ mob++;
+ }
+ if (g_board[to] & enemy) mob++;
+ from = g_pieceList[pieceIdx++];
+ }
+ result += 22 * mob;
- return result;
+ return result;
}
function Evaluate() {
- var curEval = g_baseEval;
-
- var evalAdjust = 0;
- // Black queen gone, then cancel white's penalty for king movement
- if (g_pieceList[pieceQueen << 4] == 0)
- evalAdjust -= pieceSquareAdj[pieceKing][g_pieceList[(colorWhite | pieceKing) << 4]];
- // White queen gone, then cancel black's penalty for king movement
- if (g_pieceList[(colorWhite | pieceQueen) << 4] == 0)
- evalAdjust += pieceSquareAdj[pieceKing][flipTable[g_pieceList[pieceKing << 4]]];
-
- // Black bishop pair
- if (g_pieceCount[pieceBishop] >= 2)
- evalAdjust -= 500;
- // White bishop pair
- if (g_pieceCount[pieceBishop | colorWhite] >= 2)
- evalAdjust += 500;
-
- var mobility = Mobility(8) - Mobility(0);
-
- if (g_toMove == 0) {
- // Black
- curEval -= mobility;
- curEval -= evalAdjust;
- }
- else {
- curEval += mobility;
- curEval += evalAdjust;
- }
-
- return curEval;
+ var curEval = g_baseEval;
+
+ var evalAdjust = 0;
+ // Black queen gone, then cancel white's penalty for king movement
+ if (g_pieceList[pieceQueen << 4] == 0)
+ evalAdjust -= pieceSquareAdj[pieceKing][g_pieceList[(colorWhite | pieceKing) << 4]];
+ // White queen gone, then cancel black's penalty for king movement
+ if (g_pieceList[(colorWhite | pieceQueen) << 4] == 0)
+ evalAdjust += pieceSquareAdj[pieceKing][flipTable[g_pieceList[pieceKing << 4]]];
+
+ // Black bishop pair
+ if (g_pieceCount[pieceBishop] >= 2) evalAdjust -= 500;
+ // White bishop pair
+ if (g_pieceCount[pieceBishop | colorWhite] >= 2) evalAdjust += 500;
+
+ var mobility = Mobility(8) - Mobility(0);
+
+ if (g_toMove == 0) {
+ // Black
+ curEval -= mobility;
+ curEval -= evalAdjust;
+ } else {
+ curEval += mobility;
+ curEval += evalAdjust;
+ }
+
+ return curEval;
}
-function ScoreMove(move){
- var moveTo = (move >> 8) & 0xFF;
- var captured = g_board[moveTo] & 0x7;
- var piece = g_board[move & 0xFF];
- var score;
- if (captured != 0) {
- var pieceType = piece & 0x7;
- score = (captured << 5) - pieceType;
- } else {
- score = historyTable[piece & 0xF][moveTo];
- }
- return score;
+function ScoreMove(move) {
+ var moveTo = (move >> 8) & 0xff;
+ var captured = g_board[moveTo] & 0x7;
+ var piece = g_board[move & 0xff];
+ var score;
+ if (captured != 0) {
+ var pieceType = piece & 0x7;
+ score = (captured << 5) - pieceType;
+ } else {
+ score = historyTable[piece & 0xf][moveTo];
+ }
+ return score;
}
function QSearch(alpha, beta, ply) {
- g_qNodeCount++;
+ g_qNodeCount++;
- var realEval = g_inCheck ? (minEval + 1) : Evaluate();
-
- if (realEval >= beta)
- return realEval;
+ var realEval = g_inCheck ? minEval + 1 : Evaluate();
- if (realEval > alpha)
- alpha = realEval;
+ if (realEval >= beta) return realEval;
- var moves = new Array();
- var moveScores = new Array();
- var wasInCheck = g_inCheck;
+ if (realEval > alpha) alpha = realEval;
- if (wasInCheck) {
- // TODO: Fast check escape generator and fast checking moves generator
- GenerateCaptureMoves(moves, null);
- GenerateAllMoves(moves);
+ var moves = new Array();
+ var moveScores = new Array();
+ var wasInCheck = g_inCheck;
- for (var i = 0; i < moves.length; i++) {
- moveScores[i] = ScoreMove(moves[i]);
- }
- } else {
- GenerateCaptureMoves(moves, null);
+ if (wasInCheck) {
+ // TODO: Fast check escape generator and fast checking moves generator
+ GenerateCaptureMoves(moves, null);
+ GenerateAllMoves(moves);
- for (var i = 0; i < moves.length; i++) {
- var captured = g_board[(moves[i] >> 8) & 0xFF] & 0x7;
- var pieceType = g_board[moves[i] & 0xFF] & 0x7;
+ for (var i = 0; i < moves.length; i++) {
+ moveScores[i] = ScoreMove(moves[i]);
+ }
+ } else {
+ GenerateCaptureMoves(moves, null);
- moveScores[i] = (captured << 5) - pieceType;
- }
- }
+ for (var i = 0; i < moves.length; i++) {
+ var captured = g_board[(moves[i] >> 8) & 0xff] & 0x7;
+ var pieceType = g_board[moves[i] & 0xff] & 0x7;
- for (var i = 0; i < moves.length; i++) {
- var bestMove = i;
- for (var j = moves.length - 1; j > i; j--) {
- if (moveScores[j] > moveScores[bestMove]) {
- bestMove = j;
- }
- }
- {
- var tmpMove = moves[i];
- moves[i] = moves[bestMove];
- moves[bestMove] = tmpMove;
-
- var tmpScore = moveScores[i];
- moveScores[i] = moveScores[bestMove];
- moveScores[bestMove] = tmpScore;
- }
+ moveScores[i] = (captured << 5) - pieceType;
+ }
+ }
- if (!wasInCheck && !See(moves[i])) {
- continue;
- }
+ for (var i = 0; i < moves.length; i++) {
+ var bestMove = i;
+ for (var j = moves.length - 1; j > i; j--) {
+ if (moveScores[j] > moveScores[bestMove]) {
+ bestMove = j;
+ }
+ }
+ {
+ var tmpMove = moves[i];
+ moves[i] = moves[bestMove];
+ moves[bestMove] = tmpMove;
+
+ var tmpScore = moveScores[i];
+ moveScores[i] = moveScores[bestMove];
+ moveScores[bestMove] = tmpScore;
+ }
- if (!MakeMove(moves[i])) {
- continue;
- }
+ if (!wasInCheck && !See(moves[i])) {
+ continue;
+ }
- var value = -QSearch(-beta, -alpha, ply - 1);
-
- UnmakeMove(moves[i]);
-
- if (value > realEval) {
- if (value >= beta)
- return value;
-
- if (value > alpha)
- alpha = value;
-
- realEval = value;
- }
- }
+ if (!MakeMove(moves[i])) {
+ continue;
+ }
+
+ var value = -QSearch(-beta, -alpha, ply - 1);
+
+ UnmakeMove(moves[i]);
- /* Disable checks... Too slow currently
+ if (value > realEval) {
+ if (value >= beta) return value;
+
+ if (value > alpha) alpha = value;
+
+ realEval = value;
+ }
+ }
+
+ /* Disable checks... Too slow currently
if (ply == 0 && !wasInCheck) {
moves = new Array();
@@ -609,335 +640,316 @@ function QSearch(alpha, beta, ply) {
}
*/
- return realEval;
+ return realEval;
}
function StoreHash(value, flags, ply, move, depth) {
- if (value >= maxMateBuffer)
- value += depth;
- else if (value <= minMateBuffer)
- value -= depth;
+ if (value >= maxMateBuffer) value += depth;
+ else if (value <= minMateBuffer) value -= depth;
g_hashTable[g_hashKeyLow & g_hashMask] = new HashEntry(g_hashKeyHigh, value, flags, ply, move);
}
function IsHashMoveValid(hashMove) {
- var from = hashMove & 0xFF;
- var to = (hashMove >> 8) & 0xFF;
- var ourPiece = g_board[from];
- var pieceType = ourPiece & 0x7;
- if (pieceType < piecePawn || pieceType > pieceKing) return false;
- // Can't move a piece we don't control
- if (g_toMove != (ourPiece & 0x8))
- return false;
- // Can't move to a square that has something of the same color
- if (g_board[to] != 0 && (g_toMove == (g_board[to] & 0x8)))
- return false;
- if (pieceType == piecePawn) {
- if (hashMove & moveflagEPC) {
- return false;
- }
+ var from = hashMove & 0xff;
+ var to = (hashMove >> 8) & 0xff;
+ var ourPiece = g_board[from];
+ var pieceType = ourPiece & 0x7;
+ if (pieceType < piecePawn || pieceType > pieceKing) return false;
+ // Can't move a piece we don't control
+ if (g_toMove != (ourPiece & 0x8)) return false;
+ // Can't move to a square that has something of the same color
+ if (g_board[to] != 0 && g_toMove == (g_board[to] & 0x8)) return false;
+ if (pieceType == piecePawn) {
+ if (hashMove & moveflagEPC) {
+ return false;
+ }
- // Valid moves are push, capture, double push, promotions
- var dir = to - from;
- if ((g_toMove == colorWhite) != (dir < 0)) {
- // Pawns have to move in the right direction
- return false;
- }
+ // Valid moves are push, capture, double push, promotions
+ var dir = to - from;
+ if ((g_toMove == colorWhite) != dir < 0) {
+ // Pawns have to move in the right direction
+ return false;
+ }
- var row = to & 0xF0;
- if (((row == 0x90 && !g_toMove) ||
- (row == 0x20 && g_toMove)) != (hashMove & moveflagPromotion)) {
- // Handle promotions
- return false;
- }
+ var row = to & 0xf0;
+ if (((row == 0x90 && !g_toMove) || (row == 0x20 && g_toMove)) != (hashMove & moveflagPromotion)) {
+ // Handle promotions
+ return false;
+ }
- if (dir == -16 || dir == 16) {
- // White/Black push
- return g_board[to] == 0;
- } else if (dir == -15 || dir == -17 || dir == 15 || dir == 17) {
- // White/Black capture
- return g_board[to] != 0;
- } else if (dir == -32) {
- // Double white push
- if (row != 0x60) return false;
- if (g_board[to] != 0) return false;
- if (g_board[from - 16] != 0) return false;
- } else if (dir == 32) {
- // Double black push
- if (row != 0x50) return false;
- if (g_board[to] != 0) return false;
- if (g_board[from + 16] != 0) return false;
- } else {
- return false;
- }
+ if (dir == -16 || dir == 16) {
+ // White/Black push
+ return g_board[to] == 0;
+ } else if (dir == -15 || dir == -17 || dir == 15 || dir == 17) {
+ // White/Black capture
+ return g_board[to] != 0;
+ } else if (dir == -32) {
+ // Double white push
+ if (row != 0x60) return false;
+ if (g_board[to] != 0) return false;
+ if (g_board[from - 16] != 0) return false;
+ } else if (dir == 32) {
+ // Double black push
+ if (row != 0x50) return false;
+ if (g_board[to] != 0) return false;
+ if (g_board[from + 16] != 0) return false;
+ } else {
+ return false;
+ }
- return true;
- } else {
- // This validates that this piece type can actually make the attack
- if (hashMove >> 16) return false;
- return IsSquareAttackableFrom(to, from);
- }
+ return true;
+ } else {
+ // This validates that this piece type can actually make the attack
+ if (hashMove >> 16) return false;
+ return IsSquareAttackableFrom(to, from);
+ }
}
function IsRepDraw() {
- var stop = g_moveCount - 1 - g_move50;
- stop = stop < 0 ? 0 : stop;
- for (var i = g_moveCount - 5; i >= stop; i -= 2) {
- if (g_repMoveStack[i] == g_hashKeyLow)
- return true;
- }
- return false;
+ var stop = g_moveCount - 1 - g_move50;
+ stop = stop < 0 ? 0 : stop;
+ for (var i = g_moveCount - 5; i >= stop; i -= 2) {
+ if (g_repMoveStack[i] == g_hashKeyLow) return true;
+ }
+ return false;
}
function MovePicker(hashMove, depth, killer1, killer2) {
- this.hashMove = hashMove;
- this.depth = depth;
- this.killer1 = killer1;
- this.killer2 = killer2;
-
- this.moves = new Array();
- this.losingCaptures = null;
- this.moveCount = 0;
- this.atMove = -1;
- this.moveScores = null;
- this.stage = 0;
-
- this.nextMove = function () {
- if (++this.atMove == this.moveCount) {
- this.stage++;
- if (this.stage == 1) {
- if (this.hashMove != null && IsHashMoveValid(hashMove)) {
- this.moves[0] = hashMove;
- this.moveCount = 1;
- }
- if (this.moveCount != 1) {
- this.hashMove = null;
- this.stage++;
- }
- }
+ this.hashMove = hashMove;
+ this.depth = depth;
+ this.killer1 = killer1;
+ this.killer2 = killer2;
+
+ this.moves = new Array();
+ this.losingCaptures = null;
+ this.moveCount = 0;
+ this.atMove = -1;
+ this.moveScores = null;
+ this.stage = 0;
+
+ this.nextMove = function () {
+ if (++this.atMove == this.moveCount) {
+ this.stage++;
+ if (this.stage == 1) {
+ if (this.hashMove != null && IsHashMoveValid(hashMove)) {
+ this.moves[0] = hashMove;
+ this.moveCount = 1;
+ }
+ if (this.moveCount != 1) {
+ this.hashMove = null;
+ this.stage++;
+ }
+ }
- if (this.stage == 2) {
- GenerateCaptureMoves(this.moves, null);
- this.moveCount = this.moves.length;
- this.moveScores = new Array(this.moveCount);
- // Move ordering
- for (var i = this.atMove; i < this.moveCount; i++) {
- var captured = g_board[(this.moves[i] >> 8) & 0xFF] & 0x7;
- var pieceType = g_board[this.moves[i] & 0xFF] & 0x7;
- this.moveScores[i] = (captured << 5) - pieceType;
- }
- // No moves, onto next stage
- if (this.atMove == this.moveCount) this.stage++;
- }
+ if (this.stage == 2) {
+ GenerateCaptureMoves(this.moves, null);
+ this.moveCount = this.moves.length;
+ this.moveScores = new Array(this.moveCount);
+ // Move ordering
+ for (var i = this.atMove; i < this.moveCount; i++) {
+ var captured = g_board[(this.moves[i] >> 8) & 0xff] & 0x7;
+ var pieceType = g_board[this.moves[i] & 0xff] & 0x7;
+ this.moveScores[i] = (captured << 5) - pieceType;
+ }
+ // No moves, onto next stage
+ if (this.atMove == this.moveCount) this.stage++;
+ }
- if (this.stage == 3) {
- if (IsHashMoveValid(this.killer1) &&
- this.killer1 != this.hashMove) {
- this.moves[this.moves.length] = this.killer1;
- this.moveCount = this.moves.length;
- } else {
- this.killer1 = 0;
- this.stage++;
- }
- }
+ if (this.stage == 3) {
+ if (IsHashMoveValid(this.killer1) && this.killer1 != this.hashMove) {
+ this.moves[this.moves.length] = this.killer1;
+ this.moveCount = this.moves.length;
+ } else {
+ this.killer1 = 0;
+ this.stage++;
+ }
+ }
- if (this.stage == 4) {
- if (IsHashMoveValid(this.killer2) &&
- this.killer2 != this.hashMove) {
- this.moves[this.moves.length] = this.killer2;
- this.moveCount = this.moves.length;
- } else {
- this.killer2 = 0;
- this.stage++;
- }
- }
+ if (this.stage == 4) {
+ if (IsHashMoveValid(this.killer2) && this.killer2 != this.hashMove) {
+ this.moves[this.moves.length] = this.killer2;
+ this.moveCount = this.moves.length;
+ } else {
+ this.killer2 = 0;
+ this.stage++;
+ }
+ }
- if (this.stage == 5) {
- GenerateAllMoves(this.moves);
- this.moveCount = this.moves.length;
- // Move ordering
- for (var i = this.atMove; i < this.moveCount; i++) this.moveScores[i] = ScoreMove(this.moves[i]);
- // No moves, onto next stage
- if (this.atMove == this.moveCount) this.stage++;
- }
+ if (this.stage == 5) {
+ GenerateAllMoves(this.moves);
+ this.moveCount = this.moves.length;
+ // Move ordering
+ for (var i = this.atMove; i < this.moveCount; i++) this.moveScores[i] = ScoreMove(this.moves[i]);
+ // No moves, onto next stage
+ if (this.atMove == this.moveCount) this.stage++;
+ }
- if (this.stage == 6) {
- // Losing captures
- if (this.losingCaptures != null) {
- for (var i = 0; i < this.losingCaptures.length; i++) {
- this.moves[this.moves.length] = this.losingCaptures[i];
- }
- for (var i = this.atMove; i < this.moveCount; i++) this.moveScores[i] = ScoreMove(this.moves[i]);
- this.moveCount = this.moves.length;
- }
- // No moves, onto next stage
- if (this.atMove == this.moveCount) this.stage++;
- }
+ if (this.stage == 6) {
+ // Losing captures
+ if (this.losingCaptures != null) {
+ for (var i = 0; i < this.losingCaptures.length; i++) {
+ this.moves[this.moves.length] = this.losingCaptures[i];
+ }
+ for (var i = this.atMove; i < this.moveCount; i++) this.moveScores[i] = ScoreMove(this.moves[i]);
+ this.moveCount = this.moves.length;
+ }
+ // No moves, onto next stage
+ if (this.atMove == this.moveCount) this.stage++;
+ }
- if (this.stage == 7)
- return 0;
- }
+ if (this.stage == 7) return 0;
+ }
- var bestMove = this.atMove;
- for (var j = this.atMove + 1; j < this.moveCount; j++) {
- if (this.moveScores[j] > this.moveScores[bestMove]) {
- bestMove = j;
- }
- }
+ var bestMove = this.atMove;
+ for (var j = this.atMove + 1; j < this.moveCount; j++) {
+ if (this.moveScores[j] > this.moveScores[bestMove]) {
+ bestMove = j;
+ }
+ }
- if (bestMove != this.atMove) {
- var tmpMove = this.moves[this.atMove];
- this.moves[this.atMove] = this.moves[bestMove];
- this.moves[bestMove] = tmpMove;
+ if (bestMove != this.atMove) {
+ var tmpMove = this.moves[this.atMove];
+ this.moves[this.atMove] = this.moves[bestMove];
+ this.moves[bestMove] = tmpMove;
- var tmpScore = this.moveScores[this.atMove];
- this.moveScores[this.atMove] = this.moveScores[bestMove];
- this.moveScores[bestMove] = tmpScore;
- }
+ var tmpScore = this.moveScores[this.atMove];
+ this.moveScores[this.atMove] = this.moveScores[bestMove];
+ this.moveScores[bestMove] = tmpScore;
+ }
- var candidateMove = this.moves[this.atMove];
- if ((this.stage > 1 && candidateMove == this.hashMove) ||
- (this.stage > 3 && candidateMove == this.killer1) ||
- (this.stage > 4 && candidateMove == this.killer2)) {
- return this.nextMove();
- }
+ var candidateMove = this.moves[this.atMove];
+ if (
+ (this.stage > 1 && candidateMove == this.hashMove) ||
+ (this.stage > 3 && candidateMove == this.killer1) ||
+ (this.stage > 4 && candidateMove == this.killer2)
+ ) {
+ return this.nextMove();
+ }
- if (this.stage == 2 && !See(candidateMove)) {
- if (this.losingCaptures == null) {
- this.losingCaptures = new Array();
- }
- this.losingCaptures[this.losingCaptures.length] = candidateMove;
- return this.nextMove();
- }
+ if (this.stage == 2 && !See(candidateMove)) {
+ if (this.losingCaptures == null) {
+ this.losingCaptures = new Array();
+ }
+ this.losingCaptures[this.losingCaptures.length] = candidateMove;
+ return this.nextMove();
+ }
- return this.moves[this.atMove];
- }
+ return this.moves[this.atMove];
+ };
}
function AllCutNode(ply, depth, beta, allowNull) {
- if (ply <= 0) {
- return QSearch(beta - 1, beta, 0);
- }
+ if (ply <= 0) {
+ return QSearch(beta - 1, beta, 0);
+ }
- if ((g_nodeCount & 127) == 127) {
- if ((new Date()).getTime() - g_startTime > g_timeout) {
- // Time cutoff
- g_searchValid = false;
- return beta - 1;
- }
- }
+ if ((g_nodeCount & 127) == 127) {
+ if (new Date().getTime() - g_startTime > g_timeout) {
+ // Time cutoff
+ g_searchValid = false;
+ return beta - 1;
+ }
+ }
- g_nodeCount++;
-
- if (IsRepDraw())
- return 0;
-
- // Mate distance pruning
- if (minEval + depth >= beta)
- return beta;
-
- if (maxEval - (depth + 1) < beta)
- return beta - 1;
-
- var hashMove = null;
- var hashNode = g_hashTable[g_hashKeyLow & g_hashMask];
- if (hashNode != null && hashNode.lock == g_hashKeyHigh) {
- hashMove = hashNode.bestMove;
- if (hashNode.hashDepth >= ply) {
- var hashValue = hashNode.value;
-
- // Fixup mate scores
- if (hashValue >= maxMateBuffer)
- hashValue -= depth;
- else if (hashValue <= minMateBuffer)
- hashValue += depth;
-
- if (hashNode.flags == hashflagExact)
- return hashValue;
- if (hashNode.flags == hashflagAlpha && hashValue < beta)
- return hashValue;
- if (hashNode.flags == hashflagBeta && hashValue >= beta)
- return hashValue;
- }
- }
+ g_nodeCount++;
- // TODO - positional gain?
-
- if (!g_inCheck &&
- allowNull &&
- beta > minMateBuffer &&
- beta < maxMateBuffer) {
- // Try some razoring
- if (hashMove == null &&
- ply < 4) {
- var razorMargin = 2500 + 200 * ply;
- if (g_baseEval < beta - razorMargin) {
- var razorBeta = beta - razorMargin;
- var v = QSearch(razorBeta - 1, razorBeta, 0);
- if (v < razorBeta)
- return v;
- }
- }
-
- // TODO - static null move
-
- // Null move
- if (ply > 1 &&
- g_baseEval >= beta - (ply >= 4 ? 2500 : 0) &&
- // Disable null move if potential zugzwang (no big pieces)
- (g_pieceCount[pieceBishop | g_toMove] != 0 ||
- g_pieceCount[pieceKnight | g_toMove] != 0 ||
- g_pieceCount[pieceRook | g_toMove] != 0 ||
- g_pieceCount[pieceQueen | g_toMove] != 0)) {
- var r = 3 + (ply >= 5 ? 1 : ply / 4);
- if (g_baseEval - beta > 1500) r++;
-
- g_toMove = 8 - g_toMove;
- g_baseEval = -g_baseEval;
- g_hashKeyLow ^= g_zobristBlackLow;
- g_hashKeyHigh ^= g_zobristBlackHigh;
-
- var value = -AllCutNode(ply - r, depth + 1, -(beta - 1), false);
-
- g_hashKeyLow ^= g_zobristBlackLow;
- g_hashKeyHigh ^= g_zobristBlackHigh;
- g_toMove = 8 - g_toMove;
- g_baseEval = -g_baseEval;
-
- if (value >= beta)
- return beta;
- }
- }
+ if (IsRepDraw()) return 0;
- var moveMade = false;
- var realEval = minEval - 1;
- var inCheck = g_inCheck;
+ // Mate distance pruning
+ if (minEval + depth >= beta) return beta;
- var movePicker = new MovePicker(hashMove, depth, g_killers[depth][0], g_killers[depth][1]);
+ if (maxEval - (depth + 1) < beta) return beta - 1;
- for (;;) {
- var currentMove = movePicker.nextMove();
- if (currentMove == 0) {
- break;
- }
+ var hashMove = null;
+ var hashNode = g_hashTable[g_hashKeyLow & g_hashMask];
+ if (hashNode != null && hashNode.lock == g_hashKeyHigh) {
+ hashMove = hashNode.bestMove;
+ if (hashNode.hashDepth >= ply) {
+ var hashValue = hashNode.value;
- var plyToSearch = ply - 1;
+ // Fixup mate scores
+ if (hashValue >= maxMateBuffer) hashValue -= depth;
+ else if (hashValue <= minMateBuffer) hashValue += depth;
- if (!MakeMove(currentMove)) {
- continue;
- }
+ if (hashNode.flags == hashflagExact) return hashValue;
+ if (hashNode.flags == hashflagAlpha && hashValue < beta) return hashValue;
+ if (hashNode.flags == hashflagBeta && hashValue >= beta) return hashValue;
+ }
+ }
+
+ // TODO - positional gain?
+
+ if (!g_inCheck && allowNull && beta > minMateBuffer && beta < maxMateBuffer) {
+ // Try some razoring
+ if (hashMove == null && ply < 4) {
+ var razorMargin = 2500 + 200 * ply;
+ if (g_baseEval < beta - razorMargin) {
+ var razorBeta = beta - razorMargin;
+ var v = QSearch(razorBeta - 1, razorBeta, 0);
+ if (v < razorBeta) return v;
+ }
+ }
+
+ // TODO - static null move
+
+ // Null move
+ if (
+ ply > 1 &&
+ g_baseEval >= beta - (ply >= 4 ? 2500 : 0) &&
+ // Disable null move if potential zugzwang (no big pieces)
+ (g_pieceCount[pieceBishop | g_toMove] != 0 ||
+ g_pieceCount[pieceKnight | g_toMove] != 0 ||
+ g_pieceCount[pieceRook | g_toMove] != 0 ||
+ g_pieceCount[pieceQueen | g_toMove] != 0)
+ ) {
+ var r = 3 + (ply >= 5 ? 1 : ply / 4);
+ if (g_baseEval - beta > 1500) r++;
+
+ g_toMove = 8 - g_toMove;
+ g_baseEval = -g_baseEval;
+ g_hashKeyLow ^= g_zobristBlackLow;
+ g_hashKeyHigh ^= g_zobristBlackHigh;
+
+ var value = -AllCutNode(ply - r, depth + 1, -(beta - 1), false);
+
+ g_hashKeyLow ^= g_zobristBlackLow;
+ g_hashKeyHigh ^= g_zobristBlackHigh;
+ g_toMove = 8 - g_toMove;
+ g_baseEval = -g_baseEval;
+
+ if (value >= beta) return beta;
+ }
+ }
+
+ var moveMade = false;
+ var realEval = minEval - 1;
+ var inCheck = g_inCheck;
+
+ var movePicker = new MovePicker(hashMove, depth, g_killers[depth][0], g_killers[depth][1]);
+
+ for (;;) {
+ var currentMove = movePicker.nextMove();
+ if (currentMove == 0) {
+ break;
+ }
+
+ var plyToSearch = ply - 1;
+
+ if (!MakeMove(currentMove)) {
+ continue;
+ }
- var value;
- var doFullSearch = true;
+ var value;
+ var doFullSearch = true;
- if (g_inCheck) {
- // Check extensions
- plyToSearch++;
- } else {
- var reduced = plyToSearch - (movePicker.atMove > 14 ? 2 : 1);
+ if (g_inCheck) {
+ // Check extensions
+ plyToSearch++;
+ } else {
+ var reduced = plyToSearch - (movePicker.atMove > 14 ? 2 : 1);
- // Futility pruning
-/* if (movePicker.stage == 5 && !inCheck) {
+ // Futility pruning
+ /* if (movePicker.stage == 5 && !inCheck) {
if (movePicker.atMove >= (15 + (1 << (5 * ply) >> 2)) &&
realEval > minMateBuffer) {
UnmakeMove(currentMove);
@@ -957,177 +969,173 @@ function AllCutNode(ply, depth, beta, allowNull) {
}
}*/
- // Late move reductions
- if (movePicker.stage == 5 && movePicker.atMove > 5 && ply >= 3) {
- value = -AllCutNode(reduced, depth + 1, -(beta - 1), true);
- doFullSearch = (value >= beta);
- }
- }
+ // Late move reductions
+ if (movePicker.stage == 5 && movePicker.atMove > 5 && ply >= 3) {
+ value = -AllCutNode(reduced, depth + 1, -(beta - 1), true);
+ doFullSearch = value >= beta;
+ }
+ }
- if (doFullSearch) {
- value = -AllCutNode(plyToSearch, depth + 1, -(beta - 1), true);
- }
+ if (doFullSearch) {
+ value = -AllCutNode(plyToSearch, depth + 1, -(beta - 1), true);
+ }
- moveMade = true;
+ moveMade = true;
- UnmakeMove(currentMove);
+ UnmakeMove(currentMove);
- if (!g_searchValid) {
- return beta - 1;
- }
+ if (!g_searchValid) {
+ return beta - 1;
+ }
- if (value > realEval) {
- if (value >= beta) {
- var histTo = (currentMove >> 8) & 0xFF;
+ if (value > realEval) {
+ if (value >= beta) {
+ var histTo = (currentMove >> 8) & 0xff;
if (g_board[histTo] == 0) {
- var histPiece = g_board[currentMove & 0xFF] & 0xF;
- historyTable[histPiece][histTo] += ply * ply;
- if (historyTable[histPiece][histTo] > 32767) {
- historyTable[histPiece][histTo] >>= 1;
- }
-
- if (g_killers[depth][0] != currentMove) {
- g_killers[depth][1] = g_killers[depth][0];
- g_killers[depth][0] = currentMove;
- }
+ var histPiece = g_board[currentMove & 0xff] & 0xf;
+ historyTable[histPiece][histTo] += ply * ply;
+ if (historyTable[histPiece][histTo] > 32767) {
+ historyTable[histPiece][histTo] >>= 1;
+ }
+
+ if (g_killers[depth][0] != currentMove) {
+ g_killers[depth][1] = g_killers[depth][0];
+ g_killers[depth][0] = currentMove;
+ }
}
- StoreHash(value, hashflagBeta, ply, currentMove, depth);
- return value;
- }
+ StoreHash(value, hashflagBeta, ply, currentMove, depth);
+ return value;
+ }
- realEval = value;
- hashMove = currentMove;
- }
- }
+ realEval = value;
+ hashMove = currentMove;
+ }
+ }
- if (!moveMade) {
- // If we have no valid moves it's either stalemate or checkmate
- if (g_inCheck)
- // Checkmate.
- return minEval + depth;
- else
- // Stalemate
- return 0;
- }
+ if (!moveMade) {
+ // If we have no valid moves it's either stalemate or checkmate
+ if (g_inCheck)
+ // Checkmate.
+ return minEval + depth;
+ // Stalemate
+ else return 0;
+ }
- StoreHash(realEval, hashflagAlpha, ply, hashMove, depth);
-
- return realEval;
+ StoreHash(realEval, hashflagAlpha, ply, hashMove, depth);
+
+ return realEval;
}
function AlphaBeta(ply, depth, alpha, beta) {
- if (ply <= 0) {
- return QSearch(alpha, beta, 0);
- }
+ if (ply <= 0) {
+ return QSearch(alpha, beta, 0);
+ }
- g_nodeCount++;
+ g_nodeCount++;
- if (depth > 0 && IsRepDraw())
- return 0;
+ if (depth > 0 && IsRepDraw()) return 0;
- // Mate distance pruning
- var oldAlpha = alpha;
- alpha = alpha < minEval + depth ? alpha : minEval + depth;
- beta = beta > maxEval - (depth + 1) ? beta : maxEval - (depth + 1);
- if (alpha >= beta)
- return alpha;
+ // Mate distance pruning
+ var oldAlpha = alpha;
+ alpha = alpha < minEval + depth ? alpha : minEval + depth;
+ beta = beta > maxEval - (depth + 1) ? beta : maxEval - (depth + 1);
+ if (alpha >= beta) return alpha;
- var hashMove = null;
- var hashFlag = hashflagAlpha;
- var hashNode = g_hashTable[g_hashKeyLow & g_hashMask];
- if (hashNode != null && hashNode.lock == g_hashKeyHigh) {
- hashMove = hashNode.bestMove;
- }
-
- var inCheck = g_inCheck;
+ var hashMove = null;
+ var hashFlag = hashflagAlpha;
+ var hashNode = g_hashTable[g_hashKeyLow & g_hashMask];
+ if (hashNode != null && hashNode.lock == g_hashKeyHigh) {
+ hashMove = hashNode.bestMove;
+ }
- var moveMade = false;
- var realEval = minEval;
+ var inCheck = g_inCheck;
- var movePicker = new MovePicker(hashMove, depth, g_killers[depth][0], g_killers[depth][1]);
+ var moveMade = false;
+ var realEval = minEval;
- for (;;) {
- var currentMove = movePicker.nextMove();
- if (currentMove == 0) {
- break;
- }
+ var movePicker = new MovePicker(hashMove, depth, g_killers[depth][0], g_killers[depth][1]);
- var plyToSearch = ply - 1;
+ for (;;) {
+ var currentMove = movePicker.nextMove();
+ if (currentMove == 0) {
+ break;
+ }
- if (!MakeMove(currentMove)) {
- continue;
- }
+ var plyToSearch = ply - 1;
- if (g_inCheck) {
- // Check extensions
- plyToSearch++;
- }
+ if (!MakeMove(currentMove)) {
+ continue;
+ }
- var value;
- if (moveMade) {
- value = -AllCutNode(plyToSearch, depth + 1, -alpha, true);
- if (value > alpha) {
- value = -AlphaBeta(plyToSearch, depth + 1, -beta, -alpha);
- }
- } else {
- value = -AlphaBeta(plyToSearch, depth + 1, -beta, -alpha);
- }
+ if (g_inCheck) {
+ // Check extensions
+ plyToSearch++;
+ }
- moveMade = true;
+ var value;
+ if (moveMade) {
+ value = -AllCutNode(plyToSearch, depth + 1, -alpha, true);
+ if (value > alpha) {
+ value = -AlphaBeta(plyToSearch, depth + 1, -beta, -alpha);
+ }
+ } else {
+ value = -AlphaBeta(plyToSearch, depth + 1, -beta, -alpha);
+ }
- UnmakeMove(currentMove);
+ moveMade = true;
- if (!g_searchValid) {
- return alpha;
- }
+ UnmakeMove(currentMove);
- if (value > realEval) {
- if (value >= beta) {
- var histTo = (currentMove >> 8) & 0xFF;
- if (g_board[histTo] == 0) {
- var histPiece = g_board[currentMove & 0xFF] & 0xF;
- historyTable[histPiece][histTo] += ply * ply;
- if (historyTable[histPiece][histTo] > 32767) {
- historyTable[histPiece][histTo] >>= 1;
- }
+ if (!g_searchValid) {
+ return alpha;
+ }
- if (g_killers[depth][0] != currentMove) {
- g_killers[depth][1] = g_killers[depth][0];
- g_killers[depth][0] = currentMove;
- }
- }
+ if (value > realEval) {
+ if (value >= beta) {
+ var histTo = (currentMove >> 8) & 0xff;
+ if (g_board[histTo] == 0) {
+ var histPiece = g_board[currentMove & 0xff] & 0xf;
+ historyTable[histPiece][histTo] += ply * ply;
+ if (historyTable[histPiece][histTo] > 32767) {
+ historyTable[histPiece][histTo] >>= 1;
+ }
+
+ if (g_killers[depth][0] != currentMove) {
+ g_killers[depth][1] = g_killers[depth][0];
+ g_killers[depth][0] = currentMove;
+ }
+ }
- StoreHash(value, hashflagBeta, ply, currentMove, depth);
- return value;
- }
+ StoreHash(value, hashflagBeta, ply, currentMove, depth);
+ return value;
+ }
- if (value > oldAlpha) {
- hashFlag = hashflagExact;
- alpha = value;
- }
+ if (value > oldAlpha) {
+ hashFlag = hashflagExact;
+ alpha = value;
+ }
- realEval = value;
- hashMove = currentMove;
- }
- }
+ realEval = value;
+ hashMove = currentMove;
+ }
+ }
- if (!moveMade) {
- // If we have no valid moves it's either stalemate or checkmate
- if (inCheck)
- // Checkmate.
- return minEval + depth;
- else
- // Stalemate
- return 0;
- }
+ if (!moveMade) {
+ // If we have no valid moves it's either stalemate or checkmate
+ if (inCheck)
+ // Checkmate.
+ return minEval + depth;
+ // Stalemate
+ else return 0;
+ }
- StoreHash(realEval, hashFlag, ply, hashMove, depth);
-
- return realEval;
+ StoreHash(realEval, hashFlag, ply, hashMove, depth);
+
+ return realEval;
}
-//
+//
// Board code
//
@@ -1152,18 +1160,13 @@ var g_rookDeltas = [-1, +1, -16, +16];
var g_queenDeltas = [-1, +1, -15, +15, -17, +17, -16, +16];
var g_castleRightsMask = [
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-0, 0, 0, 0, 7,15,15,15, 3,15,15,11, 0, 0, 0, 0,
-0, 0, 0, 0,15,15,15,15,15,15,15,15, 0, 0, 0, 0,
-0, 0, 0, 0,15,15,15,15,15,15,15,15, 0, 0, 0, 0,
-0, 0, 0, 0,15,15,15,15,15,15,15,15, 0, 0, 0, 0,
-0, 0, 0, 0,15,15,15,15,15,15,15,15, 0, 0, 0, 0,
-0, 0, 0, 0,15,15,15,15,15,15,15,15, 0, 0, 0, 0,
-0, 0, 0, 0,15,15,15,15,15,15,15,15, 0, 0, 0, 0,
-0, 0, 0, 0,13,15,15,15,12,15,15,14, 0, 0, 0, 0,
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 15, 15,
+ 15, 3, 15, 15, 11, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+ 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+ 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+ 15, 0, 0, 0, 0, 0, 0, 0, 0, 13, 15, 15, 15, 12, 15, 15, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+];
var moveflagEPC = 0x2 << 16;
var moveflagCastleKing = 0x4 << 16;
@@ -1174,81 +1177,71 @@ var moveflagPromoteQueen = 0x40 << 16;
var moveflagPromoteBishop = 0x80 << 16;
function MT() {
- var N = 624;
+ var N = 624;
var M = 397;
var MAG01 = [0x0, 0x9908b0df];
-
- this.mt = new Array(N);
- this.mti = N + 1;
- this.setSeed = function()
- {
+ this.mt = new Array(N);
+ this.mti = N + 1;
+
+ this.setSeed = function () {
var a = arguments;
switch (a.length) {
- case 1:
- if (a[0].constructor === Number) {
- this.mt[0]= a[0];
- for (var i = 1; i < N; ++i) {
- var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30);
- this.mt[i] = ((1812433253 * ((s & 0xffff0000) >>> 16))
- << 16)
- + 1812433253 * (s & 0x0000ffff)
- + i;
+ case 1:
+ if (a[0].constructor === Number) {
+ this.mt[0] = a[0];
+ for (var i = 1; i < N; ++i) {
+ var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30);
+ this.mt[i] = ((1812433253 * ((s & 0xffff0000) >>> 16)) << 16) + 1812433253 * (s & 0x0000ffff) + i;
+ }
+ this.mti = N;
+ return;
}
- this.mti = N;
- return;
- }
- this.setSeed(19650218);
-
- var l = a[0].length;
- var i = 1;
- var j = 0;
-
- for (var k = N > l ? N : l; k != 0; --k) {
- var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30)
- this.mt[i] = (this.mt[i]
- ^ (((1664525 * ((s & 0xffff0000) >>> 16)) << 16)
- + 1664525 * (s & 0x0000ffff)))
- + a[0][j]
- + j;
- if (++i >= N) {
- this.mt[0] = this.mt[N - 1];
- i = 1;
- }
- if (++j >= l) {
- j = 0;
+ this.setSeed(19650218);
+
+ var l = a[0].length;
+ var i = 1;
+ var j = 0;
+
+ for (var k = N > l ? N : l; k != 0; --k) {
+ var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30);
+ this.mt[i] =
+ (this.mt[i] ^ (((1664525 * ((s & 0xffff0000) >>> 16)) << 16) + 1664525 * (s & 0x0000ffff))) + a[0][j] + j;
+ if (++i >= N) {
+ this.mt[0] = this.mt[N - 1];
+ i = 1;
+ }
+ if (++j >= l) {
+ j = 0;
+ }
}
- }
- for (var k = N - 1; k != 0; --k) {
- var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30);
- this.mt[i] = (this.mt[i]
- ^ (((1566083941 * ((s & 0xffff0000) >>> 16)) << 16)
- + 1566083941 * (s & 0x0000ffff)))
- - i;
- if (++i >= N) {
- this.mt[0] = this.mt[N-1];
- i = 1;
+ for (var k = N - 1; k != 0; --k) {
+ var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30);
+ this.mt[i] =
+ (this.mt[i] ^ (((1566083941 * ((s & 0xffff0000) >>> 16)) << 16) + 1566083941 * (s & 0x0000ffff))) - i;
+ if (++i >= N) {
+ this.mt[0] = this.mt[N - 1];
+ i = 1;
+ }
}
- }
- this.mt[0] = 0x80000000;
- return;
- default:
- var seeds = new Array();
- for (var i = 0; i < a.length; ++i) {
- seeds.push(a[i]);
- }
- this.setSeed(seeds);
- return;
+ this.mt[0] = 0x80000000;
+ return;
+ default:
+ var seeds = new Array();
+ for (var i = 0; i < a.length; ++i) {
+ seeds.push(a[i]);
+ }
+ this.setSeed(seeds);
+ return;
}
- }
+ };
- this.setSeed(0x1BADF00D);
+ this.setSeed(0x1badf00d);
- this.next = function (bits)
- {
+ this.next = function (bits) {
if (this.mti >= N) {
var x = 0;
@@ -1271,8 +1264,8 @@ function MT() {
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= y >>> 18;
- return (y >>> (32 - bits)) & 0xFFFFFFFF;
- }
+ return (y >>> (32 - bits)) & 0xffffffff;
+ };
}
// Position variables
@@ -1311,314 +1304,315 @@ var hashflagBeta = 2;
var hashflagExact = 3;
function HashEntry(lock, value, flags, hashDepth, bestMove, globalPly) {
- this.lock = lock;
- this.value = value;
- this.flags = flags;
- this.hashDepth = hashDepth;
- this.bestMove = bestMove;
+ this.lock = lock;
+ this.value = value;
+ this.flags = flags;
+ this.hashDepth = hashDepth;
+ this.bestMove = bestMove;
}
function MakeSquare(row, column) {
- return ((row + 2) << 4) | (column + 4);
+ return ((row + 2) << 4) | (column + 4);
}
function MakeTable(table) {
- var result = new Array(256);
- for (var i = 0; i < 256; i++) {
- result[i] = 0;
- }
- for (var row = 0; row < 8; row++) {
- for (var col = 0; col < 8; col++) {
- result[MakeSquare(row, col)] = table[row * 8 + col];
- }
- }
- return result;
+ var result = new Array(256);
+ for (var i = 0; i < 256; i++) {
+ result[i] = 0;
+ }
+ for (var row = 0; row < 8; row++) {
+ for (var col = 0; col < 8; col++) {
+ result[MakeSquare(row, col)] = table[row * 8 + col];
+ }
+ }
+ return result;
}
function ResetGame() {
- g_killers = new Array(128);
- for (var i = 0; i < 128; i++) {
- g_killers[i] = [0, 0];
- }
-
- g_hashTable = new Array(g_hashSize);
-
- for (var i = 0; i < 32; i++) {
- historyTable[i] = new Array(256);
- for (var j = 0; j < 256; j++)
- historyTable[i][j] = 0;
- }
+ g_killers = new Array(128);
+ for (var i = 0; i < 128; i++) {
+ g_killers[i] = [0, 0];
+ }
- var mt = new MT(0x1badf00d);
+ g_hashTable = new Array(g_hashSize);
- g_zobristLow = new Array(256);
- g_zobristHigh = new Array(256);
- for (var i = 0; i < 256; i++) {
- g_zobristLow[i] = new Array(16);
- g_zobristHigh[i] = new Array(16);
- for (var j = 0; j < 16; j++) {
- g_zobristLow[i][j] = mt.next(32);
- g_zobristHigh[i][j] = mt.next(32);
- }
- }
- g_zobristBlackLow = mt.next(32);
- g_zobristBlackHigh = mt.next(32);
+ for (var i = 0; i < 32; i++) {
+ historyTable[i] = new Array(256);
+ for (var j = 0; j < 256; j++) historyTable[i][j] = 0;
+ }
- for (var row = 0; row < 8; row++) {
- for (var col = 0; col < 8; col++) {
- var square = MakeSquare(row, col);
- flipTable[square] = MakeSquare(7 - row, col);
- }
- }
+ var mt = new MT(0x1badf00d);
- pieceSquareAdj[piecePawn] = MakeTable(pawnAdj);
- pieceSquareAdj[pieceKnight] = MakeTable(knightAdj);
- pieceSquareAdj[pieceBishop] = MakeTable(bishopAdj);
- pieceSquareAdj[pieceRook] = MakeTable(rookAdj);
- pieceSquareAdj[pieceQueen] = MakeTable(emptyAdj);
- pieceSquareAdj[pieceKing] = MakeTable(kingAdj);
-
- var pieceDeltas = [[], [], g_knightDeltas, g_bishopDeltas, g_rookDeltas, g_queenDeltas, g_queenDeltas];
-
- for (var i = 0; i < 256; i++) {
- g_vectorDelta[i] = new Object();
- g_vectorDelta[i].delta = 0;
- g_vectorDelta[i].pieceMask = new Array(2);
- g_vectorDelta[i].pieceMask[0] = 0;
- g_vectorDelta[i].pieceMask[1] = 0;
- }
-
- // Initialize the vector delta table
- for (var row = 0; row < 0x80; row += 0x10)
- for (var col = 0; col < 0x8; col++) {
- var square = row | col;
-
- // Pawn moves
- var index = square - (square - 17) + 128;
- g_vectorDelta[index].pieceMask[colorWhite >> 3] |= (1 << piecePawn);
- index = square - (square - 15) + 128;
- g_vectorDelta[index].pieceMask[colorWhite >> 3] |= (1 << piecePawn);
-
- index = square - (square + 17) + 128;
- g_vectorDelta[index].pieceMask[0] |= (1 << piecePawn);
- index = square - (square + 15) + 128;
- g_vectorDelta[index].pieceMask[0] |= (1 << piecePawn);
-
- for (var i = pieceKnight; i <= pieceKing; i++) {
- for (var dir = 0; dir < pieceDeltas[i].length; dir++) {
- var target = square + pieceDeltas[i][dir];
- while (!(target & 0x88)) {
- index = square - target + 128;
-
- g_vectorDelta[index].pieceMask[colorWhite >> 3] |= (1 << i);
- g_vectorDelta[index].pieceMask[0] |= (1 << i);
-
- var flip = -1;
- if (square < target)
- flip = 1;
-
- if ((square & 0xF0) == (target & 0xF0)) {
- // On the same row
- g_vectorDelta[index].delta = flip * 1;
- } else if ((square & 0x0F) == (target & 0x0F)) {
- // On the same column
- g_vectorDelta[index].delta = flip * 16;
- } else if ((square % 15) == (target % 15)) {
- g_vectorDelta[index].delta = flip * 15;
- } else if ((square % 17) == (target % 17)) {
- g_vectorDelta[index].delta = flip * 17;
- }
+ g_zobristLow = new Array(256);
+ g_zobristHigh = new Array(256);
+ for (var i = 0; i < 256; i++) {
+ g_zobristLow[i] = new Array(16);
+ g_zobristHigh[i] = new Array(16);
+ for (var j = 0; j < 16; j++) {
+ g_zobristLow[i][j] = mt.next(32);
+ g_zobristHigh[i][j] = mt.next(32);
+ }
+ }
+ g_zobristBlackLow = mt.next(32);
+ g_zobristBlackHigh = mt.next(32);
- if (i == pieceKnight) {
- g_vectorDelta[index].delta = pieceDeltas[i][dir];
- break;
- }
+ for (var row = 0; row < 8; row++) {
+ for (var col = 0; col < 8; col++) {
+ var square = MakeSquare(row, col);
+ flipTable[square] = MakeSquare(7 - row, col);
+ }
+ }
- if (i == pieceKing)
- break;
+ pieceSquareAdj[piecePawn] = MakeTable(pawnAdj);
+ pieceSquareAdj[pieceKnight] = MakeTable(knightAdj);
+ pieceSquareAdj[pieceBishop] = MakeTable(bishopAdj);
+ pieceSquareAdj[pieceRook] = MakeTable(rookAdj);
+ pieceSquareAdj[pieceQueen] = MakeTable(emptyAdj);
+ pieceSquareAdj[pieceKing] = MakeTable(kingAdj);
+
+ var pieceDeltas = [[], [], g_knightDeltas, g_bishopDeltas, g_rookDeltas, g_queenDeltas, g_queenDeltas];
+
+ for (var i = 0; i < 256; i++) {
+ g_vectorDelta[i] = new Object();
+ g_vectorDelta[i].delta = 0;
+ g_vectorDelta[i].pieceMask = new Array(2);
+ g_vectorDelta[i].pieceMask[0] = 0;
+ g_vectorDelta[i].pieceMask[1] = 0;
+ }
- target += pieceDeltas[i][dir];
- }
- }
- }
- }
+ // Initialize the vector delta table
+ for (var row = 0; row < 0x80; row += 0x10)
+ for (var col = 0; col < 0x8; col++) {
+ var square = row | col;
+
+ // Pawn moves
+ var index = square - (square - 17) + 128;
+ g_vectorDelta[index].pieceMask[colorWhite >> 3] |= 1 << piecePawn;
+ index = square - (square - 15) + 128;
+ g_vectorDelta[index].pieceMask[colorWhite >> 3] |= 1 << piecePawn;
+
+ index = square - (square + 17) + 128;
+ g_vectorDelta[index].pieceMask[0] |= 1 << piecePawn;
+ index = square - (square + 15) + 128;
+ g_vectorDelta[index].pieceMask[0] |= 1 << piecePawn;
+
+ for (var i = pieceKnight; i <= pieceKing; i++) {
+ for (var dir = 0; dir < pieceDeltas[i].length; dir++) {
+ var target = square + pieceDeltas[i][dir];
+ while (!(target & 0x88)) {
+ index = square - target + 128;
+
+ g_vectorDelta[index].pieceMask[colorWhite >> 3] |= 1 << i;
+ g_vectorDelta[index].pieceMask[0] |= 1 << i;
+
+ var flip = -1;
+ if (square < target) flip = 1;
+
+ if ((square & 0xf0) == (target & 0xf0)) {
+ // On the same row
+ g_vectorDelta[index].delta = flip * 1;
+ } else if ((square & 0x0f) == (target & 0x0f)) {
+ // On the same column
+ g_vectorDelta[index].delta = flip * 16;
+ } else if (square % 15 == target % 15) {
+ g_vectorDelta[index].delta = flip * 15;
+ } else if (square % 17 == target % 17) {
+ g_vectorDelta[index].delta = flip * 17;
+ }
+
+ if (i == pieceKnight) {
+ g_vectorDelta[index].delta = pieceDeltas[i][dir];
+ break;
+ }
+
+ if (i == pieceKing) break;
+
+ target += pieceDeltas[i][dir];
+ }
+ }
+ }
+ }
- InitializeEval();
- InitializeFromFen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
+ InitializeEval();
+ InitializeFromFen('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');
}
function InitializeEval() {
- g_mobUnit = new Array(2);
- for (var i = 0; i < 2; i++) {
- g_mobUnit[i] = new Array();
- var enemy = i == 0 ? 0x10 : 8;
- var friend = i == 0 ? 8 : 0x10;
- g_mobUnit[i][0] = 1;
- g_mobUnit[i][0x80] = 0;
- g_mobUnit[i][enemy | piecePawn] = 1;
- g_mobUnit[i][enemy | pieceBishop] = 2;
- g_mobUnit[i][enemy | pieceKnight] = 2;
- g_mobUnit[i][enemy | pieceRook] = 4;
- g_mobUnit[i][enemy | pieceQueen] = 6;
- g_mobUnit[i][enemy | pieceKing] = 6;
- g_mobUnit[i][friend | piecePawn] = 0;
- g_mobUnit[i][friend | pieceBishop] = 0;
- g_mobUnit[i][friend | pieceKnight] = 0;
- g_mobUnit[i][friend | pieceRook] = 0;
- g_mobUnit[i][friend | pieceQueen] = 0;
- g_mobUnit[i][friend | pieceKing] = 0;
- }
+ g_mobUnit = new Array(2);
+ for (var i = 0; i < 2; i++) {
+ g_mobUnit[i] = new Array();
+ var enemy = i == 0 ? 0x10 : 8;
+ var friend = i == 0 ? 8 : 0x10;
+ g_mobUnit[i][0] = 1;
+ g_mobUnit[i][0x80] = 0;
+ g_mobUnit[i][enemy | piecePawn] = 1;
+ g_mobUnit[i][enemy | pieceBishop] = 2;
+ g_mobUnit[i][enemy | pieceKnight] = 2;
+ g_mobUnit[i][enemy | pieceRook] = 4;
+ g_mobUnit[i][enemy | pieceQueen] = 6;
+ g_mobUnit[i][enemy | pieceKing] = 6;
+ g_mobUnit[i][friend | piecePawn] = 0;
+ g_mobUnit[i][friend | pieceBishop] = 0;
+ g_mobUnit[i][friend | pieceKnight] = 0;
+ g_mobUnit[i][friend | pieceRook] = 0;
+ g_mobUnit[i][friend | pieceQueen] = 0;
+ g_mobUnit[i][friend | pieceKing] = 0;
+ }
}
function SetHash() {
- var result = new Object();
- result.hashKeyLow = 0;
- result.hashKeyHigh = 0;
-
- for (var i = 0; i < 256; i++) {
- var piece = g_board[i];
- if (piece & 0x18) {
- result.hashKeyLow ^= g_zobristLow[i][piece & 0xF]
- result.hashKeyHigh ^= g_zobristHigh[i][piece & 0xF]
- }
- }
+ var result = new Object();
+ result.hashKeyLow = 0;
+ result.hashKeyHigh = 0;
+
+ for (var i = 0; i < 256; i++) {
+ var piece = g_board[i];
+ if (piece & 0x18) {
+ result.hashKeyLow ^= g_zobristLow[i][piece & 0xf];
+ result.hashKeyHigh ^= g_zobristHigh[i][piece & 0xf];
+ }
+ }
- if (!g_toMove) {
- result.hashKeyLow ^= g_zobristBlackLow;
- result.hashKeyHigh ^= g_zobristBlackHigh;
- }
+ if (!g_toMove) {
+ result.hashKeyLow ^= g_zobristBlackLow;
+ result.hashKeyHigh ^= g_zobristBlackHigh;
+ }
- return result;
+ return result;
}
function InitializeFromFen(fen) {
- var chunks = fen.split(' ');
-
- for (var i = 0; i < 256; i++)
- g_board[i] = 0x80;
-
- var row = 0;
- var col = 0;
-
- var pieces = chunks[0];
- for (var i = 0; i < pieces.length; i++) {
- var c = pieces.charAt(i);
-
- if (c == '/') {
- row++;
- col = 0;
- }
- else {
- if (c >= '0' && c <= '9') {
- for (var j = 0; j < parseInt(c); j++) {
- g_board[MakeSquare(row, col)] = 0;
- col++;
- }
- }
- else {
- var isBlack = c >= 'a' && c <= 'z';
- var piece = isBlack ? colorBlack : colorWhite;
- if (!isBlack)
- c = pieces.toLowerCase().charAt(i);
- switch (c) {
- case 'p':
- piece |= piecePawn;
- break;
- case 'b':
- piece |= pieceBishop;
- break;
- case 'n':
- piece |= pieceKnight;
- break;
- case 'r':
- piece |= pieceRook;
- break;
- case 'q':
- piece |= pieceQueen;
- break;
- case 'k':
- piece |= pieceKing;
- break;
- }
-
- g_board[MakeSquare(row, col)] = piece;
- col++;
- }
- }
- }
-
- InitializePieceList();
-
- g_toMove = chunks[1].charAt(0) == 'w' ? colorWhite : 0;
- var them = 8 - g_toMove;
-
- g_castleRights = 0;
- if (chunks[2].indexOf('K') != -1) {
- if (g_board[MakeSquare(7, 4)] != (pieceKing | colorWhite) ||
- g_board[MakeSquare(7, 7)] != (pieceRook | colorWhite)) {
- return 'Invalid FEN: White kingside castling not allowed';
- }
- g_castleRights |= 1;
- }
- if (chunks[2].indexOf('Q') != -1) {
- if (g_board[MakeSquare(7, 4)] != (pieceKing | colorWhite) ||
- g_board[MakeSquare(7, 0)] != (pieceRook | colorWhite)) {
- return 'Invalid FEN: White queenside castling not allowed';
- }
- g_castleRights |= 2;
- }
- if (chunks[2].indexOf('k') != -1) {
- if (g_board[MakeSquare(0, 4)] != (pieceKing | colorBlack) ||
- g_board[MakeSquare(0, 7)] != (pieceRook | colorBlack)) {
- return 'Invalid FEN: Black kingside castling not allowed';
- }
- g_castleRights |= 4;
- }
- if (chunks[2].indexOf('q') != -1) {
- if (g_board[MakeSquare(0, 4)] != (pieceKing | colorBlack) ||
- g_board[MakeSquare(0, 0)] != (pieceRook | colorBlack)) {
- return 'Invalid FEN: Black queenside castling not allowed';
- }
- g_castleRights |= 8;
- }
-
- g_enPassentSquare = -1;
- if (chunks[3].indexOf('-') == -1) {
- var col = chunks[3].charAt(0).charCodeAt() - 'a'.charCodeAt();
- var row = 8 - (chunks[3].charAt(1).charCodeAt() - '0'.charCodeAt());
- g_enPassentSquare = MakeSquare(row, col);
- }
+ var chunks = fen.split(' ');
- var hashResult = SetHash();
- g_hashKeyLow = hashResult.hashKeyLow;
- g_hashKeyHigh = hashResult.hashKeyHigh;
-
- g_baseEval = 0;
- for (var i = 0; i < 256; i++) {
- if (g_board[i] & colorWhite) {
- g_baseEval += pieceSquareAdj[g_board[i] & 0x7][i];
- g_baseEval += materialTable[g_board[i] & 0x7];
- } else if (g_board[i] & colorBlack) {
- g_baseEval -= pieceSquareAdj[g_board[i] & 0x7][flipTable[i]];
- g_baseEval -= materialTable[g_board[i] & 0x7];
- }
- }
- if (!g_toMove) g_baseEval = -g_baseEval;
+ for (var i = 0; i < 256; i++) g_board[i] = 0x80;
- g_move50 = 0;
- g_inCheck = IsSquareAttackable(g_pieceList[(g_toMove | pieceKing) << 4], them);
+ var row = 0;
+ var col = 0;
- // Check for king capture (invalid FEN)
- if (IsSquareAttackable(g_pieceList[(them | pieceKing) << 4], g_toMove)) {
- return 'Invalid FEN: Can capture king';
- }
+ var pieces = chunks[0];
+ for (var i = 0; i < pieces.length; i++) {
+ var c = pieces.charAt(i);
+
+ if (c == '/') {
+ row++;
+ col = 0;
+ } else {
+ if (c >= '0' && c <= '9') {
+ for (var j = 0; j < parseInt(c); j++) {
+ g_board[MakeSquare(row, col)] = 0;
+ col++;
+ }
+ } else {
+ var isBlack = c >= 'a' && c <= 'z';
+ var piece = isBlack ? colorBlack : colorWhite;
+ if (!isBlack) c = pieces.toLowerCase().charAt(i);
+ switch (c) {
+ case 'p':
+ piece |= piecePawn;
+ break;
+ case 'b':
+ piece |= pieceBishop;
+ break;
+ case 'n':
+ piece |= pieceKnight;
+ break;
+ case 'r':
+ piece |= pieceRook;
+ break;
+ case 'q':
+ piece |= pieceQueen;
+ break;
+ case 'k':
+ piece |= pieceKing;
+ break;
+ }
+
+ g_board[MakeSquare(row, col)] = piece;
+ col++;
+ }
+ }
+ }
+
+ InitializePieceList();
+
+ g_toMove = chunks[1].charAt(0) == 'w' ? colorWhite : 0;
+ var them = 8 - g_toMove;
+
+ g_castleRights = 0;
+ if (chunks[2].indexOf('K') != -1) {
+ if (
+ g_board[MakeSquare(7, 4)] != (pieceKing | colorWhite) ||
+ g_board[MakeSquare(7, 7)] != (pieceRook | colorWhite)
+ ) {
+ return 'Invalid FEN: White kingside castling not allowed';
+ }
+ g_castleRights |= 1;
+ }
+ if (chunks[2].indexOf('Q') != -1) {
+ if (
+ g_board[MakeSquare(7, 4)] != (pieceKing | colorWhite) ||
+ g_board[MakeSquare(7, 0)] != (pieceRook | colorWhite)
+ ) {
+ return 'Invalid FEN: White queenside castling not allowed';
+ }
+ g_castleRights |= 2;
+ }
+ if (chunks[2].indexOf('k') != -1) {
+ if (
+ g_board[MakeSquare(0, 4)] != (pieceKing | colorBlack) ||
+ g_board[MakeSquare(0, 7)] != (pieceRook | colorBlack)
+ ) {
+ return 'Invalid FEN: Black kingside castling not allowed';
+ }
+ g_castleRights |= 4;
+ }
+ if (chunks[2].indexOf('q') != -1) {
+ if (
+ g_board[MakeSquare(0, 4)] != (pieceKing | colorBlack) ||
+ g_board[MakeSquare(0, 0)] != (pieceRook | colorBlack)
+ ) {
+ return 'Invalid FEN: Black queenside castling not allowed';
+ }
+ g_castleRights |= 8;
+ }
+
+ g_enPassentSquare = -1;
+ if (chunks[3].indexOf('-') == -1) {
+ var col = chunks[3].charAt(0).charCodeAt() - 'a'.charCodeAt();
+ var row = 8 - (chunks[3].charAt(1).charCodeAt() - '0'.charCodeAt());
+ g_enPassentSquare = MakeSquare(row, col);
+ }
+
+ var hashResult = SetHash();
+ g_hashKeyLow = hashResult.hashKeyLow;
+ g_hashKeyHigh = hashResult.hashKeyHigh;
+
+ g_baseEval = 0;
+ for (var i = 0; i < 256; i++) {
+ if (g_board[i] & colorWhite) {
+ g_baseEval += pieceSquareAdj[g_board[i] & 0x7][i];
+ g_baseEval += materialTable[g_board[i] & 0x7];
+ } else if (g_board[i] & colorBlack) {
+ g_baseEval -= pieceSquareAdj[g_board[i] & 0x7][flipTable[i]];
+ g_baseEval -= materialTable[g_board[i] & 0x7];
+ }
+ }
+ if (!g_toMove) g_baseEval = -g_baseEval;
+
+ g_move50 = 0;
+ g_inCheck = IsSquareAttackable(g_pieceList[(g_toMove | pieceKing) << 4], them);
+
+ // Check for king capture (invalid FEN)
+ if (IsSquareAttackable(g_pieceList[(them | pieceKing) << 4], g_toMove)) {
+ return 'Invalid FEN: Can capture king';
+ }
- // Checkmate/stalemate
- if (GenerateValidMoves().length == 0) {
- return g_inCheck ? 'Checkmate' : 'Stalemate';
- }
+ // Checkmate/stalemate
+ if (GenerateValidMoves().length == 0) {
+ return g_inCheck ? 'Checkmate' : 'Stalemate';
+ }
- return '';
+ return '';
}
var g_pieceIndex = new Array(256);
@@ -1626,432 +1620,433 @@ var g_pieceList = new Array(2 * 8 * 16);
var g_pieceCount = new Array(2 * 8);
function InitializePieceList() {
- for (var i = 0; i < 16; i++) {
- g_pieceCount[i] = 0;
- for (var j = 0; j < 16; j++) {
- // 0 is used as the terminator for piece lists
- g_pieceList[(i << 4) | j] = 0;
- }
- }
+ for (var i = 0; i < 16; i++) {
+ g_pieceCount[i] = 0;
+ for (var j = 0; j < 16; j++) {
+ // 0 is used as the terminator for piece lists
+ g_pieceList[(i << 4) | j] = 0;
+ }
+ }
- for (var i = 0; i < 256; i++) {
- g_pieceIndex[i] = 0;
- if (g_board[i] & (colorWhite | colorBlack)) {
- var piece = g_board[i] & 0xF;
+ for (var i = 0; i < 256; i++) {
+ g_pieceIndex[i] = 0;
+ if (g_board[i] & (colorWhite | colorBlack)) {
+ var piece = g_board[i] & 0xf;
g_pieceList[(piece << 4) | g_pieceCount[piece]] = i;
g_pieceIndex[i] = g_pieceCount[piece];
g_pieceCount[piece]++;
- }
- }
+ }
+ }
}
-function MakeMove(move){
- var me = g_toMove >> 3;
- var otherColor = 8 - g_toMove;
-
- var flags = move & 0xFF0000;
- var to = (move >> 8) & 0xFF;
- var from = move & 0xFF;
- var captured = g_board[to];
- var piece = g_board[from];
- var epcEnd = to;
-
- if (flags & moveflagEPC) {
- epcEnd = me ? (to + 0x10) : (to - 0x10);
- captured = g_board[epcEnd];
- g_board[epcEnd] = pieceEmpty;
- }
+function MakeMove(move) {
+ var me = g_toMove >> 3;
+ var otherColor = 8 - g_toMove;
+
+ var flags = move & 0xff0000;
+ var to = (move >> 8) & 0xff;
+ var from = move & 0xff;
+ var captured = g_board[to];
+ var piece = g_board[from];
+ var epcEnd = to;
+
+ if (flags & moveflagEPC) {
+ epcEnd = me ? to + 0x10 : to - 0x10;
+ captured = g_board[epcEnd];
+ g_board[epcEnd] = pieceEmpty;
+ }
- g_moveUndoStack[g_moveCount] = new UndoHistory(g_enPassentSquare, g_castleRights, g_inCheck, g_baseEval, g_hashKeyLow, g_hashKeyHigh, g_move50, captured);
- g_moveCount++;
+ g_moveUndoStack[g_moveCount] = new UndoHistory(
+ g_enPassentSquare,
+ g_castleRights,
+ g_inCheck,
+ g_baseEval,
+ g_hashKeyLow,
+ g_hashKeyHigh,
+ g_move50,
+ captured
+ );
+ g_moveCount++;
+
+ g_enPassentSquare = -1;
+
+ if (flags) {
+ if (flags & moveflagCastleKing) {
+ if (IsSquareAttackable(from + 1, otherColor) || IsSquareAttackable(from + 2, otherColor)) {
+ g_moveCount--;
+ return false;
+ }
- g_enPassentSquare = -1;
+ var rook = g_board[to + 1];
- if (flags) {
- if (flags & moveflagCastleKing) {
- if (IsSquareAttackable(from + 1, otherColor) ||
- IsSquareAttackable(from + 2, otherColor)) {
- g_moveCount--;
- return false;
- }
-
- var rook = g_board[to + 1];
-
- g_hashKeyLow ^= g_zobristLow[to + 1][rook & 0xF];
- g_hashKeyHigh ^= g_zobristHigh[to + 1][rook & 0xF];
- g_hashKeyLow ^= g_zobristLow[to - 1][rook & 0xF];
- g_hashKeyHigh ^= g_zobristHigh[to - 1][rook & 0xF];
-
- g_board[to - 1] = rook;
- g_board[to + 1] = pieceEmpty;
-
- g_baseEval -= pieceSquareAdj[rook & 0x7][me == 0 ? flipTable[to + 1] : (to + 1)];
- g_baseEval += pieceSquareAdj[rook & 0x7][me == 0 ? flipTable[to - 1] : (to - 1)];
-
- var rookIndex = g_pieceIndex[to + 1];
- g_pieceIndex[to - 1] = rookIndex;
- g_pieceList[((rook & 0xF) << 4) | rookIndex] = to - 1;
- } else if (flags & moveflagCastleQueen) {
- if (IsSquareAttackable(from - 1, otherColor) ||
- IsSquareAttackable(from - 2, otherColor)) {
- g_moveCount--;
- return false;
- }
-
- var rook = g_board[to - 2];
+ g_hashKeyLow ^= g_zobristLow[to + 1][rook & 0xf];
+ g_hashKeyHigh ^= g_zobristHigh[to + 1][rook & 0xf];
+ g_hashKeyLow ^= g_zobristLow[to - 1][rook & 0xf];
+ g_hashKeyHigh ^= g_zobristHigh[to - 1][rook & 0xf];
- g_hashKeyLow ^= g_zobristLow[to -2][rook & 0xF];
- g_hashKeyHigh ^= g_zobristHigh[to - 2][rook & 0xF];
- g_hashKeyLow ^= g_zobristLow[to + 1][rook & 0xF];
- g_hashKeyHigh ^= g_zobristHigh[to + 1][rook & 0xF];
-
- g_board[to + 1] = rook;
- g_board[to - 2] = pieceEmpty;
-
- g_baseEval -= pieceSquareAdj[rook & 0x7][me == 0 ? flipTable[to - 2] : (to - 2)];
- g_baseEval += pieceSquareAdj[rook & 0x7][me == 0 ? flipTable[to + 1] : (to + 1)];
+ g_board[to - 1] = rook;
+ g_board[to + 1] = pieceEmpty;
- var rookIndex = g_pieceIndex[to - 2];
- g_pieceIndex[to + 1] = rookIndex;
- g_pieceList[((rook & 0xF) << 4) | rookIndex] = to + 1;
- }
- }
+ g_baseEval -= pieceSquareAdj[rook & 0x7][me == 0 ? flipTable[to + 1] : to + 1];
+ g_baseEval += pieceSquareAdj[rook & 0x7][me == 0 ? flipTable[to - 1] : to - 1];
- if (captured) {
- // Remove our piece from the piece list
- var capturedType = captured & 0xF;
- g_pieceCount[capturedType]--;
- var lastPieceSquare = g_pieceList[(capturedType << 4) | g_pieceCount[capturedType]];
- g_pieceIndex[lastPieceSquare] = g_pieceIndex[epcEnd];
- g_pieceList[(capturedType << 4) | g_pieceIndex[lastPieceSquare]] = lastPieceSquare;
- g_pieceList[(capturedType << 4) | g_pieceCount[capturedType]] = 0;
-
- g_baseEval += materialTable[captured & 0x7];
- g_baseEval += pieceSquareAdj[captured & 0x7][me ? flipTable[epcEnd] : epcEnd];
-
- g_hashKeyLow ^= g_zobristLow[epcEnd][capturedType];
- g_hashKeyHigh ^= g_zobristHigh[epcEnd][capturedType];
- g_move50 = 0;
- } else if ((piece & 0x7) == piecePawn) {
- var diff = to - from;
- if (diff < 0) diff = -diff;
- if (diff > 16) {
- g_enPassentSquare = me ? (to + 0x10) : (to - 0x10);
- }
- g_move50 = 0;
- }
+ var rookIndex = g_pieceIndex[to + 1];
+ g_pieceIndex[to - 1] = rookIndex;
+ g_pieceList[((rook & 0xf) << 4) | rookIndex] = to - 1;
+ } else if (flags & moveflagCastleQueen) {
+ if (IsSquareAttackable(from - 1, otherColor) || IsSquareAttackable(from - 2, otherColor)) {
+ g_moveCount--;
+ return false;
+ }
- g_hashKeyLow ^= g_zobristLow[from][piece & 0xF];
- g_hashKeyHigh ^= g_zobristHigh[from][piece & 0xF];
- g_hashKeyLow ^= g_zobristLow[to][piece & 0xF];
- g_hashKeyHigh ^= g_zobristHigh[to][piece & 0xF];
- g_hashKeyLow ^= g_zobristBlackLow;
- g_hashKeyHigh ^= g_zobristBlackHigh;
-
- g_castleRights &= g_castleRightsMask[from] & g_castleRightsMask[to];
-
- g_baseEval -= pieceSquareAdj[piece & 0x7][me == 0 ? flipTable[from] : from];
-
- // Move our piece in the piece list
- g_pieceIndex[to] = g_pieceIndex[from];
- g_pieceList[((piece & 0xF) << 4) | g_pieceIndex[to]] = to;
-
- if (flags & moveflagPromotion) {
- var newPiece = piece & (~0x7);
- if (flags & moveflagPromoteKnight)
- newPiece |= pieceKnight;
- else if (flags & moveflagPromoteQueen)
- newPiece |= pieceQueen;
- else if (flags & moveflagPromoteBishop)
- newPiece |= pieceBishop;
- else
- newPiece |= pieceRook;
-
- g_hashKeyLow ^= g_zobristLow[to][piece & 0xF];
- g_hashKeyHigh ^= g_zobristHigh[to][piece & 0xF];
- g_board[to] = newPiece;
- g_hashKeyLow ^= g_zobristLow[to][newPiece & 0xF];
- g_hashKeyHigh ^= g_zobristHigh[to][newPiece & 0xF];
-
- g_baseEval += pieceSquareAdj[newPiece & 0x7][me == 0 ? flipTable[to] : to];
- g_baseEval -= materialTable[piecePawn];
- g_baseEval += materialTable[newPiece & 0x7];
-
- var pawnType = piece & 0xF;
- var promoteType = newPiece & 0xF;
-
- g_pieceCount[pawnType]--;
-
- var lastPawnSquare = g_pieceList[(pawnType << 4) | g_pieceCount[pawnType]];
- g_pieceIndex[lastPawnSquare] = g_pieceIndex[to];
- g_pieceList[(pawnType << 4) | g_pieceIndex[lastPawnSquare]] = lastPawnSquare;
- g_pieceList[(pawnType << 4) | g_pieceCount[pawnType]] = 0;
- g_pieceIndex[to] = g_pieceCount[promoteType];
- g_pieceList[(promoteType << 4) | g_pieceIndex[to]] = to;
- g_pieceCount[promoteType]++;
- } else {
- g_board[to] = g_board[from];
-
- g_baseEval += pieceSquareAdj[piece & 0x7][me == 0 ? flipTable[to] : to];
- }
- g_board[from] = pieceEmpty;
-
- g_toMove = otherColor;
- g_baseEval = -g_baseEval;
-
- if ((piece & 0x7) == pieceKing || g_inCheck) {
- if (IsSquareAttackable(g_pieceList[(pieceKing | (8 - g_toMove)) << 4], otherColor)) {
- UnmakeMove(move);
- return false;
- }
- } else {
- var kingPos = g_pieceList[(pieceKing | (8 - g_toMove)) << 4];
-
- if (ExposesCheck(from, kingPos)) {
- UnmakeMove(move);
- return false;
- }
-
- if (epcEnd != to) {
- if (ExposesCheck(epcEnd, kingPos)) {
- UnmakeMove(move);
- return false;
- }
- }
- }
-
- g_inCheck = false;
-
- if (flags <= moveflagEPC) {
- var theirKingPos = g_pieceList[(pieceKing | g_toMove) << 4];
-
- // First check if the piece we moved can attack the enemy king
- g_inCheck = IsSquareAttackableFrom(theirKingPos, to);
-
- if (!g_inCheck) {
- // Now check if the square we moved from exposes check on the enemy king
- g_inCheck = ExposesCheck(from, theirKingPos);
-
- if (!g_inCheck) {
- // Finally, ep. capture can cause another square to be exposed
- if (epcEnd != to) {
- g_inCheck = ExposesCheck(epcEnd, theirKingPos);
- }
- }
- }
- }
- else {
- // Castle or promotion, slow check
- g_inCheck = IsSquareAttackable(g_pieceList[(pieceKing | g_toMove) << 4], 8 - g_toMove);
- }
+ var rook = g_board[to - 2];
- g_repMoveStack[g_moveCount - 1] = g_hashKeyLow;
- g_move50++;
+ g_hashKeyLow ^= g_zobristLow[to - 2][rook & 0xf];
+ g_hashKeyHigh ^= g_zobristHigh[to - 2][rook & 0xf];
+ g_hashKeyLow ^= g_zobristLow[to + 1][rook & 0xf];
+ g_hashKeyHigh ^= g_zobristHigh[to + 1][rook & 0xf];
- return true;
+ g_board[to + 1] = rook;
+ g_board[to - 2] = pieceEmpty;
+
+ g_baseEval -= pieceSquareAdj[rook & 0x7][me == 0 ? flipTable[to - 2] : to - 2];
+ g_baseEval += pieceSquareAdj[rook & 0x7][me == 0 ? flipTable[to + 1] : to + 1];
+
+ var rookIndex = g_pieceIndex[to - 2];
+ g_pieceIndex[to + 1] = rookIndex;
+ g_pieceList[((rook & 0xf) << 4) | rookIndex] = to + 1;
+ }
+ }
+
+ if (captured) {
+ // Remove our piece from the piece list
+ var capturedType = captured & 0xf;
+ g_pieceCount[capturedType]--;
+ var lastPieceSquare = g_pieceList[(capturedType << 4) | g_pieceCount[capturedType]];
+ g_pieceIndex[lastPieceSquare] = g_pieceIndex[epcEnd];
+ g_pieceList[(capturedType << 4) | g_pieceIndex[lastPieceSquare]] = lastPieceSquare;
+ g_pieceList[(capturedType << 4) | g_pieceCount[capturedType]] = 0;
+
+ g_baseEval += materialTable[captured & 0x7];
+ g_baseEval += pieceSquareAdj[captured & 0x7][me ? flipTable[epcEnd] : epcEnd];
+
+ g_hashKeyLow ^= g_zobristLow[epcEnd][capturedType];
+ g_hashKeyHigh ^= g_zobristHigh[epcEnd][capturedType];
+ g_move50 = 0;
+ } else if ((piece & 0x7) == piecePawn) {
+ var diff = to - from;
+ if (diff < 0) diff = -diff;
+ if (diff > 16) {
+ g_enPassentSquare = me ? to + 0x10 : to - 0x10;
+ }
+ g_move50 = 0;
+ }
+
+ g_hashKeyLow ^= g_zobristLow[from][piece & 0xf];
+ g_hashKeyHigh ^= g_zobristHigh[from][piece & 0xf];
+ g_hashKeyLow ^= g_zobristLow[to][piece & 0xf];
+ g_hashKeyHigh ^= g_zobristHigh[to][piece & 0xf];
+ g_hashKeyLow ^= g_zobristBlackLow;
+ g_hashKeyHigh ^= g_zobristBlackHigh;
+
+ g_castleRights &= g_castleRightsMask[from] & g_castleRightsMask[to];
+
+ g_baseEval -= pieceSquareAdj[piece & 0x7][me == 0 ? flipTable[from] : from];
+
+ // Move our piece in the piece list
+ g_pieceIndex[to] = g_pieceIndex[from];
+ g_pieceList[((piece & 0xf) << 4) | g_pieceIndex[to]] = to;
+
+ if (flags & moveflagPromotion) {
+ var newPiece = piece & ~0x7;
+ if (flags & moveflagPromoteKnight) newPiece |= pieceKnight;
+ else if (flags & moveflagPromoteQueen) newPiece |= pieceQueen;
+ else if (flags & moveflagPromoteBishop) newPiece |= pieceBishop;
+ else newPiece |= pieceRook;
+
+ g_hashKeyLow ^= g_zobristLow[to][piece & 0xf];
+ g_hashKeyHigh ^= g_zobristHigh[to][piece & 0xf];
+ g_board[to] = newPiece;
+ g_hashKeyLow ^= g_zobristLow[to][newPiece & 0xf];
+ g_hashKeyHigh ^= g_zobristHigh[to][newPiece & 0xf];
+
+ g_baseEval += pieceSquareAdj[newPiece & 0x7][me == 0 ? flipTable[to] : to];
+ g_baseEval -= materialTable[piecePawn];
+ g_baseEval += materialTable[newPiece & 0x7];
+
+ var pawnType = piece & 0xf;
+ var promoteType = newPiece & 0xf;
+
+ g_pieceCount[pawnType]--;
+
+ var lastPawnSquare = g_pieceList[(pawnType << 4) | g_pieceCount[pawnType]];
+ g_pieceIndex[lastPawnSquare] = g_pieceIndex[to];
+ g_pieceList[(pawnType << 4) | g_pieceIndex[lastPawnSquare]] = lastPawnSquare;
+ g_pieceList[(pawnType << 4) | g_pieceCount[pawnType]] = 0;
+ g_pieceIndex[to] = g_pieceCount[promoteType];
+ g_pieceList[(promoteType << 4) | g_pieceIndex[to]] = to;
+ g_pieceCount[promoteType]++;
+ } else {
+ g_board[to] = g_board[from];
+
+ g_baseEval += pieceSquareAdj[piece & 0x7][me == 0 ? flipTable[to] : to];
+ }
+ g_board[from] = pieceEmpty;
+
+ g_toMove = otherColor;
+ g_baseEval = -g_baseEval;
+
+ if ((piece & 0x7) == pieceKing || g_inCheck) {
+ if (IsSquareAttackable(g_pieceList[(pieceKing | (8 - g_toMove)) << 4], otherColor)) {
+ UnmakeMove(move);
+ return false;
+ }
+ } else {
+ var kingPos = g_pieceList[(pieceKing | (8 - g_toMove)) << 4];
+
+ if (ExposesCheck(from, kingPos)) {
+ UnmakeMove(move);
+ return false;
+ }
+
+ if (epcEnd != to) {
+ if (ExposesCheck(epcEnd, kingPos)) {
+ UnmakeMove(move);
+ return false;
+ }
+ }
+ }
+
+ g_inCheck = false;
+
+ if (flags <= moveflagEPC) {
+ var theirKingPos = g_pieceList[(pieceKing | g_toMove) << 4];
+
+ // First check if the piece we moved can attack the enemy king
+ g_inCheck = IsSquareAttackableFrom(theirKingPos, to);
+
+ if (!g_inCheck) {
+ // Now check if the square we moved from exposes check on the enemy king
+ g_inCheck = ExposesCheck(from, theirKingPos);
+
+ if (!g_inCheck) {
+ // Finally, ep. capture can cause another square to be exposed
+ if (epcEnd != to) {
+ g_inCheck = ExposesCheck(epcEnd, theirKingPos);
+ }
+ }
+ }
+ } else {
+ // Castle or promotion, slow check
+ g_inCheck = IsSquareAttackable(g_pieceList[(pieceKing | g_toMove) << 4], 8 - g_toMove);
+ }
+
+ g_repMoveStack[g_moveCount - 1] = g_hashKeyLow;
+ g_move50++;
+
+ return true;
}
-function UnmakeMove(move){
- g_toMove = 8 - g_toMove;
- g_baseEval = -g_baseEval;
-
- g_moveCount--;
- g_enPassentSquare = g_moveUndoStack[g_moveCount].ep;
- g_castleRights = g_moveUndoStack[g_moveCount].castleRights;
- g_inCheck = g_moveUndoStack[g_moveCount].inCheck;
- g_baseEval = g_moveUndoStack[g_moveCount].baseEval;
- g_hashKeyLow = g_moveUndoStack[g_moveCount].hashKeyLow;
- g_hashKeyHigh = g_moveUndoStack[g_moveCount].hashKeyHigh;
- g_move50 = g_moveUndoStack[g_moveCount].move50;
-
- var otherColor = 8 - g_toMove;
- var me = g_toMove >> 3;
- var them = otherColor >> 3;
-
- var flags = move & 0xFF0000;
- var captured = g_moveUndoStack[g_moveCount].captured;
- var to = (move >> 8) & 0xFF;
- var from = move & 0xFF;
-
- var piece = g_board[to];
-
- if (flags) {
- if (flags & moveflagCastleKing) {
- var rook = g_board[to - 1];
- g_board[to + 1] = rook;
- g_board[to - 1] = pieceEmpty;
-
- var rookIndex = g_pieceIndex[to - 1];
- g_pieceIndex[to + 1] = rookIndex;
- g_pieceList[((rook & 0xF) << 4) | rookIndex] = to + 1;
- }
- else if (flags & moveflagCastleQueen) {
- var rook = g_board[to + 1];
- g_board[to - 2] = rook;
- g_board[to + 1] = pieceEmpty;
-
- var rookIndex = g_pieceIndex[to + 1];
- g_pieceIndex[to - 2] = rookIndex;
- g_pieceList[((rook & 0xF) << 4) | rookIndex] = to - 2;
- }
- }
-
- if (flags & moveflagPromotion) {
- piece = (g_board[to] & (~0x7)) | piecePawn;
- g_board[from] = piece;
-
- var pawnType = g_board[from] & 0xF;
- var promoteType = g_board[to] & 0xF;
-
- g_pieceCount[promoteType]--;
-
- var lastPromoteSquare = g_pieceList[(promoteType << 4) | g_pieceCount[promoteType]];
- g_pieceIndex[lastPromoteSquare] = g_pieceIndex[to];
- g_pieceList[(promoteType << 4) | g_pieceIndex[lastPromoteSquare]] = lastPromoteSquare;
- g_pieceList[(promoteType << 4) | g_pieceCount[promoteType]] = 0;
- g_pieceIndex[to] = g_pieceCount[pawnType];
- g_pieceList[(pawnType << 4) | g_pieceIndex[to]] = to;
- g_pieceCount[pawnType]++;
- }
- else {
- g_board[from] = g_board[to];
- }
+function UnmakeMove(move) {
+ g_toMove = 8 - g_toMove;
+ g_baseEval = -g_baseEval;
+
+ g_moveCount--;
+ g_enPassentSquare = g_moveUndoStack[g_moveCount].ep;
+ g_castleRights = g_moveUndoStack[g_moveCount].castleRights;
+ g_inCheck = g_moveUndoStack[g_moveCount].inCheck;
+ g_baseEval = g_moveUndoStack[g_moveCount].baseEval;
+ g_hashKeyLow = g_moveUndoStack[g_moveCount].hashKeyLow;
+ g_hashKeyHigh = g_moveUndoStack[g_moveCount].hashKeyHigh;
+ g_move50 = g_moveUndoStack[g_moveCount].move50;
+
+ var otherColor = 8 - g_toMove;
+ var me = g_toMove >> 3;
+ var them = otherColor >> 3;
+
+ var flags = move & 0xff0000;
+ var captured = g_moveUndoStack[g_moveCount].captured;
+ var to = (move >> 8) & 0xff;
+ var from = move & 0xff;
+
+ var piece = g_board[to];
+
+ if (flags) {
+ if (flags & moveflagCastleKing) {
+ var rook = g_board[to - 1];
+ g_board[to + 1] = rook;
+ g_board[to - 1] = pieceEmpty;
+
+ var rookIndex = g_pieceIndex[to - 1];
+ g_pieceIndex[to + 1] = rookIndex;
+ g_pieceList[((rook & 0xf) << 4) | rookIndex] = to + 1;
+ } else if (flags & moveflagCastleQueen) {
+ var rook = g_board[to + 1];
+ g_board[to - 2] = rook;
+ g_board[to + 1] = pieceEmpty;
+
+ var rookIndex = g_pieceIndex[to + 1];
+ g_pieceIndex[to - 2] = rookIndex;
+ g_pieceList[((rook & 0xf) << 4) | rookIndex] = to - 2;
+ }
+ }
- var epcEnd = to;
- if (flags & moveflagEPC) {
- if (g_toMove == colorWhite)
- epcEnd = to + 0x10;
- else
- epcEnd = to - 0x10;
- g_board[to] = pieceEmpty;
- }
-
- g_board[epcEnd] = captured;
+ if (flags & moveflagPromotion) {
+ piece = (g_board[to] & ~0x7) | piecePawn;
+ g_board[from] = piece;
+
+ var pawnType = g_board[from] & 0xf;
+ var promoteType = g_board[to] & 0xf;
+
+ g_pieceCount[promoteType]--;
+
+ var lastPromoteSquare = g_pieceList[(promoteType << 4) | g_pieceCount[promoteType]];
+ g_pieceIndex[lastPromoteSquare] = g_pieceIndex[to];
+ g_pieceList[(promoteType << 4) | g_pieceIndex[lastPromoteSquare]] = lastPromoteSquare;
+ g_pieceList[(promoteType << 4) | g_pieceCount[promoteType]] = 0;
+ g_pieceIndex[to] = g_pieceCount[pawnType];
+ g_pieceList[(pawnType << 4) | g_pieceIndex[to]] = to;
+ g_pieceCount[pawnType]++;
+ } else {
+ g_board[from] = g_board[to];
+ }
+
+ var epcEnd = to;
+ if (flags & moveflagEPC) {
+ if (g_toMove == colorWhite) epcEnd = to + 0x10;
+ else epcEnd = to - 0x10;
+ g_board[to] = pieceEmpty;
+ }
+
+ g_board[epcEnd] = captured;
// Move our piece in the piece list
- g_pieceIndex[from] = g_pieceIndex[to];
- g_pieceList[((piece & 0xF) << 4) | g_pieceIndex[from]] = from;
+ g_pieceIndex[from] = g_pieceIndex[to];
+ g_pieceList[((piece & 0xf) << 4) | g_pieceIndex[from]] = from;
- if (captured) {
+ if (captured) {
// Restore our piece to the piece list
- var captureType = captured & 0xF;
- g_pieceIndex[epcEnd] = g_pieceCount[captureType];
- g_pieceList[(captureType << 4) | g_pieceCount[captureType]] = epcEnd;
- g_pieceCount[captureType]++;
- }
+ var captureType = captured & 0xf;
+ g_pieceIndex[epcEnd] = g_pieceCount[captureType];
+ g_pieceList[(captureType << 4) | g_pieceCount[captureType]] = epcEnd;
+ g_pieceCount[captureType]++;
+ }
}
-function ExposesCheck(from, kingPos){
- var index = kingPos - from + 128;
- // If a queen can't reach it, nobody can!
- if ((g_vectorDelta[index].pieceMask[0] & (1 << (pieceQueen))) != 0) {
- var delta = g_vectorDelta[index].delta;
- var pos = kingPos + delta;
- while (g_board[pos] == 0) pos += delta;
-
- var piece = g_board[pos];
- if (((piece & (g_board[kingPos] ^ 0x18)) & 0x18) == 0)
- return false;
-
- // Now see if the piece can actually attack the king
- var backwardIndex = pos - kingPos + 128;
- return (g_vectorDelta[backwardIndex].pieceMask[(piece >> 3) & 1] & (1 << (piece & 0x7))) != 0;
- }
- return false;
+function ExposesCheck(from, kingPos) {
+ var index = kingPos - from + 128;
+ // If a queen can't reach it, nobody can!
+ if ((g_vectorDelta[index].pieceMask[0] & (1 << pieceQueen)) != 0) {
+ var delta = g_vectorDelta[index].delta;
+ var pos = kingPos + delta;
+ while (g_board[pos] == 0) pos += delta;
+
+ var piece = g_board[pos];
+ if ((piece & (g_board[kingPos] ^ 0x18) & 0x18) == 0) return false;
+
+ // Now see if the piece can actually attack the king
+ var backwardIndex = pos - kingPos + 128;
+ return (g_vectorDelta[backwardIndex].pieceMask[(piece >> 3) & 1] & (1 << (piece & 0x7))) != 0;
+ }
+ return false;
}
function IsSquareOnPieceLine(target, from) {
- var index = from - target + 128;
- var piece = g_board[from];
- return (g_vectorDelta[index].pieceMask[(piece >> 3) & 1] & (1 << (piece & 0x7))) ? true : false;
+ var index = from - target + 128;
+ var piece = g_board[from];
+ return g_vectorDelta[index].pieceMask[(piece >> 3) & 1] & (1 << (piece & 0x7)) ? true : false;
}
-function IsSquareAttackableFrom(target, from){
- var index = from - target + 128;
- var piece = g_board[from];
- if (g_vectorDelta[index].pieceMask[(piece >> 3) & 1] & (1 << (piece & 0x7))) {
- // Yes, this square is pseudo-attackable. Now, check for real attack
+function IsSquareAttackableFrom(target, from) {
+ var index = from - target + 128;
+ var piece = g_board[from];
+ if (g_vectorDelta[index].pieceMask[(piece >> 3) & 1] & (1 << (piece & 0x7))) {
+ // Yes, this square is pseudo-attackable. Now, check for real attack
var inc = g_vectorDelta[index].delta;
- do {
+ do {
from += inc;
- if (from == target)
- return true;
+ if (from == target) return true;
} while (g_board[from] == 0);
- }
-
- return false;
+ }
+
+ return false;
}
function IsSquareAttackable(target, color) {
// Attackable by pawns?
var inc = color ? -16 : 16;
var pawn = (color ? colorWhite : colorBlack) | 1;
- if (g_board[target - (inc - 1)] == pawn)
- return true;
- if (g_board[target - (inc + 1)] == pawn)
- return true;
-
+ if (g_board[target - (inc - 1)] == pawn) return true;
+ if (g_board[target - (inc + 1)] == pawn) return true;
+
// Attackable by pieces?
for (var i = 2; i <= 6; i++) {
- var index = (color | i) << 4;
- var square = g_pieceList[index];
+ var index = (color | i) << 4;
+ var square = g_pieceList[index];
while (square != 0) {
- if (IsSquareAttackableFrom(target, square))
- return true;
+ if (IsSquareAttackableFrom(target, square)) return true;
square = g_pieceList[++index];
}
- }
- return false;
+ }
+ return false;
}
function GenerateMove(from, to) {
- return from | (to << 8);
+ return from | (to << 8);
}
-function GenerateMove(from, to, flags){
- return from | (to << 8) | flags;
+function GenerateMove(from, to, flags) {
+ return from | (to << 8) | flags;
}
function GenerateValidMoves() {
- var moveList = new Array();
- var allMoves = new Array();
- GenerateCaptureMoves(allMoves, null);
- GenerateAllMoves(allMoves);
-
- for (var i = allMoves.length - 1; i >= 0; i--) {
- if (MakeMove(allMoves[i])) {
- moveList[moveList.length] = allMoves[i];
- UnmakeMove(allMoves[i]);
- }
- }
-
- return moveList;
+ var moveList = new Array();
+ var allMoves = new Array();
+ GenerateCaptureMoves(allMoves, null);
+ GenerateAllMoves(allMoves);
+
+ for (var i = allMoves.length - 1; i >= 0; i--) {
+ if (MakeMove(allMoves[i])) {
+ moveList[moveList.length] = allMoves[i];
+ UnmakeMove(allMoves[i]);
+ }
+ }
+
+ return moveList;
}
function GenerateAllMoves(moveStack) {
- var from, to, piece, pieceIdx;
+ var from, to, piece, pieceIdx;
// Pawn quiet moves
- pieceIdx = (g_toMove | 1) << 4;
- from = g_pieceList[pieceIdx++];
- while (from != 0) {
- GeneratePawnMoves(moveStack, from);
- from = g_pieceList[pieceIdx++];
- }
+ pieceIdx = (g_toMove | 1) << 4;
+ from = g_pieceList[pieceIdx++];
+ while (from != 0) {
+ GeneratePawnMoves(moveStack, from);
+ from = g_pieceList[pieceIdx++];
+ }
- // Knight quiet moves
+ // Knight quiet moves
pieceIdx = (g_toMove | 2) << 4;
from = g_pieceList[pieceIdx++];
while (from != 0) {
- to = from + 31; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 33; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 14; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 14; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 31; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 33; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 18; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 18; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 31;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 33;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 14;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 14;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 31;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 33;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 18;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 18;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
from = g_pieceList[pieceIdx++];
}
@@ -2059,10 +2054,26 @@ function GenerateAllMoves(moveStack) {
pieceIdx = (g_toMove | 3) << 4;
from = g_pieceList[pieceIdx++];
while (from != 0) {
- to = from - 15; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to -= 15; }
- to = from - 17; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to -= 17; }
- to = from + 15; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to += 15; }
- to = from + 17; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to += 17; }
+ to = from - 15;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to -= 15;
+ }
+ to = from - 17;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to -= 17;
+ }
+ to = from + 15;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to += 15;
+ }
+ to = from + 17;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to += 17;
+ }
from = g_pieceList[pieceIdx++];
}
@@ -2070,446 +2081,586 @@ function GenerateAllMoves(moveStack) {
pieceIdx = (g_toMove | 4) << 4;
from = g_pieceList[pieceIdx++];
while (from != 0) {
- to = from - 1; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to--; }
- to = from + 1; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to++; }
- to = from + 16; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to += 16; }
- to = from - 16; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to -= 16; }
+ to = from - 1;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to--;
+ }
+ to = from + 1;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to++;
+ }
+ to = from + 16;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to += 16;
+ }
+ to = from - 16;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to -= 16;
+ }
from = g_pieceList[pieceIdx++];
}
-
+
// Queen quiet moves
pieceIdx = (g_toMove | 5) << 4;
from = g_pieceList[pieceIdx++];
while (from != 0) {
- to = from - 15; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to -= 15; }
- to = from - 17; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to -= 17; }
- to = from + 15; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to += 15; }
- to = from + 17; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to += 17; }
- to = from - 1; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to--; }
- to = from + 1; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to++; }
- to = from + 16; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to += 16; }
- to = from - 16; while (g_board[to] == 0) { moveStack[moveStack.length] = GenerateMove(from, to); to -= 16; }
+ to = from - 15;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to -= 15;
+ }
+ to = from - 17;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to -= 17;
+ }
+ to = from + 15;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to += 15;
+ }
+ to = from + 17;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to += 17;
+ }
+ to = from - 1;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to--;
+ }
+ to = from + 1;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to++;
+ }
+ to = from + 16;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to += 16;
+ }
+ to = from - 16;
+ while (g_board[to] == 0) {
+ moveStack[moveStack.length] = GenerateMove(from, to);
+ to -= 16;
+ }
from = g_pieceList[pieceIdx++];
}
-
+
// King quiet moves
{
pieceIdx = (g_toMove | 6) << 4;
from = g_pieceList[pieceIdx];
- to = from - 15; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 17; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 15; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 17; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 1; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 1; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 16; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 16; if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
-
- if (!g_inCheck) {
- var castleRights = g_castleRights;
- if (!g_toMove)
- castleRights >>= 2;
- if (castleRights & 1) {
- // Kingside castle
- if (g_board[from + 1] == pieceEmpty && g_board[from + 2] == pieceEmpty) {
- moveStack[moveStack.length] = GenerateMove(from, from + 0x02, moveflagCastleKing);
- }
- }
- if (castleRights & 2) {
- // Queenside castle
- if (g_board[from - 1] == pieceEmpty && g_board[from - 2] == pieceEmpty && g_board[from - 3] == pieceEmpty) {
- moveStack[moveStack.length] = GenerateMove(from, from - 0x02, moveflagCastleQueen);
- }
- }
- }
+ to = from - 15;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 17;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 15;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 17;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 1;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 1;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 16;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 16;
+ if (g_board[to] == 0) moveStack[moveStack.length] = GenerateMove(from, to);
+
+ if (!g_inCheck) {
+ var castleRights = g_castleRights;
+ if (!g_toMove) castleRights >>= 2;
+ if (castleRights & 1) {
+ // Kingside castle
+ if (g_board[from + 1] == pieceEmpty && g_board[from + 2] == pieceEmpty) {
+ moveStack[moveStack.length] = GenerateMove(from, from + 0x02, moveflagCastleKing);
+ }
+ }
+ if (castleRights & 2) {
+ // Queenside castle
+ if (g_board[from - 1] == pieceEmpty && g_board[from - 2] == pieceEmpty && g_board[from - 3] == pieceEmpty) {
+ moveStack[moveStack.length] = GenerateMove(from, from - 0x02, moveflagCastleQueen);
+ }
+ }
+ }
}
}
function GenerateCaptureMoves(moveStack, moveScores) {
- var from, to, piece, pieceIdx;
- var inc = (g_toMove == 8) ? -16 : 16;
- var enemy = g_toMove == 8 ? 0x10 : 0x8;
-
- // Pawn captures
- pieceIdx = (g_toMove | 1) << 4;
- from = g_pieceList[pieceIdx++];
- while (from != 0) {
- to = from + inc - 1;
- if (g_board[to] & enemy) {
- MovePawnTo(moveStack, from, to);
- }
+ var from, to, piece, pieceIdx;
+ var inc = g_toMove == 8 ? -16 : 16;
+ var enemy = g_toMove == 8 ? 0x10 : 0x8;
- to = from + inc + 1;
- if (g_board[to] & enemy) {
- MovePawnTo(moveStack, from, to);
- }
+ // Pawn captures
+ pieceIdx = (g_toMove | 1) << 4;
+ from = g_pieceList[pieceIdx++];
+ while (from != 0) {
+ to = from + inc - 1;
+ if (g_board[to] & enemy) {
+ MovePawnTo(moveStack, from, to);
+ }
- from = g_pieceList[pieceIdx++];
- }
+ to = from + inc + 1;
+ if (g_board[to] & enemy) {
+ MovePawnTo(moveStack, from, to);
+ }
+
+ from = g_pieceList[pieceIdx++];
+ }
- if (g_enPassentSquare != -1) {
- var inc = (g_toMove == colorWhite) ? -16 : 16;
- var pawn = g_toMove | piecePawn;
+ if (g_enPassentSquare != -1) {
+ var inc = g_toMove == colorWhite ? -16 : 16;
+ var pawn = g_toMove | piecePawn;
- var from = g_enPassentSquare - (inc + 1);
- if ((g_board[from] & 0xF) == pawn) {
- moveStack[moveStack.length] = GenerateMove(from, g_enPassentSquare, moveflagEPC);
- }
+ var from = g_enPassentSquare - (inc + 1);
+ if ((g_board[from] & 0xf) == pawn) {
+ moveStack[moveStack.length] = GenerateMove(from, g_enPassentSquare, moveflagEPC);
+ }
- from = g_enPassentSquare - (inc - 1);
- if ((g_board[from] & 0xF) == pawn) {
- moveStack[moveStack.length] = GenerateMove(from, g_enPassentSquare, moveflagEPC);
- }
- }
+ from = g_enPassentSquare - (inc - 1);
+ if ((g_board[from] & 0xf) == pawn) {
+ moveStack[moveStack.length] = GenerateMove(from, g_enPassentSquare, moveflagEPC);
+ }
+ }
- // Knight captures
+ // Knight captures
pieceIdx = (g_toMove | 2) << 4;
from = g_pieceList[pieceIdx++];
while (from != 0) {
- to = from + 31; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 33; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 14; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 14; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 31; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 33; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 18; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 18; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 31;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 33;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 14;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 14;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 31;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 33;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 18;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 18;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
from = g_pieceList[pieceIdx++];
}
-
+
// Bishop captures
pieceIdx = (g_toMove | 3) << 4;
from = g_pieceList[pieceIdx++];
while (from != 0) {
- to = from; do { to -= 15; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to -= 17; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to += 15; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to += 17; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to -= 15;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to -= 17;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to += 15;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to += 17;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
from = g_pieceList[pieceIdx++];
}
-
+
// Rook captures
pieceIdx = (g_toMove | 4) << 4;
from = g_pieceList[pieceIdx++];
while (from != 0) {
- to = from; do { to--; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to++; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to -= 16; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to += 16; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to--;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to++;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to -= 16;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to += 16;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
from = g_pieceList[pieceIdx++];
}
-
+
// Queen captures
pieceIdx = (g_toMove | 5) << 4;
from = g_pieceList[pieceIdx++];
while (from != 0) {
- to = from; do { to -= 15; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to -= 17; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to += 15; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to += 17; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to--; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to++; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to -= 16; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from; do { to += 16; } while (g_board[to] == 0); if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to -= 15;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to -= 17;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to += 15;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to += 17;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to--;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to++;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to -= 16;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from;
+ do {
+ to += 16;
+ } while (g_board[to] == 0);
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
from = g_pieceList[pieceIdx++];
}
-
+
// King captures
{
pieceIdx = (g_toMove | 6) << 4;
from = g_pieceList[pieceIdx];
- to = from - 15; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 17; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 15; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 17; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 1; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 1; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from - 16; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
- to = from + 16; if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 15;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 17;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 15;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 17;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 1;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 1;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from - 16;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
+ to = from + 16;
+ if (g_board[to] & enemy) moveStack[moveStack.length] = GenerateMove(from, to);
}
}
function MovePawnTo(moveStack, start, square) {
- var row = square & 0xF0;
- if ((row == 0x90) || (row == 0x20)) {
- moveStack[moveStack.length] = GenerateMove(start, square, moveflagPromotion | moveflagPromoteQueen);
- moveStack[moveStack.length] = GenerateMove(start, square, moveflagPromotion | moveflagPromoteKnight);
- moveStack[moveStack.length] = GenerateMove(start, square, moveflagPromotion | moveflagPromoteBishop);
- moveStack[moveStack.length] = GenerateMove(start, square, moveflagPromotion);
- }
- else {
- moveStack[moveStack.length] = GenerateMove(start, square, 0);
- }
+ var row = square & 0xf0;
+ if (row == 0x90 || row == 0x20) {
+ moveStack[moveStack.length] = GenerateMove(start, square, moveflagPromotion | moveflagPromoteQueen);
+ moveStack[moveStack.length] = GenerateMove(start, square, moveflagPromotion | moveflagPromoteKnight);
+ moveStack[moveStack.length] = GenerateMove(start, square, moveflagPromotion | moveflagPromoteBishop);
+ moveStack[moveStack.length] = GenerateMove(start, square, moveflagPromotion);
+ } else {
+ moveStack[moveStack.length] = GenerateMove(start, square, 0);
+ }
}
function GeneratePawnMoves(moveStack, from) {
- var piece = g_board[from];
- var color = piece & colorWhite;
- var inc = (color == colorWhite) ? -16 : 16;
-
+ var piece = g_board[from];
+ var color = piece & colorWhite;
+ var inc = color == colorWhite ? -16 : 16;
+
// Quiet pawn moves
var to = from + inc;
if (g_board[to] == 0) {
MovePawnTo(moveStack, from, to, pieceEmpty);
-
+
// Check if we can do a 2 square jump
- if ((((from & 0xF0) == 0x30) && color != colorWhite) ||
- (((from & 0xF0) == 0x80) && color == colorWhite)) {
+ if (((from & 0xf0) == 0x30 && color != colorWhite) || ((from & 0xf0) == 0x80 && color == colorWhite)) {
to += inc;
if (g_board[to] == 0) {
moveStack[moveStack.length] = GenerateMove(from, to);
- }
+ }
}
}
}
function UndoHistory(ep, castleRights, inCheck, baseEval, hashKeyLow, hashKeyHigh, move50, captured) {
- this.ep = ep;
- this.castleRights = castleRights;
- this.inCheck = inCheck;
- this.baseEval = baseEval;
- this.hashKeyLow = hashKeyLow;
- this.hashKeyHigh = hashKeyHigh;
- this.move50 = move50;
- this.captured = captured;
+ this.ep = ep;
+ this.castleRights = castleRights;
+ this.inCheck = inCheck;
+ this.baseEval = baseEval;
+ this.hashKeyLow = hashKeyLow;
+ this.hashKeyHigh = hashKeyHigh;
+ this.move50 = move50;
+ this.captured = captured;
}
-var g_seeValues = [0, 1, 3, 3, 5, 9, 900, 0,
- 0, 1, 3, 3, 5, 9, 900, 0];
+var g_seeValues = [0, 1, 3, 3, 5, 9, 900, 0, 0, 1, 3, 3, 5, 9, 900, 0];
function See(move) {
- var from = move & 0xFF;
- var to = (move >> 8) & 0xFF;
+ var from = move & 0xff;
+ var to = (move >> 8) & 0xff;
- var fromPiece = g_board[from];
+ var fromPiece = g_board[from];
- var fromValue = g_seeValues[fromPiece & 0xF];
- var toValue = g_seeValues[g_board[to] & 0xF];
+ var fromValue = g_seeValues[fromPiece & 0xf];
+ var toValue = g_seeValues[g_board[to] & 0xf];
- if (fromValue <= toValue) {
- return true;
- }
+ if (fromValue <= toValue) {
+ return true;
+ }
- if (move >> 16) {
- // Castles, promotion, ep are always good
- return true;
- }
+ if (move >> 16) {
+ // Castles, promotion, ep are always good
+ return true;
+ }
- var us = (fromPiece & colorWhite) ? colorWhite : 0;
- var them = 8 - us;
+ var us = fromPiece & colorWhite ? colorWhite : 0;
+ var them = 8 - us;
- // Pawn attacks
- // If any opponent pawns can capture back, this capture is probably not worthwhile (as we must be using knight or above).
- var inc = (fromPiece & colorWhite) ? -16 : 16; // Note: this is capture direction from to, so reversed from normal move direction
- if (((g_board[to + inc + 1] & 0xF) == (piecePawn | them)) ||
- ((g_board[to + inc - 1] & 0xF) == (piecePawn | them))) {
- return false;
- }
+ // Pawn attacks
+ // If any opponent pawns can capture back, this capture is probably not worthwhile (as we must be using knight or above).
+ var inc = fromPiece & colorWhite ? -16 : 16; // Note: this is capture direction from to, so reversed from normal move direction
+ if ((g_board[to + inc + 1] & 0xf) == (piecePawn | them) || (g_board[to + inc - 1] & 0xf) == (piecePawn | them)) {
+ return false;
+ }
- var themAttacks = new Array();
+ var themAttacks = new Array();
- // Knight attacks
- // If any opponent knights can capture back, and the deficit we have to make up is greater than the knights value,
- // it's not worth it. We can capture on this square again, and the opponent doesn't have to capture back.
- var captureDeficit = fromValue - toValue;
- SeeAddKnightAttacks(to, them, themAttacks);
- if (themAttacks.length != 0 && captureDeficit > g_seeValues[pieceKnight]) {
- return false;
- }
+ // Knight attacks
+ // If any opponent knights can capture back, and the deficit we have to make up is greater than the knights value,
+ // it's not worth it. We can capture on this square again, and the opponent doesn't have to capture back.
+ var captureDeficit = fromValue - toValue;
+ SeeAddKnightAttacks(to, them, themAttacks);
+ if (themAttacks.length != 0 && captureDeficit > g_seeValues[pieceKnight]) {
+ return false;
+ }
- // Slider attacks
- g_board[from] = 0;
- for (var pieceType = pieceBishop; pieceType <= pieceQueen; pieceType++) {
- if (SeeAddSliderAttacks(to, them, themAttacks, pieceType)) {
- if (captureDeficit > g_seeValues[pieceType]) {
- g_board[from] = fromPiece;
- return false;
- }
- }
- }
+ // Slider attacks
+ g_board[from] = 0;
+ for (var pieceType = pieceBishop; pieceType <= pieceQueen; pieceType++) {
+ if (SeeAddSliderAttacks(to, them, themAttacks, pieceType)) {
+ if (captureDeficit > g_seeValues[pieceType]) {
+ g_board[from] = fromPiece;
+ return false;
+ }
+ }
+ }
- // Pawn defenses
- // At this point, we are sure we are making a "losing" capture. The opponent can not capture back with a
- // pawn. They cannot capture back with a minor/major and stand pat either. So, if we can capture with
- // a pawn, it's got to be a winning or equal capture.
- if (((g_board[to - inc + 1] & 0xF) == (piecePawn | us)) ||
- ((g_board[to - inc - 1] & 0xF) == (piecePawn | us))) {
- g_board[from] = fromPiece;
- return true;
- }
+ // Pawn defenses
+ // At this point, we are sure we are making a "losing" capture. The opponent can not capture back with a
+ // pawn. They cannot capture back with a minor/major and stand pat either. So, if we can capture with
+ // a pawn, it's got to be a winning or equal capture.
+ if ((g_board[to - inc + 1] & 0xf) == (piecePawn | us) || (g_board[to - inc - 1] & 0xf) == (piecePawn | us)) {
+ g_board[from] = fromPiece;
+ return true;
+ }
- // King attacks
- SeeAddSliderAttacks(to, them, themAttacks, pieceKing);
+ // King attacks
+ SeeAddSliderAttacks(to, them, themAttacks, pieceKing);
- // Our attacks
- var usAttacks = new Array();
- SeeAddKnightAttacks(to, us, usAttacks);
- for (var pieceType = pieceBishop; pieceType <= pieceKing; pieceType++) {
- SeeAddSliderAttacks(to, us, usAttacks, pieceType);
- }
+ // Our attacks
+ var usAttacks = new Array();
+ SeeAddKnightAttacks(to, us, usAttacks);
+ for (var pieceType = pieceBishop; pieceType <= pieceKing; pieceType++) {
+ SeeAddSliderAttacks(to, us, usAttacks, pieceType);
+ }
- g_board[from] = fromPiece;
+ g_board[from] = fromPiece;
- // We are currently winning the amount of material of the captured piece, time to see if the opponent
- // can get it back somehow. We assume the opponent can capture our current piece in this score, which
- // simplifies the later code considerably.
- var seeValue = toValue - fromValue;
+ // We are currently winning the amount of material of the captured piece, time to see if the opponent
+ // can get it back somehow. We assume the opponent can capture our current piece in this score, which
+ // simplifies the later code considerably.
+ var seeValue = toValue - fromValue;
- for (; ; ) {
- var capturingPieceValue = 1000;
- var capturingPieceIndex = -1;
+ for (;;) {
+ var capturingPieceValue = 1000;
+ var capturingPieceIndex = -1;
- // Find the least valuable piece of the opponent that can attack the square
- for (var i = 0; i < themAttacks.length; i++) {
- if (themAttacks[i] != 0) {
- var pieceValue = g_seeValues[g_board[themAttacks[i]] & 0x7];
- if (pieceValue < capturingPieceValue) {
- capturingPieceValue = pieceValue;
- capturingPieceIndex = i;
- }
- }
- }
+ // Find the least valuable piece of the opponent that can attack the square
+ for (var i = 0; i < themAttacks.length; i++) {
+ if (themAttacks[i] != 0) {
+ var pieceValue = g_seeValues[g_board[themAttacks[i]] & 0x7];
+ if (pieceValue < capturingPieceValue) {
+ capturingPieceValue = pieceValue;
+ capturingPieceIndex = i;
+ }
+ }
+ }
- if (capturingPieceIndex == -1) {
- // Opponent can't capture back, we win
- return true;
- }
+ if (capturingPieceIndex == -1) {
+ // Opponent can't capture back, we win
+ return true;
+ }
- // Now, if seeValue < 0, the opponent is winning. If even after we take their piece,
- // we can't bring it back to 0, then we have lost this battle.
- seeValue += capturingPieceValue;
- if (seeValue < 0) {
- return false;
- }
+ // Now, if seeValue < 0, the opponent is winning. If even after we take their piece,
+ // we can't bring it back to 0, then we have lost this battle.
+ seeValue += capturingPieceValue;
+ if (seeValue < 0) {
+ return false;
+ }
- var capturingPieceSquare = themAttacks[capturingPieceIndex];
- themAttacks[capturingPieceIndex] = 0;
+ var capturingPieceSquare = themAttacks[capturingPieceIndex];
+ themAttacks[capturingPieceIndex] = 0;
- // Add any x-ray attackers
- SeeAddXrayAttack(to, capturingPieceSquare, us, usAttacks, themAttacks);
+ // Add any x-ray attackers
+ SeeAddXrayAttack(to, capturingPieceSquare, us, usAttacks, themAttacks);
- // Our turn to capture
- capturingPieceValue = 1000;
- capturingPieceIndex = -1;
+ // Our turn to capture
+ capturingPieceValue = 1000;
+ capturingPieceIndex = -1;
- // Find our least valuable piece that can attack the square
- for (var i = 0; i < usAttacks.length; i++) {
- if (usAttacks[i] != 0) {
- var pieceValue = g_seeValues[g_board[usAttacks[i]] & 0x7];
- if (pieceValue < capturingPieceValue) {
- capturingPieceValue = pieceValue;
- capturingPieceIndex = i;
- }
- }
- }
+ // Find our least valuable piece that can attack the square
+ for (var i = 0; i < usAttacks.length; i++) {
+ if (usAttacks[i] != 0) {
+ var pieceValue = g_seeValues[g_board[usAttacks[i]] & 0x7];
+ if (pieceValue < capturingPieceValue) {
+ capturingPieceValue = pieceValue;
+ capturingPieceIndex = i;
+ }
+ }
+ }
- if (capturingPieceIndex == -1) {
- // We can't capture back, we lose :(
- return false;
- }
+ if (capturingPieceIndex == -1) {
+ // We can't capture back, we lose :(
+ return false;
+ }
- // Assume our opponent can capture us back, and if we are still winning, we can stand-pat
- // here, and assume we've won.
- seeValue -= capturingPieceValue;
- if (seeValue >= 0) {
- return true;
- }
+ // Assume our opponent can capture us back, and if we are still winning, we can stand-pat
+ // here, and assume we've won.
+ seeValue -= capturingPieceValue;
+ if (seeValue >= 0) {
+ return true;
+ }
- capturingPieceSquare = usAttacks[capturingPieceIndex];
- usAttacks[capturingPieceIndex] = 0;
+ capturingPieceSquare = usAttacks[capturingPieceIndex];
+ usAttacks[capturingPieceIndex] = 0;
- // Add any x-ray attackers
- SeeAddXrayAttack(to, capturingPieceSquare, us, usAttacks, themAttacks);
- }
+ // Add any x-ray attackers
+ SeeAddXrayAttack(to, capturingPieceSquare, us, usAttacks, themAttacks);
+ }
}
function SeeAddXrayAttack(target, square, us, usAttacks, themAttacks) {
- var index = square - target + 128;
- var delta = -g_vectorDelta[index].delta;
- if (delta == 0)
- return;
- square += delta;
- while (g_board[square] == 0) {
- square += delta;
- }
+ var index = square - target + 128;
+ var delta = -g_vectorDelta[index].delta;
+ if (delta == 0) return;
+ square += delta;
+ while (g_board[square] == 0) {
+ square += delta;
+ }
- if ((g_board[square] & 0x18) && IsSquareOnPieceLine(target, square)) {
- if ((g_board[square] & 8) == us) {
- usAttacks[usAttacks.length] = square;
- } else {
- themAttacks[themAttacks.length] = square;
- }
- }
+ if (g_board[square] & 0x18 && IsSquareOnPieceLine(target, square)) {
+ if ((g_board[square] & 8) == us) {
+ usAttacks[usAttacks.length] = square;
+ } else {
+ themAttacks[themAttacks.length] = square;
+ }
+ }
}
// target = attacking square, us = color of knights to look for, attacks = array to add squares to
function SeeAddKnightAttacks(target, us, attacks) {
- var pieceIdx = (us | pieceKnight) << 4;
- var attackerSq = g_pieceList[pieceIdx++];
+ var pieceIdx = (us | pieceKnight) << 4;
+ var attackerSq = g_pieceList[pieceIdx++];
- while (attackerSq != 0) {
- if (IsSquareOnPieceLine(target, attackerSq)) {
- attacks[attacks.length] = attackerSq;
- }
- attackerSq = g_pieceList[pieceIdx++];
- }
+ while (attackerSq != 0) {
+ if (IsSquareOnPieceLine(target, attackerSq)) {
+ attacks[attacks.length] = attackerSq;
+ }
+ attackerSq = g_pieceList[pieceIdx++];
+ }
}
function SeeAddSliderAttacks(target, us, attacks, pieceType) {
- var pieceIdx = (us | pieceType) << 4;
- var attackerSq = g_pieceList[pieceIdx++];
- var hit = false;
-
- while (attackerSq != 0) {
- if (IsSquareAttackableFrom(target, attackerSq)) {
- attacks[attacks.length] = attackerSq;
- hit = true;
- }
- attackerSq = g_pieceList[pieceIdx++];
- }
+ var pieceIdx = (us | pieceType) << 4;
+ var attackerSq = g_pieceList[pieceIdx++];
+ var hit = false;
+
+ while (attackerSq != 0) {
+ if (IsSquareAttackableFrom(target, attackerSq)) {
+ attacks[attacks.length] = attackerSq;
+ hit = true;
+ }
+ attackerSq = g_pieceList[pieceIdx++];
+ }
- return hit;
+ return hit;
}
function BuildPVMessage(bestMove, value, timeTaken, ply) {
- var totalNodes = g_nodeCount + g_qNodeCount;
- return "Ply:" + ply + " Score:" + value + " Nodes:" + totalNodes + " NPS:" + ((totalNodes / (timeTaken / 1000)) | 0) + " " + PVFromHash(bestMove, 15);
+ var totalNodes = g_nodeCount + g_qNodeCount;
+ return (
+ 'Ply:' +
+ ply +
+ ' Score:' +
+ value +
+ ' Nodes:' +
+ totalNodes +
+ ' NPS:' +
+ ((totalNodes / (timeTaken / 1000)) | 0) +
+ ' ' +
+ PVFromHash(bestMove, 15)
+ );
}
//////////////////////////////////////////////////
// Test Harness
//////////////////////////////////////////////////
function FinishPlyCallback(bestMove, value, timeTaken, ply) {
- postMessage("pv " + BuildPVMessage(bestMove, value, timeTaken, ply));
+ postMessage('pv ' + BuildPVMessage(bestMove, value, timeTaken, ply));
}
function FinishMoveLocalTesting(bestMove, value, timeTaken, ply) {
- if (bestMove != null) {
- MakeMove(bestMove);
- postMessage(FormatMove(bestMove));
- }
+ if (bestMove != null) {
+ MakeMove(bestMove);
+ postMessage(FormatMove(bestMove));
+ }
}
var needsReset = true;
self.onmessage = function (e) {
- if (e.data == "go" || needsReset) {
- ResetGame();
- needsReset = false;
- if (e.data == "go") return;
- }
- if (e.data.match("^position") == "position") {
- ResetGame();
- var result = InitializeFromFen(e.data.substr(9, e.data.length - 9));
- if (result.length != 0) {
- postMessage("message " + result);
- }
- } else if (e.data.match("^search") == "search") {
- g_timeout = parseInt(e.data.substr(7, e.data.length - 7), 10);
- Search(FinishMoveLocalTesting, 99, FinishPlyCallback);
- } else if (e.data == "analyze") {
- g_timeout = 99999999999;
- Search(null, 99, FinishPlyCallback);
- } else {
- MakeMove(GetMoveFromString(e.data));
- }
-}
+ if (e.data == 'go' || needsReset) {
+ ResetGame();
+ needsReset = false;
+ if (e.data == 'go') return;
+ }
+ if (e.data.match('^position') == 'position') {
+ ResetGame();
+ var result = InitializeFromFen(e.data.substr(9, e.data.length - 9));
+ if (result.length != 0) {
+ postMessage('message ' + result);
+ }
+ } else if (e.data.match('^search') == 'search') {
+ g_timeout = parseInt(e.data.substr(7, e.data.length - 7), 10);
+ Search(FinishMoveLocalTesting, 99, FinishPlyCallback);
+ } else if (e.data == 'analyze') {
+ g_timeout = 99999999999;
+ Search(null, 99, FinishPlyCallback);
+ } else {
+ MakeMove(GetMoveFromString(e.data));
+ }
+};
diff --git a/html/browser/marked-paradise.js b/html/browser/marked-paradise.js
index a92cadb1cfe66..53a56863ec5dc 100644
--- a/html/browser/marked-paradise.js
+++ b/html/browser/marked-paradise.js
@@ -4,22 +4,18 @@
var $ = document.querySelector.bind(document);
function parse(node) {
- for (var i = 0; i < node.childNodes.length; i++)
- parse(node.childNodes[i]);
+ for (var i = 0; i < node.childNodes.length; i++) parse(node.childNodes[i]);
- if (!node.innerHTML)
- return;
+ if (!node.innerHTML) return;
if (node.children.length == 0) {
node.innerHTML = marked(node.innerHTML.replace(/
/gi, '\n').replace(/\t/gi, ''), { breaks: false, gfm: false });
// marked.js wraps content into
tags, which is looks atrocious when we call it recursively.
// The following line unwraps it.
- if (node.children.length == 1 && node.children[0].tagName == "P")
- node.innerHTML = node.children[0].innerHTML;
+ if (node.children.length == 1 && node.children[0].tagName == 'P') node.innerHTML = node.children[0].innerHTML;
}
}
-window.onload = function() {
- if ($('#markdown'))
- parse($('#markdown'));
-}
+window.onload = function () {
+ if ($('#markdown')) parse($('#markdown'));
+};
diff --git a/html/browser/playeroptions.css b/html/browser/playeroptions.css
index 564d176930055..7bd220a334dd6 100644
--- a/html/browser/playeroptions.css
+++ b/html/browser/playeroptions.css
@@ -12,4 +12,3 @@
.commandPosition {
font-weight: bold;
}
-
diff --git a/html/browser/rankedInput.js b/html/browser/rankedInput.js
index fb5af2aeb6979..25aa8e658c580 100644
--- a/html/browser/rankedInput.js
+++ b/html/browser/rankedInput.js
@@ -1,26 +1,26 @@
var uid;
function allowDrop(ev) {
- ev.preventDefault();
+ ev.preventDefault();
}
function drag(ev) {
- var index = ev.target.getAttribute('index');
- if (index) {
- ev.dataTransfer.setData('text', index);
- }
+ var index = ev.target.getAttribute('index');
+ if (index) {
+ ev.dataTransfer.setData('text', index);
+ }
}
function drop(ev) {
- ev.preventDefault();
- var data = ev.dataTransfer.getData('text');
- if (data && ev.target.getAttribute('index')) {
- window.location = '?src=' + uid + ';' + 'cut=' + data + ';' + 'insert=' + ev.target.getAttribute('index');
- }
+ ev.preventDefault();
+ var data = ev.dataTransfer.getData('text');
+ if (data && ev.target.getAttribute('index')) {
+ window.location = '?src=' + uid + ';' + 'cut=' + data + ';' + 'insert=' + ev.target.getAttribute('index');
+ }
}
function setUid() {
- uid = document.getElementById('choices').getAttribute('uid');
+ uid = document.getElementById('choices').getAttribute('uid');
}
window.onload = setUid;
diff --git a/html/search.js b/html/search.js
index abc47a975731f..59ac83573b700 100644
--- a/html/search.js
+++ b/html/search.js
@@ -1,33 +1,33 @@
-function selectTextField(){
+function selectTextField() {
var filter_text = document.getElementById('filter');
filter_text.focus();
filter_text.select();
}
-function updateSearch(){
+function updateSearch() {
var input_form = document.getElementById('filter');
var filter = input_form.value.toLowerCase();
input_form.value = filter;
var table = document.getElementById('searchable');
var alt_style = 'norm';
- for(var i = 0; i < table.rows.length; i++){
- try{
+ for (var i = 0; i < table.rows.length; i++) {
+ try {
var row = table.rows[i];
- if(row.className == 'title') continue;
- var found=0;
- for(var j = 0; j < row.cells.length; j++){
+ if (row.className == 'title') continue;
+ var found = 0;
+ for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j];
- if(cell.innerText.toLowerCase().indexOf(filter) != -1){
- found=1;
+ if (cell.innerText.toLowerCase().indexOf(filter) != -1) {
+ found = 1;
break;
}
}
- if(found == 0) row.style.display='none';
- else{
- row.style.display='block';
+ if (found == 0) row.style.display = 'none';
+ else {
+ row.style.display = 'block';
row.className = alt_style;
- if(alt_style == 'alt') alt_style = 'norm';
+ if (alt_style == 'alt') alt_style = 'norm';
else alt_style = 'alt';
}
- }catch(err) { }
+ } catch (err) {}
}
-}
\ No newline at end of file
+}
diff --git a/html/statbrowser.css b/html/statbrowser.css
index d78fe76184ab1..171fb7667ae62 100644
--- a/html/statbrowser.css
+++ b/html/statbrowser.css
@@ -21,7 +21,7 @@ body {
a {
color: black;
- text-decoration: none
+ text-decoration: none;
}
a:hover,
@@ -231,7 +231,7 @@ body.dark {
}
.dark .link,
-.dark .listedturf_link{
+.dark .listedturf_link {
color: #abc6ec;
}
@@ -275,7 +275,7 @@ body.ntos {
}
.ntos .link,
-.ntos .listedturf_link{
+.ntos .listedturf_link {
color: #abc6ec;
}
@@ -319,7 +319,7 @@ body.paradise {
}
.paradise .link,
-.paradise .listedturf_link{
+.paradise .listedturf_link {
color: #edc1b2;
}
diff --git a/html/statbrowser.js b/html/statbrowser.js
index c44d424a1b362..ad0788d43248e 100644
--- a/html/statbrowser.js
+++ b/html/statbrowser.js
@@ -6,7 +6,7 @@ if (!Array.prototype.includes) {
if (this[i] == thing) return true;
}
return false;
- }
+ };
}
if (!String.prototype.trim) {
String.prototype.trim = function () {
@@ -18,16 +18,16 @@ if (!String.prototype.trim) {
// If you use this, you'll need to uncomment the Statpanel-Debug message
// handling, currently in code/modules/client/client_procs.dm
function log_debug(data) {
- Byond.sendMessage("Statpanel-Debug", JSON.stringify(data));
+ Byond.sendMessage('Statpanel-Debug', JSON.stringify(data));
}
// Status panel implementation ------------------------------------------------
-var status_tab_parts = [["Loading...", ""]];
+var status_tab_parts = [['Loading...', '']];
var current_tab = null;
-var mc_tab_parts = [["Loading...", ""]];
+var mc_tab_parts = [['Loading...', '']];
var href_token = null;
var verb_tabs = [];
-var verbs = [["", ""]]; // list with a list inside
+var verbs = [['', '']]; // list with a list inside
var permanent_tabs = []; // tabs that won't be cleared by wipes
var turf_row_inner_height = 33;
var turf_row_outer_height = 35;
@@ -35,8 +35,8 @@ var turf_rows = {};
var turf_incomplete_rows = {};
var turf_size = 0;
var turf_image_errors = {};
-var turfcontents = {"total": 0};
-var turfname = "";
+var turfcontents = { 'total': 0 };
+var turfname = '';
var imageFirstRetryDelay = 50;
var imageRetryDelay = 500;
var imageRetryLimit = 50;
@@ -53,31 +53,29 @@ function run_after_focus(callback) {
}
function createStatusTab(name) {
- if (name.indexOf(".") != -1) {
- var splitName = name.split(".");
- if (split_admin_tabs && splitName[0] === "Admin")
- name = splitName[1];
- else
- name = splitName[0];
- }
- if (document.getElementById(name) || name.trim() == "") {
+ if (name.indexOf('.') != -1) {
+ var splitName = name.split('.');
+ if (split_admin_tabs && splitName[0] === 'Admin') name = splitName[1];
+ else name = splitName[0];
+ }
+ if (document.getElementById(name) || name.trim() == '') {
return;
}
if (!verb_tabs.includes(name) && !permanent_tabs.includes(name)) {
return;
}
- var B = document.createElement("BUTTON");
+ var B = document.createElement('BUTTON');
B.onclick = function () {
tab_change(name);
this.blur();
};
B.id = name;
B.textContent = name;
- B.className = "button";
+ B.className = 'button';
//ORDERING ALPHABETICALLY
B.style.order = name.charCodeAt(0);
- if (name == "Status" || name == "MC") {
- B.style.order = name == "Status" ? 1 : 2;
+ if (name == 'Status' || name == 'MC') {
+ B.style.order = name == 'Status' ? 1 : 2;
}
//END ORDERING
menu.appendChild(B);
@@ -104,17 +102,16 @@ function sortVerbs() {
var selector = a[0] == b[0] ? 1 : 0;
if (a[selector].toUpperCase() < b[selector].toUpperCase()) {
return 1;
- }
- else if (a[selector].toUpperCase() > b[selector].toUpperCase()) {
+ } else if (a[selector].toUpperCase() > b[selector].toUpperCase()) {
return -1;
}
return 0;
- })
+ });
}
window.onresize = function () {
under_menu.style.height = menu.clientHeight + 'px';
-}
+};
function addPermanentTab(name) {
if (!permanent_tabs.includes(name)) {
@@ -145,7 +142,7 @@ function remove_verb(v) {
for (var i = verbs.length - 1; i >= 0; i--) {
var part_to_remove = verbs[i];
if (part_to_remove[1] == verb_to_remove[1]) {
- verbs.splice(i, 1)
+ verbs.splice(i, 1);
}
}
}
@@ -158,15 +155,13 @@ function check_verbs() {
function verbs_cat_check(cat) {
var tabCat = cat;
- if (cat.indexOf(".") != -1) {
- var splitName = cat.split(".");
- if (split_admin_tabs && splitName[0] === "Admin")
- tabCat = splitName[1];
- else
- tabCat = splitName[0];
+ if (cat.indexOf('.') != -1) {
+ var splitName = cat.split('.');
+ if (split_admin_tabs && splitName[0] === 'Admin') tabCat = splitName[1];
+ else tabCat = splitName[0];
}
var verbs_in_cat = 0;
- var verbcat = "";
+ var verbcat = '';
if (!verb_tabs.includes(tabCat)) {
removeStatusTab(tabCat);
return;
@@ -174,44 +169,39 @@ function verbs_cat_check(cat) {
for (var v = 0; v < verbs.length; v++) {
var part = verbs[v];
verbcat = part[0];
- if (verbcat.indexOf(".") != -1) {
- var splitName = verbcat.split(".");
- if (split_admin_tabs && splitName[0] === "Admin")
- verbcat = splitName[1];
- else
- verbcat = splitName[0];
+ if (verbcat.indexOf('.') != -1) {
+ var splitName = verbcat.split('.');
+ if (split_admin_tabs && splitName[0] === 'Admin') verbcat = splitName[1];
+ else verbcat = splitName[0];
}
- if (verbcat != tabCat || verbcat.trim() == "") {
+ if (verbcat != tabCat || verbcat.trim() == '') {
continue;
- }
- else {
+ } else {
verbs_in_cat = 1;
break; // we only need one
}
}
if (verbs_in_cat != 1) {
removeStatusTab(tabCat);
- if (current_tab == tabCat)
- tab_change("Status");
+ if (current_tab == tabCat) tab_change('Status');
}
}
function findVerbindex(name, verblist) {
for (var i = 0; i < verblist.length; i++) {
var part = verblist[i];
- if (part[1] == name)
- return i;
+ if (part[1] == name) return i;
}
}
function wipe_verbs() {
- verbs = [["", ""]];
+ verbs = [['', '']];
verb_tabs = [];
checkStatusTab(); // remove all empty verb tabs
}
function update_verbs() {
wipe_verbs();
- Byond.sendMessage("Update-Verbs");
+ Byond.sendMessage('Update-Verbs');
}
function SendTabsToByond() {
@@ -223,35 +213,33 @@ function SendTabsToByond() {
}
function SendTabToByond(tab) {
- Byond.sendMessage("Send-Tabs", {tab: tab});
+ Byond.sendMessage('Send-Tabs', { tab: tab });
}
//Byond can't have this tab anymore since we're removing it
function TakeTabFromByond(tab) {
- Byond.sendMessage("Remove-Tabs", {tab: tab});
+ Byond.sendMessage('Remove-Tabs', { tab: tab });
}
function tab_change(tab) {
if (tab == current_tab) return;
- if (document.getElementById(current_tab))
- document.getElementById(current_tab).className = "button"; // disable active on last button
+ if (document.getElementById(current_tab)) document.getElementById(current_tab).className = 'button'; // disable active on last button
current_tab = tab;
set_byond_tab(tab);
- if (document.getElementById(tab))
- document.getElementById(tab).className = "button active"; // make current button active
- var verb_tabs_thingy = (verb_tabs.includes(tab));
- if (tab == "Status") {
+ if (document.getElementById(tab)) document.getElementById(tab).className = 'button active'; // make current button active
+ var verb_tabs_thingy = verb_tabs.includes(tab);
+ if (tab == 'Status') {
draw_status();
- } else if (tab == "MC") {
+ } else if (tab == 'MC') {
draw_mc();
} else if (verb_tabs_thingy) {
draw_verbs(tab);
- } else if (tab == "Debug Stat Panel") {
+ } else if (tab == 'Debug Stat Panel') {
draw_debug();
} else if (tab == turfname) {
draw_listedturf();
} else {
- statcontentdiv.textContext = "Loading...";
+ statcontentdiv.textContext = 'Loading...';
}
Byond.winset(Byond.windowId, {
'is-visible': true,
@@ -259,119 +247,122 @@ function tab_change(tab) {
}
function set_byond_tab(tab) {
- Byond.sendMessage("Set-Tab", {tab: tab});
+ Byond.sendMessage('Set-Tab', { tab: tab });
}
function draw_debug() {
- statcontentdiv.textContent = "";
- var wipeverbstabs = document.createElement("div");
- var link = document.createElement("a");
- link.onclick = function () { wipe_verbs() };
- link.textContent = "Wipe All Verbs";
+ statcontentdiv.textContent = '';
+ var wipeverbstabs = document.createElement('div');
+ var link = document.createElement('a');
+ link.onclick = function () {
+ wipe_verbs();
+ };
+ link.textContent = 'Wipe All Verbs';
wipeverbstabs.appendChild(link);
- document.getElementById("statcontent").appendChild(wipeverbstabs);
- var wipeUpdateVerbsTabs = document.createElement("div");
- var updateLink = document.createElement("a");
- updateLink.onclick = function () { update_verbs() };
- updateLink.textContent = "Wipe and Update All Verbs";
+ document.getElementById('statcontent').appendChild(wipeverbstabs);
+ var wipeUpdateVerbsTabs = document.createElement('div');
+ var updateLink = document.createElement('a');
+ updateLink.onclick = function () {
+ update_verbs();
+ };
+ updateLink.textContent = 'Wipe and Update All Verbs';
wipeUpdateVerbsTabs.appendChild(updateLink);
- document.getElementById("statcontent").appendChild(wipeUpdateVerbsTabs);
- var text = document.createElement("div");
- text.textContent = "Verb Tabs:";
- document.getElementById("statcontent").appendChild(text);
- var table1 = document.createElement("table");
+ document.getElementById('statcontent').appendChild(wipeUpdateVerbsTabs);
+ var text = document.createElement('div');
+ text.textContent = 'Verb Tabs:';
+ document.getElementById('statcontent').appendChild(text);
+ var table1 = document.createElement('table');
for (var i = 0; i < verb_tabs.length; i++) {
var part = verb_tabs[i];
// Hide subgroups except admin subgroups if they are split
- if (verb_tabs[i].lastIndexOf(".") != -1) {
- var splitName = verb_tabs[i].split(".");
- if (split_admin_tabs && splitName[0] === "Admin")
- part = splitName[1];
- else
- continue;
+ if (verb_tabs[i].lastIndexOf('.') != -1) {
+ var splitName = verb_tabs[i].split('.');
+ if (split_admin_tabs && splitName[0] === 'Admin') part = splitName[1];
+ else continue;
}
- var tr = document.createElement("tr");
- var td1 = document.createElement("td");
+ var tr = document.createElement('tr');
+ var td1 = document.createElement('td');
td1.textContent = part;
- var a = document.createElement("a");
- a.onclick = function (part) {
- return function () { removeStatusTab(part) };
- }(part);
- a.textContent = " Delete Tab " + part;
+ var a = document.createElement('a');
+ a.onclick = (function (part) {
+ return function () {
+ removeStatusTab(part);
+ };
+ })(part);
+ a.textContent = ' Delete Tab ' + part;
td1.appendChild(a);
tr.appendChild(td1);
table1.appendChild(tr);
}
- document.getElementById("statcontent").appendChild(table1);
- var header2 = document.createElement("div");
- header2.textContent = "Verbs:";
- document.getElementById("statcontent").appendChild(header2);
- var table2 = document.createElement("table");
+ document.getElementById('statcontent').appendChild(table1);
+ var header2 = document.createElement('div');
+ header2.textContent = 'Verbs:';
+ document.getElementById('statcontent').appendChild(header2);
+ var table2 = document.createElement('table');
for (var v = 0; v < verbs.length; v++) {
var part2 = verbs[v];
- var trr = document.createElement("tr");
- var tdd1 = document.createElement("td");
+ var trr = document.createElement('tr');
+ var tdd1 = document.createElement('td');
tdd1.textContent = part2[0];
- var tdd2 = document.createElement("td");
+ var tdd2 = document.createElement('td');
tdd2.textContent = part2[1];
trr.appendChild(tdd1);
trr.appendChild(tdd2);
table2.appendChild(trr);
}
- document.getElementById("statcontent").appendChild(table2);
- var text3 = document.createElement("div");
- text3.textContent = "Permanent Tabs:";
- document.getElementById("statcontent").appendChild(text3);
- var table3 = document.createElement("table");
+ document.getElementById('statcontent').appendChild(table2);
+ var text3 = document.createElement('div');
+ text3.textContent = 'Permanent Tabs:';
+ document.getElementById('statcontent').appendChild(text3);
+ var table3 = document.createElement('table');
for (var i = 0; i < permanent_tabs.length; i++) {
var part3 = permanent_tabs[i];
- var trrr = document.createElement("tr");
- var tddd1 = document.createElement("td");
+ var trrr = document.createElement('tr');
+ var tddd1 = document.createElement('td');
tddd1.textContent = part3;
trrr.appendChild(tddd1);
table3.appendChild(trrr);
}
- document.getElementById("statcontent").appendChild(table3);
-
+ document.getElementById('statcontent').appendChild(table3);
}
function draw_status() {
- if (!document.getElementById("Status")) {
- createStatusTab("Status");
- current_tab = "Status";
+ if (!document.getElementById('Status')) {
+ createStatusTab('Status');
+ current_tab = 'Status';
}
statcontentdiv.textContent = '';
- var table = document.createElement("table");
+ var table = document.createElement('table');
for (var i = 0; i < status_tab_parts.length; i++) {
var part = status_tab_parts[i];
- var tr = document.createElement("tr");
- var td1 = document.createElement("td");
+ var tr = document.createElement('tr');
+ var td1 = document.createElement('td');
td1.textContent = part[0];
- var td2 = document.createElement("td");
+ var td2 = document.createElement('td');
td2.insertAdjacentHTML('beforeend', part[1]);
tr.appendChild(td1);
tr.appendChild(td2);
table.appendChild(tr);
}
- document.getElementById("statcontent").appendChild(table);
+ document.getElementById('statcontent').appendChild(table);
if (verb_tabs.length == 0 || !verbs) {
- Byond.command("Fix-Stat-Panel");
+ Byond.command('Fix-Stat-Panel');
}
}
function draw_mc() {
- statcontentdiv.textContent = "";
- var table = document.createElement("table");
+ statcontentdiv.textContent = '';
+ var table = document.createElement('table');
for (var i = 0; i < mc_tab_parts.length; i++) {
var part = mc_tab_parts[i];
- var tr = document.createElement("tr");
- var td1 = document.createElement("td");
+ var tr = document.createElement('tr');
+ var td1 = document.createElement('td');
td1.textContent = part[0];
- var td2 = document.createElement("td");
+ var td2 = document.createElement('td');
if (part[2]) {
- var a = document.createElement("a");
- a.onclick = debug_statclick(part[2])
+ var a = document.createElement('a');
+ a.onclick = debug_statclick(part[2]);
a.insertAdjacentHTML('beforeend', part[1]);
td2.appendChild(a);
} else {
@@ -381,69 +372,69 @@ function draw_mc() {
tr.appendChild(td2);
table.appendChild(tr);
}
- document.getElementById("statcontent").appendChild(table);
+ document.getElementById('statcontent').appendChild(table);
}
function listedturf_add_row(table, table_index, true_index) {
let row = table.insertRow(table_index);
- row.style.height = turf_row_inner_height + "px"
- row.style.padding = "0px"
- row.style.margin = "0px"
+ row.style.height = turf_row_inner_height + 'px';
+ row.style.padding = '0px';
+ row.style.margin = '0px';
turf_rows[true_index] = row;
turf_incomplete_rows[true_index] = true_index + 1;
}
function listedturf_fill_row(row, item_index) {
- let object_info = turfcontents["" + item_index];
- if(!object_info) {
+ let object_info = turfcontents['' + item_index];
+ if (!object_info) {
return false;
}
- let cell = document.createElement("td");
- cell.style.height = turf_row_inner_height + "px"
- cell.style.padding = "0px"
- cell.style.margin = "0px"
- row.appendChild(cell)
+ let cell = document.createElement('td');
+ cell.style.height = turf_row_inner_height + 'px';
+ cell.style.padding = '0px';
+ cell.style.margin = '0px';
+ row.appendChild(cell);
- var button = document.createElement("div");
- button.className = "listedturf_link";
- var clickcatcher = "";
- button.onmousedown = function (object_info) {
+ var button = document.createElement('div');
+ button.className = 'listedturf_link';
+ var clickcatcher = '';
+ button.onmousedown = (function (object_info) {
// The outer function is used to close over a fresh "object_info"
// variable, rather than every onmousedown getting the "object_info"
// of the last entry.
return function (e) {
e.preventDefault();
- clickcatcher = "?src=" + object_info[1];
+ clickcatcher = '?src=' + object_info[1];
switch (e.button) {
case 1:
- clickcatcher += ";statpanel_item_click=middle"
+ clickcatcher += ';statpanel_item_click=middle';
break;
case 2:
- clickcatcher += ";statpanel_item_click=right"
+ clickcatcher += ';statpanel_item_click=right';
break;
default:
- clickcatcher += ";statpanel_item_click=left"
+ clickcatcher += ';statpanel_item_click=left';
}
if (e.shiftKey) {
- clickcatcher += ";statpanel_item_shiftclick=1";
+ clickcatcher += ';statpanel_item_shiftclick=1';
}
if (e.ctrlKey) {
- clickcatcher += ";statpanel_item_ctrlclick=1";
+ clickcatcher += ';statpanel_item_ctrlclick=1';
}
if (e.altKey) {
- clickcatcher += ";statpanel_item_altclick=1";
+ clickcatcher += ';statpanel_item_altclick=1';
}
window.location.href = clickcatcher;
- }
- }(object_info);
+ };
+ })(object_info);
cell.appendChild(button);
- let img = document.createElement("img");
+ let img = document.createElement('img');
img.id = object_info[1];
img.src = object_info[2];
- img.style.verticalAlign = "middle";
- img.onerror = function (object_info) {
+ img.style.verticalAlign = 'middle';
+ img.onerror = (function (object_info) {
return function () {
let delay = imageRetryDelay;
if (!turf_image_errors[object_info[3]]) {
@@ -455,18 +446,18 @@ function listedturf_fill_row(row, item_index) {
return;
}
- Byond.sendMessage("Resend-Asset", object_info[3]);
+ Byond.sendMessage('Resend-Asset', object_info[3]);
setTimeout(function () {
// Use the failure count as a cachebreaker to force-reload.
let img = document.getElementById(object_info[1]);
- img.src = object_info[2] + "?" + turf_image_errors[object_info[3]];
+ img.src = object_info[2] + '?' + turf_image_errors[object_info[3]];
}, imageRetryDelay);
- }
- }(object_info);
+ };
+ })(object_info);
button.appendChild(img);
- var label = document.createElement("span");
- label.style.marginLeft = "5px";
+ var label = document.createElement('span');
+ label.style.marginLeft = '5px';
label.textContent = object_info[0];
button.appendChild(label);
@@ -474,9 +465,9 @@ function listedturf_fill_row(row, item_index) {
}
function listedturf_fill_all() {
- for(let i in turf_incomplete_rows) {
+ for (let i in turf_incomplete_rows) {
let item_index = turf_incomplete_rows[i];
- if(!turf_rows[i] || listedturf_fill_row(turf_rows[i], item_index)) {
+ if (!turf_rows[i] || listedturf_fill_row(turf_rows[i], item_index)) {
delete turf_incomplete_rows[i];
}
}
@@ -492,8 +483,8 @@ function listedturf_scrolled() {
let height = document.documentElement.clientHeight;
let bottom_edge = top_edge + height;
let total = document.documentElement.scrollHeight;
- let table = document.getElementById("listedturf_table");
- let padding = document.getElementById("listedturf_padding");
+ let table = document.getElementById('listedturf_table');
+ let padding = document.getElementById('listedturf_padding');
if (!turf_rows.initialized) {
turf_rows = {
@@ -509,8 +500,8 @@ function listedturf_scrolled() {
let desired_min_row = Math.min(turf_size, Math.max(0, Math.floor(top_edge / turf_row_outer_height) - 10));
let desired_max_row = Math.min(turf_size, desired_min_row + Math.ceil(height / turf_row_outer_height) + 21);
- padding.style.height = (desired_min_row * turf_row_outer_height) + "px";
- if(desired_min_row == turf_rows.min_row && desired_max_row == turf_rows.max_row) {
+ padding.style.height = desired_min_row * turf_row_outer_height + 'px';
+ if (desired_min_row == turf_rows.min_row && desired_max_row == turf_rows.max_row) {
listedturf_fill_all();
suppress_next_scroll_message = false;
return;
@@ -522,7 +513,7 @@ function listedturf_scrolled() {
}
} else if (desired_min_row > turf_rows.min_row) {
for (let i = turf_rows.min_row; i < desired_min_row && i < turf_rows.max_row; i++) {
- if(turf_rows[i]) {
+ if (turf_rows[i]) {
turf_rows[i].remove();
delete turf_rows[i];
}
@@ -530,12 +521,11 @@ function listedturf_scrolled() {
}
turf_rows.min_row = desired_min_row;
- padding.style.height = turf_rows.min_row * turf_row_outer_height + "px"
-
+ padding.style.height = turf_rows.min_row * turf_row_outer_height + 'px';
if (desired_max_row < turf_rows.max_row) {
for (let i = Math.max(desired_max_row, turf_rows.min_row); i < turf_rows.max_row; i++) {
- if(turf_rows[i]) {
+ if (turf_rows[i]) {
turf_rows[i].remove();
delete turf_rows[i];
}
@@ -550,47 +540,49 @@ function listedturf_scrolled() {
listedturf_fill_all();
if (!suppress_next_scroll_message) {
- Byond.sendMessage("Listedturf-Scroll", {"min": turf_rows.min_row, "max": turf_rows.max_row})
+ Byond.sendMessage('Listedturf-Scroll', { 'min': turf_rows.min_row, 'max': turf_rows.max_row });
}
suppress_next_scroll_message = false;
}
function draw_listedturf() {
- if(document.getElementById("listedturf_div")) {
- let div = document.getElementById("listedturf_div");
- div.style.height = (turf_row_outer_height * turf_size) + "px";
+ if (document.getElementById('listedturf_div')) {
+ let div = document.getElementById('listedturf_div');
+ div.style.height = turf_row_outer_height * turf_size + 'px';
suppress_next_scroll_message = true;
listedturf_scrolled();
- return
+ return;
}
- statcontentdiv.textContent = "";
+ statcontentdiv.textContent = '';
turf_rows = {};
- window.onscroll = function() { listedturf_scrolled(); };
-
- let div = document.createElement("div");
- div.id = "listedturf_div";
- div.style.height = (turf_row_outer_height * turf_size) + "px";
- document.getElementById("statcontent").appendChild(div);
-
- let table = document.createElement("table");
- table.id = "listedturf_table";
- table.style.width = "100%"
- table.style.height = "100%"
- div.appendChild(table)
-
- let padding = document.createElement("tr");
- padding.id = "listedturf_padding";
- padding.style.height = "0px";
- padding.style.padding = "0px"
- padding.style.margin = "0px"
+ window.onscroll = function () {
+ listedturf_scrolled();
+ };
+
+ let div = document.createElement('div');
+ div.id = 'listedturf_div';
+ div.style.height = turf_row_outer_height * turf_size + 'px';
+ document.getElementById('statcontent').appendChild(div);
+
+ let table = document.createElement('table');
+ table.id = 'listedturf_table';
+ table.style.width = '100%';
+ table.style.height = '100%';
+ div.appendChild(table);
+
+ let padding = document.createElement('tr');
+ padding.id = 'listedturf_padding';
+ padding.style.height = '0px';
+ padding.style.padding = '0px';
+ padding.style.margin = '0px';
table.appendChild(padding);
- let end_flex = document.createElement("tr");
- end_flex.id = "listedturf_end_flex";
- end_flex.style.height = "100%";
- end_flex.style.padding = "0px"
- end_flex.style.margin = "0px"
+ let end_flex = document.createElement('tr');
+ end_flex.id = 'listedturf_end_flex';
+ end_flex.style.height = '100%';
+ end_flex.style.padding = '0px';
+ end_flex.style.margin = '0px';
table.appendChild(end_flex);
suppress_next_scroll_message = true;
@@ -601,24 +593,24 @@ function remove_listedturf() {
removePermanentTab(turfname);
checkStatusTab();
if (current_tab == turfname) {
- tab_change("Status");
+ tab_change('Status');
}
- if(document.getElementById("listedturf_div")) {
- document.getElementById("listedturf_div").remove();
+ if (document.getElementById('listedturf_div')) {
+ document.getElementById('listedturf_div').remove();
}
turf_rows = {};
turf_incomplete_rows = {};
turf_size = 0;
- turfcontents = {"total": 0};
- turfname = "";
+ turfcontents = { 'total': 0 };
+ turfname = '';
}
function remove_mc() {
- removePermanentTab("MC");
- if (current_tab == "MC") {
- tab_change("Status");
+ removePermanentTab('MC');
+ if (current_tab == 'MC') {
+ tab_change('Status');
}
-};
+}
function make_verb_onclick(command) {
return function () {
@@ -630,61 +622,59 @@ function make_verb_onclick(command) {
function debug_statclick(stat_item_uid) {
return function () {
- Byond.sendMessage("Debug-Stat-Entry", {stat_item_uid: stat_item_uid})
+ Byond.sendMessage('Debug-Stat-Entry', { stat_item_uid: stat_item_uid });
};
}
function draw_verbs(cat) {
- statcontentdiv.textContent = "";
- var table = document.createElement("div");
+ statcontentdiv.textContent = '';
+ var table = document.createElement('div');
var additions = {}; // additional sub-categories to be rendered
- table.className = "grid-container";
+ table.className = 'grid-container';
sortVerbs();
- if (split_admin_tabs && cat.lastIndexOf(".") != -1) {
- var splitName = cat.split(".");
- if (splitName[0] === "Admin")
- cat = splitName[1];
+ if (split_admin_tabs && cat.lastIndexOf('.') != -1) {
+ var splitName = cat.split('.');
+ if (splitName[0] === 'Admin') cat = splitName[1];
}
verbs.reverse(); // sort verbs backwards before we draw
for (var i = 0; i < verbs.length; ++i) {
var part = verbs[i];
var name = part[0];
- if (split_admin_tabs && name.lastIndexOf(".") != -1) {
- var splitName = name.split(".");
- if (splitName[0] === "Admin")
- name = splitName[1];
+ if (split_admin_tabs && name.lastIndexOf('.') != -1) {
+ var splitName = name.split('.');
+ if (splitName[0] === 'Admin') name = splitName[1];
}
var command = part[1];
- if (command && name.lastIndexOf(cat, 0) != -1 && (name.length == cat.length || name.charAt(cat.length) == ".")) {
- var subCat = name.lastIndexOf(".") != -1 ? name.split(".")[1] : null;
+ if (command && name.lastIndexOf(cat, 0) != -1 && (name.length == cat.length || name.charAt(cat.length) == '.')) {
+ var subCat = name.lastIndexOf('.') != -1 ? name.split('.')[1] : null;
if (subCat && !additions[subCat]) {
- var newTable = document.createElement("div");
- newTable.className = "grid-container";
+ var newTable = document.createElement('div');
+ newTable.className = 'grid-container';
additions[subCat] = newTable;
}
- var a = document.createElement("a");
- a.href = "#";
- a.onclick = make_verb_onclick(command.replace(/\s/g, "-"));
- a.className = "grid-item";
- var t = document.createElement("span");
+ var a = document.createElement('a');
+ a.href = '#';
+ a.onclick = make_verb_onclick(command.replace(/\s/g, '-'));
+ a.className = 'grid-item';
+ var t = document.createElement('span');
t.textContent = command;
- t.className = "grid-item-text";
+ t.className = 'grid-item-text';
a.appendChild(t);
(subCat ? additions[subCat] : table).appendChild(a);
}
}
// Append base table to view
- var content = document.getElementById("statcontent");
+ var content = document.getElementById('statcontent');
content.appendChild(table);
// Append additional sub-categories if relevant
for (var cat in additions) {
if (additions.hasOwnProperty(cat)) {
// do addition here
- var header = document.createElement("h3");
+ var header = document.createElement('h3');
header.textContent = cat;
content.appendChild(header);
content.appendChild(additions[cat]);
@@ -693,35 +683,35 @@ function draw_verbs(cat) {
}
function set_theme(which) {
- if (which == "light") {
- document.body.className = "";
+ if (which == 'light') {
+ document.body.className = '';
set_style_sheet('chat_panel_white');
- } else if (which == "dark") {
- document.body.className = "dark";
+ } else if (which == 'dark') {
+ document.body.className = 'dark';
set_style_sheet('chat_panel');
- } else if (which == "ntos") {
- document.body.className = "ntos";
+ } else if (which == 'ntos') {
+ document.body.className = 'ntos';
set_style_sheet('chat_panel_ntos');
- } else if (which == "paradise") {
- document.body.className = "paradise";
+ } else if (which == 'paradise') {
+ document.body.className = 'paradise';
set_style_sheet('chat_panel_paradise');
- } else if (which == "syndicate") {
- document.body.className = "syndicate";
+ } else if (which == 'syndicate') {
+ document.body.className = 'syndicate';
set_style_sheet('chat_panel_syndicate');
}
}
function set_style_sheet(sheet) {
- if (document.getElementById("goonStyle")) {
- var currentSheet = document.getElementById("goonStyle");
+ if (document.getElementById('goonStyle')) {
+ var currentSheet = document.getElementById('goonStyle');
currentSheet.parentElement.removeChild(currentSheet);
}
var head = document.getElementsByTagName('head')[0];
- var sheetElement = document.createElement("link");
- sheetElement.id = "goonStyle";
- sheetElement.rel = "stylesheet";
- sheetElement.type = "text/css";
- sheetElement.href = sheet + ".css";
+ var sheetElement = document.createElement('link');
+ sheetElement.id = 'goonStyle';
+ sheetElement.rel = 'stylesheet';
+ sheetElement.type = 'text/css';
+ sheetElement.href = sheet + '.css';
sheetElement.media = 'all';
head.appendChild(sheetElement);
}
@@ -752,18 +742,14 @@ function add_verb_list(payload) {
to_add.sort(); // sort what we're adding
for (var i = 0; i < to_add.length; i++) {
var part = to_add[i];
- if (!part[0])
- continue;
+ if (!part[0]) continue;
var category = part[0];
- if (category.indexOf(".") != -1) {
- var splitName = category.split(".");
- if (split_admin_tabs && splitName[0] === "Admin")
- category = splitName[1];
- else
- category = splitName[0];
+ if (category.indexOf('.') != -1) {
+ var splitName = category.split('.');
+ if (split_admin_tabs && splitName[0] === 'Admin') category = splitName[1];
+ else category = splitName[0];
}
- if (findVerbindex(part[1], verbs))
- continue;
+ if (findVerbindex(part[1], verbs)) continue;
if (verb_tabs.includes(category)) {
verbs.push(part);
if (current_tab == category) {
@@ -775,18 +761,18 @@ function add_verb_list(payload) {
createStatusTab(category);
}
}
-};
+}
-document.addEventListener("mouseup", restoreFocus);
-document.addEventListener("keyup", restoreFocus);
+document.addEventListener('mouseup', restoreFocus);
+document.addEventListener('keyup', restoreFocus);
if (!current_tab) {
- addPermanentTab("Status");
- tab_change("Status");
+ addPermanentTab('Status');
+ tab_change('Status');
}
window.onload = function () {
- Byond.sendMessage("Update-Verbs");
+ Byond.sendMessage('Update-Verbs');
};
Byond.subscribeTo('remove_verb_list', function (v) {
@@ -796,8 +782,7 @@ Byond.subscribeTo('remove_verb_list', function (v) {
}
check_verbs();
sortVerbs();
- if (verb_tabs.includes(current_tab))
- draw_verbs(current_tab);
+ if (verb_tabs.includes(current_tab)) draw_verbs(current_tab);
});
// passes a 2D list of (verbcategory, verbname) creates tabs and adds verbs to respective list
@@ -808,7 +793,7 @@ Byond.subscribeTo('init_verbs', function (payload) {
verb_tabs = payload.panel_tabs;
verb_tabs.sort(); // sort it
var do_update = false;
- var cat = "";
+ var cat = '';
for (var i = 0; i < verb_tabs.length; i++) {
cat = verb_tabs[i];
createStatusTab(cat); // create a category if the verb doesn't exist yet
@@ -830,54 +815,55 @@ Byond.subscribeTo('update_stat', function (payload) {
status_tab_parts = [];
var parsed = payload.global_data;
- for (var i = 0; i < parsed.length; i++)
- {
+ for (var i = 0; i < parsed.length; i++) {
if (parsed[i] != null) {
status_tab_parts.push(parsed[i]);
}
}
- for (var i = 0; i < 4; i++) // Spacing to split global and mob specific data
- {
- status_tab_parts.push(["", ""]);
+ for (
+ var i = 0;
+ i < 4;
+ i++ // Spacing to split global and mob specific data
+ ) {
+ status_tab_parts.push(['', '']);
}
parsed = payload.mob_specific_data;
- for (var i = 0; i < parsed.length; i++)
- {
+ for (var i = 0; i < parsed.length; i++) {
if (parsed[i] != null) {
status_tab_parts.push(parsed[i]);
}
}
- if (current_tab == "Status") {
+ if (current_tab == 'Status') {
draw_status();
- } else if (current_tab == "Debug Stat Panel") {
+ } else if (current_tab == 'Debug Stat Panel') {
draw_debug();
}
});
Byond.subscribeTo('update_mc', function (payload) {
mc_tab_parts = payload.mc_data;
- mc_tab_parts.splice(0, 0, ["Location:", payload.coord_entry]);
+ mc_tab_parts.splice(0, 0, ['Location:', payload.coord_entry]);
- if (!verb_tabs.includes("MC")) {
- verb_tabs.push("MC");
+ if (!verb_tabs.includes('MC')) {
+ verb_tabs.push('MC');
}
- createStatusTab("MC");
+ createStatusTab('MC');
- if (current_tab == "MC") {
+ if (current_tab == 'MC') {
draw_mc();
}
});
Byond.subscribeTo('create_debug', function () {
- if (!document.getElementById("Debug Stat Panel")) {
- addPermanentTab("Debug Stat Panel");
+ if (!document.getElementById('Debug Stat Panel')) {
+ addPermanentTab('Debug Stat Panel');
} else {
- removePermanentTab("Debug Stat Panel");
+ removePermanentTab('Debug Stat Panel');
}
});
@@ -897,7 +883,7 @@ Byond.subscribeTo('remove_mc_tab', function (removeHref) {
Byond.subscribeTo('update_listedturf', function (TC) {
turfcontents = TC;
- turf_size = TC["total"];
+ turf_size = TC['total'];
if (current_tab == turfname) {
draw_listedturf();
}
@@ -905,19 +891,19 @@ Byond.subscribeTo('update_listedturf', function (TC) {
Byond.subscribeTo('update_interviews', function (I) {
interviewManager = I;
- if (current_tab == "Tickets") {
+ if (current_tab == 'Tickets') {
draw_interviews();
}
});
Byond.subscribeTo('update_split_admin_tabs', function (status) {
- status = (status == true);
+ status = status == true;
if (split_admin_tabs !== status) {
if (split_admin_tabs === true) {
- removeStatusTab("Events");
- removeStatusTab("Fun");
- removeStatusTab("Game");
+ removeStatusTab('Events');
+ removeStatusTab('Fun');
+ removeStatusTab('Game');
}
update_verbs();
}
@@ -926,10 +912,9 @@ Byond.subscribeTo('update_split_admin_tabs', function (status) {
Byond.subscribeTo('add_mc_tab', function (ht) {
href_token = ht;
- addPermanentTab("MC");
+ addPermanentTab('MC');
});
-
Byond.subscribeTo('remove_listedturf', remove_listedturf);
Byond.subscribeTo('remove_mc', remove_mc);
diff --git a/tgui/.editorconfig b/tgui/.editorconfig
index 33092d4928a4e..fe153c1cb8e85 100644
--- a/tgui/.editorconfig
+++ b/tgui/.editorconfig
@@ -10,4 +10,4 @@ trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
-max_line_length = 80
+max_line_length = 120
diff --git a/tgui/.prettierrc.yml b/tgui/.prettierrc.yml
index 2911fcd522dd8..93ea671b74e60 100644
--- a/tgui/.prettierrc.yml
+++ b/tgui/.prettierrc.yml
@@ -2,7 +2,7 @@ arrowParens: always
bracketSpacing: true
endOfLine: lf
jsxSingleQuote: false
-printWidth: 80
+printWidth: 120
proseWrap: preserve
quoteProps: preserve
semi: true
diff --git a/tgui/.yarn/sdks/eslint/bin/eslint.js b/tgui/.yarn/sdks/eslint/bin/eslint.js
index 9ef98e400b47b..f0557a07767ea 100644
--- a/tgui/.yarn/sdks/eslint/bin/eslint.js
+++ b/tgui/.yarn/sdks/eslint/bin/eslint.js
@@ -1,10 +1,10 @@
#!/usr/bin/env node
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
+const { existsSync } = require(`fs`);
+const { createRequire } = require(`module`);
+const { resolve } = require(`path`);
-const relPnpApiPath = "../../../../.pnp.cjs";
+const relPnpApiPath = '../../../../.pnp.cjs';
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
diff --git a/tgui/.yarn/sdks/eslint/lib/api.js b/tgui/.yarn/sdks/eslint/lib/api.js
index 653b22bae06f4..93f1f0c282476 100644
--- a/tgui/.yarn/sdks/eslint/lib/api.js
+++ b/tgui/.yarn/sdks/eslint/lib/api.js
@@ -1,10 +1,10 @@
#!/usr/bin/env node
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
+const { existsSync } = require(`fs`);
+const { createRequire } = require(`module`);
+const { resolve } = require(`path`);
-const relPnpApiPath = "../../../../.pnp.cjs";
+const relPnpApiPath = '../../../../.pnp.cjs';
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
diff --git a/tgui/.yarn/sdks/eslint/lib/unsupported-api.js b/tgui/.yarn/sdks/eslint/lib/unsupported-api.js
index 30fdf158b4756..01e7653dcc92b 100644
--- a/tgui/.yarn/sdks/eslint/lib/unsupported-api.js
+++ b/tgui/.yarn/sdks/eslint/lib/unsupported-api.js
@@ -1,10 +1,10 @@
#!/usr/bin/env node
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
+const { existsSync } = require(`fs`);
+const { createRequire } = require(`module`);
+const { resolve } = require(`path`);
-const relPnpApiPath = "../../../../.pnp.cjs";
+const relPnpApiPath = '../../../../.pnp.cjs';
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
diff --git a/tgui/.yarn/sdks/typescript/lib/tsc.js b/tgui/.yarn/sdks/typescript/lib/tsc.js
index 2f62fc96c0a08..1d3e2a83cf2d9 100644
--- a/tgui/.yarn/sdks/typescript/lib/tsc.js
+++ b/tgui/.yarn/sdks/typescript/lib/tsc.js
@@ -1,10 +1,10 @@
#!/usr/bin/env node
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
+const { existsSync } = require(`fs`);
+const { createRequire } = require(`module`);
+const { resolve } = require(`path`);
-const relPnpApiPath = "../../../../.pnp.cjs";
+const relPnpApiPath = '../../../../.pnp.cjs';
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
diff --git a/tgui/.yarn/sdks/typescript/lib/tsserver.js b/tgui/.yarn/sdks/typescript/lib/tsserver.js
index bbb1e46501b52..a11bb7bcbbbd6 100644
--- a/tgui/.yarn/sdks/typescript/lib/tsserver.js
+++ b/tgui/.yarn/sdks/typescript/lib/tsserver.js
@@ -1,29 +1,31 @@
#!/usr/bin/env node
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
+const { existsSync } = require(`fs`);
+const { createRequire } = require(`module`);
+const { resolve } = require(`path`);
-const relPnpApiPath = "../../../../.pnp.cjs";
+const relPnpApiPath = '../../../../.pnp.cjs';
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
-const moduleWrapper = tsserver => {
+const moduleWrapper = (tsserver) => {
if (!process.versions.pnp) {
return tsserver;
}
- const {isAbsolute} = require(`path`);
+ const { isAbsolute } = require(`path`);
const pnpApi = require(`pnpapi`);
- const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
- const isPortal = str => str.startsWith("portal:/");
- const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
+ const isVirtual = (str) => str.match(/\/(\$\$virtual|__virtual__)\//);
+ const isPortal = (str) => str.startsWith('portal:/');
+ const normalize = (str) => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
- const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
- return `${locator.name}@${locator.reference}`;
- }));
+ const dependencyTreeRoots = new Set(
+ pnpApi.getDependencyTreeRoots().map((locator) => {
+ return `${locator.name}@${locator.reference}`;
+ })
+ );
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
// doesn't understand. This layer makes sure to remove the protocol
@@ -45,7 +47,10 @@ const moduleWrapper = tsserver => {
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
if (resolved) {
const locator = pnpApi.findPackageLocator(resolved);
- if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
+ if (
+ locator &&
+ (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))
+ ) {
str = resolved;
}
}
@@ -73,41 +78,55 @@ const moduleWrapper = tsserver => {
// Before | ^/zip/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
- case `vscode <1.61`: {
- str = `^zip:${str}`;
- } break;
+ case `vscode <1.61`:
+ {
+ str = `^zip:${str}`;
+ }
+ break;
- case `vscode <1.66`: {
- str = `^/zip/${str}`;
- } break;
+ case `vscode <1.66`:
+ {
+ str = `^/zip/${str}`;
+ }
+ break;
- case `vscode <1.68`: {
- str = `^/zip${str}`;
- } break;
+ case `vscode <1.68`:
+ {
+ str = `^/zip${str}`;
+ }
+ break;
- case `vscode`: {
- str = `^/zip/${str}`;
- } break;
+ case `vscode`:
+ {
+ str = `^/zip/${str}`;
+ }
+ break;
// To make "go to definition" work,
// We have to resolve the actual file system path from virtual path
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
- case `coc-nvim`: {
- str = normalize(resolved).replace(/\.zip\//, `.zip::`);
- str = resolve(`zipfile:${str}`);
- } break;
+ case `coc-nvim`:
+ {
+ str = normalize(resolved).replace(/\.zip\//, `.zip::`);
+ str = resolve(`zipfile:${str}`);
+ }
+ break;
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
// We have to resolve the actual file system path from virtual path,
// everything else is up to neovim
- case `neovim`: {
- str = normalize(resolved).replace(/\.zip\//, `.zip::`);
- str = `zipfile://${str}`;
- } break;
-
- default: {
- str = `zip:${str}`;
- } break;
+ case `neovim`:
+ {
+ str = normalize(resolved).replace(/\.zip\//, `.zip::`);
+ str = `zipfile://${str}`;
+ }
+ break;
+
+ default:
+ {
+ str = `zip:${str}`;
+ }
+ break;
}
} else {
str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`);
@@ -119,26 +138,30 @@ const moduleWrapper = tsserver => {
function fromEditorPath(str) {
switch (hostInfo) {
- case `coc-nvim`: {
- str = str.replace(/\.zip::/, `.zip/`);
- // The path for coc-nvim is in format of /