Mida is a chess engine built entirely in C++. From version 2.0 it uses NNUE for evaluation.
Version | CCRL 40/15 | CCRL Blitz |
---|---|---|
2.3 | 3146 | 3107 |
2.2 | 3088 | 3088 |
2.1 | 2941 | / |
2.0 | / (~2600) | / (~2600) |
1.2.1 | / | 2360 |
1.2 | / | / |
1.1 | / | 2331 |
1.0 | / | 2233 |
To represent various board states, most chess engines, including Mida, use bitboards, which are 64-bits unsigned integers: this representation is convenient because there are 64 squares on a chess board: therefore, we can represent the occupied squares, attacked squares ecc... by setting to 1 (or "hot") the bits that correspond to an occupied or attacked square, for example.
This implementation is faster because bit-wise operations are very efficient. You can explore further here, understanding the full potential of bitboards implementation.
Move genearation consists in generating all the legal moves for a given side and a given position. While this task may seem easy at first, I can assure you will find many obstacles along the way.
To do this, I followed this article that I strongly recommend.
From version 2.0, Mida uses Neural Network evaluation, with HalfKP structure.
The network was very briefly trained, because for now that's not what I want to focus on. Still, it does the job.
More specifically, it was trained for 35 epochs on a small set of Leela and Stockfish data of around 600 million positions. A small part of these were from DFRC games, but I haven't had the chance to test Mida in this chess variant, so I don't know how it could perform.
The search is based on Alpha-beta pruning algorithm, with various pruning and reduction techniques to reduce the number of visited nodes and increase the reached depth:
To compile the code, just run the commands:
git clone https://github.com/GiacomoPorpiglia/Mida
cd Mida/src
make
./Mida
The engine is built to work with UCI (Universal Chess Interface), and you can easily find all the commands online. The most useful are:
For this project I used a lot of awesome resources:
Also, thanks to Graham Banks, admin of CCRL, for helping me compile the code properly so that it can execute also on machines without GCC installed, and to all the testers for the useful work they do.
Thank you for supporting Mida developement and training through
Changed History heuristic (now aligned with the implementation of all top engines). This improves the move ordering. Also, history score is now used in LMR to adjust the reduction.
"Improving cuts": We check if the evaluation has improved compared to the eval from the second last node, and if the score is lower, (meaning the branch is not improving), we can search it with more aggressive prunings (for now only in LMP) because it's probably not a good branch.
Increased reduction in Null Move Pruning: the reduction is now adjusted also based on the distance of the eval from beta. Also, null move pruning is now applied only if the eval is >= than beta.
Changes in LMR: the reduction factor (from now will be called R) is now not only the value from the LMR table, but is also adjusted based on the move. In particular:
Hash table size set to a default value of 64 MB (still have to make it customizable)
Optimizations in tt entry's size (previouslt 24 bytes, now 16) and added Aging as overwriting condition.
This version has its main updates in the search function.
The main updates in v1.1 are: