Files
prosperon/examples/chess/rules.cm
2026-02-25 16:58:06 -06:00

46 lines
1.7 KiB
Plaintext

/* helper -- robust coord access */
function cx(c) { return !is_null(c.x) ? c.x : c[0] }
function cy(c) { return !is_null(c.y) ? c.y : c[1] }
/* simple move-shape checks */
var deltas = {
pawn: function (pc, dx, dy, ctx) {
var dir = (pc.colour == 'white') ? 1 : -1;
var base = (pc.colour == 'white') ? 1 : 6;
var one = (dy == dir && dx == 0 && length(ctx.grid.at(ctx.to)) == 0);
var two = (dy == 2 * dir && dx == 0 && cy(pc.coord) == base &&
length(ctx.grid.at({ x: cx(pc.coord), y: cy(pc.coord)+dir })) == 0 &&
length(ctx.grid.at(ctx.to)) == 0);
var cap = (dy == dir && abs(dx) == 1 && length(ctx.grid.at(ctx.to)));
return one || two || cap;
},
rook : function (pc, dx, dy) { return (dx == 0 || dy == 0); },
bishop: function (pc, dx, dy) { return abs(dx) == abs(dy); },
queen : function (pc, dx, dy) { return (dx == 0 || dy == 0 || abs(dx) == abs(dy)); },
knight: function (pc, dx, dy) { return (abs(dx) == 1 && abs(dy) == 2) ||
(abs(dx) == 2 && abs(dy) == 1); },
king : function (pc, dx, dy) { return max(abs(dx), abs(dy)) == 1; }
};
function clearLine(from, to, grid) {
var dx = sign(cx(to) - cx(from));
var dy = sign(cy(to) - cy(from));
var x = cx(from) + dx, y = cy(from) + dy;
while (x != cx(to) || y != cy(to)) {
if (length(grid.at({ x: x, y: y }))) return false;
x += dx; y += dy;
}
return true;
}
function canMove(piece, from, to, grid) {
var dx = cx(to) - cx(from);
var dy = cy(to) - cy(from);
var f = deltas[piece.kind];
if (!f || !f(piece, dx, dy, {grid: grid, to: to})) return false;
if (piece.kind == 'knight') return true;
return clearLine(from, to, grid);
}
return { canMove: canMove };