@lichess-org/chessground
Version:
lichess.org chess ui
58 lines (49 loc) • 2.6 kB
text/typescript
import * as util from './util.js';
import * as cg from './types.js';
import { HeadlessState } from './state.js';
import { Mobility, MobilityContext } from './types.js';
const pawn: Mobility = (ctx: MobilityContext) =>
util.diff(ctx.orig.pos[0], ctx.dest.pos[0]) <= 1 &&
(util.diff(ctx.orig.pos[0], ctx.dest.pos[0]) === 1
? ctx.dest.pos[1] === ctx.orig.pos[1] + (ctx.color === 'white' ? 1 : -1)
: util.pawnDirAdvance(...ctx.orig.pos, ...ctx.dest.pos, ctx.color === 'white'));
const knight: Mobility = (ctx: MobilityContext) => util.knightDir(...ctx.orig.pos, ...ctx.dest.pos);
const bishop: Mobility = (ctx: MobilityContext) => util.bishopDir(...ctx.orig.pos, ...ctx.dest.pos);
const rook: Mobility = (ctx: MobilityContext) => util.rookDir(...ctx.orig.pos, ...ctx.dest.pos);
const queen: Mobility = (ctx: MobilityContext) => bishop(ctx) || rook(ctx);
const king: Mobility = (ctx: MobilityContext) =>
util.kingDirNonCastling(...ctx.orig.pos, ...ctx.dest.pos) ||
(ctx.orig.pos[1] === ctx.dest.pos[1] &&
ctx.orig.pos[1] === (ctx.color === 'white' ? 0 : 7) &&
((ctx.orig.pos[0] === 4 &&
((ctx.dest.pos[0] === 2 && ctx.rookFilesFriendlies.includes(0)) ||
(ctx.dest.pos[0] === 6 && ctx.rookFilesFriendlies.includes(7)))) ||
ctx.rookFilesFriendlies.includes(ctx.dest.pos[0])));
const mobilityByRole = { pawn, knight, bishop, rook, queen, king };
export function premove(state: HeadlessState, key: cg.Key): cg.Key[] {
const pieces = state.pieces;
const piece = pieces.get(key);
if (!piece || piece.color === state.turnColor) return [];
const color = piece.color,
friendlies = new Map([...pieces].filter(([_, p]) => p.color === color)),
enemies = new Map([...pieces].filter(([_, p]) => p.color === util.opposite(color))),
orig = { key, pos: util.key2pos(key) },
mobility: Mobility = (ctx: MobilityContext) =>
mobilityByRole[piece.role](ctx) && state.premovable.additionalPremoveRequirements(ctx),
partialCtx = {
orig,
role: piece.role,
allPieces: pieces,
friendlies: friendlies,
enemies: enemies,
color: color,
rookFilesFriendlies: Array.from(pieces)
.filter(
([k, p]) => k[1] === (color === 'white' ? '1' : '8') && p.color === color && p.role === 'rook',
)
.map(([k]) => util.key2pos(k)[0]),
lastMove: state.lastMove,
};
// todo - remove more properties from MobilityContext that aren't used in this file, and adjust as needed in lila.
return util.allPosAndKey.filter(dest => mobility({ ...partialCtx, dest })).map(pk => pk.key);
}