Banks 55th Amateur Series Division 6

MadChess 2.0 participated in Graham Banks’ 55th amateur tournament in division 6.

                             1  2  3  4  5  6  7  8  9  0  1  2  3  4  5  6  
1   Jazz 840 64-bit          ** ½0 11 10 01 11 10 1½ 11 1½ 11 11 ½1 11 11 1½  23.5/30
2   K2 0.75                  ½1 ** 11 ½1 10 11 ½0 1½ 11 0½ ½1 10 ½½ 11 11 11  22.0/30
3   MadChess 2.0 64-bit      00 00 ** 01 11 01 01 01 10 1½ 11 1½ ½1 11 ½½ ½1  18.0/30
4   CmcChess 2.6 64-bit      01 ½0 10 ** 11 11 ½0 01 ½0 10 00 ½1 ½½ 11 11 1½  17.5/30
5   Tigran 2.4n 64-bit       10 01 00 00 ** 0½ 11 ½0 11 1½ 01 10 ½1 1½ ½1 11  17.0/30  233.25
6   Waxman 2014              00 00 10 00 1½ ** 1½ 11 01 ½1 01 1½ 1½ ½1 ½1 1½  17.0/30  225.50
7   Myrddin 0.87 64-bit      01 ½1 10 ½1 00 0½ ** ½0 ½1 11 01 11 11 00 10 01  16.5/30
8   Fischerle 0.9.65 64-bit  0½ 0½ 10 10 ½1 00 ½1 ** 00 ½1 ½1 ½0 ½½ ½½ 1½ 11  15.0/30
9   Protej 0.5.8c            00 00 01 ½1 00 10 ½0 11 ** 0½ 0½ ½0 11 11 1½ ½0  13.5/30
10  Nemeton 1.2              0½ 1½ 0½ 01 0½ ½0 00 ½0 1½ ** 10 ½0 ½0 ½1 01 11  13.0/30
11  FireFly 2.7.0 64-bit     00 ½0 00 11 10 10 10 ½0 1½ 01 ** 11 01 00 01 00  12.5/30  184.75
12  Orion 0.2 64-bit         00 01 0½ ½0 01 0½ 00 ½1 ½1 ½1 00 ** 11 0½ ½½ ½½  12.5/30  175.50
13  Lozza 1.15 64-bit        ½0 ½½ ½0 ½½ ½0 0½ 00 ½½ 00 ½1 10 00 ** 0½ 1½ 11  11.5/30
14  CyberPagno 2.2 64-bit    00 00 00 00 0½ ½0 11 ½½ 00 ½0 11 1½ 1½ ** 0½ 10  11.0/30  146.50
15  Gibbon 2.69a 64-bit      00 00 ½½ 00 ½0 ½0 01 0½ 0½ 10 10 ½½ 0½ 1½ ** 11  11.0/30  143.00
16  Floyd 0.6 64-bit         0½ 00 ½0 0½ 00 0½ 10 00 ½1 00 11 ½½ 00 01 00 **   8.5/30

Games

MadChess 2.0 Released

I have released version 2 of my chess engine. I’ve rewritten the engine from scratch in a more procedural style code- as opposed to the sub-optimal (for chess engines at least) object-oriented style I used in MadChess 1.x.

The engine is about 115 – 160 Elo stronger than its predecessor, depending on time control. I estimate it is about 2350 Elo.

Source code and EXEs available on the Downloads page.

MadChess 2.0 Beta Build 127 (Limit-Strength)

I have added parameters to limit the playing strength of MadChess 2.0 Beta.

WriteMessageLine("option name Pawn type spin default " + Evaluation.DefaultPawnMaterialScore +
" min 1 max 1500");
WriteMessageLine("option name Knight type spin default " + Evaluation.DefaultKnightMaterialScore +
" min 1 max 1500");
WriteMessageLine("option name Bishop type spin default " + Evaluation.DefaultBishopMaterialScore +
" min 1 max 1500");
WriteMessageLine("option name Rook type spin default " + Evaluation.DefaultRookMaterialScore +
" min 1 max 1500");
WriteMessageLine("option name Queen type spin default " + Evaluation.DefaultQueenMaterialScore +
" min 1 max 1500");
WriteMessageLine("option name PieceLocation type check default true");
WriteMessageLine("option name PassedPawns type check default true");
WriteMessageLine("option name Mobility type check default true");
WriteMessageLine("option name KingSafety type check default true");
WriteMessageLine("option name BishopPair type check default true");
WriteMessageLine("option name Outposts type check default true");
WriteMessageLine("option name Trades type check default true");
WriteMessageLine("option name 7thRank type check default true");
WriteMessageLine("option name NPS type spin default 0 min 0 max 1000000");
WriteMessageLine("option name MoveError type spin default 0 min 0 max 1000");
WriteMessageLine("option name BlunderError type spin default 0 min 0 max 1000");
WriteMessageLine("option name BlunderPercent type spin default 0 min 0 max 100");
WriteMessageLine("option name UCI_LimitStrength type check default false");
WriteMessageLine("option name LimitStrength type check default false");
WriteMessageLine("option name UCI_Elo type spin default " + Search.MinElo + " min " + Search.MinElo +
" max " + Search.MaxElo);
WriteMessageLine("option name Elo type spin default " + Search.MinElo + " min " + Search.MinElo +
" max " + Search.MaxElo);

The simplest way to limit the playing strength of MadChess 2.0 Beta is to set the LimitStrength and Elo parameters. The engine will automatically configure material scores and positional knowledge.

// Evaluation
public void ConfigureStrength(int Elo)
{
// Set default parameters.
SetDefaultParameters();
// Limit material and positional understanding.
if (Elo < 800)
{
// Beginner
// Overvalue queen and undervalue rook.
RookMaterialScore = 300;
QueenMaterialScore = 1200;
}
if (Elo < 1000)
{
// Novice
// Value knight and bishop equally.
KnightMaterialScore = 300;
BishopMaterialScore = 300;
// Misplace pieces.
UnderstandsPieceLocation = false;
}
if (Elo < 1200)
{
// Social
UnderstandsPassedPawns = false;
}
if (Elo < 1400)
{
// Strong Social
UnderstandsMobility = false;
}
if (Elo < 1600)
{
// Club
UnderstandsKingSafety = false;
}
if (Elo < 1800)
{
// Strong Club
UnderstandsBishopPair = false;
UnderstandsOutposts = false;
}
if (Elo < 2000)
{
// Expert
Understands7thRank = false;
UnderstandsTrades = false;
}
if (_uciStream.Debug)
{
_uciStream.WriteMessageLine("info string PawnMaterialScore = " + PawnMaterialScore);
_uciStream.WriteMessageLine("info string KnightMaterialScore = " + KnightMaterialScore);
_uciStream.WriteMessageLine("info string BishopMaterialScore = " + BishopMaterialScore);
_uciStream.WriteMessageLine("info string RookMaterialScore = " + RookMaterialScore);
_uciStream.WriteMessageLine("info string QueenMaterialScore = " + QueenMaterialScore);
_uciStream.WriteMessageLine("info string UnderstandsPieceLocation = " + UnderstandsPieceLocation);
_uciStream.WriteMessageLine("info string UnderstandsPassedPawns = " + UnderstandsPassedPawns);
_uciStream.WriteMessageLine("info string UnderstandsMobility = " + UnderstandsMobility);
_uciStream.WriteMessageLine("info string UnderstandsKingSafety = " + UnderstandsKingSafety);
_uciStream.WriteMessageLine("info string UnderstandsBishopPair = " + UnderstandsBishopPair);
_uciStream.WriteMessageLine("info string UnderstandsOutposts = " + UnderstandsOutposts);
_uciStream.WriteMessageLine("info string Understands7thRank = " + Understands7thRank);
_uciStream.WriteMessageLine("info string UnderstandsTrades = " + UnderstandsTrades);
}
}

In addition, the engine will configure search speed (Nodes Per Second), move error, blunder error, and blunder percent based on the Elo value.

