UNPKG

chess

Version:

An algebraic notation driven chess engine that can validate board position and produce a list of viable moves (notated).

101 lines (83 loc) 2.29 kB
/** GameValidation is the 3rd phase of validation for the game and is intended to support Game level events. Examples of Game scope validation include Check, Checkmate, 3-fold position repetition and pawn promotion. */ import { BoardValidation } from './boardValidation.js'; import { PieceType } from './piece.js'; export class GameValidation { constructor (game) { this.game = game; } static create (game) { return new GameValidation(game); } findKingSquare (side) { let i = 0, squares = this.game.board.getSquares(side); for (i = 0; i < squares.length; i++) { if (squares[i].piece.type === PieceType.King) { return squares[i]; } } } isRepetition () { let hash = '', hashCount = [], i = 0; // analyze 3-fold repetition (draw) for (i = 0; i < this.game.moveHistory.length; i++) { hash = this.game.moveHistory[i].hashCode; hashCount[hash] = hashCount[hash] ? hashCount[hash] + 1 : 1; /* eslint no-magic-numbers: 0 */ if (hashCount[hash] === 3) { return true; } } return false; } start (callback) { // ensure callback is set callback = callback || ((err, result) => new Promise((resolve, reject) => { if (err) { return reject(err); } return resolve(result); })); let kingSquare = null, result = { isCheck : false, isCheckmate : false, isFiftyMoveDraw : false, isRepetition : false, isStalemate : false, validMoves : [] }, setResult = (v, result, isKingAttacked) => { return (err, validMoves) => { if (err) { return callback(err); } result.isCheck = isKingAttacked && validMoves.length > 0; result.isCheckmate = isKingAttacked && validMoves.length === 0; result.isStalemate = !isKingAttacked && validMoves.length === 0; result.isRepetition = v.isRepetition(); result.validMoves = validMoves; return callback(null, result); }; }, v = BoardValidation.create(this.game); if (this.game) { // find current side king square kingSquare = this.findKingSquare(this.game.getCurrentSide()); // find valid moves return v.start(setResult(this, result, v.isSquareAttacked(kingSquare))); } return callback(new Error('game is invalid')); } } export default { GameValidation };