Files
chess/frontend/main.js
2022-01-05 22:10:04 +01:00

121 lines
3.3 KiB
JavaScript

import * as visuals from "./visuals.js";
function get_json(url) {
var request = new XMLHttpRequest();
request.open("get", url, false);
request.send(null);
return JSON.parse(request.responseText);
}
function post_json(url, json) {
var request = new XMLHttpRequest();
request.open("post", url, false);
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.send(JSON.stringify(json));
if (request.status != 200) return null;
return JSON.parse(request.responseText);
}
class Backend {
getConfig() {
return new Map(
Object.entries(get_json("http://localhost:3000/get_state/"))
);
}
makeMove(source, target) {
return post_json("http://localhost:3000/make_move/", [source, target]);
}
chooseMove(color) {
return post_json("http://localhost:3000/choose_move/", color);
}
getAvailableMoves(position) {
return post_json("http://localhost:3000/get_moves/", position);
}
reset() {
return post_json("http://localhost:3000/reset/");
}
}
class Chess {
constructor() {
this.backend = new Backend();
this.canvas = new visuals.Canvas();
this.autoplay = false;
this.button = document.createElement("button");
this.button.innerHTML = "Autoplay Off";
this.button.onclick = () => {
this.autoplay = !this.autoplay;
this.button.innerHTML = ["Autoplay Off", "Autoplay On"][
Number(this.autoplay)
];
};
document.body.appendChild(this.button);
this.resetButton = document.createElement("button");
this.resetButton.innerHTML = "Reset";
this.resetButton.onclick = () => {
this.backend.reset();
this.updateState();
};
document.body.appendChild(this.resetButton);
this.configVis = new visuals.ConfigVis(this.backend.getConfig());
this.configVis.draw(this.canvas);
this.activeSquares = new visuals.ActiveSquares();
this.moveSource = null;
this.canMoveTo = [];
document.onclick = (ev) => this.click(ev);
}
updateState() {
let config = this.backend.getConfig();
this.configVis.configuration = config;
this.configVis.draw(this.canvas);
}
chooseMove() {
let move = this.backend.chooseMove("black");
if (move === null) return;
this.backend.makeMove(...move);
this.updateState();
}
initializeMove(source) {
if (source === null) return;
let validMoves = this.backend.getAvailableMoves(source);
if (validMoves === null) return;
this.activeSquares.selectSquare(this.canvas, source);
this.activeSquares.setMoveSquares(this.canvas, validMoves);
this.moveSource = source;
}
finalizeMove(target) {
let success;
if (target !== null) {
success = this.backend.makeMove(this.moveSource, target) !== null;
} else {
success = false;
}
this.activeSquares.unselectSquare(this.canvas);
this.activeSquares.unsetMoveSquares(this.canvas);
this.updateState();
this.moveSource = null;
if (this.autoplay && success) {
this.chooseMove();
}
}
click(ev) {
let rc = this.canvas.screenCoordsToRowCol(ev.clientX, ev.clientY);
let position;
if (rc === null) {
position = null;
} else {
position = visuals.rowColToBoardIndex(...rc);
}
if (this.moveSource === null) {
this.initializeMove(position);
} else {
this.finalizeMove(position);
}
}
}
new Chess();