// Search
private void ConfigureStrength()
{
// Set default parameters.
SetDefaultParameters();
// Limit search speed.
// Rating 400 600 800 1000 1200 1400 1600 1800 2000 2200
// Nodes Per Second 100 100 105 231 1410 7912 33692 115396 335644 861034
double scale = 0.02d;
int power = 8;
int constant = 100;
double ratingClass = (double)(_elo - MinElo) / 200;
NodesPerSecond = GetNonLinearBonus(ratingClass, scale, power, constant);
// Allow errors on every move.
// Rating 400 600 800 1000 1200 1400 1600 1800 2000 2200
// Move Error 162 128 98 72 50 32 18 8 2 0
scale = 2d;
power = 2;
constant = 0;
ratingClass = (double)(MaxElo - _elo) / 200;
MoveError = GetNonLinearBonus(ratingClass, scale, power, constant);
// Allow occassional blunders.
// Rating 400 600 800 1000 1200 1400 1600 1800 2000 2200
// Blunder Error 511 409 319 241 175 121 79 49 31 25
// Blunder Pct 25 21 17 14 11 9 7 6 5 5
scale = 6d;
power = 2;
constant = 25;
BlunderError = GetNonLinearBonus(ratingClass, scale, power, constant);
scale = 0.25d;
power = 2;
constant = 5;
BlunderPercent = GetNonLinearBonus(ratingClass, scale, power, constant);
if (_uciStream.Debug)
{
_uciStream.WriteMessageLine("info string NPS = " + NodesPerSecond + " MoveError = " + MoveError +
" BlunderError = " + BlunderError + " BlunderPercent = " + BlunderPercent + ".");
}
}
private static int GetNonLinearBonus(double RatingClass, double Scale, int Power, int Constant)
{
return (int) (Scale * Math.Pow(RatingClass, Power)) + Constant;
}

Banks 54th Amateur Series Division 6

MadChess 1.4 participated in Graham Banks’ 54th amateur tournament in division 6.

                                  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5  6  
1   PikoSzachy Extreme            ** 00 11 ½½ 1½ 11 11 10 11 01 11 ½1 01 11 1½ ½1  22.0/30
2   Lozza 1.15 64-bit             11 ** 01 01 ½½ ½½ 11 ½1 ½½ ½1 ½1 1½ 10 1½ ½1 ½1  20.5/30
3   Tigran 2.4n 64-bit            00 10 ** 00 10 1½ ½1 11 11 1½ 1½ ½½ 11 1½ 11 1½  20.0/30
4   Jazz 840 64-bit               ½½ 10 11 ** 01 ½½ 00 1½ 11 1½ 0½ ½1 11 10 01 10  18.0/30  267.50
5   Gibbon 2.69a 64-bit           0½ ½½ 01 10 ** ½½ ½1 10 10 1½ ½½ 11 10 1½ 11 10  18.0/30  254.50
6   MadChess 1.4 64-bit           00 ½½ 0½ ½½ ½½ ** 0½ 0½ ½1 1½ ½0 01 ½1 01 11 ½1  15.0/30  207.75
7   Schooner 1.4.1 64-bit         00 00 ½0 11 ½0 1½ ** ½1 ½0 11 10 10 ½0 1½ ½½ ½1  15.0/30  207.00
8   FireFly 2.7.0 64-bit          01 ½0 00 0½ 01 1½ ½0 ** 00 ½1 ½½ 11 11 ½1 ½0 ½1  15.0/30  205.50
9   Waxman 2014                   00 ½½ 00 00 01 ½0 ½1 11 ** ½0 01 1½ 11 01 ½1 1½  15.0/30  201.00
10  CyberPagno 2.2 64-bit         10 ½0 0½ 0½ 0½ 0½ 00 ½0 ½1 ** 1½ 1½ 10 ½1 ½½ 1½  13.5/30
11  Exacto 0.e 64-bit             00 ½0 0½ 1½ ½½ ½1 01 ½½ 10 0½ ** 0½ 00 01 ½½ 1½  12.5/30
12  ChessKiss 1.7c 64-bit         ½0 0½ ½½ ½0 00 10 01 00 0½ 0½ 1½ ** 10 00 11 11  12.0/30
13  Protej 0.5.8c                 10 01 00 00 01 ½0 ½1 00 00 01 11 01 ** 10 00 ½1  11.5/30  166.00
14  Orion 0.2                     00 0½ 0½ 01 0½ 10 0½ ½0 10 ½0 10 11 01 ** ½0 ½½  11.5/30  161.75
15  Nemeton 1.2                   0½ ½0 00 10 00 00 ½½ ½1 ½0 ½½ ½½ 00 11 ½1 ** 10  11.5/30  159.50
16  Absolute Zero 2.4.0.0 64-bit  ½0 ½0 0½ 01 01 ½0 ½0 ½0 0½ 0½ 0½ 00 ½0 ½½ 01 **   9.0/30

