quoridor

A JavaScipt Quoridor library for move validation etc.

Usage no npm install needed!

<script type="module">
  import quoridor from 'https://cdn.skypack.dev/quoridor';
</script>

README

quoridor.js

Installation

npm install quoridor

API

createNewGame: () => Game

Generates a new game.

import { createNewGame, getUnicodeRepresentation } from 'quoridor';

const game = createNewGame();

console.log(getUnicodeRepresentation(game));

// ┌───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┐
// │   ║   ║   ║   ║   ║   ║   ║   ║   ║   ║   │
// │   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
// │ 9 │   │   │   │   │ 2 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 8 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 7 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 6 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 5 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 4 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 3 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 2 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 1 │   │   │   │   │ 1 │   │   │   │   │   │
// │   └───┴───┴───┴───┴───┴───┴───┴───┴───┘   │
// │   ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I ║   │
// └───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┘

createGameFromMoves: (moves: Move[]) => Game

Generates a game from an array of moves. Does not verify that the moves are valid.

import { createGameFromMoves, getUnicodeRepresentation } from 'quoridor';

const game = createGameFromMoves(['e2', 'e8', 'd7v']);

console.log(getUnicodeRepresentation(game));

// ┌───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┐
// │   ║   ║   ║   ║   ║   ║   ║   ║   ║   ║   │
// │   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
// │ 9 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 8 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 7 │   │   │   │   ║ 2 │   │   │   │   │   │
// │   ├───┼───┼───┼───╫───┼───┼───┼───┼───┤   │
// │ 6 │   │   │   │   ║   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 5 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 4 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 3 │   │   │   │   │ 1 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 2 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 1 │   │   │   │   │   │   │   │   │   │   │
// │   └───┴───┴───┴───┴───┴───┴───┴───┴───┘   │
// │   ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I     │
// └───╫───╫───╫───╫───╫───╫───╫───╫───╫───────┘

getUnicodeRepresentation: (game: Game) => string

Returns a string representation of the board game state using Unicode box-drawing characters.

import { createNewGame, getUnicodeRepresentation } from 'quoridor';

const unicodeRepresentation = getUnicodeRepresentation(createNewGame())

console.log(unicodeRepresentation);

// ┌───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┐
// │   ║   ║   ║   ║   ║   ║   ║   ║   ║   ║   │
// │   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
// │ 9 │   │   │   │   │ 2 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 8 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 7 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 6 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 5 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 4 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 3 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 2 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 1 │   │   │   │   │ 1 │   │   │   │   │   │
// │   └───┴───┴───┴───┴───┴───┴───┴───┴───┘   │
// │   ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I ║   │
// └───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┘

isMoveValid: (game: Game, move: Move) => boolean

Checks if a move is valid.

import { createGameFromMoves, isMoveValid } from 'quoridor';

const game = createGameFromMoves(['e2', 'e8', 'd7v']);
const move = 'd7';

const moveIsValid = isMoveValid(game, move);

console.log(moveIsValid);

// false

undo: (game: Game) => Game

Returns a new game with the most recent move undone. If no moves have been made yet, an identical game is returned.

import { createGameFromMoves, undo, getUnicodeRepresentation } from 'quoridor';

const game = createGameFromMoves(['e2', 'e8', 'd7v']);
const gameWithUndoneMove = undo(game);

console.log(getUnicodeRepresentation(game));

// ┌───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┐
// │   ║   ║   ║   ║   ║   ║   ║   ║   ║   ║   │
// │   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
// │ 9 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 8 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 7 │   │   │   │   ║ 2 │   │   │   │   │   │
// │   ├───┼───┼───┼───╫───┼───┼───┼───┼───┤   │
// │ 6 │   │   │   │   ║   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 5 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 4 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 3 │   │   │   │   │ 1 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 2 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 1 │   │   │   │   │   │   │   │   │   │   │
// │   └───┴───┴───┴───┴───┴───┴───┴───┴───┘   │
// │   ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I     │
// └───╫───╫───╫───╫───╫───╫───╫───╫───╫───────┘

console.log(getUnicodeRepresentation(gameWithUndoneMove));

// ┌───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┐
// │   ║   ║   ║   ║   ║   ║   ║   ║   ║   ║   │
// │   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
// │ 9 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 8 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 7 │   │   │   │   │ 2 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 6 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 5 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 4 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 3 │   │   │   │   │ 1 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 2 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 1 │   │   │   │   │   │   │   │   │   │   │
// │   └───┴───┴───┴───┴───┴───┴───┴───┴───┘   │
// │   ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I ║   │
// └───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┘

redo: (game: Game) => Game

Returns a new game with the most recently undone move redone. If no moves have been undone yet, an identical game is returned.

import { createGameFromMoves, redo, undo, getUnicodeRepresentation } from 'quoridor';

const game = createGameFromMoves(['e2', 'e8', 'd7v']);
const gameWithUndoneMove = undo(game);
const gameWithUndoneMoveRedone = redo(gameWithUndoneMove);

console.log(getUnicodeRepresentation(game));

// ┌───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┐
// │   ║   ║   ║   ║   ║   ║   ║   ║   ║   ║   │
// │   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
// │ 9 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 8 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 7 │   │   │   │   ║ 2 │   │   │   │   │   │
// │   ├───┼───┼───┼───╫───┼───┼───┼───┼───┤   │
// │ 6 │   │   │   │   ║   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 5 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 4 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 3 │   │   │   │   │ 1 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 2 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 1 │   │   │   │   │   │   │   │   │   │   │
// │   └───┴───┴───┴───┴───┴───┴───┴───┴───┘   │
// │   ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I     │
// └───╫───╫───╫───╫───╫───╫───╫───╫───╫───────┘

console.log(getUnicodeRepresentation(gameWithUndoneMove));

// ┌───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┐
// │   ║   ║   ║   ║   ║   ║   ║   ║   ║   ║   │
// │   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
// │ 9 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 8 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 7 │   │   │   │   │ 2 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 6 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 5 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 4 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 3 │   │   │   │   │ 1 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 2 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 1 │   │   │   │   │   │   │   │   │   │   │
// │   └───┴───┴───┴───┴───┴───┴───┴───┴───┘   │
// │   ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I ║   │
// └───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┘

console.log(getUnicodeRepresentation(gameWithUndoneMoveRedone));

// ┌───╫───╫───╫───╫───╫───╫───╫───╫───╫───╫───┐
// │   ║   ║   ║   ║   ║   ║   ║   ║   ║   ║   │
// │   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
// │ 9 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 8 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 7 │   │   │   │   ║ 2 │   │   │   │   │   │
// │   ├───┼───┼───┼───╫───┼───┼───┼───┼───┤   │
// │ 6 │   │   │   │   ║   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 5 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 4 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 3 │   │   │   │   │ 1 │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 2 │   │   │   │   │   │   │   │   │   │   │
// │   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤   │
// │ 1 │   │   │   │   │   │   │   │   │   │   │
// │   └───┴───┴───┴───┴───┴───┴───┴───┴───┘   │
// │   ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I     │
// └───╫───╫───╫───╫───╫───╫───╫───╫───╫───────┘

Publishing a new version

Check that linting, formatting, build and tests pass

npm run lint
npm run format
npm run build
npm test

Bump version

npm version [major | minor | patch]

Publish to NPM

npm publish