UNPKG

xchess

Version:

Chess Engine

350 lines (264 loc) 4.8 kB
export {Piece, King, Queen, Rook, Bishop, Knight, Pawn} import {Color, white, black} from './color.js' import * as pawn from './pawn.js' import {IS_STRING} from './types.js' import { INVALID_PIECE, INVALID_PIECE_COLOR, } from './errors.js' const Types = new Map(); const ColorTypes = new Map(); function InitTypes(... types){ for(const type of types) AddType(type); } function AddType(Type){ Types.set(Type.char.toLowerCase(), Type); Types.set(Type.name.toLowerCase(), Type); AddTypeColor(Type, white); AddTypeColor(Type, black); } function AddTypeColor(Type, Color){ const Creator = PieceCreator(Type, Color); ColorTypes.set(Color.codeOf(Type.code), Creator); ColorTypes.set(Type.signs[+ Color], Creator); ColorTypes.set(Color.fenOf(Type.char), Creator); } function PieceCreator(Type, Color){ return () => new Type(Color); } function from(value){ if(Piece.is(value)) return value; const Create = ColorTypes.get(value); if(Create) return Create(); throw INVALID_PIECE(value); } function fromColor(value, color){ if(Piece.is(value)){ if(value.color.eq(color)) return value; throw INVALID_PIECE_COLOR(value.color); } if(IS_STRING(value)){ const Type = Types.get(value.toLowerCase()); if(Type) return new Type(color); } throw INVALID_PIECE(value); } class Piece { static is(value){ return value instanceof this; } static validate(value){ if(this.is(value)) return value; throw INVALID_PIECE(value); } static from(value){ return from(value); } static fromColor(value, color){ return fromColor(value, color); } static get code(){ return NaN; } static get char(){ return '�'; } static get signs(){ return '��'; } static get weight(){ return 0; } #color; constructor(color){ this.#color = Color.from(color); } get color(){ return this.#color; } get code(){ return this.color.codeOf(this.constructor.code); } get name(){ return this.constructor.name; } get sign(){ return this.constructor.signs[+ this.color]; } get char(){ return this.constructor.char; } get fen(){ return this.color.fenOf(this.char); } get moveLetter(){ return this.char; } get weight(){ return this.constructor.weight; } valueOf(){ return this.code; } toString(){ return this.sign; } toJSON(){ return this.fen; } clone(){ return new this.constructor(this.color); } // rules opposite(piece){ const target = Piece.from(piece); return this.color.opposite(target.color); } moves(context){ const moves = []; const {board} = context; for(const move of this.allMoves(context)) if(!move.check(board)) moves.push(move); return moves; } allMoves(context){ return []; } test(target, board){ return false; } } class King extends Piece { static get code(){ return 0; } static get char(){ return 'K'; } static get signs(){ return '♔♚'; } // rules allMoves(context){ return [ ... context.board.near(this), ... context.castling.moves(context), ]; } test(target, board){ return board.isNear(this, target); } } class Queen extends Piece { static get code(){ return 1; } static get char(){ return 'Q'; } static get signs(){ return '♕♛'; } static get weight(){ return 9; } // rules allMoves(context){ return context.board.traceAll(this); } test(target, board){ return board.crossAny(this, target); } } class Rook extends Piece { static get code(){ return 2; } static get char(){ return 'R'; } static get signs(){ return '♖♜'; } static get weight(){ return 5; } // rules allMoves(context){ return context.board.traceT(this); } test(target, board){ return board.crossT(this, target); } } class Bishop extends Piece { static get code(){ return 3; } static get char(){ return 'B'; } static get signs(){ return '♗♝'; } static get weight(){ return 3; } // rules allMoves(context){ return context.board.traceX(this); } test(target, board){ return board.crossX(this, target); } } class Knight extends Piece { static get code(){ return 4; } static get char(){ return 'N'; } static get signs(){ return '♘♞'; } static get weight(){ return 3; } // rules allMoves(context){ return context.board.L(this); } test(target, board){ return board.isL(this, target); } } class Pawn extends Piece { static get code(){ return 5; } static get char(){ return 'P'; } static get signs(){ return '♙♟'; } get moveLetter(){ return ''; } static get weight(){ return 1; } // rules allMoves(context){ return [... pawn.allMoves(this, context)]; } test(target, board){ return pawn.test(this, target, board); } } InitTypes(King, Queen, Rook, Bishop, Knight, Pawn);