UNPKG

xchess

Version:

Chess Engine

357 lines (284 loc) 5.84 kB
export {BoardView} import {white, black} from './color.js' import {Piece} from './piece.js' import {King, Queen, Rook, Bishop, Knight, Pawn} from './standart-piece.js' import {PieceSet} from './piece-set.js' import {squares} from './square.js' import {inspect} from './inspect.js' import {Weight, Advantage, PiecesStat} from './piece-stat.js' import {InsertEvent, DeleteEvent, TransferEvent} from './events.js' class BoardView { #context; constructor(context){ this.#context = context; } get #board(){ return this.#context.board; } // read get size(){ return this.#board.size; } keys(){ return this.#board.keys(); } values(){ return this.#board.values(); } entries(){ return this.#board.entries(); } at(x, y){ return this.#board.at(x, y); } has(square){ return this.#board.has(square); } get(square){ return this.#board.get(square); } find(piece){ return this.#board.find(piece); } contains(piece){ return this.#board.contains(piece); } byColor(color){ const pieces = new PieceSet(); for(const piece of this.values()) if(piece.color.eq(color)) pieces.add(piece); return pieces; } white(){ return this.byColor(white); } black(){ return this.byColor(black); } // Stat get weight(){ return Weight(this.values()); } advantage(color){ return Advantage(this.values(), color); } stat(){ return PiecesStat(this.values()); } // I/O [inspect.custom](){ return `${this.constructor.name}(${this.size}) {}`; } * [Symbol.iterator](){ yield * this.#board; } toString(){ return this.fen; } hash(){ return this.#board.hash(); } toJSON(){ return this.#board.toJSON(); } text(opts){ return this.#board.text(opts); } log(opts){ this.#board.log(opts); } get fen(){ return this.#board.fen; } // write #access(){ this.#context.access(); } #onInsert(piece, square){ this.#context.dispatch(new InsertEvent(piece, square)); } #onDelete(piece, square){ this.#context.dispatch(new DeleteEvent(piece, square)); } #onTransfer(piece, from, to){ this.#context.dispatch(new TransferEvent(piece, from, to)); } set fen(fen){ this.#access(); const deleted = new Map(this.#board); this.#board.fen = fen; for(const [square, piece] of deleted) this.#onDelete(piece, square); for(const [square, piece] of this) this.#onInsert(piece, square); } setAll(board){ this.#access(); const deleted = new Map(this.#board); this.#board.setAll(board); for(const [square, piece] of deleted) this.#onDelete(piece, square); for(const [square, piece] of this) this.#onInsert(piece, square); } set(square, piece){ this.#access(); const report = this.#board.set(square, piece); if(report.deleted) this.#onDelete(report.deleted, report.to); if(report.inserted) this.#onInsert(report.inserted, report.to); if(report.moved) this.#onTransfer(report.moved, report.from, report.to); return report; } move(from, to){ this.#access(); const report = this.#board.move(from, to); if(report.deleted) this.#onDelete(report.deleted, report.to); if(report.moved) this.#onTransfer(report.moved, report.from, report.to); return report; } delete(square){ this.#access(); const {change, from, deleted} = this.#board.delete(square); if(change){ this.#onDelete(deleted, from); return {change, from, deleted}; } return {change}; } clear(){ this.#access(); const board = new Map(this.#board); const count = this.#board.clear(); for(const [square, piece] of board) this.#onDelete(piece, square); return count; } // Piece king(square, color){ const piece = new King(color); this.set(square, piece); return piece; } queen(square, color){ const piece = new Queen(color); this.set(square, piece); return piece; } rook(square, color){ const piece = new Rook(color); this.set(square, piece); return piece; } bishop(square, color){ const piece = new Bishop(color); this.set(square, piece); return piece; } knight(square, color){ const piece = new Knight(color); this.set(square, piece); return piece; } pawn(square, color){ const piece = new Pawn(color); this.set(square, piece); return piece; } k(square){ return this.king(square, black); } q(square){ return this.queen(square, black); } r(square){ return this.rook(square, black); } b(square){ return this.bishop(square, black); } n(square){ return this.knight(square, black); } p(square){ return this.pawn(square, black); } K(square){ return this.king(square, white); } Q(square){ return this.queen(square, white); } R(square){ return this.rook(square, white); } B(square){ return this.bishop(square, white); } N(square){ return this.knight(square, white); } P(square){ return this.pawn(square, white); } setup(){ this.clear(); // Black this.r('a8'); this.n('b8'); this.b('c8'); this.q('d8'); this.k('e8'); this.b('f8'); this.n('g8'); this.r('h8'); this.p('a7'); this.p('b7'); this.p('c7'); this.p('d7'); this.p('e7'); this.p('f7'); this.p('g7'); this.p('h7'); // White this.P('a2'); this.P('b2'); this.P('c2'); this.P('d2'); this.P('e2'); this.P('f2'); this.P('g2'); this.P('h2'); this.R('a1'); this.N('b1'); this.B('c1'); this.Q('d1'); this.K('e1'); this.B('f1'); this.N('g1'); this.R('h1'); return this; } sample(){ for(const square of squares){ (Math.random() < 0.5) ? this.delete(square) : this.set(square, Piece.rand()); } } gist(){ const gist = Array(squares.length); gist.fill(0); let gap = 0; for(const square of squares){ if(this.has(square)){ if(gap > 0) gist[gap - 1] ++; gap = 0; } else gap ++; } if(gap > 0) gist[gap] ++; return gist; } }