MadChess adjusts its playing strength by configuring a set of four engine parameters. As playing strength (Elo rating) is decreased…
- Chess knowledge is attenuated or suppressed entirely.
- Search speed is decreased.
- Severity of move errors is increased.
- Chance of blundering and severity of blunders is increased.
These parameters are internal to the engine. They are not exposed as UCI options.
Update 2023 Jan 13: I’m experimenting with MadChess’ implementation of UCI_LimitStrength. The algorithms and engine parameter values described on this page are implemented in a beta version, available here. The 3.2 Beta version has no playing strength improvement over 3.1, and therefore, should not be tested for inclusion in rating lists.
Chess knowledge is controlled by engine parameters that affect how MadChess evaluates material and non-material aspects of a position.
Material evaluation terms are adjusted for ratings below 1000 Elo. These adjustments simulate a player who undervalues pawns and rooks, overvalues their queen, values knights and bishops equally, etc. See the ConfigureLimitedStrength method in the
Eval class for details.
Positive positional evaluation terms add to a material advantage or compensate for a material disadvantage. Likewise, negative positional evaluation terms detract from a material advantage or increase the degree to which a materially losing position is lost. MadChess evaluates passed pawns, king safety, piece location and mobility, and other positional terms.
At weaker playing strengths, positional evaluation terms are attenuated or suppressed entirely. This is accomplished by multiplying the evaluation term by a percentage that is linearly interpolated from 0% at the lowest rating (600 Elo) to 100% at the highest rating for the term. Each evaluation term is designated a rating range over which knowledge is gained. In effect…
- MadChess weakened to 600 Elo has no understanding of passed pawns or any other positional advantages or disadvantages.
- MadChess weakened to 1200 Elo fully understands passed pawns.
See the table below for details.
|Evaluation Term||Knowledge Percentage|
- Bonus given to each pawn or minor piece that threatens to capture a more valuable piece on its next move.
- Decrease endgame score based on difficulty to win. Or increase endgame score if winning side has many pawns. See the DetermineEndgameScale method in the
Evalclass for details.
Search speed is controlled by the internal Nodes Per Second (NPS) engine parameter. When contemplating a move, MadChess tracks how many positions (or “nodes”) it has examined and how much time has passed since the search began. If the search rate exceeds the NPS limit, MadChess stalls (going into a no-op loop) until enough time has passed for the search rate to drop below the NPS limit. The NPS limit (and Move Error, Blunder Error, and Blunder Percent) is calculated from a non-linear equation. See the ConfigureLimitedStrength method in the
Search class for details.
At weaker playing strengths, low search speed prevents MadChess from “seeing” too many moves ahead, causing it to overlook tactical sequences. At full strength, MadChess can search more than two million NPS. At 1000 Elo, MadChess searches two thousand NPS. See the table below for details.
Severity Of Move Errors
The severity of move errors is controlled by the internal Move Error and Blunder Error engine parameters. If Move Error or Blunder Error is greater than zero, MadChess performs a non-PVS search and randomly selects the best move or an inferior move. A “non-PVS search” means the alpha / beta window remains open at the root in order to determine exact scores for more than a single move.
- On every move MadChess may select a move that is from zero to Move Error centipawns worse than the best move.
- If blundering, MadChess may select a move that is from zero to Blunder Error centipawns worse than the best move. See Chance Of Blundering below.
Every move in the error range, plus the best move, has an equal chance of being played. For example, if three inferior moves exist in the error range, MadChess will play the best move 25% of the time (1 / 4). If four inferior moves exist in the error range, MadChess will play the best move 20% of the time (1 / 5). See the table below for details.
Move Error and Blunder Error are specified in centipawns, which is 1/100 the value of a pawn. How are positions scored in fractions of a pawn when piece values typically are scored as whole number multiples of a pawn?
One of the first lessons a new player is taught is the relative value of chess pieces: A knight and bishop = 3 pawns, a rook = 5 pawns, a queen = 9 pawns.
When MadChess assigns a score to a position, it considers material (pawns and pieces) but also considers other aspects of a position such as passed pawns, king safety, piece location and mobility, etc. These non-material aspects are scored in fractions of a pawn.
Chance Of Blundering
The chance of blundering is controlled by by the internal Blunder Percent engine parameter. On every move, MadChess determines whether it will blunder (play a poor move such as one that hangs a piece). If so, it uses the Blunder Error parameter when selecting an inferior move. Because a blunder is considered a severe move error, the value of the Blunder Error parameter is much greater than the value of the Move Error parameter. See the table below for details.
|Rating (Elo)||Search Speed (NPS)||Move Error||Blunder Error||Blunder Percent|
If you wish to see precise values of all engine parameters that affect playing strength, for any Elo rating from 600 – 2600, run MadChess from the command line. Enter the following commands:
debug on setoption name uci_limitstrength value true setoption name uci_elo value [Elo rating]
❯ .\MadChess.Engine.exe debug on setoption name uci_limitstrength value true info string LimitStrength = True, ELO = 600. info string NPS = 32, MoveError = 55, BlunderError = 341, BlunderPer128 = 21. info string MgPawnMaterial = 0 info string EgPawnMaterial = 0 info string MgKnightMaterial = 300 info string EgKnightMaterial = 620 info string MgBishopMaterial = 300 info string EgBishopMaterial = 620 info string MgRookMaterial = 335 info string EgRookMaterial = 716 info string MgQueenMaterial = 1296 info string EgQueenMaterial = 2737 info string LsPassedPawnsPer128 = 0 info string LsKingSafetyPer128 = 0 info string LsPieceLocationPer128 = 0 info string LsPieceMobilityPer128 = 0 info string LsPawnStructurePer128 = 0 info string LsThreatsPer128 = 0 info string LsMinorPiecesPer128 = 0 info string LsMajorPiecesPer128 = 0 info string LsEndgameScalePer128 = 0 setoption name uci_elo value 1075 info string LimitStrength = True, ELO = 1075. info string NPS = 6140, MoveError = 34, BlunderError = 185, BlunderPer128 = 14. info string MgPawnMaterial = 100 info string EgPawnMaterial = 153 info string MgKnightMaterial = 300 info string EgKnightMaterial = 620 info string MgBishopMaterial = 330 info string EgBishopMaterial = 655 info string MgRookMaterial = 500 info string EgRookMaterial = 1069 info string MgQueenMaterial = 975 info string EgQueenMaterial = 2058 info string LsPassedPawnsPer128 = 101 info string LsKingSafetyPer128 = 76 info string LsPieceLocationPer128 = 60 info string LsPieceMobilityPer128 = 50 info string LsPawnStructurePer128 = 43 info string LsThreatsPer128 = 38 info string LsMinorPiecesPer128 = 35 info string LsMajorPiecesPer128 = 35 info string LsEndgameScalePer128 = 33
Note percent parameters are not actually per “cent” (per 100) but per 128. This facilitates quick integer division. Because 128 is a power of two, the C# compiler transforms division by 128 to a shift of bits seven places to the right, a very fast operation on modern CPUs.