Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/adam-mcdaniel/chess-engine

A dependency-free chess engine♟️ library built to run anywhere.
https://github.com/adam-mcdaniel/chess-engine

ai chess game

Last synced: about 1 month ago
JSON representation

A dependency-free chess engine♟️ library built to run anywhere.

Awesome Lists containing this project

README

        


♔chess-engine♚


A dependency-free chess engine library built to run anywhere.


Demo
|
Docs
|
Contact Me

Written in Rust🦀💖



Chess in the terminal


Chess in the web

## Why write a Chess engine?

Above all, [this video](https://www.youtube.com/watch?v=DpXy041BIlA&t=7s) by [Tom7](http://tom7.org/) is my inspiration for this project. He's absolutely brilliant and I implore you to watch his content.

I love chess a _lot_. It's definitely one of my favorite games ever. However, I've always been disappointed when trying to write programs that play chess digitally (particularly in a compiled language). Although several amazing engines exist, it's near impossible to find a neat library for chess-related-programming that runs on everything.

chess-engine is a solution to my problem. If you want a chess engine that runs on embedded devices, the terminal, [the desktop (with a gui)](https://github.com/adam-mcdaniel/chess-engine/tree/main/examples/chess-gui), _and_ [the web](https://adam-mcdaniel.github.io/chess-engine/docs/book/index.html#average-ai), this is probably your best bet.

## How does it work?

This particular AI (along with most other chess AIs) works using the [Minimax algorithm](https://en.wikipedia.org/wiki/Minimax), along with [Alpha-Beta pruning](https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning) for optimization.

Now, let's unpack that.

The Minimax algorithm essentially iterates through all possible moves recursively, and evaluates all of the boards after the moves are played. If the board is _more_ favorable, it will **encourage** playing its parent move, but if a board is _less_ favorable, then it will select **against** playing a given move.

![Minimax](./assets/mini-max.jpeg)

Additionally, when the AI attempts to see past just the current board, it will assume the human _always_ responds with the best moves. As a result, the computer almost **never** blunders.
This allows the computer to almost always play objectively better moves than the player.

## Embedded in the Web

Because it has zero dependencies, it's extremely simple to embed in the web browser using wasm. [Try playing it yourself!](https://adam-mcdaniel.github.io/chess-engine/docs/book/index.html#average-ai)



Average AI Setting



Try playing it yourself!

## Usage

The `Board` structure has a few different methods that allow users to generate moves from a given position, including `get_best_next_move`, `get_worst_next_move`, and `get_legal_moves`. These are particularly handy for writing chess AIs to play against.

```rust
fn main() {
let board = Board::default();

// Get the best move with 4 moves of lookahead
let best_move = board.get_best_next_move(4);
// Get the worst move with 3 moves of lookahead
let worst_move = board.get_worst_next_move(3);

// Get all of the possible legal moves for the given player
let legal_moves = board.get_legal_moves();
// Print the board
println!("{}", board);

print!("CPU chose to ");
match best_move {
Move::Piece(from, to) => println!("move {} to {}", from, to),
Move::KingSideCastle => println!("castle kingside"),
Move::QueenSideCastle => println!("castle queenside"),
Move::Resign => println!("resign")
}
}
```

To add some variation or more advanced play, consider writing an AI that plays known openings that build better positions before using the `get_best_next_move` method!

#### Custom Boards

Additionally, users can create their own custom `Board` objects other than the default one. This is done using the `BoardBuilder` structure. The `BoardBuilder` structure supports enabling and disabling castling, placing rows and columns of pieces, and placing individual pieces.

_**Keep in mind when using a `BoardBuilder` that castling is disabled by default!**_



Play the Horde Chess Variant


Play the Horde Chess Variant

```rust
fn main() {
// `BoardBuilder::new()` returns an empty board
// with castling disabled.
// Creating a board builder from another board
// structure will preserve
// all settings from the board (such as castling
// and the last en-passant move).

// This BoardBuilder constructs the "Horde" chess variant!
let board = BoardBuilder::from(Board::default())
.row(Piece::Pawn(WHITE, A1))
.row(Piece::Pawn(WHITE, A2))
.row(Piece::Pawn(WHITE, A3))
.row(Piece::Pawn(WHITE, A4))
.piece(Piece::Pawn(WHITE, F5))
.piece(Piece::Pawn(WHITE, G5))
.piece(Piece::Pawn(WHITE, B5))
.piece(Piece::Pawn(WHITE, C5))
.build();

// The CPU can also play variants!
let cpu_move = board.get_best_next_move(3);

match board.play_move(cpu_move) {
GameResult::Continuing(next_board) => {
println!("{}", next_board);
}

GameResult::Victory(winner) => {
// You can use the ! operator on a player's
// color to invert.
println!("{} loses. {} is victorious.",
!winner, winner
);
}

GameResult::IllegalMove(x) => {
eprintln!("{} is an illegal move.", x);
}

GameResult::Stalemate => {
println!("Drawn game.");
}
}
}
```

## About the Author



Website
|
Blog
|
GitHub


I'm a freshman in college, mainly working on side projects like these in the ~30 minute breaks between classes. If you enjoy my projects, consider supporting me by buying me a coffee!


Buy Me A Coffee