UNPKG

chessops

Version:

Chess and chess variant rules and operations

107 lines (99 loc) 3.01 kB
/** * Compatibility with other libraries. * * Convert between the formats used by chessops, * [chessground](https://github.com/lichess-org/chessground), * and [scalachess](https://github.com/lichess-org/scalachess). * * @packageDocumentation */ import { Position } from './chess.js'; import { isDrop, Move, Rules, SquareName } from './types.js'; import { makeSquare, squareFile } from './util.js'; export interface ChessgroundDestsOpts { chess960?: boolean; } /** * Computes the legal move destinations in the format used by chessground. * * Includes both possible representations of castling moves (unless * `chess960` mode is enabled), so that the `rookCastles` option will work * correctly. */ export const chessgroundDests = (pos: Position, opts?: ChessgroundDestsOpts): Map<SquareName, SquareName[]> => { const result = new Map(); const ctx = pos.ctx(); for (const [from, squares] of pos.allDests(ctx)) { if (squares.nonEmpty()) { const d = Array.from(squares, makeSquare); if (!opts?.chess960 && from === ctx.king && squareFile(from) === 4) { // Chessground needs both types of castling dests and filters based on // a rookCastles setting. if (squares.has(0)) d.push('c1'); else if (squares.has(56)) d.push('c8'); if (squares.has(7)) d.push('g1'); else if (squares.has(63)) d.push('g8'); } result.set(makeSquare(from), d); } } return result; }; export const chessgroundMove = (move: Move): SquareName[] => isDrop(move) ? [makeSquare(move.to)] : [makeSquare(move.from), makeSquare(move.to)]; export const scalachessCharPair = (move: Move): string => isDrop(move) ? String.fromCharCode( 35 + move.to, 35 + 64 + 8 * 5 + ['queen', 'rook', 'bishop', 'knight', 'pawn'].indexOf(move.role), ) : String.fromCharCode( 35 + move.from, move.promotion ? 35 + 64 + 8 * ['queen', 'rook', 'bishop', 'knight', 'king'].indexOf(move.promotion) + squareFile(move.to) : 35 + move.to, ); export const lichessRules = ( variant: | 'standard' | 'chess960' | 'antichess' | 'fromPosition' | 'kingOfTheHill' | 'threeCheck' | 'atomic' | 'horde' | 'racingKings' | 'crazyhouse', ): Rules => { switch (variant) { case 'standard': case 'chess960': case 'fromPosition': return 'chess'; case 'threeCheck': return '3check'; case 'kingOfTheHill': return 'kingofthehill'; case 'racingKings': return 'racingkings'; default: return variant; } }; export const lichessVariant = ( rules: Rules, ): 'standard' | 'antichess' | 'kingOfTheHill' | 'threeCheck' | 'atomic' | 'horde' | 'racingKings' | 'crazyhouse' => { switch (rules) { case 'chess': return 'standard'; case '3check': return 'threeCheck'; case 'kingofthehill': return 'kingOfTheHill'; case 'racingkings': return 'racingKings'; default: return rules; } };