A small turn-based board game you can play in the browser.
- basically Starchess, a hexagonal chess-variant, but with added pieces.
- playable prototype built with Vite+React and boardgame.io.
- hosted with render and vercel
- You can play on: https://play-hex-chess.vercel.app/.
- Shape: a horizontally oriented regular hexagram, consisting of 37 numbered cells.
- Orientation: orthogonal directions are defined as the six directions to a cell's edge-adjacent neighbours (N, NW, SW, S, SE, NE); diagonal directions are defined as the six directions to a cell's corner (E, NE, NW, W, SW, SE).
Pawns start on the second rank like in chess. At the beginning of the game, the players place five of their other pieces alternately on the cells behind their pawns.
- White back-rank cells: 4, 11, 17, 22, 28
- Black back-rank cells: 10, 16, 21, 27, 34
For convenience there are two buttons:
- Place All (Fixed): places your remaining pieces down in a fixed order.
- Place All (Random): places your remaining pieces down in a random order.
When both players have finished placing, the game automatically switches to the Play phase.
- Your turn: Click one of your pieces to see its legal moves (shown as small grey dots), then click a destination cell to move.
- Move onto an opponent’s piece to capture it.
- Your turn ends after you move a piece.
- Unlike in chess, there is no "check".
- You win the game by capturing the opponent's king.
- The game is a draw, when a player has no legal move.
- Pawns that reach the opponent’s back rank promote to a queen immediately.
Moves usually follow the hexagrams orthogonal directions. The moon piece is an exception, as it can move on the diagonals.
- Moves one step straight forward (White moves “up”, Black moves “down”).
- Can move two steps from its starting cell if both cells are empty.
- Captures one step forward-left or forward-right.
- No en-passant.
- Moves one step in any orthogonal direction.
- No castling.
- Moves two steps in any orthogonal direction, then one step in an adjacent orthogonal direction. (an “L” on the hex grid).
- Knights jump over pieces in between.
- Moves any number of steps vertically (straight up/down).
- Moves any number of steps along the non-vertical orthogonal directions.
- Moves any number of steps in any orthogonal direction.
- Moves any number of steps in any forward facing direction.
- White moves "up" | Black moves "down"
- Moves one or two steps in any orthogonal direction.
- If it moves two steps and captures an enemy piece, ANY piece in the intermediate cell is also captured.
- Moves one step in any orthogonal direction.
- Can swap places with a friendly piece.
- Moves like the Knight and looks like one to the opponent.
- When captured, also removes the piece that captured it.
- On even turns: moves like a bishop.
- On odd turns: moves any number of steps along the non-vertical diagonal directions.
- Install
npm install
- Start the dev server
npm run dev
- Open the localhost URL in your browser.
- hexGrid.js – Board shape and coordinate helpers (axial directions, index lookup).
- rules.js – Pure rules: piece metadata, setup constants, move definitions.
- game.js – boardgame.io game: phases, moves, logging, and simple AI enumeration.
- board.jsx – React UI: renders the board, highlights legal moves, handles selection and setup UI.
- app.jsx - React UI: landing page and play mode selection.
VITE_SERVER_URLis set on vercel and links to the server on render. - server.js - boardgame.io server.
CLIENT_ORIGINis set on render and links to vercel.
- rules.js/
PIECES: add your piece for white and black. 'WR' and 'BR' are the piece codes for the rooks.
export const PIECES = {
[...]
WR: { color: 'W', glyph: '♖', kind: 'rook' },
BR: { color: 'B', glyph: '♜', kind: 'rook' },
[...]
}
- rules.js/
SETUP_POOL: add your piece code for white and black.
export const SETUP_POOL = Object.freeze({
W: Object.freeze(['WK', 'WN', 'WB', 'WQ', 'WR', 'WC']),
B: Object.freeze(['BK', 'BN', 'BB', 'BQ', 'BR', 'BC']),
});
- rules.js: implement your move function. Cells simply contain the piece code as a string or null if empty. The move function returns an array of legal indices.
function rookMoves(cells, index) {
const pieceCode = cells[index];
if (!pieceCode) return [];
const directions = [0, 3];
return directions.flatMap(d => slide(cells, index, d));
}
- rules.js/
legalMovesFromCells: add your move function.
export function legalMovesFromCells(cells, index) {
[...]
case 'rook': return rookMoves(cells, index);
[...]
}
-
(Optional) Some pieces may have special abilities that cannot be simply described by moving from one cell to another. In this case, you may need to implement additional logic in game.js/
applyPlay. This may also be needed inside rules.js/nextStateCells, if you want the AI to include your move logic. -
(Optional) rules.js/
isKingAttacked: this function is used by the AI to not blunder their king in one turn. Also add your move logic here, if you want.
export function isKingAttacked(cells, kingColor) {
[...]
if (isSlideAttacked([2, 5], ['rook', 'queen'])) {
return true;
}
[...]
}
- (Optional) Add images of your pieces to the assets folder. Name them after your piece code (e.g. 'wr.svg').
Images for Pawns, Kings, Knights, Rooks, Bishops, Queens:
- Cburnett, CC BY-SA 3.0, via Wikimedia Commons
Images for Chargers:
- NikNaks93, CC BY-SA 3.0, via Wikimedia Commons
Images for Dragons:
- Cburnett (knight); Conorpetersen (dragon), CC BY-SA 3.0, via Wikimedia Commons
Images for Guardians:
- Black: Sunny3113, CC BY-SA 4.0, via Wikimedia Commons
- White: Uray M. János, GFDL, via Wikimedia Commons
Images for Fools:
- tdl44.png and tll44.png: Mykol Dolgalov / derivative work: NikNaks93, CC BY-SA 3.0, via Wikimedia Commons
Images for Moon:
- wdl44.png and wll44.png: OmegaChessFan / derivative work: NikNaks93, CC BY-SA 3.0, via Wikimedia Commons
Image for chessboard icon:
Sound effects for pieces:
- Move: el_boss, Creative Commons 0, via freesound.org
- Capture: el_boss, Creative Commons 0, via freesound.org
MIT