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