MadChess 3.0 Beta f231dac (PVS and Null Move Improvements)

I improved MadChess 3.0 Beta’s Principal Variation Search (PVS) by consolidating two separate re-searches into one. In addition, I changed the null move implementation so it reduces the search horizon more aggressively if the current position’s static score far exceeds beta.

Previously, if a PVS search failed high, the engine would confirm the fail high first by restoring beta from bestScore + 1 to its original value and re-searching. If that also failed high, it restored the search horizon from a reduced value to its original value and re-searched. If that failed high the engine took a beta cutoff.

I simplified the code to a single re-search.

Null move now reduces more aggressively if the current position’s static score far exceeds beta.

This increased the playing strength of MadChess 3.0 Beta by 20 Elo.

 

Feature Category Date Commit1 WAC2 Elo Rating3 Improvement
PVS and Null Move Search 2021 Feb 09 f231dac 285 2550 +20
Remove Aspiration Windows Search 2020 Dec 20 4b7963b 290 2530 +9
Time Management Search 2020 Dec 19 d143bb5 286 2521 +8
Crash Bug Search 2020 Aug 29 2d855ec 288 2513 +0
King Safety Evaluation 2020 Aug 16 6794c89 288 2513 +63
Eval Param Tuning Evaluation 2020 Jul 23 bef88d5 283 2450 +30
Late Move Pruning Search 2020 Feb 08 6f3d17a 288 2420 +29
Piece Mobility Evaluation 2020 Feb 01 5c5d4fc 282 2391 +62
Passed Pawns Evaluation 2018 Dec 27 103 279 2329 +119
Staged Move Generation Search 2018 Dec 15 93 275 2210 +39
History Heuristics Search 2018 Dec 03 84 275 2171 +28
Eval Param Tuning Evaluation 2018 Nov 24 75 272 2143 +47
Sophisticated Search
Material and Piece Location
Baseline 2018 Nov 08 58 269 2096 0
  1. GitHub commit (hash) or Subversion source code revision (integer)
  2. Win At Chess position test, 3 seconds per position
  3. Bullet chess, 2 min / game + 1 sec / move

Play Rather Than Code

Watching The Queen’s Gambit on Netflix nudged me to play chess online. I’ve spent time on chess over the last few years… programming an engine, not actually playing. I’m very rusty. Though my puzzle rating is decent. It’s much higher than my game rating, suggesting I need to work on time management. Thinking fast is not my strength, but everyone online plays blitz or bullet so here goes nothing…

Last night I joined a bullet tournament with a 2+1 clock. Each player has 2 minutes to make all their moves in the game, plus 1 second added to their clock after each move. Many of the games I played were blunderfests. But I managed to play solidly in a few. Here’s a well played game considering I’m making most of my moves in like 2 or 3 seconds. I play white (DamageInkk). Afterwards I had MadChess analyze the game. Converting a “won” game is not inevitable for a patzer like me, especially with the time pressure, so I was glad to do it and glad to see MadChess confirm I played accurately from move 16 on.

I like the checkmate configuration at the end of the game: My opponent chases my pawn, walking right into a discovered check / pawn promotion mate.

Knight Outpost

A knight positioned on an outpost controls opponent territory, restricting movement of the opponent’s pieces on the opponent’s side of the board. An outpost is defined as a square on the fifth or sixth rank, occupied by a minor piece (usually a knight), supported by its own pawn, and positioned such that it cannot ever be attacked by an opposing pawn. In other words, the opponent has no pawns on the neighboring files, or if the opponent has pawns on the neighboring files, they’ve advanced even with or beyond the outpost square.

r4rk1/1qb2ppp/1pN2n2/pP2p3/P3P3/4BP2/3RQ1PP/3R2K1 b - - 0 1

Red highlights in the above position indicate squares in black territory attacked by the white knight on c6. Yellow highlights indicate squares in white territory attacked by the same knight.

Controlling Space

Controlling board space- especially central squares- provides room to maneuver pieces. It cramps the opponent’s position, who will have difficulty bringing pieces out from behind their pawns. And it enables a quick redeployment of pieces from one zone of action (queenside, for example) to another zone of action (kingside) to initiate an attack or muster a defense around the king.

