The MadChess UCI_LimitStrength Algorithm

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 2022 Sep 30: 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

Chess knowledge is controlled by engine parameters that affect how MadChess evaluates material and non-material aspects of a position.

Positional Understanding

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
Rating (Elo) 600 800 1000 1200 1400 1600 1800 2000 2200 2300 2400
Passed Pawns 0% 33% 66% 100% 100% 100% 100% 100% 100% 100% 100%
King Safety 0% 25% 50% 75% 100% 100% 100% 100% 100% 100% 100%
Piece Location 0% 20% 40% 59% 80% 100% 100% 100% 100% 100% 100%
Piece Mobility 0% 16% 33% 50% 66% 83% 100% 100% 100% 100% 100%
Pawn Structure 0% 14% 28% 42% 57% 71% 85% 100% 100% 100% 100%
Threats1 0% 13% 25% 38% 50% 63% 75% 88% 100% 100% 100%
Minor Pieces 0% 12% 23% 35% 47% 59% 70% 82% 94% 100% 100%
Major Pieces 0% 12% 23% 35% 47% 59% 70% 82% 94% 100% 100%
Endgame Scaling2 0% 11% 22% 33% 44% 55% 66% 77% 88% 94% 100%
  1. Bonus given to each pawn or minor piece that threatens to capture a more valuable piece on its next move.
  2. Decrease endgame score based on difficulty to win. Or increase endgame score if winning side has many pawns. See the DetermineEndgameScale method in the Eval class for details.
Material Understanding

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.

Search Speed

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 less than 4,000 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 MultiPV search and randomly selects the best move or an inferior 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.

Centipawns

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
600 500 50 603 13
800 700 41 475 12
1000 3,700 33 366 11
1200 16,700 27 276 10
1400 51,700 21 204 9
1600 125,500 16 147 9
1800 259,700 12 106 8
2000 480,700 9 77 7
2200 819,700 6 59 6
2300 1,044,512 6 54 5
2400 1,312,700 5 51 5
2500 1,629,512 5 50 5
2600 2,000,500 5 50 5

Precise Values

If you wish to see the 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]

For example:

❯ .\MadChess.Engine.exe
debug on

setoption name uci_limitstrength value true
info string LimitStrength = True, ELO = 600.
info string NPS = 500, MoveError = 50, BlunderError = 603, BlunderPer128 = 16.
info string MgPawnMaterial = 0
info string EgPawnMaterial = 0
info string MgKnightMaterial = 300
info string EgKnightMaterial = 519
info string MgBishopMaterial = 300
info string EgBishopMaterial = 519
info string MgRookMaterial = 335
info string EgRookMaterial = 574
info string MgQueenMaterial = 1296
info string EgQueenMaterial = 2222
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 = 6863, MoveError = 31, BlunderError = 330, BlunderPer128 = 13.
info string MgPawnMaterial = 100
info string EgPawnMaterial = 127
info string MgKnightMaterial = 300
info string EgKnightMaterial = 519
info string MgBishopMaterial = 330
info string EgBishopMaterial = 545
info string MgRookMaterial = 500
info string EgRookMaterial = 858
info string MgQueenMaterial = 975
info string EgQueenMaterial = 1671
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

Comments are closed.