kokopu
Version:
A JavaScript/TypeScript library implementing the chess game rules and providing tools to read/write the standard chess file formats.
165 lines (127 loc) • 6.53 kB
text/typescript
/*!
* -------------------------------------------------------------------------- *
* *
* Kokopu - A JavaScript/TypeScript chess library. *
* <https://www.npmjs.com/package/kokopu> *
* Copyright (C) 2018-2026 Yoann Le Montagner <yo35 -at- melix.net> *
* *
* Kokopu is free software: you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License *
* as published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version. *
* *
* Kokopu is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General *
* Public License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* -------------------------------------------------------------------------- */
import { Color, Piece, ColoredPiece, File, Rank, Square, GameResult, GameVariant } from '../base_types';
/* eslint-disable @stylistic/computed-property-spacing, @stylistic/no-multi-spaces, @stylistic/no-whitespace-before-property, @stylistic/semi-spacing,
@stylistic/space-before-function-paren, @stylistic/space-in-parens, @stylistic/type-annotation-spacing */
export const enum ColorImpl {
WHITE = 0,
BLACK = 1,
}
export const enum PieceImpl {
KING = 0,
QUEEN = 1,
ROOK = 2,
BISHOP = 3,
KNIGHT = 4,
PAWN = 5,
}
export const enum CpI {
WK = 0, BK = 1,
WQ = 2, BQ = 3,
WR = 4, BR = 5,
WB = 6, BB = 7,
WN = 8, BN = 9,
WP = 10, BP = 11,
}
/**
* Special constants for chessboard square state.
*/
export const enum SpI {
EMPTY = -1,
INVALID = -2, // Just for the internal board representation.
}
export const enum SquareImpl {
A1 = 0, B1 = 1, C1 = 2, D1 = 3, E1 = 4, F1 = 5, G1 = 6, H1 = 7,
A2 = 16, B2 = 17, C2 = 18, D2 = 19, E2 = 20, F2 = 21, G2 = 22, H2 = 23,
A3 = 32, B3 = 33, C3 = 34, D3 = 35, E3 = 36, F3 = 37, G3 = 38, H3 = 39,
A4 = 48, B4 = 49, C4 = 50, D4 = 51, E4 = 52, F4 = 53, G4 = 54, H4 = 55,
A5 = 64, B5 = 65, C5 = 66, D5 = 67, E5 = 68, F5 = 69, G5 = 70, H5 = 71,
A6 = 80, B6 = 81, C6 = 82, D6 = 83, E6 = 84, F6 = 85, G6 = 86, H6 = 87,
A7 = 96, B7 = 97, C7 = 98, D7 = 99, E7 = 100, F7 = 101, G7 = 102, H7 = 103,
A8 = 112, B8 = 113, C8 = 114, D8 = 115, E8 = 116, F8 = 117, G8 = 118, H8 = 119,
}
export const enum GameResultImpl {
WHITE_WINS = 0,
BLACK_WINS = 1,
DRAW = 2,
LINE = 3,
}
export const enum GameVariantImpl {
REGULAR_CHESS = 0,
CHESS960 = 1,
NO_KING = 2,
WHITE_KING_ONLY = 3,
BLACK_KING_ONLY = 4,
ANTICHESS = 5,
HORDE = 6,
}
const COLOR_SYMBOL = [ ...'wb' ];
const PIECE_SYMBOL = [ ...'kqrbnp' ];
const FILE_SYMBOL = [ ...'abcdefgh' ];
const RANK_SYMBOL = [ ...'12345678' ];
const RESULT_SYMBOL = [ '1-0', '0-1', '1/2-1/2', '*' ];
const VARIANT_SYMBOL = [ 'regular', 'chess960', 'no-king', 'white-king-only', 'black-king-only', 'antichess', 'horde' ];
const FIGURINE_SYMBOL = [ ...'\u2654\u265a\u2655\u265b\u2656\u265c\u2657\u265d\u2658\u265e\u2659\u265f' ];
export function colorToString (color : number) { return COLOR_SYMBOL [color ] as Color ; }
export function pieceToString (piece : number) { return PIECE_SYMBOL [piece ] as Piece ; }
export function fileToString (file : number) { return FILE_SYMBOL [file ] as File ; }
export function rankToString (rank : number) { return RANK_SYMBOL [rank ] as Rank ; }
export function resultToString (result : number) { return RESULT_SYMBOL [result ] as GameResult ; }
export function variantToString(variant : number) { return VARIANT_SYMBOL[variant] as GameVariant; }
export function colorFromString (color : unknown) { return typeof color === 'string' ? COLOR_SYMBOL .indexOf(color ) : -1; }
export function pieceFromString (piece : unknown) { return typeof piece === 'string' ? PIECE_SYMBOL .indexOf(piece ) : -1; }
export function fileFromString (file : unknown) { return typeof file === 'string' ? FILE_SYMBOL .indexOf(file ) : -1; }
export function rankFromString (rank : unknown) { return typeof rank === 'string' ? RANK_SYMBOL .indexOf(rank ) : -1; }
export function resultFromString (result : unknown) { return typeof result === 'string' ? RESULT_SYMBOL .indexOf(result ) : -1; }
export function variantFromString(variant : unknown) { return typeof variant === 'string' ? VARIANT_SYMBOL.indexOf(variant) : -1; }
export function squareToString(square: number) {
return FILE_SYMBOL[square % 16] + RANK_SYMBOL[Math.trunc(square / 16)] as Square;
}
export function squareFromString(square: unknown) {
if (typeof square !== 'string' || !/^[a-h][1-8]$/.test(square)) {
return -1;
}
const file = FILE_SYMBOL.indexOf(square[0]);
const rank = RANK_SYMBOL.indexOf(square[1]);
return rank * 16 + file;
}
export function coloredPieceToString(cp: number) {
return COLOR_SYMBOL[cp % 2] + PIECE_SYMBOL[Math.trunc(cp / 2)] as ColoredPiece;
}
export function coloredPieceFromString(cp: unknown) {
if (typeof cp !== 'string' || !/^[wb][kqrbnp]$/.test(cp)) {
return -1;
}
const color = COLOR_SYMBOL.indexOf(cp[0]);
const piece = PIECE_SYMBOL.indexOf(cp[1]);
return piece * 2 + color;
}
export function figurineToString(cp: number) {
return FIGURINE_SYMBOL[cp];
}
export function figurineFromString(cp: unknown) {
return FIGURINE_SYMBOL.indexOf(String(cp));
}
export function squareColorImpl(square: number) {
return (~square ^ (square >> 4)) & 0x1;
}