-
Notifications
You must be signed in to change notification settings - Fork 35
Variety
[cite_start]Standard chess engines are typically deterministic: given the same position, time control, and thread count, they will almost always play the exact same move[cite: 1080]. While efficient for analysis, this makes them predictable opponents and poor sparring partners.
[cite_start]ShashChess 41 introduces the Variety system, a stochastic mechanism integrated directly into the Quiescence Search[cite: 1082]. [cite_start]Unlike simple "MultiPV" randomization which picks suboptimal moves, Variety introduces controlled noise into the evaluation of leaf nodes, simulating human factors like "optimism" and "fighting spirit"[cite: 1083, 1084].
The logic is located within the search.cpp file. [cite_start]It modifies the static evaluation of a quiet position by adding a pseudo-random increment before returning it to the Alpha-Beta search tree[cite: 1086, 1087].
The system applies a dynamic bonus based on a Pseudo-Random Number Generator (PRNG). The formula ensures safety by being self-regulating:
[cite_start]$$Eval_{final} = Eval_{static} + \text{Random}(0, Limit - |Eval_{static}|)$$ [cite: 1090]
- Self-Regulating: If the position is exactly equal (0.00), the noise is maximal. [cite_start]As the position becomes decisive (won or lost), the noise decreases to zero[cite: 1110, 1111].
- Safety: This prevents the engine from hallucinating in clearly won or lost positions. [cite_start]It only adds "flavor" to balanced or unclear positions[cite: 1112, 1113].
- Optimism Bias: The increment is always added, never subtracted. [cite_start]This encourages the engine to be "optimistic," playing lines it might otherwise discard as too drawish[cite: 1114, 1115].
// Logic snippet from search.cpp
int maxValidIncrement = maxIncrement - std::abs(bestValue);
if (maxValidIncrement < 0) { maxValidIncrement = 0; }
// Inject randomness
int increment = static_cast<int>(rng.rand<uint64_t>() % (maxValidIncrement + 1));
bestValue += increment;The system offers three levels of operation via the UCI option Variety:
- Behavior: Standard deterministic engine behavior.
- Use Case: Precise analysis and engine-vs-engine rating testing where reproducibility is required.
- Limit: 13 centipawns (approx. 0.13 pawns).
- Effect: Adds a subtle noise layer. The engine remains objectively very strong with no measurable Elo loss, but it breaks deterministic loops.
- Use Case: Sparring partners, opening book generation, and avoiding identical games from the same starting position.
- Limit: 309 centipawns (approx. 3 pawns).
- Effect: Simulates a human player's "fighting spirit". In an objectively equal position (0.00), the engine might "believe" it has a significant advantage due to the noise.
This prompts the engine to play aggressively rather than steering for a draw. It may enter complications that are objectively unsound but practically difficult to refute.
- Use Case: Playing against humans to avoid "boring" computer draws or training to defend against speculative attacks.
The Variety option perfectly complements the Shashin philosophy:
The Psychological mode effectively forces the engine into Chaos Zones (where
By artificially inflating evaluations, it mimics the High Tal desire to complicate the game, rejecting the safety of Capablanca (stable) evaluations.
"Fewer Draws, More Fun." Even if the engine calculates a line to be a draw, the Psychological noise pushes it to continue playing for a win, simulating human ambition.