Games

MadChess 2.0 Beta Build 123 (Rook And Queen On 7th Rank)

I added rook and queen on 7th rank evaluation to MadChess 2.0 Beta. The code awards a bonus for a rook or queen on the 7th rank if the enemy king is on the 8th rank (its 1st rank).

Also, I removed late move pruning. (When I implemented late move pruning in build 44 it added 39 Elo to the playing strength of MadChess 2.0 Beta.) I replaced it with more aggressive null and late move reductions, and more aggressive futility pruning, but found it decreased the playing strength. Next, I restored late move pruning and left in the aggressive reductions. I found the strength increased, but not quite back to where it had been. I discovered a non-linear relationship between these search techniques. The combined strength of null move reductions, LMR, LMP, and futility pruning is not additive. I experimented with various parameter configurations before deciding to abandon LMP. It took 300 hours of testing to confirm the revised search was equivalently strong to the search with LMP.

private const int _mgRookOn7thRank = 20;
private const int _egRookOn7thRank = 40;
private const int _mgQueenOn7thRank = 10;
private const int _egQueenOn7thRank = 20;
private const int _nullMoveReduction = 3;
private const int _pvsMinToHorizon = 3;
private const int _quietSearchRecaptureDepth = 3;
futilityMargins = new[] {50, 100, 175, 275, 400, 550};
_lateMoveReductions = new[] {3, 7, 15};
private void EvaluateRooks(out int MgRooks, out int EgRooks)
{
MgRooks = 0;
EgRooks = 0;
int whiteKingRank = _board.WhiteRanks[_board.CurrentPosition.WhiteKingSquare];
int blackKingRank = _board.BlackRanks[_board.CurrentPosition.BlackKingSquare];
if ((whiteKingRank != 1) && (blackKingRank != 1)) return;
for (int rook = 0; rook < _rooks; rook++)
{
int square = _rookSquares[rook];
byte piece = _board.CurrentPosition.Squares[square];
if (piece == Piece.WhiteRook)
{
// White rook
if ((_board.WhiteRanks[square] == 7) && (blackKingRank == 1))
{
// White rook is on 7th rank. Black king is on 1st rank.
MgRooks += _mgRookOn7thRank;
EgRooks += _egRookOn7thRank;
}
}
else
{
// Black rook
if ((_board.BlackRanks[square] == 7) && (whiteKingRank == 1))
{
// Black rook is on 7th rank. White king is on 1st rank.
MgRooks -= _mgRookOn7thRank;
EgRooks -= _egRookOn7thRank;
}
}
}
}
private void EvaluateQueens(out int MgQueens, out int EgQueens)
{
MgQueens = 0;
EgQueens = 0;
int whiteKingRank = _board.WhiteRanks[_board.CurrentPosition.WhiteKingSquare];
int blackKingRank = _board.BlackRanks[_board.CurrentPosition.BlackKingSquare];
if ((whiteKingRank != 1) && (blackKingRank != 1)) return;
for (int queen = 0; queen < _queens; queen++)
{
int square = _queenSquares[queen];
byte piece = _board.CurrentPosition.Squares[square];
if (piece == Piece.WhiteQueen)
{
// White queen
if ((_board.WhiteRanks[square] == 7) && (blackKingRank == 1))
{
// White queen is on 7th rank. Black king is on 1st rank.
MgQueens += _mgQueenOn7thRank;
EgQueens += _egQueenOn7thRank;
}
}
else
{
// Black queen
if ((_board.BlackRanks[square] == 7) && (whiteKingRank == 1))
{
// Black queen is on 7th rank. White king is on 1st rank.
MgQueens -= _mgQueenOn7thRank;
EgQueens -= _egQueenOn7thRank;
}
}
}
}

