Skip to content

Commit

Permalink
Add sf16 WDL model
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasf committed Jul 8, 2023
1 parent 67aa18e commit c461118
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
18 changes: 15 additions & 3 deletions chess/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

try:
from typing import Literal
_WdlModel = Literal["sf", "sf15.1", "sf15", "sf14", "sf12", "lichess"]
_WdlModel = Literal["sf", "sf16", "sf15.1", "sf15", "sf14", "sf12", "lichess"]
except ImportError:
# Before Python 3.8.
_WdlModel = str # type: ignore
Expand Down Expand Up @@ -637,11 +637,20 @@ def __ge__(self, other: object) -> bool:
else:
return NotImplemented

def _sf16_wins(cp: int, *, ply: int) -> int:
# https://github.com/official-stockfish/Stockfish/blob/sf_16/src/uci.h#L38
NormalizeToPawnValue = 328
# https://github.com/official-stockfish/Stockfish/blob/sf_16/src/uci.cpp#L200-L224
m = min(240, max(ply, 0)) / 64
a = (((0.38036525 * m + -2.82015070) * m + 23.17882135) * m) + 307.36768407
b = (((-2.29434733 * m + 13.27689788) * m + -14.26828904) * m) + 63.45318330
x = min(4000, max(cp * NormalizeToPawnValue / 100, -4000))
return int(0.5 + 1000 / (1 + math.exp((a - x) / b)))

def _sf15_1_wins(cp: int, *, ply: int) -> int:
# https://github.com/official-stockfish/Stockfish/blob/sf_15.1/src/uci.cpp#L200-L224
# https://github.com/official-stockfish/Stockfish/blob/sf_15.1/src/uci.h#L38
NormalizeToPawnValue = 361
# https://github.com/official-stockfish/Stockfish/blob/sf_15.1/src/uci.cpp#L200-L224
m = min(240, max(ply, 0)) / 64
a = (((-0.58270499 * m + 2.68512549) * m + 15.24638015) * m) + 344.49745382
b = (((-2.65734562 * m + 15.96509799) * m + -20.69040836) * m) + 73.61029937
Expand Down Expand Up @@ -703,9 +712,12 @@ def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl:
elif model == "sf15":
wins = _sf15_wins(self.cp, ply=ply)
losses = _sf15_wins(-self.cp, ply=ply)
else:
elif model == "sf15.1":
wins = _sf15_1_wins(self.cp, ply=ply)
losses = _sf15_1_wins(-self.cp, ply=ply)
else:
wins = _sf16_wins(self.cp, ply=ply)
losses = _sf16_wins(-self.cp, ply=ply)
draws = 1000 - wins - losses
return Wdl(wins, draws, losses)

Expand Down
1 change: 1 addition & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3002,6 +3002,7 @@ def test_wdl_model(self):
self.assertEqual(chess.engine.Cp(146).wdl(model="sf14", ply=25), chess.engine.Wdl(601, 398, 1))
self.assertEqual(chess.engine.Cp(40).wdl(model="sf15", ply=25), chess.engine.Wdl(58, 937, 5))
self.assertEqual(chess.engine.Cp(100).wdl(model="sf15.1", ply=64), chess.engine.Wdl(497, 503, 0))
self.assertEqual(chess.engine.Cp(-52).wdl(model="sf16", ply=63), chess.engine.Wdl(0, 932, 68))

@catchAndSkip(FileNotFoundError, "need stockfish")
def test_sf_forced_mates(self):
Expand Down

0 comments on commit c461118

Please sign in to comment.