46 lines
1.7 KiB
Plaintext
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 };
|