UNPKG

xchess

Version:

Chess Engine

457 lines (362 loc) 6.93 kB
export {GameContext} import {Emitter} from './emitter.js' import {RestoreEvent} from './events.js' import {Board} from './board.js' import {PieceSet} from './piece-set.js' import {SetupState} from './setup-state.js' import {StateCounter} from './state-counter.js' class GameContext extends Emitter { #game; #board = new Board(); #captureList = new PieceSet(); #stateCounter = new StateCounter(); first = null; state = new SetupState(this); constructor(game){ super(); this.#game = game; } get game(){ return this.#game; } get prev(){ return this.state.prev; } get next(){ return this.state.next; } get board(){ return this.#board; } get captureList(){ return this.#captureList; } get stateCounter(){ return this.#stateCounter; } get current(){ return this.state.handler; } get time(){ return this.state.time; } get count(){ return this.state.count; } get fullmoveNumber(){ return this.state.fullmoveNumber; } get halfmoveClock(){ return this.state.halfmoveClock; } get color(){ return this.state.color; } get gameColor(){ return this.state.gameColor; } get doubleMovePawn(){ return this.state.doubleMovePawn; } get enPassantTarget(){ return this.state.enPassantTarget; } get castling(){ return this.state.castling; } get prevCastling(){ return this.state.prevCastling; } get wk(){ return this.state.wk; } get wq(){ return this.state.wq; } get bk(){ return this.state.bk; } get bq(){ return this.state.bq; } get lastMove(){ return this.state.lastMove; } get moves(){ return this.state.moves; } get isCheck(){ return this.state.isCheck; } get checkKing(){ return this.state.checkKing; } get checkKingTarget(){ return this.state.checkKingTarget; } get hash(){ return this.state.hash; } get repetition(){ return this.state.repetition; } get newRepetition(){ return this.state.newRepetition; } get ownRepetition(){ return this.state.ownRepetition; } get drawOffer(){ return this.state.drawOffer; } set drawOffer(drawOffer){ this.state.setDrawOffer(drawOffer); } // Setup access(){ this.state.access(); } change(){ this.emit('change'); } setAll(config){ this.state.setAll(config); } set board(board){ this.state.setBoard(board); this.change(); } set captureList(pieceList){ this.state.setCaptureList(pieceList); this.change(); } set count(count){ this.state.setCount(count); this.change(); } set fullmoveNumber(value){ this.state.setFullmoveNumber(value); this.change(); } set halfmoveClock(value){ this.state.setHalfmoveClock(value); this.change(); } set color(color){ this.state.setColor(color); this.change(); } set doubleMovePawn(pawn){ this.state.setDoubleMovePawn(pawn); this.change(); } set enPassantTarget(square){ this.state.setEnPassantTarget(square); this.change(); } set wk(value){ this.state.setWK(value); this.change(); } set wq(value){ this.state.setWQ(value); this.change(); } set bk(value){ this.state.setBK(value); this.change(); } set bq(value){ this.state.setBQ(value); this.change(); } // Stat stat(){ return { state: this.state, prev: this.prev, next: this.next, target: this.state.target, status: this.status, time: this.time, board: this.board, captureList: this.captureList, stateCounter: this.stateCounter, hash: this.hash, color: this.color, count: this.count, fullmoveNumber: this.fullmoveNumber, halfmoveClock: this.halfmoveClock, repetition: this.repetition, ownRepetition: this.ownRepetition, newRepetition: this.newRepetition, doubleMovePawn: this.doubleMovePawn, castling: this.castling, prevCastling: this.prevCastling, drawOffer: this.drawOffer, lastMove: this.lastMove, moves: this.moves, isCheck: this.isCheck, result: this.result, winner: this.winner, loser: this.loser, subject: this.subject, }; } get status(){ return this.state.status; } get isSetup(){ return this.state.isSetup; } get isMovement(){ return this.state.isMovement; } get isPromotion(){ return this.state.isPromotion; } get isDrawOffer(){ return this.state.isDrawOffer; } get isEnd(){ return this.state.isEnd; } get isWin(){ return this.state.isWin; } get isDraw(){ return this.state.isDraw; } get isImmediate(){ return this.state.isImmediate; } get isCheckmate(){ return this.state.isCheckmate; } get isStalemate(){ return this.state.isStalemate; } get winner(){ return this.state.winner; } get loser(){ return this.state.loser; } get subject(){ return this.state.subject; } get result(){ return this.state.result; } // I/O get fen(){ return this.state.fen; } set fen(fen){ this.state.setFEN(fen); this.change(); } // Events dispatch(event){ this.game.dispatchEvent(event); } emit(type){ this.dispatch(new Event(type)); } // Rules isDeadPosition(){ return this.board.isDeadPosition(); } isCheckmateChance(color){ return this.board.isCheckmateChance(color); } // Game Events play(){ return this.state.play(); } forfeit(color){ return this.state.forfeit(color); } resign(color){ return this.state.resign(color); } draw(color){ return this.state.draw(color); } toDraw(color){ return this.state.toDraw(color); } flagFall(){ return this.state.flagFall(); } move(move){ return this.state.move(move); } promote(piece){ return this.state.promote(piece); } // Log Events restore(count){ this.dispatch(new RestoreEvent(count)); } undo(){ const prev = this.prev; if(prev){ this.state.undo(); this.state = prev; this.emit('undo'); this.restore(-1); return true; } return false; } redo(){ const next = this.next; if(next){ this.state = next; this.state.redo(); this.emit('redo'); this.restore(1); return true; } return false; } go(countVal){ const count = Math.trunc(countVal); if(count){ let cursor = 0, state = this.state; while(cursor < count && (state = state.next)){ this.state = state; this.state.redo(); cursor ++; } while(cursor > count && (state = state.prev)){ this.state.undo(); this.state = state; cursor --; } if(cursor){ this.restore(cursor); return cursor; } } return 0; } goto(offsetVal){ const offset = Math.trunc(offsetVal); if(offset != this.count){ let state = this.state; const beginCount = this.count; while(this.count < offset && (state = state.next)){ this.state = state; this.state.redo(); } while(this.count > offset && (state = state.prev)){ this.state.undo(); this.state = state; } if(this.count !== beginCount){ const result = this.count - beginCount; this.restore(result); return result; } } return 0; } }