Be careful not to overextend when grabbing space. In the following position, white appears to control more space than black. Black’s counterplay demonstrates, however, that white merely occupies space but does not control it.

r1bq1rk1/ppp1ppbp/n2p1np1/4P3/2PP1P2/2N2N2/PP4PP/R1BQKB1R b KQ - 0 1

Black moves his knight to safety (and attacks the e5 central square) then takes advantage of white’s greediness.

Fortunes have changed. Now black controls more territory.

MadChess 3.0 Beta 4b7963b (Remove Aspiration Windows)

When analyzing a Carlsen versus Vachier-Lagrave game, I noticed MadChess 3.0 Beta struggling to find Magnus Carlsen’s crushing 23rd move, d6, in the following position.

2r2rk1/1ppq2b1/1n6/1N1Ppp2/p7/Pn2BP2/1PQ1BP2/3RK2R w K - 0 23

In the engine output displayed by the Hiarcs Chess GUI, I noticed MadChess kept restarting its search of ply 18. It indicated it was searching the first move (of 47 legal moves), second move, third move, etc… then would restart searching the first move again, still on ply 18. It restarted searching the first move of ply 18 numerous times. I suspected this was due to search instability caused by aspiration windows: searching a window centered around the previous ply’s score (ply 17 for this position) causes a fail high, the window is expanded in the direction of the fail high, sometimes (bizarrely) this causes a fail low, the window is expanded in the direction of the fail low, causing a fail high, low, high, etc… until the window is wide enough in both directions to return a stable score.

For this position, with aspiration windows enabled (by default they are), MadChess took four minutes to find Carlsen’s move. Even though MadChess is single-threaded, it has a non-deterministic search because it generates random Zobrist position keys (for the initial key, piece squares, side-to-move, castling rights, and en passant squares). Due to this non-determinism, in some cases restarting MadChess and searching the position again caused MadChess to recommend sub-optimal moves, unable to find Carlsen’s move even after 18 minutes, when I gave up.

I’ve long suspected aspiration windows are worthless, so I disabled them, produced a new build of MadChess, restarted the Hiracs Chess GUI, and searched the position again. MadChess found Carlsen’s move in 45 seconds. Restarting MadChess and searching the position again reliably found Carlsen’s move at ply 18 within 40 – 50 seconds.

Knowing the performance of a chess engine on one particular position is not indicative of how it performs in games against a variety of opponents, I decided to remove the aspiration window code (not merely disable it), then run a gauntlet tournament against ten opponents. I removed the following code.

The tournament confirmed my suspicions. MadChess performed 9 Elo stronger without aspiration windows.

See my Are Aspiration Windows Worthless? post on the TalkChess forum for a discussion of this blog post.

 

Feature Category Date Commit1 WAC2 Elo Rating3 Improvement
Remove Aspiration Windows Search 2020 Dec 20 4b7963b 290 2530 +9
Time Management Search 2020 Dec 19 d143bb5 286 2521 +8
Crash Bug Search 2020 Aug 29 2d855ec 288 2513 +0
King Safety Evaluation 2020 Aug 16 6794c89 288 2513 +63
Eval Param Tuning Evaluation 2020 Jul 23 bef88d5 283 2450 +30
Late Move Pruning Search 2020 Feb 08 6f3d17a 288 2420 +29
Piece Mobility Evaluation 2020 Feb 01 5c5d4fc 282 2391 +62
Passed Pawns Evaluation 2018 Dec 27 103 279 2329 +119
Staged Move Generation Search 2018 Dec 15 93 275 2210 +39
History Heuristics Search 2018 Dec 03 84 275 2171 +28
Eval Param Tuning Evaluation 2018 Nov 24 75 272 2143 +47
Sophisticated Search
Material and Piece Location
Baseline 2018 Nov 08 58 269 2096 0
  1. GitHub commit (hash) or Subversion source code revision (integer)
  2. Win At Chess position test, 3 seconds per position
  3. Bullet chess, 2 min / game + 1 sec / move