This added 20 Elo to the playing strength of MadChess 2.0 Beta.

MadChess 2.0             2306.9 :   1600 (+835,=299,-466),  61.5 %

vs.                             :  games (   +,   =,   -),   (%) :    Diff,    SD, CFS (%)
Glass 1.6                       :    100 (  22,  24,  54),  34.0 :  -140.1,  15.0,    0.0
RomiChess P3L                   :    100 (  20,  20,  60),  30.0 :  -133.7,  16.2,    0.0
OliThink 5.3.2                  :    100 (  23,  20,  57),  33.0 :  -109.7,  15.5,    0.0
Myrddin 0.87                    :    100 (  31,  21,  48),  41.5 :   -75.0,  17.3,    0.0
Sungorus 1.4                    :    100 (  49,  15,  36),  56.5 :    -3.1,   8.2,   35.2
FireFly v2.6.0                  :    100 (  47,  31,  22),  62.5 :   +89.0,  10.0,  100.0
ZCT 0.3.2450                    :    100 (  42,  28,  30),  56.0 :   +94.7,  10.8,  100.0
Beowulf 2.4                     :    100 (  59,  19,  22),  68.5 :   +97.1,  13.0,  100.0
Jazz v444                       :    100 (  60,  17,  23),  68.5 :  +108.9,  10.0,  100.0
Brainless 1.0                   :    100 (  57,  17,  26),  65.5 :  +148.2,  17.8,  100.0
Wing 2.0                        :    100 (  61,  20,  19),  71.0 :  +177.5,  10.1,  100.0
BikJump v2.01                   :    100 (  61,  22,  17),  72.0 :  +198.9,  10.7,  100.0
Matheus-2.3                     :    100 (  66,  19,  15),  75.5 :  +220.5,  10.7,  100.0
Monarch 1.7                     :    100 (  72,  12,  16),  78.0 :  +245.5,  11.0,  100.0
BigLion 2.23w                   :    100 (  82,   7,  11),  85.5 :  +277.1,   9.4,  100.0
Sharper 0.17                    :    100 (  83,   7,  10),  86.5 :  +289.8,  10.8,  100.0
Feature Category Date Rev1 WAC2 Elo Rating3 Improvement
Rook And Queen On 7th Rank Evaluation 2015 Aug 20 123 279 2307 +20
Knight Outposts Evaluation 2015 May 27 83 276 2287 +25
Tune Reductions And Pruning Search 2015 Apr 26 74 275 2262 +20
Bishop Pair Evaluation 2015 Apr 15 69 275 2242 +18
Free Passed Pawns Evaluation 2015 Mar 10 59 270 2224 +31
Unstoppable Pawns
Draws, Material Trades
Evaluation 2015 Jan 31 52 270 2193 +39
Late Move Pruning Search 2015 Jan 10 44 273 2154 +39
History Heuristic
Late Move Reductions
Search 2015 Jan 04 40 275 2115 +50
Killer Moves Search 2015 Jan 03 38 275 2065 +61
Futility Pruning Search 2014 Dec 29 37 256 2004 +54
Null Move
Quiescence Recaptures
Search 2014 Dec 28 34 242 1950 +46
King Safety Evaluation 2014 Dec 24 32 225 1904 +27
Piece Mobility Evaluation 2014 Dec 16 29 225 1877 +64
Draw By Repetition Bug Evaluation 2014 Dec 10 27 225 1813 +47
Passed Pawns Evaluation 2014 Dec 09 26 225 1766 +72
Time Management Search 2014 Dec 08 25 231 1694 +24
Delay Move Generation
Aspiration Window Bug
Search 2014 Dec 02 23 231 1670 +44
MVV / LVA Move Order
Draw By Insufficient Material
Move List Overflow Bug
Search 2014 Dec 01 22 235 1626 +30
Tapered Evaluation
MG and EG Piece Location
Evaluation 2014 Nov 29 21 234 1596 +107
Alpha / Beta Negamax
Aspiration Windows
Quiescence, Hash
Material, Piece Squares
Baseline 2014 Nov 25 20 236 1489
  1. Subversion source code revision
  2. Win At Chess position test, 3 seconds per position
  3. Bullet chess, 2 min / game + 1 sec / move