Skip to content

Commit 5201d08

Browse files
authored
Merge pull request #943 from ianfab/sf_15_1_wdl
Add SF 15.1 win rate model
2 parents 5673479 + b1de45e commit 5201d08

2 files changed

Lines changed: 18 additions & 3 deletions

File tree

chess/engine.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
try:
4646
from typing import Literal
47-
_WdlModel = Literal["sf", "sf15", "sf14", "sf12", "lichess"]
47+
_WdlModel = Literal["sf", "sf15.1", "sf15", "sf14", "sf12", "lichess"]
4848
except ImportError:
4949
# Before Python 3.8.
5050
_WdlModel = str # type: ignore
@@ -564,7 +564,8 @@ def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl:
564564
565565
:param model:
566566
* ``sf``, the WDL model used by the latest Stockfish
567-
(currently ``sf15``).
567+
(currently ``sf15.1``).
568+
* ``sf15.1``, the WDL model used by Stockfish 15.1.
568569
* ``sf15``, the WDL model used by Stockfish 15.
569570
* ``sf14``, the WDL model used by Stockfish 14.
570571
* ``sf12``, the WDL model used by Stockfish 12.
@@ -628,6 +629,16 @@ def __ge__(self, other: object) -> bool:
628629
return NotImplemented
629630

630631

632+
def _sf15_1_wins(cp: int, *, ply: int) -> int:
633+
# https://github.com/official-stockfish/Stockfish/blob/sf_15.1/src/uci.cpp#L200-L224
634+
# https://github.com/official-stockfish/Stockfish/blob/sf_15.1/src/uci.h#L38
635+
NormalizeToPawnValue = 361
636+
m = min(240, max(ply, 0)) / 64
637+
a = (((-0.58270499 * m + 2.68512549) * m + 15.24638015) * m) + 344.49745382
638+
b = (((-2.65734562 * m + 15.96509799) * m + -20.69040836) * m) + 73.61029937
639+
x = min(4000, max(cp * NormalizeToPawnValue / 100, -4000))
640+
return int(0.5 + 1000 / (1 + math.exp((a - x) / b)))
641+
631642
def _sf15_wins(cp: int, *, ply: int) -> int:
632643
# https://github.com/official-stockfish/Stockfish/blob/sf_15/src/uci.cpp#L200-L220
633644
m = min(240, max(ply, 0)) / 64
@@ -678,9 +689,12 @@ def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl:
678689
elif model == "sf14":
679690
wins = _sf14_wins(self.cp, ply=ply)
680691
losses = _sf14_wins(-self.cp, ply=ply)
681-
else:
692+
elif model == "sf15":
682693
wins = _sf15_wins(self.cp, ply=ply)
683694
losses = _sf15_wins(-self.cp, ply=ply)
695+
else:
696+
wins = _sf15_1_wins(self.cp, ply=ply)
697+
losses = _sf15_1_wins(-self.cp, ply=ply)
684698
draws = 1000 - wins - losses
685699
return Wdl(wins, draws, losses)
686700

test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2969,6 +2969,7 @@ def test_wdl_model(self):
29692969
self.assertEqual(chess.engine.Cp(131).wdl(model="sf12", ply=25), chess.engine.Wdl(524, 467, 9))
29702970
self.assertEqual(chess.engine.Cp(146).wdl(model="sf14", ply=25), chess.engine.Wdl(601, 398, 1))
29712971
self.assertEqual(chess.engine.Cp(40).wdl(model="sf15", ply=25), chess.engine.Wdl(58, 937, 5))
2972+
self.assertEqual(chess.engine.Cp(100).wdl(model="sf15.1", ply=64), chess.engine.Wdl(497, 503, 0))
29722973

29732974
@catchAndSkip(FileNotFoundError, "need stockfish")
29742975
def test_sf_forced_mates(self):

0 commit comments

Comments
 (0)