Skip to content

Be Ready for the Only Clever Chess engine that remains Irrefutably Unbeaten

Notifications You must be signed in to change notification settings

pierre-reboud/brocciu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Brocciu

License: MIT

Brocciu

Be Ready for the Only Clever Chess Engine that remains Irrefutably Unbeaten

Brocciu is a simple interface to access the Lichess-Api programmatically. It lets a custom bot engine intercept incoming challenges and react to them in parallel using a threadpool. Additionally, it comes with a simple chess engine written in Rust that implements the Monte-Carlo-Tree-Search algorithm using the straight-forward (but slow) Rc<RefCell<Node>> data structure.

Game example

Performance

Runs approximately 5-10k MCTS iterations/s depending on the current board position on WSL2 with a i5-5200U CPU without nightly cargo optimization flags. assets/flamegraph.svg indicates that the bottleneck lies in the simulation step (takes around 60% of the compute budget).

The discussion on Graphs and arena allocation outlines more performant (and complex/unsafe) graph data structure solutions. Additionally, this crate implements a more efficient parallelized tree search than the one provided here.

Usage

Api config setup

In the json file /configs/default_api.json, enter your lichess username and token. The token can be obtained by following the bot instructions. Subsequently, rename the file to /configs/api.json.

Simple Example

Use the provided example chess engine:

use brocciu;
use tokio;

// Create a runtime environment
#[tokio::main]
async fn main(){
    // Run brocciu
    brocciu::main().await;
}

For debugging purposes, the generated DAG can be visualized using the brocciu::utils::graph_visualization::draw_graph function.

Docker

Alternatively, brocciu's docker image can be built and run using the following command:

docker build -t brocciu . && docker run brocciu

TODO: Advanced Example

Use your own engine, by letting it implement the Engine trait:

use brocciu;
use tokio;

struct MyEngine{}

/* The Engine trait

pub trait Engine{
    fn new(game: Rc<RefCell<chess::Game>>) -> Self;
    fn get_next_move(&mut self, bot_color: chess::Color) -> Result<(String, bool), NoAvailableMoveError>;
}

*/

impl brocciu::mcts::search::Engine<MyEngine> for MyEngine{
    pub fn new(game: Rc<RefCell<chess::Game>>) -> MyEngine {
        // Your implementation
    }
    pub fn get_next_move() -> Result<(String, bool), brocciu::mcts::search::NoAvailableMoveError>{
        // Your implementation
    }
}

// Create a runtime environment
#[tokio::main]
async fn main(){
    // Run brocciu

    brocciu::run()
}

Feature Tracking

This project only offers the most bare-bone features necessary for functionality. The following features have yet to be implemented

State Comment
Selection Policy: Currently only UCT -> Add more refined node selection policies
Simulation Policy: Currently random self-play -> Add more refined node simulation policies (e.g. with NNs)
Simulation Time Dynamization: Currently, each move generation takes a constant amount of time except when reaching fully explored tree states -> Allocate different search time budgets at different game stages
Simulation Break Condition: Currently constant depth break condition -> Break simulate step when position obviously leads to stalemate
Challenge Initiation: Currently, bot can only react to exogeneous challenges -> Initiate challenges against the computer
Challenge Types: Currently, only regular untimed challenge types supported. Non-standard (and timed) challenges result in undefined behavior -> Accept different challenge types;
Tree Data Structure: Current node data structure is Rc/Weak<RefCell<Node>> -> Use a more efficient node data structure
Profiling/Performance: Currently, the simulation step takes 60% of the compute budget -> Review simulation end conditions
Spurious Zobrist Hash Collisions: Currently, each node is maximally expanded once. A hash collision occuring in the game's path leads to panicking -> Review better recovery options
Other

Contributing

Pull requests are welcome. Please open an issue to describe the desired feature. No ETA implied.