import * as visuals from './visuals.js'; function setupBoard() { let pawns = []; for (let x of 'abcdefgh') { pawns.push(new Piece('pawn', 'black', `${x}7`), new Piece('pawn', 'white', `${x}2`)); } return new Configuration([ new Piece('rook', 'black', 'a8'), new Piece('rook', 'black', 'h8'), new Piece('knight', 'black', 'b8'), new Piece('knight', 'black', 'g8'), new Piece('bishop', 'black', 'c8'), new Piece('bishop', 'black', 'f8'), new Piece('queen', 'black', 'd8'), new Piece('king', 'black', 'e8'), ...pawns, new Piece('rook', 'white', 'a1'), new Piece('rook', 'white', 'h1'), new Piece('knight', 'white', 'b1'), new Piece('knight', 'white', 'g1'), new Piece('bishop', 'white', 'c1'), new Piece('bishop', 'white', 'f1'), new Piece('queen', 'white', 'd1'), new Piece('king', 'white', 'e1'), ]); } class Backend { constructor() { this.config = setupBoard(); } getConfig() { return this.config.clone(); } makeMove(move) { this.config = this.config.makeMove(move); return this.config.clone(); } getAvailableMoves(position) { return [] } } class Chess { constructor() { this.backend = new Backend(); this.configVis = null; this.canvas = new visuals.Canvas(); this.moveSource = null; this.canMoveTo = []; this.syncBackend(); document.onclick = (ev) => this.click(ev); } syncBackend() { let config = this.backend.getConfig(); if (this.configVis !== null) { this.configVis.undraw(); } this.configVis = new visuals.ConfigVis(config.pieces); this.configVis.draw(this.canvas); } showAvailableMoves(canMoveTo) { } click(ev) { if (this.moveSource === null) { this._firstClick(ev); } else { this._secondClick(ev); } } _firstClick(ev) { let rcA = this.canvas.screenCoordsToRowCol(ev.clientX, ev.clientY); if (rcA === null) return; let positionA = visuals.rowColToBoardIndex(...rcA); this.showAvailableMoves(this.backend.getAvailableMoves(positionA)); this.moveSource = positionA; } _secondClick(ev) { let rcB = this.canvas.screenCoordsToRowCol(ev.clientX, ev.clientY); if (rcB !== null) { let move = { from: this.moveSource, to: visuals.rowColToBoardIndex(...rcB), } this.backend.makeMove(move); this.syncBackend(); } this.moveSource = null; } } class Move { constructor(kind, from, to) { this.kind = kind; this.from = from; this.to = to; } } class Piece { constructor(who, color, position) { this.who = who; this.color = color; this.position = position; } clone() { return new Piece(this.who, this.color, this.position); } moveTo(position) { return new Piece(this.who, this.color, position); } } class Configuration { constructor(pieces) { this.pieces = pieces } clone() { let pieces = []; for (let piece of this.pieces) { pieces.push(piece.clone()); } return new Configuration(pieces); } getAt(position) { return this.pieces.find(piece => piece.position === position) || null; } dropAt(position) { return new Configuration( this.pieces.filter(piece => piece.position !== position) ); } makeMove(move) { const pieceToMove = this.getAt(move.from); if (pieceToMove === null) return this; else return new Configuration([ ...(this.dropAt(move.from).dropAt(move.to).pieces), pieceToMove.moveTo(move.to) ]) } } new Chess();