Files
chess/frontend/main.js
2021-11-08 21:55:51 +01:00

150 lines
3.5 KiB
JavaScript

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();