mirror of
https://github.com/sockspls/badfish
synced 2025-04-29 16:23:09 +00:00
UCI_Elo implementation (#2225)
This exploits the recent fractional Skill Level, and is a result from some discussion in #2221 and the older #758. Basically, if UCI_LimitStrength is set, it will internally convert UCI_Elo to a matching fractional Skill Level. The Elo estimate is based on games at TC 60+0.6, Hash 64Mb, 8moves_v3.pgn, rated with Ordo, anchored to goldfish1.13 (CCRL 40/4 ~2000). Note that this is mostly about internal consistency, the anchoring to CCRL is a bit weak, e.g. within this tournament, goldfish and sungorus only have a 200Elo difference, their rating difference on CCRL is 300Elo. I propose that we continue to expose 'Skill Level' as an UCI option, for backwards compatibility. The result of a tournament under those conditions are given by the following table, where the player name reflects the UCI_Elo. # PLAYER : RATING ERROR POINTS PLAYED (%) CFS(%) 1 Elo2837 : 2792.2 50.8 536.5 711 75 100 2 Elo2745 : 2739.0 49.0 487.5 711 69 100 3 Elo2654 : 2666.4 49.2 418.0 711 59 100 4 Elo2562 : 2604.5 38.5 894.5 1383 65 100 5 Elo2471 : 2515.2 38.1 651.5 924 71 100 6 Elo2380 : 2365.9 35.4 478.5 924 52 100 7 Elo2289 : 2290.0 28.0 864.0 1596 54 100 8 sungorus1.4 : 2204.9 27.8 680.5 1596 43 60 9 Elo2197 : 2201.1 30.1 523.5 924 57 100 10 Elo2106 : 2103.8 24.5 730.5 1428 51 100 11 Elo2014 : 2030.5 30.3 377.5 756 50 98 12 goldfish1.13 : 2000.0 ---- 511.0 1428 36 100 13 Elo1923 : 1928.5 30.9 641.5 1260 51 100 14 Elo1831 : 1829.0 42.1 370.5 756 49 100 15 Elo1740 : 1738.3 42.9 277.5 756 37 100 16 Elo1649 : 1625.0 42.1 525.5 1260 42 100 17 Elo1558 : 1521.5 49.9 298.0 756 39 100 18 Elo1467 : 1471.3 51.3 246.5 756 33 100 19 Elo1375 : 1407.1 51.9 183.0 756 24 --- It can be observed that all set Elos correspond within the error bars with the observed Ordo rating. No functional change
This commit is contained in:
parent
650aeaf242
commit
0dbc72d82e
3 changed files with 22 additions and 4 deletions
11
Readme.md
11
Readme.md
|
@ -55,7 +55,16 @@ Currently, Stockfish has the following UCI options:
|
|||
Leave at 1 for best performance.
|
||||
|
||||
* #### Skill Level
|
||||
Lower the Skill Level in order to make Stockfish play weaker.
|
||||
Lower the Skill Level in order to make Stockfish play weaker (see also UCI_LimitStrength).
|
||||
Internally, MultiPV is enabled, and with a certain probability depending on the Skill Level a
|
||||
weaker move will be played.
|
||||
|
||||
* #### UCI_LimitStrength
|
||||
Enable weaker play aiming for an Elo rating as set by UCI_Elo. This option overrides Skill Level.
|
||||
|
||||
* #### UCI_Elo
|
||||
If enabled by UCI_LimitStrength, aim for an engine strength of the given Elo.
|
||||
This Elo rating has been calibrated at a time control of 60s+0.6s and anchored to CCRL 40/4.
|
||||
|
||||
* #### Move Overhead
|
||||
Assume a time delay of x ms due to network and GUI overheads. This is useful to
|
||||
|
|
|
@ -271,7 +271,7 @@ void MainThread::search() {
|
|||
// Check if there are threads with a better score than main thread
|
||||
if ( Options["MultiPV"] == 1
|
||||
&& !Limits.depth
|
||||
&& !Skill(Options["Skill Level"]).enabled()
|
||||
&& !(Skill(Options["Skill Level"]).enabled() || Options["UCI_LimitStrength"])
|
||||
&& rootMoves[0].pv[0] != MOVE_NONE)
|
||||
{
|
||||
std::map<Move, int64_t> votes;
|
||||
|
@ -335,11 +335,18 @@ void Thread::search() {
|
|||
beta = VALUE_INFINITE;
|
||||
|
||||
multiPV = Options["MultiPV"];
|
||||
|
||||
// Pick integer skill levels, but non-deterministically round up or down
|
||||
// such that the average integer skill corresponds to the input floating point one.
|
||||
// UCI_Elo is converted to a suitable fractional skill level, using anchoring
|
||||
// to CCRL Elo (goldfish 1.13 = 2000) and a fit through Ordo derived Elo
|
||||
// for match (TC 60+0.6) results spanning a wide range of k values.
|
||||
PRNG rng(now());
|
||||
int intLevel = int(Options["Skill Level"]) +
|
||||
((Options["Skill Level"] - int(Options["Skill Level"])) * 1024 > rng.rand<unsigned>() % 1024 ? 1 : 0);
|
||||
double floatLevel = Options["UCI_LimitStrength"] ?
|
||||
clamp(std::pow((Options["UCI_Elo"] - 1346.6) / 143.4, 1 / 0.806), 0.0, 20.0) :
|
||||
double(Options["Skill Level"]);
|
||||
int intLevel = int(floatLevel) +
|
||||
((floatLevel - int(floatLevel)) * 1024 > rng.rand<unsigned>() % 1024 ? 1 : 0);
|
||||
Skill skill(intLevel);
|
||||
|
||||
// When playing with strength handicap enable MultiPV search that we will
|
||||
|
|
|
@ -74,6 +74,8 @@ void init(OptionsMap& o) {
|
|||
o["nodestime"] << Option(0, 0, 10000);
|
||||
o["UCI_Chess960"] << Option(false);
|
||||
o["UCI_AnalyseMode"] << Option(false);
|
||||
o["UCI_LimitStrength"] << Option(false);
|
||||
o["UCI_Elo"] << Option(1350, 1350, 2850);
|
||||
o["SyzygyPath"] << Option("<empty>", on_tb_path);
|
||||
o["SyzygyProbeDepth"] << Option(1, 1, 100);
|
||||
o["Syzygy50MoveRule"] << Option(true);
|
||||
|
|
Loading…
Add table
Reference in a new issue