#club #bindings #hexchess #find-king #bedard-hexchess

hexchess

A Rust / TypeScript library for Gliński's hexagonal chess, and the brain of hexchess.club

15 releases (6 breaking)

new 2.0.0-beta.7 Apr 21, 2025
0.10.0 Sep 17, 2024

#127 in Game dev

Download history 48/week @ 2025-02-10 11/week @ 2025-02-17 44/week @ 2025-03-31 506/week @ 2025-04-07 89/week @ 2025-04-14

639 downloads per month

MIT license

410KB
9K SLoC

Rust 5K SLoC // 0.0% comments TypeScript 4K SLoC // 0.0% comments

@bedard/hexchess

Build Coverage NPM Crates.io License

A Rust / TypeScript library for Gliński's hexagonal chess, and the brain of hexchess.club.

Installation

Install this package via NPM.

Depending on your bundler and target, you may need plugins for Web Assembly and top-level await to utilize WASM bindings.

npm install @bedard/hexchess

pnpm install @bedard/hexchess

yarn add @bedard/hexchess

Basic usage

The Hexchess class is a deserialized version of Forsyth–Edwards Notation. It contains the board state, current turn, en passant, and move numbers. Since castling is not a part of hexagonal chess, that section is omitted. The board data is stored as an array of Piece | null, sorted in FEN-order.

To create a game at the starting position, use Hexchess.init.

import { Hexchess } from '@bedard/hexchess'

const hexchess = Hexchess.init()

Hexchess instances have the following shape. The board represents an array of position values, sorted in FEN-order.

{
  board: [
    'b',  'q',  'b',  'k',  'n',  null, 'b',  null, 'n',  'r',
    null, null, null, null, null, 'r',  'p',  'p',  'p',  'p',
    'p',  'p',  'p',  'p',  'p',  null, null, null, null, null,
    null, null, null, null, null, null, null, null, null, null,
    null, 'P',  null, null, null, null, null, null, null, null,
    null, 'P',  null, 'P',  null, null, null, null, null, null,
    null, 'P',  null, 'B',  null, 'P',  null, null, null, null,
    null, 'P',  null, null, 'B',  null, null, 'P',  null, null,
    null, 'P',  'R',  'N',  'Q',  'B',  'K',  'N',  'R',  'P',
    null
  ],
  turn: 'w',
  ep: null,
  halfmove: 0,
  fullmove: 1
}

The following methods are available for interacting with the game. A pair of constants named initialPosition and positions are available as well.

apply

Apply a whitespace separated sequence of moves.

const hexchess = Hexchess.init()

hexchess.apply('g4g5 e7e6 f5f6 e6f6')

hexchess.toString() // 'b/qbk/n1b1n/r5r/ppp1ppppp/5p5/6P4/4P6/3P1B1P3/2P2B2P2/1PRNQBKNRP1 w - 0 3'

applyMove

Apply a single move from string or San.

const hexchess = Hexchess.init()

hexchess.applyMove(San.parse('g4g6'))

hexchess.toString() // 'b/qbk/n1b1n/r5r/ppppppppp/11/5PP4/4P6/3P1B1P3/2P2B2P2/1PRNQBKNRP1 b - 0 1'

applyMoveUnsafe

Apply a single move from string or San, regardless of turn or legality.

const hexchess = Hexchess.init()

hexchess.applyMoveUnsafe('b1b6')

hexchess.toString() // 'b/qbk/n1b1n/r5r/ppppppppp/1P9/5P5/4P1P4/3P1B1P3/2P2B2P2/2RNQBKNRP1 b - 0 1'

clone

Deeply clone a Hexchess instance.

const hexchess = Hexchess.init()

const clone = hexchess.clone()

hexchess === clone // false

currentMoves

Get all current legal moves.

const hexchess = new Hexchess('1/3/5/7/9/11/5P5/11/11/11/11 w - 0 1')

const moves = hexchess.currentMoves()

moves.map(String) // ['f5f6, 'f5f7', ...]

findKing

Find FEN index for king belonging to Color.

const hexchess = Hexchess.init()

hexchess.findKing('b') // 3
hexchess.findKing('w') // 86

get

Get board value from position name.

const hexchess = Hexchess.init()

hexchess.get('e1') // 'Q'

getColor

Get all board indices occupied by Color pieces.

const hexchess = Hexchess.init()

hexchess.getColor('b') // [0,  1,  2,  ...]

isCheck

Test if the board is in check.

const hexchess = Hexchess.init()

isCheck(hexckess) // false

isCheckmate

Test if the game is in checkmate.

const hexchess = Hexchess.init()

isCheckmate(hexckess) // false

isStalemate

Test if the game is in stalemate.

const hexchess = Hexchess.init()

isStalemate(hexckess) // false

movesFrom

Get all legal moves from a position.

const hexchess = Hexchess.init()

const moves = hexchess.movesFrom('f6')

moves.map(String) // ['f6f7']

movesFromUnsafe

Get all moves from a position, including ones that result in self-check.

const hexchess = Hexchess.parse('1/3/5/7/4r4/5K5/11/11/11/11/11 w - 0 1')

const moves = hexchess.movesUnsafe()

moves.map(String) // ['f6f7', 'f6g7' ...]

toString

Serialize a Hexchess instance to string.

const hexchess = Hexchess.init()

hexchess.toString() // 'b/qbk/n1b1n/r5r/ppppppppp/11/5P5/4P1P4/3P1B1P3/2P2B2P2/1PRNQBKNRP1 w - 0 1'

Wasm Bindings

The Rust crate for this library is exposed via WebAssembly. If your environment permits it, these are the functions you should use when writing engines or evaluators.

All APIs are the same as above, but with a functional syntax that accepts a Hexchess as the first argument, and returns a new Hexchess instance. The following methods are available to create and serialize objects.

import {
  apply,
  initHexchess,
  stringifyHexchess,
} from '@bedard/hexchess/wasm' // <- note the import path

const hexchess = apply(initHexchess(), 'g4g6 f7g6 f5f7 g6f6')

stringifyHexchess(hexchess) // 'b/qbk/n1b1n/r5r/pppp1pppp/5p5/11/4P6/3P1B1P3/2P2B2P2/1PRNQBKNRP1 w - 0 3'

Below is a list of the available bindings.

  • apply
  • applyMove
  • applyMoveUnsafe
  • createHexchess
  • currentMoves
  • findKing
  • get
  • initHexchess
  • isCheck
  • isCheckmate
  • isStalemate
  • movesFrom
  • movesFromUnsafe
  • parseHexchess
  • parseSan
  • stringifyHexchess
  • stringifySan

License

MIT

Copyright (c) 2024-present, Scott Bedard

Dependencies

~2–2.8MB
~47K SLoC