I have released version 2.2 of my chess engine. Source code and Windows binaries are available on the Downloads page. MadChess 2.2 is about 50 Elo stronger than version 2.1. It includes the following improvements.
- Added best move estimation. In principal variations where the cached position does not specify a best move, MadChess will search at reduced depth to obtain a best move. Then it completes the full depth search, searching the best move first. This is called Internal Iterative Deepening (IID) in other engines, though I find the name misleading. It’s recursive but not iterative.
- Added endgame piece location constants to differentiate the value of pieces in the middlegame and endgame. Evaluation tuning found a significant difference only for rooks.
- Modified the GetExchangeScore method to use standard 100, 300, 500, 900 piece material values rather than the tuned material values. This forces the engine to consider knights and bishops equal for the purpose of Static Exchange Evaluation (SEE).
- Tuned evaluation parameters using the technique described by Peter Österlund.
- Fixed a bug that prevented the evaluation from recognizing drawn endgames.
- Added a help command that lists custom (non-standard UCI) commands.
- Added a staticscore custom command that displays evaluation score details by color (white, black) and phase (middlegame, endgame). The scores include differences and totals to clearly indicate strengths and weaknesses of a position for each side.
As I write this post, MadChess is competing in a long time control gauntlet. Presently it’s rated 2574 +/- 69 Elo after 126 games. I’ve seen this show before. I expect its rating to decline as more games are played and the engine “regresses to the mean.” Nonetheless, I expect MadChess 2.2 to be rated > 2500 Elo in rapid chess. So now I can rightfully claim MadChess plays Grandmaster quality chess.
Update 2017 Jul 10: MadChess 2.2 completed the gauntlet tournament. It’s rated 2511 in rapid chess.
MadChess is written in a managed1 programming language, C#, using a mailbox2 board representation. Managed programming languages, such as C# or Java, feature high-level abstractions and trade performance for code clarity. Similarly, array board representations are easier to understand than bitboards- again trading speed for clarity. Despite these trade-offs, it’s possible to write a strong chess engine using a managed programming language and mailbox board representation, as I’ve demonstrated with MadChess.
How strong? I was curious how MadChess compares to other engines of similar technical design. I reviewed the engine list on Ron Murawski’s Computer Chess Wiki, which includes the programming language of each engine. I believe MadChess is the strongest managed, mailbox chess engine. Stronger chess engines have been written in managed languages, but they use bitboards. Lozza is a close 2nd, written- impressively- in Javascript.
Engine | Programming Language | Board Representation | CCRL Rating |
---|---|---|---|
Carballo | Java | Bitboard | 2727 |
NoraGrace | C# | Bitboard | 2619 |
Cuckoo Chess | Java | Bitboard | 2590 |
MadChess | C# | Mailbox | 2511 |
Lozza | Javascript | Mailbox | 2442 |
Absolute Zero | C# | Bitboard | 2320 |
Mediocre | Java | Mailbox | 2314 |
Fischerle | Java | Bitboard | 2297 |
Dolphin | C# | Mailbox | 2232 |
Cupcake | Java | Bitboard | 2006 |
Chess4J | Java | Bitboard | 1965 |
Deepov | Java | Bitboard | 1844 |
Ziggy | Java | Mailbox | 1709 |
SharpChess | C# | Mailbox | 1674 |
Pulse | Java | Mailbox | 1571 |
DarkFusch | C# | Bitboard | 1172 |
jChecs | Java | Mailbox | 1128 |
Of course this prompts a couple questions.
- Should I rewrite MadChess using bitboards?
- Should I rewrite MadChess using a more performance-capable programming language, such as C++?
I will ponder these questions. Regarding changing programming languages, I’m intrigued by the .NET Native and Core RT projects, which aim to compile C# to IL code, statically link .NET Framework IL code, cross-compile the IL code to C++, then use an optimizing C++ compiler to produce a single executable. If this technique can deliver the simplicity of C# with the performance of C++, I’ll have no reason to switch programming languages. I’m cautiously optimistic.
- So named because memory is automatically managed by the runtime and its garbage collector, not manually managed by the programmer.
- An array with each index representing a square, index values indicating an empty square or occupying piece. So named because the array representation resembles a mailbox commonly found in apartments.