diff --git a/public/engines/lc0-js/MaiaWeights/maia-1100.pb.gz b/public/engines/lc0-js/MaiaWeights/maia-1100.pb.gz new file mode 100644 index 00000000..10838269 Binary files /dev/null and b/public/engines/lc0-js/MaiaWeights/maia-1100.pb.gz differ diff --git a/public/engines/lc0-js/MaiaWeights/maia-1300.pb.gz b/public/engines/lc0-js/MaiaWeights/maia-1300.pb.gz new file mode 100644 index 00000000..97181c6c Binary files /dev/null and b/public/engines/lc0-js/MaiaWeights/maia-1300.pb.gz differ diff --git a/public/engines/lc0-js/MaiaWeights/maia-1400.pb.gz b/public/engines/lc0-js/MaiaWeights/maia-1400.pb.gz new file mode 100644 index 00000000..4c2c9ccc Binary files /dev/null and b/public/engines/lc0-js/MaiaWeights/maia-1400.pb.gz differ diff --git a/public/engines/lc0-js/MaiaWeights/maia-1500.pb.gz b/public/engines/lc0-js/MaiaWeights/maia-1500.pb.gz new file mode 100644 index 00000000..651551e2 Binary files /dev/null and b/public/engines/lc0-js/MaiaWeights/maia-1500.pb.gz differ diff --git a/public/engines/lc0-js/MaiaWeights/maia-1600.pb.gz b/public/engines/lc0-js/MaiaWeights/maia-1600.pb.gz new file mode 100644 index 00000000..a5fcec72 Binary files /dev/null and b/public/engines/lc0-js/MaiaWeights/maia-1600.pb.gz differ diff --git a/public/engines/lc0-js/MaiaWeights/maia-1700.pb.gz b/public/engines/lc0-js/MaiaWeights/maia-1700.pb.gz new file mode 100644 index 00000000..ab4208a7 Binary files /dev/null and b/public/engines/lc0-js/MaiaWeights/maia-1700.pb.gz differ diff --git a/public/engines/lc0-js/MaiaWeights/maia-1800.pb.gz b/public/engines/lc0-js/MaiaWeights/maia-1800.pb.gz new file mode 100644 index 00000000..431bb241 Binary files /dev/null and b/public/engines/lc0-js/MaiaWeights/maia-1800.pb.gz differ diff --git a/public/engines/lc0-js/MaiaWeights/maia-1900.pb.gz b/public/engines/lc0-js/MaiaWeights/maia-1900.pb.gz new file mode 100644 index 00000000..52d22a82 Binary files /dev/null and b/public/engines/lc0-js/MaiaWeights/maia-1900.pb.gz differ diff --git a/public/engines/lc0-js/chessboard-0.3.0.css b/public/engines/lc0-js/chessboard-0.3.0.css new file mode 100644 index 00000000..09104a65 --- /dev/null +++ b/public/engines/lc0-js/chessboard-0.3.0.css @@ -0,0 +1,70 @@ +/*! + * chessboard.js v0.3.0 + * + * Copyright 2013 Chris Oakman + * Released under the MIT license + * https://github.com/oakmac/chessboardjs/blob/master/LICENSE + * + * Date: 10 Aug 2013 + */ + +/* clearfix */ +.clearfix-7da63 { + clear: both; +} + +/* board */ +.board-b72b1 { + border: 2px solid #404040; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +/* square */ +.square-55d63 { + float: left; + position: relative; + + /* disable any native browser highlighting */ + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* white square */ +.white-1e1d7 { + background-color: #f0d9b5; + color: #b58863; +} + +/* black square */ +.black-3c85d { + background-color: #b58863; + color: #f0d9b5; +} + +/* highlighted square */ +.highlight1-32417, .highlight2-9c5d2 { + -webkit-box-shadow: inset 0 0 3px 3px yellow; + -moz-box-shadow: inset 0 0 3px 3px yellow; + box-shadow: inset 0 0 3px 3px yellow; +} + +/* notation */ +.notation-322f9 { + cursor: default; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + position: absolute; +} +.alpha-d2270 { + bottom: 1px; + right: 3px; +} +.numeric-fc462 { + top: 2px; + left: 2px; +} \ No newline at end of file diff --git a/public/engines/lc0-js/chessboard-0.3.0.js b/public/engines/lc0-js/chessboard-0.3.0.js new file mode 100644 index 00000000..8f1ac2d4 --- /dev/null +++ b/public/engines/lc0-js/chessboard-0.3.0.js @@ -0,0 +1,1714 @@ +/*! + * chessboard.js v0.3.0 + * + * Copyright 2013 Chris Oakman + * Released under the MIT license + * http://chessboardjs.com/license + * + * Date: 10 Aug 2013 + */ + +// start anonymous scope +;(function() { +'use strict'; + +//------------------------------------------------------------------------------ +// Chess Util Functions +//------------------------------------------------------------------------------ +var COLUMNS = 'abcdefgh'.split(''); + +function validMove(move) { + // move should be a string + if (typeof move !== 'string') return false; + + // move should be in the form of "e2-e4", "f6-d5" + var tmp = move.split('-'); + if (tmp.length !== 2) return false; + + return (validSquare(tmp[0]) === true && validSquare(tmp[1]) === true); +} + +function validSquare(square) { + if (typeof square !== 'string') return false; + return (square.search(/^[a-h][1-8]$/) !== -1); +} + +function validPieceCode(code) { + if (typeof code !== 'string') return false; + return (code.search(/^[bw][KQRNBP]$/) !== -1); +} + +// TODO: this whole function could probably be replaced with a single regex +function validFen(fen) { + if (typeof fen !== 'string') return false; + + // cut off any move, castling, etc info from the end + // we're only interested in position information + fen = fen.replace(/ .+$/, ''); + + // FEN should be 8 sections separated by slashes + var chunks = fen.split('/'); + if (chunks.length !== 8) return false; + + // check the piece sections + for (var i = 0; i < 8; i++) { + if (chunks[i] === '' || + chunks[i].length > 8 || + chunks[i].search(/[^kqrbnpKQRNBP1-8]/) !== -1) { + return false; + } + } + + return true; +} + +function validPositionObject(pos) { + if (typeof pos !== 'object') return false; + + for (var i in pos) { + if (pos.hasOwnProperty(i) !== true) continue; + + if (validSquare(i) !== true || validPieceCode(pos[i]) !== true) { + return false; + } + } + + return true; +} + +// convert FEN piece code to bP, wK, etc +function fenToPieceCode(piece) { + // black piece + if (piece.toLowerCase() === piece) { + return 'b' + piece.toUpperCase(); + } + + // white piece + return 'w' + piece.toUpperCase(); +} + +// convert bP, wK, etc code to FEN structure +function pieceCodeToFen(piece) { + var tmp = piece.split(''); + + // white piece + if (tmp[0] === 'w') { + return tmp[1].toUpperCase(); + } + + // black piece + return tmp[1].toLowerCase(); +} + +// convert FEN string to position object +// returns false if the FEN string is invalid +function fenToObj(fen) { + if (validFen(fen) !== true) { + return false; + } + + // cut off any move, castling, etc info from the end + // we're only interested in position information + fen = fen.replace(/ .+$/, ''); + + var rows = fen.split('/'); + var position = {}; + + var currentRow = 8; + for (var i = 0; i < 8; i++) { + var row = rows[i].split(''); + var colIndex = 0; + + // loop through each character in the FEN section + for (var j = 0; j < row.length; j++) { + // number / empty squares + if (row[j].search(/[1-8]/) !== -1) { + var emptySquares = parseInt(row[j], 10); + colIndex += emptySquares; + } + // piece + else { + var square = COLUMNS[colIndex] + currentRow; + position[square] = fenToPieceCode(row[j]); + colIndex++; + } + } + + currentRow--; + } + + return position; +} + +// position object to FEN string +// returns false if the obj is not a valid position object +function objToFen(obj) { + if (validPositionObject(obj) !== true) { + return false; + } + + var fen = ''; + + var currentRow = 8; + for (var i = 0; i < 8; i++) { + for (var j = 0; j < 8; j++) { + var square = COLUMNS[j] + currentRow; + + // piece exists + if (obj.hasOwnProperty(square) === true) { + fen += pieceCodeToFen(obj[square]); + } + + // empty space + else { + fen += '1'; + } + } + + if (i !== 7) { + fen += '/'; + } + + currentRow--; + } + + // squeeze the numbers together + // haha, I love this solution... + fen = fen.replace(/11111111/g, '8'); + fen = fen.replace(/1111111/g, '7'); + fen = fen.replace(/111111/g, '6'); + fen = fen.replace(/11111/g, '5'); + fen = fen.replace(/1111/g, '4'); + fen = fen.replace(/111/g, '3'); + fen = fen.replace(/11/g, '2'); + + return fen; +} + +window['ChessBoard'] = window['ChessBoard'] || function(containerElOrId, cfg) { +'use strict'; + +cfg = cfg || {}; + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +var MINIMUM_JQUERY_VERSION = '1.7.0', + START_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR', + START_POSITION = fenToObj(START_FEN); + +// use unique class names to prevent clashing with anything else on the page +// and simplify selectors +var CSS = { + alpha: 'alpha-d2270', + black: 'black-3c85d', + board: 'board-b72b1', + chessboard: 'chessboard-63f37', + clearfix: 'clearfix-7da63', + highlight1: 'highlight1-32417', + highlight2: 'highlight2-9c5d2', + notation: 'notation-322f9', + numeric: 'numeric-fc462', + piece: 'piece-417db', + row: 'row-5277c', + sparePieces: 'spare-pieces-7492f', + sparePiecesBottom: 'spare-pieces-bottom-ae20f', + sparePiecesTop: 'spare-pieces-top-4028b', + square: 'square-55d63', + white: 'white-1e1d7' +}; + +//------------------------------------------------------------------------------ +// Module Scope Variables +//------------------------------------------------------------------------------ + +// DOM elements +var containerEl, + boardEl, + draggedPieceEl, + sparePiecesTopEl, + sparePiecesBottomEl; + +// constructor return object +var widget = {}; + +//------------------------------------------------------------------------------ +// Stateful +//------------------------------------------------------------------------------ + +var ANIMATION_HAPPENING = false, + BOARD_BORDER_SIZE = 2, + CURRENT_ORIENTATION = 'white', + CURRENT_POSITION = {}, + SQUARE_SIZE, + DRAGGED_PIECE, + DRAGGED_PIECE_LOCATION, + DRAGGED_PIECE_SOURCE, + DRAGGING_A_PIECE = false, + SPARE_PIECE_ELS_IDS = {}, + SQUARE_ELS_IDS = {}, + SQUARE_ELS_OFFSETS; + +//------------------------------------------------------------------------------ +// JS Util Functions +//------------------------------------------------------------------------------ + +// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript +function createId() { + return 'xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'.replace(/x/g, function(c) { + var r = Math.random() * 16 | 0; + return r.toString(16); + }); +} + +function deepCopy(thing) { + return JSON.parse(JSON.stringify(thing)); +} + +function parseSemVer(version) { + var tmp = version.split('.'); + return { + major: parseInt(tmp[0], 10), + minor: parseInt(tmp[1], 10), + patch: parseInt(tmp[2], 10) + }; +} + +// returns true if version is >= minimum +function compareSemVer(version, minimum) { + version = parseSemVer(version); + minimum = parseSemVer(minimum); + + var versionNum = (version.major * 10000 * 10000) + + (version.minor * 10000) + version.patch; + var minimumNum = (minimum.major * 10000 * 10000) + + (minimum.minor * 10000) + minimum.patch; + + return (versionNum >= minimumNum); +} + +//------------------------------------------------------------------------------ +// Validation / Errors +//------------------------------------------------------------------------------ + +function error(code, msg, obj) { + // do nothing if showErrors is not set + if (cfg.hasOwnProperty('showErrors') !== true || + cfg.showErrors === false) { + return; + } + + var errorText = 'ChessBoard Error ' + code + ': ' + msg; + + // print to console + if (cfg.showErrors === 'console' && + typeof console === 'object' && + typeof console.log === 'function') { + console.log(errorText); + if (arguments.length >= 2) { + console.log(obj); + } + return; + } + + // alert errors + if (cfg.showErrors === 'alert') { + if (obj) { + errorText += '\n\n' + JSON.stringify(obj); + } + window.alert(errorText); + return; + } + + // custom function + if (typeof cfg.showErrors === 'function') { + cfg.showErrors(code, msg, obj); + } +} + +// check dependencies +function checkDeps() { + // if containerId is a string, it must be the ID of a DOM node + if (typeof containerElOrId === 'string') { + // cannot be empty + if (containerElOrId === '') { + window.alert('ChessBoard Error 1001: ' + + 'The first argument to ChessBoard() cannot be an empty string.' + + '\n\nExiting...'); + return false; + } + + // make sure the container element exists in the DOM + var el = document.getElementById(containerElOrId); + if (! el) { + window.alert('ChessBoard Error 1002: Element with id "' + + containerElOrId + '" does not exist in the DOM.' + + '\n\nExiting...'); + return false; + } + + // set the containerEl + containerEl = $(el); + } + + // else it must be something that becomes a jQuery collection + // with size 1 + // ie: a single DOM node or jQuery object + else { + containerEl = $(containerElOrId); + + if (containerEl.length !== 1) { + window.alert('ChessBoard Error 1003: The first argument to ' + + 'ChessBoard() must be an ID or a single DOM node.' + + '\n\nExiting...'); + return false; + } + } + + // JSON must exist + if (! window.JSON || + typeof JSON.stringify !== 'function' || + typeof JSON.parse !== 'function') { + window.alert('ChessBoard Error 1004: JSON does not exist. ' + + 'Please include a JSON polyfill.\n\nExiting...'); + return false; + } + + // check for a compatible version of jQuery + if (! (typeof window.$ && $.fn && $.fn.jquery && + compareSemVer($.fn.jquery, MINIMUM_JQUERY_VERSION) === true)) { + window.alert('ChessBoard Error 1005: Unable to find a valid version ' + + 'of jQuery. Please include jQuery ' + MINIMUM_JQUERY_VERSION + ' or ' + + 'higher on the page.\n\nExiting...'); + return false; + } + + return true; +} + +function validAnimationSpeed(speed) { + if (speed === 'fast' || speed === 'slow') { + return true; + } + + if ((parseInt(speed, 10) + '') !== (speed + '')) { + return false; + } + + return (speed >= 0); +} + +// validate config / set default options +function expandConfig() { + if (typeof cfg === 'string' || validPositionObject(cfg) === true) { + cfg = { + position: cfg + }; + } + + // default for orientation is white + if (cfg.orientation !== 'black') { + cfg.orientation = 'white'; + } + CURRENT_ORIENTATION = cfg.orientation; + + // default for showNotation is true + if (cfg.showNotation !== false) { + cfg.showNotation = true; + } + + // default for draggable is false + if (cfg.draggable !== true) { + cfg.draggable = false; + } + + // default for dropOffBoard is 'snapback' + if (cfg.dropOffBoard !== 'trash') { + cfg.dropOffBoard = 'snapback'; + } + + // default for sparePieces is false + if (cfg.sparePieces !== true) { + cfg.sparePieces = false; + } + + // draggable must be true if sparePieces is enabled + if (cfg.sparePieces === true) { + cfg.draggable = true; + } + + // default piece theme is wikipedia + if (cfg.hasOwnProperty('pieceTheme') !== true || + (typeof cfg.pieceTheme !== 'string' && + typeof cfg.pieceTheme !== 'function')) { + cfg.pieceTheme = 'img/chesspieces/wikipedia/{piece}.png'; + } + + // animation speeds + if (cfg.hasOwnProperty('appearSpeed') !== true || + validAnimationSpeed(cfg.appearSpeed) !== true) { + cfg.appearSpeed = 200; + } + if (cfg.hasOwnProperty('moveSpeed') !== true || + validAnimationSpeed(cfg.moveSpeed) !== true) { + cfg.moveSpeed = 200; + } + if (cfg.hasOwnProperty('snapbackSpeed') !== true || + validAnimationSpeed(cfg.snapbackSpeed) !== true) { + cfg.snapbackSpeed = 50; + } + if (cfg.hasOwnProperty('snapSpeed') !== true || + validAnimationSpeed(cfg.snapSpeed) !== true) { + cfg.snapSpeed = 25; + } + if (cfg.hasOwnProperty('trashSpeed') !== true || + validAnimationSpeed(cfg.trashSpeed) !== true) { + cfg.trashSpeed = 100; + } + + // make sure position is valid + if (cfg.hasOwnProperty('position') === true) { + if (cfg.position === 'start') { + CURRENT_POSITION = deepCopy(START_POSITION); + } + + else if (validFen(cfg.position) === true) { + CURRENT_POSITION = fenToObj(cfg.position); + } + + else if (validPositionObject(cfg.position) === true) { + CURRENT_POSITION = deepCopy(cfg.position); + } + + else { + error(7263, 'Invalid value passed to config.position.', cfg.position); + } + } + + return true; +} + +//------------------------------------------------------------------------------ +// DOM Misc +//------------------------------------------------------------------------------ + +// calculates square size based on the width of the container +// got a little CSS black magic here, so let me explain: +// get the width of the container element (could be anything), reduce by 1 for +// fudge factor, and then keep reducing until we find an exact mod 8 for +// our square size +function calculateSquareSize() { + var containerWidth = parseInt(containerEl.css('width'), 10); + + // defensive, prevent infinite loop + if (! containerWidth || containerWidth <= 0) { + return 0; + } + + // pad one pixel + var boardWidth = containerWidth - 1; + + while (boardWidth % 8 !== 0 && boardWidth > 0) { + boardWidth--; + } + + return (boardWidth / 8); +} + +// create random IDs for elements +function createElIds() { + // squares on the board + for (var i = 0; i < COLUMNS.length; i++) { + for (var j = 1; j <= 8; j++) { + var square = COLUMNS[i] + j; + SQUARE_ELS_IDS[square] = square + '-' + createId(); + } + } + + // spare pieces + var pieces = 'KQRBNP'.split(''); + for (var i = 0; i < pieces.length; i++) { + var whitePiece = 'w' + pieces[i]; + var blackPiece = 'b' + pieces[i]; + SPARE_PIECE_ELS_IDS[whitePiece] = whitePiece + '-' + createId(); + SPARE_PIECE_ELS_IDS[blackPiece] = blackPiece + '-' + createId(); + } +} + +//------------------------------------------------------------------------------ +// Markup Building +//------------------------------------------------------------------------------ + +function buildBoardContainer() { + var html = '
+Lc0-js by The LCZero Authors. +JavaScript chessboard powered by chessboard.js and chess.js. +Neural network accelerated by tensorflowjs. +
+