The game of chess written in Gleam

Hex Docs GitHub

⚠️🛠️ This project is a work in progress! While all features are complete, significant documentation and API verification efforts are underway!

This is the game of chess implemented as a Gleam library using a purely functional programming paradigm.

Great care has been taken to design an easy to use API with strong type safety and descriptive error returns. (Check out the docs!)

This project has no UI or user-facing I/O. There is, however, a basic text renderer to let you experiment before building your own UI! See the chapter Module Structure below.

Extensive snapshot-testing is done through birdie. See the chapter Testing below.

Features

Play chess acoording to professional chess rules!

1 The rule of achieving a draw by a dead position is omitted as implementation is quite complex and could have significant impact on performance.

This should however not impact the actual user experience of playing chess much, as being in a dead position eventually results in a draw through either mutual agreement, threefold repetition or the 50 move rule anyway.

Let me know if you know a nifty algorithm for this!

Example Usage

This example showcases Gleam code, though the project may be used with any Erlang or JavaScript runtime through Gleam’s compiler options.

import chess
import chess/coordinates as coord

pub fn main() {
  // Create a new game in standard chess starting position
  let game = chess.new_game()

  echo chess.get_status(game)
  // => GameOngoing(next_player: White)

  // White gets all legal moves of pawn on E2
  echo chess.get_moves(game, coord.e2)
  // => E3 and E4

  // White moves pawn E2 to E4
  let move =
    chess.PlayerMovesFigure(chess.StandardFigureMove(
      from: coord.e2,
      to: coord.e4,
    ))
  let assert Ok(game) = chess.player_move(game, move)

  // Now it's black's turn
  echo chess.get_status(game)
  // => GameOngoing(next_player: Black)

  // Black tries to illegally move king to E5
  let illegal_move =
    chess.PlayerMovesFigure(chess.StandardFigureMove(
      from: coord.e8,
      to: coord.e5,
    ))
  echo chess.player_move(game, illegal_move)
  // => Error(PlayerMoveIsIllegal)

  // Black is frustrated and forfeits the game
  let forfeit_move = chess.PlayerForfeits
  let assert Ok(game) = chess.player_move(game, forfeit_move)
  echo chess.get_status(game)
  // => GameEnded(Victory(winner: White, by: Forfeit))
}

Module Structure

Use the main module chess for all the necessary types and functions.

All other submodules are strictly optional, but are here for your convenience:

The submodule chess/coordinates provides constants to quickly reference all squares on the chess board without constructing those values yourself.

chess/algebraic_notation allows you to express chess moves in standard algebraic chess notation, as in e4, Bxc3+ or exd8=R#.

Lastly, the module chess/text_renderer provides a basic text renderer to express chess positions as a string - with or without ANSI codes to highlight a selected figure and its possible moves. See the example screenshot of in the chapter Testing below.

Development

To compile/change the project yourself install Gleam and download the source:

git clone git@github.com:OlZe/Functional-Chess.git
cd Functional-Chess
gleam test

The html docs are built and deployed automatically on push to main through GitHub Actions. If you want to build your own html docs locally use:

gleam docs build --open

Testing

Tests are automatically evaluated on push to main through GitHub Actions.

Birdie is used to allow for snapshot testing, where test scenarios manipulate the chess board, pretty print it to the console, and require the user to view and confirm that the scenarios were executed correctly. See the example below.

Once a snapshot was confirmed to be correct, it will no longer require confirmation, unless the output changes, in which case birdie will show a diff between the old confirmed output and the new changed output.

When cloning this repo, all snapshots should already be confirmed to be correct.

An example screenshot of a new snapshot where a chess board is pretty printed to console, with the queen’s moves highlighted. The test asks to confirm whether the queen’s moves are correct.

To run the tests locally, use:

gleam test

If there are any snapshots that require confirmation use the following to view them:

gleam run -m birdie
Search Document