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. You may weaken MadChess’ playing strength by using the GUI’s Elo rating field or slider. This causes the GUI to set MadChess’ UCI_LimitStrength and UCI_Elo options. MadChess responds by calculating the value of the above engine parameters based on the selected Elo rating. Advanced users may wish to customize formulas used to calculate the above engine parameters. You may do so by modifying a JSON file included with MadChess. See the Advanced Configuration section below for details.

Simplicity Versus Control

Why two methods to weaken MadChess’ playing strength? (GUI’s Elo rating field and JSON file)

Well, most users want the simplicity of setting an Elo rating. Adding obscure engine parameters to UCI options would confuse most users, who would be left wondering, “Do I set Elo rating, or NPS, or Move Error, or… all of them?” Reducing UCI options that control playing strength to a single Elo rating creates the best experience for most users. If, however, you are a user who desires more control, you’ll be happy to learn MadChess grants such control. Follow instructions in the Advanced Configuration section below.

Have questions about limiting MadChess’ playing strength? Read the FAQ.

Chess Knowledge

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

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 Evaluation class for details.

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.

Positional Parameter Values by Rating
Evaluation Term                    Knowledge Percent

Rating (Elo)                       600   800  1000  1200  1400  1600  1800  2000  2200  2300  2400
==================================================================================================
Pawn Material Value                 0%  100%  100%  100%  100%  100%  100%  100%  100%  100%  100%
Knight and Bishop Material Value    0%   50%  100%  100%  100%  100%  100%  100%  100%  100%  100%
Rook and Queen Material Value       0%   50%  100%  100%  100%  100%  100%  100%  100%  100%  100%
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%   60%   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%
Threats                             0%   12%   25%   37%   50%   62%   75%   87%  100%  100%  100%
Minor Pieces                        0%   11%   23%   35%   47%   58%   70%   82%   94%  100%  100%
Major Pieces                        0%   11%   22%   33%   44%   55%   66%   77%   88%   94%  100%

Threats are a bonus given to each pawn or minor piece that threatens to capture a more valuable piece on its next move.

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 searches more than two million NPS. At 1000 Elo, MadChess searches seventeen hundred 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.

Regarding 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 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 or allows a tactical combination).  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.

Search Parameter Values by Rating
Rating (Elo)  Search Speed (NPS)  Move Error  Blunder Error  Blunder Percent
============================================================================
         600                 836         100            300             10.9
         800               1,028          82            252              9.4
        1000               1,751          67            210              8.1
        1200               3,857          54            172              6.9
        1400               8,999          42            140              5.9
        1600              20,071          32            112              5.1
        1800              41,754          24             90              4.3
        2000              81,180          18             72              3.8
        2200             148,732          13             60              3.4
        2300             197,414          12             55              3.2
        2400             258,972          10             52              3.1
        2600             431,710          10             50              3.1

NpsEndgamePer128 = 32

Unreasonable Inferior Moves

When selecting an inferior move to play, MadChess will exclude moves it considers unreasonable. This prevents MadChess, when weakened to a lower Elo rating, from playing dumb moves even a chess novice wouldn’t play. Unreasonable moves include…

  • A king or rook move that forfeits castling rights.
  • Moving a minor or major piece to a square attacked by enemy pawn(s).
  • Failing to recapture an equal or greater value minor or major piece.
  • Shuffling a piece between the same two squares.
  • Retreating a minor or major piece to own back rank.

This does not prevent MadChess from playing the best move even if it qualifies as unreasonable. See the IsInferiorMoveUnreasonable method in the Search class for details.

Precise Values

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:

> .\MadChess.Engine.exe

setoption name uci_limitstrength value true

debug on

setoption name uci_elo value 1075
info string LimitStrength = True, ELO = 1075.
info string NPS = 2312, MoveError = 62, BlunderError = 195, BlunderPer1024 = 78.
info string MgPawnMaterial = 100
info string EgPawnMaterial = 168
info string MgKnightMaterial = 449
info string EgKnightMaterial = 577
info string MgBishopMaterial = 470
info string EgBishopMaterial = 614
info string MgRookMaterial = 547
info string EgRookMaterial = 1112
info string MgQueenMaterial = 1368
info string EgQueenMaterial = 1958
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 = 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. Similarly, per 1024 values are transformed by the C# compiler to a bitshift 10 right .

Advanced Configuration

MadChess calculates a knowledge percent for positional evaluation parameters when the UCI_Elo option is set. You may alter the rating range over which knowledge is gained by adjusting the following values in the MadChess.AdvancedConfig.json file included with MadChess. Comments in the JSON file explain the positional knowledge percent formula.

You must restart MadChess for changes to the JSON file to take effect.

MadChess calculates the value of the following search parameters when the UCI_Elo option is set.

  • nodesPerSecond
  • moveError
  • blunderError
  • blunderPer1024

These values are calculated from a non-linear formula. You may alter the scale, power, and constant used to calculate each search parameter by adjusting the following values in the MadChess.AdvancedConfig.json file included with MadChess. Comments in the JSON file explain the search parameter formula.

You must restart MadChess for changes to the JSON file to take effect.

After adjusting positional evaluation rating ranges and search scales, powers, and constants, run MadChess from the command line. Enter the following command to see how your adjustments affect MadChess’ internal playing strength parameter values over its supported rating range of 600 – 2600 Elo.

Limit-Strength Parameter Values By Rating
> .\MadChess.Engine.exe

showlimitstrengthparams
Evaluation Term                    Knowledge Percent

Rating (Elo)                       600   800  1000  1200  1400  1600  1800  2000  2200  2300  2400
==================================================================================================
Pawn Material Value                 0%  100%  100%  100%  100%  100%  100%  100%  100%  100%  100%
Knight and Bishop Material Value    0%   50%  100%  100%  100%  100%  100%  100%  100%  100%  100%
Rook and Queen Material Value       0%   50%  100%  100%  100%  100%  100%  100%  100%  100%  100%
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%   60%   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%
Threats                             0%   12%   25%   37%   50%   62%   75%   87%  100%  100%  100%
Minor Pieces                        0%   11%   23%   35%   47%   58%   70%   82%   94%  100%  100%
Major Pieces                        0%   11%   22%   33%   44%   55%   66%   77%   88%   94%  100%

Rating (Elo)  Search Speed (NPS)  Move Error  Blunder Error  Blunder Percent
============================================================================
         600                 836         100            300             10.9
         800               1,028          82            252              9.4
        1000               1,751          67            210              8.1
        1200               3,857          54            172              6.9
        1400               8,999          42            140              5.9
        1600              20,071          32            112              5.1
        1800              41,754          24             90              4.3
        2000              81,180          18             72              3.8
        2200             148,732          13             60              3.4
        2300             197,414          12             55              3.2
        2400             258,972          10             52              3.1
        2600             431,710          10             50              3.1

NpsEndgamePer128: 32

NpsEndgamePer128 slows down MadChess’ search as a game progresses to the endgame phase. This prevents MadChess from “seeing” more moves ahead, for the same nodesPerSecond value, compared to the middlegame phase, simply because less pawns and pieces remain on the board (yielding less moves, per position, that must be searched).

Comments are closed.