I had a Frankenstein moment yesterday. I use the word “Frankenstein” in reference to MadChess. Meaning, I’ve used my powers of concentration to create this thing, a chess engine, by imagining, thinking, then writing code to “teach” it to play a game of chess. This thing becomes terribly powerful. It’s capable of playing the game I “taught” it with the strength of a super Grandmaster, far exceeding my abilities.
While I’m glad I can use MadChess to analyze my games against Internet opponents (after the game is complete, of course), and rely on MadChess’ suggested improvements and variations (it is a Grandmaster after all), it would be nice to play a game against it. For that to be enjoyable, though, I must handicap MadChess so it plays weaker and gives me a fighting chance to win.
The Universal Chess Interface (UCI), a protocol supported by chess applications that enables users to connect the application to any chess engine, supports handicapping an engine via the
UCI_Elo options. The user selects a playing strength (Elo rating). It’s up to the engine’s author to determine how to simulate weak play at the specified Elo rating.
In MadChess’ source code, I accomplish this via four techniques:
- Removing knowledge (of piece mobility, king safety, pawn structure, etc).
- Decreasing search speed (examine, say, 1,500 positions per second instead of two million).
- Randomly selecting an inferior move at most e centipawns worse than the best move (where e varies inversely with Elo rating).
- Occasionally (p percent of moves), selecting a blunder (seriously inferior move) at most b centipawns worse (where b is much greater than e).
See The MadChess UCI_LimitStrength Algorithm for details.
So I’m playing a 5m + 5s blitz game against MadChess. I’ve handicapped MadChess by limiting its strength to 900 Elo. As the author of the engine I know this implies MadChess will blunder on approximately 11% of its moves. This blunder can be as severe as approximately 400 centipawns, which is greater than the value of a knight or bishop. I know this because I wrote the code and devised the handicapping formulas.
I play white, MadChess plays black. The game begins 1.e4 c5 2.Nf3 Nc6 3.d4 cxd4 4.Nxd4 h5 5.Nc3 Nf6 6.Bc4 Na5 7.Be2 e5 8.Nf3 Bb4 9.Bd2 Rh6 10.Nxe5 Rh8 11.Nc4 Rb8 12.O-O Nxc4 13.Bxc4 Qc7 14.Qe2 Ng4 15.g3 Qd8 16.a3 Bd6 17.Nd5 Bc5 18.Qf3.
I’m up a pawn. Now MadChess threatens my queen and light-squared bishop via 18… Ne5. I evade the threat to my queen and protect my bishop by playing 19. Qc3, eyeing black’s undefended knight on e5 and pawn on g7. MadChess persists, threatening my queen again via 19… Bd4.
Er, wait… that move makes no sense. Doesn’t it simply blunder the bishop? I examine the board and determine black’s bishop on d4 is unprotected by any of its pieces. “Oh,” I think to myself, “this must be MadChess’ limit-strength algorithm kicking in. The engine is making an idle threat but hanging its bishop. This is well within the 400 centipawn blunder it may play once every nine moves or so.” I capture the black bishop via 20. Qxd4.
Frankenstein, I mean MadChess, replies 20… Nf3+, forking my king and queen. Doh!
I walked into that trap. I played on hoping MadChess would blunder some material back to me, leveling the game. But it was I who made further mistakes. I resigned after black’s 33rd move forked another of my pieces.
So I have used my powers of concentration to create a chess engine (via coding) that can defeat my powers of concentration (playing a game of chess).
So I have used my powers of concentration to create a chess engine (via coding) that can defeat my powers of concentration (playing a game of chess). I attempt to weaken my creation, act satisfied when I believe it has indeed played a weak move, then am smacked in the face by the brutish engine. Surreal.
To correct this problem, I need to code less and play more.
After the game I gave Komodo Dragon, a world-class chess engine, two seconds per move to analyze the game. See the full game, with Komodo’s suggested improvements, below.