From e87e3c792aabfab71e514ded1dfe0b0bfb23b927 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 31 Aug 2017 22:33:23 +0200 Subject: [PATCH 0001/1831] Accept Z0 for null move --- chess/__init__.py | 2 +- chess/pgn.py | 1 + data/pgn/anastasian-lewis.pgn | 20 ++++++++++++++++++++ test.py | 6 ++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 data/pgn/anastasian-lewis.pgn diff --git a/chess/__init__.py b/chess/__init__.py index 62a2a6722..4b9a23083 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2492,7 +2492,7 @@ def parse_san(self, san): match = SAN_REGEX.match(san) if not match: # Null moves. - if san == "--": + if san in ["--", "Z0"]: return Move.null() raise ValueError("invalid san: {0}".format(repr(san))) diff --git a/chess/pgn.py b/chess/pgn.py index e50eec86c..5ef62a9f7 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -89,6 +89,7 @@ [NBKRQ]?[a-h]?[1-8]?[\-x]?[a-h][1-8](?:=?[nbrqkNBRQK])? |[PNBRQK]?@[a-h][1-8] |-- + |Z0 |O-O(?:-O)? |0-0(?:-0)? ) diff --git a/data/pgn/anastasian-lewis.pgn b/data/pgn/anastasian-lewis.pgn new file mode 100644 index 000000000..04faad1e2 --- /dev/null +++ b/data/pgn/anastasian-lewis.pgn @@ -0,0 +1,20 @@ +[Event "World Senior Teams +50"] +[Site "Radebeul GER"] +[Date "2016.07.03"] +[Round "8.2"] +[White "Anastasian, A."] +[Black "Lewis, An"] +[Result "1-0"] +[ECO "E90"] +[WhiteElo "2532"] +[BlackElo "2269"] +[PlyCount "84"] +[EventDate "2016.06.26"] + +1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. h3 e5 7. d5 Na6 8. Be3 Nh5 +9. Nh2 Qe8 10. Be2 Nf4 11. Bf3 f5 12. a3 Nc5 13. Bxc5 dxc5 14. O-O Qe7 15. Re1 +a6 16. Ne2 Qd6 17. Nf1 Bd7 18. Rb1 b6 19. Nd2 Bh6 20. Nxf4 Bxf4 21. b4 Rae8 22. +Qc2 Rf6 23. Qc3 Qf8 24. Nb3 cxb4 25. axb4 Bg5 26. Rb2 Rf7 27. Nc1 Qh6 28. Nd3 +fxe4 29. Bxe4 Bxh3 30. gxh3 Qxh3 31. Bg2 Qh4 32. Re4 Qh5 33. Rbe2 Ref8 34. c5 +Bf4 35. Nxe5 Qh2+ 36. Kf1 Rf5 37. Nf3 Qh5 38. Re7 Bh6 39. R2e5 bxc5 40. bxc5 +Rxf3 41. Bxf3 Z0 42. Ke1 Qh1+ 1-0 diff --git a/test.py b/test.py index 3ac3dc009..779f09702 100755 --- a/test.py +++ b/test.py @@ -2122,6 +2122,12 @@ def test_cutechess_fischerrandom(self): self.assertTrue(board.chess960) self.assertEqual(board.fen(), "nbbrknrq/pppppppp/8/8/8/8/PPPPPPPP/NBBRKNRQ w KQkq - 0 1") + def test_z0(self): + with open("data/pgn/anastasian-lewis.pgn") as pgn: + game = chess.pgn.read_game(pgn) + board = game.end().board() + self.assertEqual(board.fen(), "5rk1/2p1R2p/p5pb/2PPR3/8/2Q2B2/5P2/4K2q w - - 3 43") + class CraftyTestCase(unittest.TestCase): From 078c1b7d2f5699cdb70492310365692d80d9d4bd Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Fri, 1 Sep 2017 02:32:21 +0530 Subject: [PATCH 0002/1831] Pulled Option & OptionMap classes into engine.py for common use --- chess/engine.py | 48 +++++++++++++++++++++++++++++++++++++++++++++++ chess/uci.py | 50 ++----------------------------------------------- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index b1f22dcd6..77a89c0df 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -57,6 +57,11 @@ class EngineStateException(Exception): pass +class Option(collections.namedtuple("Option", ["name", "type", "default", "min", "max", "var"])): + """Information about an available option for an UCI engine.""" + pass + + class MockProcess(object): def __init__(self, engine): self.engine = engine @@ -242,6 +247,49 @@ def __repr__(self): return "".format(hex(id(self)), self.pid()) +class OptionMap(collections.MutableMapping): + def __init__(self, data=None, **kwargs): + self._store = dict() + if data is None: + data = {} + self.update(data, **kwargs) + + def __setitem__(self, key, value): + self._store[key.lower()] = (key, value) + + def __getitem__(self, key): + return self._store[key.lower()][1] + + def __delitem__(self, key): + del self._store[key.lower()] + + def __iter__(self): + return (casedkey for casedkey, mappedvalue in self._store.values()) + + def __len__(self): + return len(self._store) + + def __eq__(self, other): + for key, value in self.items(): + if key not in other or other[key] != value: + return False + + for key, value in other.items(): + if key not in self or self[key] != value: + return False + + return True + + def copy(self): + return type(self)(self._store.values()) + + def __copy__(self): + return self.copy() + + def __repr__(self): + return "{0}({1})".format(type(self).__name__, dict(self.items())) + + def _popen_engine(command, engine_cls, setpgrp=False, _popen_lock=threading.Lock(), **kwargs): """ Opens a local chess engine process. diff --git a/chess/uci.py b/chess/uci.py index 3c1670ce6..9f06e4c79 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -21,6 +21,8 @@ from chess.engine import MockProcess from chess.engine import PopenProcess from chess.engine import SpurProcess +from chess.engine import Option +from chess.engine import OptionMap from chess.engine import LOGGER from chess.engine import FUTURE_POLL_TIMEOUT from chess.engine import _popen_engine @@ -37,11 +39,6 @@ import collections -class Option(collections.namedtuple("Option", ["name", "type", "default", "min", "max", "var"])): - """Information about an available option for an UCI engine.""" - pass - - class Score(collections.namedtuple("Score", ["cp", "mate"])): """A centipawns or mate score sent by an UCI engine.""" pass @@ -52,49 +49,6 @@ class BestMove(collections.namedtuple("BestMove", ["bestmove", "ponder"])): pass -class OptionMap(collections.MutableMapping): - def __init__(self, data=None, **kwargs): - self._store = dict() - if data is None: - data = {} - self.update(data, **kwargs) - - def __setitem__(self, key, value): - self._store[key.lower()] = (key, value) - - def __getitem__(self, key): - return self._store[key.lower()][1] - - def __delitem__(self, key): - del self._store[key.lower()] - - def __iter__(self): - return (casedkey for casedkey, mappedvalue in self._store.values()) - - def __len__(self): - return len(self._store) - - def __eq__(self, other): - for key, value in self.items(): - if key not in other or other[key] != value: - return False - - for key, value in other.items(): - if key not in self or self[key] != value: - return False - - return True - - def copy(self): - return type(self)(self._store.values()) - - def __copy__(self): - return self.copy() - - def __repr__(self): - return "{0}({1})".format(type(self).__name__, dict(self.items())) - - class InfoHandler(object): """ Chess engines may send information about their calculations with the From a9eb6a337471502361817a3ba50e02a6a496ec94 Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Fri, 1 Sep 2017 02:33:32 +0530 Subject: [PATCH 0003/1831] Initial FeatureMap commit. Needs testing --- chess/xboard.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/chess/xboard.py b/chess/xboard.py index f9c420d9d..d00de407c 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -23,6 +23,8 @@ from chess.engine import MockProcess from chess.engine import PopenProcess from chess.engine import SpurProcess +from chess.engine import Option +from chess.engine import OptionMap from chess.engine import LOGGER from chess.engine import FUTURE_POLL_TIMEOUT from chess.engine import _popen_engine @@ -142,6 +144,49 @@ def __exit__(self, exc_type, exc_value, traceback): self.release() +class FeatureMap(object): + def __init__(self): + # Populated with defaults to begin with + self._features = { + "ping" : 0, # TODO: Remove dependency of xboard module on ping + "setboard" : 0, + "playother" : 0, + "san" : 0, + "usermove" : 0, + "time" : 1, + "draw" : 1, + "sigint" : 1, + "sigterm" : 1, + "reuse" : 1, + "analyze" : 1, + "myname" : None, + "variants" : None, + "colors" : 1, + "ics" : 0, + "name" : None, + "pause" : 0, + "nps" : 1, + "debug" : 0, + "memory" : 0, + "smp" : 0, + "egt" : 0, + "option" : OptionMap(), + "done" : None + } + + def _set_feature(self, key, value): + try: + self._features[key] = value + except KeyError: + LOGGER.exception("exception looking up feature") + + def get(self, key): + try: + return self._features[key] + except KeyError: + LOGGER.exception("exception looking up feature") + + class Engine(object): def __init__(self, Executor=concurrent.futures.ThreadPoolExecutor): self.idle = True @@ -155,7 +200,7 @@ def __init__(self, Executor=concurrent.futures.ThreadPoolExecutor): self.name = None self.author = None - #self.options = OptionMap() + self.features = FeatureMap() self.pong = threading.Event() self.ping_num = None # TODO: Make this a pong Event local instead of data member self.pong_received = threading.Condition() @@ -183,6 +228,11 @@ def send_line(self, line): def on_line_received(self, buf): LOGGER.debug("%s >> %s", self.process, buf) + # Not too happy with this quasi-hack to prevent splitting within + # options' space-separated values + if buf.startswith("feature"): + return self._feature(buf[8:]) + command_and_args = buf.split() if not command_and_args: return @@ -209,6 +259,33 @@ def on_terminated(self): with self.state_changed: self.state_changed.notify_all() + def _feature(self, features): + """ + Does not conform to CECP spec regarding `done` and instead reads all + features atomically. + """ + if features.startswith("option"): + features = features.replace("\"", "") + params = features.split("=")[1].split() + name = params[0] + type = params[1][1:] + default = int(params[2]) + min = int(params[3]) + max = int(params[4]) + var = [] #TODO: Add support + option = Option(name, type, default, min, max, var) + self.features._features["option"][option.name] = option + return + + features = features.split() + feature_map = [ feature.split("=") for feature in features ] + for (key, value) in feature_map: + value = value.strip("\"") + if key == "variant": + self.features._set_feature(key, value.split(",")) + else: + self.features._set_feature(key, value) + def _pong(self, pong_arg): try: pong_num = int(pong_arg) From ec35a87b1042017c8cfb4d8cfac74d214324840d Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Sat, 2 Sep 2017 17:46:16 +0530 Subject: [PATCH 0004/1831] Parsing integer feature values properly and added checks before feature-specific API calls --- chess/xboard.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/chess/xboard.py b/chess/xboard.py index d00de407c..6f0a9fae7 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -175,6 +175,11 @@ def __init__(self): } def _set_feature(self, key, value): + try: + value = int(value) + except ValueError: + pass + try: self._features[key] = value except KeyError: @@ -186,6 +191,9 @@ def get(self, key): except KeyError: LOGGER.exception("exception looking up feature") + def supports(self, key): + return self.get(key) == 1 + class Engine(object): def __init__(self, Executor=concurrent.futures.ThreadPoolExecutor): @@ -482,7 +490,7 @@ def xboard(self, async_callback=None): def command(): with self.semaphore: self.send_line("xboard") - self.send_line("protover 2") # TODO: Add option for this and parse input + self.send_line("protover 2") if self.terminated.is_set(): raise EngineTerminatedException() @@ -562,6 +570,9 @@ def memory(self, amount, async_callback=None): :return: Nothing """ + if not self.features.supports("memory"): + raise EngineStateException("engine does not support the 'memory' feature") + with self.state_changed: if not self.idle: raise EngineStateException("memory command while engine is busy") @@ -584,6 +595,9 @@ def cores(self, num, async_callback=None): :return: Nothing """ + if not self.features.supports("smp"): + raise EngineStateException("engine does not support the 'smp' feature") + with self.state_changed: if not self.idle: raise EngineStateException("cores command while engine is busy") @@ -603,6 +617,9 @@ def playother(self, async_callback=None): :return: Nothing """ + if not self.features.supports("playother"): + raise EngineStateException("engine does not support the 'playother' feature") + with self.state_changed: if not self.idle: raise EngineStateException("playother command while engine is busy") @@ -667,6 +684,9 @@ def time(self, time, async_callback=None): :return: Nothing """ + if not self.features.supports("time"): + raise EngineStateException("engine does not support the 'time' feature") + with self.state_changed: if not self.idle: raise EngineStateException("time command while engine is busy") @@ -816,6 +836,9 @@ def usermove(self, move, async_callback=None): :return: Nothing """ + if not self.features.supports("usermove"): + raise EngineStateException("engine does not support the 'usermove' feature") + if self.auto_force: self.force() elif not self.in_force: From b3a5a88fc9d2e976c125b9f26d94e9b39a976e58 Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Sat, 2 Sep 2017 18:24:43 +0530 Subject: [PATCH 0005/1831] Prepending usermove when feature supported --- chess/xboard.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/chess/xboard.py b/chess/xboard.py index 6f0a9fae7..419463005 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -836,8 +836,9 @@ def usermove(self, move, async_callback=None): :return: Nothing """ - if not self.features.supports("usermove"): - raise EngineStateException("engine does not support the 'usermove' feature") + builder = [] + if self.features.supports("usermove"): + builder.append("usermove") if self.auto_force: self.force() @@ -862,12 +863,10 @@ def usermove(self, move, async_callback=None): except ValueError: LOGGER.exception("exception parsing move") - builder = [] - builder.append("usermove") - builder.append(move) + builder.append(str(move)) def command(): # Use the join(builder) once we parse usermove=1 feature - move_str = str(move)#" ".join(builder) + move_str = " ".join(builder) if self.in_force: with self.semaphore: self.send_line(move_str) From d19e1faa349c0699d2070ab89817d806409b5540 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 2 Sep 2017 15:56:43 +0200 Subject: [PATCH 0006/1831] Test a wierd PGN header --- test.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test.py b/test.py index 779f09702..25aedd3c4 100755 --- a/test.py +++ b/test.py @@ -2128,6 +2128,11 @@ def test_z0(self): board = game.end().board() self.assertEqual(board.fen(), "5rk1/2p1R2p/p5pb/2PPR3/8/2Q2B2/5P2/4K2q w - - 3 43") + def test_wierd_header(self): + pgn = StringIO(r"""[Black "[=0040.34h5a4]"]""") + game = chess.pgn.read_game(pgn) + self.assertEqual(game.headers["Black"], "[=0040.34h5a4]") + class CraftyTestCase(unittest.TestCase): From c25caf9c13084ce23e0b1b9d7e8935672d8a4b75 Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Mon, 4 Sep 2017 21:46:26 +0530 Subject: [PATCH 0007/1831] Added api for modifying engine options and some tests with wyld --- .travis.yml | 6 ++++++ chess/xboard.py | 42 +++++++++++++++++++++++++++++++++++++++--- test.py | 34 ++++++++++++++++++++++++---------- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 27730b944..4abf7fb61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,12 @@ before_install: - make unix-gcc - export PATH="`pwd`:${PATH}" - cd .. + - # WyldChess + - git clone https://github.com/Mk-Chan/WyldChess + - cd WyldChess/src + - make + - export PATH="`pwd`:${PATH}" + - cd ../.. - # Gaviota libgtb - git clone https://github.com/michiguel/Gaviota-Tablebases.git --depth 1 - cd Gaviota-Tablebases diff --git a/chess/xboard.py b/chess/xboard.py index 419463005..1ca79f3d6 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -145,6 +145,7 @@ def __exit__(self, exc_type, exc_value, traceback): class FeatureMap(object): + def __init__(self): # Populated with defaults to begin with self._features = { @@ -501,12 +502,47 @@ def command(): return self._queue_command(command, async_callback) + def option(self, options, async_callback=None): + """ + Set values for the engines available options. + + :param options: A dictionary with option names as keys. + + :return: Nothing + """ + option_lines = [] + + for name, value in options.items(): + # Building string manually to avoid spaces + option_string = "option " + name + option = self.features._features["option"][name] + has_value = option.type in \ + ("spin", "check", "combo", "string") + if has_value and value is not None: + value = str(value) + option_string += "=" + value + option_lines.append(option_string) + elif not has_value and value is None: + option_lines.append(option_string) + pass + + def command(): + with self.semaphore: + with self.pong_received: + for option_line in option_lines: + self.send_line(option_line) + + if self.terminated.is_set(): + raise EngineTerminatedException() + + return self._queue_command(command, async_callback) + def new(self, async_callback=None): """ Reset the board to the standard chess starting position. Set White on move. Leave force mode and set the engine to play Black. - Associate the engine's clock with Black and the opponent's clock + Associate the engines clock with Black and the opponent's clock with White. Reset clocks and time controls to the start of a new game. Use wall clock for time measurement. @@ -564,7 +600,7 @@ def command(): def memory(self, amount, async_callback=None): """ - Set the maximum memory of the engine's hash/pawn/bitbase/etc tables. + Set the maximum memory of the engines hash/pawn/bitbase/etc tables. :param amount: Maximum amount of memory to use in MegaBytes @@ -678,7 +714,7 @@ def command(): def time(self, time, async_callback=None): """ - Synchronize the engine's clock with the total amount of time left. + Synchronize the engines clock with the total amount of time left. :param time: The total time left in centiseconds diff --git a/test.py b/test.py index 25aedd3c4..9a76c16b8 100755 --- a/test.py +++ b/test.py @@ -2134,6 +2134,30 @@ def test_wierd_header(self): self.assertEqual(game.headers["Black"], "[=0040.34h5a4]") +class WyldTestCase(unittest.TestCase): + + def setUp(self): + try: + self.engine = chess.xboard.popen_engine("wyldchess") + except OSError: + self.skipTest("need wyldchess") + + self.engine.xboard() + + def tearDown(self): + self.engine.quit() + + def test_options(self): + self.engine.new() + self.engine.st(2) + self.engine.sd(100) + option_dict = { "MoveOverhead" : 1900 }; + self.engine.option(option_dict) + self.engine.go(async_callback=True) + time.sleep(0.2) + self.assertTrue(self.engine.idle, True) + + class CraftyTestCase(unittest.TestCase): def setUp(self): @@ -2148,16 +2172,6 @@ def setUp(self): def tearDown(self): self.engine.quit() - def test_st(self): - self.engine.new() - self.engine.st(1) - self.engine.go() - - def test_sd(self): - self.engine.new() - self.engine.sd(5) - self.engine.go() - def test_level(self): self.engine.new() self.engine.level(1, 0, 1, 0) From 257f1fcd8dd799ef33ffa400efad9116325a81ef Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Tue, 5 Sep 2017 22:24:08 +0530 Subject: [PATCH 0008/1831] Added support for combo option --- chess/xboard.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/chess/xboard.py b/chess/xboard.py index 1ca79f3d6..697e67eb2 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -211,7 +211,7 @@ def __init__(self, Executor=concurrent.futures.ThreadPoolExecutor): self.author = None self.features = FeatureMap() self.pong = threading.Event() - self.ping_num = None # TODO: Make this a pong Event local instead of data member + self.ping_num = None self.pong_received = threading.Condition() self.auto_force = False self.in_force = False @@ -278,10 +278,25 @@ def _feature(self, features): params = features.split("=")[1].split() name = params[0] type = params[1][1:] - default = int(params[2]) - min = int(params[3]) - max = int(params[4]) - var = [] #TODO: Add support + min = None + max = None + var = [] + if type == "combo": + choices = params[2:] + for choice in choices: + if choice == "///": + continue + elif choice[0] == "*": + default = choice[1:] + var.append(choice[1:]) + else: + var.append(choice) + print(var) + print(default) + else: + default = int(params[2]) + min = int(params[3]) + max = int(params[4]) option = Option(name, type, default, min, max, var) self.features._features["option"][option.name] = option return @@ -524,7 +539,6 @@ def option(self, options, async_callback=None): option_lines.append(option_string) elif not has_value and value is None: option_lines.append(option_string) - pass def command(): with self.semaphore: From 4fad365aa4dba006b6a311ebfc16b7dc634f3b87 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 5 Sep 2017 21:25:35 +0200 Subject: [PATCH 0009/1831] Factor out _edges --- chess/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 4b9a23083..5780476b1 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -280,6 +280,10 @@ def _sliding_attacks(square, occupied, deltas): BB_PAWN_ATTACKS = [[_sliding_attacks(sq, BB_ALL, deltas) for sq in SQUARES] for deltas in [[-7, -9], [7, 9]]] +def _edges(square): + return (((BB_RANK_1 | BB_RANK_8) & ~BB_RANKS[square_rank(square)]) | + ((BB_FILE_A | BB_FILE_H) & ~BB_FILES[square_file(square)])) + def _attack_table(deltas): mask_table = [] attack_table = [] @@ -287,12 +291,8 @@ def _attack_table(deltas): for square, bb in enumerate(BB_SQUARES): attacks = {} - edges = (((BB_RANK_1 | BB_RANK_8) & ~BB_RANKS[square_rank(square)]) | - ((BB_FILE_A | BB_FILE_H) & ~BB_FILES[square_file(square)])) - - mask = _sliding_attacks(square, 0, deltas) & ~edges - # Carry-Rippler trick to iterate subsets of mask. + mask = _sliding_attacks(square, 0, deltas) & ~_edges(square) subset = 0 while True: attacks[subset] = _sliding_attacks(square, subset, deltas) From a1a264ed5f83a96818b9ec525348e5442f6b1a59 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 21:12:53 +0200 Subject: [PATCH 0010/1831] Add Board.has_pseudo_legal_en_passant --- chess/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index 5780476b1..507a22b4d 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1952,6 +1952,10 @@ def castling_xfen(self): else: return "-" + def has_pseudo_legal_en_passant(self): + """Checks if there is a pseudo legal en passant capture.""" + return self.ep_square is not None and any(self.generate_pseudo_legal_ep()) + def has_legal_en_passant(self): """Checks if there is a legal en passant capture.""" return self.ep_square is not None and any(self.generate_legal_ep()) From 367e526912c53c66dce095c02cfea396f73f6c58 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 21:20:47 +0200 Subject: [PATCH 0011/1831] Factor out minimal ep square validation --- chess/__init__.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 507a22b4d..20ba13240 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2840,6 +2840,16 @@ def status(self): errors |= STATUS_BAD_CASTLING_RIGHTS # En passant. + if self.ep_square != self._valid_ep_square(): + errors |= STATUS_INVALID_EP_SQUARE + + # Side to move giving check. + if self.was_into_check(): + errors |= STATUS_OPPOSITE_CHECK + + return errors + + def _valid_ep_square(self): if self.ep_square: if self.turn == WHITE: ep_rank = 5 @@ -2852,26 +2862,22 @@ def status(self): # The en passant square must be on the third or sixth rank. if square_rank(self.ep_square) != ep_rank: - errors |= STATUS_INVALID_EP_SQUARE + return # The last move must have been a double pawn push, so there must # be a pawn of the correct color on the fourth or fifth rank. if not self.pawns & self.occupied_co[not self.turn] & pawn_mask: - errors |= STATUS_INVALID_EP_SQUARE + return # And the en passant square must be empty. if self.occupied & BB_SQUARES[self.ep_square]: - errors |= STATUS_INVALID_EP_SQUARE + return # And the second rank must be empty. if self.occupied & seventh_rank_mask: - errors |= STATUS_INVALID_EP_SQUARE - - # Side to move giving check. - if self.was_into_check(): - errors |= STATUS_OPPOSITE_CHECK + return - return errors + return self.ep_square def is_valid(self): """ From 1b399e51214fd81ad2f2ca373a57962df7734de9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 21:25:06 +0200 Subject: [PATCH 0012/1831] Relax ep square validation in Board.set_fen --- chess/__init__.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 20ba13240..295a883a4 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2021,12 +2021,8 @@ def set_fen(self, fen): # Check that the en passant part is valid. if parts[3] != "-": - if parts[1] == "w": - if square_rank(SQUARE_NAMES.index(parts[3])) != 5: - raise ValueError("expected ep square to be on sixth rank: {0}".format(repr(fen))) - else: - if square_rank(SQUARE_NAMES.index(parts[3])) != 2: - raise ValueError("expected ep square to be on third rank: {0}".format(repr(fen))) + if parts[3] not in SQUARE_NAMES: + raise ValueError("invalid en passant part in fen: {0}".format(repr(fen))) # Check that the half move part is valid. if int(parts[4]) < 0: From 7abc2c632cf247e4dc8baea7e0e44ef935a19aa4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 22:16:15 +0200 Subject: [PATCH 0013/1831] Rewrite FEN formatting options (fixes #162) --- chess/__init__.py | 64 ++++++++++++++++++++++++++--------------------- chess/variant.py | 8 +++--- test.py | 6 +++++ 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 295a883a4..4ecebff58 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1960,42 +1960,41 @@ def has_legal_en_passant(self): """Checks if there is a legal en passant capture.""" return self.ep_square is not None and any(self.generate_legal_ep()) - def fen(self, promoted=None): + def fen(self, shredder=False, en_passant="legal", promoted=None): """ - Gets the FEN representation of the position. + Gets a FEN representation of the position. A FEN string (e.g. ``rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1``) consists - of the position part (:func:`~chess.Board.board_fen()`), the turn, - the castling part (:func:`~chess.Board.castling_xfen()`), a relevant - en passant square (:data:`~chess.Board.ep_square`, - :func:`~chess.Board.has_legal_en_passant()`), the halfmove clock - and the fullmove number. - - Optionally designates *promoted* pieces with a ``~`` before - their symbol. + of the position part :func:`~chess.Board.board_fen()`, the + :data:`~chess.Board.turn`, the castling part + (:data:`~chess.Board.castling_rights`), + the en passant square (:data:`~chess.Board.ep_square`), + the :data:`~chess.Board.halfmove_clock` + and the :data:`~chess.Board.fullmove_number`. + + :param shredder: Use :func:`~chess.Board.castling_shredder_fen()` + and encode castling rights by the file of the rook + (like ``HAha``) instead of the default + :func:`~chess.Board.castling_xfen()` (like ``KQkq``). + :param en_passant: By default only fully legal en passant squares + are included (:func:`~chess.Board.has_legal_en_passant()`). + Pass ``fen`` to strictly follow the FEN spec + (always include the en passant square after a double pawn move) + or ``xfen`` to follow the X-FEN spec + (:func:`~chess.Board.has_pseudo_legal_en_passant()`). + :param promoted: Mark promoted pieces like ``Q~``. By default this is + only enabled in chess variants where this is relevant. """ return " ".join([ - self.epd(promoted=promoted), + self.epd(shredder=shredder, en_passant=en_passant, promoted=promoted), str(self.halfmove_clock), str(self.fullmove_number) ]) - def shredder_fen(self, promoted=None): - """ - Gets the Shredder FEN representation of the position. - - Castling rights are encoded by the file of the rook. The starting - castling rights in normal chess are HAha. - - Use :func:`~chess.Board.castling_shredder_fen()` to get just the - castling part. - - Optionally designates *promoted* pieces with a ``~`` before - their symbol. - """ + def shredder_fen(self, en_passant="legal", promoted=None): return " ".join([ - self.epd(shredder_fen=True, promoted=promoted), + self.epd(shredder=True, en_passant=en_passant, promoted=promoted), str(self.halfmove_clock), str(self.fullmove_number) ]) @@ -2201,10 +2200,13 @@ def _epd_operations(self, operations): return "".join(epd) - def epd(self, shredder_fen=False, promoted=None, **operations): + def epd(self, shredder=False, en_passant="legal", promoted=None, **operations): """ Gets an EPD representation of the current position. + See :func:`~chess.Board.fen()` for FEN formatting options (*shredder*, + *ep_square* and *promoted*). + EPD operations can be given as keyword arguments. Supported operands are strings, integers, floats and moves and lists of moves and None. All other operands are converted to strings. @@ -2221,8 +2223,14 @@ def epd(self, shredder_fen=False, promoted=None, **operations): epd.append(self.board_fen(promoted=promoted)) epd.append("w" if self.turn == WHITE else "b") - epd.append(self.castling_shredder_fen() if shredder_fen else self.castling_xfen()) - epd.append(SQUARE_NAMES[self.ep_square] if self.has_legal_en_passant() else "-") + epd.append(self.castling_shredder_fen() if shredder else self.castling_xfen()) + + if en_passant == "fen": + epd.append(SQUARE_NAMES[self.ep_square] if self.ep_square is not None else "-") + elif en_passant == "xfen": + epd.append(SQUARE_NAMES[self.ep_square] if self.has_pseudo_legal_en_passant() else "-") + else: + epd.append(SQUARE_NAMES[self.ep_square] if self.has_legal_en_passant() else "-") if operations: epd.append(self._epd_operations(operations)) diff --git a/chess/variant.py b/chess/variant.py index 663530dff..cf3373d24 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -550,9 +550,9 @@ def set_fen(self, fen): self.remaining_checks[chess.WHITE] = wc self.remaining_checks[chess.BLACK] = bc - def epd(self, shredder_fen=False, promoted=None, **operations): + def epd(self, shredder=False, en_passant="legal", promoted=None, **operations): epd = [] - epd.append(super(ThreeCheckBoard, self).epd(shredder_fen=shredder_fen, promoted=promoted)) + epd.append(super(ThreeCheckBoard, self).epd(shredder=shredder, en_passant=en_passant, promoted=promoted)) epd.append("%d+%d" % (max(self.remaining_checks[chess.WHITE], 0), max(self.remaining_checks[chess.BLACK], 0))) if operations: epd.append(self._epd_operations(operations)) @@ -782,8 +782,8 @@ def board_fen(self, promoted=None): promoted = True return super(CrazyhouseBoard, self).board_fen(promoted=promoted) - def epd(self, shredder_fen=False, promoted=None, **operations): - epd = super(CrazyhouseBoard, self).epd(shredder_fen=shredder_fen, promoted=promoted) + def epd(self, shredder=False, en_passant="legal", promoted=None, **operations): + epd = super(CrazyhouseBoard, self).epd(shredder=shredder, en_passant=en_passant, promoted=promoted) board_part, info_part = epd.split(" ", 1) return "%s[%s%s] %s" % (board_part, str(self.pockets[chess.WHITE]).upper(), str(self.pockets[chess.BLACK]), info_part) diff --git a/test.py b/test.py index 9a76c16b8..90e82d660 100755 --- a/test.py +++ b/test.py @@ -254,6 +254,12 @@ def test_xfen(self): board = chess.Board(fen) self.assertEqual(board.fen(), "1r6/8/8/pP6/8/8/8/1K6 w - - 0 1") + def test_fen_en_passant(self): + board = chess.Board() + board.push_san("e4") + self.assertEqual(board.fen(en_passant="fen"), "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1") + self.assertEqual(board.fen(en_passant="xfen"), "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1") + def test_get_set(self): board = chess.Board() self.assertEqual(board.piece_at(chess.B1), chess.Piece.from_symbol("N")) From 128a4b668f59a6c8a1331120ee828a795c45a09f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 22:55:12 +0200 Subject: [PATCH 0014/1831] Document Board.promoted --- docs/core.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/core.rst b/docs/core.rst index 6344a67f3..17467aa99 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -146,6 +146,10 @@ Board The number of half moves since the last capture or pawn move. + .. py:attribute:: promoted + + A bitmask of pieces that have been promoted. + .. py:attribute:: chess960 Whether the board is in Chess960 mode. In Chess960 castling moves are From 39f0ed2cfe797d3e9311b4d1d955dc4d9952ddf8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 23:19:03 +0200 Subject: [PATCH 0015/1831] Add BB_CORNERS --- chess/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 4ecebff58..7eb9c7de6 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -135,6 +135,8 @@ def square_mirror(square): BB_A8, BB_B8, BB_C8, BB_D8, BB_E8, BB_F8, BB_G8, BB_H8 ] = [1 << sq for sq in SQUARES] +BB_CORNERS = BB_A1 | BB_H1 | BB_A8 | BB_H8 + BB_LIGHT_SQUARES = 0x55aa55aa55aa55aa BB_DARK_SQUARES = 0xaa55aa55aa55aa55 @@ -542,7 +544,7 @@ def _reset_board(self): self.pawns = BB_RANK_2 | BB_RANK_7 self.knights = BB_B1 | BB_G1 | BB_B8 | BB_G8 self.bishops = BB_C1 | BB_F1 | BB_C8 | BB_F8 - self.rooks = BB_A1 | BB_H1 | BB_A8 | BB_H8 + self.rooks = BB_CORNERS self.queens = BB_D1 | BB_D8 self.kings = BB_E1 | BB_E8 @@ -1171,7 +1173,7 @@ def __init__(self, fen=STARTING_FEN, chess960=False): def reset(self): """Restores the starting position.""" self.turn = WHITE - self.castling_rights = BB_A1 | BB_H1 | BB_A8 | BB_H8 + self.castling_rights = BB_CORNERS self.ep_square = None self.halfmove_clock = 0 self.fullmove_number = 1 @@ -2771,7 +2773,7 @@ def has_chess960_castling_rights(self): # Standard chess castling rights can only be on the standard # starting rook squares. - if castling_rights & ~(BB_A1 | BB_A8 | BB_H1 | BB_H8): + if castling_rights & ~BB_CORNERS: return True # If there are any castling rights in standard chess, the king must be From 5e2ca0e4e6889a95c951bff51ece6acc96389c77 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 23:34:43 +0200 Subject: [PATCH 0016/1831] Add BaseBoard.set_pieces and BaseBoard.pieces --- chess/__init__.py | 23 +++++++++++++++++++++++ test.py | 8 ++++++++ 2 files changed, 31 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index 7eb9c7de6..f1df05b90 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -798,6 +798,25 @@ def set_board_fen(self, fen): """ self._set_board_fen(fen) + def pieces(self): + """Gets a dictionary of :class:`~chess.Piece`s indexed by squares.""" + result = {} + for square in scan_reversed(self.occupied): + result[square] = self.piece_at(square) + return result + + def _set_pieces(self, pieces): + self._clear_board() + for square, piece in pieces.items(): + self._set_piece_at(square, piece.piece_type, piece.color) + + def set_pieces(self, pieces): + """ + Sets up the board from a dictionary of :class:`~chess.Piece`s + indexed by squares. + """ + self._set_pieces(pieces) + def _set_chess960_pos(self, sharnagl): if not 0 <= sharnagl <= 959: raise ValueError("chess960 position index not 0 <= {0} <= 959".format(repr(sharnagl))) @@ -2106,6 +2125,10 @@ def set_board_fen(self, fen): super(Board, self).set_board_fen(fen) self.clear_stack() + def set_pieces(self, pieces): + super(Board, self).set_pieces(pieces) + self.clear_stack() + def set_chess960_pos(self, sharnagl): super(Board, self).set_chess960_pos(sharnagl) self.chess960 = True diff --git a/test.py b/test.py index 90e82d660..3b0172238 100755 --- a/test.py +++ b/test.py @@ -1392,6 +1392,14 @@ def test_set_chess960_pos(self): self.assertEqual(board.board_fen(), "rkrnnqbb/pppppppp/8/8/8/8/PPPPPPPP/RKRNNQBB") self.assertEqual(board.chess960_pos(), 959) + def test_set_pieces(self): + a = chess.BaseBoard.empty() + b = chess.BaseBoard() + a.set_pieces(b.pieces()) + self.assertEqual(a, b) + a.set_pieces({}) + self.assertNotEqual(a, b) + class SquareSetTestCase(unittest.TestCase): From 2364586c16a485a039539a001a852c395065900d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 23:41:27 +0200 Subject: [PATCH 0017/1831] Document it is safe to set Board properties --- chess/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index f1df05b90..92a8c4390 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1155,6 +1155,10 @@ class Board(BaseBoard): by a king move to the corresponding rook square. Use :func:`chess.Board.from_chess960_pos()` to create a board with one of the Chess960 starting positions. + + Its safe to set :data:`~Board.turn`, :data:`~Board.castling_rights`, + :data:`~Board.ep_square`, :data:`~Board.halfmove_clock` and + :data:`~Board.fullmove_number` directly. """ aliases = ["Standard", "Chess", "Classical", "Normal"] From 10926b92c76d64c58ba1eb5dcce35cfe8f567a6b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 23:47:00 +0200 Subject: [PATCH 0018/1831] Document how to set castling rights --- docs/core.rst | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/core.rst b/docs/core.rst index 17467aa99..c579594a0 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -121,14 +121,21 @@ Board Bitmask of the rooks with castling rights. - >>> white_castle_kingside = board.castling_rights & chess.BB_H1 + To test for specific squares: - Also see :func:`~chess.Board.has_castling_rights()`, + >>> board.castling_rights & chess.BB_H1 + True # White can castle kingside with the h1 rook + + To add a specific square: + + >>> board.castling_rights |= chess.BB_A1 + + Use :func:`~chess.Board.set_castling_fen()` to set multiple castling + rights. Also see :func:`~chess.Board.has_castling_rights()`, :func:`~chess.Board.has_kingside_castling_rights()`, :func:`~chess.Board.has_queenside_castling_rights()`, :func:`~chess.Board.has_chess960_castling_rights()`, - :func:`~chess.Board.clean_castling_rights()` and - :func:`~chess.Board.set_castling_fen()`. + :func:`~chess.Board.clean_castling_rights()`. .. py:attribute:: ep_square From ad70cd2b90c2837d262d546f2f8041b4d2e6fc9c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 23:50:52 +0200 Subject: [PATCH 0019/1831] Fix pieces and set_pieces docs --- chess/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 92a8c4390..9b1f94693 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -799,7 +799,9 @@ def set_board_fen(self, fen): self._set_board_fen(fen) def pieces(self): - """Gets a dictionary of :class:`~chess.Piece`s indexed by squares.""" + """ + Gets a dictionary of :class:`pieces ` by square index. + """ result = {} for square in scan_reversed(self.occupied): result[square] = self.piece_at(square) @@ -812,8 +814,8 @@ def _set_pieces(self, pieces): def set_pieces(self, pieces): """ - Sets up the board from a dictionary of :class:`~chess.Piece`s - indexed by squares. + Sets up the board from a dictionary of :class:`pieces ` + by square index. """ self._set_pieces(pieces) From f2e28e24d999e67e1e83ebd68df3653fe45c1e18 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Sep 2017 23:59:41 +0200 Subject: [PATCH 0020/1831] Rename to piece_map (pieces was taken) (#149) --- chess/__init__.py | 12 ++++++------ test.py | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 9b1f94693..3e0126588 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -798,7 +798,7 @@ def set_board_fen(self, fen): """ self._set_board_fen(fen) - def pieces(self): + def piece_map(self): """ Gets a dictionary of :class:`pieces ` by square index. """ @@ -807,17 +807,17 @@ def pieces(self): result[square] = self.piece_at(square) return result - def _set_pieces(self, pieces): + def _set_piece_map(self, pieces): self._clear_board() for square, piece in pieces.items(): self._set_piece_at(square, piece.piece_type, piece.color) - def set_pieces(self, pieces): + def set_piece_map(self, pieces): """ Sets up the board from a dictionary of :class:`pieces ` by square index. """ - self._set_pieces(pieces) + self._set_piece_map(pieces) def _set_chess960_pos(self, sharnagl): if not 0 <= sharnagl <= 959: @@ -2131,8 +2131,8 @@ def set_board_fen(self, fen): super(Board, self).set_board_fen(fen) self.clear_stack() - def set_pieces(self, pieces): - super(Board, self).set_pieces(pieces) + def set_piece_map(self, pieces): + super(Board, self).set_piece_map(pieces) self.clear_stack() def set_chess960_pos(self, sharnagl): diff --git a/test.py b/test.py index 3b0172238..0140cf93f 100755 --- a/test.py +++ b/test.py @@ -1392,12 +1392,12 @@ def test_set_chess960_pos(self): self.assertEqual(board.board_fen(), "rkrnnqbb/pppppppp/8/8/8/8/PPPPPPPP/RKRNNQBB") self.assertEqual(board.chess960_pos(), 959) - def test_set_pieces(self): + def test_set_piece_map(self): a = chess.BaseBoard.empty() b = chess.BaseBoard() - a.set_pieces(b.pieces()) + a.set_piece_map(b.piece_map()) self.assertEqual(a, b) - a.set_pieces({}) + a.set_piece_map({}) self.assertNotEqual(a, b) From dec8941e5973fb0ef462f61c063e8edc3e307e77 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 10 Sep 2017 09:45:58 +0200 Subject: [PATCH 0021/1831] Do some ep square validation on move generation --- chess/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 3e0126588..e63af68fd 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1318,9 +1318,13 @@ def generate_pseudo_legal_ep(self, from_mask=BB_ALL, to_mask=BB_ALL): if not self.ep_square or not BB_SQUARES[self.ep_square] & to_mask: return + if BB_SQUARES[self.ep_square] & self.occupied: + return + capturers = ( self.pawns & self.occupied_co[self.turn] & from_mask & - BB_PAWN_ATTACKS[not self.turn][self.ep_square]) + BB_PAWN_ATTACKS[not self.turn][self.ep_square] & + BB_RANKS[4 if self.turn else 3]) for capturer in scan_reversed(capturers): yield Move(capturer, self.ep_square) From 738de0920d6f1272b8d2c9a9f35609044b9b274a Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Tue, 12 Sep 2017 20:05:44 +0530 Subject: [PATCH 0022/1831] Added the stop/movenow command --- chess/xboard.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/chess/xboard.py b/chess/xboard.py index 697e67eb2..6d51a5396 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -875,6 +875,36 @@ def command(): return self._queue_command(command, async_callback) + def stop(self, async_callback=None): + """ + Stop calculating as soon as possible. The actual XBoard command is `?`. + + :return: Nothing. + """ + # Only send stop when the engine is actually searching. + def command(): + with self.semaphore: + with self.state_changed: + if not self.idle: + self.search_started.wait() + + backoff = 0.5 + while not self.move_received.is_set() and not self.terminated.is_set(): + if self.idle: + break + else: + self.send_line("?") + self.bestmove_received.wait(backoff) + backoff *= 2 + + self.idle = True + self.state_changed.notify_all() + + if self.terminated.is_set(): + raise EngineTerminatedException() + + return self._queue_command(command, async_callback) + def usermove(self, move, async_callback=None): """ Tell the XBoard engine to make a move on it's internal From 0a239990e5607feb1f9f40c1996c24a8ed42740b Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Tue, 12 Sep 2017 20:17:20 +0530 Subject: [PATCH 0023/1831] Added a test for stop() and bug fix in the same --- chess/xboard.py | 2 +- test.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/chess/xboard.py b/chess/xboard.py index 6d51a5396..1e009138c 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -894,7 +894,7 @@ def command(): break else: self.send_line("?") - self.bestmove_received.wait(backoff) + self.move_received.wait(backoff) backoff *= 2 self.idle = True diff --git a/test.py b/test.py index 0140cf93f..e7e1c7db7 100755 --- a/test.py +++ b/test.py @@ -2191,6 +2191,13 @@ def test_level(self): self.engine.level(1, 0, 1, 0) self.engine.go() + def test_stop(self): + self.engine.new() + self.engine.time(1000000) + self.engine.go(async_callback=True) + time.sleep(0.1) + self.engine.stop() + def test_time(self): self.engine.new() self.engine.level(0, 1, 0, 0) From 8a7923e1c21c18f9a93a49f89d37294a5dc90d07 Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Tue, 12 Sep 2017 20:35:07 +0530 Subject: [PATCH 0024/1831] Removed option testing, errored again --- .travis.yml | 6 ------ test.py | 24 ------------------------ 2 files changed, 30 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4abf7fb61..27730b944 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,12 +37,6 @@ before_install: - make unix-gcc - export PATH="`pwd`:${PATH}" - cd .. - - # WyldChess - - git clone https://github.com/Mk-Chan/WyldChess - - cd WyldChess/src - - make - - export PATH="`pwd`:${PATH}" - - cd ../.. - # Gaviota libgtb - git clone https://github.com/michiguel/Gaviota-Tablebases.git --depth 1 - cd Gaviota-Tablebases diff --git a/test.py b/test.py index e7e1c7db7..73139255b 100755 --- a/test.py +++ b/test.py @@ -2148,30 +2148,6 @@ def test_wierd_header(self): self.assertEqual(game.headers["Black"], "[=0040.34h5a4]") -class WyldTestCase(unittest.TestCase): - - def setUp(self): - try: - self.engine = chess.xboard.popen_engine("wyldchess") - except OSError: - self.skipTest("need wyldchess") - - self.engine.xboard() - - def tearDown(self): - self.engine.quit() - - def test_options(self): - self.engine.new() - self.engine.st(2) - self.engine.sd(100) - option_dict = { "MoveOverhead" : 1900 }; - self.engine.option(option_dict) - self.engine.go(async_callback=True) - time.sleep(0.2) - self.assertTrue(self.engine.idle, True) - - class CraftyTestCase(unittest.TestCase): def setUp(self): From d03b088a233ec709e0637935bc32705705b71318 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 27 Sep 2017 14:07:40 +0200 Subject: [PATCH 0025/1831] Support semicolon comments in PGNs --- chess/pgn.py | 3 +++ test.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/chess/pgn.py b/chess/pgn.py index 5ef62a9f7..8c2ade137 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -94,6 +94,7 @@ |0-0(?:-0)? ) |(\{.*) + |(;.*) |(\$[0-9]+) |(\() |(\)) @@ -896,6 +897,8 @@ def read_game(handle, Visitor=GameModelCreator): if line: read_next_line = False break + elif token.startswith(";"): + break elif token.startswith("$"): # Found a NAG. try: diff --git a/test.py b/test.py index 73139255b..b3e31d8b6 100755 --- a/test.py +++ b/test.py @@ -2147,6 +2147,13 @@ def test_wierd_header(self): game = chess.pgn.read_game(pgn) self.assertEqual(game.headers["Black"], "[=0040.34h5a4]") + def test_semicolon_comment(self): + pgn = StringIO("1. e4 ; e5") + game = chess.pgn.read_game(pgn) + node = game.variations[0] + self.assertEqual(node.move, chess.Move.from_uci("e2e4")) + self.assertTrue(node.is_end()) + class CraftyTestCase(unittest.TestCase): From 89bc1ef40e0a2d2967661fc2dbf441ddeb3da2d0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Oct 2017 11:24:08 +0200 Subject: [PATCH 0026/1831] Ensure some functions strictly return bools (#169) --- chess/__init__.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index e63af68fd..a67ec2e11 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2646,17 +2646,17 @@ def push_uci(self, uci): def is_en_passant(self, move): """Checks if the given pseudo-legal move is an en passant capture.""" return (self.ep_square == move.to_square and - self.pawns & BB_SQUARES[move.from_square] and + bool(self.pawns & BB_SQUARES[move.from_square]) and abs(move.to_square - move.from_square) in [7, 9] and not self.occupied & BB_SQUARES[move.to_square]) def is_capture(self, move): """Checks if the given pseudo-legal move is a capture.""" - return BB_SQUARES[move.to_square] & self.occupied_co[not self.turn] or self.is_en_passant(move) + return bool(BB_SQUARES[move.to_square] & self.occupied_co[not self.turn]) or self.is_en_passant(move) def is_zeroing(self, move): """Checks if the given pseudo-legal move is a capture or pawn move.""" - return BB_SQUARES[move.from_square] & self.pawns or BB_SQUARES[move.to_square] & self.occupied_co[not self.turn] + return bool(BB_SQUARES[move.from_square] & self.pawns or BB_SQUARES[move.to_square] & self.occupied_co[not self.turn]) def is_irreversible(self, move): """ @@ -2666,17 +2666,17 @@ def is_irreversible(self, move): rights are irreversible. """ backrank = BB_RANK_1 if self.turn == WHITE else BB_RANK_8 - castling_rights = self.clean_castling_rights() & backrank - return (self.is_zeroing(move) or - castling_rights and BB_SQUARES[move.from_square] & self.kings & ~self.promoted or - castling_rights & BB_SQUARES[move.from_square] or - castling_rights & BB_SQUARES[move.to_square]) + cr = self.clean_castling_rights() & backrank + return bool(self.is_zeroing(move) or + cr and BB_SQUARES[move.from_square] & self.kings & ~self.promoted or + cr & BB_SQUARES[move.from_square] or + cr & BB_SQUARES[move.to_square]) def is_castling(self, move): """Checks if the given pseudo-legal move is a castling move.""" if self.kings & BB_SQUARES[move.from_square]: diff = square_file(move.from_square) - square_file(move.to_square) - return abs(diff) > 1 or self.rooks & self.occupied_co[self.turn] & BB_SQUARES[move.to_square] + return abs(diff) > 1 or bool(self.rooks & self.occupied_co[self.turn] & BB_SQUARES[move.to_square]) return False def is_kingside_castling(self, move): From 82a573a422ddf675306a36a8c9d221555b6ed845 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 10 Oct 2017 22:10:51 +0200 Subject: [PATCH 0027/1831] Factor out _carry_rippler() --- chess/__init__.py | 20 +++++++++++++------- test.py | 4 ++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index a67ec2e11..af904c8d1 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -286,6 +286,15 @@ def _edges(square): return (((BB_RANK_1 | BB_RANK_8) & ~BB_RANKS[square_rank(square)]) | ((BB_FILE_A | BB_FILE_H) & ~BB_FILES[square_file(square)])) +def _carry_rippler(mask): + # Carry-Rippler trick to iterate subsets of mask. + subset = 0 + while True: + yield subset + subset = (subset - mask) & mask + if not subset: + break + def _attack_table(deltas): mask_table = [] attack_table = [] @@ -293,16 +302,10 @@ def _attack_table(deltas): for square, bb in enumerate(BB_SQUARES): attacks = {} - # Carry-Rippler trick to iterate subsets of mask. mask = _sliding_attacks(square, 0, deltas) & ~_edges(square) - subset = 0 - while True: + for subset in _carry_rippler(mask): attacks[subset] = _sliding_attacks(square, subset, deltas) - subset = (subset - mask) & mask - if not subset: - break - attack_table.append(attacks) mask_table.append(mask) @@ -3390,6 +3393,9 @@ def pop(self): def clear(self): self.mask = BB_VOID + def carry_rippler(self): + return _carry_rippler(self.mask) + def __bool__(self): return bool(self.mask) diff --git a/test.py b/test.py index b3e31d8b6..b390b935f 100755 --- a/test.py +++ b/test.py @@ -1525,6 +1525,10 @@ def test_from_square(self): self.assertEqual(chess.SquareSet.from_square(chess.H5), chess.BB_H5) self.assertEqual(chess.SquareSet.from_square(chess.C2), chess.BB_C2) + def test_carry_rippler(self): + self.assertEqual(sum(1 for _ in chess.SquareSet(chess.BB_D1).carry_rippler()), 2 ** 1) + self.assertEqual(sum(1 for _ in chess.SquareSet(chess.BB_FILE_B).carry_rippler()), 2 ** 8) + class PolyglotTestCase(unittest.TestCase): From 036077d0e93671463f7019d8fbad893ab0e79068 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 12 Oct 2017 11:08:18 +0200 Subject: [PATCH 0028/1831] Document BB_CORNERS --- docs/core.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/core.rst b/docs/core.rst index c579594a0..01e687d65 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -241,3 +241,6 @@ Other masks: .. py:data:: chess.BB_BACKRANKS :annotation: = chess.BB_RANK_1 | chess.BB_RANK_8 + +.. py:data:: chess.BB_CORNERS + :annotation: = 0x8100000000000081 From 4b433bc57c2185eb725ee3e4e2919e7028a1c722 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 12 Oct 2017 11:08:30 +0200 Subject: [PATCH 0029/1831] Update changelog --- CHANGELOG.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 22848e436..d6dadd61b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,34 @@ Changelog for python-chess ========================== +Upcoming in the next release +---------------------------- + +Bugfixes: + +* Some XBoard commands were not returning futures. +* Support semicolon comments in PGNs. + +Changes: + +* Changed FEN and EPD formatting options. It is now possible to include en + passant squares in FEN and X-FEN style, or to include only strictly relevant + en passant squares. +* Relax en passant square validation in `Board.set_fen()`. +* Ensure `is_en_passant()`, `is_capture()`, `is_zeroing()` and + `is_irreversible()` strictly return bools. +* Accept `Z0` as a null move in PGNs. + +New features: + +* XBoard: Add `memory`, `core`, `stop` and `movenow` commands. + Abstract `post`/`nopost`. Initial `FeatureMap` support. Support `usermove`. +* Added `Board.has_pseudo_legal_en_passant()`. +* Added `Board.piece_map()`. +* Added `SquareSet.carry_rippler()`. +* Factored out some (unstable) low level APIs: `BB_CORNERS`, + `_carry_rippler()`, `_edges()`. + New in v0.19.0 -------------- From a268b90ba6b1be47cd76af8f7659c645dc36bb3b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 12 Oct 2017 11:35:34 +0200 Subject: [PATCH 0030/1831] Upgrade setuptools on travis --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 27730b944..d4fcf2110 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,6 +52,8 @@ before_install: - wget --no-verbose --no-check-certificate --no-clobber --input-file TEST-SOURCE.txt - cd ../../.. install: + - pip install --upgrade pip wheel + - pip install --upgrade setuptools - pip install coverage coveralls - pip install -e .[test] script: From d8f4b18d0292a42b2102b996e9d683ee89e0f9b0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 13 Oct 2017 02:03:18 +0200 Subject: [PATCH 0031/1831] Bump 0.20.0 --- CHANGELOG.rst | 4 ++-- chess/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d6dadd61b..b49c6da63 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,8 @@ Changelog for python-chess ========================== -Upcoming in the next release ----------------------------- +New in v0.20.0 +-------------- Bugfixes: diff --git a/chess/__init__.py b/chess/__init__.py index af904c8d1..304834528 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "0.19.0" +__version__ = "0.20.0" import copy import re From 06d2c569e347467dddd2dee2ab3c7cab747e7d15 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 13 Oct 2017 16:40:40 +0200 Subject: [PATCH 0032/1831] Fix lock release in InfoHandler docs --- chess/uci.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/uci.py b/chess/uci.py index 9f06e4c79..b9a00840f 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -78,8 +78,8 @@ class InfoHandler(object): >>> class MyHandler(chess.uci.InfoHandler): ... def post_info(self): ... # Called whenever a complete *info* line has been processed. - ... super(MyHandler, self).post_info() ... print(self.info) + ... super(MyHandler, self).post_info() # release lock """ def __init__(self): self.lock = threading.Lock() From 1e9098a8d6f7b7a16292dfa8cdd0f8a994bbfe0a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 13 Oct 2017 17:02:55 +0200 Subject: [PATCH 0033/1831] Fix typo --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 304834528..8d65703e1 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3522,7 +3522,7 @@ def from_square(cls, square): """ Creates a SquareSet from a single square. - >>> chess.SquareSet.from_square(chess.A1) == chess.BB_A1: + >>> chess.SquareSet.from_square(chess.A1) == chess.BB_A1 True """ return cls(BB_SQUARES[square]) From df6e0640b8f59a52cd688d31c97a01302137c600 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 13 Oct 2017 23:25:56 +0200 Subject: [PATCH 0034/1831] Center svg arrows on flipped board (fixes #170) --- chess/svg.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 0ddd28153..43dc7ea0c 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -221,10 +221,10 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No tail_file = chess.square_file(arrow[0]) tail_rank = chess.square_rank(arrow[0]) - xhead = margin + (head_file + 0.5 if not flipped else 8 - head_file) * SQUARE_SIZE - yhead = margin + (7.5 - head_rank if not flipped else head_rank + 1) * SQUARE_SIZE - xtail = margin + (tail_file + 0.5 if not flipped else 8 - tail_file) * SQUARE_SIZE - ytail = margin + (7.5 - tail_rank if not flipped else tail_rank + 1) * SQUARE_SIZE + xhead = margin + (head_file + 0.5 if not flipped else 7.5 - head_file) * SQUARE_SIZE + yhead = margin + (7.5 - head_rank if not flipped else head_rank + 0.5) * SQUARE_SIZE + xtail = margin + (tail_file + 0.5 if not flipped else 7.5 - tail_file) * SQUARE_SIZE + ytail = margin + (7.5 - tail_rank if not flipped else tail_rank + 0.5) * SQUARE_SIZE if (head_file, head_rank) == (tail_file, tail_rank): ET.SubElement(svg, "circle", { From daa81353741bd042ff32811b169866155e44911f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 13 Oct 2017 23:37:59 +0200 Subject: [PATCH 0035/1831] Fix SVG arrow head size --- chess/svg.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 43dc7ea0c..8e5767a5e 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -52,7 +52,7 @@ XX = """""" -ARROWHEAD = """""" +ARROWHEAD = """""" CHECK_GRADIENT = """""" @@ -253,7 +253,7 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No "x2": str(xhead), "y2": str(yhead), "stroke": "#888", - "stroke-width": "15", + "stroke-width": str(marker_length / 3), "opacity": "0.5", "stroke-linecap": "round", "marker-end": "url(#arrowhead)", From 22889f344f0348695ff93a137dd357598e8b9609 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 01:42:05 +0200 Subject: [PATCH 0036/1831] Make polyglot doctest runnable --- chess/polyglot.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/chess/polyglot.py b/chess/polyglot.py index 360ab74bc..b8630f235 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -494,6 +494,14 @@ def open_reader(path): """ Creates a reader for the file at the given path. + The following example opens a book to find all entries for the start + position: + + >>> import chess + >>> import chess.polyglot + >>> + >>> board = chess.Board() + >>> >>> with chess.polyglot.open_reader("data/polyglot/performance.bin") as reader: ... for entry in reader.find_all(board): ... print(entry.move(), entry.weight, entry.learn) From 1326ec1d3228c0c0d6de0b64ce2cbfbef61fdfb2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 01:46:02 +0200 Subject: [PATCH 0037/1831] Make variant doctests runnable --- docs/variant.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/variant.rst b/docs/variant.rst index 86907244e..b0cc72552 100644 --- a/docs/variant.rst +++ b/docs/variant.rst @@ -4,6 +4,7 @@ Variants python-chess supports several chess variants. >>> import chess.variant +>>> >>> board = chess.variant.GiveawayBoard() >>> # General information about the variants @@ -51,6 +52,10 @@ UCI Stockfish and other engines allow you to switch variants by setting the ``UCI_Variant`` option. +>>> import chess.uci +>>> +>>> engine = chess.uci.popen_engine("stockfish") +>>> >>> board = chess.variant.RacingKingsBoard() >>> engine.setoption({ ... "UCI_Variant": type(board).uci_variant, @@ -63,4 +68,6 @@ Syzygy Syzygy tablebases are available for suicide, giveaway and atomic chess. +>>> import chess.syzygy +>>> >>> tables = chess.syzygy.open_tablebases("data/syzygy", VariantBoard=chess.variant.AtomicBoard) From 56ef5662f6c321d1c807ecbf127a7177a1487b1f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 01:49:24 +0200 Subject: [PATCH 0038/1831] Make svg doctests runnable --- chess/svg.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 8e5767a5e..397b058c0 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -106,7 +106,10 @@ def piece(piece, size=None): """ Renders the given :class:`chess.Piece` as an SVG. - >>> chess.svg.piece(chess.Piece.from_symbol("R")) + >>> import chess + >>> import chess.svg + >>> + >>> chess.svg.piece(chess.Piece.from_symbol("R")) # doctest: +SKIP .. image:: ../docs/wR.svg """ @@ -130,9 +133,12 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No :param size: Limit the SVG size by setting width and height of the image. :param style: CSS to use instead of the default stylesheet. + >>> import chess + >>> import chess.svg + >>> >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1") >>> squares = board.attacks(chess.E4) - >>> chess.svg.board(board=board, squares=squares) + >>> chess.svg.board(board=board, squares=squares) # doctest: +SKIP .. image:: ../docs/Ne4.svg """ From 707259d0b9ab9bd1ffcd0a886300435a75ace648 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 01:57:22 +0200 Subject: [PATCH 0039/1831] Make syzygy doctests runnable --- chess/syzygy.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 752761e78..2ab28769b 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1657,8 +1657,12 @@ def probe_wdl(self, board): loss. Mate can be forced but the position can be drawn due to the fifty-move rule. + >>> import chess + >>> import chess.syzygy + >>> >>> with chess.syzygy.open_tablebases("data/syzygy/regular") as tablebases: - ... tablebases.probe_wdl(chess.Board("8/2K5/4B3/3N4/8/8/4k3/8 b - - 0 1")) + ... board = chess.Board("8/2K5/4B3/3N4/8/8/4k3/8 b - - 0 1") + ... print(tablebases.probe_wdl(board)) ... -2 @@ -1840,8 +1844,12 @@ def probe_dtz(self, board): Engines like Stockfish calculate themselves, checking with DTZ, but only play according to DTZ if they can not manage on their own. + >>> import chess + >>> import chess.syzygy + >>> >>> with chess.syzygy.open_tablebases("data/syzygy/regular") as tablebases: - ... tablebases.probe_dtz(chess.Board("8/2K5/4B3/3N4/8/8/4k3/8 b - - 0 1")) + ... board = chess.Board("8/2K5/4B3/3N4/8/8/4k3/8 b - - 0 1") + ... print(tablebases.probe_dtz(board)) ... -53 From 3402efeb4cb77cdbf84a933a36c695244930428e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 02:01:53 +0200 Subject: [PATCH 0040/1831] Make gaviota doctests runnable --- chess/gaviota.py | 12 ++++++++++-- docs/variant.rst | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index f498f762a..02fa15339 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1553,8 +1553,12 @@ def probe_dtm(self, board): In the example position white to move will get mated in 10 half moves: + >>> import chess + >>> import chess.gaviota + >>> >>> with chess.gaviota.open_tablebases("data/gaviota") as tablebases: - ... tablebases.probe_dtm(chess.Board("8/8/8/8/8/8/8/K2kr3 w - - 0 1")) + ... board = chess.Board("8/8/8/8/8/8/8/K2kr3 w - - 0 1") + ... print(tablebases.probe_dtm(board)) ... -10 @@ -1629,8 +1633,12 @@ def probe_wdl(self, board): Returns ``1`` if the side to move is winning, ``0`` if it is a draw, and ``-1`` if the side to move is losing. + >>> import chess + >>> import chess.gaviota + >>> >>> with chess.gaviota.open_tablebases("data/gaviota") as tablebases: - ... tablebases.probe_wdl(chess.Board("8/4k3/8/B7/8/8/8/4K3 w - - 0 1")) + ... board = chess.Board("8/4k3/8/B7/8/8/8/4K3 w - - 0 1") + ... print(tablebases.probe_wdl(board)) ... 0 diff --git a/docs/variant.rst b/docs/variant.rst index b0cc72552..4fd6b72dc 100644 --- a/docs/variant.rst +++ b/docs/variant.rst @@ -53,6 +53,7 @@ Stockfish and other engines allow you to switch variants by setting the ``UCI_Variant`` option. >>> import chess.uci +>>> import chess.variant >>> >>> engine = chess.uci.popen_engine("stockfish") >>> @@ -69,5 +70,6 @@ Syzygy Syzygy tablebases are available for suicide, giveaway and atomic chess. >>> import chess.syzygy +>>> import chess.variant >>> >>> tables = chess.syzygy.open_tablebases("data/syzygy", VariantBoard=chess.variant.AtomicBoard) From 60c21fc4e4e8267137e690ebab45e008c99295ec Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 02:11:11 +0200 Subject: [PATCH 0041/1831] Make BB_CORNERS annotation more clear --- docs/core.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core.rst b/docs/core.rst index 01e687d65..a950483c6 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -243,4 +243,4 @@ Other masks: :annotation: = chess.BB_RANK_1 | chess.BB_RANK_8 .. py:data:: chess.BB_CORNERS - :annotation: = 0x8100000000000081 + :annotation: = chess.BB_A1 | chess.BB_H1 | chess.BB_A8 | chess.BB_H8 From 08ef4e3b5d6ff494555fa2fc372d67f6d774be52 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 02:19:16 +0200 Subject: [PATCH 0042/1831] Move chess.pgn.Game.headers docs --- chess/pgn.py | 22 +--------------------- docs/pgn.rst | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 8c2ade137..56f1a774f 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -364,27 +364,7 @@ def __str__(self): class Game(GameNode): """ The root node of a game with extra information such as headers and the - starting position. - - By default the following 7 headers are provided in an ordered dictionary: - - >>> game = chess.pgn.Game() - >>> game.headers["Event"] - '?' - >>> game.headers["Site"] - '?' - >>> game.headers["Date"] - '????.??.??' - >>> game.headers["Round"] - '?' - >>> game.headers["White"] - '?' - >>> game.headers["Black"] - '?' - >>> game.headers["Result"] - '*' - - Also has all the other properties and methods of + starting position. Also has all the other properties and methods of :class:`~chess.pgn.GameNode`. """ diff --git a/docs/pgn.rst b/docs/pgn.rst index 6989b9a06..305063e9d 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -14,7 +14,26 @@ headers. .. py:attribute:: headers - A `collections.OrderedDict()` of game headers. + A :class:`collections.OrderedDict()` of game headers. By default the + following 7 headers are provided: + + >>> import chess.pgn + >>> + >>> game = chess.pgn.Game() + >>> game.headers["Event"] + '?' + >>> game.headers["Site"] + '?' + >>> game.headers["Date"] + '????.??.??' + >>> game.headers["Round"] + '?' + >>> game.headers["White"] + '?' + >>> game.headers["Black"] + '?' + >>> game.headers["Result"] + '*' .. py:attribute:: errors From db03057a5e6055ce49ecf976014ca64ef2f950c9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 02:37:12 +0200 Subject: [PATCH 0043/1831] Reorganize PGN docs --- chess/pgn.py | 11 ++++++++ docs/pgn.rst | 80 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 56f1a774f..7caa31447 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -751,18 +751,29 @@ def read_game(handle, Visitor=GameModelCreator): """ Reads a game from a file opened in text mode. + >>> import chess.pgn + >>> >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn") + >>> >>> first_game = chess.pgn.read_game(pgn) >>> second_game = chess.pgn.read_game(pgn) >>> >>> first_game.headers["Event"] 'IBM Man-Machine, New York USA' + >>> + >>> board = first_game.board() + >>> for move in first_game.main_line(): + ... board.push(move) + ... + >>> board + Board('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1') By using text mode the parser does not need to handle encodings. It is the callers responsibility to open the file with the correct encoding. PGN files are ASCII or UTF-8 most of the time. So the following should cover most relevant cases (ASCII, UTF-8, UTF-8 with BOM). + >>> # Python 3 >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn", encoding="utf-8-sig") Use :class:`~io.StringIO` to parse games from a string. diff --git a/docs/pgn.rst b/docs/pgn.rst index 305063e9d..9b027232c 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -1,6 +1,44 @@ PGN parsing and writing ======================= +Parsing +------- + +.. autofunction:: chess.pgn.read_game + +Writing +------- + +If you want to export your game game with all headers, comments and variations +you can use: + +>>> import chess +>>> import chess.pgn +>>> +>>> game = chess.pgn.Game() +>>> game.headers["Event"] = "Example" +>>> node = game.add_variation(chess.Move.from_uci("e2e4")) +>>> node = node.add_variation(chess.Move.from_uci("e7e5")) +>>> node.comment = "Comment" +>>> +>>> print(game) +[Event "Example"] +[Site "?"] +[Date "????.??.??"] +[Round "?"] +[White "?"] +[Black "?"] +[Result "*"] + +1. e4 e5 { Comment } * + +Remember that games in files should be separated with extra blank lines. + +>>> print(game, file=open("/dev/null", "w"), end="\n\n") + +Use the :class:`~chess.pgn.StringExporter()` or +:class:`~chess.pgn.FileExporter()` visitors if you need more control. + Game model ---------- @@ -75,39 +113,6 @@ headers. A list of child nodes. -Parsing -------- - -.. autofunction:: chess.pgn.read_game - -.. autofunction:: chess.pgn.scan_headers - -.. autofunction:: chess.pgn.scan_offsets - -Writing -------- - -If you want to export your game game with all headers, comments and variations -you can use: - ->>> print(game) -[Event "?"] -[Site "?"] -[Date "????.??.??"] -[Round "?"] -[White "?"] -[Black "?"] -[Result "*"] - -1. e4 e5 { Comment } * - -Remember that games in files should be separated with extra blank lines. - ->>> print(game, file=handle, end="\n\n") - -Use the :class:`~chess.pgn.StringExporter()` or -:class:`~chess.pgn.FileExporter()` visitors if you need more control. - Visitors -------- @@ -140,3 +145,12 @@ like ``!``, ``?``, ``!!``, etc. are also converted to NAGs. .. autodata:: chess.pgn.NAG_BLUNDER .. autodata:: chess.pgn.NAG_SPECULATIVE_MOVE .. autodata:: chess.pgn.NAG_DUBIOUS_MOVE + +Skimming +-------- + +These functions allow quickly skimming games without fully parsing them. + +.. autofunction:: chess.pgn.scan_headers + +.. autofunction:: chess.pgn.scan_offsets From baeafce986a623c3985cb6862fcb842563df390a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 02:47:42 +0200 Subject: [PATCH 0044/1831] Make pgn doctests runnable --- chess/pgn.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 7caa31447..ddb81bf00 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -613,6 +613,10 @@ class StringExporter(BaseVisitor): """ Allows exporting a game as a string. + >>> import chess.pgn + >>> + >>> game = chess.pgn.Game() + >>> >>> exporter = chess.pgn.StringExporter(headers=True, variations=True, comments=True) >>> pgn_string = game.accept(exporter) @@ -717,7 +721,11 @@ class FileExporter(StringExporter): There will always be a blank line after each game. Handling encodings is up to the caller. - >>> new_pgn = open("new.pgn", "w", encoding="utf-8") + >>> import chess.pgn + >>> + >>> game = chess.pgn.Game() + >>> + >>> new_pgn = open("/dev/null", "w", encoding="utf-8") >>> exporter = chess.pgn.FileExporter(new_pgn) >>> game.accept(exporter) """ @@ -761,12 +769,13 @@ def read_game(handle, Visitor=GameModelCreator): >>> first_game.headers["Event"] 'IBM Man-Machine, New York USA' >>> + >>> # Iterate through all moves and play them on a board. >>> board = first_game.board() >>> for move in first_game.main_line(): ... board.push(move) ... >>> board - Board('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1') + Board('4r3/6P1/2p2P1k/1p6/pP2p1R1/P1B5/2P2K2/3r4 b - - 0 45') By using text mode the parser does not need to handle encodings. It is the callers responsibility to open the file with the correct encoding. @@ -781,10 +790,10 @@ def read_game(handle, Visitor=GameModelCreator): >>> pgn_string = "1. e4 e5 2. Nf3 *" >>> >>> try: - >>> from StringIO import StringIO # Python 2 - >>> except ImportError: - >>> from io import StringIO # Python 3 - >>> + ... from StringIO import StringIO # Python 2 + ... except ImportError: + ... from io import StringIO # Python 3 + ... >>> pgn = StringIO(pgn_string) >>> game = chess.pgn.read_game(pgn) @@ -964,7 +973,10 @@ def scan_headers(handle): This example scans for the first game with Kasparov as the white player. - >>> pgn = open("mega.pgn") + >>> import chess.pgn + >>> + >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn") + >>> >>> for offset, headers in chess.pgn.scan_headers(pgn): ... if "Kasparov" in headers["White"]: ... kasparov_offset = offset @@ -973,6 +985,7 @@ def scan_headers(handle): Then it can later be seeked an parsed. >>> pgn.seek(kasparov_offset) + 0 >>> game = chess.pgn.read_game(pgn) This also works nicely with generators, scanning lazily only when the next From 901b0b92a4cd85e3d5b0a4d6beb68d7f1136679b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 03:23:06 +0200 Subject: [PATCH 0045/1831] Fix SquareSet doctests --- chess/__init__.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 8d65703e1..1f2394fd5 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3268,21 +3268,24 @@ class SquareSet(object): """ A set of squares. - >>> chess.SquareSet(chess.BB_A8 | chess.BB_RANK_1) + >>> import chess + >>> + >>> squares = chess.SquareSet(chess.BB_A8 | chess.BB_RANK_1) + >>> squares SquareSet(0x01000000000000ff) >>> print(squares) + 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - . . . . . . . . - . 1 . . . . 1 . + 1 1 1 1 1 1 1 1 >>> len(squares) - 2 + 9 >>> bool(squares) True @@ -3291,22 +3294,36 @@ class SquareSet(object): True >>> for square in squares: + ... # 0 -- chess.A1 ... # 1 -- chess.B1 + ... # 2 -- chess.C1 + ... # 3 -- chess.D1 + ... # 4 -- chess.E1 + ... # 5 -- chess.F1 ... # 6 -- chess.G1 + ... # 7 -- chess.H1 + ... # 56 -- chess.A8 ... print(square) ... + 0 1 + 2 + 3 + 4 + 5 6 + 7 + 56 >>> list(squares) - [1, 6] + [0, 1, 2, 3, 4, 5, 6, 7, 56] Square sets are internally represented by 64 bit integer masks of the included squares. Bitwise operations can be used to compute unions, intersections and shifts. >>> int(squares) - 66 + 72057594037928191 Also supports common set operations like :func:`~chess.SquareSet.issubset()`, :func:`~chess.SquareSet.issuperset()`, @@ -3522,6 +3539,8 @@ def from_square(cls, square): """ Creates a SquareSet from a single square. + >>> import chess + >>> >>> chess.SquareSet.from_square(chess.A1) == chess.BB_A1 True """ From 18602e85ccbc7a4da473ff23c0ac9d2d05c0d8d9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 03:29:08 +0200 Subject: [PATCH 0046/1831] Make chess/__init__.py doctests runnable --- chess/__init__.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 1f2394fd5..722954093 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -517,6 +517,8 @@ def null(cls): forfeits en passant capturing). Null moves evaluate to ``False`` in boolean contexts. + >>> import chess + >>> >>> bool(chess.Move.null()) False """ @@ -886,8 +888,7 @@ def _set_chess960_pos(self, sharnagl): def set_chess960_pos(self, sharnagl): """ Sets up a Chess960 starting position given its index between 0 and 959. - - >>> board.set_chess960_pos(random.randint(0, 959)) + Also see :func:`~chess.BaseBoard.from_chess960_pos()`. """ self._set_chess960_pos(sharnagl) @@ -1113,7 +1114,11 @@ def empty(cls): def from_chess960_pos(cls, sharnagl): """ Creates a new board, initialized to a Chess960 starting position. - Also see :func:`~chess.BaseBoard.set_chess960_pos()`. + + >>> import chess + >>> import random + >>> + >>> board = chess.Board.from_chess960_pos(random.randint(0, 959)) """ board = cls.empty() board.set_chess960_pos(sharnagl) @@ -1435,6 +1440,8 @@ def pin(self, color, square): Detects an absolute pin (and its direction) of the given square to the king of the given color. + >>> import chess + >>> >>> board = chess.Board("rnb1k2r/ppp2ppp/5n2/3q4/1b1P4/2N5/PP3PPP/R1BQKBNR w KQkq - 3 7") >>> board.is_pinned(chess.WHITE, chess.C3) True @@ -1797,6 +1804,10 @@ def push(self, move): Updates the position with the given move and puts it onto the move stack. + >>> import chess + >>> + >>> board = chess.Board() + >>> >>> Nf3 = chess.Move.from_uci("g1f3") >>> board.push(Nf3) # Make the move @@ -2254,6 +2265,9 @@ def epd(self, shredder=False, en_passant="legal", promoted=None, **operations): *hmvc* and *fmvc* are not included by default. You can use: + >>> import chess + >>> + >>> board = chess.Board() >>> board.epd(hmvc=board.halfmove_clock, fmvc=board.fullmove_number) 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - hmvc 0; fmvc 1;' """ From 25441821f53ca9338ed6e77aa32e3da690c482da Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Oct 2017 03:32:15 +0200 Subject: [PATCH 0047/1831] Make doctests in docs/core.rst runnable --- docs/core.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/core.rst b/docs/core.rst index a950483c6..1988f29e2 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -123,8 +123,11 @@ Board To test for specific squares: - >>> board.castling_rights & chess.BB_H1 - True # White can castle kingside with the h1 rook + >>> import chess + >>> + >>> board = chess.Board() + >>> bool(board.castling_rights & chess.BB_H1) # White can castle with the h1 rook + True To add a specific square: @@ -167,15 +170,14 @@ Board A dynamic list of legal moves. - The following operations do not just generate everything but map to - more efficient methods. - + >>> import chess + >>> + >>> board = chess.Board() >>> len(board.legal_moves) 20 - >>> bool(board.legal_moves) True - + >>> move = chess.Move.from_uci("g1f3") >>> move in board.legal_moves True From 25293df7b83fc758fc07d7ee198b689bb148e5f1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 16 Oct 2017 13:26:01 +0200 Subject: [PATCH 0048/1831] Bump 0.20.1 --- CHANGELOG.rst | 8 ++++++++ chess/__init__.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b49c6da63..e81afd0f1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ Changelog for python-chess ========================== +New in v0.20.1 +-------------- + +Bugfixes: + +* Fix arrow positioning on SVG boards. +* Documentation fixes and improvements, making most doctests runnable. + New in v0.20.0 -------------- diff --git a/chess/__init__.py b/chess/__init__.py index 722954093..e74b302f9 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "0.20.0" +__version__ = "0.20.1" import copy import re From 399f6dcdb37193bbc888f2f81048417f3e709b1d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 21 Oct 2017 14:27:00 +0200 Subject: [PATCH 0049/1831] Test atomic castle with kings touching --- test.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test.py b/test.py index b390b935f..3cd5ea079 100755 --- a/test.py +++ b/test.py @@ -3141,6 +3141,11 @@ def test_castling_uncovered_rank_attack(self): board = chess.variant.AtomicBoard("8/8/8/8/8/8/2k5/rR4KR w KQ - 0 1", chess960=True) self.assertTrue(board.is_legal(chess.Move.from_uci("g1b1"))) + def test_atomic_castle_with_kings_touching(self): + board = chess.variant.AtomicBoard("5b1r/1p5p/4ppp1/4Bn2/1PPP1PP1/4P2P/3k4/4K2R w K - 1 1") + board.push_san("O-O") + self.assertEqual(board.fen(), "5b1r/1p5p/4ppp1/4Bn2/1PPP1PP1/4P2P/3k4/5RK1 b - - 2 1") + class RacingKingsTestCase(unittest.TestCase): From 7891ec16b536a7cca06d467011d06d9b2f5f6cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sat, 21 Oct 2017 16:55:46 +0200 Subject: [PATCH 0050/1831] Improve class Arrow in chess.svg A subclass of collections.namedtuple must implement the __slots__ attribute and, in this case, an empty tuple must be assigned to it. --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index 397b058c0..6dbab8ebd 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -72,7 +72,7 @@ class Arrow(collections.namedtuple("Arrow", ["tail", "head"])): """Details of an arrow to be drawn.""" - pass + __slots__ = () def _svg(viewbox, size): From cc598dbc14a86b5fc7e5df893410448a8b229660 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 21 Oct 2017 18:41:55 +0200 Subject: [PATCH 0051/1831] More namedtuple tweaks (thanks @PedanticHacker) --- chess/engine.py | 5 +++-- chess/gaviota.py | 4 ++-- chess/polyglot.py | 4 +++- chess/svg.py | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 77a89c0df..f7cd5e712 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -57,9 +57,10 @@ class EngineStateException(Exception): pass -class Option(collections.namedtuple("Option", ["name", "type", "default", "min", "max", "var"])): +class Option(collections.namedtuple("Option", "name type default min max var")): """Information about an available option for an UCI engine.""" - pass + + __slots__ = () class MockProcess(object): diff --git a/chess/gaviota.py b/chess/gaviota.py index 02fa15339..281df2085 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1172,7 +1172,7 @@ def kpppk_pctoindex(c): return ppp48_slice * BLOCK_A + wk * BLOCK_B + bk -Endgamekey = collections.namedtuple("Endgamekey", ["maxindex", "slice_n", "pctoi"]) +Endgamekey = collections.namedtuple("Endgamekey", "maxindex slice_n pctoi") EGKEY = { "kqk": Endgamekey(MAX_KXK, 1, kxk_pctoindex), @@ -1517,7 +1517,7 @@ def __init__(self, white_squares, white_types, black_squares, black_types, side, self.white_piece_squares = None -Zipinfo = collections.namedtuple("Zipinfo", ["extraoffset", "totalblocks", "blockindex"]) +Zipinfo = collections.namedtuple("Zipinfo", "extraoffset totalblocks blockindex") class PythonTablebases(object): diff --git a/chess/polyglot.py b/chess/polyglot.py index b8630f235..1d5b1394e 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -296,9 +296,11 @@ def zobrist_hash(board, _hasher=ZobristHasher(POLYGLOT_RANDOM_ARRAY)): return _hasher(board) -class Entry(collections.namedtuple("Entry", ["key", "raw_move", "weight", "learn"])): +class Entry(collections.namedtuple("Entry", "key raw_move weight learn")): """An entry from a polyglot opening book.""" + __slots__ = () + def move(self, chess960=False): """Gets the move (as a :class:`~chess.Move` object).""" # Extract source and target square. diff --git a/chess/svg.py b/chess/svg.py index 6dbab8ebd..f1eec7428 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -70,8 +70,9 @@ """ -class Arrow(collections.namedtuple("Arrow", ["tail", "head"])): +class Arrow(collections.namedtuple("Arrow", "tail head")): """Details of an arrow to be drawn.""" + __slots__ = () From 6573b84d14594262fea692ccffe8225e1091b9fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sun, 22 Oct 2017 15:24:43 +0200 Subject: [PATCH 0052/1831] Improve chess.svg.board docs Add an example of the exact code that the programmer would need to pass in to generate an arrow on the chessboard. --- chess/svg.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index f1eec7428..e5a62c18e 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -129,8 +129,7 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No :param coordinates: Pass ``False`` to disable coordinates in the margin. :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked as check. - :param arrows: A list of :class:`~chess.svg.Arrow` objects or tuples - like ``(chess.E2, chess.E4)``. + :param arrows: A list of :class:`~chess.svg.Arrow` objects like ``[chess.svg.Arrow(chess.E2, chess.E4)]``. :param size: Limit the SVG size by setting width and height of the image. :param style: CSS to use instead of the default stylesheet. From 66128b8cad152005f59b474f97a91546581882d4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 22 Oct 2017 17:05:29 +0200 Subject: [PATCH 0053/1831] Explain SVG circles (#174) --- chess/svg.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index e5a62c18e..630a35667 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -129,7 +129,9 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No :param coordinates: Pass ``False`` to disable coordinates in the margin. :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked as check. - :param arrows: A list of :class:`~chess.svg.Arrow` objects like ``[chess.svg.Arrow(chess.E2, chess.E4)]``. + :param arrows: A list of :class:`~chess.svg.Arrow` objects like + ``[chess.svg.Arrow(chess.E2, chess.E4)]``. Arrows from a square to the + same square are drawn as circles. :param size: Limit the SVG size by setting width and height of the image. :param style: CSS to use instead of the default stylesheet. From d674bf43a37bacd2d876c9408ec970f7fdf9daf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Mon, 23 Oct 2017 01:24:03 +0200 Subject: [PATCH 0054/1831] Fix board argument doc of chess.svg.board I've elaborated on the `board` argument documentation of the `chess.svg.board` function. This in conjunction with my pull request with other argument elaborations finally fix this part of the documentation. --- chess/svg.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index 630a35667..b3d33db94 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -123,7 +123,8 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No """ Renders a board with pieces and/or selected squares as an SVG. - :param board: A :class:`chess.BaseBoard` with pieces or ``None``. + :param board: A :class:`chess.Board` for a chessboard with pieces or + ``None`` (the default) for a chessboard without pieces. :param squares: A :class:`chess.SquareSet` with selected squares. :param flipped: Pass ``True`` to flip the board. :param coordinates: Pass ``False`` to disable coordinates in the margin. From d4b61f72ebad1274460f75c9cb38cc2f9bfd3f0c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 23 Oct 2017 11:24:59 +0200 Subject: [PATCH 0055/1831] chess.svg.board requires just a BaseBoard (#177) --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index b3d33db94..268449826 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -123,7 +123,7 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No """ Renders a board with pieces and/or selected squares as an SVG. - :param board: A :class:`chess.Board` for a chessboard with pieces or + :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or ``None`` (the default) for a chessboard without pieces. :param squares: A :class:`chess.SquareSet` with selected squares. :param flipped: Pass ``True`` to flip the board. From ccd144218c60d228d129dfec498b11c8b9394fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Tue, 24 Oct 2017 13:38:26 +0200 Subject: [PATCH 0056/1831] Fix `chess.svg` module This patch is the second (and hopefully the last) attempt to correctly document some arguments of the `chess.svg.board` function. Also, the patch fixes the value of the `DEFAULT_STYLE` constant so that the string is on one line only and is not triple quoted and that the ugly backslash can be removed. There's no point for a constant's value to be laid out so that something can be added to it. Remember, it's a constant. --- chess/svg.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 268449826..5532d9709 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -63,11 +63,7 @@ "square light lastmove": "#cdd16a", } -DEFAULT_STYLE = """\ -.check { - fill: url(#check_gradient); -} -""" +DEFAULT_STYLE = ".check {fill: url(#check_gradient);}" class Arrow(collections.namedtuple("Arrow", "tail head")): @@ -105,7 +101,7 @@ def _text(content, x, y, width, height): def piece(piece, size=None): """ - Renders the given :class:`chess.Piece` as an SVG. + Renders the given :class:`chess.Piece` as an SVG image. >>> import chess >>> import chess.svg @@ -121,7 +117,7 @@ def piece(piece, size=None): def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=None, check=None, arrows=(), size=None, style=None): """ - Renders a board with pieces and/or selected squares as an SVG. + Renders a board with pieces and/or selected squares as an SVG image. :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or ``None`` (the default) for a chessboard without pieces. @@ -131,10 +127,13 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked as check. :param arrows: A list of :class:`~chess.svg.Arrow` objects like - ``[chess.svg.Arrow(chess.E2, chess.E4)]``. Arrows from a square to the - same square are drawn as circles. - :param size: Limit the SVG size by setting width and height of the image. - :param style: CSS to use instead of the default stylesheet. + ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like + ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same + square is drawn as a circle, like ``[(chess.E2, chess.E2)]``. + :param size: Adjust size of the SVG image by passing in a number like + ``400`` which renders a board with 400 by 400 pixels. + :param style: Pass in a CSS style sheet to alter the default style sheet of + the SVG image. >>> import chess >>> import chess.svg From c2a8792929096ef34211eb4ac3b3800021d00e25 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 24 Oct 2017 21:41:54 +0200 Subject: [PATCH 0057/1831] Make DEFAULT_STYLE multiline again --- chess/svg.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index 5532d9709..c10949b7c 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -63,7 +63,11 @@ "square light lastmove": "#cdd16a", } -DEFAULT_STYLE = ".check {fill: url(#check_gradient);}" +DEFAULT_STYLE = """ +.check { + fill: url(#check_gradient); +} +""" class Arrow(collections.namedtuple("Arrow", "tail head")): From eba6635b66819cc907b264bb57e8b70385277d06 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 24 Oct 2017 21:48:20 +0200 Subject: [PATCH 0058/1831] More doc tweaks ("stylesheet", as opposed to "style sheet", is really the right way to talk about CSS) --- chess/svg.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index c10949b7c..2f67a3024 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -134,10 +134,9 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same square is drawn as a circle, like ``[(chess.E2, chess.E2)]``. - :param size: Adjust size of the SVG image by passing in a number like - ``400`` which renders a board with 400 by 400 pixels. - :param style: Pass in a CSS style sheet to alter the default style sheet of - the SVG image. + :param size: The size of the image in pixels (e.g. ``400`` for a 400 by 400 + board) or ``None`` (the default) for no size limit. + :param style: A CSS stylesheet to include in the SVG image. >>> import chess >>> import chess.svg From 708d590cecbb9768fe1ce62e1c2401bf70e47649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Wed, 25 Oct 2017 01:00:03 +0200 Subject: [PATCH 0059/1831] Some small tweaks In README.rst, `IPython notebook` is fixed to `Jupyter Notebook`, because `IPython Notebook` is deprecated and will be gone in the future, also capitalize the word `Notebook` because that's part of the official name. In `chess.svg`, some small tweaks are made. --- README.rst | 2 +- chess/svg.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 713c568ef..71a6baae9 100644 --- a/README.rst +++ b/README.rst @@ -68,7 +68,7 @@ Features * Supports Python 2.6+, Python 3.3+ and PyPy. -* IPython notebook integration. +* Jupyter Notebook integration. `SVG rendering docs `_. .. code:: python diff --git a/chess/svg.py b/chess/svg.py index 2f67a3024..44917f4cf 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -65,7 +65,7 @@ DEFAULT_STYLE = """ .check { - fill: url(#check_gradient); + fill: url(#check_gradient); } """ @@ -134,8 +134,8 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same square is drawn as a circle, like ``[(chess.E2, chess.E2)]``. - :param size: The size of the image in pixels (e.g. ``400`` for a 400 by 400 - board) or ``None`` (the default) for no size limit. + :param size: The size of the image in pixels (e.g., ``400`` for a 400 by + 400 board) or ``None`` (the default) for no size limit. :param style: A CSS stylesheet to include in the SVG image. >>> import chess From fbe2a2cec46d219dfbcc121cd9317d1f93e63657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Wed, 25 Oct 2017 16:24:04 +0200 Subject: [PATCH 0060/1831] Small tweaks to `examples/push_san.py` I found some little things that look better the way as in this patch. --- examples/push_san.py | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/push_san.py b/examples/push_san.py index 484a41d5b..99cf30927 100755 --- a/examples/push_san.py +++ b/examples/push_san.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -"""Play the immortal game using Board.push_san().""" +"""Play the immortal game using push_san() from chess.Board().""" from __future__ import print_function @@ -12,95 +12,95 @@ def play_immortal_game(): board = chess.Board() - # 1.e4 e5 + # 1. e4 e5 board.push_san("e4") board.push_san("e5") - # 2.f4 exf4 + # 2. f4 exf4 board.push_san("f4") board.push_san("exf4") - # 3.Bc4 Qh4+ + # 3. Bc4 Qh4+ board.push_san("Bc4") board.push_san("Qh4+") - # 4.Kf1 b5?! + # 4. Kf1 b5?! board.push_san("Kf1") board.push_san("b5") - # 5.Bxb5 Nf6 + # 5. Bxb5 Nf6 board.push_san("Bxb5") board.push_san("Nf6") - # 6.Nf3 Qh6 + # 6. Nf3 Qh6 board.push_san("Nf3") board.push_san("Qh6") - # 7.d3 Nh5 + # 7. d3 Nh5 board.push_san("d3") board.push_san("Nh5") - # 8.Nh4 Qg5 + # 8. Nh4 Qg5 board.push_san("Nh4") board.push_san("Qg5") - # 9.Nf5 c6 + # 9. Nf5 c6 board.push_san("Nf5") board.push_san("c6") - # 10.g4 Nf6 + # 10. g4 Nf6 board.push_san("g4") board.push_san("Nf6") - # 11.Rg1! cxb5? + # 11. Rg1! cxb5? board.push_san("Rg1") board.push_san("cxb5") - # 12.h4! Qg6 + # 12. h4! Qg6 board.push_san("h4") board.push_san("Qg6") - # 13.h5 Qg5 + # 13. h5 Qg5 board.push_san("h5") board.push_san("Qg5") - # 14.Qf3 Ng8 + # 14. Qf3 Ng8 board.push_san("Qf3") board.push_san("Ng8") - # 15.Bxf4 Qf6 + # 15. Bxf4 Qf6 board.push_san("Bxf4") board.push_san("Qf6") - # 16.Nc3 Bc5 + # 16. Nc3 Bc5 board.push_san("Nc3") board.push_san("Bc5") - # 17.Nd5 Qxb2 + # 17. Nd5 Qxb2 board.push_san("Nd5") board.push_san("Qxb2") - # 18.Bd6! Bxg1? + # 18. Bd6! Bxg1? board.push_san("Bd6") board.push_san("Bxg1") - # 19.e5! Qxa1+ + # 19. e5! Qxa1+ board.push_san("e5") board.push_san("Qxa1+") - # 20.Ke2 Na6 + # 20. Ke2 Na6 board.push_san("Ke2") board.push_san("Na6") - # 21.Nxg7+ Kd8 + # 21. Nxg7+ Kd8 board.push_san("Nxg7+") board.push_san("Kd8") - # 22.Qf6+! Nxf6 + # 22. Qf6+! Nxf6 board.push_san("Qf6+") board.push_san("Nxf6") - # 23.Be7# 1-0 + # 23. Be7# 1-0 board.push_san("Be7#") assert board.is_checkmate() From df45b6ed7e2b95858a8fb7f50797a4c0a933b4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Wed, 25 Oct 2017 19:43:08 +0200 Subject: [PATCH 0061/1831] Update `uci.py` In this module, mostly the docstrings are fixed: some missing commas added, also added asterisks and double-backticks for proper RST formatting for words that need them, also added __slots__ to namedtuple types you forgot... One major fix in here is that the `debug()` function's *on* argument is now made `False` by default (the change is reflected in the docstring). --- chess/uci.py | 72 ++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/chess/uci.py b/chess/uci.py index b9a00840f..6f3e64d81 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -39,14 +39,14 @@ import collections -class Score(collections.namedtuple("Score", ["cp", "mate"])): - """A centipawns or mate score sent by an UCI engine.""" - pass +class Score(collections.namedtuple("Score", "cp mate")): + """A *cp* (centipawns) or *mate* score sent by an UCI engine.""" + __slots__ -class BestMove(collections.namedtuple("BestMove", ["bestmove", "ponder"])): +class BestMove(collections.namedtuple("BestMove", "bestmove ponder")): """A bestmove and ponder move sent by an UCI engine.""" - pass + __slots__ class InfoHandler(object): @@ -72,8 +72,8 @@ class InfoHandler(object): See :attr:`~chess.uci.InfoHandler.info` for a way to access this dictionary in a thread-safe way during search. - If you want to be notified whenever new information is available - you would usually subclass the *InfoHandler* class: + If you want to be notified whenever new information is available, + you would usually subclass the :class:`~chess.uci.InfoHandler` class: >>> class MyHandler(chess.uci.InfoHandler): ... def post_info(self): @@ -110,33 +110,33 @@ def pv(self, moves): """ Received the principal variation as a list of moves. - In MultiPV mode this is related to the most recent *multipv* number + In *MultiPV* mode, this is related to the most recent *multipv* number sent by the engine. """ self.info["pv"][self.info.get("multipv", 1)] = moves def multipv(self, num): """ - Received a new multipv number, starting at 1. + Received a new *multipv* number, starting at 1. - If multipv occurs in an info line, this is guaranteed to be called + If *multipv* occurs in an info line, this is guaranteed to be called before *score* or *pv*. """ self.info["multipv"] = num def score(self, cp, mate, lowerbound, upperbound): """ - Received a new evaluation in centipawns or a mate score. + Received a new evaluation in *cp* (centipawns) or a *mate* score. - *cp* may be *None* if no score in centipawns is available. + *cp* may be ``None`` if no score in centipawns is available. - *mate* may be *None* if no forced mate has been found. A negative - numbers means the engine thinks it will get mated. + *mate* may be ``None`` if no forced mate has been found. A negative + number means the engine thinks it will get mated. - lowerbound and upperbound are usually *False*. If *True*, the sent - score are just a lowerbound or upperbound. + *lowerbound* and *upperbound* are usually ``False``. If ``True``, + the sent score is just a *lowerbound* or *upperbound*. - In MultiPV mode this is related to the most recent *multipv* number + In MultiPV mode, this is related to the most recent *multipv* number sent by the engine. """ if not lowerbound and not upperbound: @@ -146,20 +146,20 @@ def currmove(self, move): """ Received a move the engine is currently thinking about. - These moves come directly from the engine. So the castling move - representation depends on the UCI_Chess960 option of the engine. + These moves come directly from the engine, so the castling move + representation depends on the *UCI_Chess960* option of the engine. """ self.info["currmove"] = move def currmovenumber(self, x): - """Received a new currmovenumber.""" + """Received a new current move number.""" self.info["currmovenumber"] = x def hashfull(self, x): """ Received new information about the hashtable. - The hashtable is x permill full. + The hashtable is *x* permill full. """ self.info["hashfull"] = x @@ -168,7 +168,7 @@ def nps(self, x): self.info["nps"] = x def tbhits(self, x): - """Received new information about the number of table base hits.""" + """Received new information about the number of tablebase hits.""" self.info["tbhits"] = x def cpuload(self, x): @@ -225,9 +225,9 @@ def on_bestmove(self, bestmove, ponder): def on_go(self): """ - A go command is being sent. + A *go* command is being sent. - Since information about the previous search is invalidated the + Since information about the previous search is invalidated, the dictionary with the current information will be cleared. """ with self.lock: @@ -687,12 +687,12 @@ def command(): return self._queue_command(command, async_callback) - def debug(self, on, async_callback=None): + def debug(self, on=False, async_callback=None): """ - Switch the debug mode on or off. + Enable debug mode by changing the *on* argument to ``True``. Disabled by default. - In debug mode the engine should send additional infos to the GUI to - help debugging. This mode should be switched off by default. + In debug mode, the engine should sequentially send additional info to the GUI to + help with the debugging. :param on: bool @@ -729,7 +729,7 @@ def command(): def setoption(self, options, async_callback=None): """ - Set values for the engines available options. + Set values for the engine's available options. :param options: A dictionary with option names as keys. @@ -778,7 +778,7 @@ def ucinewgame(self, async_callback=None): This can be a new game the engine should play or if the engine should analyse a position from a different game. Using this command is - recommended but not required. + recommended, but not required. :return: Nothing """ @@ -808,7 +808,7 @@ def position(self, board, async_callback=None): up to the position will be sent, so that the engine can detect repetitions. - If the position is from a new game it is recommended to use the + If the position is from a new game, it is recommended to use the *ucinewgame* command before the *position* command. :param board: A *chess.Board*. @@ -889,7 +889,7 @@ def go(self, searchmoves=None, ponder=False, wtime=None, btime=None, winc=None, *depth*, *nodes*, *mate*, *infinite* or some time control settings, so that the engine knows how long to calculate. - Note that when using *infinite* or *ponder* the engine will not stop + Note that when using *infinite* or *ponder*, the engine will not stop until it is told to. :param searchmoves: Restrict search to moves in this list. @@ -1030,7 +1030,7 @@ def ponderhit(self, async_callback=None): """ May be sent if the expected ponder move has been played. - The engine should continue searching but should switch from pondering + The engine should continue searching, but should switch from pondering to normal search. :return: Nothing. @@ -1093,7 +1093,7 @@ def terminate(self, async_callback=None): Terminate the engine. This is not an UCI command. It instead tries to terminate the engine - on operating system level, for example by sending SIGTERM on Unix + on operating system level, like sending SIGTERM on Unix systems. If possible, first try the *quit* command. :return: The return code of the engine process (or a Future). @@ -1105,7 +1105,7 @@ def kill(self, async_callback=None): """ Kill the engine. - Forcefully kill the engine process, for example by sending SIGKILL. + Forcefully kill the engine process, like by sending SIGKILL. :return: The return code of the engine process (or a Future). """ @@ -1132,7 +1132,7 @@ def popen_engine(command, engine_cls=Engine, setpgrp=False, _popen_lock=threadin 'Tord Romstad, Marco Costalba and Joona Kiiski' :param setpgrp: Open the engine process in a new process group. This will - stop signals (such as keyboards interrupts) from propagating from the + stop signals (such as keyboard interrupts) from propagating from the parent process. Defaults to ``False``. """ return _popen_engine(command, engine_cls, setpgrp, _popen_lock, **kwargs) From 46443c692a45c7014afceab93bf0760cc75657b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Wed, 25 Oct 2017 20:10:02 +0200 Subject: [PATCH 0062/1831] Update `patch-1` Oops, forgot to add `= ()` to those `__slots__`. --- chess/uci.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/uci.py b/chess/uci.py index 6f3e64d81..2f68d1b30 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -41,12 +41,12 @@ class Score(collections.namedtuple("Score", "cp mate")): """A *cp* (centipawns) or *mate* score sent by an UCI engine.""" - __slots__ + __slots__ = () class BestMove(collections.namedtuple("BestMove", "bestmove ponder")): """A bestmove and ponder move sent by an UCI engine.""" - __slots__ + __slots__ = () class InfoHandler(object): From 918a16bf60cf7d27c15dfc040e59d9cd683b7c70 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 27 Oct 2017 14:26:15 +0200 Subject: [PATCH 0063/1831] revert functional change on uci debug (#184) --- chess/uci.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/uci.py b/chess/uci.py index 2f68d1b30..899da1855 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -687,12 +687,12 @@ def command(): return self._queue_command(command, async_callback) - def debug(self, on=False, async_callback=None): + def debug(self, on, async_callback=None): """ - Enable debug mode by changing the *on* argument to ``True``. Disabled by default. + Switch the debug mode on or off. - In debug mode, the engine should sequentially send additional info to the GUI to - help with the debugging. + In debug mode, the engine should send additional information to the + GUI to help with the debugging. Usually this mode is off by default. :param on: bool From 29ea5471826c63bd0a129ae1a657cd7836eabd56 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 27 Oct 2017 14:38:37 +0200 Subject: [PATCH 0064/1831] cherry pick svg doc tweaks (closes #186) --- README.rst | 2 +- docs/svg.rst | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 71a6baae9..55f307807 100644 --- a/README.rst +++ b/README.rst @@ -68,7 +68,7 @@ Features * Supports Python 2.6+, Python 3.3+ and PyPy. -* Jupyter Notebook integration. +* IPython/Jupyter Notebook integration. `SVG rendering docs `_. .. code:: python diff --git a/docs/svg.rst b/docs/svg.rst index 8647c69a9..7e9430a52 100644 --- a/docs/svg.rst +++ b/docs/svg.rst @@ -1,10 +1,10 @@ SVG rendering ============= -This module renders SVGs (mostly for IPython integration). Piece images -are copyright -`Colin M.L. Burnett `_ and -triple licensed under GFDL & BSD & GPL. +The :mod:`chess.svg` module renders SVG images (mostly for IPython/Jupyter +notebook integration). The piece images by +`Colin M.L. Burnett `_ are triple +licensed under the GFDL, BSD and GPL. .. autofunction:: chess.svg.piece From 95b3d3bfc8e8e437f1e597de8cf3be798b6daab2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 27 Oct 2017 14:44:30 +0200 Subject: [PATCH 0065/1831] cherry pick uci doc fixes (closes #187) --- docs/uci.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/uci.rst b/docs/uci.rst index 349e5e730..a9268a33b 100644 --- a/docs/uci.rst +++ b/docs/uci.rst @@ -58,7 +58,7 @@ no longer alive. Asynchronous communication -------------------------- -By default all operations are executed synchronously and their result is +By default, all operations are executed synchronously and their result is returned. For example >>> engine.go(movetime=2000) @@ -76,7 +76,7 @@ BestMove(bestmove=Move.from_uci('e2e4'), ponder=None) >>> command.done() True -Instead of just passing *async_callback=True* a callback function may be +Instead of just passing *async_callback=True*, a callback function may be passed. It will be invoked **possibly on a different thread** as soon as the command is completed. It takes the command future as a single argument. @@ -94,7 +94,7 @@ is ``e1g1`` for short castling. The same move would be ``e1h1`` in *UCI_Chess960* mode. This is abstracted away by the UCI module, but if the engine supports it, it -is recommended to enable enable *UCI_Chess960* mode. +is recommended to enable *UCI_Chess960* mode. >>> engine.setoption({"UCI_Chess960": True}) @@ -115,7 +115,7 @@ Info handler .. py:attribute:: lowerbound - If the score is not exact but only a lowerbound. + If the score is not exact, but only a lowerbound. .. py:attribute:: upperbound @@ -127,7 +127,7 @@ Info handler .. py:attribute:: info The default implementation stores all received information in this - dictionary. To get a consistent snapshot use the object as if it were + dictionary. To get a consistent snapshot, use the object as if it were a :class:`threading.Lock()`. >>> # Start thinking. From 5a1ac40e7804e26f1d999e214721ad40d7b4634f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Fri, 27 Oct 2017 17:45:54 +0200 Subject: [PATCH 0066/1831] Update uci.py I did my best yet again to improve the docstrings, so that the docs will be even better. --- chess/uci.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/chess/uci.py b/chess/uci.py index 899da1855..82308b35d 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -45,15 +45,15 @@ class Score(collections.namedtuple("Score", "cp mate")): class BestMove(collections.namedtuple("BestMove", "bestmove ponder")): - """A bestmove and ponder move sent by an UCI engine.""" + """A *bestmove* and *ponder* move sent by an UCI engine.""" __slots__ = () class InfoHandler(object): """ Chess engines may send information about their calculations with the - *info* command. Info handlers can be used to aggregate or react to this - information. + *info* command. An :class:`~chess.uci.InfoHandler` instance can be used + to aggregate or react to this information. >>> # Register a standard info handler. >>> info_handler = chess.uci.InfoHandler() @@ -77,9 +77,9 @@ class InfoHandler(object): >>> class MyHandler(chess.uci.InfoHandler): ... def post_info(self): - ... # Called whenever a complete *info* line has been processed. + ... # Called whenever a complete info line has been processed. ... print(self.info) - ... super(MyHandler, self).post_info() # release lock + ... super(MyHandler, self).post_info() # Release the lock. """ def __init__(self): self.lock = threading.Lock() @@ -184,7 +184,7 @@ def refutation(self, move, refuted_by): Received a new refutation of a move. *refuted_by* may be a list of moves representing the mainline of the - refutation or *None* if no refutation has been found. + refutation or ``None`` if no refutation has been found. Engines should only send refutations if the *UCI_ShowRefutations* option has been enabled. @@ -195,17 +195,17 @@ def currline(self, cpunr, moves): """ Received a new snapshot of a line a specific CPU is calculating. - *cpunr* is an integer representing a specific CPU. *moves* is a list + *cpunr* is an integer representing a specific CPU and *moves* is a list of moves. """ self.info["currline"][cpunr] = moves def pre_info(self, line): """ - Received a new info line about to be processed. + Received a new info line to be processed. - When subclassing remember to call this method of the parent class in - order to keep the locking in tact. + When subclassing, remember to call this method on the parent class + to keep the locking intact. """ self.lock.acquire() self.info.pop("multipv", None) @@ -214,13 +214,13 @@ def post_info(self): """ Processing of a new info line has been finished. - When subclassing remember to call this method of the parent class in - order to keep the locking in tact. + When subclassing, remember to call this method on the parent class + to keep the locking intact. """ self.lock.release() def on_bestmove(self, bestmove, ponder): - """A new bestmove and pondermove have been received.""" + """A new *bestmove* and *ponder* move have been received.""" pass def on_go(self): @@ -374,7 +374,7 @@ def _bestmove(self, arg): self.ponder = None if self.bestmove is not None and len(tokens) >= 3 and tokens[1] == "ponder" and tokens[2] != "(none)": - # The ponder move must be legal after the bestmove. Generally we + # The ponder move must be legal after the bestmove. Generally, we # trust the engine on this. But we still have to convert # non-UCI_Chess960 castling moves. try: From 0a1291d5e2f3d282af4b5c5d97c62a3223f53209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Fri, 27 Oct 2017 18:04:45 +0200 Subject: [PATCH 0067/1831] Update uci.py #2 Forgot to fix something in uci.py and here it is. ;) --- chess/uci.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/uci.py b/chess/uci.py index 899da1855..54298ec25 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -692,7 +692,7 @@ def debug(self, on, async_callback=None): Switch the debug mode on or off. In debug mode, the engine should send additional information to the - GUI to help with the debugging. Usually this mode is off by default. + GUI to help with the debugging. Usually, this mode is off by default. :param on: bool @@ -854,7 +854,7 @@ def position(self, board, async_callback=None): while switchyard: board.push(switchyard.pop()) - # Send startposition. + # Send starting position. if uci_variant == "chess" and board.fen() == chess.STARTING_FEN: builder.append("startpos") else: From 764bb1021d17bec0efc4a368c4d55a79696cbe2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Fri, 27 Oct 2017 20:06:32 +0200 Subject: [PATCH 0068/1831] Update docs/svg.rst I don't know why the build on Travis CI failed only for Python 3.6, so I'll do another pull request. --- docs/svg.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/svg.rst b/docs/svg.rst index 7e9430a52..8d838ad88 100644 --- a/docs/svg.rst +++ b/docs/svg.rst @@ -2,7 +2,7 @@ SVG rendering ============= The :mod:`chess.svg` module renders SVG images (mostly for IPython/Jupyter -notebook integration). The piece images by +Notebook integration). The piece images by `Colin M.L. Burnett `_ are triple licensed under the GFDL, BSD and GPL. From 7ef928ddb00b39cb9062856860d9c4792ecd3e25 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 28 Oct 2017 15:40:05 +0200 Subject: [PATCH 0069/1831] cherry pick grammar fixes (closes #195) --- README.rst | 34 +++++++++++++++++----------------- chess/__init__.py | 8 ++++---- chess/gaviota.py | 4 ++-- docs/core.rst | 2 +- test.py | 2 +- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.rst b/README.rst index 55f307807..83cf90cf7 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ Introduction ------------ python-chess is a pure Python chess library with move generation and validation -and handling of common formats. This is the scholars mate in python-chess: +and handling of common formats. This is the Scholar's mate in python-chess: .. code:: python @@ -117,7 +117,7 @@ Features >>> board.is_game_over() True -* Detects repetitions. Has a half move clock. +* Detects repetitions. Has a half-move clock. .. code:: python @@ -130,9 +130,9 @@ Features >>> board.can_claim_draw() False - With the new rules from July 2014 a game ends drawn (even without a claim) - once a fivefold repetition occurs or if there are 75 moves without a pawn - push or capture. Other ways of ending a game take precedence. + With the new rules from July 2014, a game ends as a draw (even without a + claim) once a fivefold repetition occurs or if there are 75 moves without + a pawn push or capture. Other ways of ending a game take precedence. .. code:: python @@ -201,9 +201,9 @@ Features >>> ops == {'bm': [chess.Move.from_uci('d6d1')], 'id': 'BK.01'} True -* Detects absolute `pins and their directions `_. +* Detects `absolute pins and their directions `_. -* Read Polyglot opening books. +* Reads Polyglot opening books. `Docs `__. .. code:: python @@ -223,7 +223,7 @@ Features >>> book.close() -* Read and write PGNs. Supports headers, comments, NAGs and a tree of +* Reads and writes PGNs. Supports headers, comments, NAGs and a tree of variations. `Docs `__. @@ -244,7 +244,7 @@ Features >>> first_game.board().variation_san(moves) '1. e4 c5 2. c4 Nc6 3. Ne2 Nf6 4. Nbc3 Nb4 5. g3 Nd3#' - >>> # Iterate through the mainline of this embarrasingly short game. + >>> # Iterate through the mainline of this embarrassingly short game. >>> node = first_game >>> while not node.is_end(): ... next_node = node.variations[0] @@ -334,18 +334,18 @@ Selected use cases If you like, let me know if you are creating something intresting with python-chess, for example: -* a stand alone chess computer based on DGT board - http://www.picochess.org/ -* a website to probe Syzygy endgame tablebases - https://syzygy-tables.info/ -* a GUI to play against UCI chess engines - http://johncheetham.com/projects/jcchess/ -* an HTTP microservice to render board images - https://github.com/niklasf/web-boardimage -* a bot to play chess on Telegram - https://github.com/cxjdavin/tgchessbot -* a tool to build `Anki `_ decks from a PGN opening repertoire - https://github.com/asdfjkl/pgn2anki +* a stand-alone chess computer based on DGT board – http://www.picochess.org/ +* a website to probe Syzygy endgame tablebases – https://syzygy-tables.info/ +* a GUI to play against UCI chess engines – http://johncheetham.com/projects/jcchess/ +* an HTTP microservice to render board images – https://github.com/niklasf/web-boardimage +* a bot to play chess on Telegram – https://github.com/cxjdavin/tgchessbot +* a tool to build `Anki `_ decks from a PGN opening repertoire – https://github.com/asdfjkl/pgn2anki Acknowledgements ---------------- Thanks to the Stockfish authors and thanks to Sam Tannous for publishing his -approach to `avoid rotated bitboards with direct lookup (pdf) `_ +approach to `avoid rotated bitboards with direct lookup (PDF) `_ alongside his GPL2+ engine `Shatranj `_. Some move generation ideas are taken from these sources. @@ -355,7 +355,7 @@ The probing code in python-chess is very directly ported from his C probing code Thanks to Miguel A. Ballicora for his `Gaviota tablebases `_. -(I wish the generating code was free software). +(I wish the generating code was free software.) License ------- diff --git a/chess/__init__.py b/chess/__init__.py index e74b302f9..f874c37aa 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1696,7 +1696,7 @@ def is_insufficient_material(self): def is_seventyfive_moves(self): """ Since the first of July 2014 a game is automatically drawn (without - a claim by one of the players) if the half move clock since a capture + a claim by one of the players) if the half-move clock since a capture or pawn move is equal to or grather than 150. Other means to end a game take precedence. """ @@ -1845,7 +1845,7 @@ def push(self, move): self.turn = not self.turn return - # Zero the half move clock. + # Zero the half-move clock. if self.is_zeroing(move): self.halfmove_clock = 0 @@ -2068,7 +2068,7 @@ def set_fen(self, fen): if parts[3] not in SQUARE_NAMES: raise ValueError("invalid en passant part in fen: {0}".format(repr(fen))) - # Check that the half move part is valid. + # Check that the half-move part is valid. if int(parts[4]) < 0: raise ValueError("halfmove clock can not be negative: {0}".format(repr(fen))) @@ -2381,7 +2381,7 @@ def set_epd(self, epd): """ Parses the given EPD string and uses it to set the position. - If present the ``hmvc`` and the ``fmvn`` are used to set the half move + If present the ``hmvc`` and the ``fmvn`` are used to set the half-move clock and the fullmove number. Otherwise ``0`` and ``1`` are used. Returns a dictionary of parsed operations. Values can be strings, diff --git a/chess/gaviota.py b/chess/gaviota.py index 281df2085..3c3eac89c 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1547,11 +1547,11 @@ def probe_dtm(self, board): """ Probes for depth to mate information. - The absolute value is the number of half moves until forced mate + The absolute value is the number of half-moves until forced mate (or ``0`` in drawn positions). The value is positive if the side to move is winning, otherwise it is negative. - In the example position white to move will get mated in 10 half moves: + In the example position white to move will get mated in 10 half-moves: >>> import chess >>> import chess.gaviota diff --git a/docs/core.rst b/docs/core.rst index 1988f29e2..363132a06 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -154,7 +154,7 @@ Board .. py:attribute:: halfmove_clock - The number of half moves since the last capture or pawn move. + The number of half-moves since the last capture or pawn move. .. py:attribute:: promoted diff --git a/test.py b/test.py index 3cd5ea079..e96afcd89 100755 --- a/test.py +++ b/test.py @@ -652,7 +652,7 @@ def test_move_count(self): def test_polyglot(self): # Test polyglot compability using test data from # http://hardy.uhasselt.be/Toga/book_format.html. Forfeiting castling - # rights should not reset the half move counter, though. + # rights should not reset the half-move counter, though. board = chess.Board() self.assertEqual(board.fen(), "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1") From 7a994746a00b4fc47bb68a29132690970bce89d5 Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Fri, 27 Oct 2017 20:43:21 +0530 Subject: [PATCH 0070/1831] Added white,black,random,nps and otim API --- chess/xboard.py | 125 ++++++++++++++++++++++++++++++++++++++++++++++-- test.py | 1 + 2 files changed, 121 insertions(+), 5 deletions(-) diff --git a/chess/xboard.py b/chess/xboard.py index 1e009138c..5c471f1be 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -145,7 +145,6 @@ def __exit__(self, exc_type, exc_value, traceback): class FeatureMap(object): - def __init__(self): # Populated with defaults to begin with self._features = { @@ -447,14 +446,14 @@ def easy(self, async_callback=None): """ Tell the engine not to ponder. """ - return self.pondering(False) + return self.pondering(False, async_callback) def hard(self, async_callback=None): """ Tell the engine to ponder. TODO: pondering not yet supported. """ - return self.pondering(True) + return self.pondering(True, async_callback) def set_post(self, flag, async_callback=None): """ @@ -482,7 +481,7 @@ def post(self, async_callback=None): :return: Nothing """ - return self.set_post(True) + return self.set_post(True, async_callback) def nopost(self, async_callback=None): """ @@ -490,7 +489,7 @@ def nopost(self, async_callback=None): :return: Nothing """ - return self.set_post(False) + return self.set_post(False, async_callback) def xboard(self, async_callback=None): """ @@ -684,6 +683,99 @@ def command(): return self._queue_command(command, async_callback) + def set_side_to_move(self, color, async_callback=None): + """ + Set the side to move, set the engine to move for the opposite side + and exit force mode. + + :param color: The desired side to move. + + :return: Nothing + """ + if not self.features.supports("colors"): + raise EngineStateException("engine does not support the 'colors' feature") + + with self.state_changed: + if not self.idle: + raise EngineStateException("{} command while engine is busy", + chess.COLOR_NAMES[color]) + + self.in_force = False + def command(): + with self.semaphore: + self.send_line(side) + + if self.terminated.is_set(): + raise EngineTerminatedException + + return self._queue_command(command, async_callback) + + def white(self, async_callback=None): + """ + Set the side to move to be white, engine to play as black and + exit force mode. + + :return: Nothing + """ + set_side_to_move(chess.WHITE, async_callback) + + def black(self, async_callback=None): + """ + Set the side to move to be black, engine to play as white and + exit force mode. + + :return: Nothing + """ + set_side_to_move(chess.BLACK, async_callback) + + def random(self, async_callback=None): + """ + Toggles random mode. + + In random mode, the engine may choose to add a random factor to it's + evaluation of any given position prompting variation in play or may + ignore it entirely. + + :return: Nothing + """ + with self.state_changed: + if not self.idle: + raise EngineStateException("random command while engine is busy") + + def command(): + with self.semaphore: + self.send_line("random") + + if self.terminated.is_set(): + raise EngineTerminatedException + + return self._queue_command(command, async_callback) + + def nps(self, target_nps, async_callback=None): + """ + Tell the engine to limit it's speed of search in terms of + Nodes Per Second to the provided value. + + :param target_nps: The limiting Nodes Per Second value + + :return: Nothing + """ + if not self.features.supports("nps"): + raise EngineStateException("engine does not support the 'nps' feature") + + with self.state_changed: + if not self.idle: + raise EngineStateException("nps command while engine is busy") + + def command(): + with self.semaphore: + self.send_line("nps " + str(target_nps)) + + if self.terminated.is_set(): + raise EngineTerminatedException + + return self._queue_command(command, async_callback) + def st(self, time, async_callback=None): """ Set maximum time the engine is to search for. @@ -750,6 +842,29 @@ def command(): return self._queue_command(command, async_callback) + def otim(self, time, async_callback=None): + """ + Synchronize the engines clock with the total amount of time left. + + :param time: The total time left in centiseconds + + :return: Nothing + """ + if not self.features.supports("time"): + raise EngineStateException("engine does not support the 'time' feature") + + with self.state_changed: + if not self.idle: + raise EngineStateException("otim command while engine is busy") + + def command(): + with self.semaphore: + self.send_line("otim " + str(time)) + + if self.terminated.is_set(): + raise EngineTerminatedException + + return self._queue_command(command, async_callback) def level(self, movestogo=0, minutes=5, seconds=None, inc=0, async_callback=None): """ diff --git a/test.py b/test.py index e96afcd89..d9f3b526a 100755 --- a/test.py +++ b/test.py @@ -2189,6 +2189,7 @@ def test_time(self): self.engine.new() self.engine.level(0, 1, 0, 0) self.engine.time(100) + self.engine.otim(100) self.engine.go() def test_mate_search(self): From 9ff1c268012145ea2194d0901a7fd6147b7cd19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sat, 28 Oct 2017 15:43:57 +0200 Subject: [PATCH 0071/1831] cherry pick grammar fixes for polyglot.py (closes #193) --- chess/polyglot.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chess/polyglot.py b/chess/polyglot.py index 1d5b1394e..6c5624cbd 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -263,7 +263,7 @@ def hash_castling(self, board): def hash_ep_square(self, board): # Hash in the en passant file. if board.ep_square: - # But only if theres actually a pawn ready to capture it. Legality + # But only if there's actually a pawn ready to capture it. Legality # of the potential capture is irrelevant. if board.turn == chess.WHITE: ep_mask = chess.shift_down(chess.BB_SQUARES[board.ep_square]) @@ -288,7 +288,7 @@ def zobrist_hash(board, _hasher=ZobristHasher(POLYGLOT_RANDOM_ARRAY)): """ Calculates the Polyglot Zobrist hash of the position. - A zobrist hash is an XOR of pseudo random values picked from + A Zobrist hash is an XOR of pseudo-random values picked from an array. Which values are picked is decided by features of the position, such as piece positions, castling rights and en passant squares. @@ -297,7 +297,7 @@ def zobrist_hash(board, _hasher=ZobristHasher(POLYGLOT_RANDOM_ARRAY)): class Entry(collections.namedtuple("Entry", "key raw_move weight learn")): - """An entry from a polyglot opening book.""" + """An entry from a Polyglot opening book.""" __slots__ = () @@ -331,7 +331,7 @@ def move(self, chess960=False): class MemoryMappedReader(object): - """Maps a polyglot opening book to memory.""" + """Maps a Polyglot opening book to memory.""" def __init__(self, filename): self.fd = os.open(filename, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) @@ -428,7 +428,7 @@ def find_all(self, board, minimum_weight=1, exclude_moves=()): def find(self, board, minimum_weight=1, exclude_moves=()): """ - Finds the main entry for the given position or zobrist hash. + Finds the main entry for the given position or Zobrist hash. The main entry is the first entry with the highest weight. From 15ef412b10fc535430730e72ee38d20db7fc2789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sat, 28 Oct 2017 15:48:26 +0200 Subject: [PATCH 0072/1831] update uci.rst (closes #188) --- docs/uci.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/uci.rst b/docs/uci.rst index a9268a33b..9aefcaf08 100644 --- a/docs/uci.rst +++ b/docs/uci.rst @@ -21,11 +21,12 @@ The `Universal Chess Interface`_ is a protocol for communicating with engines. .. py:attribute:: author - The author, as sent via *id author*. Just like the name. + The author of the engine. Conforming engines should send this as + *id author* after the initial *uci* command. .. py:attribute:: options - A case insensitive dictionary of :ref:`options`. The engine should send + A case-insensitive dictionary of :ref:`options`. The engine should send available options when it receives the initial *uci* command. .. py:attribute:: uciok @@ -93,8 +94,8 @@ There are different ways castling moves may be encoded. The normal way to do it is ``e1g1`` for short castling. The same move would be ``e1h1`` in *UCI_Chess960* mode. -This is abstracted away by the UCI module, but if the engine supports it, it -is recommended to enable *UCI_Chess960* mode. +This is abstracted away by the :mod:`chess.uci` module, but if the engine +supports it, it is recommended to enable *UCI_Chess960* mode. >>> engine.setoption({"UCI_Chess960": True}) @@ -110,8 +111,8 @@ Info handler .. py:attribute:: mate - Mate in x or ``None``. Negative if the engine thinks it is going to be - mated. + Mate in x or ``None``. Negative number if the engine thinks it is going + to be mated. .. py:attribute:: lowerbound @@ -160,7 +161,7 @@ Options Officially documented types are ``check`` for a boolean value, ``spin`` for an integer value between a minimum and a maximum, ``combo`` for an enumeration of predefined string values (one of which can be selected), - ``button`` for an action and ``string`` for a textfield. + ``button`` for an action and ``string`` for a text field. .. py:attribute:: default From a649dec4ee277f662627f825384b314e23b51a05 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 28 Oct 2017 15:55:59 +0200 Subject: [PATCH 0073/1831] minor doc tweak --- chess/uci.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/uci.py b/chess/uci.py index 82308b35d..3001854f5 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -119,7 +119,7 @@ def multipv(self, num): """ Received a new *multipv* number, starting at 1. - If *multipv* occurs in an info line, this is guaranteed to be called + If *multipv* occurs in an *info* line, this is guaranteed to be called before *score* or *pv*. """ self.info["multipv"] = num From 15be1c91d120d08743ac637b2f55b43d95ff222e Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Sat, 28 Oct 2017 19:30:16 +0530 Subject: [PATCH 0074/1831] Simplified some code by abstracting out feature and is-busy asserts --- chess/xboard.py | 95 ++++++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 64 deletions(-) diff --git a/chess/xboard.py b/chess/xboard.py index 5c471f1be..d6faf9e27 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -400,6 +400,15 @@ def _queue_command(self, command, async_callback): except concurrent.futures.TimeoutError: pass + def _assert_supports_feature(self, feature_name): + if not self.features.supports(feature_name): + raise EngineStateException("engine does not support the '{}' feature", feature_name) + + def _assert_not_busy(self, cmd): + with self.state_changed: + if not self.idle: + raise EngineStateException("{} command while engine is busy", cmd) + def ping(self, async_callback=None): """ Command used to synchronize with the engine. @@ -565,9 +574,7 @@ def new(self, async_callback=None): :return: Nothing """ - with self.state_changed: - if not self.idle: - raise EngineStateException("new command while engine is busy") + self._assert_not_busy("new") def command(): with self.semaphore: @@ -589,9 +596,7 @@ def setboard(self, board, async_callback=None): :raises: :exc:`~chess.engine.EngineStateException` if the engine is still calculating. """ - with self.state_changed: - if not self.idle: - raise EngineStateException("setboard command while engine is busy") + self._assert_not_busy("setboard") # Setboard should be sent after force. self.force() @@ -619,12 +624,8 @@ def memory(self, amount, async_callback=None): :return: Nothing """ - if not self.features.supports("memory"): - raise EngineStateException("engine does not support the 'memory' feature") - - with self.state_changed: - if not self.idle: - raise EngineStateException("memory command while engine is busy") + self._assert_supports_feature("memory") + self._assert_not_busy("memory") def command(): with self.semaphore: @@ -644,12 +645,8 @@ def cores(self, num, async_callback=None): :return: Nothing """ - if not self.features.supports("smp"): - raise EngineStateException("engine does not support the 'smp' feature") - - with self.state_changed: - if not self.idle: - raise EngineStateException("cores command while engine is busy") + self._assert_supports_feature("smp") + self._assert_not_busy("cores") def command(): with self.semaphore: @@ -666,12 +663,8 @@ def playother(self, async_callback=None): :return: Nothing """ - if not self.features.supports("playother"): - raise EngineStateException("engine does not support the 'playother' feature") - - with self.state_changed: - if not self.idle: - raise EngineStateException("playother command while engine is busy") + self._assert_supports_feature("playother") + self._assert_not_busy("playother") self.in_force = False def command(): @@ -692,13 +685,8 @@ def set_side_to_move(self, color, async_callback=None): :return: Nothing """ - if not self.features.supports("colors"): - raise EngineStateException("engine does not support the 'colors' feature") - - with self.state_changed: - if not self.idle: - raise EngineStateException("{} command while engine is busy", - chess.COLOR_NAMES[color]) + self._assert_supports_feature("colors") + self._assert_not_busy(chess.COLOR_NAMES[color]) self.in_force = False def command(): @@ -738,9 +726,7 @@ def random(self, async_callback=None): :return: Nothing """ - with self.state_changed: - if not self.idle: - raise EngineStateException("random command while engine is busy") + self._assert_not_busy("random") def command(): with self.semaphore: @@ -760,12 +746,8 @@ def nps(self, target_nps, async_callback=None): :return: Nothing """ - if not self.features.supports("nps"): - raise EngineStateException("engine does not support the 'nps' feature") - - with self.state_changed: - if not self.idle: - raise EngineStateException("nps command while engine is busy") + self._assert_supports_feature("nps") + self._assert_not_busy("nps") def command(): with self.semaphore: @@ -784,9 +766,7 @@ def st(self, time, async_callback=None): :return: Nothing """ - with self.state_changed: - if not self.idle: - raise EngineStateException("st command while engine is busy") + self._assert_not_busy("st") def command(): with self.semaphore: @@ -805,9 +785,7 @@ def sd(self, depth, async_callback=None): :return: Nothing """ - with self.state_changed: - if not self.idle: - raise EngineStateException("sd command while engine is busy") + self._assert_not_busy("sd") def command(): with self.semaphore: @@ -826,12 +804,8 @@ def time(self, time, async_callback=None): :return: Nothing """ - if not self.features.supports("time"): - raise EngineStateException("engine does not support the 'time' feature") - - with self.state_changed: - if not self.idle: - raise EngineStateException("time command while engine is busy") + self._assert_supports_feature("time") + self._assert_not_busy("time") def command(): with self.semaphore: @@ -850,12 +824,8 @@ def otim(self, time, async_callback=None): :return: Nothing """ - if not self.features.supports("time"): - raise EngineStateException("engine does not support the 'time' feature") - - with self.state_changed: - if not self.idle: - raise EngineStateException("otim command while engine is busy") + self._assert_supports_feature("time") + self._assert_not_busy("otim") def command(): with self.semaphore: @@ -885,9 +855,7 @@ def level(self, movestogo=0, minutes=5, seconds=None, inc=0, async_callback=None :return: Nothing """ - with self.state_changed: - if not self.idle: - raise EngineStateException("level command while engine is busy") + self._assert_not_busy("level") builder = [] builder.append("level") @@ -949,10 +917,9 @@ def go(self, async_callback=None): :raises: :exc:`~chess.engine.EngineStateException` if the engine is already calculating. """ - with self.state_changed: - if not self.idle: - raise EngineStateException("go command while engine is already busy") + self._assert_not_busy("go") + with self.state_changed: self.idle = False self.search_started.clear() self.move_received.clear() From caeb45d95acf4b614a2a6d310fac60e1562a1734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sat, 28 Oct 2017 19:27:55 +0200 Subject: [PATCH 0075/1831] Update uci.py Found some things I missed to fix. The inline comments don't end with a period (checked PEP8), so I fixed that. Also, chess players (White and Black) are always written with the capital initial. Fixed one instance where None was not properly formatted; double-backticks formatting rather than asterisk formatting, just like everywhere else. --- chess/uci.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/uci.py b/chess/uci.py index 4845749fc..20c418061 100644 --- a/chess/uci.py +++ b/chess/uci.py @@ -79,7 +79,7 @@ class InfoHandler(object): ... def post_info(self): ... # Called whenever a complete info line has been processed. ... print(self.info) - ... super(MyHandler, self).post_info() # Release the lock. + ... super(MyHandler, self).post_info() # Release the lock """ def __init__(self): self.lock = threading.Lock() @@ -895,8 +895,8 @@ def go(self, searchmoves=None, ponder=False, wtime=None, btime=None, winc=None, :param searchmoves: Restrict search to moves in this list. :param ponder: Bool to enable pondering mode. The engine will not stop pondering in the background until a *stop* command is received. - :param wtime: Integer of milliseconds white has left on the clock. - :param btime: Integer of milliseconds black has left on the clock. + :param wtime: Integer of milliseconds White has left on the clock. + :param btime: Integer of milliseconds Black has left on the clock. :param winc: Integer of white Fisher increment. :param binc: Integer of black Fisher increment. :param movestogo: Number of moves to the next time control. If this is @@ -910,7 +910,7 @@ def go(self, searchmoves=None, ponder=False, wtime=None, btime=None, winc=None, :return: A tuple of two elements. The first is the best move according to the engine. The second is the ponder move. This is the reply - as sent by the engine. Either of the elements may be *None*. + as sent by the engine. Either of the elements may be ``None``. :raises: :exc:`~chess.uci.EngineStateException` if the engine is already calculating. From 987efda844651950a15f57f7b606a252f6dc1f01 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 28 Oct 2017 19:55:05 +0200 Subject: [PATCH 0076/1831] setup.py: remove doctest comments from long description (#197) --- setup.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/setup.py b/setup.py index 2aa9ba610..443924b03 100755 --- a/setup.py +++ b/setup.py @@ -22,6 +22,7 @@ import setuptools import sys import platform +import re def read_description(): @@ -46,6 +47,9 @@ def read_description(): "//travis-ci.org/niklasf/python-chess.svg?branch=master", "//travis-ci.org/niklasf/python-chess.svg?branch=v{0}".format(chess.__version__)) + # Remove doctest comments. + description = re.sub("\s*# doctest:.*", "", description) + return description From dc59e85508171e02edacc661817bf278ff01ceb5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 29 Oct 2017 00:07:34 +0200 Subject: [PATCH 0077/1831] use en dash for copyright footer (fixes #199) --- docs/conf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 6ec37ff79..9578f39d5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +from __future__ import unicode_literals + import sys import os @@ -19,7 +21,7 @@ # General information about the project. project = "python-chess" -copyright = "2014-2017, Niklas Fiekas" +copyright = "2014–2017, Niklas Fiekas" # The version. version = chess.__version__ From 08cfdfb54c24c4faaf097f5ae362e1b38382d442 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 29 Oct 2017 08:11:56 +0100 Subject: [PATCH 0078/1831] tweak project description (closes #201) --- README.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 83cf90cf7..dba8ced74 100644 --- a/README.rst +++ b/README.rst @@ -16,8 +16,9 @@ python-chess: a pure Python chess library Introduction ------------ -python-chess is a pure Python chess library with move generation and validation -and handling of common formats. This is the Scholar's mate in python-chess: +python-chess is a pure Python chess library with move generation, move +validation and support for common formats. This is the Scholar's mate in +python-chess: .. code:: python From 950319d532c21ad3378b4582582019e7ed8baabb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sun, 29 Oct 2017 08:45:28 +0100 Subject: [PATCH 0079/1831] grammar fixes for __init__.py (closes #202) --- chess/__init__.py | 128 +++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index f874c37aa..1ba4b3b65 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -58,10 +58,10 @@ RANK_NAMES = ["1", "2", "3", "4", "5", "6", "7", "8"] STARTING_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" -"""The FEN of the standard chess starting position.""" +"""The FEN for the standard chess starting position.""" STARTING_BOARD_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR" -"""The board part of the FEN of the standard chess starting position.""" +"""The board part of the FEN for the standard chess starting position.""" STATUS_VALID = 0 STATUS_NO_WHITE_KING = 1 @@ -104,12 +104,12 @@ def square_rank(square): return square >> 3 def square_name(square): - """Gets the name of the square, e.g. ``a3``.""" + """Gets the name of the square, like ``a3``.""" return FILE_NAMES[square_file(square)] + RANK_NAMES[square_rank(square)] def square_distance(a, b): """ - Gets the distance (i.e. the number of king steps) from square *a* to *b*. + Gets the distance (i.e., the number of king steps) from square *a* to *b*. """ return max(abs(square_file(a) - square_file(b)), abs(square_rank(a) - square_rank(b))) @@ -166,7 +166,7 @@ def square_mirror(square): try: - # Added in Python 2.7 and 3.1 respectively. + # Added in Python 2.7 and 3.1, respectively. int.bit_length except AttributeError: def _lsb_table(): @@ -366,7 +366,7 @@ def symbol(self): def unicode_symbol(self, invert_color=False): """ - Gets the unicode character for the piece. + Gets the Unicode character for the piece. """ if not invert_color: return UNICODE_PIECE_SYMBOLS[self.symbol()] @@ -404,7 +404,7 @@ def __ne__(self, other): @classmethod def from_symbol(cls, symbol): """ - Creates a piece instance from a piece symbol. + Creates a :class:`~chess.Piece` instance from a piece symbol. :raises: :exc:`ValueError` if the symbol is invalid. """ @@ -430,12 +430,12 @@ def __init__(self, from_square, to_square, promotion=None, drop=None): def uci(self): """ - Gets a UCI string for the move. + Gets an UCI string for the move. - For example a move from A7 to A8 would be ``a7a8`` or ``a7a8q`` if it - is a promotion to a queen. + For example, a move from a7 to a8 would be ``a7a8`` or ``a7a8q`` + (if the latter is a promotion to a queen). - The UCI representatin of null moves is ``0000``. + The UCI representation of a null move is ``0000``. """ if self.drop: return PIECE_SYMBOLS[self.drop].upper() + "@" + SQUARE_NAMES[self.to_square] @@ -490,7 +490,7 @@ def __deepcopy__(self, memo): @classmethod def from_uci(cls, uci): """ - Parses a UCI string. + Parses an UCI string. :raises: :exc:`ValueError` if the UCI string is invalid. """ @@ -530,9 +530,9 @@ class BaseBoard(object): A board representing the position of chess pieces. See :class:`~chess.Board` for a full board with move generation. - The board is initialized to the standard chess starting position, unless + The board is initialized with the standard chess starting position, unless otherwise specified in the optional *board_fen* argument. If *board_fen* - is ``None`` an empty board is created. + is ``None``, an empty board is created. """ def __init__(self, board_fen=STARTING_BOARD_FEN): @@ -636,7 +636,7 @@ def king(self, color): Finds the king square of the given side. Returns ``None`` if there is no king of that color. - In variants with king promotions only non-promoted kings are + In variants with king promotions, only non-promoted kings are considered. """ king_mask = self.occupied_co[color] & self.kings & ~self.promoted @@ -939,7 +939,7 @@ def chess960_pos(self): bs2 = lsb(x) * 2 cc_pos += bs2 - # Algorithm from ChessX src/database/bitboard.cpp r2254. + # Algorithm from ChessX, src/database/bitboard.cpp, r2254. q = 0 qf = False n0 = 0 @@ -1113,7 +1113,7 @@ def empty(cls): @classmethod def from_chess960_pos(cls, sharnagl): """ - Creates a new board, initialized to a Chess960 starting position. + Creates a new board, initialized with a Chess960 starting position. >>> import chess >>> import random @@ -1159,14 +1159,14 @@ class Board(BaseBoard): The board is initialized to the standard chess starting position, unless otherwise specified in the optional *fen* argument. - If *fen* is ``None`` an empty board is created. + If *fen* is ``None``, an empty board is created. Optionally supports *chess960*. In Chess960 castling moves are encoded by a king move to the corresponding rook square. Use :func:`chess.Board.from_chess960_pos()` to create a board with one of the Chess960 starting positions. - Its safe to set :data:`~Board.turn`, :data:`~Board.castling_rights`, + It's safe to set :data:`~Board.turn`, :data:`~Board.castling_rights`, :data:`~Board.ep_square`, :data:`~Board.halfmove_clock` and :data:`~Board.fullmove_number` directly. """ @@ -1522,7 +1522,7 @@ def is_pseudo_legal(self, move): if not self.occupied_co[self.turn] & from_mask: return False - # Only pawns can promote and only on the backrank. + # Only pawns can promote and only on the back rank. if move.promotion: if piece != PAWN: return False @@ -1555,7 +1555,7 @@ def is_variant_end(self): """ Checks if the game is over due to a special variant end condition. - Note for example that stalemate is not considered a variant-specific + Note, for example, that stalemate is not considered a variant-specific end condition (this method will return ``False``), yet it can have a special **result** in suicide chess (any of :func:`~chess.Board.is_variant_loss()`, @@ -1609,7 +1609,7 @@ def is_game_over(self, claim_draw=False): if self.is_fivefold_repetition(): return True - # Draw claim. + # Claim draw. if claim_draw and self.can_claim_draw(): return True @@ -1620,10 +1620,10 @@ def result(self, claim_draw=False): Gets the game result. ``1-0``, ``0-1`` or ``1/2-1/2`` if the - :func:`game is over `. Otherwise the result - is undetermined: ``*``. + :func:`game is over `. Otherwise, the + result is undetermined: ``*``. """ - # Chess variant support + # Chess variant support. if self.is_variant_loss(): return "0-1" if self.turn == WHITE else "1-0" elif self.is_variant_win(): @@ -1695,7 +1695,7 @@ def is_insufficient_material(self): def is_seventyfive_moves(self): """ - Since the first of July 2014 a game is automatically drawn (without + Since the 1st of July 2014, a game is automatically drawn (without a claim by one of the players) if the half-move clock since a capture or pawn move is equal to or grather than 150. Other means to end a game take precedence. @@ -1708,7 +1708,7 @@ def is_seventyfive_moves(self): def is_fivefold_repetition(self): """ - Since the first of July 2014 a game is automatically drawn (without + Since the 1st of July 2014 a game is automatically drawn (without a claim by one of the players) if a position occurs for the fifth time on consecutive alternating moves. """ @@ -1720,11 +1720,11 @@ def is_fivefold_repetition(self): switchyard = collections.deque() for _ in range(4): - # Go back two full moves, each. + # Go back two full moves each. for _ in range(4): switchyard.append(self.pop()) - # Check the position was the same before. + # Check if the position was the same as before. if self._transposition_key() != transposition_key: while switchyard: self.push(switchyard.pop()) @@ -1825,7 +1825,7 @@ def push(self, move): move = self._to_chess960(move) - # Reset ep square. + # Reset en passant square. ep_square = self.ep_square self.ep_square = None @@ -1834,7 +1834,7 @@ def push(self, move): if self.turn == BLACK: self.fullmove_number += 1 - # On a null move simply swap turns and reset the en passant square. + # On a null move, simply swap turns and reset the en passant square. if not move: self.turn = not self.turn return @@ -1904,7 +1904,7 @@ def push(self, move): self._set_piece_at(G1 if self.turn == WHITE else G8, KING, self.turn) self._set_piece_at(F1 if self.turn == WHITE else F8, ROOK, self.turn) - # Put piece on target square. + # Put the piece on the target square. if not castling and piece_type: was_promoted = self.promoted & to_bb self._set_piece_at(move.to_square, piece_type, self.turn, promoted) @@ -1998,7 +1998,7 @@ def castling_xfen(self): return "-" def has_pseudo_legal_en_passant(self): - """Checks if there is a pseudo legal en passant capture.""" + """Checks if there is a pseudo-legal en passant capture.""" return self.ep_square is not None and any(self.generate_pseudo_legal_ep()) def has_legal_en_passant(self): @@ -2009,7 +2009,7 @@ def fen(self, shredder=False, en_passant="legal", promoted=None): """ Gets a FEN representation of the position. - A FEN string (e.g. + A FEN string (e.g., ``rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1``) consists of the position part :func:`~chess.Board.board_fen()`, the :data:`~chess.Board.turn`, the castling part @@ -2022,13 +2022,13 @@ def fen(self, shredder=False, en_passant="legal", promoted=None): and encode castling rights by the file of the rook (like ``HAha``) instead of the default :func:`~chess.Board.castling_xfen()` (like ``KQkq``). - :param en_passant: By default only fully legal en passant squares + :param en_passant: By default, only fully legal en passant squares are included (:func:`~chess.Board.has_legal_en_passant()`). - Pass ``fen`` to strictly follow the FEN spec + Pass ``fen`` to strictly follow the FEN specification (always include the en passant square after a double pawn move) - or ``xfen`` to follow the X-FEN spec + or ``xfen`` to follow the X-FEN specification (:func:`~chess.Board.has_pseudo_legal_en_passant()`). - :param promoted: Mark promoted pieces like ``Q~``. By default this is + :param promoted: Mark promoted pieces like ``Q~``. By default, this is only enabled in chess variants where this is relevant. """ return " ".join([ @@ -2070,12 +2070,12 @@ def set_fen(self, fen): # Check that the half-move part is valid. if int(parts[4]) < 0: - raise ValueError("halfmove clock can not be negative: {0}".format(repr(fen))) + raise ValueError("half-move clock can not be negative: {0}".format(repr(fen))) - # Check that the fullmove number part is valid. - # 0 is allowed for compability but later replaced with 1. + # Check that the full-move number part is valid. + # 0 is allowed for compability, but later replaced with 1. if int(parts[5]) < 0: - raise ValueError("fullmove number must be positive: {0}".format(repr(fen))) + raise ValueError("full-move number must be positive: {0}".format(repr(fen))) # Validate the board part and set it. self._set_board_fen(parts[0]) @@ -2257,7 +2257,7 @@ def epd(self, shredder=False, en_passant="legal", promoted=None, **operations): *ep_square* and *promoted*). EPD operations can be given as keyword arguments. Supported operands - are strings, integers, floats and moves and lists of moves and None. + are strings, integers, floats, moves, lists of moves and ``None``. All other operands are converted to strings. A list of moves for *pv* will be interpreted as a variation. All other @@ -2381,8 +2381,8 @@ def set_epd(self, epd): """ Parses the given EPD string and uses it to set the position. - If present the ``hmvc`` and the ``fmvn`` are used to set the half-move - clock and the fullmove number. Otherwise ``0`` and ``1`` are used. + If present, ``hmvc`` and the ``fmvn`` are used to set the half-move + clock and the full-move number. Otherwise, ``0`` and ``1`` are used. Returns a dictionary of parsed operations. Values can be strings, integers, floats or move objects. @@ -2455,7 +2455,7 @@ def san(self, move): san = PIECE_SYMBOLS[piece].upper() # Get ambiguous move candidates. - # Relevant candidates: Not excatly the current move, + # Relevant candidates: not excatly the current move, # but to the same square. others = 0 from_mask = self.pieces_mask(piece, self.turn) @@ -2494,7 +2494,7 @@ def san(self, move): if move.promotion: san += "=" + PIECE_SYMBOLS[move.promotion].upper() - # Add check or checkmate suffix + # Add check or checkmate suffix. if is_checkmate: san += "#" elif is_check: @@ -2504,11 +2504,11 @@ def san(self, move): def variation_san(self, variation): """ - Given a sequence of moves, return a string representing the sequence - in standard algebraic notation (e.g. ``1. e4 e5 2. Nf3 Nc6`` or + Given a sequence of moves, returns a string representing the sequence + in standard algebraic notation (e.g., ``1. e4 e5 2. Nf3 Nc6`` or ``37...Bg6 38. fxg6``). - This board will not be modified as a result of calling this. + The board will not be modified as a result of calling this. :raises: :exc:`ValueError` if any moves in the sequence are illegal. """ @@ -2533,7 +2533,7 @@ def variation_san(self, variation): def parse_san(self, san): """ Uses the current position as the context to parse a move in standard - algebraic notation and return the corresponding move object. + algebraic notation and returns the corresponding move object. The returned move is guaranteed to be either legal or a null move. @@ -2614,7 +2614,7 @@ def uci(self, move, chess960=None): Gets the UCI notation of the move. *chess960* defaults to the mode of the board. Pass ``True`` to force - *Chess960* mode. + Chess960 mode. """ if chess960 is None: chess960 = self.chess960 @@ -2679,7 +2679,7 @@ def is_irreversible(self, move): """ Checks if the given pseudo-legal move is irreversible. - In standard chess pawn moves, captures and moves that destroy castling + In standard chess, pawn moves, captures and moves that destroy castling rights are irreversible. """ backrank = BB_RANK_1 if self.turn == WHITE else BB_RANK_8 @@ -2735,7 +2735,7 @@ def clean_castling_rights(self): return white_castling | black_castling else: - # The kings must be on the backrank. + # The kings must be on the back rank. white_king_mask = self.occupied_co[WHITE] & self.kings & BB_RANK_1 & ~self.promoted black_king_mask = self.occupied_co[BLACK] & self.kings & BB_RANK_8 & ~self.promoted if not white_king_mask: @@ -2844,7 +2844,7 @@ def status(self): :data:`~chess.STATUS_VALID` for a completely valid board. - Otherwise bitwise combinations of: + Otherwise, bitwise combinations of: :data:`~chess.STATUS_NO_WHITE_KING`, :data:`~chess.STATUS_NO_BLACK_KING`, :data:`~chess.STATUS_TOO_MANY_KINGS`, @@ -2881,13 +2881,13 @@ def status(self): if popcount(self.occupied_co[BLACK]) > 16: errors |= STATUS_TOO_MANY_BLACK_PIECES - # There can not be more than eight pawns of any color. + # There can not be more than 8 pawns of any color. if popcount(self.occupied_co[WHITE] & self.pawns) > 8: errors |= STATUS_TOO_MANY_WHITE_PAWNS if popcount(self.occupied_co[BLACK] & self.pawns) > 8: errors |= STATUS_TOO_MANY_BLACK_PAWNS - # Pawns can not be on the backrank. + # Pawns can not be on the back rank. if self.pawns & BB_BACKRANKS: errors |= STATUS_PAWNS_ON_BACKRANK @@ -2947,7 +2947,7 @@ def is_valid(self): return self.status() == STATUS_VALID def _ep_skewered(self, king, capturer): - # Handle the special case where the king would be in check, if the + # Handle the special case where the king would be in check if the # pawn and its capturer disappear from the rank. # Vertical skewers of the captured pawn are not possible. (Pins on @@ -2985,7 +2985,7 @@ def _slider_blockers(self, king): for sniper in scan_reversed(snipers & self.occupied_co[not self.turn]): b = BB_BETWEEN[king][sniper] & self.occupied - # Add to blockers if exactly one piece in between. + # Add to blockers if exactly one piece in-between. if b and BB_SQUARES[msb(b)] == b: blockers |= b @@ -3251,7 +3251,7 @@ def __repr__(self): sans = ", ".join(builder) - return "".format(hex(id(self)), sans) + return "".format(hex(id(self)), sans) class LegalMoveGenerator(object): @@ -3332,7 +3332,7 @@ class SquareSet(object): >>> list(squares) [0, 1, 2, 3, 4, 5, 6, 7, 56] - Square sets are internally represented by 64 bit integer masks of the + Square sets are internally represented by 64-bit integer masks of the included squares. Bitwise operations can be used to compute unions, intersections and shifts. @@ -3389,12 +3389,12 @@ def copy(self): return type(self)(self.mask) def add(self, square): - """Add a square to the set.""" + """Adds a square to the set.""" self.mask |= BB_SQUARES[square] def remove(self, square): """ - Remove a square from the set. + Removes a square from the set. :raises: :exc:`KeyError` if the given square was not in the set. """ @@ -3551,7 +3551,7 @@ def _repr_svg_(self): @classmethod def from_square(cls, square): """ - Creates a SquareSet from a single square. + Creates a :class:`~chess.SquareSet` from a single square. >>> import chess >>> From ef71e7471c733f477db9548bff8623d30e53f68f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 29 Oct 2017 09:04:40 +0100 Subject: [PATCH 0080/1831] fix typo: excatly -> exactly --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 1ba4b3b65..ff4620500 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2455,7 +2455,7 @@ def san(self, move): san = PIECE_SYMBOLS[piece].upper() # Get ambiguous move candidates. - # Relevant candidates: not excatly the current move, + # Relevant candidates: not exactly the current move, # but to the same square. others = 0 from_mask = self.pieces_mask(piece, self.turn) From 6a81a0731e050f3fe29befedfbd6ab51f8ce6a48 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 29 Oct 2017 09:12:06 +0100 Subject: [PATCH 0081/1831] fixup set_epd docs --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index ff4620500..06f640a9a 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2381,7 +2381,7 @@ def set_epd(self, epd): """ Parses the given EPD string and uses it to set the position. - If present, ``hmvc`` and the ``fmvn`` are used to set the half-move + If present, ``hmvc`` and ``fmvn`` are used to set the half-move clock and the full-move number. Otherwise, ``0`` and ``1`` are used. Returns a dictionary of parsed operations. Values can be strings, From f7f2fba8357f284b6f9bcb12991d1738131098da Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 30 Oct 2017 08:46:43 +0100 Subject: [PATCH 0082/1831] minor comment tweaks (closes #203) --- chess/engine.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index f7cd5e712..a0d96aac9 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -305,14 +305,14 @@ def _popen_engine(command, engine_cls, setpgrp=False, _popen_lock=threading.Lock popen_args = {} if setpgrp: try: - # Windows + # Windows. popen_args["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP except AttributeError: - # Unix + # Unix. popen_args["preexec_fn"] = os.setpgrp popen_args.update(kwargs) - # Work around possible race condition in Python 2 subprocess module, + # Work around a possible race condition in Python 2 subprocess module # that can occur when concurrently opening processes. with _popen_lock: PopenProcess(engine, command, **popen_args) From 719c1c954b6d11b8a47bb21eb54eed4a5082cacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Mon, 30 Oct 2017 13:45:47 +0100 Subject: [PATCH 0083/1831] Update pgn.rst I had to fix this as well. --- docs/pgn.rst | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/pgn.rst b/docs/pgn.rst index 9b027232c..9a62e75e4 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -9,8 +9,8 @@ Parsing Writing ------- -If you want to export your game game with all headers, comments and variations -you can use: +If you want to export your game with all headers, comments and variations, +you can do it like this: >>> import chess >>> import chess.pgn @@ -42,17 +42,17 @@ Use the :class:`~chess.pgn.StringExporter()` or Game model ---------- -Games are represented as a tree of moves. Each `GameNode` can have extra -information such as comments. The root node of a game -(`Game` extends `GameNode`) also holds general information, such as game -headers. +Games are represented as a tree of moves. Each :class:`~chess.pgn.GameNode` can have extra +information, such as comments. The root node of a game +(the :class:`~chess.pgn.Game` class extends the :chess:`~chess.pgn.GameNode` class) also +holds general information, such as game headers. .. autoclass:: chess.pgn.Game :members: .. py:attribute:: headers - A :class:`collections.OrderedDict()` of game headers. By default the + A :class:`collections.OrderedDict` class of game headers. By default, the following 7 headers are provided: >>> import chess.pgn @@ -76,7 +76,7 @@ headers. .. py:attribute:: errors A list of illegal or ambiguous move errors encountered while parsing - the game. + a game. .. autoclass:: chess.pgn.GameNode :members: @@ -106,8 +106,9 @@ headers. :annotation: = '' A comment for the start of a variation. Only nodes that - actually start a variation (`starts_variation()`) can have a starting - comment. The root node can not have a starting comment. + actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` + checks this) can have a starting comment. The root node can not have + a starting comment. .. py:attribute:: variations @@ -116,7 +117,7 @@ headers. Visitors -------- -Visitors are an advanced concept for game tree traversal. +Visitors are an advanced concept for game-tree traversal. .. autoclass:: chess.pgn.BaseVisitor :members: @@ -137,7 +138,7 @@ NAGs Numeric anotation glyphs describe moves and positions using standardized codes that are understood by many chess programs. During PGN parsing, annotations -like ``!``, ``?``, ``!!``, etc. are also converted to NAGs. +like ``!``, ``?``, ``!!``, etc., are also converted to NAGs. .. autodata:: chess.pgn.NAG_GOOD_MOVE .. autodata:: chess.pgn.NAG_MISTAKE @@ -149,7 +150,7 @@ like ``!``, ``?``, ``!!``, etc. are also converted to NAGs. Skimming -------- -These functions allow quickly skimming games without fully parsing them. +These functions allow for quickly skimming games without fully parsing them. .. autofunction:: chess.pgn.scan_headers From a197b5f10b340ea1975dbd7ce716a13ffd1139ef Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 30 Oct 2017 16:06:45 +0100 Subject: [PATCH 0084/1831] fixup pgn.rst (#205) --- docs/pgn.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/pgn.rst b/docs/pgn.rst index 9a62e75e4..70a5f44eb 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -44,7 +44,7 @@ Game model Games are represented as a tree of moves. Each :class:`~chess.pgn.GameNode` can have extra information, such as comments. The root node of a game -(the :class:`~chess.pgn.Game` class extends the :chess:`~chess.pgn.GameNode` class) also +(:class:`~chess.pgn.Game` extends the :chess:`~chess.pgn.GameNode`) also holds general information, such as game headers. .. autoclass:: chess.pgn.Game @@ -52,7 +52,7 @@ holds general information, such as game headers. .. py:attribute:: headers - A :class:`collections.OrderedDict` class of game headers. By default, the + A :class:`collections.OrderedDict` of game headers. By default, the following 7 headers are provided: >>> import chess.pgn @@ -76,7 +76,7 @@ holds general information, such as game headers. .. py:attribute:: errors A list of illegal or ambiguous move errors encountered while parsing - a game. + the game. .. autoclass:: chess.pgn.GameNode :members: @@ -117,7 +117,7 @@ holds general information, such as game headers. Visitors -------- -Visitors are an advanced concept for game-tree traversal. +Visitors are an advanced concept for game tree traversal. .. autoclass:: chess.pgn.BaseVisitor :members: From e86b63fecebbe2b55148a9d5ae25bb4f7496f8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Mon, 30 Oct 2017 16:26:17 +0100 Subject: [PATCH 0085/1831] grammar and doc fixes for pgn.py (closes #204) --- chess/pgn.py | 82 +++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index ddb81bf00..5925d7ce9 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -30,7 +30,7 @@ LOGGER = logging.getLogger(__name__) -# Reference of Numeric Annotation Glyphs: +# Reference of Numeric Annotation Glyphs (NAGs): # https://en.wikipedia.org/wiki/Numeric_Annotation_Glyphs NAG_NULL = 0 @@ -201,7 +201,7 @@ def is_main_line(self): def is_main_variation(self): """ Checks if this node is the first variation from the point of view of its - parent. The root node also is in the main variation. + parent. The root node is also in the main variation. """ if not self.parent: return True @@ -210,7 +210,7 @@ def is_main_variation(self): def variation(self, move): """ - Gets a child node by move or index. + Gets a child node by either the move or the variation index. """ for index, variation in enumerate(self.variations): if move == variation.move or index == move or move == variation: @@ -219,31 +219,31 @@ def variation(self, move): raise KeyError("variation not found") def has_variation(self, move): - """Checks if the given move appears as a variation.""" + """Checks if the given *move* appears as a variation.""" return move in (variation.move for variation in self.variations) def promote_to_main(self, move): - """Promotes the given move to the main variation.""" + """Promotes the given *move* to the main variation.""" variation = self.variation(move) self.variations.remove(variation) self.variations.insert(0, variation) def promote(self, move): - """Moves the given variation one up in the list of variations.""" + """Moves a variation one up in the list of variations.""" variation = self.variation(move) i = self.variations.index(variation) if i > 0: self.variations[i - 1], self.variations[i] = self.variations[i], self.variations[i - 1] def demote(self, move): - """Moves the given variation one down in the list of variations.""" + """Moves a variation one down in the list of variations.""" variation = self.variation(move) i = self.variations.index(variation) if i < len(self.variations) - 1: self.variations[i + 1], self.variations[i] = self.variations[i], self.variations[i + 1] def remove_variation(self, move): - """Removes a variation by move.""" + """Removes a variation.""" self.variations.remove(self.variation(move)) def add_variation(self, move, comment="", starting_comment="", nags=()): @@ -303,7 +303,7 @@ def accept(self, visitor, _board=None): """ board = self.board() if _board is None else _board - # The mainline move goes first. + # The first move of the main line goes first. if self.variations: main_variation = self.variations[0] visitor.visit_move(board, main_variation.move) @@ -316,7 +316,7 @@ def accept(self, visitor, _board=None): if main_variation.comment: visitor.visit_comment(main_variation.comment) - # Then visit sidelines. + # Then visit side lines. for variation in itertools.islice(self.variations, 1, None): # Start variation. visitor.begin_variation() @@ -344,7 +344,7 @@ def accept(self, visitor, _board=None): # End variation. visitor.end_variation() - # The mainline is continued last. + # The main line is continued last. if self.variations: main_variation = self.variations[0] @@ -386,12 +386,12 @@ def board(self, _cache=False): """ Gets the starting position of the game. - Unless the ``FEN`` header tag is set this is the default starting + Unless the ``FEN`` header tag is set, this is the default starting position (for the ``Variant``). """ chess960 = self.headers.get("Variant", "").lower() in [ "chess960", - "fischerandom", # Cutechess + "fischerandom", # Cute Chess "fischerrandom"] if chess960 or "Variant" not in self.headers: @@ -461,7 +461,7 @@ def from_board(cls, board): while board.move_stack: switchyard.append(board.pop()) - # Setup initial position. + # Setup the initial position. game = cls() game.setup(board) node = game @@ -483,7 +483,7 @@ class BaseVisitor(object): Use with :func:`chess.pgn.Game.accept()` or :func:`chess.pgn.GameNode.accept()`. - Methods are called in PGN order. + The methods are called in PGN order. """ def begin_game(self): @@ -491,7 +491,7 @@ def begin_game(self): pass def begin_headers(self): - """Called at the start of the game headers.""" + """Called at the start of game headers.""" pass def visit_header(self, tagname, tagvalue): @@ -522,7 +522,7 @@ def visit_nag(self, nag): def begin_variation(self): """ Called at the start of a new variation. It is not called for the - mainline of the game. + main line of the game. """ pass @@ -531,7 +531,9 @@ def end_variation(self): pass def visit_result(self, result): - """Called at the end of the game with the *Result*-header.""" + """ + Called at the end of a game with the value from the *Result*-header. + """ pass def end_game(self): @@ -543,7 +545,7 @@ def result(self): return True def handle_error(self, error): - """Called for errors encountered. Defaults to raising an exception.""" + """Called for encountered errors. Defaults to raising an exception.""" raise error @@ -579,12 +581,12 @@ def visit_result(self, result): def visit_comment(self, comment): if self.in_variation or (self.variation_stack[-1].parent is None and self.variation_stack[-1].is_end()): # Add as a comment for the current node if in the middle of - # a variation. Add as a comment for the game, if the comment + # a variation. Add as a comment for the game if the comment # starts before any move. new_comment = [self.variation_stack[-1].comment, comment] self.variation_stack[-1].comment = "\n".join(new_comment).strip() else: - # Otherwise it is a starting comment. + # Otherwise, it is a starting comment. new_comment = [self.starting_comment, comment] self.starting_comment = "\n".join(new_comment).strip() @@ -624,7 +626,7 @@ class StringExporter(BaseVisitor): then the entire movetext will be on a single line. This does not affect header tags and comments. - There will be no newlines at the end of the string. + There will be no newline characters at the end of the string. """ def __init__(self, columns=80, headers=True, comments=True, variations=True): @@ -715,8 +717,8 @@ def __str__(self): class FileExporter(StringExporter): """ - Like a :class:`~chess.pgn.StringExporter`, but games are written directly - to a text file. + Acts like a :class:`~chess.pgn.StringExporter`, but games are written + directly into a text file. There will always be a blank line after each game. Handling encodings is up to the caller. @@ -777,9 +779,9 @@ def read_game(handle, Visitor=GameModelCreator): >>> board Board('4r3/6P1/2p2P1k/1p6/pP2p1R1/P1B5/2P2K2/3r4 b - - 0 45') - By using text mode the parser does not need to handle encodings. It is the - callers responsibility to open the file with the correct encoding. - PGN files are ASCII or UTF-8 most of the time. So the following should + By using text mode, the parser does not need to handle encodings. It is the + caller's responsibility to open the file with the correct encoding. + PGN files are ASCII or UTF-8 most of the time. So, the following should cover most relevant cases (ASCII, UTF-8, UTF-8 with BOM). >>> # Python 3 @@ -798,16 +800,16 @@ def read_game(handle, Visitor=GameModelCreator): >>> game = chess.pgn.read_game(pgn) The end of a game is determined by a completely blank line or the end of - the file. (Of course blank lines in comments are possible.) + the file. (Of course, blank lines in comments are possible.) - According to the standard at least the usual 7 header tags are required - for a valid game. This parser also handles games without any headers just - fine. + According to the PGN standard, at least the usual 7 header tags are + required for a valid game. This parser also handles games without any + headers just fine. The parser is relatively forgiving when it comes to errors. It skips over tokens it can not parse. Any exceptions are logged. - Returns the parsed game or ``None`` if the EOF is reached. + Returns the parsed game or ``None`` if the end of file is reached. """ visitor = Visitor() @@ -862,7 +864,7 @@ def read_game(handle, Visitor=GameModelCreator): line = handle.readline() continue - # An empty line is the end of a game. + # An empty line means the end of a game. if found_content and line.isspace(): if found_game: visitor.end_game() @@ -964,12 +966,12 @@ def scan_headers(handle): """ Scan a PGN file opened in text mode for game offsets and headers. - Yields a tuple for each game. The first element is the offset. The second - element is an ordered dictionary of game headers. + Yields a tuple for each game. The first element is the offset and the + second element is an ordered dictionary of game headers. Since actually parsing many games from a big file is relatively expensive, - this is a better way to look only for specific games and seek and parse - them later. + this is a better way to look only for specific games and then seek and + parse them later. This example scans for the first game with Kasparov as the white player. @@ -1008,7 +1010,7 @@ def scan_headers(handle): line = handle.readline() while line: - # Skip single line comments. + # Skip single-line comments. if line.startswith("%"): last_pos = handle.tell() line = handle.readline() @@ -1036,12 +1038,12 @@ def scan_headers(handle): line = handle.readline() continue - # Reading movetext. Update parser state in_comment in order to skip + # Reading movetext. Update parser's in_comment state in order to skip # comments that look like header tags. if (not in_comment and "{" in line) or (in_comment and "}" in line): in_comment = line.rfind("{") > line.rfind("}") - # Reading movetext. If there were headers, previously, those are now + # Reading movetext. If there were headers previously, those are now # complete and can be yielded. if game_pos is not None: yield game_pos, game_headers From 79ef694472f18c08cecc3053cb669710eb0540ef Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 31 Oct 2017 02:07:48 +0100 Subject: [PATCH 0086/1831] minor doc tweak (#204) --- chess/pgn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 5925d7ce9..9c2b365b3 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -532,7 +532,7 @@ def end_variation(self): def visit_result(self, result): """ - Called at the end of a game with the value from the *Result*-header. + Called at the end of a game with the value from the ``Result`` header. """ pass From 55fc4c023c5dbc5bf787241215c62b719399595d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Wed, 1 Nov 2017 10:33:31 +0100 Subject: [PATCH 0087/1831] Update README.rst mainline --> main line --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index dba8ced74..171a1235f 100644 --- a/README.rst +++ b/README.rst @@ -240,12 +240,12 @@ Features >>> first_game.headers["Black"] 'Bordais' - >>> # Get the mainline as a list of moves. + >>> # Get the main line as a list of moves. >>> moves = first_game.main_line() >>> first_game.board().variation_san(moves) '1. e4 c5 2. c4 Nc6 3. Ne2 Nf6 4. Nbc3 Nb4 5. g3 Nd3#' - >>> # Iterate through the mainline of this embarrassingly short game. + >>> # Iterate through the main line of this embarrassingly short game. >>> node = first_game >>> while not node.is_end(): ... next_node = node.variations[0] From 1e78a1f7baab322bd040d63a831a4127d2f2f90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Wed, 1 Nov 2017 12:33:09 +0100 Subject: [PATCH 0088/1831] Update README.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a comment. The in-line comments don’t end with the dot, so I removed it, also added the missing “a” word. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 171a1235f..31c82faed 100644 --- a/README.rst +++ b/README.rst @@ -300,7 +300,7 @@ Features >>> # Synchronous mode. >>> board = chess.Board("1k1r4/pp1b1R2/3q2pp/4p3/2B5/4Q3/PPP2B2/2K5 b - - 0 1") >>> engine.position(board) - >>> engine.go(movetime=2000) # Gets tuple of bestmove and ponder move. + >>> engine.go(movetime=2000) # Gets a tuple of bestmove and ponder move BestMove(bestmove=Move.from_uci('d6d1'), ponder=Move.from_uci('c1d1')) >>> # Asynchronous mode. From aeeebe329885045cdb6ea9bc520515c4471d5778 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 31 Oct 2017 11:27:55 +0100 Subject: [PATCH 0089/1831] olympuschess.com no longer hosting Gaviota tables --- data/gaviota/SOURCE.txt | 290 ++++++++++++++++++++-------------------- 1 file changed, 145 insertions(+), 145 deletions(-) diff --git a/data/gaviota/SOURCE.txt b/data/gaviota/SOURCE.txt index 732ec0a1c..dda9c83c7 100644 --- a/data/gaviota/SOURCE.txt +++ b/data/gaviota/SOURCE.txt @@ -1,145 +1,145 @@ -http://www.olympuschess.com/egtb/gaviota/kbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kpkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kppk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbbpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbnkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbnkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbnkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbnkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbnkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbnnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbnpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbpkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbpkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbpkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbpkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbpkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kbppk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knnkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knnkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knnkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knnkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knnkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knnnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knnpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knpkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knpkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knpkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knpkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knpkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/knppk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kppkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kppkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kppkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kppkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kppkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kpppk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqbpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqnkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqnkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqnkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqnkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqnkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqnnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqnpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqpkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqpkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqpkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqpkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqpkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqppk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqqk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqqrk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/kqrrk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krbpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krnkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krnkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krnkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krnkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krnkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krnnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krnpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krpkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krpkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krpkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krpkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krpkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krppk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrbk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrkb.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrkn.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrkp.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrkq.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrkr.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrnk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrpk.gtb.cp4 -http://www.olympuschess.com/egtb/gaviota/krrrk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbk.gtb.cp4 +https://syzygy-tables.info/gaviota/knk.gtb.cp4 +https://syzygy-tables.info/gaviota/kpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqk.gtb.cp4 +https://syzygy-tables.info/gaviota/krk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kbkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kbkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kbnk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbpk.gtb.cp4 +https://syzygy-tables.info/gaviota/knkn.gtb.cp4 +https://syzygy-tables.info/gaviota/knkp.gtb.cp4 +https://syzygy-tables.info/gaviota/knnk.gtb.cp4 +https://syzygy-tables.info/gaviota/knpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kpkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kppk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kqkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kqkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kqkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kqkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kqnk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrk.gtb.cp4 +https://syzygy-tables.info/gaviota/krbk.gtb.cp4 +https://syzygy-tables.info/gaviota/krkb.gtb.cp4 +https://syzygy-tables.info/gaviota/krkn.gtb.cp4 +https://syzygy-tables.info/gaviota/krkp.gtb.cp4 +https://syzygy-tables.info/gaviota/krkr.gtb.cp4 +https://syzygy-tables.info/gaviota/krnk.gtb.cp4 +https://syzygy-tables.info/gaviota/krpk.gtb.cp4 +https://syzygy-tables.info/gaviota/krrk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbbk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbnk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbbpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbnkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kbnkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kbnkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kbnkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kbnkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kbnnk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbnpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kbpkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kbpkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kbpkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kbpkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kbpkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kbppk.gtb.cp4 +https://syzygy-tables.info/gaviota/knnkb.gtb.cp4 +https://syzygy-tables.info/gaviota/knnkn.gtb.cp4 +https://syzygy-tables.info/gaviota/knnkp.gtb.cp4 +https://syzygy-tables.info/gaviota/knnkq.gtb.cp4 +https://syzygy-tables.info/gaviota/knnkr.gtb.cp4 +https://syzygy-tables.info/gaviota/knnnk.gtb.cp4 +https://syzygy-tables.info/gaviota/knnpk.gtb.cp4 +https://syzygy-tables.info/gaviota/knpkb.gtb.cp4 +https://syzygy-tables.info/gaviota/knpkn.gtb.cp4 +https://syzygy-tables.info/gaviota/knpkp.gtb.cp4 +https://syzygy-tables.info/gaviota/knpkq.gtb.cp4 +https://syzygy-tables.info/gaviota/knpkr.gtb.cp4 +https://syzygy-tables.info/gaviota/knppk.gtb.cp4 +https://syzygy-tables.info/gaviota/kppkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kppkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kppkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kppkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kppkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kpppk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbbk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbnk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqbpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqnkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kqnkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kqnkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kqnkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kqnkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kqnnk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqnpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqpkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kqpkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kqpkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kqpkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kqpkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kqppk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqbk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqnk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqqk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqqrk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrbk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrkb.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrkn.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrkp.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrkq.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrkr.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrnk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrpk.gtb.cp4 +https://syzygy-tables.info/gaviota/kqrrk.gtb.cp4 +https://syzygy-tables.info/gaviota/krbbk.gtb.cp4 +https://syzygy-tables.info/gaviota/krbkb.gtb.cp4 +https://syzygy-tables.info/gaviota/krbkn.gtb.cp4 +https://syzygy-tables.info/gaviota/krbkp.gtb.cp4 +https://syzygy-tables.info/gaviota/krbkq.gtb.cp4 +https://syzygy-tables.info/gaviota/krbkr.gtb.cp4 +https://syzygy-tables.info/gaviota/krbnk.gtb.cp4 +https://syzygy-tables.info/gaviota/krbpk.gtb.cp4 +https://syzygy-tables.info/gaviota/krnkb.gtb.cp4 +https://syzygy-tables.info/gaviota/krnkn.gtb.cp4 +https://syzygy-tables.info/gaviota/krnkp.gtb.cp4 +https://syzygy-tables.info/gaviota/krnkq.gtb.cp4 +https://syzygy-tables.info/gaviota/krnkr.gtb.cp4 +https://syzygy-tables.info/gaviota/krnnk.gtb.cp4 +https://syzygy-tables.info/gaviota/krnpk.gtb.cp4 +https://syzygy-tables.info/gaviota/krpkb.gtb.cp4 +https://syzygy-tables.info/gaviota/krpkn.gtb.cp4 +https://syzygy-tables.info/gaviota/krpkp.gtb.cp4 +https://syzygy-tables.info/gaviota/krpkq.gtb.cp4 +https://syzygy-tables.info/gaviota/krpkr.gtb.cp4 +https://syzygy-tables.info/gaviota/krppk.gtb.cp4 +https://syzygy-tables.info/gaviota/krrbk.gtb.cp4 +https://syzygy-tables.info/gaviota/krrkb.gtb.cp4 +https://syzygy-tables.info/gaviota/krrkn.gtb.cp4 +https://syzygy-tables.info/gaviota/krrkp.gtb.cp4 +https://syzygy-tables.info/gaviota/krrkq.gtb.cp4 +https://syzygy-tables.info/gaviota/krrkr.gtb.cp4 +https://syzygy-tables.info/gaviota/krrnk.gtb.cp4 +https://syzygy-tables.info/gaviota/krrpk.gtb.cp4 +https://syzygy-tables.info/gaviota/krrrk.gtb.cp4 From 62d77f9a80af5ff7e8c763ba232079d7a3e839b8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 31 Oct 2017 12:29:07 +0100 Subject: [PATCH 0090/1831] fix typo in pgn.rst --- docs/pgn.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pgn.rst b/docs/pgn.rst index 70a5f44eb..aad2a948a 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -44,7 +44,7 @@ Game model Games are represented as a tree of moves. Each :class:`~chess.pgn.GameNode` can have extra information, such as comments. The root node of a game -(:class:`~chess.pgn.Game` extends the :chess:`~chess.pgn.GameNode`) also +(:class:`~chess.pgn.Game` extends the :class:`~chess.pgn.GameNode`) also holds general information, such as game headers. .. autoclass:: chess.pgn.Game From 94dd2bdc71dbb51401c65193dad79d709edd08e2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 2 Nov 2017 01:25:58 +0100 Subject: [PATCH 0091/1831] fix dtz ranges in syzygy docs --- chess/syzygy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 2ab28769b..6c6040776 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1812,7 +1812,7 @@ def probe_dtz(self, board): +-----+------------------+--------------------------------------------+ | WDL | DTZ | | +=====+==================+============================================+ - | -2 | -100 <= n < -1 | Unconditional loss (assuming 50-move | + | -2 | -100 <= n <= -1 | Unconditional loss (assuming 50-move | | | | counter is zero), where a zeroing move can | | | | be forced in -n plies. | +-----+------------------+--------------------------------------------+ @@ -1828,7 +1828,7 @@ def probe_dtz(self, board): | | | n - 100 plies (if a later phase is | | | | responsible for the cursed win). | +-----+------------------+--------------------------------------------+ - | 2 | 1 < n <= 100 | Unconditional win (assuming 50-move | + | 2 | 1 <= n <= 100 | Unconditional win (assuming 50-move | | | | counter is zero), where a zeroing move can | | | | be forced in n plies. | +-----+------------------+--------------------------------------------+ From 9ca205b93fa10f0225a7838be7e1c924750bdb04 Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Fri, 3 Nov 2017 13:00:22 +0530 Subject: [PATCH 0092/1831] Code simplification and fixed bug in level command string building --- chess/xboard.py | 157 ++++++++++++------------------------------------ 1 file changed, 37 insertions(+), 120 deletions(-) diff --git a/chess/xboard.py b/chess/xboard.py index d6faf9e27..f46766c3a 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -409,6 +409,15 @@ def _assert_not_busy(self, cmd): if not self.idle: raise EngineStateException("{} command while engine is busy", cmd) + def command(self, msg): + def cmd(): + with self.semaphore: + self.send_line(msg) + + if self.terminated.is_set(): + raise EngineTerminatedException + return cmd + def ping(self, async_callback=None): """ Command used to synchronize with the engine. @@ -439,16 +448,12 @@ def pondering(self, ponder, async_callback=None): :return: Nothing """ - def command(): - with self.semaphore: - if ponder: - self.send_line("hard") - else: - self.send_line("easy") - - if self.terminated.is_set(): - raise EngineTerminatedException() + if ponder: + msg = "hard" + else: + msg = "easy" + command = self.command(msg) return self._queue_command(command, async_callback) def easy(self, async_callback=None): @@ -472,16 +477,12 @@ def set_post(self, flag, async_callback=None): :return: Nothing """ - def command(): - with self.semaphore: - if flag == True: - self.send_line("post") - else: - self.send_line("nopost") - - if self.terminated.is_set(): - raise EngineTerminatedException() + if flag: + msg = "post" + else: + msg = "nopost" + command = self.command(msg) return self._queue_command(command, async_callback) def post(self, async_callback=None): @@ -519,6 +520,7 @@ def command(): if self.terminated.is_set(): raise EngineTerminatedException() + # TODO: Remove perhaps? self.post() self.easy() self.ping() @@ -575,14 +577,7 @@ def new(self, async_callback=None): :return: Nothing """ self._assert_not_busy("new") - - def command(): - with self.semaphore: - self.send_line("new") - - if self.terminated.is_set(): - raise EngineTerminatedException() - + command = self.command("new") return self._queue_command(command, async_callback) def setboard(self, board, async_callback=None): @@ -607,13 +602,7 @@ def setboard(self, board, async_callback=None): self.board = board.copy(stack=False) - def command(): - with self.semaphore: - self.send_line(" ".join(builder)) - - if self.terminated.is_set(): - raise EngineTerminatedException() - + command = self.command(" ".join(builder)) return self._queue_command(command, async_callback) def memory(self, amount, async_callback=None): @@ -627,13 +616,7 @@ def memory(self, amount, async_callback=None): self._assert_supports_feature("memory") self._assert_not_busy("memory") - def command(): - with self.semaphore: - self.send_line("memory " + str(amount)) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("memory " + str(amount)) return self._queue_command(command, async_callback) def cores(self, num, async_callback=None): @@ -648,13 +631,7 @@ def cores(self, num, async_callback=None): self._assert_supports_feature("smp") self._assert_not_busy("cores") - def command(): - with self.semaphore: - self.send_line("cores " + str(num)) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("cores " + str(num)) return self._queue_command(command, async_callback) def playother(self, async_callback=None): @@ -667,13 +644,7 @@ def playother(self, async_callback=None): self._assert_not_busy("playother") self.in_force = False - def command(): - with self.semaphore: - self.send_line("playother") - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("playother") return self._queue_command(command, async_callback) def set_side_to_move(self, color, async_callback=None): @@ -689,13 +660,7 @@ def set_side_to_move(self, color, async_callback=None): self._assert_not_busy(chess.COLOR_NAMES[color]) self.in_force = False - def command(): - with self.semaphore: - self.send_line(side) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command(side) return self._queue_command(command, async_callback) def white(self, async_callback=None): @@ -728,13 +693,7 @@ def random(self, async_callback=None): """ self._assert_not_busy("random") - def command(): - with self.semaphore: - self.send_line("random") - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("random") return self._queue_command(command, async_callback) def nps(self, target_nps, async_callback=None): @@ -749,13 +708,7 @@ def nps(self, target_nps, async_callback=None): self._assert_supports_feature("nps") self._assert_not_busy("nps") - def command(): - with self.semaphore: - self.send_line("nps " + str(target_nps)) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("nps " + str(target_nps)) return self._queue_command(command, async_callback) def st(self, time, async_callback=None): @@ -768,13 +721,7 @@ def st(self, time, async_callback=None): """ self._assert_not_busy("st") - def command(): - with self.semaphore: - self.send_line("st " + str(time)) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("st " + str(time)) return self._queue_command(command, async_callback) def sd(self, depth, async_callback=None): @@ -787,13 +734,7 @@ def sd(self, depth, async_callback=None): """ self._assert_not_busy("sd") - def command(): - with self.semaphore: - self.send_line("sd " + str(depth)) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("sd " + str(depth)) return self._queue_command(command, async_callback) def time(self, time, async_callback=None): @@ -807,13 +748,7 @@ def time(self, time, async_callback=None): self._assert_supports_feature("time") self._assert_not_busy("time") - def command(): - with self.semaphore: - self.send_line("time " + str(time)) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("time " + str(time)) return self._queue_command(command, async_callback) def otim(self, time, async_callback=None): @@ -827,13 +762,7 @@ def otim(self, time, async_callback=None): self._assert_supports_feature("time") self._assert_not_busy("otim") - def command(): - with self.semaphore: - self.send_line("otim " + str(time)) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("otim " + str(time)) return self._queue_command(command, async_callback) def level(self, movestogo=0, minutes=5, seconds=None, inc=0, async_callback=None): @@ -860,21 +789,15 @@ def level(self, movestogo=0, minutes=5, seconds=None, inc=0, async_callback=None builder = [] builder.append("level") builder.append(str(int(movestogo))) - builder.append(str(int(minutes))) if seconds is not None: - builder.append(":") - builder.append(str(int(seconds))) + builder.append(str(int(minutes)) + ":" + str(int(seconds))) + else: + builder.append(str(int(minutes))) builder.append(str(int(inc))) - def command(): - with self.semaphore: - self.send_line(" ".join(builder)) - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command(" ".join(builder)) return self._queue_command(command, async_callback) def set_auto_force(self, flag): @@ -898,13 +821,7 @@ def force(self, async_callback=None): :return: Nothing """ self.in_force = True - def command(): - with self.semaphore: - self.send_line("force") - - if self.terminated.is_set(): - raise EngineTerminatedException - + command = self.command("force") return self._queue_command(command, async_callback) def go(self, async_callback=None): From c9a7cf3c4c8336d7fbda8ce2a4296781432efd28 Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Fri, 3 Nov 2017 18:02:03 +0530 Subject: [PATCH 0093/1831] Fixed a bunch of errors and warnings from pylint --- chess/xboard.py | 116 +++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/chess/xboard.py b/chess/xboard.py index f46766c3a..591cfc50e 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -18,11 +18,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import concurrent.futures +import threading +import random + from chess.engine import EngineTerminatedException from chess.engine import EngineStateException -from chess.engine import MockProcess -from chess.engine import PopenProcess -from chess.engine import SpurProcess from chess.engine import Option from chess.engine import OptionMap from chess.engine import LOGGER @@ -32,15 +33,6 @@ import chess -import concurrent.futures -import threading -import random - -try: - import backport_collections as collections -except ImportError: - import collections - class PostHandler(object): """ @@ -81,21 +73,21 @@ def __init__(self): self.post = {} self.post["pv"] = {} - def depth(self, x): + def depth(self, depth): """Received depth in plies.""" - self.post["depth"] = x + self.post["depth"] = depth - def score(self, x): + def score(self, score): """Receieved score in centipawns.""" - self.post["score"] = x + self.post["score"] = score - def time(self, x): + def time(self, time): """Received new time searched in centiseconds.""" - self.post["time"] = x + self.post["time"] = time - def nodes(self, x): + def nodes(self, nodes): """Received number of nodes searched.""" - self.post["nodes"] = x + self.post["nodes"] = nodes def pv(self, moves): """Received the principal variation as a list of moves.""" @@ -128,7 +120,6 @@ def on_go(self): with self.lock: self.post.clear() self.post["pv"] = {} - pass def acquire(self, blocking=True): return self.lock.acquire(blocking) @@ -148,33 +139,33 @@ class FeatureMap(object): def __init__(self): # Populated with defaults to begin with self._features = { - "ping" : 0, # TODO: Remove dependency of xboard module on ping - "setboard" : 0, - "playother" : 0, - "san" : 0, - "usermove" : 0, - "time" : 1, - "draw" : 1, - "sigint" : 1, - "sigterm" : 1, - "reuse" : 1, - "analyze" : 1, - "myname" : None, - "variants" : None, - "colors" : 1, - "ics" : 0, - "name" : None, - "pause" : 0, - "nps" : 1, - "debug" : 0, - "memory" : 0, - "smp" : 0, - "egt" : 0, - "option" : OptionMap(), - "done" : None - } - - def _set_feature(self, key, value): + "ping" : 0, # TODO: Remove dependency of xboard module on ping + "setboard" : 0, + "playother" : 0, + "san" : 0, + "usermove" : 0, + "time" : 1, + "draw" : 1, + "sigint" : 1, + "sigterm" : 1, + "reuse" : 1, + "analyze" : 1, + "myname" : None, + "variants" : None, + "colors" : 1, + "ics" : 0, + "name" : None, + "pause" : 0, + "nps" : 1, + "debug" : 0, + "memory" : 0, + "smp" : 0, + "egt" : 0, + "option" : OptionMap(), + "done" : None + } + + def set_feature(self, key, value): try: value = int(value) except ValueError: @@ -185,6 +176,18 @@ def _set_feature(self, key, value): except KeyError: LOGGER.exception("exception looking up feature") + def get_option(self, key): + try: + return self._features["option"][key] + except KeyError: + LOGGER.exception("exception looking up option") + + def set_option(self, key, value): + try: + self._features["option"][key] = value + except KeyError: + LOGGER.exception("exception looking up option") + def get(self, key): try: return self._features[key] @@ -297,17 +300,17 @@ def _feature(self, features): min = int(params[3]) max = int(params[4]) option = Option(name, type, default, min, max, var) - self.features._features["option"][option.name] = option + self.features.set_option(option.name, option) return features = features.split() - feature_map = [ feature.split("=") for feature in features ] + feature_map = [feature.split("=") for feature in features] for (key, value) in feature_map: value = value.strip("\"") if key == "variant": - self.features._set_feature(key, value.split(",")) + self.features.set_feature(key, value.split(",")) else: - self.features._set_feature(key, value) + self.features.set_feature(key, value) def _pong(self, pong_arg): try: @@ -540,7 +543,7 @@ def option(self, options, async_callback=None): for name, value in options.items(): # Building string manually to avoid spaces option_string = "option " + name - option = self.features._features["option"][name] + option = self.features.get_option(name) has_value = option.type in \ ("spin", "check", "combo", "string") if has_value and value is not None: @@ -657,7 +660,8 @@ def set_side_to_move(self, color, async_callback=None): :return: Nothing """ self._assert_supports_feature("colors") - self._assert_not_busy(chess.COLOR_NAMES[color]) + side = chess.COLOR_NAMES[color] + self._assert_not_busy(side) self.in_force = False command = self.command(side) @@ -670,7 +674,7 @@ def white(self, async_callback=None): :return: Nothing """ - set_side_to_move(chess.WHITE, async_callback) + self.set_side_to_move(chess.WHITE, async_callback) def black(self, async_callback=None): """ @@ -679,7 +683,7 @@ def black(self, async_callback=None): :return: Nothing """ - set_side_to_move(chess.BLACK, async_callback) + self.set_side_to_move(chess.BLACK, async_callback) def random(self, async_callback=None): """ From 26cdde2a3417c529e5c44c66dc5a645c283b0b9b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Nov 2017 16:26:06 +0100 Subject: [PATCH 0094/1831] test and fix ThreeCheckBoard.is_irreversible() --- chess/variant.py | 2 +- test.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/chess/variant.py b/chess/variant.py index cf3373d24..63661fbd3 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -570,7 +570,7 @@ def is_variant_loss(self): def is_variant_win(self): return self.remaining_checks[self.turn] <= 0 and self.remaining_checks[not self.turn] > 0 - def is_irreversible(move): + def is_irreversible(self, move): if super(ThreeCheckBoard, self).is_irreversible(move): return True diff --git a/test.py b/test.py index d9f3b526a..a09af2479 100755 --- a/test.py +++ b/test.py @@ -3275,6 +3275,30 @@ def test_set_epd(self): self.assertEqual(board.epd(), "4r3/ppk3p1/4b2p/2ppPp2/5P2/2P3P1/PP1N2P1/3R2K1 w - - 1+3") self.assertEqual(extra["foo"], "bar") + def test_check_is_irreversible(self): + board = chess.variant.ThreeCheckBoard() + + move = board.parse_san("Nf3") + self.assertFalse(board.is_irreversible(move)) + board.push(move) + + move = board.parse_san("e5") + self.assertTrue(board.is_irreversible(move)) + board.push(move) + + move = board.parse_san("Nxe5") + self.assertTrue(board.is_irreversible(move)) + board.push(move) + + # Loses castling rights. + move = board.parse_san("Ke7") + self.assertTrue(board.is_irreversible(move)) + board.push(move) + + # Gives a check. + move = board.parse_san("Nc6+") + self.assertTrue(board.is_irreversible(move)) + class CrazyhouseTestCase(unittest.TestCase): From 5f2322e3841f255b51b66885a13a813fff22c13e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Nov 2017 16:35:29 +0100 Subject: [PATCH 0095/1831] test and fix ThreeCheckBoard._transposition_key() --- chess/variant.py | 2 +- test.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/chess/variant.py b/chess/variant.py index 63661fbd3..827640030 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -581,7 +581,7 @@ def is_irreversible(self, move): def _transposition_key(self): return (super(ThreeCheckBoard, self)._transposition_key(), - self.remaining_checks[WHITE], self.remaining_checks[BLACK]) + self.remaining_checks[chess.WHITE], self.remaining_checks[chess.BLACK]) def copy(self, stack=True): board = super(ThreeCheckBoard, self).copy(stack=stack) diff --git a/test.py b/test.py index a09af2479..cf497336d 100755 --- a/test.py +++ b/test.py @@ -3299,6 +3299,17 @@ def test_check_is_irreversible(self): move = board.parse_san("Nc6+") self.assertTrue(board.is_irreversible(move)) + def test_three_check_eq(self): + a = chess.variant.ThreeCheckBoard() + a.push_san("e4") + + b = chess.variant.ThreeCheckBoard("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1 +0+0") + c = chess.variant.ThreeCheckBoard("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1 +0+1") + + self.assertEqual(a, b) + self.assertNotEqual(a, c) + self.assertNotEqual(b, c) + class CrazyhouseTestCase(unittest.TestCase): From 0a7fa1a0f7fc307734ceeb3bb2661958034b7d8d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Nov 2017 16:48:06 +0100 Subject: [PATCH 0096/1831] remove unused variable --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 06f640a9a..dea53621a 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -299,7 +299,7 @@ def _attack_table(deltas): mask_table = [] attack_table = [] - for square, bb in enumerate(BB_SQUARES): + for square in SQUARES: attacks = {} mask = _sliding_attacks(square, 0, deltas) & ~_edges(square) From 0d007c23f593957f049b16df105d82d447e5833b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Nov 2017 16:48:20 +0100 Subject: [PATCH 0097/1831] support Board.set_piece_at(_, _, promoted=False) --- chess/__init__.py | 4 ++-- test.py | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index dea53621a..4b9aff555 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1249,8 +1249,8 @@ def remove_piece_at(self, square): self.clear_stack() return piece - def set_piece_at(self, square, piece): - super(Board, self).set_piece_at(square, piece) + def set_piece_at(self, square, piece, promoted=False): + super(Board, self).set_piece_at(square, piece, promoted=promoted) self.clear_stack() def generate_pseudo_legal_moves(self, from_mask=BB_ALL, to_mask=BB_ALL): diff --git a/test.py b/test.py index cf497336d..db8ae2cd2 100755 --- a/test.py +++ b/test.py @@ -273,6 +273,9 @@ def test_get_set(self): board.set_piece_at(chess.F1, None) self.assertEqual(board.piece_at(chess.F1), None) + board.set_piece_at(chess.H7, chess.Piece.from_symbol("Q"), promoted=True) + self.assertEqual(board.promoted, chess.BB_H7) + def test_pawn_captures(self): board = chess.Board() From b5a96f4cd2789147dc96e64f646a8a2dff3e938d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Nov 2017 17:00:24 +0100 Subject: [PATCH 0098/1831] fix unused variables --- chess/syzygy.py | 12 ++++++------ examples/bratko_kopec/bratko_kopec.py | 4 ++-- release.py | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 6c6040776..534e634dd 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -608,7 +608,7 @@ def __init__(self, directory, filename, variant): self.enc_type = 2 else: # only for suicide j = 16 - for i in range(16): + for _ in range(16): for piece_type in PCHR: if 1 < black_part.count(piece_type) < j: j = black_part.count(piece_type) @@ -1574,7 +1574,7 @@ def probe_ab(self, board, alpha, beta, threats=False): for move in board.generate_legal_moves(to_mask=board.occupied_co[not board.turn]): board.push(move) try: - v_plus, success = self.probe_ab(board, -beta, -alpha) + v_plus, _ = self.probe_ab(board, -beta, -alpha) v = -v_plus finally: board.pop() @@ -1631,7 +1631,7 @@ def sprobe_capts(self, board, alpha, beta): board.push(move) try: - v_plus, success = self.sprobe_ab(board, -beta, -alpha) + v_plus, _ = self.sprobe_ab(board, -beta, -alpha) v = -v_plus finally: board.pop() @@ -1680,7 +1680,7 @@ def probe_wdl(self, board): raise KeyError("syzygy tables support up to 6 pieces, not {0}: {1}".format(chess.popcount(board.occupied), board.fen())) # Probe. - v, success = self.probe_ab(board, -2, 2) + v, _ = self.probe_ab(board, -2, 2) # If en passant is not possible, we are done. if not board.ep_square or self.variant.captures_compulsory: @@ -1693,7 +1693,7 @@ def probe_wdl(self, board): for move in board.generate_legal_ep(): board.push(move) try: - v0_plus, success = self.probe_ab(board, -2, 2) + v0_plus, _ = self.probe_ab(board, -2, 2) v0 = -v0_plus finally: board.pop() @@ -1872,7 +1872,7 @@ def probe_dtz(self, board): for move in board.generate_legal_ep(): board.push(move) try: - v0_plus, success = self.probe_ab(board, -2, 2) + v0_plus, _ = self.probe_ab(board, -2, 2) v0 = -v0_plus finally: board.pop() diff --git a/examples/bratko_kopec/bratko_kopec.py b/examples/bratko_kopec/bratko_kopec.py index 175633c39..aae6b1077 100755 --- a/examples/bratko_kopec/bratko_kopec.py +++ b/examples/bratko_kopec/bratko_kopec.py @@ -31,7 +31,7 @@ def test_epd(engine, epd, VariantBoard, threads, movetime): }) engine.position(position) - enginemove, pondermove = engine.go(movetime=movetime) + enginemove, _ = engine.go(movetime=movetime) if "am" in epd_info and enginemove in epd_info["am"]: print("%s: %s | +0" % (epd_string, position.san(enginemove))) @@ -93,7 +93,7 @@ def test_epd_with_fractional_scores(engine, epd, VariantBoard, threads, movetime # Assess the final best move by the engine. time.sleep(movetime / 4000.0) engine.stop() - enginemove, pondermove = search.result() + enginemove, _ = search.result() if "am" in epd_info and enginemove in epd_info["am"]: pass # fail elif "bm" in epd_info and enginemove not in epd_info["bm"]: diff --git a/release.py b/release.py index 35f5d7a23..46f3ba152 100755 --- a/release.py +++ b/release.py @@ -4,11 +4,6 @@ import os import chess import sys -import zipfile -import textwrap -import configparser -import requests -import bs4 def system(command): From 850e4d565cb80a13da10e2526f6b4bb512ca7d4b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 4 Nov 2017 11:12:26 +0100 Subject: [PATCH 0099/1831] add sesse as source of regular syzygy tables --- data/syzygy/regular/SOURCE-5.txt | 290 ++++++++++++ data/syzygy/regular/SOURCE-6.txt | 730 +++++++++++++++++++++++++++++++ 2 files changed, 1020 insertions(+) create mode 100644 data/syzygy/regular/SOURCE-5.txt create mode 100644 data/syzygy/regular/SOURCE-6.txt diff --git a/data/syzygy/regular/SOURCE-5.txt b/data/syzygy/regular/SOURCE-5.txt new file mode 100644 index 000000000..953fa02ac --- /dev/null +++ b/data/syzygy/regular/SOURCE-5.txt @@ -0,0 +1,290 @@ +http://tablebase.sesse.net/syzygy/3-4-5/KQvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQNvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQPvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRNvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRPvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBNvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBPvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNNvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNPvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKQ.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKQ.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKR.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKR.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKB.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKB.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKN.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKN.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKP.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPPvKP.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQQvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQQvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQRvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQRvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQQPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQQPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRRvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRRvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQRPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQRPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQBPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQBPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQNNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQNNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQNPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQNPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KQPPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KQPPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRRvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRRvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRRPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRRPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRBPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRBPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRNNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRNNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRNPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRNPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KRPPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KRPPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBBvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBBvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBBPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBBPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBNNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBNNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBNPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBNPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KBPPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KBPPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNNNvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNNNvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNNPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNNPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KNPPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KNPPvK.rtbz +http://tablebase.sesse.net/syzygy/3-4-5/KPPPvK.rtbw +http://tablebase.sesse.net/syzygy/3-4-5/KPPPvK.rtbz diff --git a/data/syzygy/regular/SOURCE-6.txt b/data/syzygy/regular/SOURCE-6.txt new file mode 100644 index 000000000..2c3fe7315 --- /dev/null +++ b/data/syzygy/regular/SOURCE-6.txt @@ -0,0 +1,730 @@ +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKQQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKQQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKQR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKQR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKQB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKQB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKQN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKQN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKQP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKQP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKRR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKRR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKRB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKRB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKRN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKRN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKQR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKQR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKQB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKQB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKQN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKQN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKQP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKQP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKRR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKRR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKRB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKRB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKRN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKRN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKQB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKQB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKQN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKQN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKQP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKQP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKRR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKRR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKRB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKRB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKRN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKRN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKQN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKQN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKQP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKQP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKRR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKRR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKRB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKRB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKRN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKRN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKQP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKQP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKRR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKRR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKRB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKRB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKRN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKRN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKRR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKRR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKRB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKRB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKRN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKRN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKRB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKRB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKRN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKRN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNvKRN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNvKRN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPvKRP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPvKRP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBvKBB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBvKBB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNvKBN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNvKBN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPvKBP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPvKBP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNvKNN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNvKNN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNPvKNP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNPvKNP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNPvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNPvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KPPvKPP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KPPvKPP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQBvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQBvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQBvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQBvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQBvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQBvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQBvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQBvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQBvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQBvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRBvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRBvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRBvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRBvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRBvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRBvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRBvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRBvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRBvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRBvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBBvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBBvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBBvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBBvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBBvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBBvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBBvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBBvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBBvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBBvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRBvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRBvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRBvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRBvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRBvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRBvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRBvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRBvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRBvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRBvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBBvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBBvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBBvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBBvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBBvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBBvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBBvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBBvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBBvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBBvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBBvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBBvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBBvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBBvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBBvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBBvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBBvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBBvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBBvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBBvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNNvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNNvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNNvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNNvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNNvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNNvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNNvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNNvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNNvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNNvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNPPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNPPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNPPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNPPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNPPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNPPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNPPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNPPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNPPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNPPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KPPPvKQ.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KPPPvKQ.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KPPPvKR.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KPPPvKR.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KPPPvKB.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KPPPvKB.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KPPPvKN.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KPPPvKN.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KPPPvKP.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KPPPvKP.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQQvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQQvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQRvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQRvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQQPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQQPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRRvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRRvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQRPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQRPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQBBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQBBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQBNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQBNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQBPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQBPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQQPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQQPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRRvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRRvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRRPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRRPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRBBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRBBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRBNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRBNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRBPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRBPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQRPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQRPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBBBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBBBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBBNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBBNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBBPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBBPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQBPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQBPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQNPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQNPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KQPPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KQPPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRRvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRRvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRRPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRRPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRBBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRBBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRBNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRBNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRBPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRBPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRRPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRRPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBBBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBBBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBBNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBBNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBBPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBBPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRBPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRBPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRNPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRNPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KRPPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KRPPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBBBvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBBBvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBBNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBBNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBBPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBBPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBBPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBBPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBNPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBNPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KBPPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KBPPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNNNvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNNNvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNNPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNNPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNNPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNNPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KNPPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KNPPPvK.rtbz +http://tablebase.sesse.net/syzygy/6-WDL/KPPPPvK.rtbw +http://tablebase.sesse.net/syzygy/6-DTZ/KPPPPvK.rtbz From 8af3b66875347866db5f6673dfe266dc81de7400 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Nov 2017 20:44:55 +0100 Subject: [PATCH 0100/1831] Import IPython.core.display.SVG in examples --- chess/svg.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 44917f4cf..d09f2d2eb 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -110,7 +110,9 @@ def piece(piece, size=None): >>> import chess >>> import chess.svg >>> - >>> chess.svg.piece(chess.Piece.from_symbol("R")) # doctest: +SKIP + >>> from IPython.core.display import SVG + >>> + >>> SVG(chess.svg.piece(chess.Piece.from_symbol("R"))) # doctest: +SKIP .. image:: ../docs/wR.svg """ @@ -141,9 +143,11 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No >>> import chess >>> import chess.svg >>> + >>> from IPython.core.display import SVG + >>> >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1") >>> squares = board.attacks(chess.E4) - >>> chess.svg.board(board=board, squares=squares) # doctest: +SKIP + >>> SVG(chess.svg.board(board=board, squares=squares)) # doctest: +SKIP .. image:: ../docs/Ne4.svg """ From 567cb0f6b88f189121966ae9660f4ab3f637ee33 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Nov 2017 21:04:59 +0100 Subject: [PATCH 0101/1831] Use slightly better unicode char for empty square --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 4b9aff555..a16bfe6bb 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1029,7 +1029,7 @@ def unicode(self, invert_color=False, borders=False): if piece: builder.append(piece.unicode_symbol(invert_color=invert_color)) else: - builder.append(".") + builder.append("·") if borders: builder.append("|") From 0cc01942ed6fc143bf7bfa4ed992d6596883dd41 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Nov 2017 22:05:37 +0100 Subject: [PATCH 0102/1831] Fix Board.unicode() test --- test.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test.py b/test.py index db8ae2cd2..6aed13ac6 100755 --- a/test.py +++ b/test.py @@ -1195,14 +1195,14 @@ def test_string_conversion(self): . . . . . . K .""")) self.assertEqual(board.unicode(), textwrap.dedent(u"""\ - . . . . . . . ♚ - . ♟ . ♛ ♞ . ♝ . - ♟ ♗ . ♟ . ♞ . . - . . . ♙ ♟ . . . - . . . . ♙ ♟ . ♟ - . . ♕ ♘ . ♗ . . - ♙ ♙ . . . . ♙ ♙ - . . . . . . ♔ .""")) + · · · · · · · ♚ + · ♟ · ♛ ♞ · ♝ · + ♟ ♗ · ♟ · ♞ · · + · · · ♙ ♟ · · · + · · · · ♙ ♟ · ♟ + · · ♕ ♘ · ♗ · · + ♙ ♙ · · · · ♙ ♙ + · · · · · · ♔ ·""")) def test_move_info(self): board = chess.Board("r1bqkb1r/p3np2/2n1p2p/1p4pP/2pP4/4PQ1N/1P2BPP1/RNB1K2R w KQkq g6 0 11") From d251ae7c786ba31148124f650060e168f8fe07dc Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Nov 2017 22:21:34 +0100 Subject: [PATCH 0103/1831] Fix unicode literal --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index a16bfe6bb..d5a8d83d0 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1029,7 +1029,7 @@ def unicode(self, invert_color=False, borders=False): if piece: builder.append(piece.unicode_symbol(invert_color=invert_color)) else: - builder.append("·") + builder.append(u"·") if borders: builder.append("|") From 8ec7c4df888f052f3354e52f7aa249b10976da3b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 12 Nov 2017 23:03:21 +0100 Subject: [PATCH 0104/1831] Split giveaway/suicide syzygy source --- data/syzygy/giveaway/SOURCE-5.txt | 2520 ----------- data/syzygy/giveaway/SOURCE-6.txt | 4620 --------------------- data/syzygy/suicide/SOURCE-6-PAWNLESS.txt | 4620 +++++++++++++++++++++ 3 files changed, 4620 insertions(+), 7140 deletions(-) create mode 100644 data/syzygy/suicide/SOURCE-6-PAWNLESS.txt diff --git a/data/syzygy/giveaway/SOURCE-5.txt b/data/syzygy/giveaway/SOURCE-5.txt index 361bc3e9c..d976fd810 100644 --- a/data/syzygy/giveaway/SOURCE-5.txt +++ b/data/syzygy/giveaway/SOURCE-5.txt @@ -8,290 +8,110 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvP.gtbw @@ -302,318 +122,128 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNvP.gtbw @@ -624,186 +254,86 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBvP.gtbw @@ -814,96 +344,52 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRvP.gtbw @@ -914,40 +400,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQvP.gtbw @@ -958,8 +430,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvP.gtbw @@ -974,218 +444,88 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNvPP.gtbw @@ -1196,126 +536,58 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBvPP.gtbw @@ -1326,64 +598,34 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRvPP.gtbw @@ -1394,26 +636,16 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQvPP.gtbw @@ -1424,8 +656,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/PPPvNP.gtbw @@ -1436,318 +666,128 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvNN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvNN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvNN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvNN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvNN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvNN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvNN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvNN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvNN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvNN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvBN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvRN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNvNP.gtbw @@ -1758,186 +798,86 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvBN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvBN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvBN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvBN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvBN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvBN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvBN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvBN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvBN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvRN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBvNP.gtbw @@ -1948,96 +888,52 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvRN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvRN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvRN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvRN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvRN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvRN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvRN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvRN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRvNP.gtbw @@ -2048,40 +944,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvNP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQvNP.gtbw @@ -2092,8 +974,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvNP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvNP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvNP.gtbw @@ -2108,176 +988,76 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNvPP.gtbw @@ -2288,146 +1068,66 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvBB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvRB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNvBP.gtbw @@ -2438,96 +1138,48 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNvPP.gtbw @@ -2538,76 +1190,40 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvRR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNvRP.gtbw @@ -2618,44 +1234,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNvPP.gtbw @@ -2666,32 +1264,20 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvQQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNvQP.gtbw @@ -2702,14 +1288,10 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNvPP.gtbw @@ -2720,8 +1302,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPvKK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNvKP.gtbw @@ -2738,186 +1318,86 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvBB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvBB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvBB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvBB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvBB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvBB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvBB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvBB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvBB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvRB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBvBP.gtbw @@ -2928,96 +1408,52 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvRB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvRB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvRB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvRB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvRB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvRB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvRB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvRB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRvBP.gtbw @@ -3028,40 +1464,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvBP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQvBP.gtbw @@ -3072,8 +1494,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvBP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvBP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvBP.gtbw @@ -3088,96 +1508,48 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBvPP.gtbw @@ -3188,76 +1560,40 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvRR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBvRP.gtbw @@ -3268,44 +1604,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBvPP.gtbw @@ -3316,32 +1634,20 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvQQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBvQP.gtbw @@ -3352,14 +1658,10 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBvPP.gtbw @@ -3370,8 +1672,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPvKK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBvKP.gtbw @@ -3388,96 +1688,52 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvRR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvRR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvRR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvRR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvRR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvRR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvRR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvRR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRvRP.gtbw @@ -3488,40 +1744,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvRP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQvRP.gtbw @@ -3532,8 +1774,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvRP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvRP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvRP.gtbw @@ -3548,44 +1788,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRvPP.gtbw @@ -3596,32 +1818,20 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvQQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRvQP.gtbw @@ -3632,14 +1842,10 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRvPP.gtbw @@ -3650,8 +1856,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPvKK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRvKP.gtbw @@ -3668,40 +1872,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvQQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvQQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvQP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQvQP.gtbw @@ -3712,8 +1902,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvQP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvQP.gtbw @@ -3728,14 +1916,10 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvPP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvPP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQvKP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQvPP.gtbw @@ -3746,8 +1930,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPvKK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQvKP.gtbw @@ -3764,8 +1946,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKvKK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPvKP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPvKP.gtbw @@ -3788,250 +1968,110 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvN.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvN.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvN.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvN.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvN.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvN.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NPPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvP.gtbw @@ -4040,206 +2080,86 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/NNNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BNNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RNNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QNNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KNNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/NNPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKNNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNNvP.gtbw @@ -4250,186 +2170,86 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BNPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBNvP.gtbw @@ -4440,96 +2260,52 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RNPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRNvP.gtbw @@ -4540,40 +2316,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQNvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQNvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQNvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QNPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQNPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQNvP.gtbw @@ -4584,8 +2346,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKNvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KNPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKNPvP.gtbw @@ -4600,138 +2360,68 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvB.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvB.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvB.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvB.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvB.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvB.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BPPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvP.gtbw @@ -4740,116 +2430,56 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/BBBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RBBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QBBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KBBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/BBPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKBBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBBvP.gtbw @@ -4860,96 +2490,52 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RBPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRBvP.gtbw @@ -4960,40 +2546,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQBvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQBvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQBvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QBPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQBPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQBvP.gtbw @@ -5004,8 +2576,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKBvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KBPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKBPvP.gtbw @@ -5020,68 +2590,38 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvR.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvR.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvR.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvR.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvR.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvR.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RPPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvP.gtbw @@ -5090,56 +2630,32 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/RRRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QRRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KRRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRRvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRRvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/RRPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKRRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRRPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRRvP.gtbw @@ -5150,40 +2666,26 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQRvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQRvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQRvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QRPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQRPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQRvP.gtbw @@ -5194,8 +2696,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKRvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KRPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKRPvP.gtbw @@ -5210,28 +2710,18 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvQ.stbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvQ.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvQ.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvQ.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvQ.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvQ.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QPPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvP.gtbw @@ -5240,20 +2730,14 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQQvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQQvP.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/QQQQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQQPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KQQQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQQvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQQvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/QQPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKQQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQQPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQQvP.gtbw @@ -5264,8 +2748,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKQvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KQPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKQPvP.gtbw @@ -5280,8 +2762,6 @@ https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvK.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvK.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKKPvK.gtbz -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvK.stbw -https://syzygy-tables.info/suicide/2-3-4-5-pawnless/KKKKvK.stbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvP.gtbw https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KPPPvP.gtbz https://syzygy-tables.info/suicide/2-3-4-5-giveaway/KKPPvP.gtbw diff --git a/data/syzygy/giveaway/SOURCE-6.txt b/data/syzygy/giveaway/SOURCE-6.txt index 5206ef874..246825c02 100644 --- a/data/syzygy/giveaway/SOURCE-6.txt +++ b/data/syzygy/giveaway/SOURCE-6.txt @@ -10,218 +10,88 @@ https://syzygy-tables.info/suicide/6-giveaway/NNPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNvNPP.gtbw @@ -232,126 +102,58 @@ https://syzygy-tables.info/suicide/6-giveaway/BNPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNvNPP.gtbw @@ -362,64 +164,34 @@ https://syzygy-tables.info/suicide/6-giveaway/RNPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvQRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvQRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNvNPP.gtbw @@ -430,26 +202,16 @@ https://syzygy-tables.info/suicide/6-giveaway/QNPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvQQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvNPP.gtbw @@ -460,8 +222,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KNPvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPvPPP.gtbw @@ -472,216 +232,96 @@ https://syzygy-tables.info/suicide/6-giveaway/BPPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BPPvNNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPvNNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvNNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvNNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvNNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvNNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvNNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvNNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvNNN.stbz https://syzygy-tables.info/suicide/6-giveaway/BPPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BPPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvQNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvKNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvKNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBvNNP.gtbw @@ -692,116 +332,60 @@ https://syzygy-tables.info/suicide/6-giveaway/RPPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPvBNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvBNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvBNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvBNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvBNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvBNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvBNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvBNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvQNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvKNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvKNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRvNNP.gtbw @@ -812,52 +396,32 @@ https://syzygy-tables.info/suicide/6-giveaway/QPPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvRNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvRNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvRNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvNNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvKNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvNNP.gtbw @@ -868,16 +432,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvNNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvNNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvNNP.gtbw @@ -892,146 +452,66 @@ https://syzygy-tables.info/suicide/6-giveaway/BBPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNvBPP.gtbw @@ -1042,96 +522,48 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvQBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvQBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBvNPP.gtbw @@ -1142,76 +574,40 @@ https://syzygy-tables.info/suicide/6-giveaway/RBPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvQRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvQRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNvBPP.gtbw @@ -1222,44 +618,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRBvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvQRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBvNPP.gtbw @@ -1270,32 +648,20 @@ https://syzygy-tables.info/suicide/6-giveaway/QBPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvQQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvBPP.gtbw @@ -1306,14 +672,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQBvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvNPP.gtbw @@ -1324,8 +686,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBPvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvBPP.gtbw @@ -1342,116 +702,60 @@ https://syzygy-tables.info/suicide/6-giveaway/RPPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPvBBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvBBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvBBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvBBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvBBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvBBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvBBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvBBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPvQBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvQBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvKBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvKBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRvBNP.gtbw @@ -1462,52 +766,32 @@ https://syzygy-tables.info/suicide/6-giveaway/QPPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvRBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvRBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvRBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvQBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvBNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvKBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvBNP.gtbw @@ -1518,16 +802,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvBNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvBNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvBNP.gtbw @@ -1542,76 +822,40 @@ https://syzygy-tables.info/suicide/6-giveaway/RRPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvQRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNvRPP.gtbw @@ -1622,44 +866,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNvQRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRvNPP.gtbw @@ -1670,32 +896,20 @@ https://syzygy-tables.info/suicide/6-giveaway/QRPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvRPP.gtbw @@ -1706,14 +920,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQRvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvNPP.gtbw @@ -1724,8 +934,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRPvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvRPP.gtbw @@ -1742,52 +950,32 @@ https://syzygy-tables.info/suicide/6-giveaway/QPPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvRRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvRRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvRRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvQRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvRNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvKRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvRNP.gtbw @@ -1798,16 +986,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvRNP.gtbw @@ -1822,32 +1006,20 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvQNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvKQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKQvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvQPP.gtbw @@ -1858,14 +1030,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQvNPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvNPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvKNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNvKQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNvKQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KKNvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvNPP.gtbw @@ -1876,8 +1044,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvKQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKQvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvQPP.gtbw @@ -1894,16 +1060,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvQNP.gtbw @@ -1918,8 +1080,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvKKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNvKKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KKKvKNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKvKNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNvKPP.gtbw @@ -1942,126 +1102,58 @@ https://syzygy-tables.info/suicide/6-giveaway/BBPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvQBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvQBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvQBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBvBPP.gtbw @@ -2072,64 +1164,34 @@ https://syzygy-tables.info/suicide/6-giveaway/RBPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvQRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvQRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBvBPP.gtbw @@ -2140,26 +1202,16 @@ https://syzygy-tables.info/suicide/6-giveaway/QBPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvQQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvKQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvKQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvBPP.gtbw @@ -2170,8 +1222,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBPvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvKBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPvPPP.gtbw @@ -2182,116 +1232,60 @@ https://syzygy-tables.info/suicide/6-giveaway/RPPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPvBBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvBBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvBBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvBBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvBBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvBBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvBBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvBBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvQBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPvQBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvQBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvKBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvKBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRvBBP.gtbw @@ -2302,52 +1296,32 @@ https://syzygy-tables.info/suicide/6-giveaway/QPPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvRBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvRBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvRBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvQBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvBBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvKBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvBBP.gtbw @@ -2358,16 +1332,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvBBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvBBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvBBP.gtbw @@ -2382,76 +1352,40 @@ https://syzygy-tables.info/suicide/6-giveaway/RRPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvQRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBvRPP.gtbw @@ -2462,44 +1396,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBvQRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRvBPP.gtbw @@ -2510,32 +1426,20 @@ https://syzygy-tables.info/suicide/6-giveaway/QRPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvRPP.gtbw @@ -2546,14 +1450,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQRvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvBPP.gtbw @@ -2564,8 +1464,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRPvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvKBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvKBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBvRPP.gtbw @@ -2582,52 +1480,32 @@ https://syzygy-tables.info/suicide/6-giveaway/QPPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvRRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvRRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvRRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvQRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvRBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvKRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvRBP.gtbw @@ -2638,16 +1516,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvRBP.gtbw @@ -2662,32 +1536,20 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvQBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvKQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKQvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvQPP.gtbw @@ -2698,14 +1560,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQvBPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvBPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvKBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBvKQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBvKQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KKBvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvBPP.gtbw @@ -2716,8 +1574,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvKQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKQvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvKBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBvQPP.gtbw @@ -2734,16 +1590,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvQBP.gtbw @@ -2758,8 +1610,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBvKKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBvKKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KKKvKBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKvKBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBvKPP.gtbw @@ -2782,64 +1632,34 @@ https://syzygy-tables.info/suicide/6-giveaway/RRPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRvQRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRvRPP.gtbw @@ -2850,26 +1670,16 @@ https://syzygy-tables.info/suicide/6-giveaway/QRPvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRvQQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvKQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvKQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvRPP.gtbw @@ -2880,8 +1690,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRPvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvKRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPvPPP.gtbw @@ -2892,52 +1700,32 @@ https://syzygy-tables.info/suicide/6-giveaway/QPPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvRRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvRRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvRRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvQRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvRRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvKRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvRRP.gtbw @@ -2948,16 +1736,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvRRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvRRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvRRP.gtbw @@ -2972,32 +1756,20 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvQRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvKQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKQvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvQPP.gtbw @@ -3008,14 +1780,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQvRPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvRPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvKRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRvKQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRvKQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KKRvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvRPP.gtbw @@ -3026,8 +1794,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvKQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKQvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvKRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRvQPP.gtbw @@ -3044,16 +1810,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvQRP.gtbw @@ -3068,8 +1830,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRvKKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRvKKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KKKvKRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKvKRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRvKPP.gtbw @@ -3092,26 +1852,16 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQvQQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvQQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQvKQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQvKQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvKQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KKQvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvQPP.gtbw @@ -3122,8 +1872,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPvKQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvKQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQvKKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQvKKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KKQvQPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvQPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPvPPP.gtbw @@ -3134,16 +1882,12 @@ https://syzygy-tables.info/suicide/6-giveaway/KPPvQQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvQQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvQQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvKQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KKPvQQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvQQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvQQP.gtbw @@ -3158,8 +1902,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvKKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQvKKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KKKvKQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKvKQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQvKPP.gtbw @@ -3182,8 +1924,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPvKKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPvKKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKvKKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKvKKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKvKKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KKKvKPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKvKPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPvPPP.gtbw @@ -3202,250 +1942,110 @@ https://syzygy-tables.info/suicide/6-giveaway/NNPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/BPPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BPPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvNN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvNN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvNN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvNN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvNN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvNN.stbz https://syzygy-tables.info/suicide/6-giveaway/NPPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NPPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvNP.gtbw @@ -3454,206 +2054,86 @@ https://syzygy-tables.info/suicide/6-giveaway/NNNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNvNP.gtbw @@ -3664,186 +2144,86 @@ https://syzygy-tables.info/suicide/6-giveaway/BNPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNvNP.gtbw @@ -3854,96 +2234,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RNPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNvNP.gtbw @@ -3954,40 +2290,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QNPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNvNP.gtbw @@ -3998,8 +2320,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KNPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvNP.gtbw @@ -4014,138 +2334,68 @@ https://syzygy-tables.info/suicide/6-giveaway/BBPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvBN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvBN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvBN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvBN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvBN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvBN.stbz https://syzygy-tables.info/suicide/6-giveaway/BPPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BPPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvNP.gtbw @@ -4154,116 +2404,56 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBvNP.gtbw @@ -4274,96 +2464,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RBPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBvNP.gtbw @@ -4374,40 +2520,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QBPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBvNP.gtbw @@ -4418,8 +2550,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvNP.gtbw @@ -4434,68 +2564,38 @@ https://syzygy-tables.info/suicide/6-giveaway/RRPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvRN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvRN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvRN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvRN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvRN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvRN.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvNP.gtbw @@ -4504,56 +2604,32 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRvNP.gtbw @@ -4564,40 +2640,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QRPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRvNP.gtbw @@ -4608,8 +2670,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvNP.gtbw @@ -4624,28 +2684,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvQN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvQN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvQN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvQN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvQN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvQN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvNP.gtbw @@ -4654,20 +2704,14 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQvNP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQvNP.gtbw @@ -4678,8 +2722,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvNP.gtbw @@ -4694,8 +2736,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvKN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvKN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvKN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvNP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvNP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvNP.gtbw @@ -4714,176 +2754,76 @@ https://syzygy-tables.info/suicide/6-giveaway/NNNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNNvPP.gtbw @@ -4894,146 +2834,66 @@ https://syzygy-tables.info/suicide/6-giveaway/NNPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNvBP.gtbw @@ -5044,96 +2904,48 @@ https://syzygy-tables.info/suicide/6-giveaway/BBNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNNvPP.gtbw @@ -5144,76 +2956,40 @@ https://syzygy-tables.info/suicide/6-giveaway/NNPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNvRP.gtbw @@ -5224,44 +3000,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNNvPP.gtbw @@ -5272,32 +3030,20 @@ https://syzygy-tables.info/suicide/6-giveaway/NNPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNvQP.gtbw @@ -5308,14 +3054,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQNNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNNvPP.gtbw @@ -5326,8 +3068,6 @@ https://syzygy-tables.info/suicide/6-giveaway/NNPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNvKP.gtbw @@ -5344,186 +3084,86 @@ https://syzygy-tables.info/suicide/6-giveaway/BNPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNvBP.gtbw @@ -5534,96 +3174,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RNPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNvBP.gtbw @@ -5634,40 +3230,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QNPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNvBP.gtbw @@ -5678,8 +3260,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KNPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvBP.gtbw @@ -5694,96 +3274,48 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBNvPP.gtbw @@ -5794,76 +3326,40 @@ https://syzygy-tables.info/suicide/6-giveaway/BNPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNvRP.gtbw @@ -5874,44 +3370,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRBNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBNvPP.gtbw @@ -5922,32 +3400,20 @@ https://syzygy-tables.info/suicide/6-giveaway/BNPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNvQP.gtbw @@ -5958,14 +3424,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQBNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBNvPP.gtbw @@ -5976,8 +3438,6 @@ https://syzygy-tables.info/suicide/6-giveaway/BNPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNvKP.gtbw @@ -5994,96 +3454,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RNPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNvRP.gtbw @@ -6094,40 +3510,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QNPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNvRP.gtbw @@ -6138,8 +3540,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KNPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvRP.gtbw @@ -6154,44 +3554,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRNvPP.gtbw @@ -6202,32 +3584,20 @@ https://syzygy-tables.info/suicide/6-giveaway/RNPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNvQP.gtbw @@ -6238,14 +3608,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQRNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRNvPP.gtbw @@ -6256,8 +3622,6 @@ https://syzygy-tables.info/suicide/6-giveaway/RNPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNvKP.gtbw @@ -6274,40 +3638,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QNPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNvQP.gtbw @@ -6318,8 +3668,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KNPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvQP.gtbw @@ -6334,14 +3682,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQNvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQNvPP.gtbw @@ -6352,8 +3696,6 @@ https://syzygy-tables.info/suicide/6-giveaway/QNPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNvKP.gtbw @@ -6370,8 +3712,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KNPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPvKP.gtbw @@ -6394,138 +3734,68 @@ https://syzygy-tables.info/suicide/6-giveaway/BBPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvBB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvBB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvBB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvBB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvBB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvBB.stbz https://syzygy-tables.info/suicide/6-giveaway/BPPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BPPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvBP.gtbw @@ -6534,116 +3804,56 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBvBP.gtbw @@ -6654,96 +3864,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RBPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBvBP.gtbw @@ -6754,40 +3920,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QBPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBvBP.gtbw @@ -6798,8 +3950,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvBP.gtbw @@ -6814,68 +3964,38 @@ https://syzygy-tables.info/suicide/6-giveaway/RRPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvRB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvRB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvRB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvRB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvRB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvRB.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvBP.gtbw @@ -6884,56 +4004,32 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRvBP.gtbw @@ -6944,40 +4040,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QRPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRvBP.gtbw @@ -6988,8 +4070,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvBP.gtbw @@ -7004,28 +4084,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvQB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvQB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvQB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvQB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvQB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvQB.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvBP.gtbw @@ -7034,20 +4104,14 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQvBP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQvBP.gtbw @@ -7058,8 +4122,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvBP.gtbw @@ -7074,8 +4136,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvKB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvKB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvKB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvBP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvBP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvBP.gtbw @@ -7094,96 +4154,48 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBBvPP.gtbw @@ -7194,76 +4206,40 @@ https://syzygy-tables.info/suicide/6-giveaway/BBPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBvRP.gtbw @@ -7274,44 +4250,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRBBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBBvPP.gtbw @@ -7322,32 +4280,20 @@ https://syzygy-tables.info/suicide/6-giveaway/BBPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBvQP.gtbw @@ -7358,14 +4304,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQBBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBBvPP.gtbw @@ -7376,8 +4318,6 @@ https://syzygy-tables.info/suicide/6-giveaway/BBPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBvKP.gtbw @@ -7394,96 +4334,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RBPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBvRP.gtbw @@ -7494,40 +4390,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QBPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBvRP.gtbw @@ -7538,8 +4420,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvRP.gtbw @@ -7554,44 +4434,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRBvPP.gtbw @@ -7602,32 +4464,20 @@ https://syzygy-tables.info/suicide/6-giveaway/RBPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBvQP.gtbw @@ -7638,14 +4488,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQRBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRBvPP.gtbw @@ -7656,8 +4502,6 @@ https://syzygy-tables.info/suicide/6-giveaway/RBPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBvKP.gtbw @@ -7674,40 +4518,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QBPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBvQP.gtbw @@ -7718,8 +4548,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvQP.gtbw @@ -7734,14 +4562,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQBvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQBvPP.gtbw @@ -7752,8 +4576,6 @@ https://syzygy-tables.info/suicide/6-giveaway/QBPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBvKP.gtbw @@ -7770,8 +4592,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPvKP.gtbw @@ -7794,68 +4614,38 @@ https://syzygy-tables.info/suicide/6-giveaway/RRPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvRR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvRR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvRR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvRR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvRR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvRR.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvRP.gtbw @@ -7864,56 +4654,32 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRvRP.gtbw @@ -7924,40 +4690,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QRPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRvRP.gtbw @@ -7968,8 +4720,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvRP.gtbw @@ -7984,28 +4734,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvQR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvQR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvQR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvQR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvQR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvQR.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvRP.gtbw @@ -8014,20 +4754,14 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQvRP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQvRP.gtbw @@ -8038,8 +4772,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvRP.gtbw @@ -8054,8 +4786,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvKR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvKR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvKR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKR.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvRP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvRP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvRP.gtbw @@ -8074,44 +4804,26 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRRvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRRvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRRvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRRvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRRvPP.gtbw @@ -8122,32 +4834,20 @@ https://syzygy-tables.info/suicide/6-giveaway/RRPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRvQP.gtbw @@ -8158,14 +4858,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQRRvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRRvPP.gtbw @@ -8176,8 +4872,6 @@ https://syzygy-tables.info/suicide/6-giveaway/RRPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRvKP.gtbw @@ -8194,40 +4888,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QRPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRvQP.gtbw @@ -8238,8 +4918,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvQP.gtbw @@ -8254,14 +4932,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQRvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQRvPP.gtbw @@ -8272,8 +4946,6 @@ https://syzygy-tables.info/suicide/6-giveaway/QRPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRvKP.gtbw @@ -8290,8 +4962,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPvKP.gtbw @@ -8314,28 +4984,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvQQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvQQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvQQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvQQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvQQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvQQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvQP.gtbw @@ -8344,20 +5004,14 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQvQP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQvQP.gtbw @@ -8368,8 +5022,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvQP.gtbw @@ -8384,8 +5036,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvKQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvKQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvKQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvQP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvQP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvQP.gtbw @@ -8404,14 +5054,10 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQQvPP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQvPP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQvKP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQQvPP.gtbw @@ -8422,8 +5068,6 @@ https://syzygy-tables.info/suicide/6-giveaway/QQPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQvKP.gtbw @@ -8440,8 +5084,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPvKP.gtbw @@ -8464,8 +5106,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKPPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKPPvKK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKPvKK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPvKK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKvKK.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPvKP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPvKP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPvKP.gtbw @@ -8494,250 +5134,110 @@ https://syzygy-tables.info/suicide/6-giveaway/NNNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/BNPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKNPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKNPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvN.stbz https://syzygy-tables.info/suicide/6-giveaway/BPPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BPPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPPvN.gtbw @@ -8746,138 +5246,68 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKBPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKBPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvN.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPPvN.gtbw @@ -8886,68 +5316,38 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKRPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKRPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvN.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPPvN.gtbw @@ -8956,28 +5356,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvN.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQQPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKQPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKQPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvN.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPPvN.gtbw @@ -8986,8 +5376,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKKPPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPPvN.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKKPvN.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKKPvN.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvN.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvN.stbz https://syzygy-tables.info/suicide/6-giveaway/NPPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NPPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNPPPvP.gtbw @@ -8998,206 +5386,86 @@ https://syzygy-tables.info/suicide/6-giveaway/NNNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/NNNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BNNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RNNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QNNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/NNNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KNNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/NNNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/NNNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KNNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKNNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNNvP.gtbw @@ -9208,186 +5476,86 @@ https://syzygy-tables.info/suicide/6-giveaway/BNNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BNNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNNvP.gtbw @@ -9398,96 +5566,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RNNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RNNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNNvP.gtbw @@ -9498,40 +5622,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QNNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QNNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QNNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNNvP.gtbw @@ -9542,8 +5652,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KNNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKNNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KNNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNNPvP.gtbw @@ -9558,138 +5666,68 @@ https://syzygy-tables.info/suicide/6-giveaway/BBNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKNPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKNPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvB.stbz https://syzygy-tables.info/suicide/6-giveaway/BNPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BNPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPPvP.gtbw @@ -9698,116 +5736,56 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBNvP.gtbw @@ -9818,96 +5796,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RBNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBNvP.gtbw @@ -9918,40 +5852,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QBNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBNvP.gtbw @@ -9962,8 +5882,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBNPvP.gtbw @@ -9978,68 +5896,38 @@ https://syzygy-tables.info/suicide/6-giveaway/RRNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKNPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKNPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RNPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RNPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPPvP.gtbw @@ -10048,56 +5936,32 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRNvP.gtbw @@ -10108,40 +5972,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QRNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRNvP.gtbw @@ -10152,8 +6002,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRNPvP.gtbw @@ -10168,28 +6016,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKNPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKNPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QNPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QNPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPPvP.gtbw @@ -10198,20 +6036,14 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQNvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQNvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQNvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQNPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQNPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQNvP.gtbw @@ -10222,8 +6054,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQNPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQNPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQNPvP.gtbw @@ -10238,8 +6068,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKNPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKNPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKNPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKNPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKNvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KNPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KNPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKNPPvP.gtbw @@ -10258,138 +6086,68 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKBPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKBPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvB.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPPvB.gtbw @@ -10398,68 +6156,38 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKRPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKRPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvB.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPPvB.gtbw @@ -10468,28 +6196,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvB.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQQPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKQPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKQPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvB.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPPvB.gtbw @@ -10498,8 +6216,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKKPPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPPvB.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKKPvB.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKKPvB.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvB.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvB.stbz https://syzygy-tables.info/suicide/6-giveaway/BPPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BPPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBPPPvP.gtbw @@ -10510,116 +6226,56 @@ https://syzygy-tables.info/suicide/6-giveaway/BBBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/BBBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RBBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QBBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/BBBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KBBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/BBBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/BBBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KBBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKBBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBBvP.gtbw @@ -10630,96 +6286,52 @@ https://syzygy-tables.info/suicide/6-giveaway/RBBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBBPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RBBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBBvP.gtbw @@ -10730,40 +6342,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QBBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBBPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QBBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBBvP.gtbw @@ -10774,8 +6372,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KBBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKBBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBBPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBBPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBBPvP.gtbw @@ -10790,68 +6386,38 @@ https://syzygy-tables.info/suicide/6-giveaway/RRBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKBPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKBPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RBPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RBPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPPvP.gtbw @@ -10860,56 +6426,32 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRBvP.gtbw @@ -10920,40 +6462,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QRBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRBPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRBvP.gtbw @@ -10964,8 +6492,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRBPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRBPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRBPvP.gtbw @@ -10980,28 +6506,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKBPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKBPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QBPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QBPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPPvP.gtbw @@ -11010,20 +6526,14 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQBvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQBvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQBvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQBPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQBPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQBvP.gtbw @@ -11034,8 +6544,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQBPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQBPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQBPvP.gtbw @@ -11050,8 +6558,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKBPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKBPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKBPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKBPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKBvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KBPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KBPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKBPPvP.gtbw @@ -11070,68 +6576,38 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKRPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKRPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvR.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPPvR.gtbw @@ -11140,28 +6616,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvR.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQQPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKQPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKQPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvR.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPPvR.gtbw @@ -11170,8 +6636,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKKPPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPPvR.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKKPvR.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKKPvR.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvR.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvR.stbz https://syzygy-tables.info/suicide/6-giveaway/RPPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RPPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRPPPvP.gtbw @@ -11182,56 +6646,32 @@ https://syzygy-tables.info/suicide/6-giveaway/RRRRPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRRRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRRvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/RRRRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRRvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QRRRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/RRRRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KRRRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRRvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRRvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQRRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQRRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRRvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/RRRPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/RRRPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KRRRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKRRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRRPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRRPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRRvP.gtbw @@ -11242,40 +6682,26 @@ https://syzygy-tables.info/suicide/6-giveaway/QRRPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRRPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRRPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRRvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQRRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRRvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QRRPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRRPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQRRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRRPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRRPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRRvP.gtbw @@ -11286,8 +6712,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KRRPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKRRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRRPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRRPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRRPvP.gtbw @@ -11302,28 +6726,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQRPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKRPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKRPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QRPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QRPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPPvP.gtbw @@ -11332,20 +6746,14 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQRPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQRvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQRvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQRvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQRPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQRPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQRPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQRPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQRvP.gtbw @@ -11356,8 +6764,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQRPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQRPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQRPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQRPvP.gtbw @@ -11372,8 +6778,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKRPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKRPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKRPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKRPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKRvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KRPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KRPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKRPPvP.gtbw @@ -11392,28 +6796,18 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvQ.stbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQQPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKQPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKQPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPPvQ.gtbw @@ -11422,8 +6816,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKKPPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPPvQ.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKKPvQ.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKKPvQ.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvQ.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvQ.stbz https://syzygy-tables.info/suicide/6-giveaway/QPPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QPPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQPPPvP.gtbw @@ -11434,20 +6826,14 @@ https://syzygy-tables.info/suicide/6-giveaway/QQQQPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQQQvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQQvP.gtbz -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/QQQQQvK.stbz https://syzygy-tables.info/suicide/6-giveaway/QQQQPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQQPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KQQQQvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQQvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQQvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/QQQPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/QQQPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KQQQPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKQQQvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQQPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQQPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQQvP.gtbw @@ -11458,8 +6844,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KQQPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQQPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKQQvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQQPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQQPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQQPvP.gtbw @@ -11474,8 +6858,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKQPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKQPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKQPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKQPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKQvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KQPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KQPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKQPPvP.gtbw @@ -11494,8 +6876,6 @@ https://syzygy-tables.info/suicide/6-giveaway/KKKPPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKPPvK.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKKKPvK.gtbw https://syzygy-tables.info/suicide/6-giveaway/KKKKPvK.gtbz -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvK.stbw -https://syzygy-tables.info/suicide/6-pawnless/KKKKKvK.stbz https://syzygy-tables.info/suicide/6-giveaway/KPPPPvP.gtbw https://syzygy-tables.info/suicide/6-giveaway/KPPPPvP.gtbz https://syzygy-tables.info/suicide/6-giveaway/KKPPPvP.gtbw diff --git a/data/syzygy/suicide/SOURCE-6-PAWNLESS.txt b/data/syzygy/suicide/SOURCE-6-PAWNLESS.txt new file mode 100644 index 000000000..4ec1b5894 --- /dev/null +++ b/data/syzygy/suicide/SOURCE-6-PAWNLESS.txt @@ -0,0 +1,4620 @@ +https://syzygy-tables.info/suicide/6-pawnless/NNNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvNNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvNNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvBNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvBNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvRNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvRNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvBBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvBBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvRBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvRBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvRRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvRRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNvKQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNvKQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvKQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvKQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvBBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvBBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvRBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvRBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvRRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvRRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBvKQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBvKQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvKQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvKQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvRRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvRRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRvKQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRvKQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQvKQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQvKQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQvKKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQvKKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvQQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvQQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKvKKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvNN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvNN.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvBN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvBN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvRN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvRN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvQN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvQN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKN.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvBB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvBB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvRB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvRB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvQB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvQB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvRR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvRR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvQR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvQR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvQQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvQQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKvKK.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvN.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvN.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/NNNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BNNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RNNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QNNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KNNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKNNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKNNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKNvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvB.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvB.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/BBBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RBBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QBBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KBBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKBBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKBBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKBvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvR.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvR.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/RRRRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QRRRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KRRRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQRRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQRRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKRRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKRRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKRvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvQ.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvQ.stbz +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/QQQQQvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KQQQQvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKQQQvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKQQvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKQvK.stbz +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvK.stbw +https://syzygy-tables.info/suicide/6-pawnless/KKKKKvK.stbz From 66caf2585c45adeb31b22eb67cc6e5d578a4eff8 Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Mon, 13 Nov 2017 19:12:36 +0530 Subject: [PATCH 0105/1831] Added undo and remove API --- chess/xboard.py | 30 ++++++++++++++++++++++++++++++ test.py | 21 +++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/chess/xboard.py b/chess/xboard.py index 591cfc50e..6201eeb42 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -608,6 +608,36 @@ def setboard(self, board, async_callback=None): command = self.command(" ".join(builder)) return self._queue_command(command, async_callback) + def undo(self, async_callback=None): + """ + Puts the engine in force mode and takes back one move. + + :return: Nothing + """ + self._assert_not_busy("undo") + + # Undo should be sent after force. + self.force() + + self.board.pop() + + command = self.command("undo") + return self._queue_command(command, async_callback) + + def remove(self, async_callback=None): + """ + Tells the engine to retract two moves (one from each side). + + :return: Nothing + """ + self._assert_not_busy("remove") + + self.board.pop() + self.board.pop() + + command = self.command("remove") + return self._queue_command(command, async_callback) + def memory(self, amount, async_callback=None): """ Set the maximum memory of the engines hash/pawn/bitbase/etc tables. diff --git a/test.py b/test.py index 6aed13ac6..6fcdb2526 100755 --- a/test.py +++ b/test.py @@ -2176,6 +2176,27 @@ def setUp(self): def tearDown(self): self.engine.quit() + def test_undo(self): + self.engine.new() + board = chess.Board() + board.set_fen("4r1k1/pQ3pp1/7p/4q3/4r3/P7/1P2nPPP/2BR1R1K b - - 0 1") + self.engine.setboard(board) + self.engine.force() + self.engine.usermove(chess.Move.from_uci("e5h2")) + self.engine.undo() + self.assertEqual(board.fen(), self.engine.board.fen()) + + def test_remove(self): + self.engine.new() + board = chess.Board() + board.set_fen("4r1k1/pQ3pp1/7p/4q3/4r3/P7/1P2nPPP/2BR1R1K b - - 0 1") + self.engine.setboard(board) + self.engine.force() + self.engine.usermove(chess.Move.from_uci("e5h2")) + self.engine.usermove(chess.Move.from_uci("h1h2")) + self.engine.remove() + self.assertEqual(board.fen(), self.engine.board.fen()) + def test_level(self): self.engine.new() self.engine.level(1, 0, 1, 0) From 0f77ca9864e07201f5d37bf038cc07b6818e138c Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Mon, 13 Nov 2017 19:20:49 +0530 Subject: [PATCH 0106/1831] Recursively passing async_callback --- chess/xboard.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/chess/xboard.py b/chess/xboard.py index 6201eeb42..db21c1210 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -524,9 +524,9 @@ def command(): raise EngineTerminatedException() # TODO: Remove perhaps? - self.post() - self.easy() - self.ping() + self.post(async_callback) + self.easy(async_callback) + self.ping(async_callback) return self._queue_command(command, async_callback) @@ -597,7 +597,7 @@ def setboard(self, board, async_callback=None): self._assert_not_busy("setboard") # Setboard should be sent after force. - self.force() + self.force(async_callback) builder = [] builder.append("setboard") @@ -617,7 +617,7 @@ def undo(self, async_callback=None): self._assert_not_busy("undo") # Undo should be sent after force. - self.force() + self.force(async_callback) self.board.pop() @@ -894,7 +894,7 @@ def command(): raise EngineTerminatedException() if self.auto_force: - self.force() + self.force(async_callback) try: self.board.push_uci(str(self.move)) @@ -954,7 +954,7 @@ def usermove(self, move, async_callback=None): builder.append("usermove") if self.auto_force: - self.force() + self.force(async_callback) elif not self.in_force: with self.state_changed: if not self.idle: From b3799e6e5d4058a60764f67901d2f09f0adccd7a Mon Sep 17 00:00:00 2001 From: Manik Charan Date: Mon, 13 Nov 2017 20:05:38 +0530 Subject: [PATCH 0107/1831] Revert "Recursively passing async_callback" This reverts commit 0f77ca9864e07201f5d37bf038cc07b6818e138c. --- chess/xboard.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/chess/xboard.py b/chess/xboard.py index db21c1210..6201eeb42 100644 --- a/chess/xboard.py +++ b/chess/xboard.py @@ -524,9 +524,9 @@ def command(): raise EngineTerminatedException() # TODO: Remove perhaps? - self.post(async_callback) - self.easy(async_callback) - self.ping(async_callback) + self.post() + self.easy() + self.ping() return self._queue_command(command, async_callback) @@ -597,7 +597,7 @@ def setboard(self, board, async_callback=None): self._assert_not_busy("setboard") # Setboard should be sent after force. - self.force(async_callback) + self.force() builder = [] builder.append("setboard") @@ -617,7 +617,7 @@ def undo(self, async_callback=None): self._assert_not_busy("undo") # Undo should be sent after force. - self.force(async_callback) + self.force() self.board.pop() @@ -894,7 +894,7 @@ def command(): raise EngineTerminatedException() if self.auto_force: - self.force(async_callback) + self.force() try: self.board.push_uci(str(self.move)) @@ -954,7 +954,7 @@ def usermove(self, move, async_callback=None): builder.append("usermove") if self.auto_force: - self.force(async_callback) + self.force() elif not self.in_force: with self.state_changed: if not self.idle: From b0231fd0576c705d1cce4e1cbae54277c7cd12e6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 13 Nov 2017 17:51:14 +0100 Subject: [PATCH 0108/1831] Support game export without tag roster --- chess/pgn.py | 17 ++++++++++++++++- test.py | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 9c2b365b3..8c764f55b 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -475,6 +475,15 @@ def from_board(cls, board): game.headers["Result"] = board.result() return game + @classmethod + def without_tag_roster(cls): + """Creates an empty game without the default 7 tag roster.""" + game = cls.__new__(cls) + super(Game, game).__init__() + game.headers = collections.OrderedDict() + game.errors = [] + return game + class BaseVisitor(object): """ @@ -635,6 +644,8 @@ def __init__(self, columns=80, headers=True, comments=True, variations=True): self.comments = comments self.variations = variations + self.found_headers = False + self.force_movenumber = True self.lines = [] @@ -658,12 +669,16 @@ def write_line(self, line=""): def end_game(self): self.write_line() + def begin_headers(self): + self.found_headers = False + def visit_header(self, tagname, tagvalue): if self.headers: + self.found_headers = True self.write_line("[{0} \"{1}\"]".format(tagname, tagvalue)) def end_headers(self): - if self.headers: + if self.found_headers: self.write_line() def begin_variation(self): diff --git a/test.py b/test.py index 6fcdb2526..a15666f9e 100755 --- a/test.py +++ b/test.py @@ -1721,6 +1721,10 @@ def test_exporter(self): game.accept(exporter) self.assertEqual(virtual_file.getvalue(), pgn + "\n\n") + def test_empty_game(self): + game = chess.pgn.Game.without_tag_roster() + self.assertEqual(str(game), "*") + def test_setup(self): game = chess.pgn.Game() self.assertEqual(game.board(), chess.Board()) From f50736b1672d6c616eee7dab93ed289c75745c03 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 13 Nov 2017 17:55:59 +0100 Subject: [PATCH 0109/1831] Do not add default tags in GameModelCreator (#212) --- chess/pgn.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 8c764f55b..0647c0aa1 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -564,7 +564,7 @@ class GameModelCreator(BaseVisitor): """ def __init__(self): - self.game = Game() + self.game = Game.without_tag_roster() self.variation_stack = [self.game] self.starting_comment = "" @@ -828,7 +828,7 @@ def read_game(handle, Visitor=GameModelCreator): """ visitor = Visitor() - dummy_game = Game() + dummy_game = Game.without_tag_roster() found_game = False found_content = False @@ -1037,14 +1037,6 @@ def scan_headers(handle): if tag_match: if game_pos is None: game_headers = collections.OrderedDict() - game_headers["Event"] = "?" - game_headers["Site"] = "?" - game_headers["Date"] = "????.??.??" - game_headers["Round"] = "?" - game_headers["White"] = "?" - game_headers["Black"] = "?" - game_headers["Result"] = "*" - game_pos = last_pos game_headers[tag_match.group(1)] = tag_match.group(2) From 5f37e7bd5bb6bb53e4e0a3e0dce4d50b9f86dcc0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 13 Nov 2017 21:40:49 +0100 Subject: [PATCH 0110/1831] Prepare changelog for 0.21.0 --- CHANGELOG.rst | 23 +++++++++++++++++++++++ chess/__init__.py | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e81afd0f1..699424242 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,29 @@ Changelog for python-chess ========================== +New in v0.21.0 +-------------- + +Bugfixes: + +* `Board.set_piece_at()` no longer shadows optional `promoted` + argument from `BaseBoard`. +* Fixed `ThreeCheckBoard.is_irreversible()` and + `ThreeCheckBoard._transposition_key()`. + +Changes: + +* `chess.pgn.read_pgn()` **no longer adds the default 7 tag roster.** + For example `game.headers["White"]` may now raise `KeyError` instead of + providing the default value `?`. Use `game.headers.get("White", "?")` for + equivalent behavior. +* Documentation fixes and tweaks by Boštjan Mejak. +* Changed unicode character for empty squares in `Board.unicode()`. + +New features: + +* XBoard: `white`, `black`, `random`, `nps`, `optim`, `undo`, `remove`. + New in v0.20.1 -------------- diff --git a/chess/__init__.py b/chess/__init__.py index d5a8d83d0..135fe4912 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "0.20.1" +__version__ = "0.21.0" import copy import re From 1b4e86e2c948da49265423f78202ea6a7706029e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 13 Nov 2017 21:40:49 +0100 Subject: [PATCH 0111/1831] Tweak changelog --- CHANGELOG.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 699424242..39e0905ff 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,7 +22,8 @@ Changes: New features: -* XBoard: `white`, `black`, `random`, `nps`, `optim`, `undo`, `remove`. +* XBoard: `white`, `black`, `random`, `nps`, `optim`, `undo`, `remove`. Thanks + to Manik Charan. New in v0.20.1 -------------- From f836693a933336578508744091e806135d426261 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 13 Nov 2017 21:56:25 +0100 Subject: [PATCH 0112/1831] release.py: ensure up to date before tagging --- release.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/release.py b/release.py index 46f3ba152..1b2f5f6f1 100755 --- a/release.py +++ b/release.py @@ -4,6 +4,7 @@ import os import chess import sys +import subprocess def system(command): @@ -18,6 +19,11 @@ def check_git(): system("git diff --exit-code") system("git diff --cached --exit-code") + system("git fetch origin") + behind = subprocess.check_output(["git", "rev-list", "--count", "master..origin/master"]) + if int(behind) > 0: + print("master is {} commits behind origin/master".format(int(behind))) + sys.exit(1) def test(): print("--- TEST ---------------------------------------------------------") @@ -105,8 +111,8 @@ def github_release(tagname): if __name__ == "__main__": check_docs() test() - check_changelog() check_git() + check_changelog() tagname = tag_and_push() update_rtd() pypi() From cf283216d464de8d038e764ab99177215a36fcdf Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 13 Nov 2017 21:57:32 +0100 Subject: [PATCH 0113/1831] release.py: do atomic push --- release.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.py b/release.py index 1b2f5f6f1..d2f4ebd6e 100755 --- a/release.py +++ b/release.py @@ -89,7 +89,7 @@ def tag_and_push(): sys.exit(1) system("git tag {0} -s -F {1}".format(tagname, release_filename)) - system("git push origin master {0}".format(tagname)) + system("git push --atomic origin master {0}".format(tagname)) return tagname From bb609abcd0fdc0e67beded94478eee61c1e07970 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 14 Nov 2017 01:12:16 +0100 Subject: [PATCH 0114/1831] Revert breaking changes from v0.21.0 (#212) --- CHANGELOG.rst | 18 ++++++++---------- chess/__init__.py | 2 +- chess/pgn.py | 4 ++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 39e0905ff..d99d72393 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,7 @@ Changelog for python-chess ========================== -New in v0.21.0 +New in v0.21.1 -------------- Bugfixes: @@ -11,20 +11,18 @@ Bugfixes: * Fixed `ThreeCheckBoard.is_irreversible()` and `ThreeCheckBoard._transposition_key()`. -Changes: - -* `chess.pgn.read_pgn()` **no longer adds the default 7 tag roster.** - For example `game.headers["White"]` may now raise `KeyError` instead of - providing the default value `?`. Use `game.headers.get("White", "?")` for - equivalent behavior. -* Documentation fixes and tweaks by Boštjan Mejak. -* Changed unicode character for empty squares in `Board.unicode()`. - New features: +* Added `Game.without_tag_roster()`. `chess.pgn.StringExporter()` can now + handle games without any headers. * XBoard: `white`, `black`, `random`, `nps`, `optim`, `undo`, `remove`. Thanks to Manik Charan. +Changes: + +* Documentation fixes and tweaks by Boštjan Mejak. +* Changed unicode character for empty squares in `Board.unicode()`. + New in v0.20.1 -------------- diff --git a/chess/__init__.py b/chess/__init__.py index 135fe4912..43900cd46 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "0.21.0" +__version__ = "0.21.1" import copy import re diff --git a/chess/pgn.py b/chess/pgn.py index 0647c0aa1..3495d167d 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -564,7 +564,7 @@ class GameModelCreator(BaseVisitor): """ def __init__(self): - self.game = Game.without_tag_roster() + self.game = Game() self.variation_stack = [self.game] self.starting_comment = "" @@ -1036,7 +1036,7 @@ def scan_headers(handle): tag_match = TAG_REGEX.match(line) if tag_match: if game_pos is None: - game_headers = collections.OrderedDict() + game_headers = Game().headers game_pos = last_pos game_headers[tag_match.group(1)] = tag_match.group(2) From a38a133446e0dfaa047734525257d3a65217a48c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 14 Nov 2017 12:40:58 +0100 Subject: [PATCH 0115/1831] Fix typo: optim -> otim --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d99d72393..5e506cde0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,7 +15,7 @@ New features: * Added `Game.without_tag_roster()`. `chess.pgn.StringExporter()` can now handle games without any headers. -* XBoard: `white`, `black`, `random`, `nps`, `optim`, `undo`, `remove`. Thanks +* XBoard: `white`, `black`, `random`, `nps`, `otim`, `undo`, `remove`. Thanks to Manik Charan. Changes: From fc696a4ef219f9342f5689141501c19d20b794a7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 17 Nov 2017 11:37:01 +0100 Subject: [PATCH 0116/1831] Make check gradient SVG Tiny compatible (fixes #223) --- chess/svg.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index d09f2d2eb..cc60d1b21 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -54,7 +54,7 @@ ARROWHEAD = """""" -CHECK_GRADIENT = """""" +CHECK_GRADIENT = """""" DEFAULT_COLORS = { "square light": "#ffce9e", @@ -63,12 +63,6 @@ "square light lastmove": "#cdd16a", } -DEFAULT_STYLE = """ -.check { - fill: url(#check_gradient); -} -""" - class Arrow(collections.namedtuple("Arrow", "tail head")): """Details of an arrow to be drawn.""" @@ -154,7 +148,8 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No margin = 20 if coordinates else 0 svg = _svg(8 * SQUARE_SIZE + 2 * margin, size) - ET.SubElement(svg, "style").text = DEFAULT_STYLE if style is None else style + if style: + ET.SubElement(svg, "style").text = style defs = ET.SubElement(svg, "defs") if board: @@ -182,8 +177,6 @@ def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=No fill_color = DEFAULT_COLORS[" ".join(cls)] cls.append(chess.SQUARE_NAMES[square]) - # Fill color is required for renderers without aabbccddeeffgghh1122334455667788 + \ No newline at end of file From 2cca78f92c5879c684986a87c404068e18a556d5 Mon Sep 17 00:00:00 2001 From: Tanmay Garg <40921153+tanmay2004@users.noreply.github.com> Date: Mon, 28 Sep 2020 00:45:57 +0530 Subject: [PATCH 1220/1831] Add missing class of parameter in docs --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index e99a6cb4e..dc287f968 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -187,7 +187,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, :param flipped: Pass ``True`` to flip the board. :param coordinates: Pass ``False`` to disable the coordinate margin. :param lastmove: A :class:`chess.Move` to be highlighted. - :param check: A square to be marked as check. + :param check: A :class:`chess.Square` to be marked as being under check. :param arrows: A list of :class:`~chess.svg.Arrow` objects like ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same From 5ec66262eaf9deee44018806b792806eb1f365cb Mon Sep 17 00:00:00 2001 From: Tanmay Garg <40921153+tanmay2004@users.noreply.github.com> Date: Mon, 28 Sep 2020 10:26:15 +0530 Subject: [PATCH 1221/1831] Update Ne4.svg With help from @PedanticHacker --- docs/Ne4.svg | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 185 insertions(+), 1 deletion(-) diff --git a/docs/Ne4.svg b/docs/Ne4.svg index bf9402aa1..f18f57b09 100644 --- a/docs/Ne4.svg +++ b/docs/Ne4.svg @@ -1 +1,185 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 0e96a7c18897effd41e7dc5ecc652bfd7e4d9b6a Mon Sep 17 00:00:00 2001 From: Tanmay Garg <40921153+tanmay2004@users.noreply.github.com> Date: Mon, 28 Sep 2020 13:15:34 +0530 Subject: [PATCH 1222/1831] Update svg.py --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index dc287f968..e3c9369e5 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -187,7 +187,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, :param flipped: Pass ``True`` to flip the board. :param coordinates: Pass ``False`` to disable the coordinate margin. :param lastmove: A :class:`chess.Move` to be highlighted. - :param check: A :class:`chess.Square` to be marked as being under check. + :param check: A :class:`chess.Square` to be marked indicating a check. :param arrows: A list of :class:`~chess.svg.Arrow` objects like ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same From d14d0da76732dc385b92f5fa8d26c5f1103da954 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 28 Sep 2020 14:04:15 +0200 Subject: [PATCH 1223/1831] Reorder chess.svg.board args --- chess/svg.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index e3c9369e5..c511e4696 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -169,12 +169,12 @@ def piece(piece: chess.Piece, size: Optional[int] = None) -> str: def board(board: Optional[chess.BaseBoard] = None, *, - squares: Optional[IntoSquareSet] = None, flipped: bool = False, coordinates: bool = True, lastmove: Optional[chess.Move] = None, check: Optional[Square] = None, arrows: Iterable[Union[Arrow, Tuple[Square, Square]]] = [], + squares: Optional[IntoSquareSet] = None, size: Optional[int] = None, colors: Dict[str, str] = {}, style: Optional[str] = None) -> str: @@ -183,7 +183,6 @@ def board(board: Optional[chess.BaseBoard] = None, *, :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or ``None`` (the default) for a chessboard without pieces. - :param squares: A :class:`chess.SquareSet` with selected squares. :param flipped: Pass ``True`` to flip the board. :param coordinates: Pass ``False`` to disable the coordinate margin. :param lastmove: A :class:`chess.Move` to be highlighted. @@ -192,6 +191,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same square is drawn as a circle, like ``[(chess.E2, chess.E2)]``. + :param squares: A :class:`chess.SquareSet` with selected squares. :param size: The size of the image in pixels (e.g., ``400`` for a 400 by 400 board) or ``None`` (the default) for no size limit. :param colors: A dictionary to override default colors. Possible keys are From 29bb0a0aff35dfdf477a52c421a6cc88dcc1d1d7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 28 Sep 2020 14:06:20 +0200 Subject: [PATCH 1224/1831] Do not refer to type aliases as :class:, yet --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index c511e4696..3edce4de1 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -186,7 +186,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, :param flipped: Pass ``True`` to flip the board. :param coordinates: Pass ``False`` to disable the coordinate margin. :param lastmove: A :class:`chess.Move` to be highlighted. - :param check: A :class:`chess.Square` to be marked indicating a check. + :param check: A square to be marked indicating a check. :param arrows: A list of :class:`~chess.svg.Arrow` objects like ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same From bcc69e95f24dcb31ee7dc9a4bad7d0ebc9be1530 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 28 Sep 2020 15:04:35 +0200 Subject: [PATCH 1225/1831] Factor out %cal and %csl handling --- chess/pgn.py | 35 +++++----------------------------- chess/svg.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 7412659f2..f9e4cd65d 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -441,21 +441,7 @@ def arrows(self) -> List[chess.svg.Arrow]: arrows = [] for match in ARROWS_REGEX.finditer(self.comment): for group in match.group(1).split(","): - color = "green" - if group[0] == "R": - color = "red" - elif group[0] == "Y": - color = "yellow" - elif group[0] == "B": - color = "blue" - - tail = chess.SQUARE_NAMES.index(group[1:3]) - if len(group) == 5: - head = chess.SQUARE_NAMES.index(group[3:5]) - else: - head = tail - - arrows.append(chess.svg.Arrow(tail, head, color=color)) + arrows.append(chess.svg.Arrow.from_pgn(group)) return arrows @@ -469,22 +455,11 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar for arrow in arrows: try: - tail, head, color = arrow.tail, arrow.head, arrow.color # type: ignore - if color == "red": - color = "R" - elif color == "yellow": - color = "Y" - elif color == "blue": - color = "B" - else: - color = "G" - except AttributeError: tail, head = arrow # type: ignore - color = "G" - if tail == head: - csl.append(f"{color}{chess.SQUARE_NAMES[tail]}") - else: - cal.append(f"{color}{chess.SQUARE_NAMES[tail]}{chess.SQUARE_NAMES[head]}") + arrow = chess.svg.Arrow(tail, head) + except TypeError: + pass + (csl if arrow.tail == arrow.head else cal).append(arrow.pgn()) self.comment = ARROWS_REGEX.sub("", self.comment).strip() diff --git a/chess/svg.py b/chess/svg.py index 3edce4de1..39182c091 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -92,9 +92,62 @@ def __init__(self, tail: Square, head: Square, *, color: str = "green") -> None: self.head = head self.color = color + def pgn(self) -> str: + """ + Returns the arrow in the format used by ``[%csl ...]`` and + ``[%cal ...]`` PGN annotations, e.g., ``Ga1`` or ``Ya2h2``. + + Colors other than ``red``, ``yellow`` and ``blue`` default to green. + """ + if self.color == "red": + color = "R" + elif self.color == "yellow": + color = "Y" + elif self.color == "blue": + color = "B" + else: + color = "G" + + if self.tail == self.head: + return f"{color}{chess.SQUARE_NAMES[self.tail]}" + else: + return f"{color}{chess.SQUARE_NAMES[self.tail]}{chess.SQUARE_NAMES[self.head]}" + + def __str__(self) -> str: + return self.pgn() + def __repr__(self) -> str: return f"Arrow({chess.SQUARE_NAMES[self.tail].upper()}, {chess.SQUARE_NAMES[self.head].upper()}, color={self.color!r})" + @classmethod + def from_pgn(cls, pgn: str) -> Arrow: + """ + Parses an arrow from the format used by ``[%csl ...]`` and + ``[%cal ...]`` PGN annotations, e.g., ``Ga1`` or ``Ya2h2``. + + Also allows skipping the color prefix, defaulting to green. + + :raises: :exc:`ValueError` if the format is invalid. + """ + if pgn.startswith("G"): + color = "green" + pgn = pgn[1:] + elif pgn.startswith("R"): + color = "red" + pgn = pgn[1:] + elif pgn.startswith("Y"): + color = "yellow" + pgn = pgn[1:] + elif pgn.startswith("B"): + color = "blue" + pgn = pgn[1:] + else: + color = "green" + + tail = chess.parse_square(pgn[:2]) + head = chess.parse_square(pgn[2:]) if len(pgn) > 2 else tail + return cls(tail, head, color=color) + class SvgWrapper(str): def _repr_svg_(self) -> SvgWrapper: From eed112a9ab03f4956764ce8ce2f1d4dbf3bb73aa Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 28 Sep 2020 15:54:51 +0200 Subject: [PATCH 1226/1831] Fix arrow ducktyping --- chess/pgn.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index f9e4cd65d..de1c5aaa6 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -450,8 +450,8 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar Replaces all valid ``[%csl ...]`` and ``[%cal ...]`` annotations in the comment of this node or adds new ones. """ - csl = [] - cal = [] + csl: List[str] = [] + cal: List[str] = [] for arrow in arrows: try: @@ -459,7 +459,7 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar arrow = chess.svg.Arrow(tail, head) except TypeError: pass - (csl if arrow.tail == arrow.head else cal).append(arrow.pgn()) + (csl if arrow.tail == arrow.head else cal).append(arrow.pgn()) # type: ignore self.comment = ARROWS_REGEX.sub("", self.comment).strip() From 1bb709822f792e263054123702e34770e4a07a1c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 12:21:34 +0200 Subject: [PATCH 1227/1831] Add chess.svg.board(..., orientation) --- chess/svg.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 39182c091..b82220ae1 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -26,7 +26,7 @@ import chess from typing import Dict, Iterable, Optional, Tuple, Union -from chess import IntoSquareSet, Square +from chess import Color, IntoSquareSet, Square SQUARE_SIZE = 45 @@ -222,22 +222,22 @@ def piece(piece: chess.Piece, size: Optional[int] = None) -> str: def board(board: Optional[chess.BaseBoard] = None, *, - flipped: bool = False, - coordinates: bool = True, + orientation: Color = chess.WHITE, lastmove: Optional[chess.Move] = None, check: Optional[Square] = None, arrows: Iterable[Union[Arrow, Tuple[Square, Square]]] = [], squares: Optional[IntoSquareSet] = None, size: Optional[int] = None, + coordinates: bool = True, colors: Dict[str, str] = {}, + flipped: bool = False, style: Optional[str] = None) -> str: """ Renders a board with pieces and/or selected squares as an SVG image. :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or ``None`` (the default) for a chessboard without pieces. - :param flipped: Pass ``True`` to flip the board. - :param coordinates: Pass ``False`` to disable the coordinate margin. + :param orientation: The point of view, defaulting to ``chess.WHITE``. :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked indicating a check. :param arrows: A list of :class:`~chess.svg.Arrow` objects like @@ -247,11 +247,13 @@ def board(board: Optional[chess.BaseBoard] = None, *, :param squares: A :class:`chess.SquareSet` with selected squares. :param size: The size of the image in pixels (e.g., ``400`` for a 400 by 400 board) or ``None`` (the default) for no size limit. + :param coordinates: Pass ``False`` to disable the coordinate margin. :param colors: A dictionary to override default colors. Possible keys are ``square light``, ``square dark``, ``square light lastmove``, ``square dark lastmove``, ``margin``, ``coord``, ``arrow green``, ``arrow blue``, ``arrow red``, and ``arrow yellow``. Values should look like ``#ffce9e`` (opaque) or ``#15781B80`` (transparent). + :param flipped: Pass ``True`` to flip the board. :param style: A CSS stylesheet to include in the SVG image. >>> import chess @@ -264,6 +266,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, .. image:: ../docs/Ne4.svg :alt: 8/8/8/8/4N3/8/8/8 """ + orientation ^= flipped margin = 15 if coordinates else 0 svg = _svg(8 * SQUARE_SIZE + 2 * margin, size) @@ -299,8 +302,8 @@ def board(board: Optional[chess.BaseBoard] = None, *, file_index = chess.square_file(square) rank_index = chess.square_rank(square) - x = (file_index if not flipped else 7 - file_index) * SQUARE_SIZE + margin - y = (7 - rank_index if not flipped else rank_index) * SQUARE_SIZE + margin + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin cls = ["square", "light" if chess.BB_LIGHT_SQUARES & bb else "dark"] if lastmove and square in [lastmove.from_square, lastmove.to_square]: @@ -350,11 +353,11 @@ def board(board: Optional[chess.BaseBoard] = None, *, if coordinates: coord_color, coord_opacity = _color(colors, "coord") for file_index, file_name in enumerate(chess.FILE_NAMES): - x = (file_index if not flipped else 7 - file_index) * SQUARE_SIZE + margin + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin svg.append(_coord(file_name, x, 0, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) svg.append(_coord(file_name, x, margin + 8 * SQUARE_SIZE, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) for rank_index, rank_name in enumerate(chess.RANK_NAMES): - y = (7 - rank_index if not flipped else rank_index) * SQUARE_SIZE + margin + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin svg.append(_coord(rank_name, 0, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) svg.append(_coord(rank_name, margin + 8 * SQUARE_SIZE, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) @@ -375,10 +378,10 @@ def board(board: Optional[chess.BaseBoard] = None, *, head_file = chess.square_file(head) head_rank = chess.square_rank(head) - xtail = margin + (tail_file + 0.5 if not flipped else 7.5 - tail_file) * SQUARE_SIZE - ytail = margin + (7.5 - tail_rank if not flipped else tail_rank + 0.5) * SQUARE_SIZE - xhead = margin + (head_file + 0.5 if not flipped else 7.5 - head_file) * SQUARE_SIZE - yhead = margin + (7.5 - head_rank if not flipped else head_rank + 0.5) * SQUARE_SIZE + xtail = margin + (tail_file + 0.5 if orientation else 7.5 - tail_file) * SQUARE_SIZE + ytail = margin + (7.5 - tail_rank if orientation else tail_rank + 0.5) * SQUARE_SIZE + xhead = margin + (head_file + 0.5 if orientation else 7.5 - head_file) * SQUARE_SIZE + yhead = margin + (7.5 - head_rank if orientation else head_rank + 0.5) * SQUARE_SIZE if (head_file, head_rank) == (tail_file, tail_rank): ET.SubElement(svg, "circle", _attrs({ From a3b4ff0433c3d1d739fbbcef0cfc66aa5fbca3ab Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 12:53:56 +0200 Subject: [PATCH 1228/1831] Do not force pawn move for fully specified SAN (closes #266) --- chess/__init__.py | 31 ++++++++++++++++++++----------- data/pgn/uci-moves.pgn | 9 +++++++++ test.py | 6 ++++++ 3 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 data/pgn/uci-moves.pgn diff --git a/chess/__init__.py b/chess/__init__.py index 04e538db5..522ccf687 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2817,7 +2817,7 @@ def parse_san(self, san: str) -> Move: raise ValueError(f"invalid san: {san!r}") - # Get target square. + # Get target square. Mask our own pieces to exclude castling moves. to_square = SQUARE_NAMES.index(match.group(4)) to_mask = BB_SQUARES[to_square] & ~self.occupied_co[self.turn] @@ -2825,20 +2825,29 @@ def parse_san(self, san: str) -> Move: p = match.group(5) promotion = p and PIECE_SYMBOLS.index(p[-1].lower()) + # Filter by original square. + from_mask = BB_ALL + if match.group(2): + from_file = FILE_NAMES.index(match.group(2)) + from_mask &= BB_FILES[from_file] + if match.group(3): + from_rank = int(match.group(3)) - 1 + from_mask &= BB_RANKS[from_rank] + # Filter by piece type. if match.group(1): piece_type = PIECE_SYMBOLS.index(match.group(1).lower()) - from_mask = self.pieces_mask(piece_type, self.turn) + from_mask &= self.pieces_mask(piece_type, self.turn) + elif match.group(2) and match.group(3): + # Allow fully specified moves, even if they are not pawn moves, + # including castling moves. + move = self.find_move(square(from_file, from_rank), to_square, promotion) + if move.promotion == promotion: + return move + else: + raise ValueError(f"missing promotion piece type: {san!r} in {self.fen()}") else: - from_mask = self.pawns - - # Filter by source file. - if match.group(2): - from_mask &= BB_FILES[FILE_NAMES.index(match.group(2))] - - # Filter by source rank. - if match.group(3): - from_mask &= BB_RANKS[int(match.group(3)) - 1] + from_mask &= self.pawns # Match legal moves. matched_move = None diff --git a/data/pgn/uci-moves.pgn b/data/pgn/uci-moves.pgn new file mode 100644 index 000000000..32c70f235 --- /dev/null +++ b/data/pgn/uci-moves.pgn @@ -0,0 +1,9 @@ +[Event "CCRL 40/4"] +[Site "CCRL"] +[Date "2006.05.24"] +[Round "1"] +[White "Aristarch 4.50"] +[Black "Chess Tiger 15"] +[Result "1/2-1/2"] + +g1f3 c7c5 e2e4 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 e7e6 c1e3 a7a6 g2g4 h7h6 d1f3 b8d7 f1e2 d8c7 f3h3 d6d5 e4d5 f8b4 e3d2 c7b6 d5e6 b6d4 e6d7 c8d7 e1c1 d4b6 d2e3 b4c5 h3g3 c5e3 f2e3 e8g8 g4g5 h6g5 g3g5 f8e8 d1d3 f6h7 c3d5 h7g5 d5b6 d7c6 h1g1 g5h3 g1g3 h3f2 b6a8 f2d3 c2d3 e8a8 g3g5 g7g6 g5c5 g8g7 h2h4 a8h8 h4h5 f7f5 d3d4 g6h5 d4d5 c6e8 c5c7 e8f7 d5d6 g7f6 d6d7 h8d8 c7b7 f6e7 e2a6 f7d5 b7b6 d8d7 a6e2 d7c7 c1d2 d5a2 b6h6 c7d7 d2e1 a2b3 h6h7 e7e6 h7d7 e6d7 e2h5 d7e6 h5d1 b3a2 e1f2 e6e5 f2f3 a2f7 d1c2 f7d5 f3g3 d5c4 c2b1 c4d5 b1d3 d5b3 d3b5 e5e4 g3f2 f5f4 b5c6 e4e5 e3e4 1/2-1/2 diff --git a/test.py b/test.py index e75054c1b..d2e73caac 100755 --- a/test.py +++ b/test.py @@ -2595,6 +2595,12 @@ def test_z0(self): board = game.end().board() self.assertEqual(board.fen(), "5rk1/2p1R2p/p5pb/2PPR3/8/2Q2B2/5P2/4K2q w - - 3 43") + def test_uci_moves(self): + with open("data/pgn/uci-moves.pgn") as pgn: + game = chess.pgn.read_game(pgn) + board = game.end().board() + self.assertEqual(board.fen(), "8/8/2B5/4k3/4Pp2/1b6/1P3K2/8 b - - 0 57") + def test_wierd_header(self): pgn = io.StringIO(r"""[Black "[=0040.34h5a4]"]""") game = chess.pgn.read_game(pgn) From 797d178d3c7703d180c91645220f4a3626fd33f5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 12:57:41 +0200 Subject: [PATCH 1229/1831] Allow 0000 and @@@@ as null moves in PGN --- chess/__init__.py | 2 +- chess/pgn.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 522ccf687..d3ca3e7ea 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2812,7 +2812,7 @@ def parse_san(self, san: str) -> Move: match = SAN_REGEX.match(san) if not match: # Null moves. - if san in ["--", "Z0"]: + if san in ["--", "Z0", "0000", "@@@@"]: return Move.null() raise ValueError(f"invalid san: {san!r}") diff --git a/chess/pgn.py b/chess/pgn.py index de1c5aaa6..cbdefdea2 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -97,6 +97,8 @@ |[PNBRQK]?@[a-h][1-8] |-- |Z0 + |0000 + |@@@@ |O-O(?:-O)? |0-0(?:-0)? ) From a3594f1f2732a0601dbd482d5bcf432bc43e6a88 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 13:04:50 +0200 Subject: [PATCH 1230/1831] Simplify parse_xboard --- chess/__init__.py | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index d3ca3e7ea..1e70916e8 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2814,8 +2814,10 @@ def parse_san(self, san: str) -> Move: # Null moves. if san in ["--", "Z0", "0000", "@@@@"]: return Move.null() - - raise ValueError(f"invalid san: {san!r}") + elif "," in san: + raise ValueError(f"unsupported multi-leg move: {san!r}") + else: + raise ValueError(f"invalid san: {san!r}") # Get target square. Mask our own pieces to exclude castling moves. to_square = SQUARE_NAMES.index(match.group(4)) @@ -2940,31 +2942,9 @@ def xboard(self, move: Move, chess960: Optional[bool] = None) -> str: else: return "O-O-O" - def parse_xboard(self, xboard: str) -> Move: - if xboard == "@@@@": - return Move.null() - elif "," in xboard: - raise ValueError(f"unsupported multi-leg xboard move: {xboard!r}") - - try: - move = Move.from_uci(xboard) - move = self._to_chess960(move) - move = self._from_chess960(self.chess960, move.from_square, move.to_square, move.promotion, move.drop) - if not self.is_legal(move): - raise ValueError(f"illegal xboard move: {xboard!r} in {self.fen()}") - return move - except ValueError: - pass + parse_xboard = parse_san - try: - return self.parse_san(xboard) - except ValueError: - raise ValueError(f"invalid or illegal xboard move: {xboard!r} in {self.fen()}") - - def push_xboard(self, xboard: str) -> Move: - move = self.parse_xboard(xboard) - self.push(move) - return move + push_xboard = push_san def is_en_passant(self, move: Move) -> bool: """Checks if the given pseudo-legal move is an en passant capture.""" From 41042967d24981c8d0bd9ce24c571f1a3a62211f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 13:09:11 +0200 Subject: [PATCH 1231/1831] Do not strip trailing space from drop notation --- chess/variant.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/variant.py b/chess/variant.py index fab1d2aea..6b774ea75 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -761,7 +761,7 @@ def generate_legal_moves(self, from_mask: chess.Bitboard = chess.BB_ALL, to_mask def parse_san(self, san: str) -> chess.Move: if "@" in san: - uci = san.rstrip("+# ") + uci = san.rstrip("+#") if uci[0] == "@": uci = "P" + uci move = chess.Move.from_uci(uci) From 6d34b24104ac5fd675dda4270c05b624570d5383 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 13:11:11 +0200 Subject: [PATCH 1232/1831] Fix parse_xboard delegation --- chess/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 1e70916e8..1c5a1d74a 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2942,7 +2942,8 @@ def xboard(self, move: Move, chess960: Optional[bool] = None) -> str: else: return "O-O-O" - parse_xboard = parse_san + def parse_xboard(self, xboard: str) -> Move: + return self.parse_san(xboard) push_xboard = push_san From 1d49c3ff1f6c5bd17bcb05598611dcd03c2ebfa7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 13:13:20 +0200 Subject: [PATCH 1233/1831] Fix promotion typing --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 1c5a1d74a..8bc0e65cb 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2825,7 +2825,7 @@ def parse_san(self, san: str) -> Move: # Get the promotion piece type. p = match.group(5) - promotion = p and PIECE_SYMBOLS.index(p[-1].lower()) + promotion = PIECE_SYMBOLS.index(p[-1].lower()) if p else None # Filter by original square. from_mask = BB_ALL From 9f0286aaa546d4ccf39b48ec9a38e8a3077ce1ff Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 13:25:16 +0200 Subject: [PATCH 1234/1831] Add deprecation notices (#659) --- chess/pgn.py | 5 +++++ chess/svg.py | 3 +++ 2 files changed, 8 insertions(+) diff --git a/chess/pgn.py b/chess/pgn.py index cbdefdea2..0ecf02dbe 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -916,6 +916,11 @@ def parse_san(self, board: chess.Board, san: str) -> chess.Move: You can override the default implementation to work around specific quirks of your input format. + + .. deprecated:: 1.1 + This method is very limited, because it depends too strongly on the + rest of the parser. Instead, please report common quirks so that + workarounds can be added for everyone. """ return board.parse_san(san) diff --git a/chess/svg.py b/chess/svg.py index b82220ae1..dd1f0de63 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -265,6 +265,9 @@ def board(board: Optional[chess.BaseBoard] = None, *, .. image:: ../docs/Ne4.svg :alt: 8/8/8/8/4N3/8/8/8 + + .. deprecated:: 1.1 + Use *orientation* with a color instead of the *flipped* toggle. """ orientation ^= flipped margin = 15 if coordinates else 0 From d5ae00da8d949dfcea3bc3bc8a9d62986bb235f2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 13:32:50 +0200 Subject: [PATCH 1235/1831] Limit size of example board --- chess/svg.py | 2 +- docs/Ne4.svg | 186 +-------------------------------------------------- 2 files changed, 2 insertions(+), 186 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index dd1f0de63..59fca6a4a 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -261,7 +261,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, >>> >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1") >>> squares = board.attacks(chess.E4) - >>> chess.svg.board(board=board, squares=squares) # doctest: +SKIP + >>> chess.svg.board(board, squares=squares, size=350) # doctest: +SKIP .. image:: ../docs/Ne4.svg :alt: 8/8/8/8/4N3/8/8/8 diff --git a/docs/Ne4.svg b/docs/Ne4.svg index f18f57b09..65dab1125 100644 --- a/docs/Ne4.svg +++ b/docs/Ne4.svg @@ -1,185 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file From d85b7b807ee67142a813510c7e42bf3a8b4e79fe Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 29 Sep 2020 16:34:33 +0200 Subject: [PATCH 1236/1831] Prepare 1.1.0 --- CHANGELOG.rst | 15 +++++++++++++++ chess/__init__.py | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0a451b701..59203f672 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,21 @@ Changelog for python-chess ========================== +New in v1.1.0 +------------- + +New features: + +* Added `chess.svg.board(..., orientation)`. This is a more idiomatic way to + set the board orientation than `flipped`. +* Added `chess.svg.Arrow.pgn()` and `chess.svg.Arrow.from_pgn()`. + +Changes: + +* Further relaxed `chess.Board.parse_san()`. Now accepts fully specified moves + like `e2e4`, even if that is not a pawn move, castling notation with zeros, + null moves in UCI notation, and null moves in XBoard notation. + New in v1.0.1 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index 8bc0e65cb..4975d0185 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.0.1" +__version__ = "1.1.0" import collections import copy From b4f77d5662954ddf6ad1f3b817a55bf7f6314d32 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 1 Oct 2020 14:21:20 +0200 Subject: [PATCH 1237/1831] Clarify BaseVisitor.parse_san() limitations (closes #662) --- chess/pgn.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 0ecf02dbe..a4f0f7eaa 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -918,9 +918,10 @@ def parse_san(self, board: chess.Board, san: str) -> chess.Move: quirks of your input format. .. deprecated:: 1.1 - This method is very limited, because it depends too strongly on the - rest of the parser. Instead, please report common quirks so that - workarounds can be added for everyone. + This method is very limited, because it is only called on moves + that the parser recognizes in the first place. Instead of adding + workarounds here, please report common quirks so that + they can be handled for everyone. """ return board.parse_san(san) From 59d7450145cbda65c9118ac4e7c5f00ba0fe8214 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 3 Oct 2020 09:54:53 +0200 Subject: [PATCH 1238/1831] Use autodoc_type_aliases --- docs/conf.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 40b9092f3..2079ddd9f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,17 +2,22 @@ import os import typing -# Do not resolve some type aliases. +# Do not resolve these. +autodoc_type_aliases = { + "Square": "chess.Square", + "Color": "chess.Color", + "PieceType": "chess.PieceType", + "Bitboard": "chess.Bitboard", + "IntoSquareSet": "chess.IntoSquareSet", +} + +# Hack to not resolve autodoc_type_aliases before Sphinx 3.3. # See https://github.com/sphinx-doc/sphinx/issues/6518. _get_type_hints = typing.get_type_hints def get_type_hints(obj, globalns=None, localns=None): if localns is None: localns = {} - localns["Square"] = "chess.Square" - localns["Color"] = "chess.Color" - localns["PieceType"] = "chess.PieceType" - localns["Bitboard"] = "chess.Bitboard" - localns["IntoSquareSet"] = "chess.IntoSquareSet" + localns.update(autodoc_type_aliases) return _get_type_hints(obj, globalns, localns) typing.get_type_hints = get_type_hints From ec90b9b7cfc8ed3b4aa08824e86c643beaa723cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sun, 4 Oct 2020 14:42:13 +0200 Subject: [PATCH 1239/1831] Stylistic tweaks for docs/conf.py --- docs/conf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 2079ddd9f..bf1f19db7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,12 +22,12 @@ def get_type_hints(obj, globalns=None, localns=None): typing.get_type_hints = get_type_hints # Import the chess module. -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath("..")) import chess # Autodoc. extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode"] -autodoc_member_order = 'bysource' +autodoc_member_order = "bysource" # The suffix of source filenames. source_suffix = ".rst" @@ -51,5 +51,5 @@ def get_type_hints(obj, globalns=None, localns=None): pygments_style = "sphinx" # The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. +# a list of built-in themes. html_theme = "default" From cf54eb7808a8a70c45bfc7a6ecccbc4b82279ed2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 19 Oct 2020 10:51:55 +0200 Subject: [PATCH 1240/1831] Add Score.score(*, mate_score: int) -> int overload --- chess/engine.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index 47325326a..34932b4cc 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -407,6 +407,10 @@ class Score(abc.ABC): MateGiven """ + @typing.overload + def score(self, *, mate_score: int) -> int: ... + @typing.overload + def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: ... @abc.abstractmethod def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: """ @@ -520,6 +524,10 @@ def __init__(self, moves: int) -> None: def mate(self) -> int: return self.moves + @typing.overload + def score(self, *, mate_score: int) -> int: ... + @typing.overload + def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: ... def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: if mate_score is None: return None @@ -550,6 +558,10 @@ class MateGivenType(Score): def mate(self) -> int: return 0 + @typing.overload + def score(self, *, mate_score: int) -> int: ... + @typing.overload + def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: ... def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: return mate_score From db8ab8c3dc8d33fc47e6ecf2bc93189b2139e648 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 19 Oct 2020 11:43:45 +0200 Subject: [PATCH 1241/1831] Score has __pos__, __neg__, __abs__ --- chess/engine.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index 34932b4cc..52a112dff 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -446,6 +446,14 @@ def is_mate(self) -> bool: def __neg__(self) -> Score: pass + @abc.abstractmethod + def __pos__(self) -> Score: + pass + + @abc.abstractmethod + def __abs__(self) -> Score: + pass + def _score_tuple(self) -> Tuple[bool, bool, bool, int, Optional[int]]: mate = self.mate() return ( From 00089bf65dabe37ad57f2fa797fde0b3e4781350 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 19 Oct 2020 12:04:21 +0200 Subject: [PATCH 1242/1831] Use ... instead of pass for abstract method body --- chess/engine.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 52a112dff..9ad2a89a6 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -444,15 +444,15 @@ def is_mate(self) -> bool: @abc.abstractmethod def __neg__(self) -> Score: - pass + ... @abc.abstractmethod def __pos__(self) -> Score: - pass + ... @abc.abstractmethod def __abs__(self) -> Score: - pass + ... def _score_tuple(self) -> Tuple[bool, bool, bool, int, Optional[int]]: mate = self.mate() From 1cfb9c2ecc9454f126e1d3f3ff04a67cb71a1fb1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 19 Oct 2020 18:21:23 +0200 Subject: [PATCH 1243/1831] Add documentation URL to package meta data --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index 5f418cbf9..d0ceefbe1 100755 --- a/setup.py +++ b/setup.py @@ -108,4 +108,7 @@ def read_description(): "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed", ], + project_urls={ + "Documentation": "https://python-chess.readthedocs.io", + }, ) From 0b4be21ade1e71750322d1e55ed6d2b9d61d187f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 20 Oct 2020 16:52:04 +0200 Subject: [PATCH 1244/1831] Remove less specific trove classifier --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index d0ceefbe1..b0d5b0cd4 100755 --- a/setup.py +++ b/setup.py @@ -99,10 +99,9 @@ def read_description(): "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3 :: Only", "Topic :: Games/Entertainment :: Board Games", "Topic :: Games/Entertainment :: Turn Based Strategy", "Topic :: Software Development :: Libraries :: Python Modules", From 37ef4a41f70e53d14c98f105535d46c00d64e854 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 20 Oct 2020 21:29:44 +0200 Subject: [PATCH 1245/1831] Tweak setup.py --- MANIFEST.in | 2 -- setup.py | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 0265f5ea9..18e068342 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1 @@ -include README.rst include CHANGELOG.rst -include LICENSE.txt diff --git a/setup.py b/setup.py index b0d5b0cd4..e3057a29d 100755 --- a/setup.py +++ b/setup.py @@ -83,14 +83,15 @@ def read_description(): long_description=read_description(), long_description_content_type="text/x-rst", license="GPL-3.0+", + license_file="LICENSE.txt", keywords="chess fen epd pgn polyglot syzygy gaviota uci xboard", url="https://github.com/niklasf/python-chess", + packages=["chess"], + test_suite="test", zip_safe=False, # For mypy package_data={ "chess": ["py.typed"], }, - packages=["chess"], - test_suite="test", python_requires=">=3.7", classifiers=[ "Development Status :: 5 - Production/Stable", @@ -98,10 +99,10 @@ def read_description(): "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Operating System :: OS Independent", - "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Topic :: Games/Entertainment :: Board Games", "Topic :: Games/Entertainment :: Turn Based Strategy", "Topic :: Software Development :: Libraries :: Python Modules", From 83321c7d9aabb479d3469c1d4a08d91f5d0c1936 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 12:14:24 +0200 Subject: [PATCH 1246/1831] Implement chess.pgn.GameNode.turn() --- chess/pgn.py | 20 +++++++++++++++++++- test.py | 16 ++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index a4f0f7eaa..74b164485 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -29,7 +29,7 @@ import chess.svg from typing import Any, Callable, Dict, Generic, Iterable, Iterator, List, Mapping, MutableMapping, Set, TextIO, Tuple, Type, TypeVar, Optional, Union -from chess import Square +from chess import Color, Square LOGGER = logging.getLogger(__name__) @@ -212,6 +212,17 @@ def _move(self) -> chess.Move: assert self.move is not None, "cannot get move of dangling GameNode" return self.move + def _turn(self) -> Color: + assert False, "cannot get turn of dangling GameNode" + + def turn(self) -> Color: + flip = False + node = self + while node.parent is not None: + flip = not flip + node = node.parent + return node._turn() ^ flip + def san(self) -> str: """ Gets the standard algebraic notation of the move leading to this node. @@ -636,6 +647,13 @@ def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str def _board(self) -> chess.Board: return self.headers.board() + def _turn(self) -> Color: + # Optimization: Parse FEN only for special starting positions. + if "FEN" in self.headers or "Variant" in self.headers: + return self.board().turn + else: + return chess.WHITE + def setup(self, board: Union[chess.Board, str]) -> None: """ Sets up a specific starting position. This sets (or resets) the diff --git a/test.py b/test.py index d2e73caac..b47577d73 100755 --- a/test.py +++ b/test.py @@ -2710,6 +2710,22 @@ def test_annotations(self): game.set_clock(-70) self.assertEqual(game.clock(), 0) # Clamped + def test_node_turn(self): + game = chess.pgn.Game() + self.assertEqual(game.turn(), chess.WHITE) + node = game.add_variation(chess.Move.from_uci("a2a3")) + self.assertEqual(node.turn(), chess.BLACK) + node = node.add_variation(chess.Move.from_uci("a7a6")) + self.assertEqual(node.turn(), chess.WHITE) + + game = chess.pgn.Game() + game.setup("4k3/8/8/8/8/8/8/4K3 b - - 7 6") + self.assertEqual(game.turn(), chess.BLACK) + node = game.add_variation(chess.Move.from_uci("e8e7")) + self.assertEqual(node.turn(), chess.WHITE) + node = node.add_variation(chess.Move.from_uci("e1e2")) + self.assertEqual(node.turn(), chess.BLACK) + @unittest.skipIf(sys.platform == "win32" and (3, 8, 0) <= sys.version_info < (3, 8, 1), "https://bugs.python.org/issue34679") class EngineTestCase(unittest.TestCase): From 37ae9bf40d411729b856cc68e1d30e31a58359b9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 12:20:18 +0200 Subject: [PATCH 1247/1831] Mainline is an iterable, not an iterator (fixes #672) --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 74b164485..bd9ea1e66 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -381,11 +381,11 @@ def add_main_variation(self, move: chess.Move, *, comment: str = "") -> GameNode return node def mainline(self) -> Mainline[GameNode]: - """Returns an iterator over the mainline starting after this node.""" + """Returns an iterable over the mainline starting after this node.""" return Mainline(self, lambda node: node) def mainline_moves(self) -> Mainline[chess.Move]: - """Returns an iterator over the main moves after this node.""" + """Returns an iterable over the main moves after this node.""" return Mainline(self, lambda node: node._move()) def add_line(self, moves: Iterable[chess.Move], *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> GameNode: From 1e18633b1f3fb44dfa8952cce6f983cefa486c69 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 12:41:41 +0200 Subject: [PATCH 1248/1831] Implement Board.ply() --- chess/__init__.py | 12 ++++++++++++ test.py | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index 4975d0185..737f28719 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1474,6 +1474,18 @@ def root(self: BoardT) -> BoardT: else: return self.copy(stack=False) + def ply(self) -> int: + """ + Returns the number of half-moves since the start of the game, as + indicated by :data:`~chess.Board.fullmove_number` and + :data:`~chess.Board.turn`. + + If moves have been pushed from the beginning, this is usually equal to + ``len(board.move_stack)``. But note that a board can be set up with + arbitrary starting positions, and the stack can be cleared. + """ + return 2 * (self.fullmove_number - 1) + (self.turn == BLACK) + def remove_piece_at(self, square: Square) -> Optional[Piece]: piece = super().remove_piece_at(square) self.clear_stack() diff --git a/test.py b/test.py index b47577d73..90cb67e89 100755 --- a/test.py +++ b/test.py @@ -205,6 +205,18 @@ def test_empty(self): self.assertEqual(board.fen(), "8/8/8/8/8/8/8/8 w - - 0 1") self.assertEqual(board, chess.Board(None)) + def test_ply(self): + board = chess.Board() + self.assertEqual(board.ply(), 0) + board.push_san("d4") + self.assertEqual(board.ply(), 1) + board.push_san("d5") + self.assertEqual(board.ply(), 2) + board.clear_stack() + self.assertEqual(board.ply(), 2) + board.push_san("Nf3") + self.assertEqual(board.ply(), 3) + def test_from_epd(self): base_epd = "rnbqkb1r/ppp1pppp/5n2/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq -" board, ops = chess.Board.from_epd(base_epd + " ce 55;") From 10bbf3ee328a31480d8011f0fb8112b1758afd20 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 12:49:01 +0200 Subject: [PATCH 1249/1831] Implement GameNode.turn() in terms of ply() --- chess/pgn.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index bd9ea1e66..2f36c73fb 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -212,16 +212,19 @@ def _move(self) -> chess.Move: assert self.move is not None, "cannot get move of dangling GameNode" return self.move - def _turn(self) -> Color: - assert False, "cannot get turn of dangling GameNode" + def _ply(self) -> int: + assert False, "cannot get ply of dangling GameNode" - def turn(self) -> Color: - flip = False + def ply(self) -> int: + ply = 0 node = self while node.parent is not None: - flip = not flip + ply += 1 node = node.parent - return node._turn() ^ flip + return node._ply() + ply + + def turn(self) -> Color: + return self.ply() % 2 == 0 def san(self) -> str: """ @@ -647,12 +650,9 @@ def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str def _board(self) -> chess.Board: return self.headers.board() - def _turn(self) -> Color: - # Optimization: Parse FEN only for special starting positions. - if "FEN" in self.headers or "Variant" in self.headers: - return self.board().turn - else: - return chess.WHITE + def _ply(self) -> Color: + # Optimization: Parse FEN only for custom starting positions. + return self.board().ply() if "FEN" in self.headers else 0 def setup(self, board: Union[chess.Board, str]) -> None: """ From 86b48893dea27f600d633fcea8340c67d7de7ab3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 13:11:29 +0200 Subject: [PATCH 1250/1831] Document GameNode.ply() and GameNode.turn() --- chess/pgn.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 2f36c73fb..80bdcf22f 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -216,6 +216,14 @@ def _ply(self) -> int: assert False, "cannot get ply of dangling GameNode" def ply(self) -> int: + """ + Returns the number of half-moves up to this node, as indicated by + fullmove number and turn of the position. + See :func:`chess.Board.ply()`. + + Usually this is equal to the number of parent nodes, but it may be + more if the game was started from a custom position. + """ ply = 0 node = self while node.parent is not None: @@ -224,6 +232,9 @@ def ply(self) -> int: return node._ply() + ply def turn(self) -> Color: + """ + Gets the color to move at this node. See :data:`chess.Board.turn`. + """ return self.ply() % 2 == 0 def san(self) -> str: @@ -650,7 +661,7 @@ def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str def _board(self) -> chess.Board: return self.headers.board() - def _ply(self) -> Color: + def _ply(self) -> int: # Optimization: Parse FEN only for custom starting positions. return self.board().ply() if "FEN" in self.headers else 0 From 8460c63bde39dc2b999225d3d236b78a2c24a808 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 13:26:05 +0200 Subject: [PATCH 1251/1831] Remove PovScore.__str__() --- chess/engine.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 9ad2a89a6..cbb4b7b59 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -370,9 +370,6 @@ def is_mate(self) -> bool: def __repr__(self) -> str: return "PovScore({!r}, {})".format(self.relative, "WHITE" if self.turn else "BLACK") - def __str__(self) -> str: - return str(self.relative) - def __eq__(self, other: object) -> bool: if isinstance(other, PovScore): return self.white() == other.white() From e32f9e15e85f75c8d981d0a272a73cb3926c4856 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 14:19:28 +0200 Subject: [PATCH 1252/1831] Use GameNode.turn() in GameNode.eval() The returned PovScore is now from the point of view of the player to move. Taking the turn into account allows resolving the ambiguity of [%eval #0]. Previously None was returned in that case. --- chess/pgn.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 80bdcf22f..1696f4ee6 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -432,11 +432,21 @@ def eval(self) -> Optional[chess.engine.PovScore]: match = EVAL_REGEX.search(self.comment) if not match: return None + + turn = self.turn() + if match.group(1): mate = int(match.group(1)) - return chess.engine.PovScore(chess.engine.Mate(mate), chess.WHITE) if mate else None + score: chess.engine.Score = chess.engine.Mate(mate) + if mate == 0: + # Resolve this ambiguity in the specification in favor of + # standard chess: The player to move after mate is the player + # who has been mated. + return chess.engine.PovScore(score, turn) else: - return chess.engine.PovScore(chess.engine.Cp(int(float(match.group(2)) * 100)), chess.WHITE) + score = chess.engine.Cp(int(float(match.group(2)) * 100)) + + return chess.engine.PovScore(score if turn else -score, turn) def set_eval(self, score: Optional[chess.engine.PovScore]) -> None: """ From 9232c9c89bcda4a0c064e5826aa14dedaec4a1b0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 14:31:53 +0200 Subject: [PATCH 1253/1831] Try Python 3.9 on readthedocs --- .readthedocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 11760dd7d..e6efe594c 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,6 +1,6 @@ version: 1 python: - version: 3.8 + version: 3.9 install: - requirements: docs/requirements.txt - method: setuptools From 53e97f3d39e8b7c320d2c1eb313adf0421da331c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 14:33:19 +0200 Subject: [PATCH 1254/1831] Tweak engine docs: Python 3.7 is now required anyway --- docs/engine.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/engine.rst b/docs/engine.rst index cea27923c..edb1b88a8 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -13,8 +13,7 @@ both kinds of engines. on your system. The preferred way to use the API is with an -`asyncio `_ event loop -(examples show usage with Python 3.7 or later). +`asyncio `_ event loop. The examples also show a synchronous wrapper :class:`~chess.engine.SimpleEngine` that automatically spawns an event loop in the background. From 83317b34a1752fb31095470b830f144c95592698 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 14:34:37 +0200 Subject: [PATCH 1255/1831] Revert "Try Python 3.9 on readthedocs" This reverts commit 9232c9c89bcda4a0c064e5826aa14dedaec4a1b0. --- .readthedocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index e6efe594c..11760dd7d 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,6 +1,6 @@ version: 1 python: - version: 3.9 + version: 3.8 install: - requirements: docs/requirements.txt - method: setuptools From facfa00dbc3ca0ee68db24342906725cc507f141 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 14:53:24 +0200 Subject: [PATCH 1256/1831] Make chess.engine.InfoDict a separate item in the documentation --- chess/engine.py | 14 ++++++++++++-- docs/engine.rst | 12 ++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index cbb4b7b59..6ec175438 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -279,7 +279,17 @@ def __repr__(self) -> str: try: class InfoDict(typing.TypedDict, total=False): - """Dictionary of extra information sent by the engine.""" + """ + Dictionary of aggregated information sent by the engine. + + Commonly used keys are: ``score`` (a :class:`~chess.engine.PovScore`), + ``pv`` (a list of :class:`~chess.Move` objects), ``depth``, + ``seldepth``, ``time`` (in seconds), ``nodes``, ``nps``, ``multipv``. + + Others: ``thits``, ``currmove``, ``currmovenumber``, ``hashfull``, + ``cpuload``, ``refutation``, ``currline``, ``ebf``, ``wdl``, and + ``string``. + """ score: PovScore pv: List[chess.Move] depth: int @@ -813,7 +823,7 @@ async def analyse(self, board: chess.Board, limit: Limit, *, multipv: Optional[i async def analyse(self, board: chess.Board, limit: Limit, *, multipv: Optional[int] = None, game: object = None, info: Info = INFO_ALL, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> Union[List[InfoDict], InfoDict]: """ Analyses a position and returns a dictionary of - `information <#chess.engine.PlayResult.info>`_. + :class:`information `. :param board: The position to analyse. The entire move stack will be sent to the engine. diff --git a/docs/engine.rst b/docs/engine.rst index edb1b88a8..ae2ad51d4 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -124,14 +124,8 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. .. py:attribute:: info :type: chess.engine.InfoDict - A dictionary of extra information sent by the engine. Commonly used - keys are: ``score`` (a :class:`~chess.engine.PovScore`), - ``pv`` (a list of :class:`~chess.Move` objects), - ``depth``, ``seldepth``, ``time`` (in seconds), ``nodes``, ``nps``, - ``tbhits``, ``multipv``. - - Others: ``currmove``, ``currmovenumber``, ``hashfull``, ``cpuload``, - ``refutation``, ``currline``, ``ebf``, ``wdl``, and ``string``. + A dictionary of extra :class:`information ` + sent by the engine. .. py:attribute:: draw_offered :type: bool @@ -194,6 +188,8 @@ Example: .. autoclass:: chess.engine.Protocol :members: analyse +.. autoclass:: chess.engine.InfoDict + .. autoclass:: chess.engine.PovScore :members: From 6ae12eb59fefe98228c7fdffe7fe63a1b57691af Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 15:36:43 +0200 Subject: [PATCH 1257/1831] Tweak typing.Literal bc --- chess/__init__.py | 14 +++++++++++--- chess/pgn.py | 12 ++++++++++-- chess/variant.py | 4 ++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 737f28719..7c97390ca 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -39,6 +39,14 @@ from typing import ClassVar, Callable, Counter, Dict, Generic, Hashable, Iterable, Iterator, List, Mapping, Optional, SupportsInt, Tuple, Type, TypeVar, Union +try: + from typing import Literal +except ImportError: + # Before Python 3.8. + _EnPassantSpec = str +else: + _EnPassantSpec = Literal["legal", "fen", "xfen"] # type: ignore + Color = bool COLORS = [WHITE, BLACK] = [True, False] @@ -2213,7 +2221,7 @@ def has_legal_en_passant(self) -> bool: """Checks if there is a legal en passant capture.""" return self.ep_square is not None and any(self.generate_legal_ep()) - def fen(self, *, shredder: bool = False, en_passant: str = "legal", promoted: Optional[bool] = None) -> str: + def fen(self, *, shredder: bool = False, en_passant: _EnPassantSpec = "legal", promoted: Optional[bool] = None) -> str: """ Gets a FEN representation of the position. @@ -2245,7 +2253,7 @@ def fen(self, *, shredder: bool = False, en_passant: str = "legal", promoted: Op str(self.fullmove_number) ]) - def shredder_fen(self, *, en_passant: str = "legal", promoted: Optional[bool] = None) -> str: + def shredder_fen(self, *, en_passant: _EnPassantSpec = "legal", promoted: Optional[bool] = None) -> str: return " ".join([ self.epd(shredder=True, en_passant=en_passant, promoted=promoted), str(self.halfmove_clock), @@ -2479,7 +2487,7 @@ def _epd_operations(self, operations: Mapping[str, Union[None, str, int, float, return "".join(epd) - def epd(self, *, shredder: bool = False, en_passant: str = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, Move, Iterable[Move]]) -> str: + def epd(self, *, shredder: bool = False, en_passant: _EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, Move, Iterable[Move]]) -> str: """ Gets an EPD representation of the current position. diff --git a/chess/pgn.py b/chess/pgn.py index 1696f4ee6..83cf73f82 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -31,6 +31,14 @@ from typing import Any, Callable, Dict, Generic, Iterable, Iterator, List, Mapping, MutableMapping, Set, TextIO, Tuple, Type, TypeVar, Optional, Union from chess import Color, Square +try: + from typing import Literal +except ImportError: + # Before Python 3.8. + _TrueLiteral = bool +else: + _TrueLiteral = Literal[True] # type: ignore + LOGGER = logging.getLogger(__name__) @@ -1166,7 +1174,7 @@ def result(self) -> chess.Board: return self.board -class SkipVisitor(BaseVisitor["typing.Literal[True]"]): +class SkipVisitor(BaseVisitor[_TrueLiteral]): """Skips a game.""" def begin_game(self) -> SkipType: @@ -1178,7 +1186,7 @@ def end_headers(self) -> SkipType: def begin_variation(self) -> SkipType: return SKIP - def result(self) -> "typing.Literal[True]": + def result(self) -> _TrueLiteral: return True diff --git a/chess/variant.py b/chess/variant.py index 6b774ea75..a801ed5ad 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -567,7 +567,7 @@ def set_fen(self, fen: str) -> None: self.remaining_checks[chess.WHITE] = wc self.remaining_checks[chess.BLACK] = bc - def epd(self, shredder: bool = False, en_passant: str = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: + def epd(self, shredder: bool = False, en_passant: chess._EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: epd = [super().epd(shredder=shredder, en_passant=en_passant, promoted=promoted), "{:d}+{:d}".format(max(self.remaining_checks[chess.WHITE], 0), max(self.remaining_checks[chess.BLACK], 0))] @@ -814,7 +814,7 @@ def board_fen(self, promoted: Optional[bool] = None) -> str: promoted = True return super().board_fen(promoted=promoted) - def epd(self, shredder: bool = False, en_passant: str = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: + def epd(self, shredder: bool = False, en_passant: chess._EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: epd = super().epd(shredder=shredder, en_passant=en_passant, promoted=promoted) board_part, info_part = epd.split(" ", 1) return f"{board_part}[{str(self.pockets[chess.WHITE]).upper()}{self.pockets[chess.BLACK]}] {info_part}" From 277ec32970408028eef397d33336c57bf63fa817 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 15:38:47 +0200 Subject: [PATCH 1258/1831] Try to run mypy on all Python versions --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a13992af3..8454ba6dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ install: - pip install --upgrade pip wheel - pip install --upgrade setuptools - pip install --upgrade coveralls - - if [[ $LATEST -eq 1 ]]; then pip install --upgrade mypy; fi + - pip install --upgrade mypy - pip install -e . script: - # Unit tests @@ -77,8 +77,8 @@ script: - echo Unit tests complete - coveralls || [[ $? -eq 139 ]] - # Typing - - if [[ $LATEST -eq 1 ]]; then python -m mypy --strict chess; fi - - if [[ $LATEST -eq 1 ]]; then python -m mypy --strict examples/**/*.py; fi + - python -m mypy --strict chess + - python -m mypy --strict examples/**/*.py - # Perft tests - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000; fi - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/tricky.perft; fi From 157ee7ea540daf9457a3f1fa1bcddeec00036e88 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 15:55:05 +0200 Subject: [PATCH 1259/1831] Bump Sphinx --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 5f571802a..89eb0be0b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -sphinx==3.2.0 +sphinx==3.2.1 From 7fabab85bc78f7388f350d61dd13f35f2f7613ca Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 16:03:05 +0200 Subject: [PATCH 1260/1831] Try to fix Travis matrix --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8454ba6dc..1b65ad49a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,9 @@ dist: xenial language: python sudo: false -python: - - "3.7" matrix: include: + - python: "3.7" - python: "3.8" env: LATEST=1 cache: From 61cccb8f9512387085af20954cf04156340a31dd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 16:09:37 +0200 Subject: [PATCH 1261/1831] Remove trailing space --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 7c97390ca..63fd03464 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3494,7 +3494,7 @@ def mirror(self: BoardT) -> BoardT: Returns a mirrored copy of the board. The board is mirrored vertically and piece colors are swapped, so that - the position is equivalent modulo color. Also swap the "en passant" + the position is equivalent modulo color. Also swap the "en passant" square, castling rights and turn. Alternatively, :func:`~chess.Board.apply_mirror()` can be used From 31fa7e492eaf7e1727798e1f281e1ab28ff08b75 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 16:44:41 +0200 Subject: [PATCH 1262/1831] Revert "Try to run mypy on all Python versions" This reverts commit 277ec32970408028eef397d33336c57bf63fa817. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b65ad49a..9f27efb19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,7 +46,7 @@ install: - pip install --upgrade pip wheel - pip install --upgrade setuptools - pip install --upgrade coveralls - - pip install --upgrade mypy + - if [[ $LATEST -eq 1 ]]; then pip install --upgrade mypy; fi - pip install -e . script: - # Unit tests @@ -76,8 +76,8 @@ script: - echo Unit tests complete - coveralls || [[ $? -eq 139 ]] - # Typing - - python -m mypy --strict chess - - python -m mypy --strict examples/**/*.py + - if [[ $LATEST -eq 1 ]]; then python -m mypy --strict chess; fi + - if [[ $LATEST -eq 1 ]]; then python -m mypy --strict examples/**/*.py; fi - # Perft tests - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000; fi - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/tricky.perft; fi From b1b1fb803caecd685ceb5756f165e4ccab9e8514 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 17:02:15 +0200 Subject: [PATCH 1263/1831] Try Python 3.9 on Travis CI (#671) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9f27efb19..d63d22051 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ matrix: include: - python: "3.7" - python: "3.8" + - python: "3.9" env: LATEST=1 cache: directories: From 45039e7d05f8b0267f2a3e96712bb7e8f4bd9f0a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 17:03:39 +0200 Subject: [PATCH 1264/1831] PyPy is not tested in CI --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 17099d100..a457c97ce 100644 --- a/README.rst +++ b/README.rst @@ -79,7 +79,7 @@ python-chess: Features -------- -* Supports Python 3.7+ and PyPy3. Includes mypy typings. +* Supports Python 3.7+. Includes mypy typings. * IPython/Jupyter Notebook integration. `SVG rendering docs `_. From f73e290a5895326c9e4d788ada11c16be8e94c8e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 17:17:46 +0200 Subject: [PATCH 1265/1831] Split changelog --- CHANGELOG-OLD.rst | 1887 +++++++++++++++++++++++++++++++++++++++++++++ CHANGELOG.rst | 1882 +------------------------------------------- 2 files changed, 1888 insertions(+), 1881 deletions(-) create mode 100644 CHANGELOG-OLD.rst diff --git a/CHANGELOG-OLD.rst b/CHANGELOG-OLD.rst new file mode 100644 index 000000000..6a9f5facf --- /dev/null +++ b/CHANGELOG-OLD.rst @@ -0,0 +1,1887 @@ +Old Changelog for python-chess up to 1.0.0 +========================================== + +New in v1.0.0 +------------- + +Changes: + +* Now requires Python 3.7+. +* `chess.engine` will now cut off illegal principal variations at the first + illegal move instead of discarding them entirely. +* `chess.engine.EngineProtocol` renamed to `chess.engine.Protocol`. +* `chess.engine.Option` is no longer a named tuple. +* Renamed `chess.gaviota` internals. +* Relaxed type annotations of `chess.pgn.GameNode.variation()` and related + methods. +* Changed default colors of `chess.svg.Arrow` and + `chess.pgn.GameNode.arrows()`. These can be overriden with the new + `chess.svg.board(..., colors)` feature. +* Documentation improvements. Will now show type aliases like `chess.Square` + instead of `int`. + +Bugfixes: + +* Fix insufficient material with same-color bishops on both sides. +* Clarify that `chess.Board.can_claim_draw()` and related methods refer to + claims by the player to move. Three-fold repetition could already be claimed + before making the final repeating move. `chess.Board.can_claim_fifty_moves()` + now also allows a claim before the final repeating move. The previous + behavior is `chess.Board.is_fifty_moves()`. +* Fix parsing of green arrows/circles in `chess.pgn.GameNode.arrows()`. +* Fix overloaded type signature of `chess.engine.Protocol.engine()`. + +New features: + +* Added `chess.parse_square()`, to be used instead of + `chess.SQUARE_NAMES.index()`. +* Added `chess.Board.apply_mirror()`. +* Added `chess.svg.board(..., colors)`, to allow overriding the default theme. + +New in v0.31.4 +-------------- + +Bugfixes: + +* Fix inconsistency where `board.is_legal()` was not accepting castling moves + in Chess960 notation (when board is in standard mode), while all other + methods did. +* Fix `chess.pgn.GameNode.set_clock()` with negative or floating point values. +* Avoid leading and trailing spaces in PGN comments when setting annotations. + +New features: + +* Finish typing and declare support for mypy. + +New in v0.31.3 +-------------- + +Bugfixes: + +* Custom castling rights assigned to `board.castling_rights` or castling rights + left over after `Board.set_board_fen()` were not correctly cleaned after + the first move. + +Changes: + +* Ignore up to one consecutive empty line between PGN headers. +* Added PGN Variant `From Position` as an alias for standard chess. +* `chess.pgn.FileExporter.result()` now returns the number of written + characters. +* `chess.engine` now avoids sending 0 for search limits, which some engines + misunderstand as no limit. +* `chess.engine` better handles null moves sent to the engine. +* `chess.engine` now gracefully handles `NULL` ponder moves and uppercase + moves received from UCI engines, which is technically invalid. + +New features: + +* Added `chess.pgn.GameNode.{clock, set_clock}()` to read and write + `[%clk ...]` **PGN annotations**. +* Added `chess.pgn.GameNode.{arrows, set_arrows}()` to read and write + `[%csl ...]` and `[%cal ...]` PGN annotations. +* Added `chess.pgn.GameNode.{eval, set_eval}()` to read and write + `[%eval ...]` PGN annotations. +* Added `SquareSet.ray(a, b)` and `SquareSet.between(a, b)`. + +New in v0.31.2 +-------------- + +Bugfixes: + +* Fix rejected/accepted in `chess.engine.XBoardProtocol`. +* Misc typing fixes. + +Changes: + +* Deprecated `chess.syzygy.is_table_name()`. Replaced with + `chess.syzygy.is_tablename()` which has additional parameters and defaults to + `one_king`. +* Take advantage of `int.bit_count()` coming in Python 3.10. + +New in v0.31.1 +-------------- + +Bugfixes: + +* `RacingKingsBoard.is_variant_win()` no longer incorrectly returns `True` + for drawn positions. +* Multiple moves for EPD opcodes *am* and *bm* are now sorted as required by + the specification. +* Coordinates of SVG boards are now properly aligned, even when rendered as + SVG Tiny. + +Changes: + +* SVG boards now have a background color for the coordinate margin, making + coordinates readable on dark backgrounds. +* Added *[Variant "Illegal"]* as an alias for standard chess + (used by Chessbase). + +Features: + +* Added `Board.find_move()`, useful for finding moves that match human input. + +New in v0.31.0 +-------------- + +Changes: + +* Replaced lookup table `chess.BB_BETWEEN[a][b]` with a function + `chess.between(a, b)`. Improves initialization and runtime performance. +* `chess.pgn.BaseVisitor.result()` is now an abstract method, forcing + subclasses to implement it. +* Removed helper attributes from `chess.engine.InfoDict`. Instead it is now + a `TypedDict`. +* `chess.engine.PovScore` equality is now semantic instead of structural: + Scores compare equal to the negative score from the opposite point of view. + +Bugfixes: + +* `chess.Board.is_irreversible()` now considers ceding legal en passant + captures as irreversible. Also documented that false-negatives due to forced + lines are by design. +* Fixed stack overflow in `chess.pgn` when exporting, visiting or getting the + final board of a very long game. +* Clarified documentation regarding board validity. +* `chess.pgn.GameNode.__repr__()` no longer errors if the root node has invalid + FEN or Variant headers. +* Carriage returns are no longer allowed in PGN header values, fixing + reparsability. +* Fixed type error when XBoard name or egt features have a value that looks + like an integer. +* `chess.engine` is now passing type checks with mypy. +* `chess.gaviota` is now passing type checks with mypy. + +Features: + +* Added `chess.Board.gives_check()`. +* `chess.engine.AnalysisResult.wait()` now returns `chess.engine.BestMove`. +* Added `empty_square` parameter for `chess.Board.unicode()` with better + aligned default (⭘). + +New in v0.30.1 +-------------- + +Changes: + +* Positions with more than two checkers are considered invalid and + `board.status()` returns `chess.STATUS_TOO_MANY_CHECKERS`. +* Pawns drops in Crazyhouse are considered zeroing and reset + `board.halfmove_clock` when played. +* Now validating file sizes when opening Syzygy tables and Polyglot opening + books. +* Explicitly warn about untrusted tablebase files and chess engines. + +Bugfixes: + +* Fix Racing Kings game end detection: Black cannot catch up if their own + pieces block the goal. White would win on the next turn, so this did not + impact the game theoretical outcome of the game. +* Fix bugs discovered by fuzzing the EPD parser: Fixed serialization of + empty strings, reparsability of empty move lists, handling of non-finite + floats, and handling of whitespace in opcodes. + +Features: + +* Added `board.checkers()`, returning a set of squares with the pieces giving + check. + +New in v0.30.0 +-------------- + +Changes: + +* **Dropped support for Python 3.5.** +* Remove explicit loop arguments in `chess.engine` module, following + https://bugs.python.org/issue36373. + +Bugfixes: + +* `chess.engine.EngineProtocol.returncode` is no longer poisoned when + `EngineProtocol.quit()` times out. +* `chess.engine.PlayResult.info` was not always of type + `chess.engine.InfoDict`. + +Features: + +* The background thread spawned by `chess.engine.SimpleEngine` is now named + for improved debuggability, revealing the PID of the engine process. +* `chess.engine.EventLoopPolicy` now supports `asyncio.PidfdChildWatcher` + when running on Python 3.9+ and Linux 5.3+. +* Add `chess.Board.san_and_push()`. + +New in v0.29.0 +-------------- + +Changes: + +* `chess.variant.GiveawayBoard` **now starts with castling rights**. + `chess.variant.AntichessBoard` is the same variant without castling rights. +* UCI info parser no longer reports errors when encountering unknown tokens. +* Performance improvements for repetition detection. +* Since Python 3.8: `chess.syzygy`/`chess.polyglot` use `madvise(MADV_RANDOM)` + to prepare table/book files for random access. + +Bugfixes: + +* Fix syntax error in type annotation of `chess.engine.run_in_background()`. +* Fix castling rights when king is exploded in Atomic. Mitigated by the fact + that the game is over and that it did not affect FEN. +* Fix insufficient material with underpromoted pieces in Crazyhouse. Mitigated + by the fact that affected positions are unreachable in Crazyhouse. + +Features: + +* Support `wdl` in UCI info (usually activated with `UCI_ShowWDL`). + +New in v0.28.3 +-------------- + +Bugfixes: + +* Follow FICS rules in Atomic castling edge cases. +* Handle self-reported errors by XBoard engines "Error: ..." or + "Illegal move: ...". + +New in v0.28.2 +-------------- + +Bugfixes: + +* Fixed exception propagation, when a UCI engine sends an invalid `bestmove`. + Thanks @fsmosca. + +Changes: + +* `chess.Move.from_uci()` no longer accepts moves from and to the same square, + for example `a1a1`. `0000` is now the only valid null move notation. + +New in v0.28.1 +-------------- + +Bugfixes: + +* The minimum Python version is 3.5.3 (instead of 3.5.0). +* Fix `board.is_irreversible()` when capturing a rook that had castling rights. + +Changes: + +* `is_en_passant()`, `is_capture()`, `is_zeroing()`, `is_irreversible()`, + `is_castling()`, `is_kingside_castling()` and `is_queenside_castling()` + now consistently return `False` for null moves. +* Added `chess.engine.InfoDict` class with typed shorthands for common keys. +* Support `[Variant "3-check"]` (from chess.com PGNs). + +New in v0.28.0 +-------------- + +Changes: + +* Dropped support for Python 3.4 (end of life reached). +* `chess.polyglot.Entry.move` **is now a property instead of a method**. + The raw move is now always decoded in the context of the position (relevant + for castling moves). +* `Piece`, `Move`, `BaseBoard` and `Board` comparisons no longer support + duck typing. +* FENs sent to engines now always include potential en passant squares, even if + no legal en passant capture exists. +* Circular SVG arrows now have a `circle` CSS class. +* Superfluous dashes (-) in EPDs are no longer treated as opcodes. +* Removed `GameCreator`, `HeaderCreator` and `BoardCreator` aliases for + `{Game,Headers,Board}Builder`. + +Bugfixes: + +* Notation like `Kh1` is no longer accepted for castling moves. +* Remove stale files from wheels published on PyPI. +* Parsing Three-Check EPDs with moves was always failing. +* Some methods in `chess.variant` were returning bool-ish integers, when they + should have returned `bool`. +* `chess.engine`: Fix line decoding when Windows line-endings arrive seperately + in stdout buffer. +* `chess.engine`: Survive timeout in analysis. +* `chess.engine`: Survive unexpected `bestmove` sent by misbehaving UCI engines. + +New features: + +* **Experimental type signatures for almost all public APIs** (`typing`). + Some modules do not yet internally pass typechecking. +* Added `Board.color_at(square)`. +* Added `chess.engine.AnalysisResult.get()` and `empty()`. +* `chess.engine`: The `UCI_AnalyseMode` option is still automatically managed, + but can now be overwritten. +* `chess.engine.EngineProtocol` and constructors now optionally take + an explicit `loop` argument. + +New in v0.27.3 +-------------- + +Changes: + +* `XBoardProtocol` will no longer raise an exception when the engine resigned. + Instead it sets a new flag `PlayResult.resigned`. `resigned` and + `draw_offered` are keyword-only arguments. +* Renamed `chess.pgn.{Game,Header,Board}Creator` to + `{Game,Headers,Board}Builder`. Aliases kept in place. + +Bugfixes: + +* Make `XBoardProtocol` robust against engines that send a move after claiming + a draw or resigning. Thanks @pascalgeo. +* `XBoardProtocol` no longer ignores `Hint:` sent by the engine. +* Fix handling of illegal moves in `XBoardProtocol`. +* Fix exception when engine is shut down while pondering. +* Fix unhandled internal exception and file descriptor leak when engine + initialization fails. +* Fix `HordeBoard.status()` when black pieces are on the first rank. + Thanks @Wisling. + +New features: + +* Added `chess.pgn.Game.builder()`, `chess.pgn.Headers.builder()` and + `chess.pgn.GameNode.dangling_node()` to simplify subclassing `GameNode`. +* `EngineProtocol.communicate()` is now also available in the synchronous API. + +New in v0.27.2 +-------------- + +Bugfixes: + +* `chess.engine.XBoardProtocol.play()` was searching 100 times longer than + intended when using `chess.engine.Limit.time`, and searching 100 times more + nodes than intended when using `chess.engine.Limit.nodes`. Thanks @pascalgeo. + +New in v0.27.1 +-------------- + +Bugfixes: + +* `chess.engine.XBoardProtocol.play()` was raising `KeyError` when using time + controls with increment or remaining moves. Thanks @pascalgeo. + +New in v0.27.0 +-------------- + +This is the second **release candidate for python-chess 1.0**. If you see the +need for breaking changes, please speak up now! + +Bugfixes: + +* `EngineProtocol.analyse(*, multipv)` was not passing this argument to the + engine and therefore only returned the first principal variation. + Thanks @svangordon. +* `chess.svg.board(*, squares)`: The X symbol on selected squares is now more + visible when it overlaps pieces. + +Changes: + +* **FEN/EPD parsing is now more relaxed**: Incomplete FENs and EPDs are + completed with reasonable defaults (`w - - 0 1`). The EPD parser accepts + fields with moves in UCI notation (for example the technically invalid + `bm g1f3` instead of `bm Nf3`). +* The PGN parser now skips games with invalid FEN headers and variations after + an illegal move (after handling the error as usual). + +New features: + +* Added `Board.is_repetition(count=3)`. +* Document that `chess.engine.EngineProtocol` is compatible with + AsyncSSH 1.16.0. + +New in v0.26.0 +-------------- + +This is the first **release candidate for python-chess 1.0**. If you see the +need for breaking changes, please speak up now! + +Changes: + +* `chess.engine` **is now stable and replaces** + `chess.uci` **and** `chess.xboard`. +* Advanced: `EngineProtocol.initialize()` is now public for use with custom + transports. +* Removed `__ne__` implementations (not required since Python 3). +* Assorted documentation and coding-style improvements. + +New features: + +* Check insufficient material for a specific side: + `board.has_insufficient_material(color)`. +* Copy boards with limited stack depth: `board.copy(stack=depth)`. + +Bugfixes: + +* Properly handle delayed engine errors, for example unsupported options. + +New in v0.25.1 +-------------- + +Bugfixes: + +* `chess.engine` did not correctly handle Windows-style line endings. + Thanks @Bstylestuff. + +New in v0.25.0 +-------------- + +New features: + +* This release introduces a new **experimental API for chess engine + communication**, `chess.engine`, based on `asyncio`. It is intended to + eventually replace `chess.uci` and `chess.xboard`. + +Bugfixes: + +* Fixed race condition in LRU-cache of open Syzygy tables. The LRU-cache is + enabled by default (*max_fds*). +* Fix deprecation warning and unclosed file in setup.py. + Thanks Mickaël Schoentgen. + +Changes: + +* `chess.pgn.read_game()` now ignores BOM at the start of the stream. +* Removed deprecated items. + +New in v0.24.2 +-------------- + +Bugfixes: + +* `CrazyhouseBoard.root()` and `ThreeCheckBoard.root()` were not returning the + correct pockets and number of remaining checks, respectively. Thanks @gbtami. +* `chess.pgn.skip_game()` now correctly skips PGN comments that contain + line-breaks and PGN header tag notation. + +Changes: + +* Renamed `chess.pgn.GameModelCreator` to `GameCreator`. Alias kept in place + and will be removed in a future release. +* Renamed `chess.engine` to `chess._engine`. Use re-exports from `chess.uci` + or `chess.xboard`. +* Renamed `Board.stack` to `Board._stack`. Do not use this directly. +* Improved memory usage: `Board.legal_moves` and `Board.pseudo_legal_moves` + no longer create reference cycles. PGN visitors can manage headers + themselves. +* Removed previously deprecated items. + +Features: + +* Added `chess.pgn.BaseVisitor.visit_board()` and `chess.pgn.BoardCreator`. + +New in v0.24.1, v0.23.11 +------------------------ + +Bugfixes: + +* Fix `chess.Board.set_epd()` and `chess.Board.from_epd()` with semicolon + in string operand. Thanks @jdart1. +* `chess.pgn.GameNode.uci()` was always raising an exception. + Also included in v0.24.0. + +New in v0.24.0 +-------------- + +This release **drops support for Python 2**. The *0.23.x* branch will be +maintained for one more month. + +Changes: + +* **Require Python 3.4.** Thanks @hugovk. +* No longer using extra pip features: + `pip install python-chess[engine,gaviota]` is now `pip install python-chess`. +* Various keyword arguments can now be used as **keyword arguments only**. +* `chess.pgn.GameNode.accept()` now + **also visits the move leading to that node**. +* `chess.pgn.GameModelCreator` now requires that `begin_game()` be called. +* `chess.pgn.scan_headers()` and `chess.pgn.scan_offsets()` have been removed. + Instead the new functions `chess.pgn.read_headers()` and + `chess.pgn.skip_game()` can be used for a similar purpose. +* `chess.syzygy`: Invalid magic headers now raise `IOError`. Previously they + were only checked in an assertion. + `type(board).{tbw_magic,tbz_magic,pawnless_tbw_magic,pawnless_tbz_magic}` + are now byte literals. +* `board.status()` constants (`STATUS_`) are now typed using `enum.IntFlag`. + Values remain unchanged. +* `chess.svg.Arrow` is no longer a `namedtuple`. +* `chess.PIECE_SYMBOLS[0]` and `chess.PIECE_NAMES[0]` are now `None` instead + of empty strings. +* Performance optimizations: + + * `chess.pgn.Game.from_board()`, + * `chess.square_name()` + * Replace `collections.deque` with lists almost everywhere. + +* Renamed symbols (aliases will be removed in the next release): + + * `chess.BB_VOID` -> `BB_EMPTY` + * `chess.bswap()` -> `flip_vertical()` + * `chess.pgn.GameNode.main_line()` -> `mainline_moves()` + * `chess.pgn.GameNode.is_main_line()` -> `is_mainline()` + * `chess.variant.BB_HILL` -> `chess.BB_CENTER` + * `chess.syzygy.open_tablebases()` -> `open_tablebase()` + * `chess.syzygy.Tablebases` -> `Tablebase` + * `chess.syzygy.Tablebase.open_directory()` -> `add_directory()` + * `chess.gaviota.open_tablebases()` -> `open_tablebase()` + * `chess.gaviota.open_tablebases_native()` -> `open_tablebase_native()` + * `chess.gaviota.NativeTablebases` -> `NativeTablebase` + * `chess.gaviota.PythonTablebases` -> `PythonTablebase` + * `chess.gaviota.NativeTablebase.open_directory()` -> `add_directory()` + * `chess.gaviota.PythonTablebase.open_directory()` -> `add_directory()` + +Bugfixes: + +* The PGN parser now gives the visitor a chance to handle unknown chess + variants and continue parsing. +* `chess.pgn.GameNode.uci()` was always raising an exception. + +New features: + +* `chess.SquareSet` now extends `collections.abc.MutableSet` and can be + initialized from iterables. +* `board.apply_transform(f)` and `board.transform(f)` can apply bitboard + transformations to a position. Examples: + `chess.flip_{vertical,horizontal,diagonal,anti_diagonal}`. +* `chess.pgn.GameNode.mainline()` iterates over nodes of the mainline. + Can also be used with `reversed()`. Reversal is now also supported for + `chess.pgn.GameNode.mainline_moves()`. +* `chess.svg.Arrow(tail, head, color="#888")` gained an optional *color* + argument. +* `chess.pgn.BaseVisitor.parse_san(board, san)` is used by parsers and can + be overwritten to deal with non-standard input formats. +* `chess.pgn`: Visitors can advise the parser to skip games or variations by + returning the special value `chess.pgn.SKIP` from `begin_game()`, + `end_headers()` or `begin_variation()`. This is only a hint. + The corresponding `end_game()` or `end_variation()` will still be called. +* Added `chess.svg.MARGIN`. + +New in v0.23.10 +--------------- + +Bugfixes: + +* `chess.SquareSet` now correctly handles negative masks. Thanks @hasnul. +* `chess.pgn` now accepts `[Variant "chess 960"]` (with the space). + +New in v0.23.9 +-------------- + +Changes: + +* Updated `Board.is_fivefold_repetition()`. FIDE rules have changed and the + repetition no longer needs to occur on consecutive alternating moves. + Thanks @LegionMammal978. + +New in v0.23.8 +-------------- + +Bugfixes: + +* `chess.syzygy`: Correctly initialize wide DTZ map for experimental 7 piece + table KRBBPvKQ. + +New in v0.23.7 +-------------- + +Bugfixes: + +* Fixed `ThreeCheckBoard.mirror()` and `CrazyhouseBoard.mirror()`, which + were previously resetting remaining checks and pockets respectively. + Thanks @QueensGambit. + +Changes: + +* `Board.move_stack` is now guaranteed to be UCI compatible with respect to + the representation of castling moves and `board.chess960`. +* Drop support for Python 3.3, which is long past end of life. +* `chess.uci`: The `position` command now manages `UCI_Chess960` and + `UCI_Variant` automatically. +* `chess.uci`: The `position` command will now always send the entire history + of moves from the root position. +* Various coding style fixes and improvements. Thanks @hugovk. + +New features: + +* Added `Board.root()`. + +New in v0.23.6 +-------------- + +Bugfixes: + +* Gaviota: Fix Python based Gaviota tablebase probing when there are multiple + en passant captures. Thanks @bjoernholzhauer. +* Syzygy: Fix DTZ for some mate in 1 positions. Similarly to the fix from + v0.23.1 this is mostly cosmetic. +* Syzygy: Fix DTZ off-by-one in some 6 piece antichess positions with moves + that threaten to force a capture. This is mostly cosmetic. + +Changes: + +* Let `uci.Engine.position()` send history of at least 8 moves if available. + Previously it sent only moves that were relevant for repetition detection. + This is mostly useful for Lc0. Once performance issues are solved, a future + version will always send the entire history. Thanks @SashaMN and @Mk-Chan. +* Various documentation fixes and improvements. + +New features: + +* Added `polyglot.MemoryMappedReader.get(board, default=None)`. + +New in v0.23.5 +-------------- + +Bugfixes: + +* Atomic chess: KNvKN is not insufficient material. +* Crazyhouse: Detect insufficient material. This can not happen unless the + game was started with insufficient material. + +Changes: + +* Better error messages when parsing info from UCI engine fails. +* Better error message for `b.set_board_fen(b.fen())`. + +New in v0.23.4 +-------------- + +New features: + +* XBoard: Support pondering. Thanks Manik Charan. +* UCI: Support unofficial `info ebf`. + +Bugfixes: + +* Implement 16 bit DTZ mapping, which is required for some of the longest + 7 piece endgames. + +New in v0.23.3 +-------------- + +New features: + +* XBoard: Support `variant`. Thanks gbtami. + +New in v0.23.2 +-------------- + +Bugfixes: + +* XBoard: Handle multiple features and features with spaces. Thanks gbtami. +* XBoard: Ignore debug output prefixed with `#`. Thanks Dan Ravensloft and + Manik Charan. + +New in v0.23.1 +-------------- + +Bugfixes: + +* Fix DTZ in case of mate in 1. This is a cosmetic fix, as the previous + behavior was only off by one (which is allowed by design). + +New in v0.23.0 +-------------- + +New features: + +* Experimental support for 7 piece Syzygy tablebases. + +Changes: + +* `chess.syzygy.filenames()` was renamed to `tablenames()` and + gained an optional `piece_count=6` argument. +* `chess.syzygy.normalize_filename()` was renamed to `normalize_tablename()`. +* The undocumented constructors of `chess.syzygy.WdlTable` and + `chess.syzygy.DtzTable` have been changed. + +New in v0.22.2 +-------------- + +Bugfixes: + +* In standard chess promoted pieces were incorrectly considered as + distinguishable from normal pieces with regard to position equality + and threefold repetition. Thanks to kn-sq-tb for reporting. + +Changes: + +* The PGN `game.headers` are now a custom mutable mapping that validates the + validity of tag names. +* Basic attack and pin methods moved to `BaseBoard`. +* Documentation fixes and improvements. + +New features: + +* Added `Board.lan()` for long algebraic notation. + +New in v0.22.1 +-------------- + +New features: + +* Added `Board.mirror()`, `SquareSet.mirror()` and `bswap()`. +* Added `chess.pgn.GameNode.accept_subgame()`. +* XBoard: Added `resign`, `analyze`, `exit`, `name`, `rating`, `computer`, + `egtpath`, `pause`, `resume`. Completed option parsing. + +Changes: + +* `chess.pgn`: Accept FICS wilds without warning. +* XBoard: Inform engine about game results. + +Bugfixes: + +* `chess.pgn`: Allow games without movetext. +* XBoard: Fixed draw handling. + +New in v0.22.0 +-------------- + +Changes: + +* `len(board.legal_moves)` **replaced by** `board.legal_moves.count()`. + Previously `list(board.legal_moves)` was generating moves twice, resulting in + a considerable slowdown. Thanks to Martin C. Doege for reporting. +* **Dropped Python 2.6 support.** +* XBoard: `offer_draw` renamed to `draw`. + +New features: + +* XBoard: Added `DrawHandler`. + +New in v0.21.2 +-------------- + +Changes: + +* `chess.svg` is now fully SVG Tiny 1.2 compatible. Removed + `chess.svg.DEFAULT_STYLE` which would from now on be always empty. + +New in v0.21.1 +-------------- + +Bugfixes: + +* `Board.set_piece_at()` no longer shadows optional `promoted` + argument from `BaseBoard`. +* Fixed `ThreeCheckBoard.is_irreversible()` and + `ThreeCheckBoard._transposition_key()`. + +New features: + +* Added `Game.without_tag_roster()`. `chess.pgn.StringExporter()` can now + handle games without any headers. +* XBoard: `white`, `black`, `random`, `nps`, `otim`, `undo`, `remove`. Thanks + to Manik Charan. + +Changes: + +* Documentation fixes and tweaks by Boštjan Mejak. +* Changed unicode character for empty squares in `Board.unicode()`. + +New in v0.21.0 +-------------- + +Release yanked. + +New in v0.20.1 +-------------- + +Bugfixes: + +* Fix arrow positioning on SVG boards. +* Documentation fixes and improvements, making most doctests runnable. + +New in v0.20.0 +-------------- + +Bugfixes: + +* Some XBoard commands were not returning futures. +* Support semicolon comments in PGNs. + +Changes: + +* Changed FEN and EPD formatting options. It is now possible to include en + passant squares in FEN and X-FEN style, or to include only strictly relevant + en passant squares. +* Relax en passant square validation in `Board.set_fen()`. +* Ensure `is_en_passant()`, `is_capture()`, `is_zeroing()` and + `is_irreversible()` strictly return bools. +* Accept `Z0` as a null move in PGNs. + +New features: + +* XBoard: Add `memory`, `core`, `stop` and `movenow` commands. + Abstract `post`/`nopost`. Initial `FeatureMap` support. Support `usermove`. +* Added `Board.has_pseudo_legal_en_passant()`. +* Added `Board.piece_map()`. +* Added `SquareSet.carry_rippler()`. +* Factored out some (unstable) low level APIs: `BB_CORNERS`, + `_carry_rippler()`, `_edges()`. + +New in v0.19.0 +-------------- + +New features: + +* **Experimental XBoard engine support.** Thanks to Manik Charan and + Cash Costello. Expect breaking changes in future releases. +* Added an undocumented `chess.polyglot.ZobristHasher` to make Zobrist hashing + easier to extend. + +Bugfixes: + +* Merely pseudo-legal en passant does no longer count for repetitions. +* Fixed repetition detection in Three-Check and Crazyhouse. (Previously + check counters and pockets were ignored.) +* Checking moves in Three-Check are now considered as irreversible by + `ThreeCheckBoard.is_irreversible()`. +* `chess.Move.from_uci("")` was raising `IndexError` instead of `ValueError`. + Thanks Jonny Balls. + +Changes: + +* `chess.syzygy.Tablebases` constructor no longer supports directly opening + a directory. Use `chess.syzygy.open_tablebases()`. +* `chess.gaviota.PythonTablebases` and `NativeTablebases` constructors + no longer support directly opening a directory. + Use `chess.gaviota.open_tablebases()`. +* `chess.Board` instances are now compared by the position they represent, + not by exact match of the internal data structures (or even move history). +* Relaxed castling right validation in Chess960: Kings/rooks of opposing sites + are no longer required to be on the same file. +* Removed misnamed `Piece.__unicode__()` and `BaseBoard.__unicode__()`. Use + `Piece.unicode_symbol()` and `BaseBoard.unicode()` instead. +* Changed `chess.SquareSet.__repr__()`. +* Support `[Variant "normal"]` in PGNs. +* `pip install python-chess[engine]` instead of `python-chess[uci]` (since + the extra dependencies are required for both UCI and XBoard engines). +* Mixed documentation fixes and improvements. + +New in v0.18.4 +-------------- + +Changes: + +* Support `[Variant "fischerandom"]` in PGNs for Cutechess compatibility. + Thanks to Steve Maughan for reporting. + +New in v0.18.3 +-------------- + +Bugfixes: + +* `chess.gaviota.NativeTablebases.get_dtm()` and `get_wdl()` were missing. + +New in v0.18.2 +-------------- + +Bugfixes: + +* Fixed castling in atomic chess when there is a rank attack. +* The halfmove clock in Crazyhouse is no longer incremented unconditionally. + `CrazyhouseBoard.is_zeroing(move)` now considers pawn moves and captures as + zeroing. Added `Board.is_irreversible(move)` that can be used instead. +* Fixed an inconsistency where the `chess.pgn` tokenizer accepts long algebraic + notation but `Board.parse_san()` did not. + +Changes: + +* Added more NAG constants in `chess.pgn`. + +New in v0.18.1 +-------------- + +Bugfixes: + +* Crazyhouse drops were accepted as pseudo-legal (and legal) even if the + respective piece was not in the pocket. +* `CrazyhouseBoard.pop()` was failing to undo en passant moves. +* `CrazyhouseBoard.pop()` was always returning `None`. +* `Move.__copy__()` was failing to copy Crazyhouse drops. +* Fix ~ order (marker for promoted pieces) in FENs. +* Promoted pieces in Crazyhouse were not communicated with UCI engines. + +Changes: + +* `ThreeCheckBoard.uci_variant` changed from `threecheck` to `3check`. + +New in v0.18.0 +-------------- + +Bugfixes: + +* Fixed `Board.parse_uci()` for crazyhouse drops. Thanks to Ryan Delaney. +* Fixed `AtomicBoard.is_insufficient_material()`. +* Fixed signature of `SuicideBoard.was_into_check()`. +* Explicitly close input and output streams when a `chess.uci.PopenProcess` + terminates. +* The documentation of `Board.attackers()` was wrongly stating that en passant + capturable pawns are considered attacked. + +Changes: + +* `chess.SquareSet` is no longer hashable (since it is mutable). +* Removed functions and constants deprecated in v0.17.0. +* Dropped `gmpy2` and `gmpy` as optional dependencies. They were no longer + improving performance. +* Various tweaks and optimizations for 5% improvement in PGN parsing and perft + speed. (Signature of `_is_safe` and `_ep_skewered` changed). +* Rewritten `chess.svg.board()` using `xml.etree`. No longer supports *pre* and + *post*. Use an XML parser if you need to modify the SVG. Now only inserts + actually used piece defintions. +* Untangled UCI process and engine instanciation, changing signatures of + constructors and allowing arbitrary arguments to `subprocess.Popen`. +* Coding style and documentation improvements. + +New features: + +* `chess.svg.board()` now supports arrows. Thanks to @rheber for implementing + this feature. +* Let `chess.uci.PopenEngine` consistently handle Ctrl+C across platforms + and Python versions. `chess.uci.popen_engine()` now supports a `setpgrp` + keyword argument to start the engine process in a new process group. + Thanks to @dubiousjim. +* Added `board.king(color)` to find the (royal) king of a given side. +* SVGs now have `viewBox` and `chess.svg.board(size=None)` supports and + defaults to `None` (i.e. scaling to the size of the container). + +New in v0.17.0 +-------------- + +Changes: + +* Rewritten move generator, various performance tweaks, code simplications + (500 lines removed) amounting to **doubled PGN parsing and perft speed**. +* Removed `board.generate_evasions()` and `board.generate_non_evasions()`. +* Removed `board.transpositions`. Transpositions are now counted on demand. +* `file_index()`, `rank_index()`, and `pop_count()` have been renamed to + `square_file()`, `square_rank()` and `popcount()` respectively. Aliases will + be removed in some future release. +* `STATUS_ILLEGAL_CHECK` has been renamed to `STATUS_RACE_CHECK`. The alias + will be removed in a future release. +* Removed `DIAG_ATTACKS_NE`, `DIAG_ATTACKS_NW`, `RANK_ATTACKS` and + `FILE_ATTACKS` as well as the corresponding masks. New attack tables + `BB_DIAG_ATTACKS` (combined both diagonal tables), `BB_RANK_ATTACKS` and + `BB_FILE_ATTACKS` are indexed by square instead of mask. +* `board.push()` no longer requires pseudo-legality. +* Documentation improvements. + +Bugfixes: + +* **Positions in variant end are now guaranteed to have no legal moves.** + `board.is_variant_end()` has been added to test for special variant end + conditions. Thanks to salvador-dali. +* `chess.svg`: Fixed a typo in the class names of black queens. Fixed fill + color for black rooks and queens. Added SVG Tiny support. These combined + changes fix display in a number of applications, including + Jupyter Qt Console. Thanks to Alexander Meshcheryakov. +* `board.ep_square` was not consistently `None` instead of `0`. +* Detect invalid racing kings positions: `STATUS_RACE_OVER`, + `STATUS_RACE_MATERIAL`. +* `SAN_REGEX`, `FEN_CASTLING_REGEX` and `TAG_REGEX` now try to match the + entire string and no longer accept newlines. +* Fixed `Move.__hash__()` for drops. + +New features: + +* `board.remove_piece_at()` now returns the removed piece. +* Added `square_distance()` and `square_mirror()`. +* Added `msb()`, `lsb()`, `scan_reversed()` and `scan_forward()`. +* Added `BB_RAYS` and `BB_BETWEEN`. + +New in v0.16.2 +-------------- + +Changes: + +* `board.move_stack` now contains the exact move objects added with + `Board.push()` (instead of normalized copies for castling moves). + This ensures they can be used with `Board.variation_san()` amongst others. +* `board.ep_square` is now `None` instead of `0` for no en passant square. +* `chess.svg`: Better vector graphics for knights. Thanks to ProgramFox. +* Documentation improvements. + +New in v0.16.1 +-------------- + +Bugfixes: + +* Explosions in atomic chess were not destroying castling rights. Thanks to + ProgramFOX for finding this issue. + +New in v0.16.0 +-------------- + +Bugfixes: + +* `pin_mask()`, `pin()` and `is_pinned()` make more sense when already + in check. Thanks to Ferdinand Mosca. + +New features: + +* **Variant support: Suicide, Giveaway, Atomic, King of the Hill, Racing Kings, + Horde, Three-check, Crazyhouse.** `chess.Move` now supports drops. +* More fine grained dependencies. Use *pip install python-chess[uci,gaviota]* to + install dependencies for the full feature set. +* Added `chess.STATUS_EMPTY` and `chess.STATUS_ILLEGAL_CHECK`. +* The `board.promoted` mask keeps track of promoted pieces. +* Optionally copy boards without the move stack: `board.copy(stack=False)`. +* `examples/bratko_kopec` now supports avoid move (am), variants and + displays fractional scores immidiately. Thanks to Daniel Dugovic. +* `perft.py` rewritten with multi-threading support and moved to + `examples/perft`. +* `chess.syzygy.dependencies()`, `chess.syzygy.all_dependencies()` to generate + Syzygy tablebase dependencies. + +Changes: + +* **Endgame tablebase probing (Syzygy, Gaviota):** `probe_wdl()` **,** + `probe_dtz()` **and** `probe_dtm()` **now raise** `KeyError` **or** + `MissingTableError` **instead of returning** *None*. If you prefer getting + `None` in case of an error use `get_wdl()`, `get_dtz()` and `get_dtm()`. +* `chess.pgn.BaseVisitor.result()` returns `True` by default and is no longer + used by `chess.pgn.read_game()` if no game was found. +* Non-fast-forward update of the Git repository to reduce size (old binary + test assets removed). +* `board.pop()` now uses a boardstate stack to undo moves. +* `uci.engine.position()` will send the move history only until the latest + zeroing move. +* Optimize `board.clean_castling_rights()` and micro-optimizations improving + PGN parser performance by around 20%. +* Syzygy tables now directly use the endgame name as hash keys. +* Improve test performance (especially on Travis CI). +* Documentation updates and improvements. + +New in v0.15.4 +-------------- + +New features: + +* Highlight last move and checks when rendering board SVGs. + +New in v0.15.3 +-------------- + +Bugfixes: + +* `pgn.Game.errors` was not populated as documented. Thanks to Ryan Delaney + for reporting. + +New features: + +* Added `pgn.GameNode.add_line()` and `pgn.GameNode.main_line()` which make + it easier to work with lists of moves as variations. + +New in v0.15.2 +-------------- + +Bugfixes: + +* Fix a bug where `shift_right()` and `shift_2_right()` were producing + integers larger than 64bit when shifting squares off the board. This is + very similar to the bug fixed in v0.15.1. Thanks to piccoloprogrammatore + for reporting. + +New in v0.15.1 +-------------- + +Bugfixes: + +* Fix a bug where `shift_up_right()` and `shift_up_left()` were producing + integers larger than 64bit when shifting squares off the board. + +New features: + +* Replaced __html__ with experimental SVG rendering for IPython. + +New in v0.15.0 +-------------- + +Changes: + +* `chess.uci.Score` **no longer has** `upperbound` **and** `lowerbound` + **attributes**. Previously these were always *False*. + +* Significant improvements of move generation speed, around **2.3x faster + PGN parsing**. Removed the following internal attributes and methods of + the `Board` class: `attacks_valid`, `attacks_to`, `attacks_from`, + `_pinned()`, `attacks_valid_stack`, `attacks_from_stack`, `attacks_to_stack`, + `generate_attacks()`. + +* UCI: Do not send *isready* directly after *go*. Though allowed by the UCI + protocol specification it is just not nescessary and many engines were having + trouble with this. + +* Polyglot: Use less memory for uniform random choices from big opening books + (reservoir sampling). + +* Documentation improvements. + +Bugfixes: + +* Allow underscores in PGN header tags. Found and fixed by Bajusz Tamás. + +New features: + +* Added `Board.chess960_pos()` to identify the Chess960 starting position + number of positions. + +* Added `chess.BB_BACKRANKS` and `chess.BB_PAWN_ATTACKS`. + +New in v0.14.1 +-------------- + +Bugfixes: + +* Backport Bugfix for Syzygy DTZ related to en passant. + See official-stockfish/Stockfish@6e2ca97d93812b2. + +Changes: + +* Added optional argument *max_fds=128* to `chess.syzygy.open_tablebases()`. + An LRU cache is used to keep at most *max_fds* files open. This allows using + many tables without running out of file descriptors. + Previously all tables were opened at once. + +* Syzygy and Gaviota now store absolute tablebase paths, in case you change + the working directory of the process. + +* The default implementation of `chess.uci.InfoHandler.score()` will no longer + store score bounds in `info["score"]`, only real scores. + +* Added `Board.set_chess960_pos()`. + +* Documentation improvements. + +New in v0.14.0 +-------------- + +Changes: + +* `Board.attacker_mask()` **has been renamed to** `Board.attackers_mask()` for + consistency. + +* **The signature of** `Board.generate_legal_moves()` **and** + `Board.generate_pseudo_legal_moves()` **has been changed.** Previously it + was possible to select piece types for selective move generation: + + `Board.generate_legal_moves(castling=True, pawns=True, knights=True, bishops=True, rooks=True, queens=True, king=True)` + + Now it is possible to select arbitrary sets of origin and target squares. + `to_mask` uses the corresponding rook squares for castling moves. + + `Board.generate_legal_moves(from_mask=BB_ALL, to_mask=BB)` + + To generate all knight and queen moves do: + + `board.generate_legal_moves(board.knights | board.queens)` + + To generate only castling moves use: + + `Board.generate_castling_moves(from_mask=BB_ALL, to_mask=BB_ALL)` + +* Additional hardening has been added on top of the bugfix from v0.13.3. + Diagonal skewers on the last double pawn move are now handled correctly, + even though such positions can not be reached with a sequence of legal moves. + +* `chess.syzygy` now uses the more efficient selective move generation. + +New features: + +* The following move generation methods have been added: + `Board.generate_pseudo_legal_ep(from_mask=BB_ALL, to_mask=BB_ALL)`, + `Board.generate_legal_ep(from_mask=BB_ALL, to_mask=BB_ALL)`, + `Board.generate_pseudo_legal_captures(from_mask=BB_ALL, to_mask=BB_ALL)`, + `Board.generate_legal_captures(from_mask=BB_ALL, to_mask=BB_ALL)`. + + +New in v0.13.3 +-------------- + +**This is a bugfix release for a move generation bug.** Other than the bugfix +itself there are only minimal fully backwardscompatible changes. +You should update immediately. + +Bugfixes: + +* When capturing en passant, both the capturer and the captured pawn disappear + from the fourth or fifth rank. If those pawns were covering a horizontal + attack on the king, then capturing en passant should not have been legal. + + `Board.generate_legal_moves()` and `Board.is_into_check()` have been fixed. + + The same principle applies for diagonal skewers, but nothing has been done + in this release: If the last double pawn move covers a diagonal attack, then + the king would have already been in check. + + v0.14.0 adds additional hardening for all cases. It is recommended you + upgrade to v0.14.0 as soon as you can deal with the + non-backwards compatible changes. + +Changes: + +* `chess.uci` now uses `subprocess32` if applicable (and available). + Additionally a lock is used to work around a race condition in Python 2, that + can occur when spawning engines from multiple threads at the same time. + +* Consistently handle tabs in UCI engine output. + +New in v0.13.2 +-------------- + +Changes: + +* `chess.syzygy.open_tablebases()` now raises if the given directory + does not exist. + +* Allow visitors to handle invalid `FEN` tags in PGNs. + +* Gaviota tablebase probing fails faster for piece counts > 5. + +Minor new features: + +* Added `chess.pgn.Game.from_board()`. + +New in v0.13.1 +-------------- + +Changes: + +* Missing *SetUp* tags in PGNs are ignored. + +* Incompatible comparisons on `chess.Piece`, `chess.Move`, `chess.Board` + and `chess.SquareSet` now return *NotImplemented* instead of *False*. + +Minor new features: + +* Factored out basic board operations to `chess.BaseBoard`. This is inherited + by `chess.Board` and extended with the usual move generation features. + +* Added optional *claim_draw* argument to `chess.Base.is_game_over()`. + +* Added `chess.Board.result(claim_draw=False)`. + +* Allow `chess.Board.set_piece_at(square, None)`. + +* Added `chess.SquareSet.from_square(square)`. + +New in v0.13.0 +-------------- + +* `chess.pgn.Game.export()` and `chess.pgn.GameNode.export()` have been + removed and replaced with a new visitor concept. + +* `chess.pgn.read_game()` no longer takes an `error_handler` argument. Errors + are now logged. Use the new visitor concept to change this behaviour. + +New in v0.12.5 +-------------- + +Bugfixes: + +* Context manager support for pure Python Gaviota probing code. Various + documentation fixes for Gaviota probing. Thanks to Jürgen Précour for + reporting. + +* PGN variation start comments for variations on the very first move were + assigned to the game. Thanks to Norbert Räcke for reporting. + +New in v0.12.4 +-------------- + +Bugfixes: + +* Another en passant related Bugfix for pure Python Gaviota tablebase probing. + +New features: + +* Added `pgn.GameNode.is_end()`. + +Changes: + +* Big speedup for `pgn` module. Boards are cached less agressively. Board + move stacks are copied faster. + +* Added tox.ini to specify test suite and flake8 options. + +New in v0.12.3 +-------------- + +Bugfixes: + +* Some invalid castling rights were silently ignored by `Board.set_fen()`. Now + it is ensured information is stored for retrieval using `Board.status()`. + +New in v0.12.2 +-------------- + +Bugfixes: + +* Some Gaviota probe results were incorrect for positions where black could + capture en passant. + +New in v0.12.1 +-------------- + +Changes: + +* Robust handling of invalid castling rights. You can also use the new + method `Board.clean_castling_rights()` to get the subset of strictly valid + castling rights. + +New in v0.12.0 +-------------- + +New features: + +* Python 2.6 support. Patch by vdbergh. + +* Pure Python Gaviota tablebase probing. Thanks to Jean-Noël Avila. + +New in v0.11.1 +-------------- + +Bugfixes: + +* `syzygy.Tablebases.probe_dtz()` has was giving wrong results for some + positions with possible en passant capturing. This was found and fixed + upstream: https://github.com/official-stockfish/Stockfish/issues/394. + +* Ignore extra spaces in UCI `info` lines, as for example sent by the + Hakkapeliitta engine. Thanks to Jürgen Précour for reporting. + +New in v0.11.0 +-------------- + +Changes: + +* **Chess960** support and the **representation of castling moves** has been + changed. + + The constructor of board has a new `chess960` argument, defaulting to + `False`: `Board(fen=STARTING_FEN, chess960=False)`. That property is + available as `Board.chess960`. + + In Chess960 mode the behaviour is as in the previous release. Castling moves + are represented as a king move to the corresponding rook square. + + In the default standard chess mode castling moves are represented with + the standard UCI notation, e.g. `e1g1` for king-side castling. + + `Board.uci(move, chess960=None)` creates UCI representations for moves. + Unlike `Move.uci()` it can convert them in the context of the current + position. + + `Board.has_chess960_castling_rights()` has been added to test for castling + rights that are impossible in standard chess. + + The modules `chess.polyglot`, `chess.pgn` and `chess.uci` will transparently + handle both modes. + +* In a previous release `Board.fen()` has been changed to only display an + en passant square if a legal en passant move is indeed possible. This has + now also been adapted for `Board.shredder_fen()` and `Board.epd()`. + +New features: + +* Get individual FEN components: `Board.board_fen()`, `Board.castling_xfen()`, + `Board.castling_shredder_fen()`. + +* Use `Board.has_legal_en_passant()` to test if a position has a legal + en passant move. + +* Make `repr(board.legal_moves)` human readable. + +New in v0.10.1 +-------------- + +Bugfixes: + +* Fix use-after-free in Gaviota tablebase initialization. + +New in v0.10.0 +-------------- + +New dependencies: + +* If you are using Python < 3.2 you have to install `futures` in order to + use the `chess.uci` module. + +Changes: + +* There are big changes in the UCI module. Most notably in async mode multiple + commands can be executed at the same time (e.g. `go infinite` and then + `stop` or `go ponder` and then `ponderhit`). + + `go infinite` and `go ponder` will now wait for a result, i.e. you may have + to call `stop` or `ponderhit` from a different thread or run the commands + asynchronously. + + `stop` and `ponderhit` no longer have a result. + +* The values of the color constants `chess.WHITE` and `chess.BLACK` have been + changed. Previously `WHITE` was `0`, `BLACK` was `1`. Now `WHITE` is `True`, + `BLACK` is `False`. The recommended way to invert `color` is using + `not color`. + +* The pseudo piece type `chess.NONE` has been removed in favor of just using + `None`. + +* Changed the `Board(fen)` constructor. If the optional `fen` argument is not + given behavior did not change. However if `None` is passed explicitly an + empty board is created. Previously the starting position would have been + set up. + +* `Board.fen()` will now only show completely legal en passant squares. + +* `Board.set_piece_at()` and `Board.remove_piece_at()` will now clear the + move stack, because the old moves may not be valid in the changed position. + +* `Board.parse_uci()` and `Board.push_uci()` will now accept null moves. + +* Changed shebangs from `#!/usr/bin/python` to `#!/usr/bin/env python` for + better virtualenv support. + +* Removed unused game data files from repository. + +Bugfixes: + +* PGN: Prefer the game result from the game termination marker over `*` in the + header. These should be identical in standard compliant PGNs. Thanks to + Skyler Dawson for reporting this. + +* Polyglot: `minimum_weight` for `find()`, `find_all()` and `choice()` was + not respected. + +* Polyglot: Negative indexing of opening books was raising `IndexError`. + +* Various documentation fixes and improvements. + +New features: + +* Experimental probing of Gaviota tablebases via libgtb. + +* New methods to construct boards: + + .. code:: python + + >>> chess.Board.empty() + Board('8/8/8/8/8/8/8/8 w - - 0 1') + + >>> board, ops = chess.Board.from_epd("4k3/8/8/8/8/8/8/4K3 b - - fmvn 17; hmvc 13") + >>> board + Board('4k3/8/8/8/8/8/8/4K3 b - - 13 17') + >>> ops + {'fmvn': 17, 'hmvc': 13} + +* Added `Board.copy()` and hooks to let the copy module to the right thing. + +* Added `Board.has_castling_rights(color)`, + `Board.has_kingside_castling_rights(color)` and + `Board.has_queenside_castling_rights(color)`. + +* Added `Board.clear_stack()`. + +* Support common set operations on `chess.SquareSet()`. + +New in v0.9.1 +------------- + +Bugfixes: + +* UCI module could not handle castling ponder moves. Thanks to Marco Belli for + reporting. +* The initial move number in PGNs was missing, if black was to move in the + starting position. Thanks to Jürgen Précour for reporting. +* Detect more impossible en passant squares in `Board.status()`. There already + was a requirement for a pawn on the fifth rank. Now the sixth and seventh + rank must be empty, additionally. We do not do further retrograde analysis, + because these are the only cases affecting move generation. + +New in v0.8.3 +------------- + +Bugfixes: + +* The initial move number in PGNs was missing, if black was to move in the + starting position. Thanks to Jürgen Précour for reporting. +* Detect more impossible en passant squares in `Board.status()`. There already + was a requirement for a pawn on the fifth rank. Now the sixth and seventh + rank must be empty, additionally. We do not do further retrograde analysis, + because these are the only cases affecting move generation. + +New in v0.9.0 +------------- + +**This is a big update with quite a few breaking changes. Carefully review +the changes before upgrading. It's no problem if you can not update right now. +The 0.8.x branch still gets bugfixes.** + +Incompatible changes: + +* Removed castling right constants. Castling rights are now represented as a + bitmask of the rook square. For example: + + .. code:: python + + >>> board = chess.Board() + + >>> # Standard castling rights. + >>> board.castling_rights == chess.BB_A1 | chess.BB_H1 | chess.BB_A8 | chess.BB_H8 + True + + >>> # Check for the presence of a specific castling right. + >>> can_white_castle_queenside = chess.BB_A1 & board.castling_rights + + Castling moves were previously encoded as the corresponding king movement in + UCI, e.g. `e1f1` for white kingside castling. **Now castling moves are + encoded as a move to the corresponding rook square** (`UCI_Chess960`-style), + e.g. `e1a1`. + + You may use the new methods `Board.uci(move, chess960=True)`, + `Board.parse_uci(uci)` and `Board.push_uci(uci)` to handle this + transparently. + + The `uci` module takes care of converting moves when communicating with an + engine that is not in `UCI_Chess960` mode. + +* The `get_entries_for_position(board)` method of polyglot opening book readers + has been changed to `find_all(board, minimum_weight=1)`. By default entries + with weight 0 are excluded. + +* The `Board.pieces` lookup list has been removed. + +* In 0.8.1 the spelling of repetition (was repitition) was fixed. + `can_claim_threefold_repetition()` and `is_fivefold_repetition()` are the + affected method names. Aliases are now removed. + +* `Board.set_epd()` will now interpret `bm`, `am` as a list of moves for the + current position and `pv` as a variation (represented by a list of moves). + Thanks to Jordan Bray for reporting this. + +* Removed `uci.InfoHandler.pre_bestmove()` and + `uci.InfoHandler.post_bestmove()`. + +* `uci.InfoHandler().info["score"]` is now relative to multipv. Use + + .. code:: python + + >>> with info_handler as info: + ... if 1 in info["score"]: + ... cp = info["score"][1].cp + + where you were previously using + + .. code:: python + + >>> with info_handler as info: + ... if "score" in info: + ... cp = info["score"].cp + +* Clear `uci.InfoHandler()` dictionary at the start of new searches + (new `on_go()`), not at the end of searches. + +* Renamed `PseudoLegalMoveGenerator.bitboard` and `LegalMoveGenerator.bitboard` + to `PseudoLegalMoveGenerator.board` and `LegalMoveGenerator.board`, + respectively. + +* Scripts removed. + +* Python 3.2 compatibility dropped. Use Python 3.3 or higher. Python 2.7 + support is not affected. + +New features: + +* **Introduced Chess960 support.** `Board(fen)` and `Board.set_fen(fen)` now + support X-FENs. Added `Board.shredder_fen()`. + `Board.status(allow_chess960=True)` has an optional argument allowing to + insist on standard chess castling rules. + Added `Board.is_valid(allow_chess960=True)`. + +* **Improved move generation using** `Shatranj-style direct lookup + `_. **Removed rotated bitboards. Perft + speed has been more than doubled.** + +* Added `choice(board)` and `weighted_choice(board)` for polyglot opening book + readers. + +* Added `Board.attacks(square)` to determine attacks *from* a given square. + There already was `Board.attackers(color, square)` returning attacks *to* + a square. + +* Added `Board.is_en_passant(move)`, `Board.is_capture(move)` and + `Board.is_castling(move)`. + +* Added `Board.pin(color, square)` and `Board.is_pinned(color, square)`. + +* There is a new method `Board.pieces(piece_type, color)` to get a set of + squares with the specified pieces. + +* Do expensive Syzygy table initialization on demand. + +* Allow promotions like `e8Q` (usually `e8=Q`) in `Board.parse_san()` and + PGN files. + +* Patch by Richard C. Gerkin: Added `Board.__unicode__()` just like + `Board.__str__()` but with unicode pieces. +* Patch by Richard C. Gerkin: Added `Board.__html__()`. + +New in v0.8.2 +------------- + +Bugfixes: + +* `pgn.Game.setup()` with the standard starting position was failing when the + standard starting position was already set. Thanks to Jordan Bray for + reporting this. + +Optimizations: + +* Remove `bswap()` from Syzygy decompression hot path. Directly read integers + with the correct endianness. + +New in v0.8.1 +------------- + +* Fixed pondering mode in uci module. For example `ponderhit()` was blocking + indefinitely. Thanks to Valeriy Huz for reporting this. + +* Patch by Richard C. Gerkin: Moved searchmoves to the end of the UCI go + command, where it will not cause other command parameters to be ignored. + +* Added missing check or checkmate suffix to castling SANs, e.g. `O-O-O#`. + +* Fixed off-by-one error in polyglot opening book binary search. This would + not have caused problems for real opening books. + +* Fixed Python 3 support for reverse polyglot opening book iteration. + +* Bestmoves may be literally `(none)` in UCI protocol, for example in + checkmate positions. Fix parser and return `None` as the bestmove in this + case. + +* Fixed spelling of repetition (was repitition). + `can_claim_threefold_repetition()` and `is_fivefold_repetition()` are the + affected method names. Aliases are there for now, but will be removed in the + next release. Thanks to Jimmy Patrick for reporting this. + +* Added `SquareSet.__reversed__()`. + +* Use containerized tests on Travis CI, test against Stockfish 6, improved + test coverage amd various minor clean-ups. + +New in v0.8.0 +------------- + +* **Implement Syzygy endgame tablebase probing.** + `https://syzygy-tables.info `_ + is an example project that provides a public API using the new features. + +* The interface for aynchronous UCI command has changed to mimic + `concurrent.futures`. `is_done()` is now just `done()`. Callbacks will + receive the command object as a single argument instead of the result. + The `result` property and `wait()` have been removed in favor of a + synchronously waiting `result()` method. + +* The result of the `stop` and `go` UCI commands are now named tuples (instead + of just normal tuples). + +* Add alias `Board` for `Bitboard`. + +* Fixed race condition during UCI engine startup. Lines received during engine + startup sometimes needed to be processed before the Engine object was fully + initialized. + +New in v0.7.0 +------------- + +* **Implement UCI engine communication.** + +* Patch by Matthew Lai: `Add caching for gameNode.board()`. + +New in v0.6.0 +------------- + +* If there are comments in a game before the first move, these are now assigned + to `Game.comment` instead of `Game.starting_comment`. `Game.starting_comment` + is ignored from now on. `Game.starts_variation()` is no longer true. + The first child node of a game can no longer have a starting comment. + It is possible to have a game with `Game.comment` set, that is otherwise + completely empty. + +* Fix export of games with variations. Previously the moves were exported in + an unusual (i.e. wrong) order. + +* Install `gmpy2` or `gmpy` if you want to use slightly faster binary + operations. + +* Ignore superfluous variation opening brackets in PGN files. + +* Add `GameNode.san()`. + +* Remove `sparse_pop_count()`. Just use `pop_count()`. + +* Remove `next_bit()`. Now use `bit_scan()`. + +New in v0.5.0 +------------- + +* PGN parsing is now more robust: `read_game()` ignores invalid tokens. + Still exceptions are going to be thrown on illegal or ambiguous moves, but + this behaviour can be changed by passing an `error_handler` argument. + + .. code:: python + + >>> # Raises ValueError: + >>> game = chess.pgn.read_game(file_with_illegal_moves) + + .. code:: python + + >>> # Silently ignores errors and continues parsing: + >>> game = chess.pgn.read_game(file_with_illegal_moves, None) + + .. code:: python + + >>> # Logs the error, continues parsing: + >>> game = chess.pgn.read_game(file_with_illegal_moves, logger.exception) + + If there are too many closing brackets this is now ignored. + + Castling moves like 0-0 (with zeros) are now accepted in PGNs. + The `Bitboard.parse_san()` method remains strict as always, though. + + Previously the parser was strictly following the PGN spefification in that + empty lines terminate a game. So a game like + + :: + + [Event "?"] + + { Starting comment block } + + 1. e4 e5 2. Nf3 Nf6 * + + would have ended directly after the starting comment. To avoid this, the + parser will now look ahead until it finds at least one move or a termination + marker like `*`, `1-0`, `1/2-1/2` or `0-1`. + +* Introduce a new function `scan_headers()` to quickly scan a PGN file for + headers without having to parse the full games. + +* Minor testcoverage improvements. + +New in v0.4.2 +------------- + +* Fix bug where `pawn_moves_from()` and consequently `is_legal()` weren't + handling en passant correctly. Thanks to Norbert Naskov for reporting. + +New in v0.4.1 +------------- + +* Fix `is_fivefold_repitition()`: The new fivefold repetition rule requires + the repetitions to occur on *alternating consecutive* moves. + +* Minor testing related improvements: Close PGN files, allow running via + setuptools. + +* Add recently introduced features to README. + +New in v0.4.0 +------------- + +* Introduce `can_claim_draw()`, `can_claim_fifty_moves()` and + `can_claim_threefold_repitition()`. + +* Since the first of July 2014 a game is also over (even without claim by one + of the players) if there were 75 moves without a pawn move or capture or + a fivefold repetition. Let `is_game_over()` respect that. Introduce + `is_seventyfive_moves()` and `is_fivefold_repitition()`. Other means of + ending a game take precedence. + +* Threefold repetition checking requires efficient hashing of positions + to build the table. So performance improvements were needed there. The + default polyglot compatible zobrist hashes are now built incrementally. + +* Fix low level rotation operations `l90()`, `l45()` and `r45()`. There was + no problem in core because correct versions of the functions were inlined. + +* Fix equality and inequality operators for `Bitboard`, `Move` and `Piece`. + Also make them robust against comparisons with incompatible types. + +* Provide equality and inequality operators for `SquareSet` and + `polyglot.Entry`. + +* Fix return values of incremental arithmetical operations for `SquareSet`. + +* Make `polyglot.Entry` a `collections.namedtuple`. + +* Determine and improve test coverage. + +* Minor coding style fixes. + +New in v0.3.1 +------------- + +* `Bitboard.status()` now correctly detects `STATUS_INVALID_EP_SQUARE`, + instead of errors or false reports. + +* Polyglot opening book reader now correctly handles knight underpromotions. + +* Minor coding style fixes, including removal of unused imports. + +New in v0.3.0 +------------- + +* Rename property `half_moves` of `Bitboard` to `halfmove_clock`. + +* Rename property `ply` of `Bitboard` to `fullmove_number`. + +* Let PGN parser handle symbols like `!`, `?`, `!?` and so on by converting + them to NAGs. + +* Add a human readable string representation for Bitboards. + + .. code:: python + + >>> print(chess.Bitboard()) + r n b q k b n r + p p p p p p p p + . . . . . . . . + . . . . . . . . + . . . . . . . . + . . . . . . . . + P P P P P P P P + R N B Q K B N R + +* Various documentation improvements. + +New in v0.2.0 +------------- + +* **Implement PGN parsing and writing.** +* Hugely improve test coverage and use Travis CI for continuous integration and + testing. +* Create an API documentation. +* Improve Polyglot opening-book handling. + +New in v0.1.0 +------------- + +Apply the lessons learned from the previous releases, redesign the API and +implement it in pure Python. + +New in v0.0.4 +------------- + +Implement the basics in C++ and provide bindings for Python. Obviously +performance was a lot better - but at the expense of having to compile +code for the target platform. + +Pre v0.0.4 +---------- + +First experiments with a way too slow pure Python API, creating way too many +objects for basic operations. diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 59203f672..48fe80784 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,1884 +27,4 @@ Bugfixes: New in v1.0.0 ------------- -Changes: - -* Now requires Python 3.7+. -* `chess.engine` will now cut off illegal principal variations at the first - illegal move instead of discarding them entirely. -* `chess.engine.EngineProtocol` renamed to `chess.engine.Protocol`. -* `chess.engine.Option` is no longer a named tuple. -* Renamed `chess.gaviota` internals. -* Relaxed type annotations of `chess.pgn.GameNode.variation()` and related - methods. -* Changed default colors of `chess.svg.Arrow` and - `chess.pgn.GameNode.arrows()`. These can be overriden with the new - `chess.svg.board(..., colors)` feature. -* Documentation improvements. Will now show type aliases like `chess.Square` - instead of `int`. - -Bugfixes: - -* Fix insufficient material with same-color bishops on both sides. -* Clarify that `chess.Board.can_claim_draw()` and related methods refer to - claims by the player to move. Three-fold repetition could already be claimed - before making the final repeating move. `chess.Board.can_claim_fifty_moves()` - now also allows a claim before the final repeating move. The previous - behavior is `chess.Board.is_fifty_moves()`. -* Fix parsing of green arrows/circles in `chess.pgn.GameNode.arrows()`. -* Fix overloaded type signature of `chess.engine.Protocol.engine()`. - -New features: - -* Added `chess.parse_square()`, to be used instead of - `chess.SQUARE_NAMES.index()`. -* Added `chess.Board.apply_mirror()`. -* Added `chess.svg.board(..., colors)`, to allow overriding the default theme. - -New in v0.31.4 --------------- - -Bugfixes: - -* Fix inconsistency where `board.is_legal()` was not accepting castling moves - in Chess960 notation (when board is in standard mode), while all other - methods did. -* Fix `chess.pgn.GameNode.set_clock()` with negative or floating point values. -* Avoid leading and trailing spaces in PGN comments when setting annotations. - -New features: - -* Finish typing and declare support for mypy. - -New in v0.31.3 --------------- - -Bugfixes: - -* Custom castling rights assigned to `board.castling_rights` or castling rights - left over after `Board.set_board_fen()` were not correctly cleaned after - the first move. - -Changes: - -* Ignore up to one consecutive empty line between PGN headers. -* Added PGN Variant `From Position` as an alias for standard chess. -* `chess.pgn.FileExporter.result()` now returns the number of written - characters. -* `chess.engine` now avoids sending 0 for search limits, which some engines - misunderstand as no limit. -* `chess.engine` better handles null moves sent to the engine. -* `chess.engine` now gracefully handles `NULL` ponder moves and uppercase - moves received from UCI engines, which is technically invalid. - -New features: - -* Added `chess.pgn.GameNode.{clock, set_clock}()` to read and write - `[%clk ...]` **PGN annotations**. -* Added `chess.pgn.GameNode.{arrows, set_arrows}()` to read and write - `[%csl ...]` and `[%cal ...]` PGN annotations. -* Added `chess.pgn.GameNode.{eval, set_eval}()` to read and write - `[%eval ...]` PGN annotations. -* Added `SquareSet.ray(a, b)` and `SquareSet.between(a, b)`. - -New in v0.31.2 --------------- - -Bugfixes: - -* Fix rejected/accepted in `chess.engine.XBoardProtocol`. -* Misc typing fixes. - -Changes: - -* Deprecated `chess.syzygy.is_table_name()`. Replaced with - `chess.syzygy.is_tablename()` which has additional parameters and defaults to - `one_king`. -* Take advantage of `int.bit_count()` coming in Python 3.10. - -New in v0.31.1 --------------- - -Bugfixes: - -* `RacingKingsBoard.is_variant_win()` no longer incorrectly returns `True` - for drawn positions. -* Multiple moves for EPD opcodes *am* and *bm* are now sorted as required by - the specification. -* Coordinates of SVG boards are now properly aligned, even when rendered as - SVG Tiny. - -Changes: - -* SVG boards now have a background color for the coordinate margin, making - coordinates readable on dark backgrounds. -* Added *[Variant "Illegal"]* as an alias for standard chess - (used by Chessbase). - -Features: - -* Added `Board.find_move()`, useful for finding moves that match human input. - -New in v0.31.0 --------------- - -Changes: - -* Replaced lookup table `chess.BB_BETWEEN[a][b]` with a function - `chess.between(a, b)`. Improves initialization and runtime performance. -* `chess.pgn.BaseVisitor.result()` is now an abstract method, forcing - subclasses to implement it. -* Removed helper attributes from `chess.engine.InfoDict`. Instead it is now - a `TypedDict`. -* `chess.engine.PovScore` equality is now semantic instead of structural: - Scores compare equal to the negative score from the opposite point of view. - -Bugfixes: - -* `chess.Board.is_irreversible()` now considers ceding legal en passant - captures as irreversible. Also documented that false-negatives due to forced - lines are by design. -* Fixed stack overflow in `chess.pgn` when exporting, visiting or getting the - final board of a very long game. -* Clarified documentation regarding board validity. -* `chess.pgn.GameNode.__repr__()` no longer errors if the root node has invalid - FEN or Variant headers. -* Carriage returns are no longer allowed in PGN header values, fixing - reparsability. -* Fixed type error when XBoard name or egt features have a value that looks - like an integer. -* `chess.engine` is now passing type checks with mypy. -* `chess.gaviota` is now passing type checks with mypy. - -Features: - -* Added `chess.Board.gives_check()`. -* `chess.engine.AnalysisResult.wait()` now returns `chess.engine.BestMove`. -* Added `empty_square` parameter for `chess.Board.unicode()` with better - aligned default (⭘). - -New in v0.30.1 --------------- - -Changes: - -* Positions with more than two checkers are considered invalid and - `board.status()` returns `chess.STATUS_TOO_MANY_CHECKERS`. -* Pawns drops in Crazyhouse are considered zeroing and reset - `board.halfmove_clock` when played. -* Now validating file sizes when opening Syzygy tables and Polyglot opening - books. -* Explicitly warn about untrusted tablebase files and chess engines. - -Bugfixes: - -* Fix Racing Kings game end detection: Black cannot catch up if their own - pieces block the goal. White would win on the next turn, so this did not - impact the game theoretical outcome of the game. -* Fix bugs discovered by fuzzing the EPD parser: Fixed serialization of - empty strings, reparsability of empty move lists, handling of non-finite - floats, and handling of whitespace in opcodes. - -Features: - -* Added `board.checkers()`, returning a set of squares with the pieces giving - check. - -New in v0.30.0 --------------- - -Changes: - -* **Dropped support for Python 3.5.** -* Remove explicit loop arguments in `chess.engine` module, following - https://bugs.python.org/issue36373. - -Bugfixes: - -* `chess.engine.EngineProtocol.returncode` is no longer poisoned when - `EngineProtocol.quit()` times out. -* `chess.engine.PlayResult.info` was not always of type - `chess.engine.InfoDict`. - -Features: - -* The background thread spawned by `chess.engine.SimpleEngine` is now named - for improved debuggability, revealing the PID of the engine process. -* `chess.engine.EventLoopPolicy` now supports `asyncio.PidfdChildWatcher` - when running on Python 3.9+ and Linux 5.3+. -* Add `chess.Board.san_and_push()`. - -New in v0.29.0 --------------- - -Changes: - -* `chess.variant.GiveawayBoard` **now starts with castling rights**. - `chess.variant.AntichessBoard` is the same variant without castling rights. -* UCI info parser no longer reports errors when encountering unknown tokens. -* Performance improvements for repetition detection. -* Since Python 3.8: `chess.syzygy`/`chess.polyglot` use `madvise(MADV_RANDOM)` - to prepare table/book files for random access. - -Bugfixes: - -* Fix syntax error in type annotation of `chess.engine.run_in_background()`. -* Fix castling rights when king is exploded in Atomic. Mitigated by the fact - that the game is over and that it did not affect FEN. -* Fix insufficient material with underpromoted pieces in Crazyhouse. Mitigated - by the fact that affected positions are unreachable in Crazyhouse. - -Features: - -* Support `wdl` in UCI info (usually activated with `UCI_ShowWDL`). - -New in v0.28.3 --------------- - -Bugfixes: - -* Follow FICS rules in Atomic castling edge cases. -* Handle self-reported errors by XBoard engines "Error: ..." or - "Illegal move: ...". - -New in v0.28.2 --------------- - -Bugfixes: - -* Fixed exception propagation, when a UCI engine sends an invalid `bestmove`. - Thanks @fsmosca. - -Changes: - -* `chess.Move.from_uci()` no longer accepts moves from and to the same square, - for example `a1a1`. `0000` is now the only valid null move notation. - -New in v0.28.1 --------------- - -Bugfixes: - -* The minimum Python version is 3.5.3 (instead of 3.5.0). -* Fix `board.is_irreversible()` when capturing a rook that had castling rights. - -Changes: - -* `is_en_passant()`, `is_capture()`, `is_zeroing()`, `is_irreversible()`, - `is_castling()`, `is_kingside_castling()` and `is_queenside_castling()` - now consistently return `False` for null moves. -* Added `chess.engine.InfoDict` class with typed shorthands for common keys. -* Support `[Variant "3-check"]` (from chess.com PGNs). - -New in v0.28.0 --------------- - -Changes: - -* Dropped support for Python 3.4 (end of life reached). -* `chess.polyglot.Entry.move` **is now a property instead of a method**. - The raw move is now always decoded in the context of the position (relevant - for castling moves). -* `Piece`, `Move`, `BaseBoard` and `Board` comparisons no longer support - duck typing. -* FENs sent to engines now always include potential en passant squares, even if - no legal en passant capture exists. -* Circular SVG arrows now have a `circle` CSS class. -* Superfluous dashes (-) in EPDs are no longer treated as opcodes. -* Removed `GameCreator`, `HeaderCreator` and `BoardCreator` aliases for - `{Game,Headers,Board}Builder`. - -Bugfixes: - -* Notation like `Kh1` is no longer accepted for castling moves. -* Remove stale files from wheels published on PyPI. -* Parsing Three-Check EPDs with moves was always failing. -* Some methods in `chess.variant` were returning bool-ish integers, when they - should have returned `bool`. -* `chess.engine`: Fix line decoding when Windows line-endings arrive seperately - in stdout buffer. -* `chess.engine`: Survive timeout in analysis. -* `chess.engine`: Survive unexpected `bestmove` sent by misbehaving UCI engines. - -New features: - -* **Experimental type signatures for almost all public APIs** (`typing`). - Some modules do not yet internally pass typechecking. -* Added `Board.color_at(square)`. -* Added `chess.engine.AnalysisResult.get()` and `empty()`. -* `chess.engine`: The `UCI_AnalyseMode` option is still automatically managed, - but can now be overwritten. -* `chess.engine.EngineProtocol` and constructors now optionally take - an explicit `loop` argument. - -New in v0.27.3 --------------- - -Changes: - -* `XBoardProtocol` will no longer raise an exception when the engine resigned. - Instead it sets a new flag `PlayResult.resigned`. `resigned` and - `draw_offered` are keyword-only arguments. -* Renamed `chess.pgn.{Game,Header,Board}Creator` to - `{Game,Headers,Board}Builder`. Aliases kept in place. - -Bugfixes: - -* Make `XBoardProtocol` robust against engines that send a move after claiming - a draw or resigning. Thanks @pascalgeo. -* `XBoardProtocol` no longer ignores `Hint:` sent by the engine. -* Fix handling of illegal moves in `XBoardProtocol`. -* Fix exception when engine is shut down while pondering. -* Fix unhandled internal exception and file descriptor leak when engine - initialization fails. -* Fix `HordeBoard.status()` when black pieces are on the first rank. - Thanks @Wisling. - -New features: - -* Added `chess.pgn.Game.builder()`, `chess.pgn.Headers.builder()` and - `chess.pgn.GameNode.dangling_node()` to simplify subclassing `GameNode`. -* `EngineProtocol.communicate()` is now also available in the synchronous API. - -New in v0.27.2 --------------- - -Bugfixes: - -* `chess.engine.XBoardProtocol.play()` was searching 100 times longer than - intended when using `chess.engine.Limit.time`, and searching 100 times more - nodes than intended when using `chess.engine.Limit.nodes`. Thanks @pascalgeo. - -New in v0.27.1 --------------- - -Bugfixes: - -* `chess.engine.XBoardProtocol.play()` was raising `KeyError` when using time - controls with increment or remaining moves. Thanks @pascalgeo. - -New in v0.27.0 --------------- - -This is the second **release candidate for python-chess 1.0**. If you see the -need for breaking changes, please speak up now! - -Bugfixes: - -* `EngineProtocol.analyse(*, multipv)` was not passing this argument to the - engine and therefore only returned the first principal variation. - Thanks @svangordon. -* `chess.svg.board(*, squares)`: The X symbol on selected squares is now more - visible when it overlaps pieces. - -Changes: - -* **FEN/EPD parsing is now more relaxed**: Incomplete FENs and EPDs are - completed with reasonable defaults (`w - - 0 1`). The EPD parser accepts - fields with moves in UCI notation (for example the technically invalid - `bm g1f3` instead of `bm Nf3`). -* The PGN parser now skips games with invalid FEN headers and variations after - an illegal move (after handling the error as usual). - -New features: - -* Added `Board.is_repetition(count=3)`. -* Document that `chess.engine.EngineProtocol` is compatible with - AsyncSSH 1.16.0. - -New in v0.26.0 --------------- - -This is the first **release candidate for python-chess 1.0**. If you see the -need for breaking changes, please speak up now! - -Changes: - -* `chess.engine` **is now stable and replaces** - `chess.uci` **and** `chess.xboard`. -* Advanced: `EngineProtocol.initialize()` is now public for use with custom - transports. -* Removed `__ne__` implementations (not required since Python 3). -* Assorted documentation and coding-style improvements. - -New features: - -* Check insufficient material for a specific side: - `board.has_insufficient_material(color)`. -* Copy boards with limited stack depth: `board.copy(stack=depth)`. - -Bugfixes: - -* Properly handle delayed engine errors, for example unsupported options. - -New in v0.25.1 --------------- - -Bugfixes: - -* `chess.engine` did not correctly handle Windows-style line endings. - Thanks @Bstylestuff. - -New in v0.25.0 --------------- - -New features: - -* This release introduces a new **experimental API for chess engine - communication**, `chess.engine`, based on `asyncio`. It is intended to - eventually replace `chess.uci` and `chess.xboard`. - -Bugfixes: - -* Fixed race condition in LRU-cache of open Syzygy tables. The LRU-cache is - enabled by default (*max_fds*). -* Fix deprecation warning and unclosed file in setup.py. - Thanks Mickaël Schoentgen. - -Changes: - -* `chess.pgn.read_game()` now ignores BOM at the start of the stream. -* Removed deprecated items. - -New in v0.24.2 --------------- - -Bugfixes: - -* `CrazyhouseBoard.root()` and `ThreeCheckBoard.root()` were not returning the - correct pockets and number of remaining checks, respectively. Thanks @gbtami. -* `chess.pgn.skip_game()` now correctly skips PGN comments that contain - line-breaks and PGN header tag notation. - -Changes: - -* Renamed `chess.pgn.GameModelCreator` to `GameCreator`. Alias kept in place - and will be removed in a future release. -* Renamed `chess.engine` to `chess._engine`. Use re-exports from `chess.uci` - or `chess.xboard`. -* Renamed `Board.stack` to `Board._stack`. Do not use this directly. -* Improved memory usage: `Board.legal_moves` and `Board.pseudo_legal_moves` - no longer create reference cycles. PGN visitors can manage headers - themselves. -* Removed previously deprecated items. - -Features: - -* Added `chess.pgn.BaseVisitor.visit_board()` and `chess.pgn.BoardCreator`. - -New in v0.24.1, v0.23.11 ------------------------- - -Bugfixes: - -* Fix `chess.Board.set_epd()` and `chess.Board.from_epd()` with semicolon - in string operand. Thanks @jdart1. -* `chess.pgn.GameNode.uci()` was always raising an exception. - Also included in v0.24.0. - -New in v0.24.0 --------------- - -This release **drops support for Python 2**. The *0.23.x* branch will be -maintained for one more month. - -Changes: - -* **Require Python 3.4.** Thanks @hugovk. -* No longer using extra pip features: - `pip install python-chess[engine,gaviota]` is now `pip install python-chess`. -* Various keyword arguments can now be used as **keyword arguments only**. -* `chess.pgn.GameNode.accept()` now - **also visits the move leading to that node**. -* `chess.pgn.GameModelCreator` now requires that `begin_game()` be called. -* `chess.pgn.scan_headers()` and `chess.pgn.scan_offsets()` have been removed. - Instead the new functions `chess.pgn.read_headers()` and - `chess.pgn.skip_game()` can be used for a similar purpose. -* `chess.syzygy`: Invalid magic headers now raise `IOError`. Previously they - were only checked in an assertion. - `type(board).{tbw_magic,tbz_magic,pawnless_tbw_magic,pawnless_tbz_magic}` - are now byte literals. -* `board.status()` constants (`STATUS_`) are now typed using `enum.IntFlag`. - Values remain unchanged. -* `chess.svg.Arrow` is no longer a `namedtuple`. -* `chess.PIECE_SYMBOLS[0]` and `chess.PIECE_NAMES[0]` are now `None` instead - of empty strings. -* Performance optimizations: - - * `chess.pgn.Game.from_board()`, - * `chess.square_name()` - * Replace `collections.deque` with lists almost everywhere. - -* Renamed symbols (aliases will be removed in the next release): - - * `chess.BB_VOID` -> `BB_EMPTY` - * `chess.bswap()` -> `flip_vertical()` - * `chess.pgn.GameNode.main_line()` -> `mainline_moves()` - * `chess.pgn.GameNode.is_main_line()` -> `is_mainline()` - * `chess.variant.BB_HILL` -> `chess.BB_CENTER` - * `chess.syzygy.open_tablebases()` -> `open_tablebase()` - * `chess.syzygy.Tablebases` -> `Tablebase` - * `chess.syzygy.Tablebase.open_directory()` -> `add_directory()` - * `chess.gaviota.open_tablebases()` -> `open_tablebase()` - * `chess.gaviota.open_tablebases_native()` -> `open_tablebase_native()` - * `chess.gaviota.NativeTablebases` -> `NativeTablebase` - * `chess.gaviota.PythonTablebases` -> `PythonTablebase` - * `chess.gaviota.NativeTablebase.open_directory()` -> `add_directory()` - * `chess.gaviota.PythonTablebase.open_directory()` -> `add_directory()` - -Bugfixes: - -* The PGN parser now gives the visitor a chance to handle unknown chess - variants and continue parsing. -* `chess.pgn.GameNode.uci()` was always raising an exception. - -New features: - -* `chess.SquareSet` now extends `collections.abc.MutableSet` and can be - initialized from iterables. -* `board.apply_transform(f)` and `board.transform(f)` can apply bitboard - transformations to a position. Examples: - `chess.flip_{vertical,horizontal,diagonal,anti_diagonal}`. -* `chess.pgn.GameNode.mainline()` iterates over nodes of the mainline. - Can also be used with `reversed()`. Reversal is now also supported for - `chess.pgn.GameNode.mainline_moves()`. -* `chess.svg.Arrow(tail, head, color="#888")` gained an optional *color* - argument. -* `chess.pgn.BaseVisitor.parse_san(board, san)` is used by parsers and can - be overwritten to deal with non-standard input formats. -* `chess.pgn`: Visitors can advise the parser to skip games or variations by - returning the special value `chess.pgn.SKIP` from `begin_game()`, - `end_headers()` or `begin_variation()`. This is only a hint. - The corresponding `end_game()` or `end_variation()` will still be called. -* Added `chess.svg.MARGIN`. - -New in v0.23.10 ---------------- - -Bugfixes: - -* `chess.SquareSet` now correctly handles negative masks. Thanks @hasnul. -* `chess.pgn` now accepts `[Variant "chess 960"]` (with the space). - -New in v0.23.9 --------------- - -Changes: - -* Updated `Board.is_fivefold_repetition()`. FIDE rules have changed and the - repetition no longer needs to occur on consecutive alternating moves. - Thanks @LegionMammal978. - -New in v0.23.8 --------------- - -Bugfixes: - -* `chess.syzygy`: Correctly initialize wide DTZ map for experimental 7 piece - table KRBBPvKQ. - -New in v0.23.7 --------------- - -Bugfixes: - -* Fixed `ThreeCheckBoard.mirror()` and `CrazyhouseBoard.mirror()`, which - were previously resetting remaining checks and pockets respectively. - Thanks @QueensGambit. - -Changes: - -* `Board.move_stack` is now guaranteed to be UCI compatible with respect to - the representation of castling moves and `board.chess960`. -* Drop support for Python 3.3, which is long past end of life. -* `chess.uci`: The `position` command now manages `UCI_Chess960` and - `UCI_Variant` automatically. -* `chess.uci`: The `position` command will now always send the entire history - of moves from the root position. -* Various coding style fixes and improvements. Thanks @hugovk. - -New features: - -* Added `Board.root()`. - -New in v0.23.6 --------------- - -Bugfixes: - -* Gaviota: Fix Python based Gaviota tablebase probing when there are multiple - en passant captures. Thanks @bjoernholzhauer. -* Syzygy: Fix DTZ for some mate in 1 positions. Similarly to the fix from - v0.23.1 this is mostly cosmetic. -* Syzygy: Fix DTZ off-by-one in some 6 piece antichess positions with moves - that threaten to force a capture. This is mostly cosmetic. - -Changes: - -* Let `uci.Engine.position()` send history of at least 8 moves if available. - Previously it sent only moves that were relevant for repetition detection. - This is mostly useful for Lc0. Once performance issues are solved, a future - version will always send the entire history. Thanks @SashaMN and @Mk-Chan. -* Various documentation fixes and improvements. - -New features: - -* Added `polyglot.MemoryMappedReader.get(board, default=None)`. - -New in v0.23.5 --------------- - -Bugfixes: - -* Atomic chess: KNvKN is not insufficient material. -* Crazyhouse: Detect insufficient material. This can not happen unless the - game was started with insufficient material. - -Changes: - -* Better error messages when parsing info from UCI engine fails. -* Better error message for `b.set_board_fen(b.fen())`. - -New in v0.23.4 --------------- - -New features: - -* XBoard: Support pondering. Thanks Manik Charan. -* UCI: Support unofficial `info ebf`. - -Bugfixes: - -* Implement 16 bit DTZ mapping, which is required for some of the longest - 7 piece endgames. - -New in v0.23.3 --------------- - -New features: - -* XBoard: Support `variant`. Thanks gbtami. - -New in v0.23.2 --------------- - -Bugfixes: - -* XBoard: Handle multiple features and features with spaces. Thanks gbtami. -* XBoard: Ignore debug output prefixed with `#`. Thanks Dan Ravensloft and - Manik Charan. - -New in v0.23.1 --------------- - -Bugfixes: - -* Fix DTZ in case of mate in 1. This is a cosmetic fix, as the previous - behavior was only off by one (which is allowed by design). - -New in v0.23.0 --------------- - -New features: - -* Experimental support for 7 piece Syzygy tablebases. - -Changes: - -* `chess.syzygy.filenames()` was renamed to `tablenames()` and - gained an optional `piece_count=6` argument. -* `chess.syzygy.normalize_filename()` was renamed to `normalize_tablename()`. -* The undocumented constructors of `chess.syzygy.WdlTable` and - `chess.syzygy.DtzTable` have been changed. - -New in v0.22.2 --------------- - -Bugfixes: - -* In standard chess promoted pieces were incorrectly considered as - distinguishable from normal pieces with regard to position equality - and threefold repetition. Thanks to kn-sq-tb for reporting. - -Changes: - -* The PGN `game.headers` are now a custom mutable mapping that validates the - validity of tag names. -* Basic attack and pin methods moved to `BaseBoard`. -* Documentation fixes and improvements. - -New features: - -* Added `Board.lan()` for long algebraic notation. - -New in v0.22.1 --------------- - -New features: - -* Added `Board.mirror()`, `SquareSet.mirror()` and `bswap()`. -* Added `chess.pgn.GameNode.accept_subgame()`. -* XBoard: Added `resign`, `analyze`, `exit`, `name`, `rating`, `computer`, - `egtpath`, `pause`, `resume`. Completed option parsing. - -Changes: - -* `chess.pgn`: Accept FICS wilds without warning. -* XBoard: Inform engine about game results. - -Bugfixes: - -* `chess.pgn`: Allow games without movetext. -* XBoard: Fixed draw handling. - -New in v0.22.0 --------------- - -Changes: - -* `len(board.legal_moves)` **replaced by** `board.legal_moves.count()`. - Previously `list(board.legal_moves)` was generating moves twice, resulting in - a considerable slowdown. Thanks to Martin C. Doege for reporting. -* **Dropped Python 2.6 support.** -* XBoard: `offer_draw` renamed to `draw`. - -New features: - -* XBoard: Added `DrawHandler`. - -New in v0.21.2 --------------- - -Changes: - -* `chess.svg` is now fully SVG Tiny 1.2 compatible. Removed - `chess.svg.DEFAULT_STYLE` which would from now on be always empty. - -New in v0.21.1 --------------- - -Bugfixes: - -* `Board.set_piece_at()` no longer shadows optional `promoted` - argument from `BaseBoard`. -* Fixed `ThreeCheckBoard.is_irreversible()` and - `ThreeCheckBoard._transposition_key()`. - -New features: - -* Added `Game.without_tag_roster()`. `chess.pgn.StringExporter()` can now - handle games without any headers. -* XBoard: `white`, `black`, `random`, `nps`, `otim`, `undo`, `remove`. Thanks - to Manik Charan. - -Changes: - -* Documentation fixes and tweaks by Boštjan Mejak. -* Changed unicode character for empty squares in `Board.unicode()`. - -New in v0.21.0 --------------- - -Release yanked. - -New in v0.20.1 --------------- - -Bugfixes: - -* Fix arrow positioning on SVG boards. -* Documentation fixes and improvements, making most doctests runnable. - -New in v0.20.0 --------------- - -Bugfixes: - -* Some XBoard commands were not returning futures. -* Support semicolon comments in PGNs. - -Changes: - -* Changed FEN and EPD formatting options. It is now possible to include en - passant squares in FEN and X-FEN style, or to include only strictly relevant - en passant squares. -* Relax en passant square validation in `Board.set_fen()`. -* Ensure `is_en_passant()`, `is_capture()`, `is_zeroing()` and - `is_irreversible()` strictly return bools. -* Accept `Z0` as a null move in PGNs. - -New features: - -* XBoard: Add `memory`, `core`, `stop` and `movenow` commands. - Abstract `post`/`nopost`. Initial `FeatureMap` support. Support `usermove`. -* Added `Board.has_pseudo_legal_en_passant()`. -* Added `Board.piece_map()`. -* Added `SquareSet.carry_rippler()`. -* Factored out some (unstable) low level APIs: `BB_CORNERS`, - `_carry_rippler()`, `_edges()`. - -New in v0.19.0 --------------- - -New features: - -* **Experimental XBoard engine support.** Thanks to Manik Charan and - Cash Costello. Expect breaking changes in future releases. -* Added an undocumented `chess.polyglot.ZobristHasher` to make Zobrist hashing - easier to extend. - -Bugfixes: - -* Merely pseudo-legal en passant does no longer count for repetitions. -* Fixed repetition detection in Three-Check and Crazyhouse. (Previously - check counters and pockets were ignored.) -* Checking moves in Three-Check are now considered as irreversible by - `ThreeCheckBoard.is_irreversible()`. -* `chess.Move.from_uci("")` was raising `IndexError` instead of `ValueError`. - Thanks Jonny Balls. - -Changes: - -* `chess.syzygy.Tablebases` constructor no longer supports directly opening - a directory. Use `chess.syzygy.open_tablebases()`. -* `chess.gaviota.PythonTablebases` and `NativeTablebases` constructors - no longer support directly opening a directory. - Use `chess.gaviota.open_tablebases()`. -* `chess.Board` instances are now compared by the position they represent, - not by exact match of the internal data structures (or even move history). -* Relaxed castling right validation in Chess960: Kings/rooks of opposing sites - are no longer required to be on the same file. -* Removed misnamed `Piece.__unicode__()` and `BaseBoard.__unicode__()`. Use - `Piece.unicode_symbol()` and `BaseBoard.unicode()` instead. -* Changed `chess.SquareSet.__repr__()`. -* Support `[Variant "normal"]` in PGNs. -* `pip install python-chess[engine]` instead of `python-chess[uci]` (since - the extra dependencies are required for both UCI and XBoard engines). -* Mixed documentation fixes and improvements. - -New in v0.18.4 --------------- - -Changes: - -* Support `[Variant "fischerandom"]` in PGNs for Cutechess compatibility. - Thanks to Steve Maughan for reporting. - -New in v0.18.3 --------------- - -Bugfixes: - -* `chess.gaviota.NativeTablebases.get_dtm()` and `get_wdl()` were missing. - -New in v0.18.2 --------------- - -Bugfixes: - -* Fixed castling in atomic chess when there is a rank attack. -* The halfmove clock in Crazyhouse is no longer incremented unconditionally. - `CrazyhouseBoard.is_zeroing(move)` now considers pawn moves and captures as - zeroing. Added `Board.is_irreversible(move)` that can be used instead. -* Fixed an inconsistency where the `chess.pgn` tokenizer accepts long algebraic - notation but `Board.parse_san()` did not. - -Changes: - -* Added more NAG constants in `chess.pgn`. - -New in v0.18.1 --------------- - -Bugfixes: - -* Crazyhouse drops were accepted as pseudo-legal (and legal) even if the - respective piece was not in the pocket. -* `CrazyhouseBoard.pop()` was failing to undo en passant moves. -* `CrazyhouseBoard.pop()` was always returning `None`. -* `Move.__copy__()` was failing to copy Crazyhouse drops. -* Fix ~ order (marker for promoted pieces) in FENs. -* Promoted pieces in Crazyhouse were not communicated with UCI engines. - -Changes: - -* `ThreeCheckBoard.uci_variant` changed from `threecheck` to `3check`. - -New in v0.18.0 --------------- - -Bugfixes: - -* Fixed `Board.parse_uci()` for crazyhouse drops. Thanks to Ryan Delaney. -* Fixed `AtomicBoard.is_insufficient_material()`. -* Fixed signature of `SuicideBoard.was_into_check()`. -* Explicitly close input and output streams when a `chess.uci.PopenProcess` - terminates. -* The documentation of `Board.attackers()` was wrongly stating that en passant - capturable pawns are considered attacked. - -Changes: - -* `chess.SquareSet` is no longer hashable (since it is mutable). -* Removed functions and constants deprecated in v0.17.0. -* Dropped `gmpy2` and `gmpy` as optional dependencies. They were no longer - improving performance. -* Various tweaks and optimizations for 5% improvement in PGN parsing and perft - speed. (Signature of `_is_safe` and `_ep_skewered` changed). -* Rewritten `chess.svg.board()` using `xml.etree`. No longer supports *pre* and - *post*. Use an XML parser if you need to modify the SVG. Now only inserts - actually used piece defintions. -* Untangled UCI process and engine instanciation, changing signatures of - constructors and allowing arbitrary arguments to `subprocess.Popen`. -* Coding style and documentation improvements. - -New features: - -* `chess.svg.board()` now supports arrows. Thanks to @rheber for implementing - this feature. -* Let `chess.uci.PopenEngine` consistently handle Ctrl+C across platforms - and Python versions. `chess.uci.popen_engine()` now supports a `setpgrp` - keyword argument to start the engine process in a new process group. - Thanks to @dubiousjim. -* Added `board.king(color)` to find the (royal) king of a given side. -* SVGs now have `viewBox` and `chess.svg.board(size=None)` supports and - defaults to `None` (i.e. scaling to the size of the container). - -New in v0.17.0 --------------- - -Changes: - -* Rewritten move generator, various performance tweaks, code simplications - (500 lines removed) amounting to **doubled PGN parsing and perft speed**. -* Removed `board.generate_evasions()` and `board.generate_non_evasions()`. -* Removed `board.transpositions`. Transpositions are now counted on demand. -* `file_index()`, `rank_index()`, and `pop_count()` have been renamed to - `square_file()`, `square_rank()` and `popcount()` respectively. Aliases will - be removed in some future release. -* `STATUS_ILLEGAL_CHECK` has been renamed to `STATUS_RACE_CHECK`. The alias - will be removed in a future release. -* Removed `DIAG_ATTACKS_NE`, `DIAG_ATTACKS_NW`, `RANK_ATTACKS` and - `FILE_ATTACKS` as well as the corresponding masks. New attack tables - `BB_DIAG_ATTACKS` (combined both diagonal tables), `BB_RANK_ATTACKS` and - `BB_FILE_ATTACKS` are indexed by square instead of mask. -* `board.push()` no longer requires pseudo-legality. -* Documentation improvements. - -Bugfixes: - -* **Positions in variant end are now guaranteed to have no legal moves.** - `board.is_variant_end()` has been added to test for special variant end - conditions. Thanks to salvador-dali. -* `chess.svg`: Fixed a typo in the class names of black queens. Fixed fill - color for black rooks and queens. Added SVG Tiny support. These combined - changes fix display in a number of applications, including - Jupyter Qt Console. Thanks to Alexander Meshcheryakov. -* `board.ep_square` was not consistently `None` instead of `0`. -* Detect invalid racing kings positions: `STATUS_RACE_OVER`, - `STATUS_RACE_MATERIAL`. -* `SAN_REGEX`, `FEN_CASTLING_REGEX` and `TAG_REGEX` now try to match the - entire string and no longer accept newlines. -* Fixed `Move.__hash__()` for drops. - -New features: - -* `board.remove_piece_at()` now returns the removed piece. -* Added `square_distance()` and `square_mirror()`. -* Added `msb()`, `lsb()`, `scan_reversed()` and `scan_forward()`. -* Added `BB_RAYS` and `BB_BETWEEN`. - -New in v0.16.2 --------------- - -Changes: - -* `board.move_stack` now contains the exact move objects added with - `Board.push()` (instead of normalized copies for castling moves). - This ensures they can be used with `Board.variation_san()` amongst others. -* `board.ep_square` is now `None` instead of `0` for no en passant square. -* `chess.svg`: Better vector graphics for knights. Thanks to ProgramFox. -* Documentation improvements. - -New in v0.16.1 --------------- - -Bugfixes: - -* Explosions in atomic chess were not destroying castling rights. Thanks to - ProgramFOX for finding this issue. - -New in v0.16.0 --------------- - -Bugfixes: - -* `pin_mask()`, `pin()` and `is_pinned()` make more sense when already - in check. Thanks to Ferdinand Mosca. - -New features: - -* **Variant support: Suicide, Giveaway, Atomic, King of the Hill, Racing Kings, - Horde, Three-check, Crazyhouse.** `chess.Move` now supports drops. -* More fine grained dependencies. Use *pip install python-chess[uci,gaviota]* to - install dependencies for the full feature set. -* Added `chess.STATUS_EMPTY` and `chess.STATUS_ILLEGAL_CHECK`. -* The `board.promoted` mask keeps track of promoted pieces. -* Optionally copy boards without the move stack: `board.copy(stack=False)`. -* `examples/bratko_kopec` now supports avoid move (am), variants and - displays fractional scores immidiately. Thanks to Daniel Dugovic. -* `perft.py` rewritten with multi-threading support and moved to - `examples/perft`. -* `chess.syzygy.dependencies()`, `chess.syzygy.all_dependencies()` to generate - Syzygy tablebase dependencies. - -Changes: - -* **Endgame tablebase probing (Syzygy, Gaviota):** `probe_wdl()` **,** - `probe_dtz()` **and** `probe_dtm()` **now raise** `KeyError` **or** - `MissingTableError` **instead of returning** *None*. If you prefer getting - `None` in case of an error use `get_wdl()`, `get_dtz()` and `get_dtm()`. -* `chess.pgn.BaseVisitor.result()` returns `True` by default and is no longer - used by `chess.pgn.read_game()` if no game was found. -* Non-fast-forward update of the Git repository to reduce size (old binary - test assets removed). -* `board.pop()` now uses a boardstate stack to undo moves. -* `uci.engine.position()` will send the move history only until the latest - zeroing move. -* Optimize `board.clean_castling_rights()` and micro-optimizations improving - PGN parser performance by around 20%. -* Syzygy tables now directly use the endgame name as hash keys. -* Improve test performance (especially on Travis CI). -* Documentation updates and improvements. - -New in v0.15.4 --------------- - -New features: - -* Highlight last move and checks when rendering board SVGs. - -New in v0.15.3 --------------- - -Bugfixes: - -* `pgn.Game.errors` was not populated as documented. Thanks to Ryan Delaney - for reporting. - -New features: - -* Added `pgn.GameNode.add_line()` and `pgn.GameNode.main_line()` which make - it easier to work with lists of moves as variations. - -New in v0.15.2 --------------- - -Bugfixes: - -* Fix a bug where `shift_right()` and `shift_2_right()` were producing - integers larger than 64bit when shifting squares off the board. This is - very similar to the bug fixed in v0.15.1. Thanks to piccoloprogrammatore - for reporting. - -New in v0.15.1 --------------- - -Bugfixes: - -* Fix a bug where `shift_up_right()` and `shift_up_left()` were producing - integers larger than 64bit when shifting squares off the board. - -New features: - -* Replaced __html__ with experimental SVG rendering for IPython. - -New in v0.15.0 --------------- - -Changes: - -* `chess.uci.Score` **no longer has** `upperbound` **and** `lowerbound` - **attributes**. Previously these were always *False*. - -* Significant improvements of move generation speed, around **2.3x faster - PGN parsing**. Removed the following internal attributes and methods of - the `Board` class: `attacks_valid`, `attacks_to`, `attacks_from`, - `_pinned()`, `attacks_valid_stack`, `attacks_from_stack`, `attacks_to_stack`, - `generate_attacks()`. - -* UCI: Do not send *isready* directly after *go*. Though allowed by the UCI - protocol specification it is just not nescessary and many engines were having - trouble with this. - -* Polyglot: Use less memory for uniform random choices from big opening books - (reservoir sampling). - -* Documentation improvements. - -Bugfixes: - -* Allow underscores in PGN header tags. Found and fixed by Bajusz Tamás. - -New features: - -* Added `Board.chess960_pos()` to identify the Chess960 starting position - number of positions. - -* Added `chess.BB_BACKRANKS` and `chess.BB_PAWN_ATTACKS`. - -New in v0.14.1 --------------- - -Bugfixes: - -* Backport Bugfix for Syzygy DTZ related to en passant. - See official-stockfish/Stockfish@6e2ca97d93812b2. - -Changes: - -* Added optional argument *max_fds=128* to `chess.syzygy.open_tablebases()`. - An LRU cache is used to keep at most *max_fds* files open. This allows using - many tables without running out of file descriptors. - Previously all tables were opened at once. - -* Syzygy and Gaviota now store absolute tablebase paths, in case you change - the working directory of the process. - -* The default implementation of `chess.uci.InfoHandler.score()` will no longer - store score bounds in `info["score"]`, only real scores. - -* Added `Board.set_chess960_pos()`. - -* Documentation improvements. - -New in v0.14.0 --------------- - -Changes: - -* `Board.attacker_mask()` **has been renamed to** `Board.attackers_mask()` for - consistency. - -* **The signature of** `Board.generate_legal_moves()` **and** - `Board.generate_pseudo_legal_moves()` **has been changed.** Previously it - was possible to select piece types for selective move generation: - - `Board.generate_legal_moves(castling=True, pawns=True, knights=True, bishops=True, rooks=True, queens=True, king=True)` - - Now it is possible to select arbitrary sets of origin and target squares. - `to_mask` uses the corresponding rook squares for castling moves. - - `Board.generate_legal_moves(from_mask=BB_ALL, to_mask=BB)` - - To generate all knight and queen moves do: - - `board.generate_legal_moves(board.knights | board.queens)` - - To generate only castling moves use: - - `Board.generate_castling_moves(from_mask=BB_ALL, to_mask=BB_ALL)` - -* Additional hardening has been added on top of the bugfix from v0.13.3. - Diagonal skewers on the last double pawn move are now handled correctly, - even though such positions can not be reached with a sequence of legal moves. - -* `chess.syzygy` now uses the more efficient selective move generation. - -New features: - -* The following move generation methods have been added: - `Board.generate_pseudo_legal_ep(from_mask=BB_ALL, to_mask=BB_ALL)`, - `Board.generate_legal_ep(from_mask=BB_ALL, to_mask=BB_ALL)`, - `Board.generate_pseudo_legal_captures(from_mask=BB_ALL, to_mask=BB_ALL)`, - `Board.generate_legal_captures(from_mask=BB_ALL, to_mask=BB_ALL)`. - - -New in v0.13.3 --------------- - -**This is a bugfix release for a move generation bug.** Other than the bugfix -itself there are only minimal fully backwardscompatible changes. -You should update immediately. - -Bugfixes: - -* When capturing en passant, both the capturer and the captured pawn disappear - from the fourth or fifth rank. If those pawns were covering a horizontal - attack on the king, then capturing en passant should not have been legal. - - `Board.generate_legal_moves()` and `Board.is_into_check()` have been fixed. - - The same principle applies for diagonal skewers, but nothing has been done - in this release: If the last double pawn move covers a diagonal attack, then - the king would have already been in check. - - v0.14.0 adds additional hardening for all cases. It is recommended you - upgrade to v0.14.0 as soon as you can deal with the - non-backwards compatible changes. - -Changes: - -* `chess.uci` now uses `subprocess32` if applicable (and available). - Additionally a lock is used to work around a race condition in Python 2, that - can occur when spawning engines from multiple threads at the same time. - -* Consistently handle tabs in UCI engine output. - -New in v0.13.2 --------------- - -Changes: - -* `chess.syzygy.open_tablebases()` now raises if the given directory - does not exist. - -* Allow visitors to handle invalid `FEN` tags in PGNs. - -* Gaviota tablebase probing fails faster for piece counts > 5. - -Minor new features: - -* Added `chess.pgn.Game.from_board()`. - -New in v0.13.1 --------------- - -Changes: - -* Missing *SetUp* tags in PGNs are ignored. - -* Incompatible comparisons on `chess.Piece`, `chess.Move`, `chess.Board` - and `chess.SquareSet` now return *NotImplemented* instead of *False*. - -Minor new features: - -* Factored out basic board operations to `chess.BaseBoard`. This is inherited - by `chess.Board` and extended with the usual move generation features. - -* Added optional *claim_draw* argument to `chess.Base.is_game_over()`. - -* Added `chess.Board.result(claim_draw=False)`. - -* Allow `chess.Board.set_piece_at(square, None)`. - -* Added `chess.SquareSet.from_square(square)`. - -New in v0.13.0 --------------- - -* `chess.pgn.Game.export()` and `chess.pgn.GameNode.export()` have been - removed and replaced with a new visitor concept. - -* `chess.pgn.read_game()` no longer takes an `error_handler` argument. Errors - are now logged. Use the new visitor concept to change this behaviour. - -New in v0.12.5 --------------- - -Bugfixes: - -* Context manager support for pure Python Gaviota probing code. Various - documentation fixes for Gaviota probing. Thanks to Jürgen Précour for - reporting. - -* PGN variation start comments for variations on the very first move were - assigned to the game. Thanks to Norbert Räcke for reporting. - -New in v0.12.4 --------------- - -Bugfixes: - -* Another en passant related Bugfix for pure Python Gaviota tablebase probing. - -New features: - -* Added `pgn.GameNode.is_end()`. - -Changes: - -* Big speedup for `pgn` module. Boards are cached less agressively. Board - move stacks are copied faster. - -* Added tox.ini to specify test suite and flake8 options. - -New in v0.12.3 --------------- - -Bugfixes: - -* Some invalid castling rights were silently ignored by `Board.set_fen()`. Now - it is ensured information is stored for retrieval using `Board.status()`. - -New in v0.12.2 --------------- - -Bugfixes: - -* Some Gaviota probe results were incorrect for positions where black could - capture en passant. - -New in v0.12.1 --------------- - -Changes: - -* Robust handling of invalid castling rights. You can also use the new - method `Board.clean_castling_rights()` to get the subset of strictly valid - castling rights. - -New in v0.12.0 --------------- - -New features: - -* Python 2.6 support. Patch by vdbergh. - -* Pure Python Gaviota tablebase probing. Thanks to Jean-Noël Avila. - -New in v0.11.1 --------------- - -Bugfixes: - -* `syzygy.Tablebases.probe_dtz()` has was giving wrong results for some - positions with possible en passant capturing. This was found and fixed - upstream: https://github.com/official-stockfish/Stockfish/issues/394. - -* Ignore extra spaces in UCI `info` lines, as for example sent by the - Hakkapeliitta engine. Thanks to Jürgen Précour for reporting. - -New in v0.11.0 --------------- - -Changes: - -* **Chess960** support and the **representation of castling moves** has been - changed. - - The constructor of board has a new `chess960` argument, defaulting to - `False`: `Board(fen=STARTING_FEN, chess960=False)`. That property is - available as `Board.chess960`. - - In Chess960 mode the behaviour is as in the previous release. Castling moves - are represented as a king move to the corresponding rook square. - - In the default standard chess mode castling moves are represented with - the standard UCI notation, e.g. `e1g1` for king-side castling. - - `Board.uci(move, chess960=None)` creates UCI representations for moves. - Unlike `Move.uci()` it can convert them in the context of the current - position. - - `Board.has_chess960_castling_rights()` has been added to test for castling - rights that are impossible in standard chess. - - The modules `chess.polyglot`, `chess.pgn` and `chess.uci` will transparently - handle both modes. - -* In a previous release `Board.fen()` has been changed to only display an - en passant square if a legal en passant move is indeed possible. This has - now also been adapted for `Board.shredder_fen()` and `Board.epd()`. - -New features: - -* Get individual FEN components: `Board.board_fen()`, `Board.castling_xfen()`, - `Board.castling_shredder_fen()`. - -* Use `Board.has_legal_en_passant()` to test if a position has a legal - en passant move. - -* Make `repr(board.legal_moves)` human readable. - -New in v0.10.1 --------------- - -Bugfixes: - -* Fix use-after-free in Gaviota tablebase initialization. - -New in v0.10.0 --------------- - -New dependencies: - -* If you are using Python < 3.2 you have to install `futures` in order to - use the `chess.uci` module. - -Changes: - -* There are big changes in the UCI module. Most notably in async mode multiple - commands can be executed at the same time (e.g. `go infinite` and then - `stop` or `go ponder` and then `ponderhit`). - - `go infinite` and `go ponder` will now wait for a result, i.e. you may have - to call `stop` or `ponderhit` from a different thread or run the commands - asynchronously. - - `stop` and `ponderhit` no longer have a result. - -* The values of the color constants `chess.WHITE` and `chess.BLACK` have been - changed. Previously `WHITE` was `0`, `BLACK` was `1`. Now `WHITE` is `True`, - `BLACK` is `False`. The recommended way to invert `color` is using - `not color`. - -* The pseudo piece type `chess.NONE` has been removed in favor of just using - `None`. - -* Changed the `Board(fen)` constructor. If the optional `fen` argument is not - given behavior did not change. However if `None` is passed explicitly an - empty board is created. Previously the starting position would have been - set up. - -* `Board.fen()` will now only show completely legal en passant squares. - -* `Board.set_piece_at()` and `Board.remove_piece_at()` will now clear the - move stack, because the old moves may not be valid in the changed position. - -* `Board.parse_uci()` and `Board.push_uci()` will now accept null moves. - -* Changed shebangs from `#!/usr/bin/python` to `#!/usr/bin/env python` for - better virtualenv support. - -* Removed unused game data files from repository. - -Bugfixes: - -* PGN: Prefer the game result from the game termination marker over `*` in the - header. These should be identical in standard compliant PGNs. Thanks to - Skyler Dawson for reporting this. - -* Polyglot: `minimum_weight` for `find()`, `find_all()` and `choice()` was - not respected. - -* Polyglot: Negative indexing of opening books was raising `IndexError`. - -* Various documentation fixes and improvements. - -New features: - -* Experimental probing of Gaviota tablebases via libgtb. - -* New methods to construct boards: - - .. code:: python - - >>> chess.Board.empty() - Board('8/8/8/8/8/8/8/8 w - - 0 1') - - >>> board, ops = chess.Board.from_epd("4k3/8/8/8/8/8/8/4K3 b - - fmvn 17; hmvc 13") - >>> board - Board('4k3/8/8/8/8/8/8/4K3 b - - 13 17') - >>> ops - {'fmvn': 17, 'hmvc': 13} - -* Added `Board.copy()` and hooks to let the copy module to the right thing. - -* Added `Board.has_castling_rights(color)`, - `Board.has_kingside_castling_rights(color)` and - `Board.has_queenside_castling_rights(color)`. - -* Added `Board.clear_stack()`. - -* Support common set operations on `chess.SquareSet()`. - -New in v0.9.1 -------------- - -Bugfixes: - -* UCI module could not handle castling ponder moves. Thanks to Marco Belli for - reporting. -* The initial move number in PGNs was missing, if black was to move in the - starting position. Thanks to Jürgen Précour for reporting. -* Detect more impossible en passant squares in `Board.status()`. There already - was a requirement for a pawn on the fifth rank. Now the sixth and seventh - rank must be empty, additionally. We do not do further retrograde analysis, - because these are the only cases affecting move generation. - -New in v0.8.3 -------------- - -Bugfixes: - -* The initial move number in PGNs was missing, if black was to move in the - starting position. Thanks to Jürgen Précour for reporting. -* Detect more impossible en passant squares in `Board.status()`. There already - was a requirement for a pawn on the fifth rank. Now the sixth and seventh - rank must be empty, additionally. We do not do further retrograde analysis, - because these are the only cases affecting move generation. - -New in v0.9.0 -------------- - -**This is a big update with quite a few breaking changes. Carefully review -the changes before upgrading. It's no problem if you can not update right now. -The 0.8.x branch still gets bugfixes.** - -Incompatible changes: - -* Removed castling right constants. Castling rights are now represented as a - bitmask of the rook square. For example: - - .. code:: python - - >>> board = chess.Board() - - >>> # Standard castling rights. - >>> board.castling_rights == chess.BB_A1 | chess.BB_H1 | chess.BB_A8 | chess.BB_H8 - True - - >>> # Check for the presence of a specific castling right. - >>> can_white_castle_queenside = chess.BB_A1 & board.castling_rights - - Castling moves were previously encoded as the corresponding king movement in - UCI, e.g. `e1f1` for white kingside castling. **Now castling moves are - encoded as a move to the corresponding rook square** (`UCI_Chess960`-style), - e.g. `e1a1`. - - You may use the new methods `Board.uci(move, chess960=True)`, - `Board.parse_uci(uci)` and `Board.push_uci(uci)` to handle this - transparently. - - The `uci` module takes care of converting moves when communicating with an - engine that is not in `UCI_Chess960` mode. - -* The `get_entries_for_position(board)` method of polyglot opening book readers - has been changed to `find_all(board, minimum_weight=1)`. By default entries - with weight 0 are excluded. - -* The `Board.pieces` lookup list has been removed. - -* In 0.8.1 the spelling of repetition (was repitition) was fixed. - `can_claim_threefold_repetition()` and `is_fivefold_repetition()` are the - affected method names. Aliases are now removed. - -* `Board.set_epd()` will now interpret `bm`, `am` as a list of moves for the - current position and `pv` as a variation (represented by a list of moves). - Thanks to Jordan Bray for reporting this. - -* Removed `uci.InfoHandler.pre_bestmove()` and - `uci.InfoHandler.post_bestmove()`. - -* `uci.InfoHandler().info["score"]` is now relative to multipv. Use - - .. code:: python - - >>> with info_handler as info: - ... if 1 in info["score"]: - ... cp = info["score"][1].cp - - where you were previously using - - .. code:: python - - >>> with info_handler as info: - ... if "score" in info: - ... cp = info["score"].cp - -* Clear `uci.InfoHandler()` dictionary at the start of new searches - (new `on_go()`), not at the end of searches. - -* Renamed `PseudoLegalMoveGenerator.bitboard` and `LegalMoveGenerator.bitboard` - to `PseudoLegalMoveGenerator.board` and `LegalMoveGenerator.board`, - respectively. - -* Scripts removed. - -* Python 3.2 compatibility dropped. Use Python 3.3 or higher. Python 2.7 - support is not affected. - -New features: - -* **Introduced Chess960 support.** `Board(fen)` and `Board.set_fen(fen)` now - support X-FENs. Added `Board.shredder_fen()`. - `Board.status(allow_chess960=True)` has an optional argument allowing to - insist on standard chess castling rules. - Added `Board.is_valid(allow_chess960=True)`. - -* **Improved move generation using** `Shatranj-style direct lookup - `_. **Removed rotated bitboards. Perft - speed has been more than doubled.** - -* Added `choice(board)` and `weighted_choice(board)` for polyglot opening book - readers. - -* Added `Board.attacks(square)` to determine attacks *from* a given square. - There already was `Board.attackers(color, square)` returning attacks *to* - a square. - -* Added `Board.is_en_passant(move)`, `Board.is_capture(move)` and - `Board.is_castling(move)`. - -* Added `Board.pin(color, square)` and `Board.is_pinned(color, square)`. - -* There is a new method `Board.pieces(piece_type, color)` to get a set of - squares with the specified pieces. - -* Do expensive Syzygy table initialization on demand. - -* Allow promotions like `e8Q` (usually `e8=Q`) in `Board.parse_san()` and - PGN files. - -* Patch by Richard C. Gerkin: Added `Board.__unicode__()` just like - `Board.__str__()` but with unicode pieces. -* Patch by Richard C. Gerkin: Added `Board.__html__()`. - -New in v0.8.2 -------------- - -Bugfixes: - -* `pgn.Game.setup()` with the standard starting position was failing when the - standard starting position was already set. Thanks to Jordan Bray for - reporting this. - -Optimizations: - -* Remove `bswap()` from Syzygy decompression hot path. Directly read integers - with the correct endianness. - -New in v0.8.1 -------------- - -* Fixed pondering mode in uci module. For example `ponderhit()` was blocking - indefinitely. Thanks to Valeriy Huz for reporting this. - -* Patch by Richard C. Gerkin: Moved searchmoves to the end of the UCI go - command, where it will not cause other command parameters to be ignored. - -* Added missing check or checkmate suffix to castling SANs, e.g. `O-O-O#`. - -* Fixed off-by-one error in polyglot opening book binary search. This would - not have caused problems for real opening books. - -* Fixed Python 3 support for reverse polyglot opening book iteration. - -* Bestmoves may be literally `(none)` in UCI protocol, for example in - checkmate positions. Fix parser and return `None` as the bestmove in this - case. - -* Fixed spelling of repetition (was repitition). - `can_claim_threefold_repetition()` and `is_fivefold_repetition()` are the - affected method names. Aliases are there for now, but will be removed in the - next release. Thanks to Jimmy Patrick for reporting this. - -* Added `SquareSet.__reversed__()`. - -* Use containerized tests on Travis CI, test against Stockfish 6, improved - test coverage amd various minor clean-ups. - -New in v0.8.0 -------------- - -* **Implement Syzygy endgame tablebase probing.** - `https://syzygy-tables.info `_ - is an example project that provides a public API using the new features. - -* The interface for aynchronous UCI command has changed to mimic - `concurrent.futures`. `is_done()` is now just `done()`. Callbacks will - receive the command object as a single argument instead of the result. - The `result` property and `wait()` have been removed in favor of a - synchronously waiting `result()` method. - -* The result of the `stop` and `go` UCI commands are now named tuples (instead - of just normal tuples). - -* Add alias `Board` for `Bitboard`. - -* Fixed race condition during UCI engine startup. Lines received during engine - startup sometimes needed to be processed before the Engine object was fully - initialized. - -New in v0.7.0 -------------- - -* **Implement UCI engine communication.** - -* Patch by Matthew Lai: `Add caching for gameNode.board()`. - -New in v0.6.0 -------------- - -* If there are comments in a game before the first move, these are now assigned - to `Game.comment` instead of `Game.starting_comment`. `Game.starting_comment` - is ignored from now on. `Game.starts_variation()` is no longer true. - The first child node of a game can no longer have a starting comment. - It is possible to have a game with `Game.comment` set, that is otherwise - completely empty. - -* Fix export of games with variations. Previously the moves were exported in - an unusual (i.e. wrong) order. - -* Install `gmpy2` or `gmpy` if you want to use slightly faster binary - operations. - -* Ignore superfluous variation opening brackets in PGN files. - -* Add `GameNode.san()`. - -* Remove `sparse_pop_count()`. Just use `pop_count()`. - -* Remove `next_bit()`. Now use `bit_scan()`. - -New in v0.5.0 -------------- - -* PGN parsing is now more robust: `read_game()` ignores invalid tokens. - Still exceptions are going to be thrown on illegal or ambiguous moves, but - this behaviour can be changed by passing an `error_handler` argument. - - .. code:: python - - >>> # Raises ValueError: - >>> game = chess.pgn.read_game(file_with_illegal_moves) - - .. code:: python - - >>> # Silently ignores errors and continues parsing: - >>> game = chess.pgn.read_game(file_with_illegal_moves, None) - - .. code:: python - - >>> # Logs the error, continues parsing: - >>> game = chess.pgn.read_game(file_with_illegal_moves, logger.exception) - - If there are too many closing brackets this is now ignored. - - Castling moves like 0-0 (with zeros) are now accepted in PGNs. - The `Bitboard.parse_san()` method remains strict as always, though. - - Previously the parser was strictly following the PGN spefification in that - empty lines terminate a game. So a game like - - :: - - [Event "?"] - - { Starting comment block } - - 1. e4 e5 2. Nf3 Nf6 * - - would have ended directly after the starting comment. To avoid this, the - parser will now look ahead until it finds at least one move or a termination - marker like `*`, `1-0`, `1/2-1/2` or `0-1`. - -* Introduce a new function `scan_headers()` to quickly scan a PGN file for - headers without having to parse the full games. - -* Minor testcoverage improvements. - -New in v0.4.2 -------------- - -* Fix bug where `pawn_moves_from()` and consequently `is_legal()` weren't - handling en passant correctly. Thanks to Norbert Naskov for reporting. - -New in v0.4.1 -------------- - -* Fix `is_fivefold_repitition()`: The new fivefold repetition rule requires - the repetitions to occur on *alternating consecutive* moves. - -* Minor testing related improvements: Close PGN files, allow running via - setuptools. - -* Add recently introduced features to README. - -New in v0.4.0 -------------- - -* Introduce `can_claim_draw()`, `can_claim_fifty_moves()` and - `can_claim_threefold_repitition()`. - -* Since the first of July 2014 a game is also over (even without claim by one - of the players) if there were 75 moves without a pawn move or capture or - a fivefold repetition. Let `is_game_over()` respect that. Introduce - `is_seventyfive_moves()` and `is_fivefold_repitition()`. Other means of - ending a game take precedence. - -* Threefold repetition checking requires efficient hashing of positions - to build the table. So performance improvements were needed there. The - default polyglot compatible zobrist hashes are now built incrementally. - -* Fix low level rotation operations `l90()`, `l45()` and `r45()`. There was - no problem in core because correct versions of the functions were inlined. - -* Fix equality and inequality operators for `Bitboard`, `Move` and `Piece`. - Also make them robust against comparisons with incompatible types. - -* Provide equality and inequality operators for `SquareSet` and - `polyglot.Entry`. - -* Fix return values of incremental arithmetical operations for `SquareSet`. - -* Make `polyglot.Entry` a `collections.namedtuple`. - -* Determine and improve test coverage. - -* Minor coding style fixes. - -New in v0.3.1 -------------- - -* `Bitboard.status()` now correctly detects `STATUS_INVALID_EP_SQUARE`, - instead of errors or false reports. - -* Polyglot opening book reader now correctly handles knight underpromotions. - -* Minor coding style fixes, including removal of unused imports. - -New in v0.3.0 -------------- - -* Rename property `half_moves` of `Bitboard` to `halfmove_clock`. - -* Rename property `ply` of `Bitboard` to `fullmove_number`. - -* Let PGN parser handle symbols like `!`, `?`, `!?` and so on by converting - them to NAGs. - -* Add a human readable string representation for Bitboards. - - .. code:: python - - >>> print(chess.Bitboard()) - r n b q k b n r - p p p p p p p p - . . . . . . . . - . . . . . . . . - . . . . . . . . - . . . . . . . . - P P P P P P P P - R N B Q K B N R - -* Various documentation improvements. - -New in v0.2.0 -------------- - -* **Implement PGN parsing and writing.** -* Hugely improve test coverage and use Travis CI for continuous integration and - testing. -* Create an API documentation. -* Improve Polyglot opening-book handling. - -New in v0.1.0 -------------- - -Apply the lessons learned from the previous releases, redesign the API and -implement it in pure Python. - -New in v0.0.4 -------------- - -Implement the basics in C++ and provide bindings for Python. Obviously -performance was a lot better - but at the expense of having to compile -code for the target platform. - -Pre v0.0.4 ----------- - -First experiments with a way too slow pure Python API, creating way too many -objects for basic operations. +See ``CHANGELOG-OLD.rst`` for changes up to v1.0.0. From 43336b48ad95d103152774f76cd71fe18dfd80f1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 17:23:04 +0200 Subject: [PATCH 1266/1831] Update tox.ini --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index eb79e3ce3..559f81ecc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,py38,pypy3 +envlist = py37,py38,py39 [testenv] passenv = LD_LIBRARY_PATH From 205f10ae1b6fe7ba9444822faedbf1bad98f9e84 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 17:30:37 +0200 Subject: [PATCH 1267/1831] Try Python 3.9-dev on Travis CI (#671) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d63d22051..dcbbd2399 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ matrix: include: - python: "3.7" - python: "3.8" - - python: "3.9" + - python: "3.9-dev" env: LATEST=1 cache: directories: From 89357e0f536bbff218cd129232cfab164fc1473a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 17:37:23 +0200 Subject: [PATCH 1268/1831] Run mypy also on Python 3.8 CI --- .travis.yml | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index dcbbd2399..2e4ae2233 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,12 @@ matrix: include: - python: "3.7" - python: "3.8" + env: + - RUN_MYPY=1 - python: "3.9-dev" - env: LATEST=1 + env: + - RUN_MYPY=1 + - RUN_PERFT=1 cache: directories: - data/gaviota @@ -47,7 +51,7 @@ install: - pip install --upgrade pip wheel - pip install --upgrade setuptools - pip install --upgrade coveralls - - if [[ $LATEST -eq 1 ]]; then pip install --upgrade mypy; fi + - if [[ $RUN_MYPY -eq 1 ]]; then pip install --upgrade mypy; fi - pip install -e . script: - # Unit tests @@ -77,13 +81,13 @@ script: - echo Unit tests complete - coveralls || [[ $? -eq 139 ]] - # Typing - - if [[ $LATEST -eq 1 ]]; then python -m mypy --strict chess; fi - - if [[ $LATEST -eq 1 ]]; then python -m mypy --strict examples/**/*.py; fi + - if [[ $RUN_MYPY -eq 1 ]]; then python -m mypy --strict chess; fi + - if [[ $RUN_MYPY -eq 1 ]]; then python -m mypy --strict examples/**/*.py; fi - # Perft tests - - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000; fi - - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/tricky.perft; fi - - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft; fi - - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft; fi - - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft; fi - - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft; fi - - if [[ $LATEST -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft; fi + - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000; fi + - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/tricky.perft; fi + - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft; fi + - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft; fi + - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft; fi + - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft; fi + - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft; fi From 85e0a4c76acb4fa58ed398822315656aa297e222 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 20:00:03 +0200 Subject: [PATCH 1269/1831] Add PovWdl and Wdl --- chess/engine.py | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index 6ec175438..ec4c96bad 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -598,6 +598,108 @@ def __str__(self) -> str: MateGiven = MateGivenType() +class PovWdl: + """ + Relative :class:`win/draw/loss statistics ` and the point + of view. + """ + + def __init__(self, relative: Wdl, turn: Color) -> None: + self.relative = relative + self.turn = turn + + def white(self) -> Wdl: + """Gets the :class:`~chess.engine.Wdl` from White's point of view.""" + return self.pov(chess.WHITE) + + def black(self) -> Wdl: + """Gets the :class:`~chess.engine.Wdl` from Black's point of view.""" + return self.pov(chess.BLACK) + + def pov(self, color: Color) -> Wdl: + """ + Gets the :class:`~chess.engine.Wdl` from the point of view of the given + *color*. + """ + return self.relative if self.turn == color else -self.relative + + def __repr__(self) -> str: + return "PovWdl({!r}, {})".format(self.wdl, "WHITE" if self.turn else "BLACK") + + # Unfortunately in python-chess v1.1.0, info["wdl"] was a simple tuple + # of the relative permille values, so we have to support __iter__, + # __len__, __getitem__ and equality comparisons with other tuples. + # Nevermind ordering, because thats not a sensible operation anyway. + + def __iter__(self): + yield self.relative.wins + yield self.relative.draws + yield self.relative.losses + + def __len__(self): + return 3 + + def __getitem__(self, idx): + return (self.relative.wins, self.relative.draws, self.relative.losses)[idx] + + def __eq__(self) -> bool: + if isinstance(other, PovWdl): + return self.white() == other.white() + elif isinstance(other, tuple): + return (self.relative.wins, self.relative.draws, self.relative.losses) == other + else: + return NotImplemented + + +@dataclasses.dataclass +class Wdl: + wins: int + draws: int + losses: int + + def total(self) -> int: + """ + Returns the total number of games. Usually ``wdl`` reported by engines + is scaled to 1000 games. + """ + self.wins + self.draws + self.losses + + def winning_chance(self) -> float: + """Returns the relative frequency of wins.""" + return self.wins / self.total() + + def drawing_chance(self) -> float: + """Returns the relative frequency of draws.""" + return self.draws / self.total() + + def losing_chance(self) -> float: + """Returns the relative frequency of losses.""" + return self.losses / self.total() + + def expectation(self) -> float: + """ + Returns the expectation value, where a win is valued 1, a draw is + valued 0.5, and a loss is valued 0. + """ + return (self.wins + 0.5 * self.draws) / self.total() + + def __iter__(self): + yield self.wins + yield self.draws + yield self.losses + + def __reversed__(self): + yield self.losses + yield self.draws + yield self.wins + + def __pos__(self) -> Wdl: + return self + + def __neg__(self) -> Wdl: + return Wdl(self.losses, self.draws, self.wins) + + class MockTransport(asyncio.SubprocessTransport, asyncio.WriteTransport): def __init__(self, protocol: Protocol) -> None: super().__init__() From 1c0e36897e25bb7dbf263376ab3b1946475699de Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 21:27:06 +0200 Subject: [PATCH 1270/1831] Integrate Wdl with InfoDict --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index ec4c96bad..e3b8b40cf 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -306,7 +306,7 @@ class InfoDict(typing.TypedDict, total=False): refutation: Dict[chess.Move, List[chess.Move]] currline: Dict[int, List[chess.Move]] ebf: float - wdl: Tuple[int, int, int] + wdl: PovWdl string: str except AttributeError: # Before Python 3.8. @@ -1566,7 +1566,7 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL LOGGER.error("Exception parsing pv from info: %r, position at root: %s", arg, root_board.fen()) elif parameter == "wdl": try: - info["wdl"] = int(tokens.pop(0)), int(tokens.pop(0)), int(tokens.pop(0)) + info["wdl"] = PovWdl(Wdl(int(tokens.pop(0)), int(tokens.pop(0)), int(tokens.pop(0))), root_board.turn) except (ValueError, IndexError): LOGGER.error("Exception parsing wdl from info: %r", arg) From 5f5291e3f29eae6a4c80f4bf6ae925d57ba1cab7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 21:58:53 +0200 Subject: [PATCH 1271/1831] Draft Score to Wdl conversion --- chess/engine.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index e3b8b40cf..e5cf2533d 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -36,9 +36,17 @@ import chess +from chess import Color from types import TracebackType from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Mapping, MutableMapping, Optional, Tuple, Type, TypeVar, Union -from chess import Color + +try: + from typing import Literal +except ImportError: + # Before Python 3.8. + _WdlModel = str +else: + _WdlModel = Literal["sf12"] # type: ignore T = TypeVar("T") @@ -377,6 +385,10 @@ def is_mate(self) -> bool: """Tests if this is a mate score.""" return self.relative.is_mate() + def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> PovWdl: + """See :func:`~chess.engine.Score.wdl()`.""" + return PovWdl(self.relative.wdl(), self.turn) + def __repr__(self) -> str: return "PovScore({!r}, {})".format(self.relative, "WHITE" if self.turn else "BLACK") @@ -449,6 +461,29 @@ def is_mate(self) -> bool: """Tests if this is a mate score.""" return self.mate() is not None + @abc.abstractmethod + def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: + """ + Returns statistics for the expected outcome of this game, based on + a *model*, given that this score is reached at *ply*. + + Scores have a total order, but it makes little sense to compute + the difference between two scores. For example, going from + ``Cp(-100)`` to ``Cp(+100)`` is much more significant than going + from ``Cp(800)`` to ``Cp(1000)``. It is better to compare the + expectation values for the outcome of the game (based on winning + chances and drawing chances). + + :param model: Currently the only implemented model is ``sf12``, the + win rate model used by Stockfish 12. + :param ply: The number of half-moves played since the starting + position. Models may scale scores slightly differently based on + this. Defaults to middle game. + + >>> Cp(100).wdl().expectation() - Cp(-100).wdl().expectation() + >>> Cp(1000).wdl().expectation() - Cp(800).wdl().expectation() + """ + @abc.abstractmethod def __neg__(self) -> Score: ... @@ -514,6 +549,20 @@ def mate(self) -> None: def score(self, *, mate_score: Optional[int] = None) -> int: return self.cp + def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: + wins = self._sf12_wins(ply=ply) + losses = (-self)._sf12_wins(ply=ply) + draws = 1000 - wins - losses + return Wdl(wins, draws, losses) + + def _sf12_wins(self, *, ply: int) -> int: + # https://github.com/official-stockfish/Stockfish/blob/sf_12/src/uci.cpp#L198-L218 + m = min(240, max(ply, 0)) / 64 + a = (((-8.24404295 * m + 64.23892342) * m + -95.73056462) * m) + 153.86478679 + b = (((-3.37154371 * m + 28.44489198) * m + -56.67657741) * m) + 72.05858751 + x = min(1000, max(self.cp, -1000)) + return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) + def __str__(self) -> str: return f"+{self.cp:d}" if self.cp > 0 else str(self.cp) @@ -551,6 +600,9 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: else: return -mate_score - self.moves + def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: + return Wdl(1000, 0, 0) if self.moves > 0 else Wdl(0, 0, 1000) + def __str__(self) -> str: return f"#+{self.moves}" if self.moves > 0 else f"#-{abs(self.moves)}" @@ -580,6 +632,9 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: ... def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: return mate_score + def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: + return Wdl(1000, 0, 0) + def __neg__(self) -> Mate: return Mate(0) From 8fdd22d4833d051b98e17f550c26e696b2b81fe7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 22:28:43 +0200 Subject: [PATCH 1272/1831] Wdl fixes and consistency checks --- chess/engine.py | 30 +++++++++++++++++------------- test.py | 13 +++++++++++++ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index e5cf2533d..3a904699a 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -25,6 +25,7 @@ import dataclasses import enum import logging +import math import warnings import shlex import subprocess @@ -470,18 +471,21 @@ def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: Scores have a total order, but it makes little sense to compute the difference between two scores. For example, going from ``Cp(-100)`` to ``Cp(+100)`` is much more significant than going - from ``Cp(800)`` to ``Cp(1000)``. It is better to compare the - expectation values for the outcome of the game (based on winning + from ``Cp(+300)`` to ``Cp(+500)``. It is better to compute differences + of the expectation values for the outcome of the game (based on winning chances and drawing chances). + >>> Cp(100).wdl().expectation() - Cp(-100).wdl().expectation() # doctest: +ELLIPSIS + 0.379... + + >>> Cp(500).wdl().expectation() - Cp(300).wdl().expectation() # doctest: +ELLIPSIS + 0.015... + :param model: Currently the only implemented model is ``sf12``, the win rate model used by Stockfish 12. :param ply: The number of half-moves played since the starting position. Models may scale scores slightly differently based on this. Defaults to middle game. - - >>> Cp(100).wdl().expectation() - Cp(-100).wdl().expectation() - >>> Cp(1000).wdl().expectation() - Cp(800).wdl().expectation() """ @abc.abstractmethod @@ -679,25 +683,25 @@ def pov(self, color: Color) -> Wdl: return self.relative if self.turn == color else -self.relative def __repr__(self) -> str: - return "PovWdl({!r}, {})".format(self.wdl, "WHITE" if self.turn else "BLACK") + return "PovWdl({!r}, {})".format(self.relative, "WHITE" if self.turn else "BLACK") # Unfortunately in python-chess v1.1.0, info["wdl"] was a simple tuple # of the relative permille values, so we have to support __iter__, # __len__, __getitem__ and equality comparisons with other tuples. # Nevermind ordering, because thats not a sensible operation anyway. - def __iter__(self): + def __iter__(self) -> Iterator[int]: yield self.relative.wins yield self.relative.draws yield self.relative.losses - def __len__(self): + def __len__(self) -> int: return 3 - def __getitem__(self, idx): + def __getitem__(self, idx: int) -> int: return (self.relative.wins, self.relative.draws, self.relative.losses)[idx] - def __eq__(self) -> bool: + def __eq__(self, other: object) -> bool: if isinstance(other, PovWdl): return self.white() == other.white() elif isinstance(other, tuple): @@ -717,7 +721,7 @@ def total(self) -> int: Returns the total number of games. Usually ``wdl`` reported by engines is scaled to 1000 games. """ - self.wins + self.draws + self.losses + return self.wins + self.draws + self.losses def winning_chance(self) -> float: """Returns the relative frequency of wins.""" @@ -738,12 +742,12 @@ def expectation(self) -> float: """ return (self.wins + 0.5 * self.draws) / self.total() - def __iter__(self): + def __iter__(self) -> Iterator[int]: yield self.wins yield self.draws yield self.losses - def __reversed__(self): + def __reversed__(self) -> Iterator[int]: yield self.losses yield self.draws yield self.wins diff --git a/test.py b/test.py index 90cb67e89..b6c9df061 100755 --- a/test.py +++ b/test.py @@ -2796,6 +2796,10 @@ def test_score_ordering(self): self.assertEqual(i >= j, a >= b) self.assertEqual(i < j, a.score(mate_score=100000) < b.score(mate_score=100000)) + self.assertTrue(not (i < j) or a.wdl().expectation() <= b.wdl().expectation()) + self.assertTrue(not (i < j) or a.wdl().winning_chance() <= b.wdl().winning_chance()) + self.assertTrue(not (i < j) or a.wdl().losing_chance() >= b.wdl().losing_chance()) + def test_score(self): # Negation. self.assertEqual(-chess.engine.Cp(+20), chess.engine.Cp(-20)) @@ -2813,6 +2817,15 @@ def test_score(self): self.assertEqual(chess.engine.Cp(-300).mate(), None) self.assertEqual(chess.engine.Mate(+5).mate(), 5) + # Wdl. + self.assertEqual(chess.engine.MateGiven.wdl().expectation(), 1) + self.assertEqual(chess.engine.Mate(0).wdl().expectation(), 0) + self.assertEqual(chess.engine.Cp(0).wdl().expectation(), 0.5) + + for cp in map(chess.engine.Cp, range(-1050, 1100, 50)): + wdl = cp.wdl() + self.assertAlmostEqual(wdl.winning_chance() + wdl.drawing_chance() + wdl.losing_chance(), 1) + @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_forced_mates(self): with chess.engine.SimpleEngine.popen_uci("stockfish", debug=True) as engine: From 43afa7679b5495bf7510e78f0c015cd5a8981303 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 22:40:35 +0200 Subject: [PATCH 1273/1831] Document Wdl --- chess/engine.py | 17 +++++++++++++++-- docs/engine.rst | 6 ++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 3a904699a..5c8640f91 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -296,8 +296,8 @@ class InfoDict(typing.TypedDict, total=False): ``seldepth``, ``time`` (in seconds), ``nodes``, ``nps``, ``multipv``. Others: ``thits``, ``currmove``, ``currmovenumber``, ``hashfull``, - ``cpuload``, ``refutation``, ``currline``, ``ebf``, ``wdl``, and - ``string``. + ``cpuload``, ``refutation``, ``currline``, ``ebf``, + ``wdl`` (a :class:`~chess.engine.PovWdl`), and ``string``. """ score: PovScore pv: List[chess.Move] @@ -663,6 +663,12 @@ class PovWdl: of view. """ + relative: Wdl + """The relative :class:`~chess.engine.Wdl`.""" + + turn: Color + """The point of view (``chess.WHITE`` or ``chess.BLACK``).""" + def __init__(self, relative: Wdl, turn: Color) -> None: self.relative = relative self.turn = turn @@ -712,9 +718,16 @@ def __eq__(self, other: object) -> bool: @dataclasses.dataclass class Wdl: + """Win/draw/loss statistics.""" + wins: int + """The number of wins.""" + draws: int + """The number of draws.""" + losses: int + """The number of losses.""" def total(self) -> int: """ diff --git a/docs/engine.rst b/docs/engine.rst index ae2ad51d4..ab0e548ad 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -206,6 +206,12 @@ Example: .. autoclass:: chess.engine.Score :members: +.. autoclass:: chess.engine.PovWdl + :members: + +.. autoclass:: chess.engine.Wdl + :members: + Indefinite or infinite analysis ------------------------------- From 869abdaa528226eced14d81aa6ae9d38860c7e53 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 22:53:12 +0200 Subject: [PATCH 1274/1831] Implement Wdl.__bool__ --- chess/engine.py | 6 ++++++ test.py | 3 +++ 2 files changed, 9 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index 5c8640f91..89d4f3f1d 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -688,6 +688,9 @@ def pov(self, color: Color) -> Wdl: """ return self.relative if self.turn == color else -self.relative + def __bool__(self) -> bool: + return bool(self.relative) + def __repr__(self) -> str: return "PovWdl({!r}, {})".format(self.relative, "WHITE" if self.turn else "BLACK") @@ -755,6 +758,9 @@ def expectation(self) -> float: """ return (self.wins + 0.5 * self.draws) / self.total() + def __bool__(self) -> bool: + return bool(self.total()) + def __iter__(self) -> Iterator[int]: yield self.wins yield self.draws diff --git a/test.py b/test.py index b6c9df061..9762a4fdc 100755 --- a/test.py +++ b/test.py @@ -2824,8 +2824,11 @@ def test_score(self): for cp in map(chess.engine.Cp, range(-1050, 1100, 50)): wdl = cp.wdl() + self.assertTrue(wdl) self.assertAlmostEqual(wdl.winning_chance() + wdl.drawing_chance() + wdl.losing_chance(), 1) + self.assertFalse(chess.engine.Wdl(0, 0, 0)) + @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_forced_mates(self): with chess.engine.SimpleEngine.popen_uci("stockfish", debug=True) as engine: From 82e503130aa5a6849cb3b847b470ca87e4a32284 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 23:13:45 +0200 Subject: [PATCH 1275/1831] Do not use try-else for Literal imports --- chess/__init__.py | 5 ++--- chess/engine.py | 5 ++--- chess/pgn.py | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 63fd03464..a71e99de8 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -41,11 +41,10 @@ try: from typing import Literal + _EnPassantSpec = Literal["legal", "fen", "xfen"] except ImportError: # Before Python 3.8. - _EnPassantSpec = str -else: - _EnPassantSpec = Literal["legal", "fen", "xfen"] # type: ignore + _EnPassantSpec = str # type: ignore Color = bool diff --git a/chess/engine.py b/chess/engine.py index 89d4f3f1d..4af6b25b9 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -43,11 +43,10 @@ try: from typing import Literal + _WdlModel = Literal["sf12"] except ImportError: # Before Python 3.8. - _WdlModel = str -else: - _WdlModel = Literal["sf12"] # type: ignore + _WdlModel = str # type: ignore T = TypeVar("T") diff --git a/chess/pgn.py b/chess/pgn.py index 83cf73f82..a88099f70 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -33,11 +33,10 @@ try: from typing import Literal + _TrueLiteral = Literal[True] except ImportError: # Before Python 3.8. - _TrueLiteral = bool -else: - _TrueLiteral = Literal[True] # type: ignore + _TrueLiteral = bool # type: ignore LOGGER = logging.getLogger(__name__) From 069f0f03fbe6f84b743d5c170a9c3cbe4917c5c6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 23:14:18 +0200 Subject: [PATCH 1276/1831] Fix typo: thits -> tbhits --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 4af6b25b9..f150bf387 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -294,7 +294,7 @@ class InfoDict(typing.TypedDict, total=False): ``pv`` (a list of :class:`~chess.Move` objects), ``depth``, ``seldepth``, ``time`` (in seconds), ``nodes``, ``nps``, ``multipv``. - Others: ``thits``, ``currmove``, ``currmovenumber``, ``hashfull``, + Others: ``tbhits``, ``currmove``, ``currmovenumber``, ``hashfull``, ``cpuload``, ``refutation``, ``currline``, ``ebf``, ``wdl`` (a :class:`~chess.engine.PovWdl`), and ``string``. """ From 1393e6efab59304fbbb8b8690e9e1444b1093933 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 23:14:57 +0200 Subject: [PATCH 1277/1831] Clarify info["multipv"] --- chess/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index f150bf387..0f0e9431f 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -292,7 +292,8 @@ class InfoDict(typing.TypedDict, total=False): Commonly used keys are: ``score`` (a :class:`~chess.engine.PovScore`), ``pv`` (a list of :class:`~chess.Move` objects), ``depth``, - ``seldepth``, ``time`` (in seconds), ``nodes``, ``nps``, ``multipv``. + ``seldepth``, ``time`` (in seconds), ``nodes``, ``nps``, ``multipv`` + (``1`` for the mainline). Others: ``tbhits``, ``currmove``, ``currmovenumber``, ``hashfull``, ``cpuload``, ``refutation``, ``currline``, ``ebf``, From 9ab3a9ea5786c9af49390b0bd0c003c613764661 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 23:29:42 +0200 Subject: [PATCH 1278/1831] Port core py:attribute to field docs --- chess/__init__.py | 113 ++++++++++++++++++++++++++++++++++++++-- docs/core.rst | 129 ---------------------------------------------- 2 files changed, 108 insertions(+), 134 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index a71e99de8..59a0ad990 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -408,7 +408,10 @@ class Piece: """A piece with type and color.""" piece_type: PieceType + """The piece type.""" + color: Color + """The piece color.""" def symbol(self) -> str: """ @@ -458,9 +461,16 @@ class Move: """ from_square: Square + """The source square.""" + to_square: Square + """The target square.""" + promotion: Optional[PieceType] = None + """The promotion piece type or ``None``.""" + drop: Optional[PieceType] = None + """The drop piece type or ``None``.""" def uci(self) -> str: """ @@ -1398,17 +1408,110 @@ class Board(BaseBoard): pawnless_tbz_suffix: ClassVar[Optional[str]] = None pawnless_tbw_magic: ClassVar[Optional[bytes]] = None pawnless_tbz_magic: ClassVar[Optional[bytes]] = None - connected_kings = False - one_king = True - captures_compulsory = False + connected_kings: ClassVar[bool] = False + one_king: ClassVar[bool] = True + captures_compulsory: ClassVar[bool] = False + + turn: Color + """The side to move (``chess.WHITE`` or ``chess.BLACK``).""" + + castling_rights: Bitboard + """ + Bitmask of the rooks with castling rights. + + To test for specific squares: + + >>> import chess + >>> + >>> board = chess.Board() + >>> bool(board.castling_rights & chess.BB_H1) # White can castle with the h1 rook + True + + To add a specific square: + + >>> board.castling_rights |= chess.BB_A1 + + Use :func:`~chess.Board.set_castling_fen()` to set multiple castling + rights. Also see :func:`~chess.Board.has_castling_rights()`, + :func:`~chess.Board.has_kingside_castling_rights()`, + :func:`~chess.Board.has_queenside_castling_rights()`, + :func:`~chess.Board.has_chess960_castling_rights()`, + :func:`~chess.Board.clean_castling_rights()`. + """ + + ep_square: Optional[Square] + """ + The potential en passant square on the third or sixth rank or ``None``. + + Use :func:`~chess.Board.has_legal_en_passant()` to test if en passant + capturing would actually be possible on the next move. + """ + + fullmove_number: int + """ + Counts move pairs. Starts at `1` and is incremented after every move + of the black side. + """ + + halfmove_clock: int + """The number of half-moves since the last capture or pawn move.""" + + promoted: chess.Bitboard + """A bitmask of pieces that have been promoted.""" + + chess960: bool + """ + Whether the board is in Chess960 mode. In Chess960 castling moves are + represented as king moves to the corresponding rook square. + """ + + legal_moves: LegalMoveGenerator + """ + A dynamic list of legal moves. + + >>> import chess + >>> + >>> board = chess.Board() + >>> board.legal_moves.count() + 20 + >>> bool(board.legal_moves) + True + >>> move = chess.Move.from_uci("g1f3") + >>> move in board.legal_moves + True + + Wraps :func:`~chess.Board.generate_legal_moves()` and + :func:`~chess.Board.is_legal()`. + """ + + pseudo_legal_moves: PseudoLegalMoveGenerator + """ + A dynamic list of pseudo-legal moves, much like the legal move list. + + Pseudo-legal moves might leave or put the king in check, but are + otherwise valid. Null moves are not pseudo-legal. Castling moves are + only included if they are completely legal. + + Wraps :func:`~chess.Board.generate_pseudo_legal_moves()` and + :func:`~chess.Board.is_pseudo_legal()`. + """ + + move_stack: List[chess.Move] + """ + The move stack. Use :func:`Board.push() `, + :func:`Board.pop() `, + :func:`Board.peek() ` and + :func:`Board.clear_stack() ` for + manipulation. + """ def __init__(self: BoardT, fen: Optional[str] = STARTING_FEN, *, chess960: bool = False) -> None: BaseBoard.__init__(self, None) self.chess960 = chess960 - self.ep_square: Optional[Square] = None - self.move_stack: List[Move] = [] + self.ep_square = None + self.move_stack = [] self._stack: List[_BoardState[BoardT]] = [] if fen is None: diff --git a/docs/core.rst b/docs/core.rst index c82092d53..50d1011d1 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -93,42 +93,12 @@ Pieces .. autoclass:: chess.Piece :members: - .. py:attribute:: piece_type - :type: chess.PieceType - - The piece type. - - .. py:attribute:: color - :type: chess.Color - - The piece color. - Moves ----- .. autoclass:: chess.Move :members: - .. py:attribute:: from_square - :type: chess.Square - - The source square. - - .. py:attribute:: to_square - :type: chess.Square - - The target square. - - .. py:attribute:: promotion - :type: Optional[chess.PieceType] - - The promotion piece type or ``None``. - - .. py:attribute:: drop - :type: Optional[chess.PieceType] - - The drop piece type or ``None``. - Board ----- @@ -139,105 +109,6 @@ Board .. autoclass:: chess.Board :members: - .. py:attribute:: turn - :type: chess.Color - - The side to move (``chess.WHITE`` or ``chess.BLACK``). - - .. py:attribute:: castling_rights - :type: chess.Bitboard - - Bitmask of the rooks with castling rights. - - To test for specific squares: - - >>> import chess - >>> - >>> board = chess.Board() - >>> bool(board.castling_rights & chess.BB_H1) # White can castle with the h1 rook - True - - To add a specific square: - - >>> board.castling_rights |= chess.BB_A1 - - Use :func:`~chess.Board.set_castling_fen()` to set multiple castling - rights. Also see :func:`~chess.Board.has_castling_rights()`, - :func:`~chess.Board.has_kingside_castling_rights()`, - :func:`~chess.Board.has_queenside_castling_rights()`, - :func:`~chess.Board.has_chess960_castling_rights()`, - :func:`~chess.Board.clean_castling_rights()`. - - .. py:attribute:: ep_square - :type: Optional[chess.Square] - - The potential en passant square on the third or sixth rank or ``None``. - - Use :func:`~chess.Board.has_legal_en_passant()` to test if en passant - capturing would actually be possible on the next move. - - .. py:attribute:: fullmove_number - :type: int - - Counts move pairs. Starts at `1` and is incremented after every move - of the black side. - - .. py:attribute:: halfmove_clock - :type: int - - The number of half-moves since the last capture or pawn move. - - .. py:attribute:: promoted - :type: chess.Bitboard - - A bitmask of pieces that have been promoted. - - .. py:attribute:: chess960 - :type: bool - - Whether the board is in Chess960 mode. In Chess960 castling moves are - represented as king moves to the corresponding rook square. - - .. py:attribute:: legal_moves - :value: chess.LegalMoveGenerator(self) - - A dynamic list of legal moves. - - >>> import chess - >>> - >>> board = chess.Board() - >>> board.legal_moves.count() - 20 - >>> bool(board.legal_moves) - True - >>> move = chess.Move.from_uci("g1f3") - >>> move in board.legal_moves - True - - Wraps :func:`~chess.Board.generate_legal_moves()` and - :func:`~chess.Board.is_legal()`. - - .. py:attribute:: pseudo_legal_moves - :value: chess.PseudoLegalMoveGenerator(self) - - A dynamic list of pseudo-legal moves, much like the legal move list. - - Pseudo-legal moves might leave or put the king in check, but are - otherwise valid. Null moves are not pseudo-legal. Castling moves are - only included if they are completely legal. - - Wraps :func:`~chess.Board.generate_pseudo_legal_moves()` and - :func:`~chess.Board.is_pseudo_legal()`. - - .. py:attribute:: move_stack - :type: List[chess.Move] - - The move stack. Use :func:`Board.push() `, - :func:`Board.pop() `, - :func:`Board.peek() ` and - :func:`Board.clear_stack() ` for - manipulation. - .. autoclass:: chess.BaseBoard :members: From 778d5794f27ed7ad4cdccf9b3a8d5ec9956c8bfb Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 21 Oct 2020 23:32:27 +0200 Subject: [PATCH 1279/1831] Document properties directly --- chess/__init__.py | 67 ++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 59a0ad990..b4aac23cf 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1465,37 +1465,6 @@ class Board(BaseBoard): represented as king moves to the corresponding rook square. """ - legal_moves: LegalMoveGenerator - """ - A dynamic list of legal moves. - - >>> import chess - >>> - >>> board = chess.Board() - >>> board.legal_moves.count() - 20 - >>> bool(board.legal_moves) - True - >>> move = chess.Move.from_uci("g1f3") - >>> move in board.legal_moves - True - - Wraps :func:`~chess.Board.generate_legal_moves()` and - :func:`~chess.Board.is_legal()`. - """ - - pseudo_legal_moves: PseudoLegalMoveGenerator - """ - A dynamic list of pseudo-legal moves, much like the legal move list. - - Pseudo-legal moves might leave or put the king in check, but are - otherwise valid. Null moves are not pseudo-legal. Castling moves are - only included if they are completely legal. - - Wraps :func:`~chess.Board.generate_pseudo_legal_moves()` and - :func:`~chess.Board.is_pseudo_legal()`. - """ - move_stack: List[chess.Move] """ The move stack. Use :func:`Board.push() `, @@ -1521,14 +1490,42 @@ def __init__(self: BoardT, fen: Optional[str] = STARTING_FEN, *, chess960: bool else: self.set_fen(fen) - @property - def pseudo_legal_moves(self) -> PseudoLegalMoveGenerator: - return PseudoLegalMoveGenerator(self) - @property def legal_moves(self) -> LegalMoveGenerator: + """ + A dynamic list of legal moves. + + >>> import chess + >>> + >>> board = chess.Board() + >>> board.legal_moves.count() + 20 + >>> bool(board.legal_moves) + True + >>> move = chess.Move.from_uci("g1f3") + >>> move in board.legal_moves + True + + Wraps :func:`~chess.Board.generate_legal_moves()` and + :func:`~chess.Board.is_legal()`. + """ return LegalMoveGenerator(self) + + @property + def pseudo_legal_moves(self) -> PseudoLegalMoveGenerator: + """ + A dynamic list of pseudo-legal moves, much like the legal move list. + + Pseudo-legal moves might leave or put the king in check, but are + otherwise valid. Null moves are not pseudo-legal. Castling moves are + only included if they are completely legal. + + Wraps :func:`~chess.Board.generate_pseudo_legal_moves()` and + :func:`~chess.Board.is_pseudo_legal()`. + """ + return PseudoLegalMoveGenerator(self) + def reset(self) -> None: """Restores the starting position.""" self.turn = WHITE From cae9f6b342f429442073dbd20b1ec8ec23da480d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Oct 2020 00:20:37 +0200 Subject: [PATCH 1280/1831] Port remaining py:attribute docs to fields --- chess/__init__.py | 4 +- chess/engine.py | 111 +++++++++++++++++++++++++++-- chess/pgn.py | 63 +++++++++++++++-- chess/polyglot.py | 12 ++++ chess/svg.py | 9 +++ docs/engine.rst | 173 +--------------------------------------------- docs/pgn.rst | 57 --------------- docs/polyglot.rst | 26 +------ docs/svg.rst | 15 ---- 9 files changed, 191 insertions(+), 279 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index b4aac23cf..67c7103fd 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1456,7 +1456,7 @@ class Board(BaseBoard): halfmove_clock: int """The number of half-moves since the last capture or pawn move.""" - promoted: chess.Bitboard + promoted: Bitboard """A bitmask of pieces that have been promoted.""" chess960: bool @@ -1465,7 +1465,7 @@ class Board(BaseBoard): represented as king moves to the corresponding rook square. """ - move_stack: List[chess.Move] + move_stack: List[Move] """ The move stack. Use :func:`Board.push() `, :func:`Board.pop() `, diff --git a/chess/engine.py b/chess/engine.py index 0f0e9431f..68871adfa 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -220,11 +220,42 @@ class Option: """Information about an available engine option.""" name: str + """The name of the option.""" + type: str + """ + The type of the option. + + +--------+-----+------+------------------------------------------------+ + | type | UCI | CECP | value | + +========+=====+======+================================================+ + | check | X | X | ``True`` or ``False`` | + +--------+-----+------+------------------------------------------------+ + | button | X | X | ``None`` | + +--------+-----+------+------------------------------------------------+ + | reset | | X | ``None`` | + +--------+-----+------+------------------------------------------------+ + | save | | X | ``None`` | + +--------+-----+------+------------------------------------------------+ + | string | X | X | string without line breaks | + +--------+-----+------+------------------------------------------------+ + | file | | X | string, interpreted as the path to a file | + +--------+-----+------+------------------------------------------------+ + | path | | X | string, interpreted as the path to a directory | + +--------+-----+------+------------------------------------------------+ + """ + default: ConfigValue + """The default value of the option.""" + min: Optional[int] + """The minimum integer value of a *spin* option.""" + max: Optional[int] + """The maximum integer value of a *spin* option.""" + var: Optional[List[str]] + """A list of allowed string values for a *combo* option.""" def parse(self, value: ConfigValue) -> ConfigValue: if self.type == "check": @@ -267,14 +298,34 @@ class Limit: """Search-termination condition.""" time: Optional[float] = None + """Search exactly *time* seconds.""" + depth: Optional[int] = None + """Search *depth* ply only.""" + nodes: Optional[int] = None + """Search only a limited number of *nodes*.""" + mate: Optional[int] = None + """Search for a mate in *mate* moves.""" + white_clock: Optional[float] = None + """Time in seconds remaining for White.""" + black_clock: Optional[float] = None + """Time in seconds remaining for Black.""" + white_inc: Optional[float] = None + """Fisher increment for White, in seconds.""" + black_inc: Optional[float] = None + """Fisher increment for Black, in seconds.""" + remaining_moves: Optional[int] = None + """ + Number of moves to the next time control. If this is not set, but + *white_clock* and *black_clock* are, then it is sudden death. + """ def __repr__(self) -> str: # Like default __repr__, but without None values. @@ -325,6 +376,24 @@ class InfoDict(typing.TypedDict, total=False): class PlayResult: """Returned by :func:`chess.engine.Protocol.play()`.""" + move: Optional[chess.Move] + """The best move according to the engine, or ``None``.""" + + ponder: Optional[chess.Move] + """The response that the engine expects after *move*, or ``None``.""" + + info: InfoDict + """ + A dictionary of extra :class:`information ` + sent by the engine. + """ + + draw_offered: bool + """Whether the engine offered a draw before moving.""" + + resigned: bool + """Whether the engine resigned.""" + def __init__(self, move: Optional[chess.Move], ponder: Optional[chess.Move], @@ -334,7 +403,7 @@ def __init__(self, resigned: bool = False) -> None: self.move = move self.ponder = ponder - self.info: InfoDict = info or {} + self.info = info or {} self.draw_offered = draw_offered self.resigned = resigned @@ -366,6 +435,12 @@ class Info(enum.IntFlag): class PovScore: """A relative :class:`~chess.engine.Score` and the point of view.""" + relative: Score + """The relative :class:`~chess.engine.Score`.""" + + turn: Color + """The point of view (``chess.WHITE`` or ``chess.BLACK``).""" + def __init__(self, relative: Score, turn: Color) -> None: self.relative = relative self.turn = turn @@ -826,8 +901,17 @@ def get_returncode(self) -> Optional[int]: class Protocol(asyncio.SubprocessProtocol, metaclass=abc.ABCMeta): """Protocol for communicating with a chess engine process.""" - id: Dict[str, str] options: MutableMapping[str, Option] + """Dictionary of available options.""" + + id: Dict[str, str] + """ + Dictionary of information about the engine. Common keys are ``name`` + and ``author``. + """ + + returncode: asyncio.Future[int] + """Future: Exit code of the process.""" def __init__(self: ProtocolT) -> None: self.loop = asyncio.get_running_loop() @@ -963,8 +1047,9 @@ async def configure(self, options: ConfigMapping) -> None: Configures global engine options. :param options: A dictionary of engine options where the keys are - names of :py:attr:`~options`. Do not set options that are - managed automatically (:func:`chess.engine.Option.is_managed()`). + names of :data:`~chess.engine.Protocol.options`. Do not set options + that are managed automatically + (:func:`chess.engine.Option.is_managed()`). """ @abc.abstractmethod @@ -2302,6 +2387,12 @@ def _parse_xboard_post(line: str, root_board: chess.Board, selector: Info = INFO class BestMove: """Returned by :func:`chess.engine.AnalysisResult.wait()`.""" + move: Optional[chess.Move] + """The best move according to the engine, or ``None``.""" + + ponder: Optional[chess.Move] + """The response that the engine expects after *move*, or ``None``.""" + def __init__(self, move: Optional[chess.Move], ponder: Optional[chess.Move]): self.move = move self.ponder = ponder @@ -2321,13 +2412,19 @@ class AnalysisResult: Automatically stops the analysis when used as a context manager. """ + multipv: List[chess.engine.InfoDict] + """ + A list of dictionaries with aggregated information sent by the engine. + One item for each root move. + """ + def __init__(self, stop: Optional[Callable[[], None]] = None): self._stop = stop self._queue: asyncio.Queue[InfoDict] = asyncio.Queue() self._posted_kork = False self._seen_kork = False self._finished: asyncio.Future[BestMove] = asyncio.Future() - self.multipv: List[InfoDict] = [{}] + self.multipv = [{}] def post(self, info: InfoDict) -> None: # Empty dictionary reserved for kork. @@ -2357,6 +2454,10 @@ def set_exception(self, exc: Exception) -> None: @property def info(self) -> InfoDict: + """ + A dictionary of aggregated information sent by the engine. This is + actually an alias for ``multipv[0]``. + """ return self.multipv[0] def stop(self) -> None: diff --git a/chess/pgn.py b/chess/pgn.py index a88099f70..d9c567b72 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -161,12 +161,47 @@ def __init__(self, node: GameNode, *, is_variation: bool = False, sidelines: boo class GameNode: + + parent: Optional[GameNode] + """ + The parent node or ``None`` if this is the root node of the game. + """ + + move: Optional[chess.Move] + """ + The move leading to this node or ``None`` if this is the root node of the + game. + """ + + nags: Set[int] + """ + A set of NAGs as integers. NAGs always go behind a move, so the root + node of the game will never have NAGs. + """ + + comment: str + """ + A comment that goes behind the move leading to this node. Comments + that occur before any moves are assigned to the root node. + """ + + starting_comment: str + """ + A comment for the start of a variation. Only nodes that + actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` + checks this) can have a starting comment. The root node can not have + a starting comment. + """ + + variations: List[GameNode] + """A list of child nodes.""" + def __init__(self) -> None: - self.parent: Optional[GameNode] = None - self.variations: List[GameNode] = [] + self.parent = None + self.variations = [] - self.move: Optional[chess.Move] = None - self.nags: Set[int] = set() + self.move = None + self.nags = set() self.starting_comment = "" self.comment = "" @@ -670,10 +705,28 @@ class Game(GameNode): :class:`~chess.pgn.GameNode`. """ + headers: Headers + """ + A mapping of headers. By default, the following 7 headers are provided + (Seven Tag Roster): + + >>> import chess.pgn + >>> + >>> game = chess.pgn.Game() + >>> game.headers + Headers(Event='?', Site='?', Date='????.??.??', Round='?', White='?', Black='?', Result='*') + """ + + errors: List[Exception] + """ + A list of errors (such as illegal or ambiguous moves) encountered while + parsing the game. + """ + def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str, str]]]] = None) -> None: super().__init__() self.headers = Headers(headers) - self.errors: List[Exception] = [] + self.errors = [] def _board(self) -> chess.Board: return self.headers.board() diff --git a/chess/polyglot.py b/chess/polyglot.py index 6851b8d8b..eaec7b631 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -303,10 +303,22 @@ class Entry(NamedTuple): """An entry from a Polyglot opening book.""" key: int + """The Zobrist hash of the position.""" + raw_move: int + """ + The raw binary representation of the move. Use + :data:`~chess.polyglot.Entry.move` instead. + """ + weight: int + """An integer value that can be used as the weight for this entry.""" + learn: int + """Another integer value that can be used for extra information.""" + move: chess.Move + """The :class:`~chess.Move`.""" class _EmptyMmap(bytearray): diff --git a/chess/svg.py b/chess/svg.py index 59fca6a4a..d6ebae274 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -87,6 +87,15 @@ class Arrow: """Details of an arrow to be drawn.""" + tail: Square + """Start square of the arrow.""" + + head: Square + """End square of the arrow.""" + + color: str + """Arrow color.""" + def __init__(self, tail: Square, head: Square, *, color: str = "green") -> None: self.tail = tail self.head = head diff --git a/docs/engine.rst b/docs/engine.rst index ab0e548ad..bf9e31eae 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -62,81 +62,9 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. .. autoclass:: chess.engine.Limit :members: - .. py:attribute:: time - :type: Optional[float] - - Search exactly *time* seconds. - - .. py:attribute:: depth - :type: Optional[int] - - Search *depth* ply only. - - .. py:attribute:: nodes - :type: Optional[int] - - Search only a limited number of *nodes*. - - .. py:attribute:: mate - :type: Optional[int] - - Search for a mate in *mate* moves. - - .. py:attribute:: white_clock - :type: Optional[float] - - Time in seconds remaining for White. - - .. py:attribute:: black_clock - :type: Optional[float] - - Time in seconds remaining for Black. - - .. py:attribute:: white_inc - :type: Optional[float] - - Fisher increment for White, in seconds. - - .. py:attribute:: black_inc - :type: Optional[float] - - Fisher increment for Black, in seconds. - - .. py:attribute:: remaining_moves - :type: Optional[int] - - Number of moves to the next time control. If this is not set, but - *white_clock* and *black_clock* are, then it is sudden death. - .. autoclass:: chess.engine.PlayResult :members: - .. py:attribute:: move - :type: Optional[chess.Move] - - The best move according to the engine, or ``None``. - - .. py:attribute:: ponder - :type: Optional[chess.Move] - - The response that the engine expects after *move*, or ``None``. - - .. py:attribute:: info - :type: chess.engine.InfoDict - - A dictionary of extra :class:`information ` - sent by the engine. - - .. py:attribute:: draw_offered - :type: bool - - Whether the engine offered a draw before moving. - - .. py:attribute:: resigned - :type: bool - - Whether the engine resigned. - Analysing and evaluating a position ----------------------------------- @@ -193,16 +121,6 @@ Example: .. autoclass:: chess.engine.PovScore :members: - .. py:attribute:: relative - :type: chess.engine.Score - - The relative :class:`~chess.engine.Score`. - - .. py:attribute:: turn - :type: chess.Color - - The point of view (``chess.WHITE`` or ``chess.BLACK``). - .. autoclass:: chess.engine.Score :members: @@ -262,31 +180,9 @@ Example: Stream information from the engine and stop on an arbitrary condition. .. autoclass:: chess.engine.AnalysisResult :members: - .. py:attribute:: info - :type: chess.engine.InfoDict - - A dictionary of aggregated information sent by the engine. This is - actually an alias for ``multipv[0]``. - - .. py:attribute:: multipv - :type: List[chess.engine.InfoDict] - - A list of dictionaries with aggregated information sent by the engine. - One item for each root move. - .. autoclass:: chess.engine.BestMove :members: - .. py:attribute:: move - :type: Optional[chess.Move] - - The best move according to the engine, or ``None``. - - .. py:attribute:: ponder - :type: Optional[chess.Move] - - The response that the engine expects after *move*, or ``None``. - Options ------- @@ -329,62 +225,10 @@ Option(name='Hash', type='spin', default=16, min=1, max=131072, var=[]) asyncio.run(main()) .. autoclass:: chess.engine.Protocol - :members: configure - - .. py:attribute:: options - :type: MutableMapping[str, chess.engine.Option] - - Dictionary of available options. + :members: options, configure .. autoclass:: chess.engine.Option - :members: is_managed - - .. py:attribute:: name - :type: str - - The name of the option. - - .. py:attribute:: type - - The type of the option. - - +--------+-----+------+------------------------------------------------+ - | type | UCI | CECP | value | - +========+=====+======+================================================+ - | check | X | X | ``True`` or ``False`` | - +--------+-----+------+------------------------------------------------+ - | button | X | X | ``None`` | - +--------+-----+------+------------------------------------------------+ - | reset | | X | ``None`` | - +--------+-----+------+------------------------------------------------+ - | save | | X | ``None`` | - +--------+-----+------+------------------------------------------------+ - | string | X | X | string without line breaks | - +--------+-----+------+------------------------------------------------+ - | file | | X | string, interpreted as the path to a file | - +--------+-----+------+------------------------------------------------+ - | path | | X | string, interpreted as the path to a directory | - +--------+-----+------+------------------------------------------------+ - - .. py:attribute:: default - :type: chess.engine.ConfigValue - - The default value of the option. - - .. py:attribute:: min - :type: Optional[int] - - The minimum integer value of a *spin* option. - - .. py:attribute:: max - :type: Optional[int] - - The maximum integer value of a *spin* option. - - .. py:attribute:: var - :type: Optional[List[str]] - - A list of allowed string values for a *combo* option. + :members: Logging ------- @@ -438,18 +282,7 @@ Reference .. autofunction:: chess.engine.popen_xboard .. autoclass:: chess.engine.Protocol - :members: initialize, ping, quit - - .. py:attribute:: returncode - :type: asyncio.Future[int] - - Future: Exit code of the process. - - .. py:attribute:: id - :type: Dict[str, str] - - Dictionary of information about the engine. Common keys are ``name`` - and ``author``. + :members: id, returncode, initialize, ping, quit .. autoclass:: chess.engine.UciProtocol diff --git a/docs/pgn.rst b/docs/pgn.rst index 00f63cdbf..a1307795b 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -50,66 +50,9 @@ holds general information, such as game headers. .. autoclass:: chess.pgn.Game :members: - .. py:attribute:: headers - :type: chess.pgn.Headers - - A mapping of headers. By default, the following 7 headers are provided - (Seven Tag Roster): - - >>> import chess.pgn - >>> - >>> game = chess.pgn.Game() - >>> game.headers - Headers(Event='?', Site='?', Date='????.??.??', Round='?', White='?', Black='?', Result='*') - - .. py:attribute:: errors - :type: List[Exception] - - A list of errors (such as illegal or ambiguous moves) encountered while - parsing the game. - .. autoclass:: chess.pgn.GameNode :members: - .. py:attribute:: parent - :type: Optional[chess.pgn.GameNode] - - The parent node or ``None`` if this is the root node of the game. - - .. py:attribute:: move - :type: Optional[chess.Move] - - The move leading to this node or ``None`` if this is the root node of the - game. - - .. py:attribute:: nags - :type: Set[int] - :value: set() - - A set of NAGs as integers. NAGs always go behind a move, so the root - node of the game will never have NAGs. - - .. py:attribute:: comment - :type: str - :value: '' - - A comment that goes behind the move leading to this node. Comments - that occur before any moves are assigned to the root node. - - .. py:attribute:: starting_comment - :type: str - :value: '' - - A comment for the start of a variation. Only nodes that - actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` - checks this) can have a starting comment. The root node can not have - a starting comment. - - .. py:attribute:: variations - :type: List[chess.pgn.GameNode] - - A list of child nodes. - Visitors -------- diff --git a/docs/polyglot.rst b/docs/polyglot.rst index ecdd14ade..18c94c426 100644 --- a/docs/polyglot.rst +++ b/docs/polyglot.rst @@ -4,32 +4,8 @@ Polyglot opening book reading .. autofunction:: chess.polyglot.open_reader .. autoclass:: chess.polyglot.Entry + :members: - .. py:attribute:: key - :type: int - - The Zobrist hash of the position. - - .. py:attribute:: raw_move - :type: int - - The raw binary representation of the move. Use - :data:`~chess.polyglot.Entry.move` instead. - - .. py:attribute:: weight - :type: int - - An integer value that can be used as the weight for this entry. - - .. py:attribute:: learn - :type: int - - Another integer value that can be used for extra information. - - .. py:attribute:: move - :type: chess.Move - - The :class:`~chess.Move`. .. autoclass:: chess.polyglot.MemoryMappedReader :members: diff --git a/docs/svg.rst b/docs/svg.rst index 6921db411..b839f10a7 100644 --- a/docs/svg.rst +++ b/docs/svg.rst @@ -13,18 +13,3 @@ licensed under the GFDL, BSD and GPL. .. autoclass:: chess.svg.Arrow :members: - - .. py:attribute:: tail - :type: chess.Square - - Start square of the arrow. - - .. py:attribute:: head - :type: chess.Square - - End square of the arrow. - - .. py:attribute:: color - :value: 'green' - - Arrow color. From f68f7b330265402747da34c8944480132baed745 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Oct 2020 00:22:12 +0200 Subject: [PATCH 1281/1831] Add a comma --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 68871adfa..b8ba32199 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -556,7 +556,7 @@ def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: >>> Cp(500).wdl().expectation() - Cp(300).wdl().expectation() # doctest: +ELLIPSIS 0.015... - :param model: Currently the only implemented model is ``sf12``, the + :param model: Currently, the only implemented model is ``sf12``, the win rate model used by Stockfish 12. :param ply: The number of half-moves played since the starting position. Models may scale scores slightly differently based on From 049f66786f1afde64d579efa67a67173f634d4c8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Oct 2020 01:04:49 +0200 Subject: [PATCH 1282/1831] Prepare changelog --- CHANGELOG.rst | 25 +++++++++++++++++++++++++ release.py | 4 ++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 48fe80784..b593d5e19 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,31 @@ Changelog for python-chess ========================== +Upcoming in v1.2.0 +------------------ + +New features: + +* Added `chess.Board.ply()`. +* Added `chess.pgn.GameNode.ply()` and `chess.pgn.GameNode.turn()`. +* Added `chess.engine.PovWdl`, `chess.engine.Wdl`, and conversions from score: + `chess.engine.PovScore.wdl()`, `chess.engine.Score.wdl()`. +* Added `chess.engine.Score(*, mate_score: int) -> int` overload. + +Changes: + +* The `PovScore` returned by `chess.pgn.GameNode.eval()` is now always + relative to the side to move. The ambiguity around `[%eval #0]` has been + resolved to `Mate(-0)`. This makes sense, given that the authors had standard + chess in mind (where a game ending move is always a loss for the opponent). +* Typed `chess.engine.InfoDict["wdl"]` as the new `chess.engine.PovWdl`, rather + than `Tuple[int, int, int]`. The new type is backwards compatible, but it + is recommended to use its documented fields and methods instead. +* Removed `chess.engine.PovScore.__str__()`. String representation falls back + to `__repr__`. +* The `en_passant` parameter of `chess.Board.fen()` and `chess.Board.epd()` is + now typed as `Literal["legal", "fen", "xfen"]` rather than `str`. + New in v1.1.0 ------------- diff --git a/release.py b/release.py index de5c1de29..0d0336057 100755 --- a/release.py +++ b/release.py @@ -35,8 +35,8 @@ def check_changelog(): with open("CHANGELOG.rst", "r") as changelog_file: changelog = changelog_file.read() - if "Upcoming in the next release" in changelog: - print("Found: Upcoming in the next release") + if "Upcoming in" in changelog: + print("Found: Upcoming in") sys.exit(1) tagname = f"v{chess.__version__}" From 6c20669b0c2363115475a183a228152ff4ce0e77 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Oct 2020 10:45:37 +0200 Subject: [PATCH 1283/1831] Explicit type annotations for reamining class vars --- chess/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 67c7103fd..e6da36a39 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1395,10 +1395,10 @@ class Board(BaseBoard): Use :func:`~chess.Board.is_valid()` to detect invalid positions. """ - aliases = ["Standard", "Chess", "Classical", "Normal", "Illegal", "From Position"] + aliases: ClassVar[List[str]] = ["Standard", "Chess", "Classical", "Normal", "Illegal", "From Position"] uci_variant: ClassVar[Optional[str]] = "chess" xboard_variant: ClassVar[Optional[str]] = "normal" - starting_fen = STARTING_FEN + starting_fen: ClassVar[str] = STARTING_FEN tbw_suffix: ClassVar[Optional[str]] = ".rtbw" tbz_suffix: ClassVar[Optional[str]] = ".rtbz" @@ -1511,7 +1511,6 @@ def legal_moves(self) -> LegalMoveGenerator: """ return LegalMoveGenerator(self) - @property def pseudo_legal_moves(self) -> PseudoLegalMoveGenerator: """ From dc529b2c640b17c1b163582d81bd4e17cf6ae6cc Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Oct 2020 01:06:45 +0200 Subject: [PATCH 1284/1831] Clarify change around [%eval #0] --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b593d5e19..6c20d762a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,7 @@ Changes: relative to the side to move. The ambiguity around `[%eval #0]` has been resolved to `Mate(-0)`. This makes sense, given that the authors had standard chess in mind (where a game ending move is always a loss for the opponent). + Previously this would be parsed as `None`. * Typed `chess.engine.InfoDict["wdl"]` as the new `chess.engine.PovWdl`, rather than `Tuple[int, int, int]`. The new type is backwards compatible, but it is recommended to use its documented fields and methods instead. From a07d343b0613c1b745eb074f49d5b35a4bc65f6a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Oct 2020 13:15:06 +0200 Subject: [PATCH 1285/1831] Fix rst in CHANGELOG (at least in the new one) --- CHANGELOG.rst | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6c20d762a..cde11fcde 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,40 +6,41 @@ Upcoming in v1.2.0 New features: -* Added `chess.Board.ply()`. -* Added `chess.pgn.GameNode.ply()` and `chess.pgn.GameNode.turn()`. -* Added `chess.engine.PovWdl`, `chess.engine.Wdl`, and conversions from score: - `chess.engine.PovScore.wdl()`, `chess.engine.Score.wdl()`. -* Added `chess.engine.Score(*, mate_score: int) -> int` overload. +* Added ``chess.Board.ply()``. +* Added ``chess.pgn.GameNode.ply()`` and ``chess.pgn.GameNode.turn()``. +* Added ``chess.engine.PovWdl``, ``chess.engine.Wdl``, and conversions from + scores: ``chess.engine.PovScore.wdl()``, ``chess.engine.Score.wdl()``. +* Added ``chess.engine.Score(*, mate_score: int) -> int`` overload. Changes: -* The `PovScore` returned by `chess.pgn.GameNode.eval()` is now always - relative to the side to move. The ambiguity around `[%eval #0]` has been - resolved to `Mate(-0)`. This makes sense, given that the authors had standard - chess in mind (where a game ending move is always a loss for the opponent). - Previously this would be parsed as `None`. -* Typed `chess.engine.InfoDict["wdl"]` as the new `chess.engine.PovWdl`, rather - than `Tuple[int, int, int]`. The new type is backwards compatible, but it - is recommended to use its documented fields and methods instead. -* Removed `chess.engine.PovScore.__str__()`. String representation falls back - to `__repr__`. -* The `en_passant` parameter of `chess.Board.fen()` and `chess.Board.epd()` is - now typed as `Literal["legal", "fen", "xfen"]` rather than `str`. +* The ``PovScore`` returned by ``chess.pgn.GameNode.eval()`` is now always + relative to the side to move. The ambiguity around ``[%eval #0]`` has been + resolved to ``Mate(-0)``. This makes sense, given that the authors had + standard chess in mind (where a game ending move is always a loss for the + opponent). Previously this would be parsed as ``None``. +* Typed ``chess.engine.InfoDict["wdl"]`` as the new ``chess.engine.PovWdl``, + rather than ``Tuple[int, int, int]``. The new type is backwards compatible, + but it is recommended to use its documented fields and methods instead. +* Removed ``chess.engine.PovScore.__str__()``. String representation falls back + to ``__repr__``. +* The ``en_passant`` parameter of ``chess.Board.fen()`` and + ``chess.Board.epd()`` is now typed as ``Literal["legal", "fen", "xfen"]`` + rather than ``str``. New in v1.1.0 ------------- New features: -* Added `chess.svg.board(..., orientation)`. This is a more idiomatic way to - set the board orientation than `flipped`. -* Added `chess.svg.Arrow.pgn()` and `chess.svg.Arrow.from_pgn()`. +* Added ``chess.svg.board(..., orientation)``. This is a more idiomatic way to + set the board orientation than ``flipped``. +* Added ``chess.svg.Arrow.pgn()`` and ``chess.svg.Arrow.from_pgn()``. Changes: -* Further relaxed `chess.Board.parse_san()`. Now accepts fully specified moves - like `e2e4`, even if that is not a pawn move, castling notation with zeros, +* Further relaxed ``chess.Board.parse_san()``. Now accepts fully specified moves + like ``e2e4``, even if that is not a pawn move, castling notation with zeros, null moves in UCI notation, and null moves in XBoard notation. New in v1.0.1 @@ -47,8 +48,8 @@ New in v1.0.1 Bugfixes: -* `chess.svg`: Restore SVG Tiny compatibility by splitting colors like - `#rrggbbaa` into a solid color and opacity. +* ``chess.svg``: Restore SVG Tiny compatibility by splitting colors like + ``#rrggbbaa`` into a solid color and opacity. New in v1.0.0 ------------- From bbf87dbf09affcccb341762266eb140abe15628a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Oct 2020 13:20:11 +0200 Subject: [PATCH 1286/1831] Add deprecation notice for PovWdl tuple like behavior --- chess/engine.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index b8ba32199..6732a57ed 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -736,6 +736,12 @@ class PovWdl: """ Relative :class:`win/draw/loss statistics ` and the point of view. + + .. deprecated:: 1.2 + Behaves like a tuple + ``(wdl.relative.wins, wdl.relative.draws, wdl.relative.losses)`` + for backwards compatibility. But it is recommended to use the provided + fields and methods instead. """ relative: Wdl From 8b7ed230711e3020422b2ab5c3b6fe2c870630fe Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Oct 2020 13:39:49 +0200 Subject: [PATCH 1287/1831] Prepare 1.2.0 --- CHANGELOG.rst | 6 +++--- chess/__init__.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index cde11fcde..7a7f90855 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,8 @@ Changelog for python-chess ========================== -Upcoming in v1.2.0 ------------------- +New in v1.2.0 +------------- New features: @@ -48,7 +48,7 @@ New in v1.0.1 Bugfixes: -* ``chess.svg``: Restore SVG Tiny compatibility by splitting colors like +* ``chess.svg``: Restored SVG Tiny compatibility by splitting colors like ``#rrggbbaa`` into a solid color and opacity. New in v1.0.0 diff --git a/chess/__init__.py b/chess/__init__.py index e6da36a39..94e11b6dc 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.1.0" +__version__ = "1.2.0" import collections import copy From 1164b787ce9f5209f695667ed15e56c3498e154d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Fri, 23 Oct 2020 02:53:09 +0200 Subject: [PATCH 1288/1831] Fix some commas and words Found some bad apples and threw them away. --- chess/engine.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 6732a57ed..182a12466 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -777,8 +777,8 @@ def __repr__(self) -> str: # Unfortunately in python-chess v1.1.0, info["wdl"] was a simple tuple # of the relative permille values, so we have to support __iter__, - # __len__, __getitem__ and equality comparisons with other tuples. - # Nevermind ordering, because thats not a sensible operation anyway. + # __len__, __getitem__, and equality comparisons with other tuples. + # Never mind the ordering, because that's not a sensible operation, anyway. def __iter__(self) -> Iterator[int]: yield self.relative.wins @@ -815,7 +815,7 @@ class Wdl: def total(self) -> int: """ - Returns the total number of games. Usually ``wdl`` reported by engines + Returns the total number of games. Usually, ``wdl`` reported by engines is scaled to 1000 games. """ return self.wins + self.draws + self.losses From 16e6543466f1982b4074c94580858495f39ccbd0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 23 Oct 2020 11:44:39 +0200 Subject: [PATCH 1289/1831] Some post hoc changelog fixes for 1.2.0 --- CHANGELOG.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7a7f90855..ff382fa39 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,15 +10,16 @@ New features: * Added ``chess.pgn.GameNode.ply()`` and ``chess.pgn.GameNode.turn()``. * Added ``chess.engine.PovWdl``, ``chess.engine.Wdl``, and conversions from scores: ``chess.engine.PovScore.wdl()``, ``chess.engine.Score.wdl()``. -* Added ``chess.engine.Score(*, mate_score: int) -> int`` overload. +* Added ``chess.engine.Score.score(*, mate_score: int) -> int`` overload. Changes: * The ``PovScore`` returned by ``chess.pgn.GameNode.eval()`` is now always relative to the side to move. The ambiguity around ``[%eval #0]`` has been - resolved to ``Mate(-0)``. This makes sense, given that the authors had - standard chess in mind (where a game ending move is always a loss for the - opponent). Previously this would be parsed as ``None``. + resolved to ``Mate(-0)``. This makes sense, given that the authors of the + specification probably had standard chess in mind (where a game ending move + is always a loss for the opponent). Previously this would be parsed as + ``None``. * Typed ``chess.engine.InfoDict["wdl"]`` as the new ``chess.engine.PovWdl``, rather than ``Tuple[int, int, int]``. The new type is backwards compatible, but it is recommended to use its documented fields and methods instead. From 133aa36028c8d635c0f36c0695c068eebc86e1ea Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 23 Oct 2020 12:30:54 +0200 Subject: [PATCH 1290/1831] Fix a missed delayed type annotation --- chess/pgn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index d9c567b72..4f5b541b3 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -305,7 +305,7 @@ def root(self) -> GameNode: node = node.parent return node - def game(self) -> "Game": + def game(self) -> Game: """Gets the root node, i.e., the game.""" root = self.root() assert isinstance(root, Game), "GameNode not rooted in Game" From f3ca606934cd2cd9b1baff81008720e00e1d640e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Fri, 23 Oct 2020 15:46:27 +0200 Subject: [PATCH 1291/1831] Fix CHANGELOG.rst Added a hyphen and a comma. --- CHANGELOG.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ff382fa39..07d76bc2f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,8 +17,8 @@ Changes: * The ``PovScore`` returned by ``chess.pgn.GameNode.eval()`` is now always relative to the side to move. The ambiguity around ``[%eval #0]`` has been resolved to ``Mate(-0)``. This makes sense, given that the authors of the - specification probably had standard chess in mind (where a game ending move - is always a loss for the opponent). Previously this would be parsed as + specification probably had standard chess in mind (where a game-ending move + is always a loss for the opponent). Previously, this would be parsed as ``None``. * Typed ``chess.engine.InfoDict["wdl"]`` as the new ``chess.engine.PovWdl``, rather than ``Tuple[int, int, int]``. The new type is backwards compatible, From a2e286bddfd191655fdf26b4ae188508934ed569 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 26 Oct 2020 11:37:37 +0100 Subject: [PATCH 1292/1831] Prepare python-chess -> chess transition (#678) --- CHANGELOG.rst | 12 ++++++++++++ README.rst | 23 ++++++++++++----------- setup.py | 2 +- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 07d76bc2f..5a4113cc6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,18 @@ Changelog for python-chess ========================== +Upcoming in v1.2.1 +------------------ + +The primary location for the published package is now +https://pypi.org/project/chess/. Thanks to +`Kristian Glass `_ for transferring the +namespace. + +The old https://pypi.org/project/python-chess/ will remain an alias that +installs the package from the new location as a dependency (as recommended by +`PEP423 `_). + New in v1.2.0 ------------- diff --git a/README.rst b/README.rst index a457c97ce..18c308a04 100644 --- a/README.rst +++ b/README.rst @@ -13,8 +13,8 @@ python-chess: a pure Python chess library :target: https://coveralls.io/github/niklasf/python-chess?branch=master :alt: coverage -.. image:: https://badge.fury.io/py/python-chess.svg - :target: https://pypi.python.org/pypi/python-chess +.. image:: https://badge.fury.io/py/chess.svg + :target: https://pypi.python.org/pypi/chess :alt: pypi package .. image:: https://readthedocs.org/projects/python-chess/badge/?version=latest @@ -64,6 +64,16 @@ python-chess: >>> board Board('r1bqkb1r/pppp1Qpp/2n2n2/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR b KQkq - 0 4') +Installing +---------- + +Download and install the latest release: + +:: + + pip install chess + + `Documentation `__ -------------------------------------------------------------------- @@ -293,15 +303,6 @@ Features >>> engine.quit() -Installing ----------- - -Download and install the latest release: - -:: - - pip install python-chess - Selected use cases ------------------ diff --git a/setup.py b/setup.py index e3057a29d..c1e795374 100755 --- a/setup.py +++ b/setup.py @@ -75,7 +75,7 @@ def read_description(): setuptools.setup( - name="python-chess", + name="chess", version=chess.__version__, author=chess.__author__, author_email=chess.__email__, From d78aa1a0bc723bbd6010143d43ab8e47390a46fd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 26 Oct 2020 11:50:00 +0100 Subject: [PATCH 1293/1831] Update acknowledgements --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index 18c308a04..d4292bc78 100644 --- a/README.rst +++ b/README.rst @@ -335,6 +335,9 @@ Thanks to Ronald de Man for his `Syzygy endgame tablebases `_. The probing code in python-chess is very directly ported from his C probing code. +Thanks to `Kristian Glass `_ for +transferring the namespace ``chess`` on PyPI. + License ------- From 800b05bf289d6be80029c27db522fe96fa8bc110 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 26 Oct 2020 12:02:03 +0100 Subject: [PATCH 1294/1831] Rename as per PEP423 (closes #678) --- python-chess-stub/README.rst | 10 ++++++++++ python-chess-stub/setup.py | 26 ++++++++++++++++++++++++++ setup.py | 1 + 3 files changed, 37 insertions(+) create mode 100644 python-chess-stub/README.rst create mode 100755 python-chess-stub/setup.py diff --git a/python-chess-stub/README.rst b/python-chess-stub/README.rst new file mode 100644 index 000000000..f672aeb9a --- /dev/null +++ b/python-chess-stub/README.rst @@ -0,0 +1,10 @@ +python-chess +============ + +Package moved +------------- + +This package has been moved to https://pypi.org/project/chess/. + +Thanks to `Kristian Glass `_ for making +the package name available. diff --git a/python-chess-stub/setup.py b/python-chess-stub/setup.py new file mode 100755 index 000000000..a0c4ef0d6 --- /dev/null +++ b/python-chess-stub/setup.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import setuptools + +setuptools.setup( + name="python-chess", + version="1.999", + author="Niklas Fiekas", + author_email="niklas.fiekas@backscattering.de", + description="A chess library with move generation, move validation, and support for common formats.", + long_description=open(os.path.join(os.path.dirname(__file__), "README.rst")).read(), + long_description_content_type="text/x-rst", + license="GPL-3.0+", + keywords="chess fen epd pgn polyglot syzygy gaviota uci xboard", + url="https://github.com/niklasf/python-chess", + packages=[], + install_requires=["chess>=1,<2"], + classifiers=[ + "Development Status :: 7 - Inactive", + ], + project_urls={ + "Documentation": "https://python-chess.readthedocs.io", + }, +) diff --git a/setup.py b/setup.py index c1e795374..5ce4d2a4b 100755 --- a/setup.py +++ b/setup.py @@ -111,4 +111,5 @@ def read_description(): project_urls={ "Documentation": "https://python-chess.readthedocs.io", }, + obsoletes=["python_chess"], ) From aba441fdf4884a23037111c8b2a8b30f69d67cd4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 26 Oct 2020 12:34:43 +0100 Subject: [PATCH 1295/1831] Prepare 1.2.1 --- CHANGELOG.rst | 4 ++-- chess/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5a4113cc6..8fd7511f2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,8 @@ Changelog for python-chess ========================== -Upcoming in v1.2.1 ------------------- +New in v1.2.1 +------------- The primary location for the published package is now https://pypi.org/project/chess/. Thanks to diff --git a/chess/__init__.py b/chess/__init__.py index 94e11b6dc..8fbd05e07 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.2.0" +__version__ = "1.2.1" import collections import copy From 963ebc55566efaffac5fc9876e52a51513b9eb5e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 27 Oct 2020 12:45:05 +0100 Subject: [PATCH 1296/1831] document workaround for #680 --- README.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.rst b/README.rst index d4292bc78..5319a9d86 100644 --- a/README.rst +++ b/README.rst @@ -73,6 +73,10 @@ Download and install the latest release: pip install chess +``ModuleNotFoundError: No module named 'chess'`` after upgrading from old +python-chess versions? ``pip install --force-reinstall chess`` +(due to `#680 `_) + `Documentation `__ -------------------------------------------------------------------- From 9d10ed8236d3d4aa0a0a4ec6bacff080b7ce4824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Wed, 28 Oct 2020 17:26:55 +0100 Subject: [PATCH 1297/1831] Add some commas (#681) --- chess/svg.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index d6ebae274..b9cb6c912 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -106,7 +106,7 @@ def pgn(self) -> str: Returns the arrow in the format used by ``[%csl ...]`` and ``[%cal ...]`` PGN annotations, e.g., ``Ga1`` or ``Ya2h2``. - Colors other than ``red``, ``yellow`` and ``blue`` default to green. + Colors other than ``red``, ``yellow``, and ``blue`` default to green. """ if self.color == "red": color = "R" @@ -244,18 +244,18 @@ def board(board: Optional[chess.BaseBoard] = None, *, """ Renders a board with pieces and/or selected squares as an SVG image. - :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or + :param board: A :class:`chess.BaseBoard` for a chessboard with pieces, or ``None`` (the default) for a chessboard without pieces. :param orientation: The point of view, defaulting to ``chess.WHITE``. :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked indicating a check. - :param arrows: A list of :class:`~chess.svg.Arrow` objects like - ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like + :param arrows: A list of :class:`~chess.svg.Arrow` objects, like + ``[chess.svg.Arrow(chess.E2, chess.E4)]``, or a list of tuples, like ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same square is drawn as a circle, like ``[(chess.E2, chess.E2)]``. :param squares: A :class:`chess.SquareSet` with selected squares. :param size: The size of the image in pixels (e.g., ``400`` for a 400 by - 400 board) or ``None`` (the default) for no size limit. + 400 board), or ``None`` (the default) for no size limit. :param coordinates: Pass ``False`` to disable the coordinate margin. :param colors: A dictionary to override default colors. Possible keys are ``square light``, ``square dark``, ``square light lastmove``, From bfa6c6ddd183a0734cf71898b0c9169c18340c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Thu, 29 Oct 2020 11:20:27 +0100 Subject: [PATCH 1298/1831] One more comma Forgot to add one more comma to the docstring text of svg.board(). --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index b9cb6c912..42b939c67 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -261,7 +261,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, ``square light``, ``square dark``, ``square light lastmove``, ``square dark lastmove``, ``margin``, ``coord``, ``arrow green``, ``arrow blue``, ``arrow red``, and ``arrow yellow``. Values should look - like ``#ffce9e`` (opaque) or ``#15781B80`` (transparent). + like ``#ffce9e`` (opaque), or ``#15781B80`` (transparent). :param flipped: Pass ``True`` to flip the board. :param style: A CSS stylesheet to include in the SVG image. From dabcd200566640b65d62c4d616b462a07492490f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 29 Oct 2020 17:48:25 +0100 Subject: [PATCH 1299/1831] Add py.typed marker --- chess/py.typed | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 chess/py.typed diff --git a/chess/py.typed b/chess/py.typed new file mode 100644 index 000000000..e69de29bb From 7348e966d0a63b40c73a42fd1bdd0e79422110c8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 29 Oct 2020 18:29:32 +0100 Subject: [PATCH 1300/1831] Prepare 1.2.2 --- CHANGELOG.rst | 8 ++++++++ chess/__init__.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8fd7511f2..63f323550 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ Changelog for python-chess ========================== +New in v1.2.2 +------------- + +Bugfixes: + +* Fixed regression, where releases were uploaded without the ``py.typed`` + marker. + New in v1.2.1 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index 8fbd05e07..2fd5cb15b 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.2.1" +__version__ = "1.2.2" import collections import copy From 0e0be18f6a5097cd63d60e5a85919b0eff5e56ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sun, 1 Nov 2020 10:49:56 +0100 Subject: [PATCH 1301/1831] Remove redundant comma There's no comma needed in this particular sentence in CHANGELOG.rst. So it was removed. --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 63f323550..d18075674 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,7 +6,7 @@ New in v1.2.2 Bugfixes: -* Fixed regression, where releases were uploaded without the ``py.typed`` +* Fixed regression where releases were uploaded without the ``py.typed`` marker. New in v1.2.1 From 52d918e3e90e9c3d4ebbdfb64e25d1a281629259 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 2 Nov 2020 10:18:40 +0100 Subject: [PATCH 1302/1831] Update PovScore repr in engine docs --- docs/engine.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/engine.rst b/docs/engine.rst index bf9e31eae..f0517c392 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -80,12 +80,12 @@ Example: board = chess.Board() info = engine.analyse(board, chess.engine.Limit(time=0.1)) print("Score:", info["score"]) - # Score: +20 + # Score: PovScore(Cp(+20), WHITE) board = chess.Board("r1bqkbnr/p1pp1ppp/1pn5/4p3/2B1P3/5Q2/PPPP1PPP/RNB1K1NR w KQkq - 2 4") info = engine.analyse(board, chess.engine.Limit(depth=20)) print("Score:", info["score"]) - # Score: #+1 + # Score: PovScore(Mate(+1), WHITE) engine.quit() @@ -101,12 +101,12 @@ Example: board = chess.Board() info = await engine.analyse(board, chess.engine.Limit(time=0.1)) print(info["score"]) - # Score: +20 + # Score: PovScore(Cp(+20), WHITE) board = chess.Board("r1bqkbnr/p1pp1ppp/1pn5/4p3/2B1P3/5Q2/PPPP1PPP/RNB1K1NR w KQkq - 2 4") info = await engine.analyse(board, chess.engine.Limit(depth=20)) print(info["score"]) - # Score: #+1 + # Score: PovScore(Mate(+1), WHITE) await engine.quit() From e559487a0d5378a4940dfb770e888884f21ed0ce Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 5 Nov 2020 22:02:55 +0100 Subject: [PATCH 1303/1831] Add GameNode.next() --- chess/pgn.py | 7 +++++++ test.py | 14 +++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 4f5b541b3..3458e4bff 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -436,6 +436,13 @@ def add_main_variation(self, move: chess.Move, *, comment: str = "") -> GameNode self.variations.insert(0, node) return node + def next(self) -> Optional[GameNode]: + """ + Returns the first node of the mainline after this node, or ``None`` if + this node does not have any children. + """ + return self.variations[0] if self.variations else None + def mainline(self) -> Mainline[GameNode]: """Returns an iterable over the mainline starting after this node.""" return Mainline(self, lambda node: node) diff --git a/test.py b/test.py index 9762a4fdc..864bb6063 100755 --- a/test.py +++ b/test.py @@ -2383,11 +2383,11 @@ def test_tricky_skip_game(self): self.assertEqual(len(offsets), 3) pgn.seek(offsets[0]) - self.assertEqual(chess.pgn.read_game(pgn).variations[0].move, chess.Move.from_uci("a2a3")) + self.assertEqual(chess.pgn.read_game(pgn).next().move, chess.Move.from_uci("a2a3")) pgn.seek(offsets[1]) - self.assertEqual(chess.pgn.read_game(pgn).variations[0].move, chess.Move.from_uci("b2b3")) + self.assertEqual(chess.pgn.read_game(pgn).next().move, chess.Move.from_uci("b2b3")) pgn.seek(offsets[2]) - self.assertEqual(chess.pgn.read_game(pgn).variations[0].move, chess.Move.from_uci("d2d3")) + self.assertEqual(chess.pgn.read_game(pgn).next().move, chess.Move.from_uci("d2d3")) self.assertEqual(chess.pgn.read_game(pgn), None) def test_read_headers(self): @@ -2510,7 +2510,7 @@ def test_chessbase_empty_line(self): game = chess.pgn.read_game(pgn) self.assertEqual(game.headers["Event"], "AlphaZero vs. Stockfish") self.assertEqual(game.headers["Round"], "1") - self.assertEqual(game.variations[0].move, chess.Move.from_uci("e2e4")) + self.assertEqual(game.next().move, chess.Move.from_uci("e2e4")) self.assertTrue(chess.pgn.read_game(pgn) is None) @@ -2621,7 +2621,7 @@ def test_wierd_header(self): def test_semicolon_comment(self): pgn = io.StringIO("1. e4 ; e5") game = chess.pgn.read_game(pgn) - node = game.variations[0] + node = game.next() self.assertEqual(node.move, chess.Move.from_uci("e2e4")) self.assertTrue(node.is_end()) @@ -2648,10 +2648,10 @@ def test_no_movetext(self): def test_subgame(self): pgn = io.StringIO("1. d4 d5 (1... Nf6 2. c4 (2. Nf3 g6 3. g3))") game = chess.pgn.read_game(pgn) - node = game.variations[0].variations[1] + node = game.next().variations[1] subgame = node.accept_subgame(chess.pgn.GameBuilder()) self.assertEqual(subgame.headers["FEN"], "rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 1 2") - self.assertEqual(subgame.variations[0].move, chess.Move.from_uci("c2c4")) + self.assertEqual(subgame.next().move, chess.Move.from_uci("c2c4")) self.assertEqual(subgame.variations[1].move, chess.Move.from_uci("g1f3")) def test_is_wild(self): From 8546224a705de4ddfed4f602fd7b07a19e1c8e12 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 12:18:25 +0100 Subject: [PATCH 1304/1831] Add chess.ray(a, b) for consistency --- chess/__init__.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 2fd5cb15b..fa312274e 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -393,6 +393,9 @@ def _rays() -> List[List[Bitboard]]: BB_RAYS = _rays() +def ray(a: Square, b: Square) -> Bitboard: + return BB_RAYS[a][b] + def between(a: Square, b: Square) -> Bitboard: bb = BB_RAYS[a][b] & ((BB_ALL << a) ^ (BB_ALL << b)) return bb & (bb - 1) @@ -759,7 +762,7 @@ def pin_mask(self, color: Color, square: Square) -> Bitboard: snipers = rays & sliders & self.occupied_co[not color] for sniper in scan_reversed(snipers): if between(sniper, king) & (self.occupied | square_mask) == square_mask: - return BB_RAYS[king][sniper] + return ray(king, sniper) break @@ -3419,14 +3422,14 @@ def _is_safe(self, king: Square, blockers: Bitboard, move: Move) -> bool: not self._ep_skewered(king, move.from_square)) else: return bool(not blockers & BB_SQUARES[move.from_square] or - BB_RAYS[move.from_square][move.to_square] & BB_SQUARES[king]) + ray(move.from_square, move.to_square) & BB_SQUARES[king]) def _generate_evasions(self, king: Square, checkers: Bitboard, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]: sliders = checkers & (self.bishops | self.rooks | self.queens) attacked = 0 for checker in scan_reversed(sliders): - attacked |= BB_RAYS[king][checker] & ~BB_SQUARES[checker] + attacked |= ray(king, checker) & ~BB_SQUARES[checker] if BB_SQUARES[king] & from_mask: for to_square in scan_reversed(BB_KING_ATTACKS[king] & ~self.occupied_co[self.turn] & ~attacked & to_mask): @@ -4017,7 +4020,7 @@ def ray(cls, a: Square, b: Square) -> SquareSet: . . . . 1 . . . . . . . . 1 . . """ - return cls(BB_RAYS[a][b]) + return cls(ray(a, b)) @classmethod def between(cls, a: Square, b: Square) -> SquareSet: From 165cfd3d181f1e85a00c81936d178d6d95350969 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 13:33:39 +0100 Subject: [PATCH 1305/1831] Introduce chess.pgn.ChildNode --- chess/pgn.py | 145 ++++++++++++++++++++++++++------------------------- test.py | 8 +-- 2 files changed, 79 insertions(+), 74 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 3458e4bff..ae4f9e4e4 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -161,7 +161,6 @@ def __init__(self, node: GameNode, *, is_variation: bool = False, sidelines: boo class GameNode: - parent: Optional[GameNode] """ The parent node or ``None`` if this is the root node of the game. @@ -173,11 +172,8 @@ class GameNode: game. """ - nags: Set[int] - """ - A set of NAGs as integers. NAGs always go behind a move, so the root - node of the game will never have NAGs. - """ + variations: List[ChildNode] + """A list of child nodes.""" comment: str """ @@ -186,31 +182,19 @@ class GameNode: """ starting_comment: str - """ - A comment for the start of a variation. Only nodes that - actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` - checks this) can have a starting comment. The root node can not have - a starting comment. - """ - - variations: List[GameNode] - """A list of child nodes.""" + nags: Set[int] - def __init__(self) -> None: + def __init__(self, *, comment: str = "") -> None: self.parent = None + self.move = None self.variations = [] + self.comment = comment - self.move = None - self.nags = set() self.starting_comment = "" - self.comment = "" + self.nags = set() self.board_cached: Optional[weakref.ref[chess.Board]] = None - @classmethod - def dangling_node(cls) -> GameNode: - return GameNode() - def _board(self) -> chess.Board: assert False, "cannot get board of dangling GameNode" @@ -250,10 +234,6 @@ def board(self) -> chess.Board: return board - def _move(self) -> chess.Move: - assert self.move is not None, "cannot get move of dangling GameNode" - return self.move - def _ply(self) -> int: assert False, "cannot get ply of dangling GameNode" @@ -279,26 +259,6 @@ def turn(self) -> Color: """ return self.ply() % 2 == 0 - def san(self) -> str: - """ - Gets the standard algebraic notation of the move leading to this node. - See :func:`chess.Board.san()`. - - Do not call this on the root node. - """ - assert self.parent is not None and self.move is not None, "cannot get san of dangling GameNode" - return self.parent.board().san(self.move) - - def uci(self, *, chess960: Optional[bool] = None) -> str: - """ - Gets the UCI notation of the move leading to this node. - See :func:`chess.Board.uci()`. - - Do not call this on the root node. - """ - assert self.parent is not None and self.move is not None, "cannot get uci of dangling GameNode" - return self.parent.board().uci(self.move, chess960=chess960) - def root(self) -> GameNode: node = self while node.parent: @@ -362,7 +322,7 @@ def is_main_variation(self) -> bool: return not self.parent.variations or self.parent.variations[0] == self - def __getitem__(self, move: Union[int, chess.Move, GameNode]) -> GameNode: + def __getitem__(self, move: Union[int, chess.Move, GameNode]) -> ChildNode: try: return self.variations[move] # type: ignore except TypeError: @@ -380,7 +340,7 @@ def __contains__(self, move: Union[int, chess.Move, GameNode]) -> bool: else: return True - def variation(self, move: Union[int, chess.Move, GameNode]) -> GameNode: + def variation(self, move: Union[int, chess.Move, GameNode]) -> ChildNode: """ Gets a child node by either the move or the variation index. """ @@ -414,42 +374,34 @@ def remove_variation(self, move: Union[int, chess.Move, GameNode]) -> None: """Removes a variation.""" self.variations.remove(self.variation(move)) - def add_variation(self, move: chess.Move, *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> GameNode: + def add_variation(self, move: chess.Move, *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> ChildNode: """Creates a child node with the given attributes.""" - node = type(self).dangling_node() - node.move = move - node.nags = set(nags) - node.comment = comment - node.starting_comment = starting_comment - - node.parent = self - self.variations.append(node) - return node + return ChildNode(self, move, comment=comment, starting_comment=starting_comment, nags=nags) - def add_main_variation(self, move: chess.Move, *, comment: str = "") -> GameNode: + def add_main_variation(self, move: chess.Move, *, comment: str = "", nags: Iterable[int] = []) -> ChildNode: """ Creates a child node with the given attributes and promotes it to the main variation. """ - node = self.add_variation(move, comment=comment) + node = self.add_variation(move, comment=comment, nags=nags) self.variations.remove(node) self.variations.insert(0, node) return node - def next(self) -> Optional[GameNode]: + def next(self) -> Optional[ChildNode]: """ Returns the first node of the mainline after this node, or ``None`` if this node does not have any children. """ return self.variations[0] if self.variations else None - def mainline(self) -> Mainline[GameNode]: + def mainline(self) -> Mainline[ChildNode]: """Returns an iterable over the mainline starting after this node.""" return Mainline(self, lambda node: node) def mainline_moves(self) -> Mainline[chess.Move]: """Returns an iterable over the main moves after this node.""" - return Mainline(self, lambda node: node._move()) + return Mainline(self, lambda node: node.move) def add_line(self, moves: Iterable[chess.Move], *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> GameNode: """ @@ -687,9 +639,60 @@ def __str__(self) -> str: return self.accept(StringExporter(columns=None)) def __repr__(self) -> str: - if self.parent is None: - return f"<{type(self).__name__} at {id(self):#x} (dangling: {self.move})>" + return f"<{type(self).__name__} at {id(self):#x} (dangling)>" + + +class ChildNode(GameNode): + parent: GameNode + move: chess.Move + + nags: Set[int] + """ + A set of NAGs as integers. NAGs always go behind a move, so the root + node of the game will never have NAGs. + """ + + starting_comment: str + """ + A comment for the start of a variation. Only nodes that + actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` + checks this) can have a starting comment. The root node can not have + a starting comment. + """ + + def __init__(self, parent: GameNode, move: chess.Move, *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> None: + super().__init__(comment=comment) + self.parent = parent + self.move = move + self.parent.variations.append(self) + + self.nags.update(nags) + self.starting_comment = starting_comment + def san(self) -> str: + """ + Gets the standard algebraic notation of the move leading to this node. + See :func:`chess.Board.san()`. + + Do not call this on the root node. + """ + assert self.parent is not None and self.move is not None, "cannot get san of dangling GameNode" + return self.parent.board().san(self.move) + + def uci(self, *, chess960: Optional[bool] = None) -> str: + """ + Gets the UCI notation of the move leading to this node. + See :func:`chess.Board.uci()`. + + Do not call this on the root node. + """ + assert self.parent is not None and self.move is not None, "cannot get uci of dangling GameNode" + return self.parent.board().uci(self.move, chess960=chess960) + + def end(self) -> ChildNode: + return typing.cast(ChildNode, super().end()) + + def __repr__(self) -> str: try: parent_board = self.parent.board() except ValueError: @@ -927,7 +930,7 @@ def builder(cls: Type[HeadersT]) -> HeadersBuilder[HeadersT]: MainlineMapT = TypeVar("MainlineMapT") class Mainline(Generic[MainlineMapT]): - def __init__(self, start: GameNode, f: Callable[[GameNode], MainlineMapT]) -> None: + def __init__(self, start: GameNode, f: Callable[[ChildNode], MainlineMapT]) -> None: self.start = start self.f = f @@ -949,7 +952,7 @@ def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: while node.variations: node = node.variations[0] node._accept_node(board, visitor) - board.push(node._move()) + board.push(node.move) return visitor.result() def __str__(self) -> str: @@ -960,7 +963,7 @@ def __repr__(self) -> str: class ReverseMainline(Generic[MainlineMapT]): - def __init__(self, stop: GameNode, f: Callable[[GameNode], MainlineMapT]) -> None: + def __init__(self, stop: GameNode, f: Callable[[ChildNode], MainlineMapT]) -> None: self.stop = stop self.f = f @@ -977,7 +980,7 @@ def __len__(self) -> int: def __iter__(self) -> Iterator[MainlineMapT]: node = self.end while node.parent and node != self.stop: - yield self.f(node) + yield self.f(typing.cast(ChildNode, node)) node = node.parent def __reversed__(self) -> Mainline[MainlineMapT]: @@ -986,7 +989,7 @@ def __reversed__(self) -> Mainline[MainlineMapT]: def __repr__(self) -> str: return "".format( id(self), - " ".join(ReverseMainline(self.stop, lambda node: node._move().uci()))) + " ".join(ReverseMainline(self.stop, lambda node: node.move.uci()))) class BaseVisitor(abc.ABC, Generic[ResultT]): diff --git a/test.py b/test.py index 864bb6063..fc22dfab8 100755 --- a/test.py +++ b/test.py @@ -2661,9 +2661,11 @@ def test_is_wild(self): def test_my_game_node(self): class MyGameNode(chess.pgn.GameNode): - @classmethod - def dangling_node(cls): - return MyGameNode() + def add_variation(self, move, *, comment="", starting_comment="", nags=[]): + return MyChildNode(self, move, comment=comment, starting_comment=starting_comment, nags=nags) + + class MyChildNode(chess.pgn.ChildNode, MyGameNode): + pass class MyGame(chess.pgn.Game, MyGameNode): pass From 007127635861b659e6d7692a85cae6260d803651 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 15:44:18 +0100 Subject: [PATCH 1306/1831] Use types to eliminate dangling game nodes --- chess/pgn.py | 190 +++++++++++++++++++++++---------------------------- 1 file changed, 86 insertions(+), 104 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index ae4f9e4e4..7b0bdf3fd 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -151,8 +151,7 @@ class SkipType(enum.Enum): class _AcceptFrame: - def __init__(self, node: GameNode, *, is_variation: bool = False, sidelines: bool = True): - assert node.parent is not None, "cannot visit dangling GameNode" + def __init__(self, node: ChildNode, *, is_variation: bool = False, sidelines: bool = True): self.state = "pre" self.node = node self.is_variation = is_variation @@ -160,7 +159,7 @@ def __init__(self, node: GameNode, *, is_variation: bool = False, sidelines: boo self.in_variation = False -class GameNode: +class GameNode(abc.ABC): parent: Optional[GameNode] """ The parent node or ``None`` if this is the root node of the game. @@ -190,14 +189,12 @@ def __init__(self, *, comment: str = "") -> None: self.variations = [] self.comment = comment + # Deprecated: These should be properties of ChildNode, but need to + # remain here for backwards compatibility. self.starting_comment = "" self.nags = set() - self.board_cached: Optional[weakref.ref[chess.Board]] = None - - def _board(self) -> chess.Board: - assert False, "cannot get board of dangling GameNode" - + @abc.abstractmethod def board(self) -> chess.Board: """ Gets a board with the position of the node. @@ -207,36 +204,8 @@ def board(self) -> chess.Board: It's a copy, so modifying the board will not alter the game. """ - if self.board_cached is not None: - board_cached = self.board_cached() - if board_cached is not None: - return board_cached.copy() - - stack = [] - node = self - while True: - if node.parent is None or node.move is None: - board = node._board() - break - elif node.board_cached is not None: - board_cached = node.board_cached() - if board_cached is not None: - board = board_cached.copy() - break - stack.append(node.move) - node = node.parent - - while stack: - board.push(stack.pop()) - - if self.parent is not None: - self.board_cached = weakref.ref(board) - - return board - - def _ply(self) -> int: - assert False, "cannot get ply of dangling GameNode" + @abc.abstractmethod def ply(self) -> int: """ Returns the number of half-moves up to this node, as indicated by @@ -246,12 +215,6 @@ def ply(self) -> int: Usually this is equal to the number of parent nodes, but it may be more if the game was started from a custom position. """ - ply = 0 - node = self - while node.parent is not None: - ply += 1 - node = node.parent - return node._ply() + ply def turn(self) -> Color: """ @@ -384,8 +347,7 @@ def add_main_variation(self, move: chess.Move, *, comment: str = "", nags: Itera main variation. """ node = self.add_variation(move, comment=comment, nags=nags) - self.variations.remove(node) - self.variations.insert(0, node) + self.variations.insert(0, self.variations.pop()) return node def next(self) -> Optional[ChildNode]: @@ -543,66 +505,12 @@ def set_clock(self, seconds: Optional[float]) -> None: self.comment += " " self.comment += clk - def _accept_node(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT]) -> None: - assert self.move is not None, "cannot visit dangling GameNode" - - if self.starting_comment: - visitor.visit_comment(self.starting_comment) - - visitor.visit_move(parent_board, self.move) - - parent_board.push(self.move) - visitor.visit_board(parent_board) - parent_board.pop() - - for nag in sorted(self.nags): - visitor.visit_nag(nag) - - if self.comment: - visitor.visit_comment(self.comment) - - def _accept(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT], *, sidelines: bool = True) -> None: - stack = [_AcceptFrame(self, sidelines=sidelines)] - - while stack: - top = stack[-1] - - if top.in_variation: - top.in_variation = False - visitor.end_variation() - - if top.state == "pre": - top.node._accept_node(parent_board, visitor) - top.state = "variations" - elif top.state == "variations": - try: - variation = next(top.variations) - except StopIteration: - if top.node.variations: - assert top.node.move is not None, "root node cannot be a variation" - parent_board.push(top.node.move) - stack.append(_AcceptFrame(top.node.variations[0], sidelines=True)) - top.state = "post" - else: - top.state = "end" - else: - if visitor.begin_variation() is not SKIP: - stack.append(_AcceptFrame(variation, sidelines=False, is_variation=True)) - top.in_variation = True - elif top.state == "post": - parent_board.pop() - top.state = "end" - else: - stack.pop() - + @abc.abstractmethod def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: """ Traverses game nodes in PGN order using the given *visitor*. Starts with the move leading to this node. Returns the *visitor* result. """ - assert self.parent is not None, "cannot visit dangling GameNode" - self._accept(self.parent.board(), visitor, sidelines=False) - return visitor.result() def accept_subgame(self, visitor: BaseVisitor[ResultT]) -> ResultT: """ @@ -669,6 +577,29 @@ def __init__(self, parent: GameNode, move: chess.Move, *, comment: str = "", sta self.nags.update(nags) self.starting_comment = starting_comment + def board(self) -> chess.Board: + stack: List[chess.Move] = [] + node: GameNode = self + + while node.move is not None and node.parent is not None: + stack.append(node.move) + node = node.parent + + board = node.game().board() + + while stack: + board.push(stack.pop()) + + return board + + def ply(self) -> int: + ply = 0 + node: GameNode = self + while node.parent is not None: + ply += 1 + node = node.parent + return node.game().ply() + ply + def san(self) -> str: """ Gets the standard algebraic notation of the move leading to this node. @@ -676,7 +607,6 @@ def san(self) -> str: Do not call this on the root node. """ - assert self.parent is not None and self.move is not None, "cannot get san of dangling GameNode" return self.parent.board().san(self.move) def uci(self, *, chess960: Optional[bool] = None) -> str: @@ -686,12 +616,64 @@ def uci(self, *, chess960: Optional[bool] = None) -> str: Do not call this on the root node. """ - assert self.parent is not None and self.move is not None, "cannot get uci of dangling GameNode" return self.parent.board().uci(self.move, chess960=chess960) def end(self) -> ChildNode: return typing.cast(ChildNode, super().end()) + def _accept_node(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT]) -> None: + if self.starting_comment: + visitor.visit_comment(self.starting_comment) + + visitor.visit_move(parent_board, self.move) + + parent_board.push(self.move) + visitor.visit_board(parent_board) + parent_board.pop() + + for nag in sorted(self.nags): + visitor.visit_nag(nag) + + if self.comment: + visitor.visit_comment(self.comment) + + def _accept(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT], *, sidelines: bool = True) -> None: + stack = [_AcceptFrame(self, sidelines=sidelines)] + + while stack: + top = stack[-1] + + if top.in_variation: + top.in_variation = False + visitor.end_variation() + + if top.state == "pre": + top.node._accept_node(parent_board, visitor) + top.state = "variations" + elif top.state == "variations": + try: + variation = next(top.variations) + except StopIteration: + if top.node.variations: + parent_board.push(top.node.move) + stack.append(_AcceptFrame(top.node.variations[0], sidelines=True)) + top.state = "post" + else: + top.state = "end" + else: + if visitor.begin_variation() is not SKIP: + stack.append(_AcceptFrame(variation, sidelines=False, is_variation=True)) + top.in_variation = True + elif top.state == "post": + parent_board.pop() + top.state = "end" + else: + stack.pop() + + def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: + self._accept(self.parent.board(), visitor, sidelines=False) + return visitor.result() + def __repr__(self) -> str: try: parent_board = self.parent.board() @@ -738,10 +720,10 @@ def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str self.headers = Headers(headers) self.errors = [] - def _board(self) -> chess.Board: + def board(self) -> chess.Board: return self.headers.board() - def _ply(self) -> int: + def ply(self) -> int: # Optimization: Parse FEN only for custom starting positions. return self.board().ply() if "FEN" in self.headers else 0 From 7d27164028bfa3d76ac44be106fba78ef5bc40a8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 16:11:18 +0100 Subject: [PATCH 1307/1831] Update GameModel documentation --- chess/pgn.py | 28 +++++++++++++++++----------- docs/pgn.rst | 18 +++++++++++------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 7b0bdf3fd..76a56921e 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -161,9 +161,7 @@ def __init__(self, node: ChildNode, *, is_variation: bool = False, sidelines: bo class GameNode(abc.ABC): parent: Optional[GameNode] - """ - The parent node or ``None`` if this is the root node of the game. - """ + """The parent node or ``None`` if this is the root node of the game.""" move: Optional[chess.Move] """ @@ -551,15 +549,17 @@ def __repr__(self) -> str: class ChildNode(GameNode): - parent: GameNode - move: chess.Move - - nags: Set[int] """ - A set of NAGs as integers. NAGs always go behind a move, so the root - node of the game will never have NAGs. + A child node of a game, with the move leading to it. + Extends :class:`~chess.pgn.GameNode`. """ + parent: GameNode + """The parent node.""" + + move: chess.Move + """The move leading to this node.""" + starting_comment: str """ A comment for the start of a variation. Only nodes that @@ -568,6 +568,12 @@ class ChildNode(GameNode): a starting comment. """ + nags: Set[int] + """ + A set of NAGs as integers. NAGs always go behind a move, so the root + node of the game will never have NAGs. + """ + def __init__(self, parent: GameNode, move: chess.Move, *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> None: super().__init__(comment=comment) self.parent = parent @@ -619,6 +625,7 @@ def uci(self, *, chess960: Optional[bool] = None) -> str: return self.parent.board().uci(self.move, chess960=chess960) def end(self) -> ChildNode: + """Follows the main variation to the end and returns the last node.""" return typing.cast(ChildNode, super().end()) def _accept_node(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT]) -> None: @@ -693,8 +700,7 @@ def __repr__(self) -> str: class Game(GameNode): """ The root node of a game with extra information such as headers and the - starting position. Also has all the other properties and methods of - :class:`~chess.pgn.GameNode`. + starting position. Extends :class:`~chess.pgn.GameNode`. """ headers: Headers diff --git a/docs/pgn.rst b/docs/pgn.rst index a1307795b..12b09ac62 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -42,17 +42,21 @@ Use the :class:`~chess.pgn.StringExporter()` or Game model ---------- -Games are represented as a tree of moves. Each :class:`~chess.pgn.GameNode` can have extra -information, such as comments. The root node of a game -(:class:`~chess.pgn.Game` extends the :class:`~chess.pgn.GameNode`) also -holds general information, such as game headers. - -.. autoclass:: chess.pgn.Game - :members: +Games are represented as a tree of moves. Conceptually each node represents a +position of the game. The tree consists of one root node +(:class:`~chess.pgn.Game`, also holding game headers) and many child +nodes (:class:`~chess.pgn.ChildNode`). +Both extend :class:`~chess.pgn.GameNode`. .. autoclass:: chess.pgn.GameNode :members: +.. autoclass:: chess.pgn.Game + :members: headers, errors, setup, accept + +.. autoclass:: chess.pgn.ChildNode + :members: parent, move, starting_comment, nags, san, uci, end + Visitors -------- From e9103b9dbec32c2c7dac64770925d7176eaddbee Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 16:26:19 +0100 Subject: [PATCH 1308/1831] Update changelog --- CHANGELOG.rst | 36 +++++++++++++++++++++++++++++------- chess/pgn.py | 6 ++---- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d18075674..426ea5c64 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,26 @@ Changelog for python-chess ========================== +Upcoming in v1.3.0 +------------------ + +Changes: + +* Introduced ``chess.pgn.ChildNode``, a subclass of ``chess.pgn.GameNode`` + for all nodes other than the root node, and converted ``chess.pgn.GameNode`` + to an abstract base class. This improves ergonomics in typed code. + + The change is backwards compatible if using only documented features. + However, a notable undocumented feature is the ability to create dangling + nodes. This is no longer possible. If you have been using this for + subclassing, override ``GameNode.add_variation()`` instead of + ``GameNode.danling_node()``. It is now the only method that creates child + nodes. + +New features: + +* Added ``GameNode.next()``. + New in v1.2.2 ------------- @@ -12,14 +32,16 @@ Bugfixes: New in v1.2.1 ------------- -The primary location for the published package is now -https://pypi.org/project/chess/. Thanks to -`Kristian Glass `_ for transferring the -namespace. +Changes: + +* The primary location for the published package is now + https://pypi.org/project/chess/. Thanks to + `Kristian Glass `_ for transferring the + namespace. -The old https://pypi.org/project/python-chess/ will remain an alias that -installs the package from the new location as a dependency (as recommended by -`PEP423 `_). + The old https://pypi.org/project/python-chess/ will remain an alias that + installs the package from the new location as a dependency (as recommended by + `PEP423 `_). New in v1.2.0 ------------- diff --git a/chess/pgn.py b/chess/pgn.py index 76a56921e..01b63eb9b 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -337,6 +337,7 @@ def remove_variation(self, move: Union[int, chess.Move, GameNode]) -> None: def add_variation(self, move: chess.Move, *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> ChildNode: """Creates a child node with the given attributes.""" + # Instanciate ChildNode only in this method. return ChildNode(self, move, comment=comment, starting_comment=starting_comment, nags=nags) def add_main_variation(self, move: chess.Move, *, comment: str = "", nags: Iterable[int] = []) -> ChildNode: @@ -544,9 +545,6 @@ def accept_subgame(self, visitor: BaseVisitor[ResultT]) -> ResultT: def __str__(self) -> str: return self.accept(StringExporter(columns=None)) - def __repr__(self) -> str: - return f"<{type(self).__name__} at {id(self):#x} (dangling)>" - class ChildNode(GameNode): """ @@ -692,7 +690,7 @@ def __repr__(self) -> str: id(self), parent_board.fullmove_number, "." if parent_board.turn == chess.WHITE else "...", - self.san()) + parent_board.san(self.move)) GameT = TypeVar("GameT", bound="Game") From 81575406805818cfc9ba70256d90b80e1a9330d5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 16:36:12 +0100 Subject: [PATCH 1309/1831] Mention change to GameNode.board() caching --- CHANGELOG.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 426ea5c64..a335aeed8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,12 +14,16 @@ Changes: However, a notable undocumented feature is the ability to create dangling nodes. This is no longer possible. If you have been using this for subclassing, override ``GameNode.add_variation()`` instead of - ``GameNode.danling_node()``. It is now the only method that creates child + ``GameNode.dangling_node()``. It is now the only method that creates child nodes. +Bugfixes: + +* Removed broken ``weakref`` based caching in ``chess.pgn.GameNode.board()``. + New features: -* Added ``GameNode.next()``. +* Added ``chess.pgn.GameNode.next()``. New in v1.2.2 ------------- From 69ce173743808bf528dab1d582c68b703b29db5e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 16:46:19 +0100 Subject: [PATCH 1310/1831] Prepare 1.3.0 --- CHANGELOG.rst | 4 ++-- chess/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a335aeed8..24070369d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,8 @@ Changelog for python-chess ========================== -Upcoming in v1.3.0 ------------------- +New in v1.3.0 +------------- Changes: diff --git a/chess/__init__.py b/chess/__init__.py index fa312274e..526494217 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.2.2" +__version__ = "1.3.0" import collections import copy From 18adf53b6716090420ac2160f9332aa23963c1a3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 20:48:25 +0100 Subject: [PATCH 1311/1831] Start porting CI to Github Actions --- .github/workflows/test.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..f153bf13b --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,17 @@ +name: Test + +on: [push, pull_request] + +jobs: + test: + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + python-version: [3.7, 3.8, 3.9] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - run: python test.py -v From 861213f68bd4143186102a671e3f0f604a5482f8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 20:58:18 +0100 Subject: [PATCH 1312/1831] Try to run perft tests on GitHub Actions --- .github/workflows/test.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f153bf13b..659316848 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,4 +14,20 @@ jobs: - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + - run: pip install -e . - run: python test.py -v + perft: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.9 + - run: pip install -e . + - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 + - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft + - run: python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft + - run: python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft + - run: python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft + - run: python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft + - run: python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft From d1b22313d4b617f5149673402561630f621b2fcc Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:03:29 +0100 Subject: [PATCH 1313/1831] Try to run mypy on Github Actions --- .github/workflows/test.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 659316848..acdb995e2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,3 +31,17 @@ jobs: - run: python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft - run: python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft - run: python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft + mypy: + strategy: + matrix: + python-version: [3.8, 3.9] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - run: pip install -e . + - run: pip install mypy + - run: python -m mypy --strict chess + - run: python -m mypy --strict examples/**/*.py From 01b7f035e1b4f6f1fa1014544ee72070be964c83 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:11:03 +0100 Subject: [PATCH 1314/1831] Check README.rst on GitHub Actions --- .github/workflows/test.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index acdb995e2..3b4a48d0c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,3 +45,17 @@ jobs: - run: pip install mypy - run: python -m mypy --strict chess - run: python -m mypy --strict examples/**/*.py + readme: + strategy: + matrix: + python-version: [3.7, 3.8, 3.9] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - run: sudo apt-get update && sudo apt-get install -y docutils-common + - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null + - run: pip install -e . + - run: python -m doctest README.rst From 62ba2c1f555c9ae2d2f5a3e15e1d2f912f828cc4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:15:52 +0100 Subject: [PATCH 1315/1831] Update status badges --- README.rst | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/README.rst b/README.rst index 5319a9d86..62720b727 100644 --- a/README.rst +++ b/README.rst @@ -1,29 +1,21 @@ python-chess: a pure Python chess library ========================================= -.. image:: https://travis-ci.org/niklasf/python-chess.svg?branch=master - :target: https://travis-ci.org/niklasf/python-chess - :alt: build - -.. image:: https://ci.appveyor.com/api/projects/status/y9k3hdbm0f0nbum9/branch/master?svg=true - :target: https://ci.appveyor.com/project/niklasf/python-chess - :alt: appveyor build - -.. image:: https://coveralls.io/repos/github/niklasf/python-chess/badge.svg?branch=master - :target: https://coveralls.io/github/niklasf/python-chess?branch=master - :alt: coverage +.. image:: https://github.com/niklasf/python-chess/workflows/Test/badge.svg + :target: https://github.com/niklasf/python-chess/actions + :alt: Test status .. image:: https://badge.fury.io/py/chess.svg :target: https://pypi.python.org/pypi/chess - :alt: pypi package + :alt: PyPI package .. image:: https://readthedocs.org/projects/python-chess/badge/?version=latest :target: https://python-chess.readthedocs.io/en/latest/ - :alt: docs + :alt: Docs .. image:: https://badges.gitter.im/python-chess/community.svg :target: https://gitter.im/python-chess/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge - :alt: chat on gitter + :alt: Chat on Gitter Introduction ------------ From e054c688036f8f68cb6c129c1609c38d87da764b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:28:02 +0100 Subject: [PATCH 1316/1831] Try to set up test dependencies on Github Actions --- .github/workflows/setup-ubuntu-latest.sh | 33 +++++++++++++++++++++++ .github/workflows/setup-windows-latest.sh | 0 .github/workflows/test.yml | 2 ++ 3 files changed, 35 insertions(+) create mode 100755 .github/workflows/setup-ubuntu-latest.sh create mode 100755 .github/workflows/setup-windows-latest.sh diff --git a/.github/workflows/setup-ubuntu-latest.sh b/.github/workflows/setup-ubuntu-latest.sh new file mode 100755 index 000000000..7383823ec --- /dev/null +++ b/.github/workflows/setup-ubuntu-latest.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# Stockfish +wget https://stockfish.s3.amazonaws.com/stockfish-11-linux.zip +unzip stockfish-11-linux.zip +mkdir -p bin +cp stockfish-11-linux/Linux/stockfish_20011801_x64_bmi2 bin/stockfish +chmod +x bin/stockfish +echo "`pwd`/bin" >> $GITHUB_PATH + +# Crafty +git clone https://github.com/lazydroid/crafty-chess +cd crafty-chess +make unix-gcc +pwd >> $GITHUB_PATH +cd .. + +# Gaviota libgtb +git clone https://github.com/michiguel/Gaviota-Tablebases.git --depth 1 +cd Gaviota-Tablebases +make +echo "::set-env LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}" +cd .. + +# Gaviota tablebases +#cd data/gaviota +#travis_wait wget --no-verbose --no-check-certificate --no-clobber --input-file TEST-SOURCE.txt +#cd ../.. + +# Suicide syzygy bases +#cd data/syzygy/suicide +#travis_wait wget --no-verbose --no-check-certificate --no-clobber --input-file TEST-SOURCE.txt +#cd ../../.. diff --git a/.github/workflows/setup-windows-latest.sh b/.github/workflows/setup-windows-latest.sh new file mode 100755 index 000000000..e69de29bb diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3b4a48d0c..166f62e43 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,6 +14,7 @@ jobs: - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + - run: .github/workflows/setup-${{ matrix.os }}.sh - run: pip install -e . - run: python test.py -v perft: @@ -58,4 +59,5 @@ jobs: - run: sudo apt-get update && sudo apt-get install -y docutils-common - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null - run: pip install -e . + - run: .github/workflows/setup-ubuntu-latest.sh - run: python -m doctest README.rst From 4fff76bd86746d2c24046e3bc6c09d6b8cba0689 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:34:17 +0100 Subject: [PATCH 1317/1831] Final attempt to setup libgtb --- .github/workflows/setup-ubuntu-latest.sh | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/.github/workflows/setup-ubuntu-latest.sh b/.github/workflows/setup-ubuntu-latest.sh index 7383823ec..de1d567fd 100755 --- a/.github/workflows/setup-ubuntu-latest.sh +++ b/.github/workflows/setup-ubuntu-latest.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh -e # Stockfish wget https://stockfish.s3.amazonaws.com/stockfish-11-linux.zip @@ -9,7 +9,7 @@ chmod +x bin/stockfish echo "`pwd`/bin" >> $GITHUB_PATH # Crafty -git clone https://github.com/lazydroid/crafty-chess +git clone https://github.com/lazydroid/crafty-chess --depth 1 cd crafty-chess make unix-gcc pwd >> $GITHUB_PATH @@ -19,15 +19,5 @@ cd .. git clone https://github.com/michiguel/Gaviota-Tablebases.git --depth 1 cd Gaviota-Tablebases make -echo "::set-env LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}" +echo "LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}" >> $GITHUB_ENV cd .. - -# Gaviota tablebases -#cd data/gaviota -#travis_wait wget --no-verbose --no-check-certificate --no-clobber --input-file TEST-SOURCE.txt -#cd ../.. - -# Suicide syzygy bases -#cd data/syzygy/suicide -#travis_wait wget --no-verbose --no-check-certificate --no-clobber --input-file TEST-SOURCE.txt -#cd ../../.. From 542605ae77191be6b1249a7b43e5152e139ba9d8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:37:10 +0100 Subject: [PATCH 1318/1831] Try to setup Stockfish for Windows in CI --- .github/workflows/setup-windows-latest.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/setup-windows-latest.sh b/.github/workflows/setup-windows-latest.sh index e69de29bb..22b7facb6 100755 --- a/.github/workflows/setup-windows-latest.sh +++ b/.github/workflows/setup-windows-latest.sh @@ -0,0 +1,6 @@ +#!/bin/sh -e + +wget https://stockfishchess.org/files/stockfish-11-win.zip +unzip stockfish-11-win.zip +mv stockfish-11-win/Windows/stockfish_20011801_x64_bmi2.exe stockfish.exe +pwd >> $GITHUB_PATH From 79c5ff77974787268feb1cf61232c3796579e29f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:38:03 +0100 Subject: [PATCH 1319/1831] Multi-threaded perft in CI --- .github/workflows/test.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 166f62e43..7328d4292 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,13 +25,13 @@ jobs: with: python-version: 3.9 - run: pip install -e . - - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft - - run: python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft - - run: python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft - - run: python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft - - run: python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft - - run: python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft + - run: python examples/perft/perft.py -t 2 examples/perft/random.perft --max-nodes 10000 + - run: python examples/perft/perft.py -t 2 examples/perft/tricky.perft + - run: python examples/perft/perft.py -t 2 --variant giveaway examples/perft/giveaway.perft + - run: python examples/perft/perft.py -t 2 --variant atomic examples/perft/atomic.perft + - run: python examples/perft/perft.py -t 2 --variant racingkings examples/perft/racingkings.perft + - run: python examples/perft/perft.py -t 2 --variant horde examples/perft/horde.perft + - run: python examples/perft/perft.py -t 2 --variant crazyhouse examples/perft/crazyhouse.perft mypy: strategy: matrix: From 52c7e1bbd9de386b2d684e6bdca8cf5a19a733cd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:41:19 +0100 Subject: [PATCH 1320/1831] Revert "Multi-threaded perft in CI" This reverts commit 79c5ff77974787268feb1cf61232c3796579e29f. --- .github/workflows/test.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7328d4292..166f62e43 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,13 +25,13 @@ jobs: with: python-version: 3.9 - run: pip install -e . - - run: python examples/perft/perft.py -t 2 examples/perft/random.perft --max-nodes 10000 - - run: python examples/perft/perft.py -t 2 examples/perft/tricky.perft - - run: python examples/perft/perft.py -t 2 --variant giveaway examples/perft/giveaway.perft - - run: python examples/perft/perft.py -t 2 --variant atomic examples/perft/atomic.perft - - run: python examples/perft/perft.py -t 2 --variant racingkings examples/perft/racingkings.perft - - run: python examples/perft/perft.py -t 2 --variant horde examples/perft/horde.perft - - run: python examples/perft/perft.py -t 2 --variant crazyhouse examples/perft/crazyhouse.perft + - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 + - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft + - run: python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft + - run: python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft + - run: python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft + - run: python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft + - run: python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft mypy: strategy: matrix: From 956166e06356ea7a5e9d5338a3247b9178b2858d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 21:43:10 +0100 Subject: [PATCH 1321/1831] Try to fix setup-windows-latest.sh --- .github/workflows/setup-windows-latest.sh | 10 ++++++++-- .github/workflows/test.yml | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/setup-windows-latest.sh b/.github/workflows/setup-windows-latest.sh index 22b7facb6..3ae917a5c 100755 --- a/.github/workflows/setup-windows-latest.sh +++ b/.github/workflows/setup-windows-latest.sh @@ -1,6 +1,12 @@ #!/bin/sh -e +echo Download ... +choco install wget wget https://stockfishchess.org/files/stockfish-11-win.zip -unzip stockfish-11-win.zip -mv stockfish-11-win/Windows/stockfish_20011801_x64_bmi2.exe stockfish.exe + +echo Unzip .. +7z e stockfish-11-win.zip stockfish-11-win/Windows/*.exe + +echo Setup path ... +mv stockfish_20011801_x64_bmi2.exe stockfish.exe pwd >> $GITHUB_PATH diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 166f62e43..ad8e518b0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - run: .github/workflows/setup-${{ matrix.os }}.sh + shell: bash - run: pip install -e . - run: python test.py -v perft: From 12c9a01f3f522e68b6e107b5e5c003f81edff368 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 6 Nov 2020 22:08:23 +0100 Subject: [PATCH 1322/1831] No longer need Travis and AppVeyor --- .travis.yml | 93 ---------------------------------------------------- appveyor.yml | 16 --------- 2 files changed, 109 deletions(-) delete mode 100644 .travis.yml delete mode 100644 appveyor.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2e4ae2233..000000000 --- a/.travis.yml +++ /dev/null @@ -1,93 +0,0 @@ -dist: xenial -language: python -sudo: false -matrix: - include: - - python: "3.7" - - python: "3.8" - env: - - RUN_MYPY=1 - - python: "3.9-dev" - env: - - RUN_MYPY=1 - - RUN_PERFT=1 -cache: - directories: - - data/gaviota - - data/syzygy/suicide -before_cache: - - rm -f data/gaviota/travis_wait_*.log || true - - rm -f data/syzygy/suicide/travis_wait_*.log || true -before_install: - - | # Stockfish - wget https://stockfish.s3.amazonaws.com/stockfish-11-linux.zip - unzip stockfish-11-linux.zip - mkdir -p bin - cp stockfish-11-linux/Linux/stockfish_20011801_x64_bmi2 bin/stockfish - chmod +x bin/stockfish - export PATH="`pwd`/bin:${PATH}" - which stockfish || (echo $PATH && false) - - | # Crafty - git clone https://github.com/lazydroid/crafty-chess - cd crafty-chess - make unix-gcc - export PATH="`pwd`:${PATH}" - cd .. - - | # Gaviota libgtb - git clone https://github.com/michiguel/Gaviota-Tablebases.git --depth 1 - cd Gaviota-Tablebases - make - export LD_LIBRARY_PATH="`pwd`:${LD_LIBRARY_PATH}" - cd .. - - | # Gaviota tablebases - cd data/gaviota - travis_wait wget --no-verbose --no-check-certificate --no-clobber --input-file TEST-SOURCE.txt - cd ../.. - - | # Suicide syzygy bases - cd data/syzygy/suicide - travis_wait wget --no-verbose --no-check-certificate --no-clobber --input-file TEST-SOURCE.txt - cd ../../.. -install: - - pip install --upgrade pip wheel - - pip install --upgrade setuptools - - pip install --upgrade coveralls - - if [[ $RUN_MYPY -eq 1 ]]; then pip install --upgrade mypy; fi - - pip install -e . -script: - - # Unit tests - - coverage erase - - coverage run --source chess test.py -vv SquareTestCase - - coverage run --source chess --append test.py -vv MoveTestCase - - coverage run --source chess --append test.py -vv PieceTestCase - - coverage run --source chess --append test.py -vv BoardTestCase - - coverage run --source chess --append test.py -vv LegalMoveGeneratorTestCase - - coverage run --source chess --append test.py -vv BaseBoardTestCase - - coverage run --source chess --append test.py -vv SquareSetTestCase - - coverage run --source chess --append test.py -vv PolyglotTestCase - - coverage run --source chess --append test.py -vv PgnTestCase - - coverage run --source chess --append test.py -vv SyzygyTestCase - - coverage run --source chess --append test.py -vv NativeGaviotaTestCase - - coverage run --source chess --append test.py -vv GaviotaTestCase - - coverage run --source chess --append test.py -vv SvgTestCase - - coverage run --source chess --append test.py -vv SuicideTestCase - - coverage run --source chess --append test.py -vv AtomicTestCase - - coverage run --source chess --append test.py -vv RacingKingsTestCase - - coverage run --source chess --append test.py -vv HordeTestCase - - coverage run --source chess --append test.py -vv ThreeCheckTestCase - - coverage run --source chess --append test.py -vv CrazyhouseTestCase - - coverage run --source chess --append test.py -vv GiveawayTestCase - - coverage run --source chess --append test.py -vv EngineTestCase - - coverage run --source chess --append -m doctest README.rst --verbose - - echo Unit tests complete - - coveralls || [[ $? -eq 139 ]] - - # Typing - - if [[ $RUN_MYPY -eq 1 ]]; then python -m mypy --strict chess; fi - - if [[ $RUN_MYPY -eq 1 ]]; then python -m mypy --strict examples/**/*.py; fi - - # Perft tests - - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000; fi - - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 examples/perft/tricky.perft; fi - - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft; fi - - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft; fi - - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft; fi - - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft; fi - - if [[ $RUN_PERFT -eq 1 ]]; then python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft; fi diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 02400dc17..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,16 +0,0 @@ -environment: - matrix: - - PYTHON: "C:\\Python37" - - PYTHON: "C:\\Python38" - -build: off - -install: - # Stockfish - - ps: Start-FileDownload "https://stockfishchess.org/files/stockfish-11-win.zip" - - 7z e stockfish-11-win.zip stockfish-11-win/Windows/*.exe - - ren stockfish_20011801_x64_bmi2.exe stockfish.exe - - set PATH=%cd%;%PATH% - -test_script: - - "%PYTHON%\\python.exe test.py -vv" From c8914c2200fe9a6a886b51fc07cf5607eccad9ee Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Nov 2020 01:03:53 +0100 Subject: [PATCH 1323/1831] Try testing with Python 3.10 alpha --- .github/workflows/test.yml | 8 ++++---- setup.py | 1 + tox.ini | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ad8e518b0..f50b4eb2c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: [3.7, 3.8, 3.9] + python-version: [3.7, 3.8, 3.9, 3.10] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: 3.10 - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft @@ -36,7 +36,7 @@ jobs: mypy: strategy: matrix: - python-version: [3.8, 3.9] + python-version: [3.8, 3.9, 3.10] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -50,7 +50,7 @@ jobs: readme: strategy: matrix: - python-version: [3.7, 3.8, 3.9] + python-version: [3.7, 3.8, 3.9, 3.10] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index 5ce4d2a4b..8d065f59b 100755 --- a/setup.py +++ b/setup.py @@ -103,6 +103,7 @@ def read_description(): "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Topic :: Games/Entertainment :: Board Games", "Topic :: Games/Entertainment :: Turn Based Strategy", "Topic :: Software Development :: Libraries :: Python Modules", diff --git a/tox.ini b/tox.ini index 559f81ecc..8bfa0772e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37,py38,py39 +envlist = py37,py38,py39,py310 [testenv] passenv = LD_LIBRARY_PATH From 973e9f60557dd8c67ca561c94659535e5e926d22 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Nov 2020 01:06:55 +0100 Subject: [PATCH 1324/1831] Fix 3.10 interpreted as 3.1 --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f50b4eb2c..74f05b751 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: [3.7, 3.8, 3.9, 3.10] + python-version: ["3.7", "3.8", "3.9", "3.10"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: - python-version: 3.10 + python-version: "3.10" - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft @@ -36,7 +36,7 @@ jobs: mypy: strategy: matrix: - python-version: [3.8, 3.9, 3.10] + python-version: ["3.8", "3.9", "3.10"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -50,7 +50,7 @@ jobs: readme: strategy: matrix: - python-version: [3.7, 3.8, 3.9, 3.10] + python-version: ["3.7", "3.8", "3.9", "3.10"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 20721771f8d202fb08ca45859ab8bdb52d65a86d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Nov 2020 01:09:26 +0100 Subject: [PATCH 1325/1831] Fully specify pre-release Python --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 74f05b751..64c82e11e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10.0-alpha.2"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: - python-version: "3.10" + python-version: "3.10.0-alpha.2" - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft @@ -36,7 +36,7 @@ jobs: mypy: strategy: matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10.0-alpha.2"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -50,7 +50,7 @@ jobs: readme: strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10.0-alpha.2"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 6d262473b774158660bd8836efbc6231c1a484cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Fri, 13 Nov 2020 08:23:00 +0100 Subject: [PATCH 1326/1831] Add a hyphen Added a hyphen to the word "weakref-based". --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 24070369d..ef76ae3a0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -19,7 +19,7 @@ Changes: Bugfixes: -* Removed broken ``weakref`` based caching in ``chess.pgn.GameNode.board()``. +* Removed broken ``weakref``-based caching in ``chess.pgn.GameNode.board()``. New features: From 76aea7385291081c32bfd161ccf8325853bfd1a6 Mon Sep 17 00:00:00 2001 From: kraktus <56031107+kraktus@users.noreply.github.com> Date: Fri, 13 Nov 2020 17:27:15 +0000 Subject: [PATCH 1327/1831] document `legal_drop_squares` and remove unnecessary copies in `_CrazyhouseBoardState` `legal_drop_squares` was not documented yet not used in the code source and considering it returns a `chess.SquareSet` I think it was intented to be exposed to the users. when restoring a previous position form a `_CrazyhouseBoardState` it's not necessary to make a copy of the pocket since the instance is discarded. Also it's not intented to be publicly used. All test passed. --- chess/variant.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index a801ed5ad..e93d992e3 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -616,8 +616,8 @@ def __init__(self, board: CrazyhouseBoardT) -> None: def restore(self, board: CrazyhouseBoardT) -> None: super().restore(board) - board.pockets[chess.WHITE] = self.pockets_w.copy() - board.pockets[chess.BLACK] = self.pockets_b.copy() + board.pockets[chess.WHITE] = self.pockets_w + board.pockets[chess.BLACK] = self.pockets_b CrazyhousePocketT = TypeVar("CrazyhousePocketT", bound="CrazyhousePocket") @@ -727,6 +727,13 @@ def legal_drop_squares_mask(self) -> chess.Bitboard: return chess.BB_EMPTY def legal_drop_squares(self) -> chess.SquareSet: + """ + Get the squares where a legal drop is possible for the side to move. + + It is legal to drop a checkmate. + + Returns a :class:`set of squares `. + """ return chess.SquareSet(self.legal_drop_squares_mask()) def is_pseudo_legal(self, move: chess.Move) -> bool: From f22baecb334987eeb74aff2e55c096e4449a6856 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 11:19:51 +0100 Subject: [PATCH 1328/1831] Improve variant docs (after #694) --- chess/variant.py | 6 ++++-- docs/variant.rst | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index e93d992e3..346c4d139 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -728,10 +728,12 @@ def legal_drop_squares_mask(self) -> chess.Bitboard: def legal_drop_squares(self) -> chess.SquareSet: """ - Get the squares where a legal drop is possible for the side to move. + Gets the squares where the side to move could legally drop a piece. + Does *not* check, if they actually have a suitable piece in their + pocket. It is legal to drop a checkmate. - + Returns a :class:`set of squares `. """ return chess.SquareSet(self.legal_drop_squares_mask()) diff --git a/docs/variant.rst b/docs/variant.rst index d98405341..14421fb56 100644 --- a/docs/variant.rst +++ b/docs/variant.rst @@ -56,10 +56,14 @@ Crazyhouse :members: .. autoclass:: chess.variant.CrazyhouseBoard + :members: legal_drop_squares .. py:attribute:: pockets :value: [chess.variant.CrazyhousePocket(), chess.variant.CrazyhousePocket()] + Pockets for each color. For example, ``board.pockets[chess.WHITE]`` + are the pocket pieces available to White. + Three-check ----------- @@ -68,6 +72,9 @@ Three-check .. py:attribute:: remaining_checks :value: [3, 3] + Remaining checks until victory for each color. For example, + ``board.remaining_checks[chess.WHITE] == 0`` implies that White has won. + UCI/XBoard ---------- From 49d8c6dfcc55a9cd62bcf3d2163261edda2e125e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 13:46:54 +0100 Subject: [PATCH 1329/1831] Experiment with images --- README.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 62720b727..f1f524d7b 100644 --- a/README.rst +++ b/README.rst @@ -299,15 +299,21 @@ Features >>> engine.quit() -Selected use cases ------------------- +Selected projects +----------------- + ++-------------------------------------------------------------+--------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ +| .. image:: https://syzygy-tables.info/static/favicon.96.png | .. image:: https://github.com/clente/chess/blob/master/man/figures/logo.png?raw=true | .. image:: https://github.com/QueensGambit/CrazyAra/blob/master/etc/media/crazyara_logo_medium.png?raw=true | ++-------------------------------------------------------------+--------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ +| https://syzygy-tables.info | https://github.com/clente/chess | https://github.com/QueensGambit/CrazyAra | ++-------------------------------------------------------------+--------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ +| A website to probe Syzygy endgame tablebases | Use python-chess from the R programming language (oppinionated wrapper) | Deep learning for Crazyhouse | ++-------------------------------------------------------------+--------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ If you like, let me know if you are creating something interesting with python-chess, for example: * a stand-alone chess computer based on DGT board – http://www.picochess.org/ -* a website to probe Syzygy endgame tablebases – https://syzygy-tables.info/ -* deep learning for Crazyhouse – https://github.com/QueensGambit/CrazyAra * a bridge between Lichess API and chess engines – https://github.com/careless25/lichess-bot * a command-line PGN annotator – https://github.com/rpdelaney/python-chess-annotator * an HTTP microservice to render board images – https://github.com/niklasf/web-boardimage From 46252e5347506eb6ff2dd21ac845922f7f58e0a6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 16:24:17 +0100 Subject: [PATCH 1330/1831] Experiment with table layouts --- README.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index f1f524d7b..6abc0dfd0 100644 --- a/README.rst +++ b/README.rst @@ -302,13 +302,14 @@ Features Selected projects ----------------- -+-------------------------------------------------------------+--------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ -| .. image:: https://syzygy-tables.info/static/favicon.96.png | .. image:: https://github.com/clente/chess/blob/master/man/figures/logo.png?raw=true | .. image:: https://github.com/QueensGambit/CrazyAra/blob/master/etc/media/crazyara_logo_medium.png?raw=true | -+-------------------------------------------------------------+--------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ -| https://syzygy-tables.info | https://github.com/clente/chess | https://github.com/QueensGambit/CrazyAra | -+-------------------------------------------------------------+--------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ -| A website to probe Syzygy endgame tablebases | Use python-chess from the R programming language (oppinionated wrapper) | Deep learning for Crazyhouse | -+-------------------------------------------------------------+--------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| .. image:: https://syzygy-tables.info/static/favicon.96.png | https://syzygy-tables.info – A website to probe Syzygy endgame tablebases | ++-------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/clente/chess/blob/master/man/figures/logo.png?raw=true | https://github.com/clente/chess – Use python-chess from the R programming language (oppinionated wrapper) | ++-------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/QueensGambit/CrazyAra/blob/master/etc/media/crazyara_logo_medium.png?raw=true | https://github.com/QueensGambit/CrazyAra – Deep learning for Crazyhouse | ++-------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ + If you like, let me know if you are creating something interesting with python-chess, for example: From 0e6866a04a70a4b3db9f03a68679025b64a38f76 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 16:42:42 +0100 Subject: [PATCH 1331/1831] Finalize table with up to date projects --- README.rst | 23 ++++++++++++----------- docs/images/clente-chess.png | Bin 0 -> 24725 bytes docs/images/crazyara.png | Bin 0 -> 20531 bytes docs/images/syzygy.png | Bin 0 -> 1364 bytes 4 files changed, 12 insertions(+), 11 deletions(-) create mode 100644 docs/images/clente-chess.png create mode 100644 docs/images/crazyara.png create mode 100644 docs/images/syzygy.png diff --git a/README.rst b/README.rst index 6abc0dfd0..c22ada69a 100644 --- a/README.rst +++ b/README.rst @@ -302,17 +302,18 @@ Features Selected projects ----------------- -+-------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://syzygy-tables.info/static/favicon.96.png | https://syzygy-tables.info – A website to probe Syzygy endgame tablebases | -+-------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/clente/chess/blob/master/man/figures/logo.png?raw=true | https://github.com/clente/chess – Use python-chess from the R programming language (oppinionated wrapper) | -+-------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/QueensGambit/CrazyAra/blob/master/etc/media/crazyara_logo_medium.png?raw=true | https://github.com/QueensGambit/CrazyAra – Deep learning for Crazyhouse | -+-------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ - - -If you like, let me know if you are creating something interesting with -python-chess, for example: +If you like, share interesting things you are doing with python-chess, for example: + ++------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info – A website to probe Syzygy endgame tablebases | +| :target: https://syzygy-tables.info | | ++------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | https://github.com/clente/chess – Oppinionated wrapper to use python-chess from R | +| :target: https://github.com/clente/chess | | ++------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://github.com/QueensGambit/CrazyAra – Deep learning for Crazyhouse | +| :target: https://github.com/QueensGambit/CrazyAra | | ++------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ * a stand-alone chess computer based on DGT board – http://www.picochess.org/ * a bridge between Lichess API and chess engines – https://github.com/careless25/lichess-bot diff --git a/docs/images/clente-chess.png b/docs/images/clente-chess.png new file mode 100644 index 0000000000000000000000000000000000000000..1efdd5937a426f644b26069693a451547735f659 GIT binary patch literal 24725 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 M>FVdQ&MBb@02BLM!~g&Q literal 0 HcmV?d00001 From 2824ecdcf48adf8a6ca1eaeb7da4b64ee2f228b0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 19:57:45 +0100 Subject: [PATCH 1332/1831] Smaller third party icons --- docs/images/clente-chess.png | Bin 24725 -> 20235 bytes docs/images/crazyara.png | Bin 20531 -> 21730 bytes docs/images/syzygy.png | Bin 1364 -> 5700 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/clente-chess.png b/docs/images/clente-chess.png index 1efdd5937a426f644b26069693a451547735f659..b34430c7d146927ce741c6a058bb6ed9fc0fa459 100644 GIT binary patch delta 16225 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 LNkvXXu0mjfoxTW? delta 20934 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 tI0IbeADRI#0}5o`Nr~F03~dC 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°E!VrRZC`6%J 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 delta 1336 zcmX@2bA_wEGr-TCmrII^fq{Y7)59eQNGE_W2OE%lG^5;tfr0r}RY*ihP-3}4K~a8M zW=^U?No7H*LTW{38UsVct+&%7rzvalxc=YT6~`phk!UG!z;bJIT%A3~rQ{oup)cR9 z=j&^Jso0{IF#Fd1{Z@Zl-CdL|c`vHJ=aritQ$MN4$>jIu=Q($3&L3Z|cjf)9mzNYX zHl27Ybzz#_;@I`fP0??k?wfmP+nXb)8KpInTawcp6JI_uN=eOs9=d$XvDEU-bH2Wu zeI`%0`g-zRR+hzDZz2^lr>#AByEjtDX2Zp_C%>&7Qr0-%T&T|fw(!l1pc;;QOTP$M zPY&O`m!CD(p#Dd@#M-iJk8hmixLbAP`poxMUWNzn*lpkV+VtDKZ&y>F3u^jj2gZBP zROJx#OMh*nk%p8fNfbWF)5mWN^!ec$AC zbJS1Dbt+UYoSrawEsIr>dBEn3Y2ErZ&wY#c^(v>W<5_CZW9U|IqiU7)XL5<*mESjZ zol%QRV%?weCUb}3iC*&%hC{VSL(*%~7tO9s&N~n#a7FT22WwhznXv26UEAM0$ypfu z_{1CcX6INo0i`o*3)*x!B+iH3+{~%eC|TI^VDiJA5$dcg5usYa?9$n`4_qXRlYJhn z6rH+PGMw9C#aA;1-%XMm>gNQ%ng2lPTR_pgb+cPnIa3LKmH z6^~4C>NDH5;^J|EWFJFyPqFYBYV(oPyijQZaDNEB)f27 zdv0m$6^(oMjFqKkKC4;1>wsP7xr~3R&dJJqpIo{x7yIkXL|cO|b=&uR>w46lx6Rr4 z{hnF7S$;fS==R>Ke!1J8Rk>l3_SudFN0Q2)mGqwTxc;S*|KESVAN~LNxmrpl^)EU9 zYO=kkLH#2Rb|y`plJ1oMz%t;sr;B3Uc0rr zx9|*u_XL=_=SK~Gyv&%r=6+u?TSOBBM?FMWcm9!eIZ9t@&61`mKutk1j^V4<&SHcbhvGVh3v1fy s_x;;uUS;7bZ}qxUy(*2NVe4(iL`|;`yXykYfC0ha>FVdQ&MBb@02%jKoB#j- From 49ea0d494f4ccd38902911b63a35492dae97d747 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 20:01:07 +0100 Subject: [PATCH 1333/1831] Tweak legal_drop_squares docs (closes #696) --- chess/variant.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/variant.py b/chess/variant.py index 346c4d139..73e33362c 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -729,7 +729,7 @@ def legal_drop_squares_mask(self) -> chess.Bitboard: def legal_drop_squares(self) -> chess.SquareSet: """ Gets the squares where the side to move could legally drop a piece. - Does *not* check, if they actually have a suitable piece in their + Does *not* check whether they actually have a suitable piece in their pocket. It is legal to drop a checkmate. From 6abc53bf70ebb3c6b36c27c015f001a1a3191dfc Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 20:24:44 +0100 Subject: [PATCH 1334/1831] Add icons for jcchess and PettingZoo --- README.rst | 20 ++++++++++++-------- docs/images/jcchess.png | Bin 0 -> 20967 bytes docs/images/pettingzoo.png | Bin 0 -> 3741 bytes 3 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 docs/images/jcchess.png create mode 100644 docs/images/pettingzoo.png diff --git a/README.rst b/README.rst index c22ada69a..9bde69c07 100644 --- a/README.rst +++ b/README.rst @@ -305,14 +305,20 @@ Selected projects If you like, share interesting things you are doing with python-chess, for example: +------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info – A website to probe Syzygy endgame tablebases | -| :target: https://syzygy-tables.info | | +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info – | +| :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | +------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | https://github.com/clente/chess – Oppinionated wrapper to use python-chess from R | -| :target: https://github.com/clente/chess | | +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | https://github.com/clente/chess – | +| :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | +------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://github.com/QueensGambit/CrazyAra – Deep learning for Crazyhouse | -| :target: https://github.com/QueensGambit/CrazyAra | | +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://crazyara.org/ – | +| :target: https://crazyara.org/ | Deep learning for Crazyhouse | ++------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | http://johncheetham.com/projects/jcchess/ – | +| :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | ++------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | https://github.com/PettingZoo-Team/PettingZoo / https://www.pettingzoo.ml/classic/chess – | +| :target: https://github.com/PettingZoo-Team/PettingZoo | A multi-agent reinforcement learning environment | +------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ * a stand-alone chess computer based on DGT board – http://www.picochess.org/ @@ -320,12 +326,10 @@ If you like, share interesting things you are doing with python-chess, for examp * a command-line PGN annotator – https://github.com/rpdelaney/python-chess-annotator * an HTTP microservice to render board images – https://github.com/niklasf/web-boardimage * a JIT compiled chess engine – https://github.com/SamRagusa/Batch-First -* a GUI to play against UCI chess engines – http://johncheetham.com/projects/jcchess/ * teaching Cognitive Science – `https://jupyter.brynmawr.edu `_ * an `Alexa skill to play blindfold chess `_ – https://github.com/laynr/blindfold-chess * a chessboard widget for PySide2 – https://github.com/H-a-y-k/hichesslib * Django Rest Framework API for multiplayer chess – https://github.com/WorkShoft/capablanca-api -* a multi-agent reinforcement learning environment – https://github.com/PettingZoo-Team/PettingZoo / https://www.pettingzoo.ml/classic/chess Acknowledgements ---------------- diff --git a/docs/images/jcchess.png b/docs/images/jcchess.png new file mode 100644 index 0000000000000000000000000000000000000000..4e3a0b529a0af8dd6ee8c1fbbca7afdea51cf121 GIT binary patch literal 20967 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

5ih#W@d5^mFz6E}(pO0Ih`Lms zaqNq;=RwEjTebsrW%WgN9vZvq(08iomo=Z31lDue58zRu38R7jk0KA=zbMMoTH*^% z)Ghs0qCbw?-^(?+?dOtB4nebRI&tAI*_t*{L*3;v-P+jJ!y^`|K20#iM-A8-o@80PNPvU4?o%zDguh=~>+x=3mOCAapd2O%hhcII3kEE3uH{~@ z&}C9FHWGv-u-UOU56W`Xla%U0t-OOo=^ei4o-gJ50kzH$_d9qhox$bxBJNxUW$91h&Fvw@yNf z*LQV&ZviT!Lo3Uk!PJVFlv*TN6PF!J?tEU2MC%euDMBx|kRR-tSz)qh?xxMjS4dq6;4Qc<3%het7pqQ6&)u|Go=e`1naGh@ zR#oz6mDTC+i@Eo%`nqRw^(CYtt>yh#{N7z~E0O(NvWYsGGD4?R1YN9bn%1zqVIQya zsj7QsApD&%D$BRgrjAh64l7cr zWqA7#g@^_Jj2LPL<-p3{|MAzm$IChB0;eMks2Lp7F`}^J665WfRa14T-Y(#YS-hXC zxj(cJI$Gj&QM7bZHR)6YJIlH{$^ISla%DYMVfV-fpj?w+kSXWerMH9L>A7$eEb*iY zG3Un-o^|BJ03;=TwQM4W^3VuE{4IT}0%fVMnOLoM8nD+gNOq+eDXru9n^nD-@r?77 zJ`~qgDy3vs%6jh&S99KF2V!njmXFsjxW?oeqoZRid_Kcf^JjvwmY>T(BmWgEuPjwB zXIgIGid2GLViEm-dL zPf;Q_g}*#!EnQD&9nTTkqk8O|CJ{uci%>eFU|qnW`Ifp`#A-Ce%8yX(=e=6$&O)KD zkTaHS49lfVC{YMrNxZMgSmJbq-7~In&F6DS_+=Q^$-RDER}Kx^5P>!Nz{DS_qxjK(%B5-19X%RkY+=RXu*;I7D;;4;lT znI1aIY4_W}^43DfJ5kN~fqjinEL%a|h*=^T_wK6X0L-VpzGZ^Pg$wU2$di0Pgp}~n z4*M1?R#QrsLs(P)J72_cUFF;hA`d-(JAX|1uF}pEPONBTrX32OiV36FukW@Ioe(ky z{0R|8X~>f?R1jUuM};PBzkq~|;XxS2u858v*z5w-3FZkN2+g02ffh?r z@Ao|lOJ1ti*XPci-0frr(0lf@Ha%h~BZLK1!@1xSqIUNR!+s9DpXIT`IWDMhPvhk$WlbL~ zWUi!0gEK+IBv^RIHpsOWy2~Y> zY2X9^S(hpno{OW<7>AeS`bH^#EzO0m6fEumc25q2$v3$>y zda+~9*7rE_uEFch#dQ15hqL>;G60+DdlYMXVHn7%u)9KO`HZgWP&%t%q&}0=r~NB@ zos#Ac3})PK<;U8K<_ly@Jcy}NkdjP`doVejk*ZuWqgsVTE)S;Gh4OcLJfd4oBBLJ; zrJ)Y#JOu>m*f5}!=S$h#iTG@EBz%bjlwJ$E-pcn@YS z;iL-VETaix-V5lmDUA;^XVTB?@g*iSYE0U+Zu0IdGtR1y%cPIggiYKNK#wpz$k-gT zD;>s8X=@vy&0+<)y;daxBMBK&L24q-{lMN>y%c@l zEj@>Y33hTxK29Y9QY?5|h6Yx8Ji2oVM|Bm>;ahV(O&)tk%@K{cR%$;Zn!<7h=gc`& zbgf==ao9K&2{@2e*knb#F`2}kBg$*`7WNQjLMfzV43v7dsMFI=zq6JGGhgEs1^B*z zaqQ(69O%Fn;XJeD^?~|T9x(8U&ZN1E_XnL<)W7PIu>`;$8Ui8@lc`R@QusSN6PR#6 zlS5hDUwZz0j%uex2(}M6;cT!UbIuS1SRQCxK=bfGO2Q|$ot&Rk+_XRIP9LqKB+WY2 zy{EW<1OQMXE#D4gYAML`nb_Mh8JXG}gP1&Q9o`OX0sufE4+kR?Ymf_xG05D~PJryR zrGt#b(o}%#J*NVTf`b^y!cyAH38dzwsBYqAZNh6xCL{BdGT2u}iZGBx8<6_@-6 z#al^$%)-URfsdKl-QAtZot??v$()&$mzS5Bg^ihwjqwe^=a;x7(y zkh6)CrGty5y&cJKP9tM`R~G>?vbT1Ue~`bmnn-xORsO@l@A4mdXBSgunYRMR+j!mp z%xo+yJd7-CjBLEjf46^YRZ#e+wVm@nRD9Eu*~7?znU#r!+1BY z{&p^wSrz1L@9Ja%l5hjrxsd!{pq)jsTuQIr~Y{UyN#5Lg7QCY ze#>ZXY3uOE;y3#5NK=!4;v8I^Z2n+OO_)J8AltW&IKMHo{wKVPrP;qG=s%6;cgz3Q zkvDh$gHn^>Ci{rSob;so)q@ftC*u^VwQ za+vaPFdDORvM?HPadUC8@|c+Na)ACuC1dC8Vq|9m`c3sl&Sd$Jy`$xu!8ksZyDFT`QJMjO;q-J67ZukF<=U>o&vWPgj zxZ68fD>*3{TY*em{(GMP3j9wd)wi|I*~Q6I=KnCL{|65ESGY>Q+1fjK{>{G{$nmez zUkj3rS>Yy9qA~BZm#+kC5cbw zcjT$LIyl%^f}H-dF#i!K|1Y?|+5aOb|4-(Bhy7(OX7Awnmb4ZwO73?5t^5B1_!on` zr3uK++5W%l`rjdc$?~^-=dI6w)xGU!Z`&jDKljIfgvFc4|2H512)F;6E=WlJ?c{%? z@4w~xw_N`t1^!3ie@EB9<@z5f@IM0oJG%aVlMDV|ci14iw+lV@xBKS`wdnY_dv9oC zIVo|#>+ffFTVcXm4V;6twle^LfbshU21v`md8>qRkx`I<*+xLdc!zUcwg&_NaO7pg zMbtf(X4AE!^asAI`x(w^pUnAq?@XyDj49+7xtfmX*eu4BdjPkfhI-`vakojChr~XA zX#fmaqmsY{0-<23FgpENMLu`+j(_OiT9^~BH;u;|N~DP(qqSRA;PP%+^|{?)&`1h( zestrONH9~Y9)KcnS$FQxEj%c-fA(8PJ7HroY;Ps_v_X;WF-S_5%0a1!9#t0x3mDh= zxIS>}lc>tGcSrH54r`B~9|t%=9%Hii==-=(Z6fBLcYET-t}rcwrlMnAR>#jp4nD_6 z(GuW{j3z?6VdssCw#oBt)ou$=@Qy6d73+{7_uZ0?;FsedXFCUN>*_g~v~PW1rTpGQ zZ+8p3wg~hO3|Md;=3{-Qaq0taFD#x-ztcg31j|&!7lOql#BG|ORlF$0bNoCA!75DK zcjf?RO}K>MV9AH7fhNI(y=fV}=egYtlu0wob&qvkX$QX@S!o-YIS#=2VbyRh@Kw?T zGZGb2Fa#*>cu~z54j5O_*4?u|WZ4D7{ZLLWqsBEiU!6O+=S&kHph#bE2CS@f=D%iE zm}bPH4VlBM#=@2&f&ch*21ot1#V`W35yn*bGliD5jC@4)4_U{{eoil1k1Q$2qF!>f zNB8~KFjNV&!$a%*{(#zd@Dly~1Lt0ZqqC85%$sI0s@m%$DI=_`tkpe(FLeF-xTug| zS;Rl=+-VbK!(c3r--UFe_Vbl-dKiVN;>m)Z%nc8w z@xLLPN-pvVU%k4Mlhh!>`GGm_pxe&GK_@b>S-y60|09`74O>T7qJ5k^&O znR5T?Fy}kLFbq@)E0Tz=34~1oGF03!3@KXXd@MxK4ETQd5Iw(ma2fc(o=bvpGdk1q z9zJNtkSlkLzMr1iy#dZ)fjnRZooa}ioO>jSq-QnjQ0=>td#t+&d&E&-vXDwkIMX?O z=3#0-vSMY_bgKLE;WCH4Eed}1(`Lcs%!LVkdY>gCUZh#N4WD=CE8S2lS@?kVLE6>~ zP#v>*x0NV)i&jXuX^>7L6dWeyZA&!YB4ez-4sDqztSl(P0}Kc!|I9-*itXSi@BWM@ zqbfES$a=_-mEy4J5Lg&XRt&^};OZMV$OFDkoz_%M;w`;r6XVdW@viF*lCR?!mFO z?WY1>zP7Mvt0Xa)Ta&3UH-g%!{qr{W_jdz^g1s98msJq-5Z{1_P+PLCD(l9J)Q=>C#>IY zqNigJh0@De*>TCp^mK}XRA=xB*E}A{gao|9>F4d)8a9M$4xC;{y*`INRi1v`Sby0&b$Yn~s?2N!rMtGjzR(p`+Bm$JWtuVPEFZFZ zJAWDBPQIIxQ#$kWeIjb3>EhcM3L=lf;*deVyv_0s{`hn9Sj3B%x%A{zJbUfn$FF`0 z8CinDD=*e8tVEh`1DCB&3lyPLazB)W31Uzx8RGJxO&Dcqo!Y?(oRgU3W{H*x2m~5a z5~PTY8dIgj9nU%;A8(`LC$N>lEkFN=7!wY5HWEg?o58bfznW6}_`+UzCJ+s1HG%i(k$TXvCbwM^WZTv+^xXCy)~C;^K-QB@igxe(+Wgk>ms_M*0@SyD0o5%W#uSguJMx({ z+Z%-_7CppYvy7QEMqastLLP$Igt*P&1#4Ed<~Ct|H;2zz{2(m{wR6*v$-aEivo{> zZPMM{%J?$9fs-Xza5DJyTV>gEL%-HerAixAXuNebkM`V5ilJ*kCJqZ$hgOkDK$w>WD<3{!d_nc@lGY=P7%DCNsL7D1W=~-U=Ft)r! zPqtn~1cjs9F_&XN6J48y?#MDCgkXpjOhUZd7q=_vb= z+I^2*;vK!U>l_zeB0Mh^y@r=c6jshsgoTT7)u(IC;A&iohVPTvi{W7j!F{t<>-g8y ztF|PN5f!r;h9|0YDQLm&*v19~4Ghc`X9?UBIh$OweW?v=JR^mQinVC8Oqz(X#H&&x zbQR_JRMAE^{R-o4&ROO$iVo*bl#&;M)Axy5qNci%sYP*$En@`@LLY7}G^ipRcBxOR zm`@Y(X^AWHi}b>!%p>&l6mW?!mdde&d=Jr~u#Lz^l>EGssbgZ<0zF}wvpb?sIBAr8 zgAzX==vV(ZcKM|~Kj;})gotzfT{4t+i76YXCvITm78rfC7n}F?2L-Q8J0SzqDUKXW&Qv_1 z0ozNC+Vj2p9-)uQ%z(Ql));~7cOs2YB|0!8a+pjneU=eoUC99cNN%@asjO$<<86#B zD+4EkLC5g%eJ!N+!6!idEa+l}HU@Zp*Xc_l+LG>YKWdpCE7EfqsV z3R|DtR^8q;#_ktwwMGOfKhCQ&#&@m^Q|e|7d2ANbHXX}z_&_{M2%fm}M4adDQ>0!W z?0Dvx;Fhq)n=#@tAAS(Zx;#6z>MG!lZI+{lKIe5i7ZA$y@yV8Ge03grZ5heV7^0}$ z5^^4fUJshvHZ%)Wycn?<2axw=ZA4hIep^D^?T4M{1#a6i6Z3N&jrj4C0`zQ9*kdE& zAQNj>IlM|rUjZhtqmv3~Qf^YNS`csLQgggFPIesTVu_jF53z1Pl~`9tcP);wz$nS3 z_I37}ZlhaOQ~y9|`h>D<9zS)4TJZ|`JeD3mj{eHl9|ERMC&-GwtIwg4H{$cLLFXhFk=lgMmyMh!Wc9{H3pT$Sj$t@>CV)9c2m3J5?nMS9PhCR14$e!)4JMiVp^ROQU;-c-07oG1Q zn{uXp4rbP-E<5AQcQ)(G`U5tbx3_i>0ff>aq%`u*o978piIK~ol;|Y**;=6wG{d&^ zvN)fJcn5RTs9_`T!O|9OT(md{KjRZu)h}&5eT>GAiDlm|I7)wEV2>4u*ehj3a)`0m z;Ziw9&$)&{goWjGdx8~9z~IOE85+lgdA{ru)Xpz1U1bqmUNsxu!zY!Nk6Y7pAFbNR z(HGurS6hyoWyLB3em=Kl^V!s*e5$Mg$?xWbuMjy#K1$OuZ>^SsBf_rHVXR zQk@*g?@PN&lyV=w7e1cJ*Guexv{zJX2kLgHYUvd!7`P@MKi*hIU$~7kGhGVm)NnR- zc~O)Kd3a@m8`pZTazyI6n?n-f>}egEUi*(F$V8Jz@Ne&77il8!M}4r(8`c>Ja0}`V zsgBuwJM-Bgor(Z+$+0Xj_r8>Ylk`2oX8Kpc?)z@5WtP^)2&Buqwfd+@-sHC!i6K9$ zKll+ZN4ui)ZQlO;GD>Gyi;nWHnHfnPMly0m2eYl+jY?HbQ$ zA7$5(M|KMam;V|vprh`{EKkPu1isE%;Gy7MnX@_`rlk3S_8>`%Iv6v-=3sS?$FdXH z9s#|a_4l<`Qi=8Dv{hV}a~|)Q@hbcEh0dkrnW`ejhP^d17F{x1FT!s(0uvk5ia!M1 zLvHxFX@uOsTkJnK)`(YLFnOk|qrpTe`lP+3eIH62n2D7&{wT9wuqE^H2Vo|=pWbkv zPv&4{Z6caW&gs^^01C%^!Y$eR7@B zgt11N)6SUU-zT-6uclf}TgQoF)#mHM63DH0Lh*#vdP=D2zm*$w{fR-4DSE#qu=)PB zvy_cXj>A0^ZaCS|gq>KKt`w18q}R6ZDm`UTvrI61!pUnU0ZUkvA^{H(y&tCv=XU7-qd7GS`D_ z*aHFd^riV#W3YU9*I4E1q#Jjd+AF;1>l?p7y@HSwW}EQV*z1y!9eL~D!~*h|KYlrP z@`VZ1E1he+m{W@5cLMV}0!U@OlHKds#c|H*>T}tRtCku{M1X~T2zZzReJWIP{JFS} z1E5J48Jl(9E6V5)9E1Y!(E=~Foe`5lVdAsvkOlmZCe-6h8-B5naEZFktE8KPGjZPC zL&zU3k9agyk)w)w}`^I8Gd#QSU3MsPU6unFfgf9uE5L2JF`7BVrl7~u~y?He+CLF*PZ0(jw>6l)yVwE84h849nC zLU~2=8J!Q#eG<1obG|-6n&akTGihL)F)*;-#5Su}HafJBg2P^WjnfnCKtiiws94#& z^Dvp#JwZl;zj*XK`oc_V5Z2Zn=8ENGlXfkebSU()p3jR?g60v3j|3a~&EsN+ndJ+D zbR{#%7HB3wX3osM%4tKv#Wc<;7#}$-3G~WtxczfT%KZx8tp$#I%{yg(30Ixshk|1s z>0Lw+wa`FT5R6JgvO^~9>7*rICKLVMcpSs~AM}J7nhTSt(-j+%x-GGgP|8c@jX-%% z4_N12vF%}S@;q`xq$F4hN)EKXTYJ?;4bm$_PeXPfP+W#%x6XNgmMX=5p=!CR2_gEha(~Vv4eJX?|s< z$sh_XO3L7Ugfcq(du&=g1B&lx0jVN~D;2C=qlG$&oC`V_)TVX5hYy^9D*ebvhH*3L zcxSBie2UAFyJNd#gez+}F4sZHC^YF>&HufIfCy<*mIw`mQoAq z1i_Qqh<`FP#taEA%RBS^uK;xgiuzqJ?jc)bkgW3RQq$+;9WrHIh8JvCGyxKmsjpVs zKt>?x8?pOg)|+1^Hp}uvc63&{UbNE)>#SFCdk19@WZ=oJ7_jN1m9fNcU&Jo1;pUd; zp1FV)L3LBSs~hNQ7roTRo3Elh4_9x~d-DS%Nw62^NUq$%3jr}W;r1W}TqOV_JNBSvrZ z@Mdd>wP>}IM-NmSeN2BFx*M3_73^Azq}|RsIP(SC`2xM_8fD){OjgR0KobW(ajF=J zx|m*s_#RR&6Zx97Q6pz06L%#vjlmxoVRU?CP~H*|I=zI(`Ubf)Cb0bz^))U~L_vXk zFG9K z9%GITqg;+hzwmYZ`BhZtBU;n>Xr9%_r%`r!_x%A`yyNg)N_cq@X?3BUkd_1Np&5d1 zLi;=am+qMl@Q+X9J$jhZ-eG)~62u95VHJ8g)bJF{&tY#T3{UUH`dM)#nO{XJ^W=JM zWTgwe6lr>NbB26AN5NRq#8Nwbp2Ge~3N!o3<$V0}H_2aE%hpmljy<%OLMc!0$}Jj~ z=5Qi-))E|l0n^d2a=VUeSqK8uxfPh+gG&vi=T6ah`$N*3%k2H5e@VAl!L)g} zx`6Ay4nrdb3(`)IwGJqar95I`BzxA5J`(>m5X*6)@}m8<2y* z^NDZh3<$(?%U53?Z=$b{3<(SN@(s8F0?FqkAW{g7Ob*guM|7<3tkKxxqsvZDxN;6#T(F<)r#H^Ps(w< z;H{vmizM0#Gv#KG#F-9}m%Br~R)scS!oQp^P&EGYDq?C*?d5@zi^aobi|?`LEzqzJ z4nZCyAHN~%Axm4P!o!j1Mx~kSjYSQn9OBRP&*jhBMk5~R8(%wg8G20D@aV}x_Y;N< zR|x5_WqQJ&G_o72#Eg6x7KX0m70F-X-%XokJ8cgOoKryXYq%j6Jiw4;-s}f+@v@p% z=D-kbKKs}aw|YM1hmR(moYo=VXAdfpuRiGIcU}SUS!8&cl3|aAzi|e3|CeAbe)}UY z+ut>qkx;G;^8Il-h7W<@tvT@8bu;FseO&N9(RX8$&%HRTvS!hC7f8#&>z9oTK>Po$ z%D%b+U_~Ir*fAW);N-u-b4k7|8d&6yFfqsRe-#ova+J^OoopTmB>cd{K+h)n!}8U* z0IAIco!_Csgx(X8g+srNX&bB=5Hw2Z^t_uImQ6<$MV%VmW$$G1^1OqIw0SL0bU139 z^}z@05u$wa4g^|vytv29`G8uM>@ciQC#0$07Q7r4IMwbyY-MKtbmozP307t^7t(?z z;Z<&&d91U~UQKwo`}bM%>?-J!=*qvl8E)R=izZYDB_{r*3keC8qep(!*2?{l*3wao zOq_D3$XtwF|32U3&>>HFVkQ^v>Fc}bYLbru94j)V5I%1$+SUBNOwW<-nF--NeCL)& zM8rB8lDZU2h`q{s-vI`JkVmt+ry{!h@$!#925s6~RA_LW>&57yn~bqBZ7m(0U_MZ# z0IlUl)0LYqD<^f7vDo;=FQiy;aS2&BN7s2fd;4L)psud2m~IM%TVHU>Lgp+bi#}KX z`}gmM@-V_BfBz*ZKgdo2dZZF<64>6}ekWdAOj+1NGx5(>fWG6+F6SD#0^cYfA7e{L zH5HXd*WmLp@C+fD+=W6UL^_BX2Tny!eGALpkWv5TQhXzKi!Y_bT#gx8WNI6sj#x0T zTo(})%~ve(hk^B`yxLus-S0olxK!1wB+Th$2le+}czLa{maqiYhc&DPl|o^hDSCYzXL$xYE@oqzBTtB4yeOHieS5C+{dcVe z>jqZX#U%t?+OFOP*F3o!6%%v1h_}ymRSF|K(%08FJMHV7g!~nTgl>&jd;sfL9Rpl< z(Vh*qu7^30`LQzNnt&Y+f8DL>VUMlq3442c{E~*cZf>(i6sKjw8yD%JnZQfN^m1Zz zn<64xJ7X@ISi3mK9b4jTC*q(6iU?61E60Th4Z1+8g9P|<@ad%p4fertj;ueN=XdlU z<%4O*t~QbT`*no%?u};9-0B;p5D3%(y%6@TuQ3LeHnw?$Q+Qa>Q>h*j=|=ioCr#u; z@?7V*WcJG!fw-yFBuY)q-0P+`ws_W!?z*}K(((@lf>VxR&E}+1adokwDJiT9FP}Wk zTH@|lIHHR)gOBluQ7DuI_nsXF!`zr;<>LS7@GW?y2bF3Sf3-M@c7x~iqi zx0elm)z(->B>vra^XA_3CGN8#V2@n`m#9^W&NEhDkKOZ&i`zw{BGWyUrs8`9)T4hP z(~-u5o=S{-RM*pmX_ZnlRVm?&#>u4wkN%%={j>XmdeE*|?c3L>(&EL%GNTKe$`{wS zhZ2wJHcuuw)!T^M+1Y7#O}aleYG4H!9?vuKfAi9CejsJP(sw7amb!Vs5+*_!qjBP; zXqadVy*bs7i^yd1WRzctDQSR6B$hzI3g5Xq zwvbd$5Qu;>A+y$wry}nQq`u+-;fFA0N^s!@AYAN}f$@GZ!rbO0K?CB_GuF zA5NHt$~G)mP+xggv7=cr7H(J*Y61m^>qmgbISF+Z5C0y?nOmJr+TRKhfQ?k_Q<$eG5DY;O@_$Y%R!1}VK!#pn}q$Qc{HT5~fxx)c%ZLjF|*Xv&f zM%r5H8kQ7DR;9D``+Q>9Pm_xg67-iZ6*<`b-(@>%^)`YA&_@I78_)2$@6{{Dl;IhG zA;VtnF&W6)T=L3_TW|xTr)NJ4HGH9grO^Zw2oQ~mii$e_DUGDh$OCEP0~mBk=9@^; z&|Sm1e8ZYjrBXAu)8bhL>6cP08(5PTC;=>2Y3(CqKoeBz2@SquUy$oeC50HiBM+s=3Qe36N zD}jm-1nVh*_1f$j*l5yQN$os<9zQmB-KK)UZ&VUK22tHUSQ{C`a4s4Zss*U+Rj#6n zc-CIv1^)reXjakoGj=j+Si;NOTl2|DJW%d(WqXo(&?&Xq`1T;R=%ApLhbWUBA}Q_d*fFL)sOk~@Zz{bAm_Ts_mAsAQDOkaH3JX9 zGrsw#>|AS_0|-O9hS`cJom$bgwArcbbhp2HEhc9BJfZp>jYc~{@>zaIy6o066|mna zbRhO7pfep#O|EJ{NdOt~d7!PwT)$IXTzvPfkFz1v;N2289Psjs;?I2@x2~{nBP0nK z85!c6C2o7e(o*gPt3Trh;qyk{rUw@zh|>)C=a8+ucT=fIh#3YRZwQoiKB`nGleUk~ zS4>5QA?OLAY95-1oNz#=Y!)xRVRAe&X`y6yaL3c9iiL&dz(-CsZ@(_x>A_jvEz#+5 zCR>(_TyS!o0Mv!-o%KbXc@M*B>_9NXk$bEuQt5<=2HG^QR6b1qKGXJU05u z4%&=EkH{zh5`p6zX){8I(zjy+I)RX1cifNyx{x61t_u|W%>gZ5PYPx#4lU(IhjRq1 z>UPIoy?Uh%)+|{1LNNA`)_?sMPdLL z0McL~SHSS2IOWjiDvGxCVK|bQsXp5*HfJHG`(3~jmfuBy_C4&Co5vveXPQ@j3Op^( zy?Ofj&cbrk?u)($Os{rx40<;prW81xIO`?nu3=4n*iHkdc%;URF|nXXnXEv<8oO%n}q@;n7vfbgGl6zy~E zw_B;66_4(lp^6;Tw}ase;OU*UHK5#z#JZn5 zwQ+&-!8z*sy$e_|YvLzTrK{z4{!t*m7CX*FLSD-g#G_vCWzs$y0TQPRMF9#(x0}uN zfXgkjSS7VuOaWmIZF_rru)ba)3+Qevif`bn@B#8guNj<$aXK}e3=>SZL5mk5A+_TV zb&}o$sJfjnS>v|0wvO}4$`u|i4?wMbwS%)6p&t_f*REnj z7jxo#&Ts-i+IKOfW|IKG5rXM|pE(Z~<-EF>vwMB9R?VE*T%u{2XZ+O?IK!q1zp4Np z+y%%*BIyDIBUEQ@Z2zSLSaUL^*v<NUqQY*yF6|tq1kAs=|9pNJ!8a z48{VTPTvjYI>D%Ezp1EiL^%Iy!0;)>ZDMY(Tl=mCu8s$ o)$$twn{IEVKMqQNJp4!JN{UKPTKfkNpt3+FxGM(aOV?8W53zP0H2?qr literal 0 HcmV?d00001 From 41a605ce7d6d8c374771b13c3cb097074f6a9771 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 20:27:35 +0100 Subject: [PATCH 1335/1831] Explicitly specify icon sizes --- README.rst | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/README.rst b/README.rst index 9bde69c07..b86c3a25a 100644 --- a/README.rst +++ b/README.rst @@ -304,22 +304,32 @@ Selected projects If you like, share interesting things you are doing with python-chess, for example: -+------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info – | -| :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | -+------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | https://github.com/clente/chess – | -| :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | -+------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://crazyara.org/ – | -| :target: https://crazyara.org/ | Deep learning for Crazyhouse | -+------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | http://johncheetham.com/projects/jcchess/ – | -| :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | -+------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | https://github.com/PettingZoo-Team/PettingZoo / https://www.pettingzoo.ml/classic/chess – | -| :target: https://github.com/PettingZoo-Team/PettingZoo | A multi-agent reinforcement learning environment | -+------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info – | +| :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | +| :height: 64 | | +| :width: 64 | | ++------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | https://github.com/clente/chess – | +| :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | +| :height: 64 | | +| :width: 64 | | ++------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://crazyara.org/ – | +| :target: https://crazyara.org/ | Deep learning for Crazyhouse | +| :height: 64 | | +| :width: 64 | | ++------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | http://johncheetham.com/projects/jcchess/ – | +| :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | +| :height: 64 | | +| :width: 64 | | ++------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | https://github.com/PettingZoo-Team/PettingZoo / https://www.pettingzoo.ml/classic/chess – | +| :target: https://github.com/PettingZoo-Team/PettingZoo | A multi-agent reinforcement learning environment | +| :height: 64 | | +| :width: 64 | | ++------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ * a stand-alone chess computer based on DGT board – http://www.picochess.org/ * a bridge between Lichess API and chess engines – https://github.com/careless25/lichess-bot From 2def3b582e806c2591f12cf300c32437153d0a53 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 20:35:21 +0100 Subject: [PATCH 1336/1831] More tweaks to featured projects --- README.rst | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/README.rst b/README.rst index b86c3a25a..42309520d 100644 --- a/README.rst +++ b/README.rst @@ -304,32 +304,32 @@ Selected projects If you like, share interesting things you are doing with python-chess, for example: -+------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info – | -| :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | -| :height: 64 | | -| :width: 64 | | -+------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | https://github.com/clente/chess – | -| :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | -| :height: 64 | | -| :width: 64 | | -+------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://crazyara.org/ – | -| :target: https://crazyara.org/ | Deep learning for Crazyhouse | -| :height: 64 | | -| :width: 64 | | -+------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | http://johncheetham.com/projects/jcchess/ – | -| :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | -| :height: 64 | | -| :width: 64 | | -+------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | https://github.com/PettingZoo-Team/PettingZoo / https://www.pettingzoo.ml/classic/chess – | -| :target: https://github.com/PettingZoo-Team/PettingZoo | A multi-agent reinforcement learning environment | -| :height: 64 | | -| :width: 64 | | -+------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info | +| :height: 64 | | +| :width: 64 | | +| :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | ++------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | https://github.com/clente/chess | +| :height: 64 | | +| :width: 64 | | +| :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | ++------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://crazyara.org/ | +| :height: 64 | | +| :width: 64 | | +| :target: https://crazyara.org/ | Deep learning for Crazyhouse | ++------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | http://johncheetham.com/projects/jcchess/ | +| :height: 64 | | +| :width: 64 | | +| :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | ++------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | https://github.com/PettingZoo-Team/PettingZoo / https://www.pettingzoo.ml/classic/chess | +| :width: 64 | | +| :height: 64 | | +| :target: https://github.com/PettingZoo-Team/PettingZoo | A multi-agent reinforcement learning environment | ++------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ * a stand-alone chess computer based on DGT board – http://www.picochess.org/ * a bridge between Lichess API and chess engines – https://github.com/careless25/lichess-bot From eb34856612fc887175017f136b2665b9bd86b850 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 20:46:20 +0100 Subject: [PATCH 1337/1831] Tweak PettingZoo entry --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 42309520d..99e142aa9 100644 --- a/README.rst +++ b/README.rst @@ -325,10 +325,10 @@ If you like, share interesting things you are doing with python-chess, for examp | :width: 64 | | | :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | https://github.com/PettingZoo-Team/PettingZoo / https://www.pettingzoo.ml/classic/chess | +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | https://www.pettingzoo.ml/classic/chess | | :width: 64 | | | :height: 64 | | -| :target: https://github.com/PettingZoo-Team/PettingZoo | A multi-agent reinforcement learning environment | +| :target: https://www.pettingzoo.ml/classic/chess | A multi-agent reinforcement learning environment | +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ * a stand-alone chess computer based on DGT board – http://www.picochess.org/ From bb6b35f37cdebc320ca1a3f2c335aa67a038720b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 14 Nov 2020 20:51:57 +0100 Subject: [PATCH 1338/1831] Tweak featured project view for mobile --- README.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 99e142aa9..d1ee38aa0 100644 --- a/README.rst +++ b/README.rst @@ -305,12 +305,12 @@ Selected projects If you like, share interesting things you are doing with python-chess, for example: +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info | +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info/ | | :height: 64 | | | :width: 64 | | | :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | https://github.com/clente/chess | +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | `clente/chess `_ | | :height: 64 | | | :width: 64 | | | :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | @@ -320,12 +320,12 @@ If you like, share interesting things you are doing with python-chess, for examp | :width: 64 | | | :target: https://crazyara.org/ | Deep learning for Crazyhouse | +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | http://johncheetham.com/projects/jcchess/ | +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | `http://johncheetham.com `_ | | :height: 64 | | | :width: 64 | | | :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | https://www.pettingzoo.ml/classic/chess | +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | `https://www.pettingzoo.ml `_ | | :width: 64 | | | :height: 64 | | | :target: https://www.pettingzoo.ml/classic/chess | A multi-agent reinforcement learning environment | From cde221f45368c21aaffac58ecf17ccb4587ac50b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 22 Nov 2020 21:54:33 +0100 Subject: [PATCH 1339/1831] Add kingOfTheHill and 3check aliases --- chess/variant.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index 73e33362c..8376b89c0 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -325,7 +325,7 @@ def status(self) -> chess.Status: class KingOfTheHillBoard(chess.Board): - aliases = ["King of the Hill", "KOTH"] + aliases = ["King of the Hill", "KOTH", "kingOfTheHill"] uci_variant = "kingofthehill" xboard_variant = "kingofthehill" # Unofficial @@ -491,7 +491,7 @@ def restore(self, board: ThreeCheckBoardT) -> None: class ThreeCheckBoard(chess.Board): - aliases = ["Three-check", "Three check", "Threecheck", "Three check chess", "3-check"] + aliases = ["Three-check", "Three check", "Threecheck", "Three check chess", "3-check", "3check"] uci_variant = "3check" xboard_variant = "3check" starting_fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 3+3 0 1" From 6322f0e27d1af53fe686fd321c11e1506d402123 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 28 Nov 2020 13:11:13 +0100 Subject: [PATCH 1340/1831] Clarify chess.engine.PlayResult.info (fixes #700) --- chess/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 182a12466..2a0bff256 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -385,7 +385,8 @@ class PlayResult: info: InfoDict """ A dictionary of extra :class:`information ` - sent by the engine. + sent by the engine, if selected with the *info* argument of + :func:`~chess.engine.Protocol.play()`. """ draw_offered: bool From 140215f51e00d9773e14a8fa33ca1d8f37058e4e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 29 Nov 2020 23:03:47 +0100 Subject: [PATCH 1341/1831] Retroactively mention #680 in changelog --- CHANGELOG.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ef76ae3a0..7a2a8c374 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -47,6 +47,10 @@ Changes: installs the package from the new location as a dependency (as recommended by `PEP423 `_). + ``ModuleNotFoundError: No module named 'chess'`` after upgrading from + previous versions? Run ``pip install --force-reinstall chess`` + (due to https://github.com/niklasf/python-chess/issues/680). + New in v1.2.0 ------------- From 2dbb07b351193a3258ae46e1f523d19e8c673280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Mon, 30 Nov 2020 10:52:55 +0100 Subject: [PATCH 1342/1831] Clarify that ebf is effective branching factor Clarified that the ebf attribute of InfoDict() is effective branching factor. Explained here: https://www.chessprogramming.org/Branching_Factor#Effective_Branching_Factor --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 2a0bff256..de5ccd6ed 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -347,7 +347,7 @@ class InfoDict(typing.TypedDict, total=False): (``1`` for the mainline). Others: ``tbhits``, ``currmove``, ``currmovenumber``, ``hashfull``, - ``cpuload``, ``refutation``, ``currline``, ``ebf``, + ``cpuload``, ``refutation``, ``currline``, ``ebf`` (effective branching factor), ``wdl`` (a :class:`~chess.engine.PovWdl`), and ``string``. """ score: PovScore From 4f1e5da29e7a54bced33db6affaacf4524771ebc Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 6 Dec 2020 12:47:12 +0100 Subject: [PATCH 1343/1831] Fix parsing of castling moves in variant 960 PGNs (fixes #705) --- chess/pgn.py | 6 ++++-- test.py | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 01b63eb9b..83a24194f 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1523,12 +1523,14 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: # Initial position. fen = headers.get("FEN", VariantBoard.starting_fen) try: - board_stack = [VariantBoard(fen, chess960=headers.is_chess960())] + board = VariantBoard(fen, chess960=headers.is_chess960()) except ValueError as error: visitor.handle_error(error) skipping_game = True else: - visitor.visit_board(board_stack[0]) + board.chess960 = board.chess960 or board.has_chess960_castling_rights() + board_stack = [board] + visitor.visit_board(board) # Fast path: Skip entire game. if skipping_game: diff --git a/test.py b/test.py index fc22dfab8..7363178c5 100755 --- a/test.py +++ b/test.py @@ -3915,6 +3915,18 @@ def test_atomic_validity(self): board = chess.variant.AtomicBoard("3N1NB1/2N1Q1N1/3RkR2/2NP1PN1/3NKN2/8/8/n7 w - - 0 1") self.assertEqual(board.status(), chess.STATUS_VALID) + def test_atomic960(self): + pgn = io.StringIO(textwrap.dedent("""\ + [Variant "Atomic"] + [FEN "rkrbbnnq/pppppppp/8/8/8/8/PPPPPPPP/RKRBBNNQ w KQkq - 0 1"] + + 1. g3 d5 2. Nf3 e5 3. Ng5 Bxg5 4. Qf3 Ne6 5. Qa3 a5 6. d4 g6 7. c3 h5 8. h4 Qh6 9. Bd2 Qxd2 10. O-O-O * + """)) + game = chess.pgn.read_game(pgn) + self.assertTrue(game.board().chess960) + self.assertEqual(game.end().parent.board().fen(), "rkr1b1n1/1pp2p2/4n1p1/p2pp2p/3P3P/Q1P3P1/PP2PP2/RK3N2 w Qkq - 0 10") + self.assertEqual(game.end().board().fen(), "rkr1b1n1/1pp2p2/4n1p1/p2pp2p/3P3P/Q1P3P1/PP2PP2/2KR1N2 b kq - 1 10") + class RacingKingsTestCase(unittest.TestCase): From cda08f229fdb43a0435d0d96d776cb8668db0d46 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 6 Dec 2020 12:59:39 +0100 Subject: [PATCH 1344/1831] Mention maia --- README.rst | 5 +++++ docs/images/maia.png | Bin 0 -> 3143 bytes 2 files changed, 5 insertions(+) create mode 100644 docs/images/maia.png diff --git a/README.rst b/README.rst index d1ee38aa0..3c70b3c54 100644 --- a/README.rst +++ b/README.rst @@ -310,6 +310,11 @@ If you like, share interesting things you are doing with python-chess, for examp | :width: 64 | | | :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/maia.png?raw=true | https://maiachess.com/ | +| :height: 64 | | +| :width: 64 | | +| :target: https://maiachess.com/ | A human-like neural network chess engine | ++------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ | .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | `clente/chess `_ | | :height: 64 | | | :width: 64 | | diff --git a/docs/images/maia.png b/docs/images/maia.png new file mode 100644 index 0000000000000000000000000000000000000000..c43c7dd31aa437aa1a941e31d058d68ce3260035 GIT binary patch literal 3143 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 literal 0 HcmV?d00001 From 5fd151defb109d9dc2f84b3b308071a22f3db0a6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 6 Dec 2020 13:11:25 +0100 Subject: [PATCH 1345/1831] Prepare 1.3.1 --- .gitignore | 2 +- CHANGELOG.rst | 9 +++++++++ README.rst | 2 +- chess/__init__.py | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7f018c159..076e4fcff 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ nosetests.xml dist/ build/ -python_chess.egg-info/ +*.egg-info/ docs/_build/ data/gaviota/*.gtb.cp4 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7a2a8c374..fca44375d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,15 @@ Changelog for python-chess ========================== +New in v1.3.1 +------------- + +Bugfixes: + +* ``chess.pgn.read_game()`` now properly detects variant games with Chess960 + castling rights (as well as mislabeled Standard Chess960 games). Previously + all castling moves in such games were rejected. + New in v1.3.0 ------------- diff --git a/README.rst b/README.rst index 3c70b3c54..9a4838c3d 100644 --- a/README.rst +++ b/README.rst @@ -302,7 +302,7 @@ Features Selected projects ----------------- -If you like, share interesting things you are doing with python-chess, for example: +If you like, share interesting things you are using python-chess for, for example: +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ | .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info/ | diff --git a/chess/__init__.py b/chess/__init__.py index 526494217..0cdb2a8db 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.3.0" +__version__ = "1.3.1" import collections import copy From 14a22afdb9aa6be4588c91311011e1ae82eee1b3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 6 Dec 2020 13:17:11 +0100 Subject: [PATCH 1346/1831] Include license via MANIFEST instead of setup.py --- MANIFEST.in | 1 + setup.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 18e068342..77ac05205 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,2 @@ include CHANGELOG.rst +include LICENSE.txt diff --git a/setup.py b/setup.py index 8d065f59b..967e7d9c9 100755 --- a/setup.py +++ b/setup.py @@ -83,7 +83,6 @@ def read_description(): long_description=read_description(), long_description_content_type="text/x-rst", license="GPL-3.0+", - license_file="LICENSE.txt", keywords="chess fen epd pgn polyglot syzygy gaviota uci xboard", url="https://github.com/niklasf/python-chess", packages=["chess"], From c5f525fcef89b809b9a904f18fa3531ac89d6df1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 7 Dec 2020 12:31:17 +0100 Subject: [PATCH 1347/1831] A comma --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fca44375d..e548e0b2e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,7 +7,7 @@ New in v1.3.1 Bugfixes: * ``chess.pgn.read_game()`` now properly detects variant games with Chess960 - castling rights (as well as mislabeled Standard Chess960 games). Previously + castling rights (as well as mislabeled Standard Chess960 games). Previously, all castling moves in such games were rejected. New in v1.3.0 From 5f61e42babb273f491087f571162b5283987df98 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 7 Dec 2020 12:46:08 +0100 Subject: [PATCH 1348/1831] Clarify find_variant() --- chess/variant.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/chess/variant.py b/chess/variant.py index 8376b89c0..863e7678e 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -867,7 +867,10 @@ def status(self) -> chess.Status: def find_variant(name: str) -> Type[chess.Board]: - """Looks for a variant board class by variant name.""" + """ + Looks for a variant board class by variant name. Supports many common + aliases. + """ for variant in VARIANTS: if any(alias.lower() == name.lower() for alias in variant.aliases): return variant From bfc727a895ba79d8ef63c8e417ccafb3c8ff9c1b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 7 Dec 2020 12:51:05 +0100 Subject: [PATCH 1349/1831] Clarify variant game end (fixes #706) --- docs/variant.rst | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/variant.rst b/docs/variant.rst index 14421fb56..0a5515873 100644 --- a/docs/variant.rst +++ b/docs/variant.rst @@ -15,10 +15,6 @@ python-chess supports several chess variants. >>> type(board).starting_fen 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w - - 0 1' -See :func:`chess.Board.is_variant_end()`, :func:`~chess.Board.is_variant_win()`, -:func:`~chess.Board.is_variant_draw()`, or :func:`~chess.Board.is_variant_loss()` -for special variant end conditions and results. - ================ ========================================= ============= ============ Variant Board class UCI/XBoard Syzygy ================ ========================================= ============= ============ @@ -36,6 +32,20 @@ Crazyhouse :class:`chess.variant.CrazyhouseBoard` crazyhouse .. autofunction:: chess.variant.find_variant +Game end +-------- + +See :func:`chess.Board.is_variant_end()`, :func:`~chess.Board.is_variant_win()`, +:func:`~chess.Board.is_variant_draw()`, +or :func:`~chess.Board.is_variant_loss()` for special variant end conditions +and results. + +Note that if all of them return ``False``, the game may still be over and +decided by standard conditions like :func:`~chess.Board.is_checkmate()`, +:func:`~chess.Board.is_stalemate()`, +:func:`~chess.Board.is_insufficient_material()`, move counters, repetitions, +and legitimate claims. + Chess960 -------- From 590e3eaea511fa7b0e31ef2decc212887f7b9f25 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 7 Dec 2020 16:24:06 +0100 Subject: [PATCH 1350/1831] Clarify chess.pgn.read_headers (#701) --- chess/pgn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 83a24194f..5b006f0e1 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1655,7 +1655,8 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: def read_headers(handle: TextIO) -> Optional[Headers]: """ - Reads game headers from a PGN file opened in text mode. + Reads game headers from a PGN file opened in text mode. Skips the rest of + the game. Since actually parsing many games from a big file is relatively expensive, this is a better way to look only for specific games and then seek and From dec8e6a95b1c255f170c300f00ea01f4e10ef3ea Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 7 Dec 2020 22:28:23 +0100 Subject: [PATCH 1351/1831] Remove unused import weakref --- chess/pgn.py | 1 - 1 file changed, 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 5b006f0e1..a5ea63549 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -21,7 +21,6 @@ import itertools import logging import re -import weakref import typing import chess From 8ca6bc38a6ec3f522284a4a80dfe17636052f603 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 8 Dec 2020 00:23:41 +0100 Subject: [PATCH 1352/1831] Allow bare except (with reraise, PyCQA/pycodestyle#703) --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 8bfa0772e..13a3dc90a 100644 --- a/tox.ini +++ b/tox.ini @@ -18,4 +18,5 @@ ignore = E741 # Allow "ambiguous" variable names W504 # Allow binary operators before EOL (end of line) E704 E301 # Allow "def overloaded(): ..." + E722 # Bare except (with or without reraise) max-line-length = 160 From 31eb8a6636f1250fe76de91cf9752e4f43d1fde5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 8 Dec 2020 12:08:51 +0100 Subject: [PATCH 1353/1831] Detect impossible checker alignment (fixes #707) --- chess/__init__.py | 43 +++++++++++++++++++++++++------------------ chess/variant.py | 1 + test.py | 8 ++++++++ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 0cdb2a8db..a41d6ee92 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -84,22 +84,24 @@ def piece_name(piece_type: PieceType) -> str: class Status(enum.IntFlag): VALID = 0 - NO_WHITE_KING = 1 - NO_BLACK_KING = 2 - TOO_MANY_KINGS = 4 - TOO_MANY_WHITE_PAWNS = 8 - TOO_MANY_BLACK_PAWNS = 16 - PAWNS_ON_BACKRANK = 32 - TOO_MANY_WHITE_PIECES = 64 - TOO_MANY_BLACK_PIECES = 128 - BAD_CASTLING_RIGHTS = 256 - INVALID_EP_SQUARE = 512 - OPPOSITE_CHECK = 1024 - EMPTY = 2048 - RACE_CHECK = 4096 - RACE_OVER = 8192 - RACE_MATERIAL = 16384 - TOO_MANY_CHECKERS = 32768 + NO_WHITE_KING = 1 << 0 + NO_BLACK_KING = 1 << 1 + TOO_MANY_KINGS = 1 << 2 + TOO_MANY_WHITE_PAWNS = 1 << 3 + TOO_MANY_BLACK_PAWNS = 1 << 4 + PAWNS_ON_BACKRANK = 1 << 5 + TOO_MANY_WHITE_PIECES = 1 << 6 + TOO_MANY_BLACK_PIECES = 1 << 7 + BAD_CASTLING_RIGHTS = 1 << 8 + INVALID_EP_SQUARE = 1 << 9 + OPPOSITE_CHECK = 1 << 10 + EMPTY = 1 << 11 + RACE_CHECK = 1 << 12 + RACE_OVER = 1 << 13 + RACE_MATERIAL = 1 << 14 + TOO_MANY_CHECKERS = 1 << 15 + IMPOSSIBLE_CHECK = 1 << 16 + STATUS_VALID = Status.VALID STATUS_NO_WHITE_KING = Status.NO_WHITE_KING @@ -118,6 +120,7 @@ class Status(enum.IntFlag): STATUS_RACE_OVER = Status.RACE_OVER STATUS_RACE_MATERIAL = Status.RACE_MATERIAL STATUS_TOO_MANY_CHECKERS = Status.TOO_MANY_CHECKERS +STATUS_IMPOSSIBLE_CHECK = Status.IMPOSSIBLE_CHECK Square = int @@ -3275,7 +3278,8 @@ def status(self) -> Status: :data:`~chess.STATUS_RACE_CHECK`, :data:`~chess.STATUS_RACE_OVER`, :data:`~chess.STATUS_RACE_MATERIAL`, - :data:`~chess.STATUS_TOO_MANY_CHECKERS`. + :data:`~chess.STATUS_TOO_MANY_CHECKERS`, + :data:`~chess.STATUS_IMPOSSIBLE_CHECK`. """ errors = STATUS_VALID @@ -3320,8 +3324,11 @@ def status(self) -> Status: errors |= STATUS_OPPOSITE_CHECK # More than the maximum number of possible checkers in the variant. - if popcount(self.checkers_mask()) > 2: + checkers = self.checkers_mask() + if popcount(checkers) > 2: errors |= STATUS_TOO_MANY_CHECKERS + elif popcount(checkers) == 2 and ray(lsb(checkers), msb(checkers)) & self.kings & ~self.promoted: + errors |= STATUS_IMPOSSIBLE_CHECK return errors diff --git a/chess/variant.py b/chess/variant.py index 863e7678e..88f002b9d 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -320,6 +320,7 @@ def status(self) -> chess.Status: status &= ~chess.STATUS_NO_BLACK_KING if chess.popcount(self.checkers_mask()) <= 14: status &= ~chess.STATUS_TOO_MANY_CHECKERS + status &= ~chess.STATUS_IMPOSSIBLE_CHECK return status diff --git a/test.py b/test.py index 7363178c5..433ca33f0 100755 --- a/test.py +++ b/test.py @@ -990,6 +990,14 @@ def test_status(self): board = chess.Board("4k3/5P2/3N4/8/8/8/4R3/4K3 b - - 0 1") self.assertEqual(board.status(), chess.STATUS_TOO_MANY_CHECKERS) + # Impossible checker alignment. + board = chess.Board("3R4/8/q4k2/2B5/1NK5/3b4/8/8 w - - 0 1") + self.assertEqual(board.status(), chess.STATUS_IMPOSSIBLE_CHECK) + board = chess.Board("2Nq4/2K5/1b6/8/7R/3k4/7P/8 w - - 0 1") + self.assertEqual(board.status(), chess.STATUS_IMPOSSIBLE_CHECK) + board = chess.Board("5R2/2P5/8/4k3/8/3rK2r/8/8 w - - 0 1") + self.assertEqual(board.status(), chess.STATUS_IMPOSSIBLE_CHECK) + def test_one_king_movegen(self): board = chess.Board.empty() board.set_piece_at(chess.A1, chess.Piece(chess.KING, chess.WHITE)) From 0bbb045a16126f99ec517f1e246ae8186835a6ca Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 12 Dec 2020 14:36:40 +0100 Subject: [PATCH 1354/1831] Prepare 1.3.2 --- CHANGELOG.rst | 11 +++++++++++ chess/__init__.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e548e0b2e..158e290ff 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,17 @@ Changelog for python-chess ========================== +New in v1.3.2 +------------- + +Bugfixes: + +* Added a new reason for ``board.status()`` to be invalid: + ``chess.STATUS_IMPOSSIBLE_CHECK``. This detects positions where two sliding + pieces are giving check while also being aligned with the king + on the same rank, file, or diagonal. Such positions are impossible to reach, + break Stockfish, and maybe other engines. + New in v1.3.1 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index a41d6ee92..cf9cf3bcf 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.3.1" +__version__ = "1.3.2" import collections import copy From e0a588d4d5cf0db67e25a0c8a91be1b11053e1e8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 14 Dec 2020 15:34:23 +0100 Subject: [PATCH 1355/1831] Avoid Piece.__hash__ collisions (fixes #711) --- chess/__init__.py | 2 +- test.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index cf9cf3bcf..e7739b212 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -435,7 +435,7 @@ def unicode_symbol(self, *, invert_color: bool = False) -> str: return UNICODE_PIECE_SYMBOLS[symbol] def __hash__(self) -> int: - return hash(self.piece_type * (self.color + 1)) + return (self.piece_type - 1) * 2 + self.color def __repr__(self) -> str: return f"Piece.from_symbol({self.symbol()!r})" diff --git a/test.py b/test.py index 433ca33f0..1c2a1929d 100755 --- a/test.py +++ b/test.py @@ -191,6 +191,12 @@ def test_from_symbol(self): self.assertEqual(black_queen.symbol(), "q") self.assertEqual(str(black_queen), "q") + def test_hash(self): + pieces = {chess.Piece.from_symbol(symbol) for symbol in "pnbrqkPNBRQK"} + self.assertEqual(len(pieces), 12) + hashes = {hash(piece) for piece in pieces} + self.assertEqual(hashes, set(range(12))) + class BoardTestCase(unittest.TestCase): From a379c96ad65046660b49d6892e4f6a1414ddda68 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 17 Dec 2020 16:01:38 +0100 Subject: [PATCH 1356/1831] Tweak icons for dark background (#713) --- docs/images/maia.png | Bin 3143 -> 18234 bytes docs/images/pettingzoo.png | Bin 3741 -> 14683 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/maia.png b/docs/images/maia.png index c43c7dd31aa437aa1a941e31d058d68ce3260035..8eaaeb1ba82d945bba1856d0184170241b371dea 100644 GIT binary patch literal 18234 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 delta 3060 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 GHRb=tEgd5O From 6c96fc3e2ee3dc71892c06f7d3701e55af25c923 Mon Sep 17 00:00:00 2001 From: Bartek Spitza <34445227+bartekspitza@users.noreply.github.com> Date: Sat, 19 Dec 2020 01:34:48 +0100 Subject: [PATCH 1357/1831] Slightly faster piece hash function --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index e7739b212..9414c978a 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -435,7 +435,7 @@ def unicode_symbol(self, *, invert_color: bool = False) -> str: return UNICODE_PIECE_SYMBOLS[symbol] def __hash__(self) -> int: - return (self.piece_type - 1) * 2 + self.color + return self.piece_type + (-1 if self.color else 5) def __repr__(self) -> str: return f"Piece.from_symbol({self.symbol()!r})" From 0890a7391ca8665d491ea88fda135b77e388bd92 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 19 Dec 2020 12:16:05 +0100 Subject: [PATCH 1358/1831] Implement Lichess winning chance model --- chess/engine.py | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index de5ccd6ed..3d696e9c1 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -43,7 +43,7 @@ try: from typing import Literal - _WdlModel = Literal["sf12"] + _WdlModel = Literal["sf12", "lichess"] except ImportError: # Before Python 3.8. _WdlModel = str # type: ignore @@ -557,8 +557,10 @@ def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: >>> Cp(500).wdl().expectation() - Cp(300).wdl().expectation() # doctest: +ELLIPSIS 0.015... - :param model: Currently, the only implemented model is ``sf12``, the - win rate model used by Stockfish 12. + :param model: + * ``sf12``, the WDL model used by Stockfish 12. + * ``lichess``, the win rate model used by Lichess. + Does not use *ply*, and does not consider drawing chances. :param ply: The number of half-moves played since the starting position. Models may scale scores slightly differently based on this. Defaults to middle game. @@ -617,6 +619,18 @@ def __ge__(self, other: object) -> bool: return NotImplemented +def _sf12_wins(cp: int, *, ply: int) -> int: + # https://github.com/official-stockfish/Stockfish/blob/sf_12/src/uci.cpp#L198-L218 + m = min(240, max(ply, 0)) / 64 + a = (((-8.24404295 * m + 64.23892342) * m + -95.73056462) * m) + 153.86478679 + b = (((-3.37154371 * m + 28.44489198) * m + -56.67657741) * m) + 72.05858751 + x = min(1000, max(cp, -1000)) + return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) + +def _lichess_winning_chance(cp: int) -> int: + return 1 / (1 + math.exp(-0.004 * cp)) + + class Cp(Score): """Centi-pawn score.""" @@ -630,19 +644,15 @@ def score(self, *, mate_score: Optional[int] = None) -> int: return self.cp def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: - wins = self._sf12_wins(ply=ply) - losses = (-self)._sf12_wins(ply=ply) + if model == "lichess": + wins = round(1000 * _lichess_winning_chance(self.cp)) + losses = 1000 - wins + else: + wins = _sf12_wins(self.cp, ply=ply) + losses = _sf12_wins(-self.cp, ply=ply) draws = 1000 - wins - losses return Wdl(wins, draws, losses) - def _sf12_wins(self, *, ply: int) -> int: - # https://github.com/official-stockfish/Stockfish/blob/sf_12/src/uci.cpp#L198-L218 - m = min(240, max(ply, 0)) / 64 - a = (((-8.24404295 * m + 64.23892342) * m + -95.73056462) * m) + 153.86478679 - b = (((-3.37154371 * m + 28.44489198) * m + -56.67657741) * m) + 72.05858751 - x = min(1000, max(self.cp, -1000)) - return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) - def __str__(self) -> str: return f"+{self.cp:d}" if self.cp > 0 else str(self.cp) @@ -681,7 +691,11 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: return -mate_score - self.moves def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: - return Wdl(1000, 0, 0) if self.moves > 0 else Wdl(0, 0, 1000) + if model == "lichess": + cp = (21 - min(10, abs(self.moves))) * 100 + return Cp(cp if self.moves > 0 else -cp).wdl(model="lichess") + else: + return Wdl(1000, 0, 0) if self.moves > 0 else Wdl(0, 0, 1000) def __str__(self) -> str: return f"#+{self.moves}" if self.moves > 0 else f"#-{abs(self.moves)}" From 622bbc4add42df85e7e578fdd923145e0e15570f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 19 Dec 2020 12:33:45 +0100 Subject: [PATCH 1359/1831] Clamp cp for Lichess WDL model --- chess/engine.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 3d696e9c1..6f92225de 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -627,7 +627,7 @@ def _sf12_wins(cp: int, *, ply: int) -> int: x = min(1000, max(cp, -1000)) return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) -def _lichess_winning_chance(cp: int) -> int: +def _lichess_raw_winning_chance(cp: int) -> int: return 1 / (1 + math.exp(-0.004 * cp)) @@ -645,7 +645,7 @@ def score(self, *, mate_score: Optional[int] = None) -> int: def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: if model == "lichess": - wins = round(1000 * _lichess_winning_chance(self.cp)) + wins = round(1000 * _lichess_raw_winning_chance(max(-1000, min(self.cp, 1000)))) losses = 1000 - wins else: wins = _sf12_wins(self.cp, ply=ply) @@ -693,7 +693,8 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: if model == "lichess": cp = (21 - min(10, abs(self.moves))) * 100 - return Cp(cp if self.moves > 0 else -cp).wdl(model="lichess") + wins = round(1000 * _lichess_raw_winning_chance(cp)) + return Wdl(wins, 0, 1000 - wins) if self.moves > 0 else Wdl(1000 - wins, 0, wins) else: return Wdl(1000, 0, 0) if self.moves > 0 else Wdl(0, 0, 1000) From 5fc5e1840d37d2fa03a70a393bf1f1bbbc653ed1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 19 Dec 2020 12:40:41 +0100 Subject: [PATCH 1360/1831] Simplify to _lichess_raw_wins --- chess/engine.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 6f92225de..b9f6619ea 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -627,8 +627,8 @@ def _sf12_wins(cp: int, *, ply: int) -> int: x = min(1000, max(cp, -1000)) return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) -def _lichess_raw_winning_chance(cp: int) -> int: - return 1 / (1 + math.exp(-0.004 * cp)) +def _lichess_raw_wins(cp: int) -> int: + return round(1000 / (1 + math.exp(-0.004 * cp))) class Cp(Score): @@ -645,7 +645,7 @@ def score(self, *, mate_score: Optional[int] = None) -> int: def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: if model == "lichess": - wins = round(1000 * _lichess_raw_winning_chance(max(-1000, min(self.cp, 1000)))) + wins = _lichess_raw_wins(max(-1000, min(self.cp, 1000))) losses = 1000 - wins else: wins = _sf12_wins(self.cp, ply=ply) @@ -693,7 +693,7 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: if model == "lichess": cp = (21 - min(10, abs(self.moves))) * 100 - wins = round(1000 * _lichess_raw_winning_chance(cp)) + wins = _lichess_raw_wins(cp) return Wdl(wins, 0, 1000 - wins) if self.moves > 0 else Wdl(1000 - wins, 0, wins) else: return Wdl(1000, 0, 0) if self.moves > 0 else Wdl(0, 0, 1000) From 2887677348c8669b5943e107ebd675c0bead968e Mon Sep 17 00:00:00 2001 From: SzymonStasiowski Date: Thu, 24 Dec 2020 00:55:25 +0100 Subject: [PATCH 1361/1831] Fix wrong declaration in Options section The snippet is not working because in following lines "engine" is called instead of declared "protocol" --- docs/engine.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/engine.rst b/docs/engine.rst index f0517c392..7637c116e 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -210,7 +210,7 @@ Option(name='Hash', type='spin', default=16, min=1, max=131072, var=[]) import chess.engine async def main() -> None: - transport, protocol = await chess.engine.popen_uci("/usr/bin/stockfish") + transport, engine = await chess.engine.popen_uci("/usr/bin/stockfish") # Check available options. print(engine.options["Hash"]) From 4ae64a70259d682c19dd522bc16f54271a3f5863 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 26 Dec 2020 11:20:23 +0100 Subject: [PATCH 1362/1831] Extend STATUS_IMPOSSIBLE_CHECK to ep square alignment See https://github.com/official-stockfish/Stockfish/issues/3270. --- chess/__init__.py | 5 ++++- test.py | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 9414c978a..e73a7d13c 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3316,7 +3316,8 @@ def status(self) -> Status: errors |= STATUS_BAD_CASTLING_RIGHTS # En passant. - if self.ep_square != self._valid_ep_square(): + valid_ep_square = self._valid_ep_square() + if self.ep_square != valid_ep_square: errors |= STATUS_INVALID_EP_SQUARE # Side to move giving check. @@ -3329,6 +3330,8 @@ def status(self) -> Status: errors |= STATUS_TOO_MANY_CHECKERS elif popcount(checkers) == 2 and ray(lsb(checkers), msb(checkers)) & self.kings & ~self.promoted: errors |= STATUS_IMPOSSIBLE_CHECK + elif valid_ep_square is not None and any(ray(checker, valid_ep_square) & self.kings & ~self.promoted for checker in scan_reversed(checkers)): + errors |= STATUS_IMPOSSIBLE_CHECK return errors diff --git a/test.py b/test.py index 1c2a1929d..367ce24eb 100755 --- a/test.py +++ b/test.py @@ -1003,6 +1003,8 @@ def test_status(self): self.assertEqual(board.status(), chess.STATUS_IMPOSSIBLE_CHECK) board = chess.Board("5R2/2P5/8/4k3/8/3rK2r/8/8 w - - 0 1") self.assertEqual(board.status(), chess.STATUS_IMPOSSIBLE_CHECK) + board = chess.Board("8/8/8/1k6/3Pp3/8/8/4KQ2 b - d3 0 1") + self.assertEqual(board.status(), chess.STATUS_IMPOSSIBLE_CHECK) def test_one_king_movegen(self): board = chess.Board.empty() From 92ece07635fcd7bc1ce2d72c08f16e262374e2bd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 26 Dec 2020 11:40:00 +0100 Subject: [PATCH 1363/1831] Fix impossible checkers considering wrong king --- chess/__init__.py | 5 +++-- test.py | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index e73a7d13c..e9f08b7ca 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3326,11 +3326,12 @@ def status(self) -> Status: # More than the maximum number of possible checkers in the variant. checkers = self.checkers_mask() + our_kings = self.kings & self.occupied_co[self.turn] & ~self.promoted if popcount(checkers) > 2: errors |= STATUS_TOO_MANY_CHECKERS - elif popcount(checkers) == 2 and ray(lsb(checkers), msb(checkers)) & self.kings & ~self.promoted: + elif popcount(checkers) == 2 and ray(lsb(checkers), msb(checkers)) & our_kings: errors |= STATUS_IMPOSSIBLE_CHECK - elif valid_ep_square is not None and any(ray(checker, valid_ep_square) & self.kings & ~self.promoted for checker in scan_reversed(checkers)): + elif valid_ep_square is not None and any(ray(checker, valid_ep_square) & our_kings for checker in scan_reversed(checkers)): errors |= STATUS_IMPOSSIBLE_CHECK return errors diff --git a/test.py b/test.py index 367ce24eb..1eb6fa4c6 100755 --- a/test.py +++ b/test.py @@ -1006,6 +1006,10 @@ def test_status(self): board = chess.Board("8/8/8/1k6/3Pp3/8/8/4KQ2 b - d3 0 1") self.assertEqual(board.status(), chess.STATUS_IMPOSSIBLE_CHECK) + # Checkers aligned with opponent king are fine. + board = chess.Board("8/8/5k2/p1q5/PP1rp1P1/3P1N2/2RK1r2/5nN1 w - - 0 3") + self.assertEqual(board.status(), chess.STATUS_VALID) + def test_one_king_movegen(self): board = chess.Board.empty() board.set_piece_at(chess.A1, chess.Piece(chess.KING, chess.WHITE)) From aae85995dba9b2e769f963e964a92b7217414ede Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 27 Dec 2020 15:04:36 +0100 Subject: [PATCH 1364/1831] Prepare 1.3.3 --- CHANGELOG.rst | 19 +++++++++++++++++++ chess/__init__.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 158e290ff..36c2d3b6e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,25 @@ Changelog for python-chess ========================== +New in v1.3.3 +------------- + +Bugfixes: + +* Fixed unintended collisions and optimized ``chess.Piece.__hash__()``. +* Fixed false-positive ``chess.STATUS_IMPOSSIBLE_CHECK`` if checkers are + aligned with other king. + +Changes: + +* Also detect ``chess.STATUS_IMPOSSIBLE_CHECK`` if checker is aligned with + en passant square and king. + +New features: + +* Implemented Lichess winning chance model for ``chess.engine.Score``: + ``score.wdl(model="lichess")``. + New in v1.3.2 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index e9f08b7ca..d9983489c 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -26,7 +26,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.3.2" +__version__ = "1.3.3" import collections import copy From 257a3a9eb7ea19f1cdfa4aafdaa24d11de761eb6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 21 Dec 2020 14:00:17 +0100 Subject: [PATCH 1365/1831] Run optipng --- docs/images/clente-chess.png | Bin 20235 -> 19313 bytes docs/images/crazyara.png | Bin 21730 -> 21425 bytes docs/images/maia.png | Bin 18234 -> 15323 bytes docs/images/pettingzoo.png | Bin 14683 -> 13204 bytes docs/images/syzygy.png | Bin 5700 -> 5603 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/clente-chess.png b/docs/images/clente-chess.png index b34430c7d146927ce741c6a058bb6ed9fc0fa459..4eb6ba16d4cf7b0c36dd75a9bb9d88b86a156a0e 100644 GIT binary patch delta 3660 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 VRnHdn!7%^;002ovPDHLkV1mE;{g(g$ diff --git a/docs/images/crazyara.png b/docs/images/crazyara.png index 62d4a8ca7d44af51356332ff9557b9683bc09367..0b1a35d29ec4291db0e8dadbfd19dfda0710a1b8 100644 GIT binary patch delta 7423 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 delta 7743 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 FV1kKDNr(Ud diff --git a/docs/images/maia.png b/docs/images/maia.png index 8eaaeb1ba82d945bba1856d0184170241b371dea..9ced0aace557c560eee7cba5a74f1d25fef3614f 100644 GIT binary patch delta 1559 zcmV+y2I%>^jse?ukQoR70001w0xklvA$v8Gt~E@500Lr5M??VshmXv^000HgNklPS->s1I!&4?047LAR+e>&k(50t zQoMMsk#w0W10tU{>vcZKEF?`@Crcm*iOAJCYkzb%LEx{d&m0<0As7VlvfiZ z*Pf?I5%6!A!tH2va#jK~AGB4aot4`78Y&Neuxu%n)c~nM7p+CrM)K{(Hm@!^Rmn(` zrBR0WVS7jy-KdQrpU?LqO|h~p)ED6_Ahnoa^rcG8@9}v2+D3rH$;L+OwtEbJ_DR^= zdQr&$oZCjkK+`{5-d|r|*SfS3AbrJVvvs&B?`R3S%w5S0;5S@SzJ`mlWT7bCX1 zN>=b-U|`@{FzW-Ikr>@Nd zf*b?7lZ5~=ZN}!`3sX=+p-@zRkf|gYSF&vsaX~dfCXYe7m;YMRNNw1Nh9}kfAlQoL zwcLaHWU&8!it%&6m&qyt|J34C?if&pHUWn3!t`y%NAWyBD2k$Hm#2yxKqZArPS;>) z9cBdpLr-|#TnJEZc6NSt)XU^Re?mSvu4MoVUq0ra$5(g@hV@0>g!J8ikQF$%2lyh9 zKNF7tkftcNw#Y8?k%BfJ#|(#HbmjoVkbYI~)&W4%Ly=D*=yJLKO;<3|br>Jy0CTl? z+b^6pYh$OoppD|0!{L~YRRKtR16)jtkk=R0Z6-J<@7y8(Z9bX>jKi*;!owl}=Nr)I z)*UG7)P)NdE-x`XK9-JuT%XNu=fG7jT|bA50opYQN0YC2pcDbP@-8HYcmsgAE#ZLt z1^~vtfZ>KHy<{yeK3`HvS*GTXWdX{|6yr;x6hK!4ws?yH$&)6Nsn*HJ#~l&hTfN!g zI#V|)?ACc5Aax!%lPn&tgL~Tc*!07-Pc8KUNpi6XwX?-3DB*B_IL0cBl+mv>xe=M$ zOk*cboG3F~FI51n+F-b)6*{rYXf&GdGIa3$wfU{N;W}v<(!Q^q<8{Ht~BeetcKsJzv`Y?8Z_#o2fTTJ(X^2c_ya*mdPSz@qzy zt*?RQ+p%aK5Fh#}M#_ET3b`;klGDWUy8zyP^lYI-p7Q{tkqqFEL}huKfZg}Yyjbor z0d@`A0I>T|XGMKrgw$H@#i4c!VAmi9@do-)fRD`o|9kUa{0}2q(WqE3pB(@I002ov JPDHLkV1gqn{yYEx delta 4491 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 diff --git a/docs/images/syzygy.png b/docs/images/syzygy.png index 324bed762dc834f616d4d6dfb0371cda0d1c42fc..ab189833eadc10811502b1453febf18b79b1db46 100644 GIT binary patch delta 146 zcmX@2^H_U=1Sb+k85zsV%m4rX|M<-GJP<$0 z+uem(kjLi}kYn%Z;uvCaIypfiupwKNYtcjo=EJL4H9FLoVpazn5D@?IpPRFGK`+Dq w|DmrZUSNviT+qPp9Ld1t#C+kCUEaktaqI2v zgItFdco;5N{5t=O^VijPCK`v=9uN9lq&4ZXvee~ELW0IZ$F(Q11C4`&qGKN`S8UZ2 zJ|=Pc>+z6-Ww~+e=6I|2D$2+`U?A5;>o!x)Voco3+ zNXDYPG1mWg{7)^gsz+a96VAoh_e}{3f$L&m*nEJu{KNYl* Date: Fri, 1 Jan 2021 18:48:08 +0100 Subject: [PATCH 1366/1831] Add chess.pgn.GameNode.set_eval(..., depth) and eval_depth() (closes #718) --- chess/pgn.py | 19 +++++++++++++++---- test.py | 8 +++++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index a5ea63549..a1efe21cb 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -126,7 +126,9 @@ \[%eval\s(?: \#([+-]?\d+) |([+-]?(?:\d{0,10}\.\d{1,2}|\d{1,10}\.?)) - )\] + )(?: + ,(\d+) + )?\] """, re.VERBOSE) ARROWS_REGEX = re.compile(r""" @@ -409,18 +411,27 @@ def eval(self) -> Optional[chess.engine.PovScore]: return chess.engine.PovScore(score if turn else -score, turn) - def set_eval(self, score: Optional[chess.engine.PovScore]) -> None: + def eval_depth(self) -> Optional[int]: + """ + Parses the first valid ``[%eval ...]`` annotation in the comment of + this node and returns the corresponding depth, if any. + """ + match = EVAL_REGEX.search(self.comment) + return int(match.group(3)) if match and match.group(3) else None + + def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] = None) -> None: """ Replaces the first valid ``[%eval ...]`` annotation in the comment of this node or adds a new one. """ eval = "" if score is not None: + depth_suffix = "" if depth is None else f",{max(depth, 0):d}" cp = score.white().score() if cp is not None: - eval = f"[%eval {float(cp) / 100:.2f}]" + eval = f"[%eval {float(cp) / 100:.2f}{depth_suffix}]" elif score.white().mate(): - eval = f"[%eval #{score.white().mate()}]" + eval = f"[%eval #{score.white().mate()}{depth_suffix}]" self.comment, found = EVAL_REGEX.subn(eval, self.comment, count=1) diff --git a/test.py b/test.py index 1eb6fa4c6..7bb956a2c 100755 --- a/test.py +++ b/test.py @@ -2720,13 +2720,15 @@ def test_annotations(self): game.set_eval(chess.engine.PovScore(chess.engine.Cp(-80), chess.WHITE)) self.assertEqual(game.comment, "foo [%bar] baz [%clk 3:25:45] [%eval -0.80]") self.assertEqual(game.eval().white().score(), -80) - game.set_eval(chess.engine.PovScore(chess.engine.Mate(1), chess.WHITE)) - self.assertEqual(game.comment, "foo [%bar] baz [%clk 3:25:45] [%eval #1]") + self.assertEqual(game.eval_depth(), None) + game.set_eval(chess.engine.PovScore(chess.engine.Mate(1), chess.WHITE), 5) + self.assertEqual(game.comment, "foo [%bar] baz [%clk 3:25:45] [%eval #1,5]") self.assertEqual(game.eval().white().mate(), 1) + self.assertEqual(game.eval_depth(), 5) self.assertEqual(game.arrows(), []) game.set_arrows([(chess.A1, chess.A1), chess.svg.Arrow(chess.A1, chess.H1, color="red"), chess.svg.Arrow(chess.B1, chess.B8)]) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1]") + self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5]") arrows = game.arrows() self.assertEqual(len(arrows), 3) self.assertEqual(arrows[0].color, "green") From a635307deacbaed19bdf5b5b1e253fd9a05a707e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 2 Jan 2021 11:59:21 +0100 Subject: [PATCH 1367/1831] Remove ModuleNotFoundError from README (kept in CHANGELOG) --- README.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.rst b/README.rst index 9a4838c3d..ee0ed6692 100644 --- a/README.rst +++ b/README.rst @@ -65,10 +65,6 @@ Download and install the latest release: pip install chess -``ModuleNotFoundError: No module named 'chess'`` after upgrading from old -python-chess versions? ``pip install --force-reinstall chess`` -(due to `#680 `_) - `Documentation `__ -------------------------------------------------------------------- From 3257cf5096885452f35f4ea12d90c78be79a7be5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 2 Jan 2021 19:27:19 +0100 Subject: [PATCH 1368/1831] Handle UCI lines with invalid UTF-8 (#726) --- chess/engine.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index b9f6619ea..2a02c7cac 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -988,11 +988,15 @@ def pipe_data_received(self, fd: int, data: Union[bytes, str]) -> None: line_bytes, self.buffer[fd] = self.buffer[fd].split(b"\n", 1) if line_bytes.endswith(b"\r"): line_bytes = line_bytes[:-1] - line = line_bytes.decode("utf-8") - if fd == 1: - self.loop.call_soon(self._line_received, line) + try: + line = line_bytes.decode("utf-8") + except UnicodeDecodeError as err: + LOGGER.warning("%s: >> %r (%s)", self, bytes(line_bytes), err) else: - self.loop.call_soon(self.error_line_received, line) + if fd == 1: + self.loop.call_soon(self._line_received, line) + else: + self.loop.call_soon(self.error_line_received, line) def error_line_received(self, line: str) -> None: LOGGER.warning("%s: stderr >> %s", self, line) From 52797d333901b2920bb336181573c10bcbd0c7c4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 2 Jan 2021 21:20:40 +0100 Subject: [PATCH 1369/1831] Use asyncio.*events*.get_running_loop() for trio-asyncio/issues#83 (fixes #725) --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 2a02c7cac..5109bfd8f 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -936,7 +936,7 @@ class Protocol(asyncio.SubprocessProtocol, metaclass=abc.ABCMeta): """Future: Exit code of the process.""" def __init__(self: ProtocolT) -> None: - self.loop = asyncio.get_running_loop() + self.loop = asyncio.events.get_running_loop() self.transport: Optional[asyncio.SubprocessTransport] = None self.buffer = { @@ -1195,7 +1195,7 @@ async def popen(cls: Type[ProtocolT], command: Union[str, List[str]], *, setpgrp popen_args["preexec_fn"] = os.setpgrp popen_args.update(kwargs) - return await asyncio.get_running_loop().subprocess_exec(cls, *command, **popen_args) # type: ignore + return await asyncio.events.get_running_loop().subprocess_exec(cls, *command, **popen_args) # type: ignore class CommandState(enum.Enum): From ba995cb1d0f5277dafc0a9e9423a5ffcec49e687 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 5 Jan 2021 22:40:54 +0100 Subject: [PATCH 1370/1831] Preemptively stop emphasizing "pure Python" (#722) --- README.rst | 8 ++++---- chess/__init__.py | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index ee0ed6692..297e9048c 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -python-chess: a pure Python chess library -========================================= +python-chess: a chess library for Python +======================================== .. image:: https://github.com/niklasf/python-chess/workflows/Test/badge.svg :target: https://github.com/niklasf/python-chess/actions @@ -20,8 +20,8 @@ python-chess: a pure Python chess library Introduction ------------ -python-chess is a pure Python chess library with move generation, move -validation and support for common formats. This is the Scholar's mate in +python-chess is a chess library for Python, with move generation, +move validation, and support for common formats. This is the Scholar's mate in python-chess: .. code:: python diff --git a/chess/__init__.py b/chess/__init__.py index d9983489c..7e0308677 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -15,9 +15,10 @@ # along with this program. If not, see . """ -A pure Python chess library with move generation and validation, Polyglot -opening book probing, PGN reading and writing, Gaviota tablebase probing, -Syzygy tablebase probing and XBoard/UCI engine communication. +A chess library with move generation and validation, +Polyglot opening book probing, PGN reading and writing, +Gaviota tablebase probing, +Syzygy tablebase probing, and XBoard/UCI engine communication. """ from __future__ import annotations From f4eaa3d4f3626bae2fa295f8cbee6448ec76aef4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 6 Jan 2021 20:11:55 +0100 Subject: [PATCH 1371/1831] Clarify comment regarding analysis timeout (fixes #728) --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 5109bfd8f..99ee94a31 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2706,7 +2706,7 @@ def analysis(self, board: chess.Board, limit: Optional[Limit] = None, *, multipv with self._not_shut_down(): coro = asyncio.wait_for( self.protocol.analysis(board, limit, multipv=multipv, game=game, info=info, root_moves=root_moves, options=options), - self.timeout) # Analyis should start immediately + self.timeout) # Timeout until analysis is *started* future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return SimpleAnalysisResult(self, future.result()) From 5426ba58368633310fc6bd99bfa2042f9baa83c7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Jan 2021 12:25:41 +0100 Subject: [PATCH 1372/1831] Bump 2021 (closes #730) --- chess/__init__.py | 2 +- chess/engine.py | 2 +- chess/gaviota.py | 2 +- chess/pgn.py | 2 +- chess/polyglot.py | 2 +- chess/svg.py | 2 +- chess/syzygy.py | 2 +- chess/variant.py | 2 +- docs/conf.py | 2 +- setup.py | 2 +- test.py | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 7e0308677..e17ce1e04 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1,5 +1,5 @@ # This file is part of the python-chess library. -# Copyright (C) 2012-2020 Niklas Fiekas +# Copyright (C) 2012-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/chess/engine.py b/chess/engine.py index 99ee94a31..7eb0b70fc 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1,5 +1,5 @@ # This file is part of the python-chess library. -# Copyright (C) 2012-2020 Niklas Fiekas +# Copyright (C) 2012-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/chess/gaviota.py b/chess/gaviota.py index ff64f5957..360cc7120 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1,6 +1,6 @@ # This file is part of the python-chess library. # Copyright (C) 2015 Jean-Noël Avila -# Copyright (C) 2015-2020 Niklas Fiekas +# Copyright (C) 2015-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/chess/pgn.py b/chess/pgn.py index a1efe21cb..9c6b4f311 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1,5 +1,5 @@ # This file is part of the python-chess library. -# Copyright (C) 2012-2020 Niklas Fiekas +# Copyright (C) 2012-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/chess/polyglot.py b/chess/polyglot.py index eaec7b631..1562d5306 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -1,5 +1,5 @@ # This file is part of the python-chess library. -# Copyright (C) 2012-2020 Niklas Fiekas +# Copyright (C) 2012-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/chess/svg.py b/chess/svg.py index 42b939c67..df69c5588 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -1,5 +1,5 @@ # This file is part of the python-chess library. -# Copyright (C) 2016-2020 Niklas Fiekas +# Copyright (C) 2016-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/chess/syzygy.py b/chess/syzygy.py index 4f8a30813..8fe3df6a1 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1,5 +1,5 @@ # This file is part of the python-chess library. -# Copyright (C) 2012-2020 Niklas Fiekas +# Copyright (C) 2012-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/chess/variant.py b/chess/variant.py index 88f002b9d..23de858e8 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -1,5 +1,5 @@ # This file is part of the python-chess library. -# Copyright (C) 2016-2020 Niklas Fiekas +# Copyright (C) 2016-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/docs/conf.py b/docs/conf.py index bf1f19db7..e3fe4f737 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -37,7 +37,7 @@ def get_type_hints(obj, globalns=None, localns=None): # General information about the project. project = "python-chess" -copyright = "2014–2020, Niklas Fiekas" +copyright = "2014–2021, Niklas Fiekas" # The version. version = chess.__version__ diff --git a/setup.py b/setup.py index 967e7d9c9..1bf8a4b7d 100755 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # # This file is part of the python-chess library. -# Copyright (C) 2012-2020 Niklas Fiekas +# Copyright (C) 2012-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/test.py b/test.py index 7bb956a2c..5d8ae213d 100755 --- a/test.py +++ b/test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # # This file is part of the python-chess library. -# Copyright (C) 2012-2020 Niklas Fiekas +# Copyright (C) 2012-2021 Niklas Fiekas # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by From 10538325e6f7330d229c7218ffdbca805a47abb3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 8 Jan 2021 13:16:01 +0100 Subject: [PATCH 1373/1831] Revert "Use asyncio.*events*.get_running_loop() for trio-asyncio/issues#83 (fixes #725)" This reverts commit 52797d333901b2920bb336181573c10bcbd0c7c4. The issue is fixed in trio-asyncio v0.12.0 via python-trio/trio-asyncio@b93c32037804298b43cc8c089313a2ef82ca0c22, so the workaround is no longer required. --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 7eb0b70fc..3a145135d 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -936,7 +936,7 @@ class Protocol(asyncio.SubprocessProtocol, metaclass=abc.ABCMeta): """Future: Exit code of the process.""" def __init__(self: ProtocolT) -> None: - self.loop = asyncio.events.get_running_loop() + self.loop = asyncio.get_running_loop() self.transport: Optional[asyncio.SubprocessTransport] = None self.buffer = { @@ -1195,7 +1195,7 @@ async def popen(cls: Type[ProtocolT], command: Union[str, List[str]], *, setpgrp popen_args["preexec_fn"] = os.setpgrp popen_args.update(kwargs) - return await asyncio.events.get_running_loop().subprocess_exec(cls, *command, **popen_args) # type: ignore + return await asyncio.get_running_loop().subprocess_exec(cls, *command, **popen_args) # type: ignore class CommandState(enum.Enum): From e1c1355e141593912ff2c144ae5ea22034c790f5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Jan 2021 18:17:30 +0100 Subject: [PATCH 1374/1831] Read and write millisecond %clk annotations (closes #727) --- chess/pgn.py | 13 +++++++------ test.py | 13 ++++++++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 9c6b4f311..436472d15 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -120,7 +120,7 @@ SKIP_MOVETEXT_REGEX = re.compile(r""";|\{|\}""") -CLOCK_REGEX = re.compile(r"""\[%clk\s(\d+):(\d+):(\d+)\]""") +CLOCK_REGEX = re.compile(r"""\[%clk\s(\d+):(\d+):(\d+(?:\.\d*)?)\]""") EVAL_REGEX = re.compile(r""" \[%eval\s(?: @@ -492,7 +492,7 @@ def clock(self) -> Optional[float]: match = CLOCK_REGEX.search(self.comment) if match is None: return None - return int(match.group(1)) * 3600 + int(match.group(2)) * 60 + int(match.group(3)) + return int(match.group(1)) * 3600 + int(match.group(2)) * 60 + float(match.group(3)) def set_clock(self, seconds: Optional[float]) -> None: """ @@ -501,11 +501,12 @@ def set_clock(self, seconds: Optional[float]) -> None: """ clk = "" if seconds is not None: - seconds = max(0, round(seconds)) - hours = seconds // 3600 - minutes = seconds % 3600 // 60 + seconds = max(0, seconds) + hours = int(seconds // 3600) + minutes = int(seconds % 3600 // 60) seconds = seconds % 3600 % 60 - clk = f"[%clk {hours:d}:{minutes:02d}:{seconds:02d}]" + seconds_part = f"{seconds:06.3f}".rstrip("0").rstrip(".") + clk = f"[%clk {hours:d}:{minutes:02d}:{seconds_part}]" self.comment, found = CLOCK_REGEX.subn(clk, self.comment, count=1) diff --git a/test.py b/test.py index 5d8ae213d..230c7b0a1 100755 --- a/test.py +++ b/test.py @@ -2740,11 +2740,18 @@ def test_annotations(self): game.set_arrows([]) self.assertEqual(game.comment, "foo [%bar] baz") - game.set_clock(1.4) - self.assertEqual(game.clock(), 1) # Rounded + def test_float_clk(self): + game = chess.pgn.Game() + game.comment = "[%clk 0:00:01.234]" + self.assertEqual(game.clock(), 1.234) + + game.set_clock(6.54321) + self.assertEqual(game.comment, "[%clk 0:00:06.543]") + self.assertEqual(game.clock(), 6.543) game.set_clock(-70) - self.assertEqual(game.clock(), 0) # Clamped + self.assertEqual(game.comment, "[%clk 0:00:00]") # Clamped + self.assertEqual(game.clock(), 0) def test_node_turn(self): game = chess.pgn.Game() From b3dd0ea28d78e4165ea9edaf6b7cbbc996c714a7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 17 Jan 2021 15:39:19 +0100 Subject: [PATCH 1375/1831] Test king captures unmoved rook --- test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test.py b/test.py index 230c7b0a1..5ba984955 100755 --- a/test.py +++ b/test.py @@ -1667,6 +1667,14 @@ def test_is_irreversible(self): self.assertFalse(board.is_irreversible(board.parse_san("Rf1"))) self.assertFalse(board.is_irreversible(chess.Move.null())) + def test_king_captures_unmoved_rook(self): + board = chess.Board("8/8/8/B2p3Q/2qPp1P1/b7/2P2PkP/4K2R b K - 0 1") + move = board.parse_uci("g2h1") + self.assertFalse(board.is_castling(move)) + self.assertEqual(board.san(move), "Kxh1") + board.push(move) + self.assertEqual(board.fen(), "8/8/8/B2p3Q/2qPp1P1/b7/2P2P1P/4K2k w - - 0 2") + class LegalMoveGeneratorTestCase(unittest.TestCase): From 9eb6f52f2a9d3aea133c9f38fd171d1b6b9696cf Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 19 Jan 2021 20:34:42 +0100 Subject: [PATCH 1376/1831] Prepare changelog --- CHANGELOG.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 36c2d3b6e..38c35404e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,23 @@ Changelog for python-chess ========================== +Upcoming in v1.3.4 +------------------ + +Bugfixes: + +* Recover from invalid UTF-8 sent by an UCI engine, by ignoring that + (and only that) line. + +New features: + +* Let ``chess.pgn.GameNode.eval()`` accept PGN comments like + ``[%eval 2.5,11]``, meaning 250 centipawns at depth 11. + Use ``chess.pgn.GameNode.eval_depth()`` and + ``chess.pgn.GameNode.set_eval(..., depth)`` to get and set the depth. +* Read and write PGN comments with millisecond precision + ``[%clk 1:23:45.678]``. + New in v1.3.3 ------------- From c06e8d3b443c7e34e75742f08c972ee654394be3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 25 Jan 2021 13:19:16 +0100 Subject: [PATCH 1377/1831] Prepare 1.4.0 --- CHANGELOG.rst | 16 ++++++++-------- chess/__init__.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 38c35404e..24d945021 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,13 +1,8 @@ Changelog for python-chess ========================== -Upcoming in v1.3.4 ------------------- - -Bugfixes: - -* Recover from invalid UTF-8 sent by an UCI engine, by ignoring that - (and only that) line. +New in v1.4.0 +------------- New features: @@ -15,9 +10,14 @@ New features: ``[%eval 2.5,11]``, meaning 250 centipawns at depth 11. Use ``chess.pgn.GameNode.eval_depth()`` and ``chess.pgn.GameNode.set_eval(..., depth)`` to get and set the depth. -* Read and write PGN comments with millisecond precision +* Read and write PGN comments with millisecond precision like ``[%clk 1:23:45.678]``. +Changes: + +* Recover from invalid UTF-8 sent by an UCI engine, by ignoring that + (and only that) line. + New in v1.3.3 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index e17ce1e04..925b26751 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.3.3" +__version__ = "1.4.0" import collections import copy From a40f2e84139dd90c0cc9207c72f9b36f5454430b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Feb 2021 18:46:23 +0100 Subject: [PATCH 1378/1831] Prevent cancelling engine command multiple times (#732) --- chess/engine.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 3a145135d..1dc93961d 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1242,9 +1242,10 @@ def set_finished(self) -> None: self.finished.set_result(None) def _cancel(self, engine: ProtocolT) -> None: - assert self.state == CommandState.Active - self.state = CommandState.Cancelling - self.cancel(engine) + if self.state != CommandState.Cancelling: + assert self.state == CommandState.Active + self.state = CommandState.Cancelling + self.cancel(engine) def _start(self, engine: ProtocolT) -> None: assert self.state == CommandState.New From 07a08545c37be5638926b5c6f84d171209bcf202 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 13 Feb 2021 14:17:45 -0800 Subject: [PATCH 1379/1831] Implement Xboard usermove feature --- chess/engine.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 1dc93961d..5eccdefd1 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1915,9 +1915,6 @@ def end(self, engine: XBoardProtocol) -> None: if not engine.features.get("sigterm", 1): LOGGER.warning("%s: Rejecting feature sigterm=0", engine) engine.send_line("rejected sigterm") - if engine.features.get("usermove", 0): - LOGGER.warning("%s: Rejecting feature usermove=1", engine) - engine.send_line("rejected usermove") if engine.features.get("san", 0): LOGGER.warning("%s: Rejecting feature san=1", engine) engine.send_line("rejected san") @@ -2012,7 +2009,8 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None for move in board.move_stack[common_stack_len:]: if not move: LOGGER.warning("Null move (in %s) may not be supported by all XBoard engines", self.board.fen()) - self.send_line(self.board.xboard(move)) + prefix = "usermove " if self.features.get("usermove", 0) else "" + self.send_line(prefix + self.board.xboard(move)) self.board.push(move) async def ping(self) -> None: From aa361fd8368a9db0abbcfa176e6ffdadb7982d3a Mon Sep 17 00:00:00 2001 From: salman69e27 Date: Fri, 19 Feb 2021 09:44:04 +0200 Subject: [PATCH 1380/1831] implement basic interactive viewer --- chess/interactive.py | 109 +++++++++++++++++++++++++++++++++++++++++++ chess/pgn.py | 4 ++ 2 files changed, 113 insertions(+) create mode 100644 chess/interactive.py diff --git a/chess/interactive.py b/chess/interactive.py new file mode 100644 index 000000000..fe706be62 --- /dev/null +++ b/chess/interactive.py @@ -0,0 +1,109 @@ +import chess.svg + + +class WidgetError(Exception): + """ + raised when ipywidgets is not installed + """ + + +class NotJupyter(Exception): + """ + raised when InteractiveViewer is instantiated from a non jupyter shell + """ + + +try: + from ipywidgets import Button, GridBox, Layout, HTML, Output + from IPython.display import display, clear_output +except ModuleNotFoundError: + raise WidgetError("You need to have ipywidgets installed and running from Jupyter") + + +class InteractiveViewer: + def __new__(cls, game): + jupyter = True + try: + if get_ipython().__class__.__name__ != "ZMQInteractiveShell": + jupyter = False + except NameError: + jupyter = False + + if not jupyter: + raise NotJupyter("The interactive viewer only runs in jupyter shell") + return object.__new__(cls) + + def __init__(self, game): + self.game = game + self.__board = game.board() + self.__moves = list(game.mainline_moves()) + self.__num_moves = len(self.__moves) + self.__next_move = 0 if self.__moves else None + self.__out = Output() + + def __next_click(self, _): + move = self.__moves[self.__next_move] + self.__next_move += 1 + self.__board.push(move) + self.show() + + def __prev_click(self, _): + self.__board.pop() + self.__next_move -= 1 + self.show() + + def __reset_click(self, _): + self.__board.reset() + self.__next_move = 0 + self.show() + + def show(self): + display(self.__out) + next_move = Button( + icon="step-forward", + layout=Layout(width="60px", grid_area="right"), + disabled=self.__next_move >= self.__num_moves, + ) + + prev_move = Button( + icon="step-backward", + layout=Layout(width="60px", grid_area="left"), + disabled=self.__next_move == 0, + ) + + reset = Button( + icon="stop", + layout=Layout(width="60px", grid_area="middle"), + disabled=self.__next_move == 0, + ) + next_move.on_click(self.__next_click) + prev_move.on_click(self.__prev_click) + reset.on_click(self.__reset_click) + + with self.__out: + grid_box = GridBox( + children=[next_move, prev_move, reset, self.svg], + layout=Layout( + width="395px", + grid_template_rows="90% 10%", + grid_template_areas=""" + "top top top top top" + ". left middle right ." + """, + ), + ) + clear_output() + display(grid_box) + + @property + def svg(self) -> HTML: + svg = chess.svg.board( + board=self.__board, + size=390, + lastmove=self.__board.peek() if self.__board.move_stack else None, + check=self.__board.king(self.__board.turn) + if self.__board.is_check() + else None, + ) + svg_widget = HTML(value=svg, layout=Layout(grid_area="top")) + return svg_widget diff --git a/chess/pgn.py b/chess/pgn.py index 436472d15..f6e00e7f0 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -738,6 +738,10 @@ def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str def board(self) -> chess.Board: return self.headers.board() + def interactive_viewer(self): + from chess.interactive import InteractiveViewer + return InteractiveViewer(self) + def ply(self) -> int: # Optimization: Parse FEN only for custom starting positions. return self.board().ply() if "FEN" in self.headers else 0 From 874dc9bb3cc72bf1fad8c4462f0ecce7dde507fe Mon Sep 17 00:00:00 2001 From: salman69e27 Date: Fri, 19 Feb 2021 12:32:19 +0200 Subject: [PATCH 1381/1831] move list in interactive viewer --- chess/interactive.py | 90 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 6 deletions(-) diff --git a/chess/interactive.py b/chess/interactive.py index fe706be62..efc413358 100644 --- a/chess/interactive.py +++ b/chess/interactive.py @@ -14,7 +14,7 @@ class NotJupyter(Exception): try: - from ipywidgets import Button, GridBox, Layout, HTML, Output + from ipywidgets import Button, GridBox, Layout, HTML, Output, HBox, Select from IPython.display import display, clear_output except ModuleNotFoundError: raise WidgetError("You need to have ipywidgets installed and running from Jupyter") @@ -30,13 +30,17 @@ def __new__(cls, game): jupyter = False if not jupyter: - raise NotJupyter("The interactive viewer only runs in jupyter shell") + raise NotJupyter("The interactive viewer only runs in Jupyter shell") + return object.__new__(cls) def __init__(self, game): self.game = game self.__board = game.board() self.__moves = list(game.mainline_moves()) + self.__white_moves = [str(move) for (i, move) in enumerate(self.__moves) if i % 2 == 0] + self.__black_moves = [str(move) for (i, move) in enumerate(self.__moves) if i % 2 == 1] + self.__move_list_len = len(self.__white_moves) self.__num_moves = len(self.__moves) self.__next_move = 0 if self.__moves else None self.__out = Output() @@ -57,6 +61,30 @@ def __reset_click(self, _): self.__next_move = 0 self.show() + def __white_select_change(self, change): + new = change["new"] + if (isinstance(new, dict)) and ("index" in new): + target = new["index"] * 2 + self.__seek(target) + self.show() + + def __black_select_change(self, change): + new = change["new"] + if (isinstance(new, dict)) and ("index" in new): + target = new["index"] * 2 + 1 + self.__seek(target) + self.show() + + def __seek(self, target): + while self.__next_move <= target: + move = self.__moves[self.__next_move] + self.__next_move += 1 + self.__board.push(move) + + while self.__next_move > target + 1: + self.__board.pop() + self.__next_move -= 1 + def show(self): display(self.__out) next_move = Button( @@ -76,19 +104,69 @@ def show(self): layout=Layout(width="60px", grid_area="middle"), disabled=self.__next_move == 0, ) + + if self.__next_move == 0: + white_move = None + black_move = None + else: + white_move = ( + self.__white_moves[self.__next_move // 2] + if (self.__next_move % 2) == 1 + else None + ) + black_move = ( + self.__black_moves[self.__next_move // 2 - 1] + if (self.__next_move % 2) == 0 + else None + ) + + white_move_list = Select( + options=self.__white_moves, + value=white_move, + rows=max(self.__move_list_len, 24), + disabled=False, + layout=Layout(width="80px"), + ) + + black_move_list = Select( + options=self.__black_moves, + value=black_move, + rows=max(self.__move_list_len, 24), + disabled=False, + layout=Layout(width="80px"), + ) + + white_move_list.observe(self.__white_select_change) + black_move_list.observe(self.__black_select_change) + + move_number_width = 3 + len(str(self.__move_list_len)) * 10 + + move_number = Select( + options=range(1, self.__move_list_len + 1), + value=None, + disabled=True, + rows=max(self.__move_list_len, 24), + layout=Layout(width=f"{move_number_width}px"), + ) + + move_list = HBox( + [move_number, white_move_list, black_move_list], + layout=Layout(height="407px", grid_area="moves"), + ) + next_move.on_click(self.__next_click) prev_move.on_click(self.__prev_click) reset.on_click(self.__reset_click) with self.__out: grid_box = GridBox( - children=[next_move, prev_move, reset, self.svg], + children=[next_move, prev_move, reset, self.svg, move_list], layout=Layout( - width="395px", + width=f"{390+move_number_width+160}px", grid_template_rows="90% 10%", grid_template_areas=""" - "top top top top top" - ". left middle right ." + "top top top top top moves" + ". left middle right . moves" """, ), ) From 86c435058b5c765129901ae11c20c43b4f4cff97 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 20 Feb 2021 13:27:27 +0100 Subject: [PATCH 1382/1831] Update chess/interactive.py Wait to clear the area until the next display is made (reduces flicker) Co-authored-by: Doug Blank --- chess/interactive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/interactive.py b/chess/interactive.py index efc413358..a834f4476 100644 --- a/chess/interactive.py +++ b/chess/interactive.py @@ -170,7 +170,7 @@ def show(self): """, ), ) - clear_output() + clear_output(wait=True) display(grid_box) @property From 7c08b2d1c6d57a4d845008e70ec4cb0b7005f899 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 20 Feb 2021 13:36:22 +0100 Subject: [PATCH 1383/1831] Postpone typing of new interactive module --- chess/interactive.py | 3 +++ chess/pgn.py | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/chess/interactive.py b/chess/interactive.py index a834f4476..edeef3df0 100644 --- a/chess/interactive.py +++ b/chess/interactive.py @@ -1,3 +1,6 @@ +# TODO: Fix typing in this file. +# mypy: ignore-errors + import chess.svg diff --git a/chess/pgn.py b/chess/pgn.py index f6e00e7f0..0f449879e 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -738,9 +738,10 @@ def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str def board(self) -> chess.Board: return self.headers.board() - def interactive_viewer(self): + # TODO: Consider naming. + def interactive_viewer(self) -> Any: from chess.interactive import InteractiveViewer - return InteractiveViewer(self) + return InteractiveViewer(self) # type: ignore def ply(self) -> int: # Optimization: Parse FEN only for custom starting positions. From 1b21b80fb9b574085c245e1261b103cfa5cdcf6f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 26 Feb 2021 13:13:31 +0100 Subject: [PATCH 1384/1831] Make interactive viewer private for now --- chess/{interactive.py => _interactive.py} | 0 chess/pgn.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename chess/{interactive.py => _interactive.py} (100%) diff --git a/chess/interactive.py b/chess/_interactive.py similarity index 100% rename from chess/interactive.py rename to chess/_interactive.py diff --git a/chess/pgn.py b/chess/pgn.py index 0f449879e..0be971c64 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -739,8 +739,8 @@ def board(self) -> chess.Board: return self.headers.board() # TODO: Consider naming. - def interactive_viewer(self) -> Any: - from chess.interactive import InteractiveViewer + def _interactive_viewer(self) -> Any: + from chess._interactive import InteractiveViewer return InteractiveViewer(self) # type: ignore def ply(self) -> int: From e5ea16f751bd59ac38ccc4e9e685ba5f827aa5cd Mon Sep 17 00:00:00 2001 From: Paul Philippov Date: Sun, 7 Mar 2021 18:59:59 -0500 Subject: [PATCH 1385/1831] Add animation of the last move. --- chess/svg.py | 54 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index df69c5588..12fdf5253 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -233,6 +233,7 @@ def piece(piece: chess.Piece, size: Optional[int] = None) -> str: def board(board: Optional[chess.BaseBoard] = None, *, orientation: Color = chess.WHITE, lastmove: Optional[chess.Move] = None, + animation: bool = False, check: Optional[Square] = None, arrows: Iterable[Union[Arrow, Tuple[Square, Square]]] = [], squares: Optional[IntoSquareSet] = None, @@ -248,6 +249,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, ``None`` (the default) for a chessboard without pieces. :param orientation: The point of view, defaulting to ``chess.WHITE``. :param lastmove: A :class:`chess.Move` to be highlighted. + :param animation: Pass ``True`` to animate lastmove. :param check: A square to be marked indicating a check. :param arrows: A list of :class:`~chess.svg.Arrow` objects, like ``[chess.svg.Arrow(chess.E2, chess.E4)]``, or a list of tuples, like @@ -299,6 +301,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, if check is not None: defs.append(ET.fromstring(CHECK_GRADIENT)) + # Render coordinates. if coordinates: margin_color, margin_opacity = _color(colors, "margin") ET.SubElement(svg, "rect", _attrs({ @@ -309,7 +312,17 @@ def board(board: Optional[chess.BaseBoard] = None, *, "fill": margin_color, "opacity": margin_opacity if margin_opacity < 1.0 else None, })) + coord_color, coord_opacity = _color(colors, "coord") + for file_index, file_name in enumerate(chess.FILE_NAMES): + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin + svg.append(_coord(file_name, x, 0, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) + svg.append(_coord(file_name, x, margin + 8 * SQUARE_SIZE, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) + for rank_index, rank_name in enumerate(chess.RANK_NAMES): + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin + svg.append(_coord(rank_name, 0, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) + svg.append(_coord(rank_name, margin + 8 * SQUARE_SIZE, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) + # Render board. for square, bb in enumerate(chess.BB_SQUARES): file_index = chess.square_file(square) rank_index = chess.square_rank(square) @@ -335,6 +348,14 @@ def board(board: Optional[chess.BaseBoard] = None, *, "opacity": fill_opacity if fill_opacity < 1.0 else None, })) + # Render check mark. + for square, bb in enumerate(chess.BB_SQUARES): + file_index = chess.square_file(square) + rank_index = chess.square_rank(square) + + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin + if square == check: ET.SubElement(svg, "rect", _attrs({ "x": x, @@ -345,15 +366,33 @@ def board(board: Optional[chess.BaseBoard] = None, *, "fill": "url(#check_gradient)", })) - # Render pieces. + # Render pieces. + for square, bb in enumerate(chess.BB_SQUARES): + file_index = chess.square_file(square) + rank_index = chess.square_rank(square) + + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin + if board is not None: piece = board.piece_at(square) if piece: - ET.SubElement(svg, "use", { + z = ET.SubElement(svg, "use", { "xlink:href": f"#{chess.COLOR_NAMES[piece.color]}-{chess.PIECE_NAMES[piece.piece_type]}", "transform": f"translate({x:d}, {y:d})", }) + # Render animated move. + if animation: + if square == lastmove.to_square: + dx = int((math.fmod(lastmove.from_square, 8) - math.fmod(lastmove.to_square, 8)) * SQUARE_SIZE) + dy = (math.ceil(lastmove.to_square / 8) - math.ceil(lastmove.from_square / 8)) * SQUARE_SIZE + ET.SubElement(z, "animateMotion", { + "dur": f"1s", + "repeatCount": f"1", + "path": f"M{dx:d},{dy:d} 0,0", + }) + # Render selected squares. if squares is not None and square in squares: ET.SubElement(svg, "use", _attrs({ @@ -362,17 +401,6 @@ def board(board: Optional[chess.BaseBoard] = None, *, "y": y, })) - if coordinates: - coord_color, coord_opacity = _color(colors, "coord") - for file_index, file_name in enumerate(chess.FILE_NAMES): - x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin - svg.append(_coord(file_name, x, 0, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) - svg.append(_coord(file_name, x, margin + 8 * SQUARE_SIZE, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) - for rank_index, rank_name in enumerate(chess.RANK_NAMES): - y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin - svg.append(_coord(rank_name, 0, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) - svg.append(_coord(rank_name, margin + 8 * SQUARE_SIZE, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) - for arrow in arrows: try: tail, head, color = arrow.tail, arrow.head, arrow.color # type: ignore From 41b57724fc23a79aa6b70a9ea8920bbcaca868a9 Mon Sep 17 00:00:00 2001 From: Paul Philippov Date: Mon, 8 Mar 2021 00:28:20 -0500 Subject: [PATCH 1386/1831] fix mypy strict errors --- chess/svg.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 12fdf5253..24bd2e764 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -384,13 +384,13 @@ def board(board: Optional[chess.BaseBoard] = None, *, # Render animated move. if animation: - if square == lastmove.to_square: - dx = int((math.fmod(lastmove.from_square, 8) - math.fmod(lastmove.to_square, 8)) * SQUARE_SIZE) - dy = (math.ceil(lastmove.to_square / 8) - math.ceil(lastmove.from_square / 8)) * SQUARE_SIZE + if lastmove is not None and square == lastmove.to_square: + lmdx = (math.fmod(lastmove.from_square, 8) - math.fmod(lastmove.to_square, 8)) * SQUARE_SIZE + lmdy = (math.ceil(lastmove.to_square / 8) - math.ceil(lastmove.from_square / 8)) * SQUARE_SIZE ET.SubElement(z, "animateMotion", { "dur": f"1s", "repeatCount": f"1", - "path": f"M{dx:d},{dy:d} 0,0", + "path": f"M{lmdx:d},{lmdy:d} 0,0", }) # Render selected squares. From e981bd0c3aaa37aee87dcd1200461e9b30b1c639 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 11 Mar 2021 21:51:04 +0100 Subject: [PATCH 1387/1831] Revert animation of last move (#747) --- chess/svg.py | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 24bd2e764..7f4f935a9 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -233,7 +233,6 @@ def piece(piece: chess.Piece, size: Optional[int] = None) -> str: def board(board: Optional[chess.BaseBoard] = None, *, orientation: Color = chess.WHITE, lastmove: Optional[chess.Move] = None, - animation: bool = False, check: Optional[Square] = None, arrows: Iterable[Union[Arrow, Tuple[Square, Square]]] = [], squares: Optional[IntoSquareSet] = None, @@ -249,7 +248,6 @@ def board(board: Optional[chess.BaseBoard] = None, *, ``None`` (the default) for a chessboard without pieces. :param orientation: The point of view, defaulting to ``chess.WHITE``. :param lastmove: A :class:`chess.Move` to be highlighted. - :param animation: Pass ``True`` to animate lastmove. :param check: A square to be marked indicating a check. :param arrows: A list of :class:`~chess.svg.Arrow` objects, like ``[chess.svg.Arrow(chess.E2, chess.E4)]``, or a list of tuples, like @@ -349,24 +347,23 @@ def board(board: Optional[chess.BaseBoard] = None, *, })) # Render check mark. - for square, bb in enumerate(chess.BB_SQUARES): - file_index = chess.square_file(square) - rank_index = chess.square_rank(square) + if check is not None: + file_index = chess.square_file(check) + rank_index = chess.square_rank(check) x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin - if square == check: - ET.SubElement(svg, "rect", _attrs({ - "x": x, - "y": y, - "width": SQUARE_SIZE, - "height": SQUARE_SIZE, - "class": "check", - "fill": "url(#check_gradient)", - })) + ET.SubElement(svg, "rect", _attrs({ + "x": x, + "y": y, + "width": SQUARE_SIZE, + "height": SQUARE_SIZE, + "class": "check", + "fill": "url(#check_gradient)", + })) - # Render pieces. + # Render pieces and selected squares. for square, bb in enumerate(chess.BB_SQUARES): file_index = chess.square_file(square) rank_index = chess.square_rank(square) @@ -377,22 +374,11 @@ def board(board: Optional[chess.BaseBoard] = None, *, if board is not None: piece = board.piece_at(square) if piece: - z = ET.SubElement(svg, "use", { + ET.SubElement(svg, "use", { "xlink:href": f"#{chess.COLOR_NAMES[piece.color]}-{chess.PIECE_NAMES[piece.piece_type]}", "transform": f"translate({x:d}, {y:d})", }) - # Render animated move. - if animation: - if lastmove is not None and square == lastmove.to_square: - lmdx = (math.fmod(lastmove.from_square, 8) - math.fmod(lastmove.to_square, 8)) * SQUARE_SIZE - lmdy = (math.ceil(lastmove.to_square / 8) - math.ceil(lastmove.from_square / 8)) * SQUARE_SIZE - ET.SubElement(z, "animateMotion", { - "dur": f"1s", - "repeatCount": f"1", - "path": f"M{lmdx:d},{lmdy:d} 0,0", - }) - # Render selected squares. if squares is not None and square in squares: ET.SubElement(svg, "use", _attrs({ @@ -401,6 +387,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, "y": y, })) + # Render arrows. for arrow in arrows: try: tail, head, color = arrow.tail, arrow.head, arrow.color # type: ignore From c979f06732a6d31df6fe8af486bb41ea0ad21d1c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 11 Mar 2021 22:18:13 +0100 Subject: [PATCH 1388/1831] Ignore trailing space after ponder move (fixes #751) --- chess/engine.py | 4 ++-- test.py | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 5eccdefd1..e948d9034 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1763,12 +1763,12 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL return info def _parse_uci_bestmove(board: chess.Board, args: str) -> BestMove: - tokens = args.split(None, 2) + tokens = args.split() move = None ponder = None - if tokens[0] not in ["(none)", "NULL"]: + if tokens and tokens[0] not in ["(none)", "NULL"]: try: # AnMon 5.75 uses uppercase letters to denote promotion types. move = board.push_uci(tokens[0].lower()) diff --git a/test.py b/test.py index 5ba984955..0386680c3 100755 --- a/test.py +++ b/test.py @@ -3182,6 +3182,31 @@ def test_uci_info(self): info = chess.engine._parse_uci_info("depth 1 seldepth 2 time 16 nodes 1 score cp 72 wdl 249 747 4 hashfull 0 nps 400 tbhits 0 multipv 1", board) self.assertEqual(info["wdl"], (249, 747, 4)) + def test_hiarcs_bestmove(self): + async def main(): + protocol = chess.engine.UciProtocol() + mock = chess.engine.MockTransport(protocol) + + mock.expect("uci", ["uciok"]) + await protocol.initialize() + + mock.expect("ucinewgame") + mock.expect("isready", ["readyok"]) + mock.expect("position fen QN4n1/6r1/3k4/8/b2K4/8/8/8 b - - 0 1") + mock.expect("go", [ + "info depth 1 seldepth 4 time 793 nodes 187 nps 235 score cp -40 pv g7g4 d4c3 string keep double space", + "bestmove g7g4 ponder d4c3 ", + ]) + result = await protocol.play(chess.Board("QN4n1/6r1/3k4/8/b2K4/8/8/8 b - - 0 1"), chess.engine.Limit(), info=chess.engine.INFO_ALL) + self.assertEqual(result.move, chess.Move.from_uci("g7g4")) + self.assertEqual(result.ponder, chess.Move.from_uci("d4c3")) + self.assertEqual(result.info["pv"], [chess.Move.from_uci("g7g4"), chess.Move.from_uci("d4c3")]) + self.assertEqual(result.info["string"], "keep double space") + mock.assert_done() + + asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) + asyncio.run(main()) + def test_xboard_options(self): async def main(): protocol = chess.engine.XBoardProtocol() From a23e90f8c33b1cb3af270657a04e1be002e791e0 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 11 Mar 2021 19:29:22 -0800 Subject: [PATCH 1389/1831] Send Xboard level command in sudden death games Games with a base time limit but no moves to reset (Limit.remaining_moves) and no increment still require a level command. Since st and level are mutually exclusive, use the presence or absence of time-per-move (Limit.time) to decide which time control command to send. --- chess/engine.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 5eccdefd1..49c6869d8 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2047,9 +2047,11 @@ def start(self, engine: XBoardProtocol) -> None: # Limit or time control. increment = limit.white_inc if board.turn else limit.black_inc - if limit.remaining_moves or increment: + if limit.time is not None: + engine.send_line(f"st {max(0.01, limit.time)}") + else: base_mins, base_secs = divmod(int((limit.white_clock if board.turn else limit.black_clock) or 0), 60) - engine.send_line(f"level {limit.remaining_moves or 0} {base_mins}:{base_secs:02d} {increment}") + engine.send_line(f"level {limit.remaining_moves or 0} {base_mins}:{base_secs:02d} {increment or 0}") if limit.nodes is not None: if limit.time is not None or limit.white_clock is not None or limit.black_clock is not None or increment is not None: @@ -2064,8 +2066,6 @@ def start(self, engine: XBoardProtocol) -> None: engine.send_line(f"st {max(1, int(limit.nodes))}") if limit.depth is not None: engine.send_line(f"sd {max(1, int(limit.depth))}") - if limit.time is not None: - engine.send_line(f"st {max(0.01, limit.time)}") if limit.white_clock is not None: engine.send_line("{} {}".format("time" if board.turn else "otim", max(1, int(limit.white_clock * 100)))) if limit.black_clock is not None: From 2b8ee3b3e5bec9945778beccbcce7581903c134a Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 11 Mar 2021 19:44:27 -0800 Subject: [PATCH 1390/1831] Fix order of time control messages in test.py --- test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test.py b/test.py index 5ba984955..d26eda2bb 100755 --- a/test.py +++ b/test.py @@ -3266,8 +3266,8 @@ async def main(): mock.expect("d2d4") mock.expect("g8f6") mock.expect("c2c4") - mock.expect("sd 17") mock.expect("st 1.5") + mock.expect("sd 17") mock.expect("nopost") mock.expect("easy") mock.expect("go", ["move e7e6"]) @@ -3279,8 +3279,8 @@ async def main(): board.pop() mock.expect("force") mock.expect("remove") - mock.expect("sd 17") mock.expect("st 1.5") + mock.expect("sd 17") mock.expect("nopost") mock.expect("easy") mock.expect("go", ["move c2c4"]) @@ -3294,8 +3294,8 @@ async def main(): mock.expect("force") mock.expect("remove") mock.expect("undo") - mock.expect("sd 17") mock.expect("st 1.5") + mock.expect("sd 17") mock.expect("nopost") mock.expect("easy") mock.expect("go", ["move d2d4"]) From 019efa8b866c871e09c763bb5603ad97c508c8e4 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 16 Mar 2021 17:23:42 -0700 Subject: [PATCH 1391/1831] Use full move stack for UCI pondering --- chess/engine.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 4c7027916..26d2bbc25 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1581,9 +1581,10 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: if ponder and best.move and best.ponder: self.pondering = True - engine.board.push(best.move) - engine.board.push(best.ponder) - engine._position(engine.board) + pondering_board = board.copy() + pondering_board.push(best.move) + pondering_board.push(best.ponder) + engine._position(pondering_board) engine._go(limit, ponder=True) if not self.pondering: From 149fb5acb6fcefff4b51ebbb4f19ba716f1ad2fd Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 16 Mar 2021 23:40:18 -0700 Subject: [PATCH 1392/1831] First step: call ponderhit when ponder move made --- chess/engine.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 4c7027916..1cff25852 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1303,6 +1303,7 @@ def __init__(self) -> None: self.board = chess.Board() self.game: object = None self.first_game = True + self.ponder_move = None async def initialize(self) -> None: class UciInitializeCommand(BaseCommand[UciProtocol, None]): @@ -1530,6 +1531,8 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None self.send_line(" ".join(builder)) async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + self.last_move = board.move_stack[-1] if board.move_stack else None + class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): def start(self, engine: UciProtocol) -> None: self.info: InfoDict = {} @@ -1581,10 +1584,13 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: if ponder and best.move and best.ponder: self.pondering = True + engine.ponder_move = best.ponder engine.board.push(best.move) engine.board.push(best.ponder) engine._position(engine.board) engine._go(limit, ponder=True) + else: + engine.ponder_move = None if not self.pondering: self.end(engine) @@ -1593,7 +1599,10 @@ def end(self, engine: UciProtocol) -> None: self.set_finished() def cancel(self, engine: UciProtocol) -> None: - engine.send_line("stop") + if engine.ponder_move and engine.ponder_move == engine.last_move: + engine.send_line("ponderhit") + else: + engine.send_line("stop") def engine_terminated(self, engine: UciProtocol, exc: Exception) -> None: # Allow terminating engine while pondering. From 2b423b1dfc348ac27a34d1c4ac8f7b03dfbf7b4e Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 17 Mar 2021 00:15:16 -0700 Subject: [PATCH 1393/1831] Skip board setup if ponderhit --- chess/engine.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index 1cff25852..42e5514de 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1304,6 +1304,7 @@ def __init__(self) -> None: self.game: object = None self.first_game = True self.ponder_move = None + self.ponderhit = False async def initialize(self) -> None: class UciInitializeCommand(BaseCommand[UciProtocol, None]): @@ -1548,6 +1549,10 @@ def start(self, engine: UciProtocol) -> None: engine._configure(options) + if engine.ponderhit: + engine.ponderhit = False + return + if engine.first_game or engine.game != game: engine.game = game engine._ucinewgame() @@ -1600,6 +1605,9 @@ def end(self, engine: UciProtocol) -> None: def cancel(self, engine: UciProtocol) -> None: if engine.ponder_move and engine.ponder_move == engine.last_move: + engine.ponderhit = True + engine.ponder_move = None + self.end(engine) engine.send_line("ponderhit") else: engine.send_line("stop") From f765558b2f510bac921f1df216bac3c959cc270c Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 17 Mar 2021 00:25:48 -0700 Subject: [PATCH 1394/1831] Reset ponder_move and ponderhit for ucinewgame --- chess/engine.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index 42e5514de..5a87eb4ca 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1395,6 +1395,8 @@ def _isready(self) -> None: def _ucinewgame(self) -> None: self.send_line("ucinewgame") self.first_game = False + self.ponder_move = None + self.ponderhit = False def debug(self, on: bool = True) -> None: """ From 0dd06853283584c1ee169683212e02533dc3e128 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 17 Mar 2021 12:52:54 +0100 Subject: [PATCH 1395/1831] Do not ignore limit.time when sending XBoard level --- chess/engine.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 26d2bbc25..5e0c607bb 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2047,11 +2047,10 @@ def start(self, engine: XBoardProtocol) -> None: engine._new(board, game, options) # Limit or time control. + clock = limit.white_clock if board.turn else limit.black_clock increment = limit.white_inc if board.turn else limit.black_inc - if limit.time is not None: - engine.send_line(f"st {max(0.01, limit.time)}") - else: - base_mins, base_secs = divmod(int((limit.white_clock if board.turn else limit.black_clock) or 0), 60) + if limit.remaining_moves or clock is not None or increment is not None: + base_mins, base_secs = divmod(int(clock) or 0, 60) engine.send_line(f"level {limit.remaining_moves or 0} {base_mins}:{base_secs:02d} {increment or 0}") if limit.nodes is not None: @@ -2065,6 +2064,8 @@ def start(self, engine: XBoardProtocol) -> None: engine.send_line("nps 1") engine.send_line(f"st {max(1, int(limit.nodes))}") + if limit.time is not None: + engine.send_line(f"st {max(0.01, limit.time)}") if limit.depth is not None: engine.send_line(f"sd {max(1, int(limit.depth))}") if limit.white_clock is not None: From 90587d1d3b674b98eccdfad63e28916f6a868ac8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 17 Mar 2021 13:02:11 +0100 Subject: [PATCH 1396/1831] Fixup last commit: Handle None for clock --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 5e0c607bb..628daedae 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2050,7 +2050,7 @@ def start(self, engine: XBoardProtocol) -> None: clock = limit.white_clock if board.turn else limit.black_clock increment = limit.white_inc if board.turn else limit.black_inc if limit.remaining_moves or clock is not None or increment is not None: - base_mins, base_secs = divmod(int(clock) or 0, 60) + base_mins, base_secs = divmod(int(clock or 0), 60) engine.send_line(f"level {limit.remaining_moves or 0} {base_mins}:{base_secs:02d} {increment or 0}") if limit.nodes is not None: From 37140d4145bb1619ed182d021a49921bbf666a9b Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 17 Mar 2021 18:08:30 -0700 Subject: [PATCH 1397/1831] Send ponderhit in next UciPlayCommand This is to make sure that the bestmove line is not missed between one command ending and the next beginning. --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 5a87eb4ca..d5af270df 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1553,6 +1553,7 @@ def start(self, engine: UciProtocol) -> None: if engine.ponderhit: engine.ponderhit = False + engine.send_line("ponderhit") return if engine.first_game or engine.game != game: @@ -1610,7 +1611,6 @@ def cancel(self, engine: UciProtocol) -> None: engine.ponderhit = True engine.ponder_move = None self.end(engine) - engine.send_line("ponderhit") else: engine.send_line("stop") From 43631b8c0cf718e3df1a24429c05eb4096a819c6 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 17 Mar 2021 18:43:26 -0700 Subject: [PATCH 1398/1831] Adjust time used for pondering time The time between a move being received (whether by position or ponderhit) and bestmove being sent back is subtracted from the time in the initial Limit paramter in the play() call. If there is a clock increment, it is added to the ponder time. If there is a remaining_moves value in the limit, it is decremented. All of these operations should give the engine a good idea of the current state of the clock after picking a move. The only deficiency is that if remaining_moves becomes zero, then the ponder time will look like the time for the rest of the game. Although, since game periods are commonly 40 moves, this is still a decent approximation. --- chess/engine.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index c6d806074..3d6c5510a 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -19,6 +19,7 @@ import abc import asyncio import collections +import copy import concurrent.futures import contextlib import copy @@ -31,6 +32,7 @@ import subprocess import sys import threading +import time import typing import os import re @@ -1541,6 +1543,7 @@ def start(self, engine: UciProtocol) -> None: self.info: InfoDict = {} self.pondering = False self.sent_isready = False + self.start_time = time.perf_counter() if "UCI_AnalyseMode" in engine.options and "UCI_AnalyseMode" not in engine.target_config and all(name.lower() != "uci_analysemode" for name in options): engine._setoption("UCI_AnalyseMode", False) @@ -1597,7 +1600,22 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: pondering_board.push(best.move) pondering_board.push(best.ponder) engine._position(pondering_board) - engine._go(limit, ponder=True) + + time_used = time.perf_counter() - self.start_time + ponder_limit = copy.copy(limit) + if pondering_board.turn == chess.WHITE: + if limit.white_clock: + ponder_limit.white_clock -= time_used + ponder_limit.white_clock += (limit.white_inc or 0.0) + else: + if limit.black_clock: + ponder_limit.black_clock -= time_used + ponder_limit.black_clock += (limit.black_inc or 0.0) + + if ponder_limit.remaining_moves: + ponder_limit.remaining_moves -= 1 + + engine._go(ponder_limit, ponder=True) else: engine.ponder_move = None From 53c186ed3c561ddfa5af2f4b73775fe8d92f433e Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 17 Mar 2021 19:08:31 -0700 Subject: [PATCH 1399/1831] Make ponder_move a UciPlayCommand field --- chess/engine.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 3d6c5510a..9cec9b2dc 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1305,7 +1305,6 @@ def __init__(self) -> None: self.board = chess.Board() self.game: object = None self.first_game = True - self.ponder_move = None self.ponderhit = False async def initialize(self) -> None: @@ -1397,7 +1396,6 @@ def _isready(self) -> None: def _ucinewgame(self) -> None: self.send_line("ucinewgame") self.first_game = False - self.ponder_move = None self.ponderhit = False def debug(self, on: bool = True) -> None: @@ -1542,6 +1540,7 @@ class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): def start(self, engine: UciProtocol) -> None: self.info: InfoDict = {} self.pondering = False + self.ponder_move = None self.sent_isready = False self.start_time = time.perf_counter() @@ -1595,7 +1594,7 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: if ponder and best.move and best.ponder: self.pondering = True - engine.ponder_move = best.ponder + self.ponder_move = best.ponder pondering_board = board.copy() pondering_board.push(best.move) pondering_board.push(best.ponder) @@ -1617,7 +1616,7 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: engine._go(ponder_limit, ponder=True) else: - engine.ponder_move = None + self.ponder_move = None if not self.pondering: self.end(engine) @@ -1626,9 +1625,8 @@ def end(self, engine: UciProtocol) -> None: self.set_finished() def cancel(self, engine: UciProtocol) -> None: - if engine.ponder_move and engine.ponder_move == engine.last_move: + if self.ponder_move and self.ponder_move == engine.last_move: engine.ponderhit = True - engine.ponder_move = None self.end(engine) else: engine.send_line("stop") From 6f36cd53ada058a48e03481bfb5e103b95055f1e Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 17 Mar 2021 19:30:34 -0700 Subject: [PATCH 1400/1831] Don't reference limit after copying --- chess/engine.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 9cec9b2dc..2046f8556 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1603,13 +1603,13 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: time_used = time.perf_counter() - self.start_time ponder_limit = copy.copy(limit) if pondering_board.turn == chess.WHITE: - if limit.white_clock: + if ponder_limit.white_clock: ponder_limit.white_clock -= time_used - ponder_limit.white_clock += (limit.white_inc or 0.0) + ponder_limit.white_clock += (ponder_limit.white_inc or 0.0) else: - if limit.black_clock: + if ponder_limit.black_clock: ponder_limit.black_clock -= time_used - ponder_limit.black_clock += (limit.black_inc or 0.0) + ponder_limit.black_clock += (ponder_limit.black_inc or 0.0) if ponder_limit.remaining_moves: ponder_limit.remaining_moves -= 1 From aa4ef365c6e4f454667d088bf2af87d660ffb1b0 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 17 Mar 2021 20:04:49 -0700 Subject: [PATCH 1401/1831] Use null Move for type consistency --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 2046f8556..fef635d16 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1540,7 +1540,7 @@ class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): def start(self, engine: UciProtocol) -> None: self.info: InfoDict = {} self.pondering = False - self.ponder_move = None + self.ponder_move = chess.Move.null() self.sent_isready = False self.start_time = time.perf_counter() @@ -1616,7 +1616,7 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: engine._go(ponder_limit, ponder=True) else: - self.ponder_move = None + self.ponder_move = chess.Move.null() if not self.pondering: self.end(engine) From 50811f2c522bd524c55ba93d85608f81b565da48 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 24 Mar 2021 17:57:37 -0700 Subject: [PATCH 1402/1831] Both clocks need incrementing in go ponder The clock specs in a go ponder command represent the state of both clocks at the time the command is sent. The opponent's clock is incremented immediately (because it's now the opponent's turn) while the engine's clock will be incremented before the next call to play(). --- chess/engine.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index fef635d16..86072b6c4 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1602,14 +1602,13 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: time_used = time.perf_counter() - self.start_time ponder_limit = copy.copy(limit) - if pondering_board.turn == chess.WHITE: - if ponder_limit.white_clock: + if ponder_limit.white_clock is not None or ponder_limit.black_clock is not None: + ponder_limit.white_clock += (ponder_limit.white_inc or 0.0) + ponder_limit.black_clock += (ponder_limit.black_inc or 0.0) + if pondering_board.turn == chess.WHITE: ponder_limit.white_clock -= time_used - ponder_limit.white_clock += (ponder_limit.white_inc or 0.0) - else: - if ponder_limit.black_clock: + else: ponder_limit.black_clock -= time_used - ponder_limit.black_clock += (ponder_limit.black_inc or 0.0) if ponder_limit.remaining_moves: ponder_limit.remaining_moves -= 1 From 4ab0e305fa3c73b4bf115ac1ebc03c0932905926 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 24 Mar 2021 18:13:26 -0700 Subject: [PATCH 1403/1831] Fixup for Github checks Make sure values are not None before using them for math. --- chess/engine.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 86072b6c4..b20c49b3f 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1602,12 +1602,15 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: time_used = time.perf_counter() - self.start_time ponder_limit = copy.copy(limit) - if ponder_limit.white_clock is not None or ponder_limit.black_clock is not None: + + if ponder_limit.white_clock is not None: ponder_limit.white_clock += (ponder_limit.white_inc or 0.0) - ponder_limit.black_clock += (ponder_limit.black_inc or 0.0) if pondering_board.turn == chess.WHITE: ponder_limit.white_clock -= time_used - else: + + if ponder_limit.black_clock is not None: + ponder_limit.black_clock += (ponder_limit.black_inc or 0.0) + if pondering_board.turn == chess.BLACK: ponder_limit.black_clock -= time_used if ponder_limit.remaining_moves: From a7eb0377f756acc575174171ac0568cb579db2eb Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 25 Mar 2021 17:11:13 -0700 Subject: [PATCH 1404/1831] Stop pondering when play() has `ponder=False` When the play() command has ponder=False (or defaulted to False), any previously started pondering should be stopped as well. --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index b20c49b3f..26b750811 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1534,7 +1534,7 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None self.send_line(" ".join(builder)) async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: - self.last_move = board.move_stack[-1] if board.move_stack else None + self.last_move = board.move_stack[-1] if (ponder and board.move_stack) else chess.Move.null() class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): def start(self, engine: UciProtocol) -> None: From d7108842f162d5ed465382bcc87a2091e5210932 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 1 Apr 2021 19:07:14 +0200 Subject: [PATCH 1405/1831] Remove chess.pgn.ReverseMainline (fixes #763) This breaking change is a required bugfix, because __reversed__ is supposed to return an Iterator, not merely an Iterable. --- chess/pgn.py | 37 +++++-------------------------------- test.py | 1 - 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 0be971c64..d4e4c1316 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -945,8 +945,11 @@ def __iter__(self) -> Iterator[MainlineMapT]: node = node.variations[0] yield self.f(node) - def __reversed__(self) -> ReverseMainline[MainlineMapT]: - return ReverseMainline(self.start, self.f) + def __reversed__(self) -> Iterator[MainlineMapT]: + node = self.start.end() + while node.parent and node != self.start: + yield self.f(typing.cast(ChildNode, node)) + node = node.parent def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: node = self.start @@ -964,36 +967,6 @@ def __repr__(self) -> str: return f"" -class ReverseMainline(Generic[MainlineMapT]): - def __init__(self, stop: GameNode, f: Callable[[ChildNode], MainlineMapT]) -> None: - self.stop = stop - self.f = f - - self.length = 0 - node = stop - while node.variations: - node = node.variations[0] - self.length += 1 - self.end = node - - def __len__(self) -> int: - return self.length - - def __iter__(self) -> Iterator[MainlineMapT]: - node = self.end - while node.parent and node != self.stop: - yield self.f(typing.cast(ChildNode, node)) - node = node.parent - - def __reversed__(self) -> Mainline[MainlineMapT]: - return Mainline(self.stop, self.f) - - def __repr__(self) -> str: - return "".format( - id(self), - " ".join(ReverseMainline(self.stop, lambda node: node.move.uci()))) - - class BaseVisitor(abc.ABC, Generic[ResultT]): """ Base class for visitors. diff --git a/test.py b/test.py index 57d89bcd6..d8bb4c5cb 100755 --- a/test.py +++ b/test.py @@ -2597,7 +2597,6 @@ def test_mainline(self): self.assertEqual(list(game.mainline_moves()), moves) self.assertTrue(game.mainline_moves()) self.assertEqual(list(reversed(game.mainline_moves())), list(reversed(moves))) - self.assertEqual(len(reversed(game.mainline_moves())), 3) self.assertEqual(str(game.mainline_moves()), "1. d3 Nf6 2. e4") def test_lan(self): From a1eda7d2e9cf4b0d922c3955c00151e86a5e002d Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 1 Apr 2021 16:48:31 -0700 Subject: [PATCH 1406/1831] Stop pondering when changing games or options If a new game is started (game parameter is changed) or if the engine is reconfigured, stop pondering and start a new search for moves. --- chess/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 26b750811..1be165d4f 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1534,7 +1534,8 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None self.send_line(" ".join(builder)) async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: - self.last_move = board.move_stack[-1] if (ponder and board.move_stack) else chess.Move.null() + same_game = not self.first_game and game == self.game and not options + self.last_move = board.move_stack[-1] if (same_game and ponder and board.move_stack) else chess.Move.null() class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): def start(self, engine: UciProtocol) -> None: From eac9ef9d0f3e4fd64ac8df22eb22351f21e67fe4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 5 Apr 2021 22:08:55 +0200 Subject: [PATCH 1407/1831] Fix analysis should reset Ponder option --- chess/engine.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index 628daedae..30e66e9fb 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1609,6 +1609,8 @@ def start(self, engine: UciProtocol) -> None: self.analysis = AnalysisResult(stop=lambda: self.cancel(engine)) self.sent_isready = False + if "Ponder" in engine.options: + engine._setoption("Ponder", False) if "UCI_AnalyseMode" in engine.options and "UCI_AnalyseMode" not in engine.target_config and all(name.lower() != "uci_analysemode" for name in options): engine._setoption("UCI_AnalyseMode", True) if "MultiPV" in engine.options or (multipv and multipv > 1): From cc5eef1e0658ee6529cc91affb1d6be9ccc549cc Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 5 Apr 2021 22:19:00 +0200 Subject: [PATCH 1408/1831] Test and fix extra stop on play after analyse --- chess/engine.py | 8 +++----- test.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 30e66e9fb..e699624ab 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1023,14 +1023,11 @@ async def communicate(self: ProtocolT, command_factory: Callable[[], BaseCommand if self.next_command is not None: self.next_command.result.cancel() self.next_command.finished.cancel() - self.next_command._done() + self.next_command.set_finished() self.next_command = command def previous_command_finished(_: Optional[asyncio.Future[None]]) -> None: - if self.command is not None: - self.command._done() - self.command, self.next_command = self.next_command, None if self.command is not None: cmd = self.command @@ -1240,9 +1237,10 @@ def set_finished(self) -> None: if not self.result.done(): self.result.set_exception(EngineError(f"engine command finished before returning result: {self!r}")) self.finished.set_result(None) + self.state = CommandState.Done def _cancel(self, engine: ProtocolT) -> None: - if self.state != CommandState.Cancelling: + if self.state != CommandState.Cancelling and self.state != CommandState.Done: assert self.state == CommandState.Active self.state = CommandState.Cancelling self.cancel(engine) diff --git a/test.py b/test.py index d8bb4c5cb..2a2e31d39 100755 --- a/test.py +++ b/test.py @@ -3120,6 +3120,34 @@ async def main(): asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) + def test_uci_play_after_analyse(self): + async def main(): + protocol = chess.engine.UciProtocol() + mock = chess.engine.MockTransport(protocol) + + # Initialize. + mock.expect("uci", ["uciok"]) + await protocol.initialize() + + # Ponder. + board = chess.Board() + mock.expect("ucinewgame") + mock.expect("isready", ["readyok"]) + mock.expect("position startpos") + mock.expect("go depth 20", ["bestmove a2a4 ponder a7a5"]) + info = await protocol.analyse(board, chess.engine.Limit(depth=20)) + self.assertEqual(info, {}) + + # Play. + mock.expect("position startpos") + mock.expect("go movetime 3000", ["bestmove a2a4 ponder a7a5"]) + await protocol.play(board, chess.engine.Limit(time=3)) + + mock.assert_done() + + asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) + asyncio.run(main()) + def test_uci_info(self): # Info: refutation. board = chess.Board("8/8/6k1/8/8/8/1K6/3B4 w - - 0 1") From aa1d28faff86f4d639f24e88a38c1a82a12ef093 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 5 Apr 2021 23:25:46 +0200 Subject: [PATCH 1409/1831] Misc ponderhit fixes and cleanup * Add test case. * Compare position, not only last move. * Fix interaction with lazy options. * Fix lingering last_move when command is cancelled before being initialized. --- chess/engine.py | 62 ++++++++++++++++++------------------ test.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 30 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 292936fd8..b91b2f840 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1014,8 +1014,8 @@ def _line_received(self: ProtocolT, line: str) -> None: def line_received(self, line: str) -> None: pass - async def communicate(self: ProtocolT, command_factory: Callable[[], BaseCommand[ProtocolT, T]]) -> T: - command = command_factory() + async def communicate(self: ProtocolT, command_factory: Callable[[ProtocolT], BaseCommand[ProtocolT, T]]) -> T: + command = command_factory(self) if self.returncode.done(): raise EngineTerminatedError(f"engine process dead (exit code: {self.returncode.result()})") @@ -1205,7 +1205,7 @@ class CommandState(enum.Enum): class BaseCommand(Generic[ProtocolT, T]): - def __init__(self) -> None: + def __init__(self, engine: ProtocolT) -> None: self.state = CommandState.New self.result: asyncio.Future[T] = asyncio.Future() @@ -1256,10 +1256,6 @@ def _start(self, engine: ProtocolT) -> None: except EngineError as err: self._handle_exception(engine, err) - def _done(self) -> None: - assert self.state != CommandState.Done - self.state = CommandState.Done - def _line_received(self, engine: ProtocolT, line: str) -> None: assert self.state in [CommandState.Active, CommandState.Cancelling] try: @@ -1303,6 +1299,7 @@ def __init__(self) -> None: self.board = chess.Board() self.game: object = None self.first_game = True + self.may_ponderhit: Optional[chess.Board] = None self.ponderhit = False async def initialize(self) -> None: @@ -1420,6 +1417,9 @@ def line_received(self, engine: UciProtocol, line: str) -> None: return await self.communicate(UciPingCommand) + def _changed_options(self, options: ConfigMapping) -> bool: + return any(value is None or value != self.config.get(name) for name, value in collections.ChainMap(options, self.target_config).items()) + def _setoption(self, name: str, value: ConfigValue) -> None: try: value = self.options[name].parse(value) @@ -1536,13 +1536,25 @@ async def play(self, board: chess.Board, limit: Limit, *, game: object = None, i self.last_move = board.move_stack[-1] if (same_game and ponder and board.move_stack) else chess.Move.null() class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): + def __init__(self, engine): + super().__init__(engine) + + # May ponderhit only in the same game and with unchanged target + # options. The managed options UCI_AnalyseMode, Ponder, and + # MultiPV never change between pondering play commands. + engine.may_ponderhit = board if ponder and not engine.first_game and game == engine.game and not engine._changed_options(options) else None + def start(self, engine: UciProtocol) -> None: self.info: InfoDict = {} - self.pondering = False - self.ponder_move = chess.Move.null() + self.pondering: Optional[chess.Board] = None self.sent_isready = False self.start_time = time.perf_counter() + if engine.ponderhit: + engine.ponderhit = False + engine.send_line("ponderhit") + return + if "UCI_AnalyseMode" in engine.options and "UCI_AnalyseMode" not in engine.target_config and all(name.lower() != "uci_analysemode" for name in options): engine._setoption("UCI_AnalyseMode", False) if "Ponder" in engine.options: @@ -1552,11 +1564,6 @@ def start(self, engine: UciProtocol) -> None: engine._configure(options) - if engine.ponderhit: - engine.ponderhit = False - engine.send_line("ponderhit") - return - if engine.first_game or engine.game != game: engine.game = game engine._ucinewgame() @@ -1586,47 +1593,42 @@ def _info(self, engine: UciProtocol, arg: str) -> None: def _bestmove(self, engine: UciProtocol, arg: str) -> None: if self.pondering: - self.pondering = False + self.pondering = None elif not self.result.cancelled(): best = _parse_uci_bestmove(engine.board, arg) self.result.set_result(PlayResult(best.move, best.ponder, self.info)) if ponder and best.move and best.ponder: - self.pondering = True - self.ponder_move = best.ponder - pondering_board = board.copy() - pondering_board.push(best.move) - pondering_board.push(best.ponder) - engine._position(pondering_board) + self.pondering = board.copy() + self.pondering.push(best.move) + self.pondering.push(best.ponder) + engine._position(self.pondering) + # Adjust clocks for pondering. time_used = time.perf_counter() - self.start_time ponder_limit = copy.copy(limit) - if ponder_limit.white_clock is not None: ponder_limit.white_clock += (ponder_limit.white_inc or 0.0) - if pondering_board.turn == chess.WHITE: + if self.pondering.turn == chess.WHITE: ponder_limit.white_clock -= time_used - if ponder_limit.black_clock is not None: ponder_limit.black_clock += (ponder_limit.black_inc or 0.0) - if pondering_board.turn == chess.BLACK: + if self.pondering.turn == chess.BLACK: ponder_limit.black_clock -= time_used - if ponder_limit.remaining_moves: ponder_limit.remaining_moves -= 1 engine._go(ponder_limit, ponder=True) - else: - self.ponder_move = chess.Move.null() if not self.pondering: self.end(engine) def end(self, engine: UciProtocol) -> None: + engine.may_ponderhit = None self.set_finished() def cancel(self, engine: UciProtocol) -> None: - if self.ponder_move and self.ponder_move == engine.last_move: + if engine.may_ponderhit and self.pondering and engine.may_ponderhit.move_stack == self.pondering.move_stack and engine.may_ponderhit == self.pondering: engine.ponderhit = True self.end(engine) else: @@ -2701,7 +2703,7 @@ async def _get() -> Mapping[str, str]: future = asyncio.run_coroutine_threadsafe(_get(), self.protocol.loop) return future.result() - def communicate(self, command_factory: Callable[[], BaseCommand[Protocol, T]]) -> T: + def communicate(self, command_factory: Callable[[Protocol], BaseCommand[Protocol, T]]) -> T: with self._not_shut_down(): coro = self.protocol.communicate(command_factory) future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) diff --git a/test.py b/test.py index 2a2e31d39..383e5101c 100755 --- a/test.py +++ b/test.py @@ -3148,6 +3148,90 @@ async def main(): asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) + def test_uci_ponderhit(self): + async def main(): + protocol = chess.engine.UciProtocol() + mock = chess.engine.MockTransport(protocol) + + # Initialize. + mock.expect("uci", [ + "option name Hash type spin default 16 min 1 max 33554432", + "option name Ponder type check default false", + "uciok", + ]) + await protocol.initialize() + + # First search. + mock.expect("setoption name Ponder value true") + mock.expect("ucinewgame") + mock.expect("isready", ["readyok"]) + mock.expect("position startpos") + mock.expect("go movetime 1000", ["bestmove d2d4 ponder g8f6"]) + mock.expect("position startpos moves d2d4 g8f6") + mock.expect("go ponder movetime 1000") + board = chess.Board() + result = await protocol.play(board, chess.engine.Limit(time=1), ponder=True) + self.assertEqual(result.move, chess.Move.from_uci("d2d4")) + self.assertEqual(result.ponder, chess.Move.from_uci("g8f6")) + + # Ponderhit. + board.push(result.move) + board.push(result.ponder) + mock.expect("ponderhit", ["bestmove c2c4 ponder e7e6"]) + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6") + mock.expect("go ponder movetime 2000") + result = await protocol.play(board, chess.engine.Limit(time=2), ponder=True) + self.assertEqual(result.move, chess.Move.from_uci("c2c4")) + self.assertEqual(result.ponder, chess.Move.from_uci("e7e6")) + + # Ponderhit prevented by changed option. + board.push(result.move) + board.push(result.ponder) + mock.expect("stop", ["bestmove g2g3 ponder f8b4"]) + mock.expect("setoption name Hash value 32") + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6") + mock.expect("go movetime 3000", ["bestmove b1c3 ponder f8b4"]) + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4") + mock.expect("go ponder movetime 3000") + result = await protocol.play(board, chess.engine.Limit(time=3), ponder=True, options={"Hash": 32}) + self.assertEqual(result.move, chess.Move.from_uci("b1c3")) + self.assertEqual(result.ponder, chess.Move.from_uci("f8b4")) + + # Ponderhit prevented by reverted option. + board.push(result.move) + board.push(result.ponder) + mock.expect("stop", ["bestmove e2e3 ponder e8g8"]) + mock.expect("setoption name Hash value 16") + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4") + mock.expect("go movetime 3000", ["bestmove d1c2 ponder d7d5"]) + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 d7d5") + mock.expect("go ponder movetime 3000") + result = await protocol.play(board, chess.engine.Limit(time=3), ponder=True) + self.assertEqual(result.move, chess.Move.from_uci("d1c2")) + self.assertEqual(result.ponder, chess.Move.from_uci("d7d5")) + + # Interject analysis. + board.push(result.move) + board.push(result.ponder) + mock.expect("stop", ["bestmove c4d5 ponder e6d5"]) + mock.expect("setoption name Ponder value false") + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 d7d5") + mock.expect("go movetime 4000", ["bestmove c4d5 ponder e6d5"]) + await protocol.analyse(board, chess.engine.Limit(time=4)) + + # Interjected analysis prevents ponderhit. + mock.expect("setoption name Ponder value true") + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 d7d5") + mock.expect("go movetime 5000", ["bestmove c4d5 ponder e6d5"]) + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 d7d5 c4d5 e6d5") + mock.expect("go ponder movetime 5000") + await protocol.play(board, chess.engine.Limit(time=5), ponder=True) + + mock.assert_done() + + asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) + asyncio.run(main()) + def test_uci_info(self): # Info: refutation. board = chess.Board("8/8/6k1/8/8/8/1K6/3B4 w - - 0 1") From 3819e318c620933742d62a5655efa414ce933a73 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 5 Apr 2021 23:33:57 +0200 Subject: [PATCH 1410/1831] Fix missing type annotation --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index b91b2f840..d6d4e8876 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1536,7 +1536,7 @@ async def play(self, board: chess.Board, limit: Limit, *, game: object = None, i self.last_move = board.move_stack[-1] if (same_game and ponder and board.move_stack) else chess.Move.null() class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): - def __init__(self, engine): + def __init__(self, engine: UciProtocol): super().__init__(engine) # May ponderhit only in the same game and with unchanged target From 32b285956909bb7a17c16471fc78f47ceb0d5121 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 00:33:07 +0200 Subject: [PATCH 1411/1831] Add experimental chess.Board.outcome() (fixes #765) --- README.rst | 4 +- chess/__init__.py | 131 +++++++++++++++++++++++++++------------------- docs/core.rst | 9 ++++ 3 files changed, 89 insertions(+), 55 deletions(-) diff --git a/README.rst b/README.rst index 297e9048c..6dc9761ad 100644 --- a/README.rst +++ b/README.rst @@ -130,8 +130,8 @@ Features False >>> board.is_insufficient_material() False - >>> board.is_game_over() - True + >>> board.outcome() + Outcome(end=, winner=True) * Detects repetitions. Has a half-move clock. diff --git a/chess/__init__.py b/chess/__init__.py index 925b26751..5007f89f3 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -103,7 +103,6 @@ class Status(enum.IntFlag): TOO_MANY_CHECKERS = 1 << 15 IMPOSSIBLE_CHECK = 1 << 16 - STATUS_VALID = Status.VALID STATUS_NO_WHITE_KING = Status.NO_WHITE_KING STATUS_NO_BLACK_KING = Status.NO_BLACK_KING @@ -124,6 +123,48 @@ class Status(enum.IntFlag): STATUS_IMPOSSIBLE_CHECK = Status.IMPOSSIBLE_CHECK +class GameEnd(enum.Enum): + """Reasons for a game to be over.""" + + Checkmate = 1 + """See :func:`chess.Board.is_checkmate()`.""" + Stalemate = 2 + """See :func:`chess.Board.is_stalemate()`.""" + InsufficientMaterial = 3 + """See :func:`chess.Board.is_insufficient_material()`.""" + SeventyfiveMoves = 4 + """See :func:`chess.Board.is_seventyfive_moves()`.""" + FivefoldRepetition = 5 + """See :func:`chess.Board.is_fivefold_repetition()`.""" + FiftyMoves = 6 + """See :func:`chess.Board.can_claim_fifty_moves()`.""" + ThreefoldRepetition = 7 + """See :func:`chess.Board.can_claim_threefold_repetition()`.""" + VariantWin = 8 + """See :func:`chess.Board.is_variant_win()`.""" + VariantLoss = 9 + """See :func:`chess.Board.is_variant_loss()`.""" + VariantDraw = 10 + """See :func:`chess.Board.is_variant_draw()`.""" + +@dataclasses.dataclass +class Outcome: + """ + Information about the outcome of an ended game, usually obtained from + :func:`chess.Board.outcome()`. + """ + + end: GameEnd + """The reason for the game to have ended.""" + + winner: Optional[Color] + """The winning color or ``None`` if drawn.""" + + def result(self): + """Returns ``1-0``, ``0-1`` or ``1/2-1/2``.""" + return "1/2-1/2" if self.winner is None else ("1-0" if self.winner else "0-1") + + Square = int SQUARES = [ A1, B1, C1, D1, E1, F1, G1, H1, @@ -1824,14 +1865,25 @@ def is_variant_draw(self) -> bool: return False def is_game_over(self, *, claim_draw: bool = False) -> bool: + return self.outcome(claim_draw=claim_draw) is not None + + def result(self, *, claim_draw: bool = False) -> str: + outcome = self.outcome(claim_draw=claim_draw) + return outcome.result() if outcome else "*" + + def outcome(self, *, claim_draw: bool = False) -> Optional[Outcome]: """ Checks if the game is over due to :func:`checkmate `, :func:`stalemate `, :func:`insufficient material `, the :func:`seventyfive-move rule `, - :func:`fivefold repetition ` + :func:`fivefold repetition `, or a :func:`variant end condition `. + Returns the :class:`chess.Outcome` if the game has ended or ``None``. + + Alternatively, use :func:`~chess.Board.is_game_over()` if you are not + interested in who won the game and why. The game is not considered to be over by the :func:`fifty-move rule ` or @@ -1839,63 +1891,36 @@ def is_game_over(self, *, claim_draw: bool = False) -> bool: unless *claim_draw* is given. Note that checking the latter can be slow. """ - # Seventyfive-move rule. - if self.is_seventyfive_moves(): - return True - - # Insufficient material. - if self.is_insufficient_material(): - return True - - # Stalemate or checkmate. - if not any(self.generate_legal_moves()): - return True - - if claim_draw: - # Claim draw, including by threefold repetition. - return self.can_claim_draw() - else: - # Fivefold repetition. - return self.is_fivefold_repetition() - - def result(self, *, claim_draw: bool = False) -> str: - """ - Gets the game result. - - ``1-0``, ``0-1`` or ``1/2-1/2`` if the - :func:`game is over `. Otherwise, the - result is undetermined: ``*``. - """ - # Chess variant support. + # Variant support. if self.is_variant_loss(): - return "0-1" if self.turn == WHITE else "1-0" - elif self.is_variant_win(): - return "1-0" if self.turn == WHITE else "0-1" - elif self.is_variant_draw(): - return "1/2-1/2" + return Outcome(GameEnd.VariantLoss, not self.turn) + if self.is_variant_win(): + return Outcome(GameEnd.VariantWin, self.turn) + if self.is_variant_draw(): + return Outcome(GameEnd.VariantDraw, None) - # Checkmate. + # Normal game end. if self.is_checkmate(): - return "0-1" if self.turn == WHITE else "1-0" - - # Draw claimed. - if claim_draw and self.can_claim_draw(): - return "1/2-1/2" - - # Seventyfive-move rule or fivefold repetition. - if self.is_seventyfive_moves() or self.is_fivefold_repetition(): - return "1/2-1/2" - - # Insufficient material. + return Outcome(GameEnd.Checkmate, not self.turn) if self.is_insufficient_material(): - return "1/2-1/2" - - # Stalemate. + return Outcome(GameEnd.InsufficientMaterial, None) if not any(self.generate_legal_moves()): - return "1/2-1/2" + return Outcome(GameEnd.Stalemate, None) + + # Automatic draws. + if self.is_seventyfive_moves(): + return Outcome(GameEnd.SeventyfiveMoves, None) + if self.is_fivefold_repetition(): + return Outcome(GameEnd.FivefoldRepetition, None) + + # Claimable draws. + if claim_draw: + if self.can_claim_fifty_moves(): + return Outcome(GameEnd.FiftyMoves, None) + if self.can_claim_threefold_repetition(): + return Outcome(GameEnd.ThreefoldRepetition, None) - # Undetermined. - return "*" + return None def is_checkmate(self) -> bool: """Checks if the current position is a checkmate.""" diff --git a/docs/core.rst b/docs/core.rst index 50d1011d1..162ab9006 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -112,6 +112,15 @@ Board .. autoclass:: chess.BaseBoard :members: +Outcome +------- + +.. autoclass:: chess.Outcome + :members: + +.. autoclass:: chess.GameEnd + :members: + Square sets ----------- From e573632d5b93544361e41f383bf9aebb66902435 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 00:35:04 +0200 Subject: [PATCH 1412/1831] Add missing return type annotation for Outcome.result() --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 5007f89f3..7fdf1982d 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -160,7 +160,7 @@ class Outcome: winner: Optional[Color] """The winning color or ``None`` if drawn.""" - def result(self): + def result(self) -> str: """Returns ``1-0``, ``0-1`` or ``1/2-1/2``.""" return "1/2-1/2" if self.winner is None else ("1-0" if self.winner else "0-1") From 0454153f8e09666924ab6c47cc8cc322248a2617 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 00:37:59 +0200 Subject: [PATCH 1413/1831] GameEnd -> Termination --- chess/__init__.py | 24 ++++++++++++------------ docs/core.rst | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 7fdf1982d..ca7446c58 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -123,7 +123,7 @@ class Status(enum.IntFlag): STATUS_IMPOSSIBLE_CHECK = Status.IMPOSSIBLE_CHECK -class GameEnd(enum.Enum): +class Termination(enum.Enum): """Reasons for a game to be over.""" Checkmate = 1 @@ -154,7 +154,7 @@ class Outcome: :func:`chess.Board.outcome()`. """ - end: GameEnd + termination: Termination """The reason for the game to have ended.""" winner: Optional[Color] @@ -1893,32 +1893,32 @@ def outcome(self, *, claim_draw: bool = False) -> Optional[Outcome]: """ # Variant support. if self.is_variant_loss(): - return Outcome(GameEnd.VariantLoss, not self.turn) + return Outcome(Termination.VariantLoss, not self.turn) if self.is_variant_win(): - return Outcome(GameEnd.VariantWin, self.turn) + return Outcome(Termination.VariantWin, self.turn) if self.is_variant_draw(): - return Outcome(GameEnd.VariantDraw, None) + return Outcome(Termination.VariantDraw, None) # Normal game end. if self.is_checkmate(): - return Outcome(GameEnd.Checkmate, not self.turn) + return Outcome(Termination.Checkmate, not self.turn) if self.is_insufficient_material(): - return Outcome(GameEnd.InsufficientMaterial, None) + return Outcome(Termination.InsufficientMaterial, None) if not any(self.generate_legal_moves()): - return Outcome(GameEnd.Stalemate, None) + return Outcome(Termination.Stalemate, None) # Automatic draws. if self.is_seventyfive_moves(): - return Outcome(GameEnd.SeventyfiveMoves, None) + return Outcome(Termination.SeventyfiveMoves, None) if self.is_fivefold_repetition(): - return Outcome(GameEnd.FivefoldRepetition, None) + return Outcome(Termination.FivefoldRepetition, None) # Claimable draws. if claim_draw: if self.can_claim_fifty_moves(): - return Outcome(GameEnd.FiftyMoves, None) + return Outcome(Termination.FiftyMoves, None) if self.can_claim_threefold_repetition(): - return Outcome(GameEnd.ThreefoldRepetition, None) + return Outcome(Termination.ThreefoldRepetition, None) return None diff --git a/docs/core.rst b/docs/core.rst index 162ab9006..ef7d3005a 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -118,7 +118,7 @@ Outcome .. autoclass:: chess.Outcome :members: -.. autoclass:: chess.GameEnd +.. autoclass:: chess.Termination :members: Square sets From 8e701104cf8cf6cb396eb3415fb7e99cc73f988b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 00:42:46 +0200 Subject: [PATCH 1414/1831] Minor doc tweaks for board.outcome() --- chess/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index ca7446c58..75d0da14e 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -124,7 +124,7 @@ class Status(enum.IntFlag): class Termination(enum.Enum): - """Reasons for a game to be over.""" + """Enum with reasons for a game to be over.""" Checkmate = 1 """See :func:`chess.Board.is_checkmate()`.""" @@ -1880,7 +1880,8 @@ def outcome(self, *, claim_draw: bool = False) -> Optional[Outcome]: the :func:`seventyfive-move rule `, :func:`fivefold repetition `, or a :func:`variant end condition `. - Returns the :class:`chess.Outcome` if the game has ended or ``None``. + Returns the :class:`chess.Outcome` if the game has ended, otherwise + ``None``. Alternatively, use :func:`~chess.Board.is_game_over()` if you are not interested in who won the game and why. From 0f5817296f72c20240b1beac479e70771c037963 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 00:44:55 +0200 Subject: [PATCH 1415/1831] Update REAMDE.rst after GameEnd -> Termination --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 6dc9761ad..ce8418980 100644 --- a/README.rst +++ b/README.rst @@ -131,7 +131,7 @@ Features >>> board.is_insufficient_material() False >>> board.outcome() - Outcome(end=, winner=True) + Outcome(termination=, winner=True) * Detects repetitions. Has a half-move clock. From 666749732b9f2df94d454a62481f774a8e88697c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 11:45:16 +0200 Subject: [PATCH 1416/1831] More idiomatic CommandState enum --- chess/engine.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index d6d4e8876..d904249a7 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1020,7 +1020,7 @@ async def communicate(self: ProtocolT, command_factory: Callable[[ProtocolT], Ba if self.returncode.done(): raise EngineTerminatedError(f"engine process dead (exit code: {self.returncode.result()})") - assert command.state == CommandState.New + assert command.state == CommandState.NEW if self.next_command is not None: self.next_command.result.cancel() @@ -1198,26 +1198,26 @@ async def popen(cls: Type[ProtocolT], command: Union[str, List[str]], *, setpgrp class CommandState(enum.Enum): - New = 1 - Active = 2 - Cancelling = 3 - Done = 4 + NEW = enum.auto() + ACTIVE = enum.auto() + CANCELLING = enum.auto() + DONE = enum.auto() class BaseCommand(Generic[ProtocolT, T]): def __init__(self, engine: ProtocolT) -> None: - self.state = CommandState.New + self.state = CommandState.NEW self.result: asyncio.Future[T] = asyncio.Future() self.finished: asyncio.Future[None] = asyncio.Future() def _engine_terminated(self, engine: ProtocolT, code: int) -> None: exc = EngineTerminatedError(f"engine process died unexpectedly (exit code: {code})") - if self.state == CommandState.Active: + if self.state == CommandState.ACTIVE: self.engine_terminated(engine, exc) - elif self.state == CommandState.Cancelling: + elif self.state == CommandState.CANCELLING: self.finished.set_result(None) - elif self.state == CommandState.New: + elif self.state == CommandState.NEW: self._handle_exception(engine, exc) def _handle_exception(self, engine: ProtocolT, exc: Exception) -> None: @@ -1235,21 +1235,21 @@ def _handle_exception(self, engine: ProtocolT, exc: Exception) -> None: self.finished.set_result(None) def set_finished(self) -> None: - assert self.state in [CommandState.Active, CommandState.Cancelling] + assert self.state in [CommandState.ACTIVE, CommandState.CANCELLING] if not self.result.done(): self.result.set_exception(EngineError(f"engine command finished before returning result: {self!r}")) self.finished.set_result(None) - self.state = CommandState.Done + self.state = CommandState.DONE def _cancel(self, engine: ProtocolT) -> None: - if self.state != CommandState.Cancelling and self.state != CommandState.Done: - assert self.state == CommandState.Active - self.state = CommandState.Cancelling + if self.state != CommandState.CANCELLING and self.state != CommandState.DONE: + assert self.state == CommandState.ACTIVE + self.state = CommandState.CANCELLING self.cancel(engine) def _start(self, engine: ProtocolT) -> None: - assert self.state == CommandState.New - self.state = CommandState.Active + assert self.state == CommandState.NEW + self.state = CommandState.ACTIVE try: self.check_initialized(engine) self.start(engine) @@ -1257,7 +1257,7 @@ def _start(self, engine: ProtocolT) -> None: self._handle_exception(engine, err) def _line_received(self, engine: ProtocolT, line: str) -> None: - assert self.state in [CommandState.Active, CommandState.Cancelling] + assert self.state in [CommandState.ACTIVE, CommandState.CANCELLING] try: self.line_received(engine, line) except EngineError as err: From b93984349393c49e0d9991eda9583df7f6fc5011 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 11:51:34 +0200 Subject: [PATCH 1417/1831] More idiomatic Termination enum --- chess/__init__.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 75d0da14e..8aeb83833 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -126,25 +126,25 @@ class Status(enum.IntFlag): class Termination(enum.Enum): """Enum with reasons for a game to be over.""" - Checkmate = 1 + CHECKMATE = enum.auto() """See :func:`chess.Board.is_checkmate()`.""" - Stalemate = 2 + STALEMATE = enum.auto() """See :func:`chess.Board.is_stalemate()`.""" - InsufficientMaterial = 3 + INSUFFICIENT_MATERIAL = enum.auto() """See :func:`chess.Board.is_insufficient_material()`.""" - SeventyfiveMoves = 4 + SEVENTYFIVE_MOVES = enum.auto() """See :func:`chess.Board.is_seventyfive_moves()`.""" - FivefoldRepetition = 5 + FIVEFOLD_REPETITION = enum.auto() """See :func:`chess.Board.is_fivefold_repetition()`.""" - FiftyMoves = 6 + FIFTY_MOVES = enum.auto() """See :func:`chess.Board.can_claim_fifty_moves()`.""" - ThreefoldRepetition = 7 + THREEFOLD_REPETITION = enum.auto() """See :func:`chess.Board.can_claim_threefold_repetition()`.""" - VariantWin = 8 + VARIANT_WIN = enum.auto() """See :func:`chess.Board.is_variant_win()`.""" - VariantLoss = 9 + VARIANT_LOSS = enum.auto() """See :func:`chess.Board.is_variant_loss()`.""" - VariantDraw = 10 + VARIANT_DRAW = enum.auto() """See :func:`chess.Board.is_variant_draw()`.""" @dataclasses.dataclass @@ -1894,32 +1894,32 @@ def outcome(self, *, claim_draw: bool = False) -> Optional[Outcome]: """ # Variant support. if self.is_variant_loss(): - return Outcome(Termination.VariantLoss, not self.turn) + return Outcome(Termination.VARIANT_LOSS, not self.turn) if self.is_variant_win(): - return Outcome(Termination.VariantWin, self.turn) + return Outcome(Termination.VARIANT_WIN, self.turn) if self.is_variant_draw(): - return Outcome(Termination.VariantDraw, None) + return Outcome(Termination.VARIANT_DRAW, None) # Normal game end. if self.is_checkmate(): - return Outcome(Termination.Checkmate, not self.turn) + return Outcome(Termination.CHECKMATE, not self.turn) if self.is_insufficient_material(): - return Outcome(Termination.InsufficientMaterial, None) + return Outcome(Termination.INSUFFICIENT_MATERIAL, None) if not any(self.generate_legal_moves()): - return Outcome(Termination.Stalemate, None) + return Outcome(Termination.STALEMATE, None) # Automatic draws. if self.is_seventyfive_moves(): - return Outcome(Termination.SeventyfiveMoves, None) + return Outcome(Termination.SEVENTYFIVE_MOVES, None) if self.is_fivefold_repetition(): - return Outcome(Termination.FivefoldRepetition, None) + return Outcome(Termination.FIVEFOLD_REPETITION, None) # Claimable draws. if claim_draw: if self.can_claim_fifty_moves(): - return Outcome(Termination.FiftyMoves, None) + return Outcome(Termination.FIFTY_MOVES, None) if self.can_claim_threefold_repetition(): - return Outcome(Termination.ThreefoldRepetition, None) + return Outcome(Termination.THREEFOLD_REPETITION, None) return None From fb513c595522c4a658aeba4cc4a006cfa2d2c410 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 11:54:11 +0200 Subject: [PATCH 1418/1831] Update README after Termination enum tweak --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ce8418980..0e2c59363 100644 --- a/README.rst +++ b/README.rst @@ -131,7 +131,7 @@ Features >>> board.is_insufficient_material() False >>> board.outcome() - Outcome(termination=, winner=True) + Outcome(termination=, winner=True) * Detects repetitions. Has a half-move clock. From 465d15ef883f24e3c114b444a32c75a02290243f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 6 Apr 2021 12:12:39 +0200 Subject: [PATCH 1419/1831] Prepare changelog --- CHANGELOG.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 24d945021..ab1962ee9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,33 @@ Changelog for python-chess ========================== +Upcoming in the next release +---------------------------- + +Bugfixes: + +* Fixed typing of ``chess.pgn.Mainline.__reversed__()``. It is now a generator, + and ``chess.pgn.ReverseMainline`` has been **removed**. + This is a breaking change but a required bugfix. +* Implement **ponderhit** for consecutive pondering calls to + ``chess.engine.Protocol.play(..., ponder=True)``. Previously, the pondering + search was always stopped and restarted. +* Provide the full move stack, not just the position, for UCI pondering. +* Fixed XBoard level in sudden death games. +* Ignore trailing space after ponder move sent by UCI engine. + Previously, such a move would be rejected. +* Prevent cancelling engine commands after they have already been cancelled or + completed. Some internals (``chess.engine.BaseCommand``) have been changed to + accomplish this. + +New features: + +* Added ``chess.Board.outcome()``. +* Implement and accept usermove festure for XBoard engines. + +Special thanks to @MarkZH for many of the engine related changes in this +release! + New in v1.4.0 ------------- From d2ba61c80326eadab728ceaf9bb2dd0c8d5f800d Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 6 Apr 2021 20:09:25 -0700 Subject: [PATCH 1420/1831] Spelling correction --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ab1962ee9..dfe66d2e5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,7 +23,7 @@ Bugfixes: New features: * Added ``chess.Board.outcome()``. -* Implement and accept usermove festure for XBoard engines. +* Implement and accept usermove feature for XBoard engines. Special thanks to @MarkZH for many of the engine related changes in this release! From abd0fc4d0b07dbb86009e0a089e796f918ae732b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 7 Apr 2021 10:42:27 +0200 Subject: [PATCH 1421/1831] Prepare 1.5.0 --- CHANGELOG.rst | 6 +++--- chess/__init__.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index dfe66d2e5..5eb6fac96 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,15 +1,15 @@ Changelog for python-chess ========================== -Upcoming in the next release ----------------------------- +New in v1.5.0 +------------- Bugfixes: * Fixed typing of ``chess.pgn.Mainline.__reversed__()``. It is now a generator, and ``chess.pgn.ReverseMainline`` has been **removed**. This is a breaking change but a required bugfix. -* Implement **ponderhit** for consecutive pondering calls to +* Implement UCI **ponderhit** for consecutive calls to ``chess.engine.Protocol.play(..., ponder=True)``. Previously, the pondering search was always stopped and restarted. * Provide the full move stack, not just the position, for UCI pondering. diff --git a/chess/__init__.py b/chess/__init__.py index 8aeb83833..ac4d48ff1 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.4.0" +__version__ = "1.5.0" import collections import copy From 31d57f7f0ac24a9b2f92017678f9394d87f9ca4e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 10 Apr 2021 09:02:35 +0200 Subject: [PATCH 1422/1831] Better error message for #767 --- chess/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index ac4d48ff1..793d1aed1 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -661,6 +661,8 @@ def pieces_mask(self, piece_type: PieceType, color: Color) -> Bitboard: bb = self.queens elif piece_type == KING: bb = self.kings + else: + assert False, f"expected PieceType, got {piece_type!r}" return bb & self.occupied_co[color] From 6cf47a83d67711b89b251a78e7c3d6c326357b21 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 17 Apr 2021 20:01:02 +0200 Subject: [PATCH 1423/1831] Link https://healeycodes.com/building-my-own-chess-engine/ --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 0e2c59363..f02d0e584 100644 --- a/README.rst +++ b/README.rst @@ -336,6 +336,7 @@ If you like, share interesting things you are using python-chess for, for exampl * a bridge between Lichess API and chess engines – https://github.com/careless25/lichess-bot * a command-line PGN annotator – https://github.com/rpdelaney/python-chess-annotator * an HTTP microservice to render board images – https://github.com/niklasf/web-boardimage +* building a toy chess engine with alpha-beta pruning, piece-square tables, and move ordering – https://healeycodes.com/building-my-own-chess-engine/ * a JIT compiled chess engine – https://github.com/SamRagusa/Batch-First * teaching Cognitive Science – `https://jupyter.brynmawr.edu `_ * an `Alexa skill to play blindfold chess `_ – https://github.com/laynr/blindfold-chess From 0bac87950dfb48a161d99224bd8ed3de4a3d4cff Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 25 Apr 2021 17:46:56 +0200 Subject: [PATCH 1424/1831] Try GitHub sponsors --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..7e1e93611 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: niklasf From a02b7d7719b4c288cadc76c51b83c449bdeaa531 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 29 Apr 2021 12:33:08 +0200 Subject: [PATCH 1425/1831] Make setpgrp more amicable --- chess/engine.py | 8 +++----- test.py | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index d904249a7..729272ce7 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1180,19 +1180,17 @@ async def quit(self) -> None: """Asks the engine to shut down.""" @classmethod - async def popen(cls: Type[ProtocolT], command: Union[str, List[str]], *, setpgrp: bool = False, **kwargs: Any) -> Tuple[asyncio.SubprocessTransport, ProtocolT]: + async def popen(cls: Type[ProtocolT], command: Union[str, List[str]], *, setpgrp: bool = False, **popen_args: Any) -> Tuple[asyncio.SubprocessTransport, ProtocolT]: if not isinstance(command, list): command = [command] - popen_args = {} if setpgrp: try: # Windows. - popen_args["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore + popen_args["creationflags"] = popen_args.get("creationflags", 0) | subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore except AttributeError: # Unix. - popen_args["preexec_fn"] = os.setpgrp - popen_args.update(kwargs) + popen_args["start_new_session"] = True return await asyncio.get_running_loop().subprocess_exec(cls, *command, **popen_args) # type: ignore diff --git a/test.py b/test.py index 383e5101c..d46317158 100755 --- a/test.py +++ b/test.py @@ -2893,7 +2893,7 @@ def test_sf_options(self): @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_analysis(self): - with chess.engine.SimpleEngine.popen_uci("stockfish", debug=True) as engine: + with chess.engine.SimpleEngine.popen_uci("stockfish", setpgrp=True, debug=True) as engine: board = chess.Board("8/6K1/1p1B1RB1/8/2Q5/2n1kP1N/3b4/4n3 w - - 0 1") limit = chess.engine.Limit(depth=26) analysis = engine.analysis(board, limit) @@ -2932,7 +2932,7 @@ def test_sf_multipv(self): @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_quit(self): - engine = chess.engine.SimpleEngine.popen_uci("stockfish", debug=True) + engine = chess.engine.SimpleEngine.popen_uci("stockfish", setpgrp=True, debug=True) with engine: engine.quit() @@ -2945,7 +2945,7 @@ def test_crafty_play_to_mate(self): logging.disable(logging.WARNING) try: with tempfile.TemporaryDirectory(prefix="crafty") as tmpdir: - with chess.engine.SimpleEngine.popen_xboard("crafty", debug=True, cwd=tmpdir) as engine: + with chess.engine.SimpleEngine.popen_xboard("crafty", setpgrp=True, debug=True, cwd=tmpdir) as engine: board = chess.Board("2bqkbn1/2pppp2/np2N3/r3P1p1/p2N2B1/5Q2/PPPPKPP1/RNB2r2 w KQkq - 0 1") limit = chess.engine.Limit(depth=10) while not board.is_game_over() and len(board.move_stack) < 5: From bbbaac9f046723d922a4f81c58bd2033c64ba3f7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 29 Apr 2021 21:16:04 +0200 Subject: [PATCH 1426/1831] Link UCI/XBoard specs --- docs/engine.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/engine.rst b/docs/engine.rst index 7637c116e..2a8a2a4c7 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -1,7 +1,9 @@ UCI/XBoard engine communication =============================== -UCI and XBoard are protocols for communicating with chess engines. This module +The `Universal chess interface (UCI) `_ +and `XBoard protocol `_ +are standards for communicating with chess engines. This module implements an abstraction for playing moves and analysing positions with both kinds of engines. From e28da7a76b5b33746107e820621be5cad894a36d Mon Sep 17 00:00:00 2001 From: stevepapazis Date: Mon, 3 May 2021 12:03:30 +0300 Subject: [PATCH 1427/1831] Implementation of HordeBoard.has_insufficient_material --- chess/variant.py | 201 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 199 insertions(+), 2 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index 23de858e8..0b31b55ee 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -457,9 +457,206 @@ def is_variant_win(self) -> bool: return bool(self.occupied) and not self.occupied_co[not self.turn] def has_insufficient_material(self, color: chess.Color) -> bool: - # TODO: Could detect some cases where the Horde can no longer mate. - return False + # The side with the king can always win by capturing the horde. + if color == chess.BLACK: + return False + + white = self.occupied_co[chess.WHITE] + queens = chess.popcount( white & self.queens ) + pawns = chess.popcount( white & self.pawns ) + rooks = chess.popcount( white & self.rooks ) + bishops = chess.popcount( white & self.bishops ) + knights = chess.popcount( white & self.knights ) + horde_darkb = chess.popcount(chess.BB_DARK_SQUARES & white & self.bishops) + horde_lightb = chess.popcount(chess.BB_LIGHT_SQUARES & white & self.bishops) + horde_bishop_co = lambda : chess.WHITE if horde_lightb >= 1 else chess.BLACK + horde_num = ( + pawns + knights + rooks + queens + + (horde_darkb if horde_darkb <= 2 else 2) + + (horde_lightb if horde_lightb <= 2 else 2) + ) + # Two same color bishops suffice to cover all the light and dark squares around the enemy king. + + pieces = self.occupied_co[chess.BLACK] + pieces_pawns = chess.popcount( pieces & self.pawns ) + pieces_bishops = chess.popcount( pieces & self.bishops ) + pieces_knights = chess.popcount( pieces & self.knights ) + pieces_rooks = chess.popcount( pieces & self.rooks ) + pieces_queens = chess.popcount( pieces & self.queens ) + pieces_darkb = lambda : chess.popcount(chess.BB_DARK_SQUARES & pieces & self.bishops) + pieces_lightb = lambda : chess.popcount(chess.BB_LIGHT_SQUARES & pieces & self.bishops) + pieces_num = chess.popcount(pieces) + pieces_oppositeb_of = lambda square_color: pieces_darkb() if square_color == chess.WHITE else pieces_lightb() + pieces_sameb_as = lambda square_color: pieces_lightb() if square_color == chess.WHITE else pieces_darkb() + pieces_of_type_not = lambda piece: pieces_num - piece + has_bishop_pair = lambda side: (horde_lightb >= 1 and horde_darkb >= 1) if side == chess.WHITE else (pieces_lightb() >= 1 and pieces_darkb() >= 1) + + if horde_num == 0: + return True + if horde_num >= 4: + # Four or more white pieces can always deliver mate. + return False + + if (pawns >= 1 or queens >= 1) and horde_num >= 2: + # Pawns/queens are never insufficient material when paired with any other + # piece (a pawn promotes to a queen and delivers mate). + return False + + if rooks >= 1 and horde_num >= 2: + # A rook is insufficient material only when it is paired with a bishop + # against a lone king. The horde can mate in any other case. + # A rook on A1 and a bishop on C3 mate a king on B1 when there is a + # friendly pawn/opposite-color-bishop/rook/queen on C2. + # A rook on B8 and a bishop C3 mate a king on A1 when there is a friendly + # knight on A2. + if not (horde_num == 2 and rooks == 1 and bishops == 1 and pieces_of_type_not(pieces_sameb_as(horde_bishop_co())) == 1): + return False + + if horde_num == 1: + if pieces_num == 1: + # A lone piece cannot mate a lone king. + return True + elif queens == 1: + # The horde has a lone queen. + # A lone queen mates a king on A1 bounded by: + # -- a pawn/rook on A2 + # -- two same color bishops on A2, B1 + # We ignore every other mating case, since it can be reduced to + # the two previous cases (e.g. a black pawn on A2 and a black + # bishop on B1). + return not ( + pieces_pawns >= 1 or + pieces_rooks >= 1 or + pieces_lightb() >= 2 or + pieces_darkb() >= 2 + ) + elif pawns == 1: + # Promote the pawn to a queen or a knight and check whether white + # can mate. + pawn_square = chess.SquareSet(self.pawns & white).pop() + promote_to_queen = HordeBoard(self.fen()) + promote_to_queen.set_piece_at( pawn_square, chess.Piece(chess.QUEEN,chess.WHITE) ) + promote_to_knight = HordeBoard(self.fen()) + promote_to_knight.set_piece_at( pawn_square, chess.Piece(chess.KNIGHT,chess.WHITE) ) + return promote_to_queen.has_insufficient_material(chess.WHITE) and promote_to_knight.has_insufficient_material(chess.WHITE) + elif rooks == 1: + # A lone rook mates a king on A8 bounded by a pawn/rook on A7 and a + # pawn/knight on B7. We ignore every other case, since it can be + # reduced to the two previous cases. + # (e.g. three pawns on A7, B7, C7) + return not ( + pieces_pawns >= 2 or + (pieces_rooks >= 1 and pieces_pawns >= 1) or + (pieces_rooks >= 1 and pieces_knights >= 1) or + (pieces_pawns >= 1 and pieces_knights >= 1) + ) + elif bishops == 1: + # The horde has a lone bishop. + return not ( + # The king can be mated on A1 if there is a pawn/opposite-color-bishop + # on A2 and an opposite-color-bishop on B1. + # If black has two or more pawns, white gets the benefit of the doubt; + # there is an outside chance that white promotes its pawns to + # opposite-color-bishops and selfmates theirself. + # Every other case that the king is mated by the bishop requires that + # black has two pawns or two opposite-color-bishop or a pawn and an + # opposite-color-bishop. + # For example a king on A3 can be mated if there is + # a pawn/opposite-color-bishop on A4, a pawn/opposite-color-bishop on + # B3, a pawn/bishop/rook/queen on A2 and any other piece on B2. + pieces_oppositeb_of(horde_bishop_co()) >= 2 or + (pieces_oppositeb_of(horde_bishop_co()) >= 1 and pieces_pawns >= 1) or + pieces_pawns >= 2 + ) + elif knights == 1: + # The horde has a lone knight. + return not ( + # The king on A1 can be smother mated by a knight on C2 if there is + # a pawn/knight/bishop on B2, a knight/rook on B1 and any other piece + # on A2. + # Moreover, when black has four or more pieces and two of them are + # pawns, black can promote their pawns and selfmate theirself. + pieces_num >= 4 and ( + pieces_knights>=2 or pieces_pawns>=2 or + (pieces_rooks>=1 and pieces_knights>=1) or + (pieces_rooks>=1 and pieces_bishops>=1) or + (pieces_knights>=1 and pieces_bishops>=1) or + (pieces_rooks>=1 and pieces_pawns>=1) or + (pieces_knights>=1 and pieces_pawns>=1) or + (pieces_bishops>=1 and pieces_pawns>=1) or + (has_bishop_pair(chess.BLACK) and pieces_pawns>=1) + ) and ( pieces_of_type_not(pieces_darkb())>=3 if pieces_darkb()>=2 else True ) + and ( pieces_of_type_not(pieces_lightb())>=3 if pieces_lightb()>=2 else True ) + ) + + # By this point, we only need to deal with white's minor pieces. + + elif horde_num == 2: + + if pieces_num == 1: + # Two minor pieces cannot mate a lone king. + return True + elif knights == 2: + # A king on A1 is mated by two knights, if it is obstructed by a + # pawn/bishop/knight on B2. On the other hand, if black only has + # major pieces it is a draw. + return not (pieces_pawns + pieces_bishops + pieces_knights >= 1) + elif has_bishop_pair(chess.WHITE): + return not ( + # A king on A1 obstructed by a pawn/bishop on A2 is mated + # by the bishop pair. + pieces_pawns >= 1 or pieces_bishops >= 1 or + # A pawn/bishop/knight on B4, a pawn/bishop/rook/queen on + # A4 and the king on A3 enable Boden's mate by the bishop + # pair. In every other case white cannot win. + ( pieces_knights >= 1 and pieces_rooks + pieces_queens >= 1 ) + ) + elif bishops >= 1 and knights >= 1: + # The horde has a bishop and a knight. + return not ( + # A king on A1 obstructed by a pawn/opposite-color-bishop on + # A2 is mated by a knight on D2 and a bishop on C3. + pieces_pawns >= 1 or pieces_oppositeb_of(horde_bishop_co()) >= 1 or + # A king on A1 bounded by two friendly pieces on A2 and B1 is + # mated when the knight moves from D4 to C2 so that both the + # knight and the bishop deliver check. + pieces_of_type_not( pieces_sameb_as(horde_bishop_co()) ) >=3 + ) + else: + # The horde has two or more bishops on the same color. + # White can only win if black has enough material to obstruct + # the squares of the opposite color around the king. + return not ( + # A king on A1 obstructed by a pawn/opposite-bishop/knight + # on A2 and a opposite-bishop/knight on B1 is mated by two + # bishops on B2 and C3. This position is theoretically + # achievable even when black has two pawns or when they + # have a pawn and an opposite color bishop. + ( pieces_pawns >= 1 and pieces_oppositeb_of(horde_bishop_co()) >= 1 ) or + ( pieces_pawns >= 1 and pieces_knights >= 1 ) or + ( pieces_oppositeb_of(horde_bishop_co()) >= 1 and pieces_knights >= 1 ) or + ( pieces_oppositeb_of(horde_bishop_co()) >= 2 ) or + pieces_knights >= 2 or + pieces_pawns >= 2 + # In every other case, white can only draw. + ) + + elif horde_num == 3: + # A king in the corner is mated by two knights and a bishop or three + # knights or the bishop pair and a knight/bishop. + if (knights == 2 and bishops == 1) or knights == 3 or has_bishop_pair(chess.WHITE): + return False + else: + # White has two same color bishops and a knight. + # A king on A1 is mated by a bishop on B2, a bishop on C1 and a + # knight on C3, as long as there is another black piece to waste + # a tempo. + return pieces_num == 1 + + return True + + def status(self) -> chess.Status: status = super().status() status &= ~chess.STATUS_NO_WHITE_KING From d9f77610c52cd4afc28506ffeaec79c63384274d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 11 May 2021 11:52:39 +0200 Subject: [PATCH 1428/1831] Match coding style --- chess/variant.py | 205 ++++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 100 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index 0b31b55ee..658d7f105 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -457,35 +457,40 @@ def is_variant_win(self) -> bool: return bool(self.occupied) and not self.occupied_co[not self.turn] def has_insufficient_material(self, color: chess.Color) -> bool: - # The side with the king can always win by capturing the horde. + # The side with the king can always win by capturing the Horde. if color == chess.BLACK: return False + # See https://github.com/stevepapazis/horde-insufficient-material-tests + # for how the following has been derived. + white = self.occupied_co[chess.WHITE] - queens = chess.popcount( white & self.queens ) - pawns = chess.popcount( white & self.pawns ) - rooks = chess.popcount( white & self.rooks ) - bishops = chess.popcount( white & self.bishops ) - knights = chess.popcount( white & self.knights ) + queens = chess.popcount(white & self.queens) + pawns = chess.popcount(white & self.pawns) + rooks = chess.popcount(white & self.rooks) + bishops = chess.popcount(white & self.bishops) + knights = chess.popcount(white & self.knights) + + # Two same color bishops suffice to cover all the light and dark + # squares around the enemy king. horde_darkb = chess.popcount(chess.BB_DARK_SQUARES & white & self.bishops) horde_lightb = chess.popcount(chess.BB_LIGHT_SQUARES & white & self.bishops) - horde_bishop_co = lambda : chess.WHITE if horde_lightb >= 1 else chess.BLACK + horde_bishop_co = lambda: chess.WHITE if horde_lightb >= 1 else chess.BLACK horde_num = ( pawns + knights + rooks + queens + (horde_darkb if horde_darkb <= 2 else 2) + (horde_lightb if horde_lightb <= 2 else 2) - ) - # Two same color bishops suffice to cover all the light and dark squares around the enemy king. + ) pieces = self.occupied_co[chess.BLACK] - pieces_pawns = chess.popcount( pieces & self.pawns ) - pieces_bishops = chess.popcount( pieces & self.bishops ) - pieces_knights = chess.popcount( pieces & self.knights ) - pieces_rooks = chess.popcount( pieces & self.rooks ) - pieces_queens = chess.popcount( pieces & self.queens ) - pieces_darkb = lambda : chess.popcount(chess.BB_DARK_SQUARES & pieces & self.bishops) - pieces_lightb = lambda : chess.popcount(chess.BB_LIGHT_SQUARES & pieces & self.bishops) - pieces_num = chess.popcount(pieces) + pieces_pawns = chess.popcount(pieces & self.pawns) + pieces_bishops = chess.popcount(pieces & self.bishops) + pieces_knights = chess.popcount(pieces & self.knights) + pieces_rooks = chess.popcount(pieces & self.rooks) + pieces_queens = chess.popcount(pieces & self.queens) + pieces_darkb = lambda: chess.popcount(chess.BB_DARK_SQUARES & pieces & self.bishops) + pieces_lightb = lambda: chess.popcount(chess.BB_LIGHT_SQUARES & pieces & self.bishops) + pieces_num = chess.popcount(pieces) pieces_oppositeb_of = lambda square_color: pieces_darkb() if square_color == chess.WHITE else pieces_lightb() pieces_sameb_as = lambda square_color: pieces_lightb() if square_color == chess.WHITE else pieces_darkb() pieces_of_type_not = lambda piece: pieces_num - piece @@ -494,16 +499,16 @@ def has_insufficient_material(self, color: chess.Color) -> bool: if horde_num == 0: return True - if horde_num >= 4: + if horde_num >= 4: # Four or more white pieces can always deliver mate. return False - + if (pawns >= 1 or queens >= 1) and horde_num >= 2: # Pawns/queens are never insufficient material when paired with any other # piece (a pawn promotes to a queen and delivers mate). return False - - if rooks >= 1 and horde_num >= 2: + + if rooks >= 1 and horde_num >= 2: # A rook is insufficient material only when it is paired with a bishop # against a lone king. The horde can mate in any other case. # A rook on A1 and a bishop on C3 mate a king on B1 when there is a @@ -520,25 +525,25 @@ def has_insufficient_material(self, color: chess.Color) -> bool: elif queens == 1: # The horde has a lone queen. # A lone queen mates a king on A1 bounded by: - # -- a pawn/rook on A2 - # -- two same color bishops on A2, B1 + # - a pawn/rook on A2 + # - two same color bishops on A2, B1 # We ignore every other mating case, since it can be reduced to # the two previous cases (e.g. a black pawn on A2 and a black # bishop on B1). return not ( - pieces_pawns >= 1 or - pieces_rooks >= 1 or - pieces_lightb() >= 2 or - pieces_darkb() >= 2 - ) + pieces_pawns >= 1 or + pieces_rooks >= 1 or + pieces_lightb() >= 2 or + pieces_darkb() >= 2 + ) elif pawns == 1: - # Promote the pawn to a queen or a knight and check whether white - # can mate. + # Promote the pawn to a queen or a knight and check whether + # white can mate. pawn_square = chess.SquareSet(self.pawns & white).pop() promote_to_queen = HordeBoard(self.fen()) - promote_to_queen.set_piece_at( pawn_square, chess.Piece(chess.QUEEN,chess.WHITE) ) + promote_to_queen.set_piece_at(pawn_square, chess.Piece(chess.QUEEN, chess.WHITE)) promote_to_knight = HordeBoard(self.fen()) - promote_to_knight.set_piece_at( pawn_square, chess.Piece(chess.KNIGHT,chess.WHITE) ) + promote_to_knight.set_piece_at(pawn_square, chess.Piece(chess.KNIGHT, chess.WHITE)) return promote_to_queen.has_insufficient_material(chess.WHITE) and promote_to_knight.has_insufficient_material(chess.WHITE) elif rooks == 1: # A lone rook mates a king on A8 bounded by a pawn/rook on A7 and a @@ -550,51 +555,52 @@ def has_insufficient_material(self, color: chess.Color) -> bool: (pieces_rooks >= 1 and pieces_pawns >= 1) or (pieces_rooks >= 1 and pieces_knights >= 1) or (pieces_pawns >= 1 and pieces_knights >= 1) - ) + ) elif bishops == 1: # The horde has a lone bishop. return not ( - # The king can be mated on A1 if there is a pawn/opposite-color-bishop - # on A2 and an opposite-color-bishop on B1. - # If black has two or more pawns, white gets the benefit of the doubt; - # there is an outside chance that white promotes its pawns to - # opposite-color-bishops and selfmates theirself. - # Every other case that the king is mated by the bishop requires that - # black has two pawns or two opposite-color-bishop or a pawn and an - # opposite-color-bishop. - # For example a king on A3 can be mated if there is - # a pawn/opposite-color-bishop on A4, a pawn/opposite-color-bishop on - # B3, a pawn/bishop/rook/queen on A2 and any other piece on B2. - pieces_oppositeb_of(horde_bishop_co()) >= 2 or - (pieces_oppositeb_of(horde_bishop_co()) >= 1 and pieces_pawns >= 1) or - pieces_pawns >= 2 - ) + # The king can be mated on A1 if there is a pawn/opposite-color-bishop + # on A2 and an opposite-color-bishop on B1. + # If black has two or more pawns, white gets the benefit of the doubt; + # there is an outside chance that white promotes its pawns to + # opposite-color-bishops and selfmates theirself. + # Every other case that the king is mated by the bishop requires that + # black has two pawns or two opposite-color-bishop or a pawn and an + # opposite-color-bishop. + # For example a king on A3 can be mated if there is + # a pawn/opposite-color-bishop on A4, a pawn/opposite-color-bishop on + # B3, a pawn/bishop/rook/queen on A2 and any other piece on B2. + pieces_oppositeb_of(horde_bishop_co()) >= 2 or + (pieces_oppositeb_of(horde_bishop_co()) >= 1 and pieces_pawns >= 1) or + pieces_pawns >= 2 + ) elif knights == 1: # The horde has a lone knight. return not ( - # The king on A1 can be smother mated by a knight on C2 if there is - # a pawn/knight/bishop on B2, a knight/rook on B1 and any other piece - # on A2. - # Moreover, when black has four or more pieces and two of them are - # pawns, black can promote their pawns and selfmate theirself. - pieces_num >= 4 and ( - pieces_knights>=2 or pieces_pawns>=2 or - (pieces_rooks>=1 and pieces_knights>=1) or - (pieces_rooks>=1 and pieces_bishops>=1) or - (pieces_knights>=1 and pieces_bishops>=1) or - (pieces_rooks>=1 and pieces_pawns>=1) or - (pieces_knights>=1 and pieces_pawns>=1) or - (pieces_bishops>=1 and pieces_pawns>=1) or - (has_bishop_pair(chess.BLACK) and pieces_pawns>=1) - ) and ( pieces_of_type_not(pieces_darkb())>=3 if pieces_darkb()>=2 else True ) - and ( pieces_of_type_not(pieces_lightb())>=3 if pieces_lightb()>=2 else True ) - ) - + # The king on A1 can be smother mated by a knight on C2 if there is + # a pawn/knight/bishop on B2, a knight/rook on B1 and any other piece + # on A2. + # Moreover, when black has four or more pieces and two of them are + # pawns, black can promote their pawns and selfmate theirself. + pieces_num >= 4 and ( + pieces_knights >= 2 or pieces_pawns >= 2 or + (pieces_rooks >= 1 and pieces_knights >= 1) or + (pieces_rooks >= 1 and pieces_bishops >= 1) or + (pieces_knights >= 1 and pieces_bishops >= 1) or + (pieces_rooks >= 1 and pieces_pawns >= 1) or + (pieces_knights >= 1 and pieces_pawns >= 1) or + (pieces_bishops >= 1 and pieces_pawns >= 1) or + (has_bishop_pair(chess.BLACK) and pieces_pawns >= 1) + ) and + (pieces_of_type_not(pieces_darkb()) >= 3 if pieces_darkb() >= 2 else True) and + (pieces_of_type_not(pieces_lightb()) >= 3 if pieces_lightb() >= 2 else True) + ) + # By this point, we only need to deal with white's minor pieces. elif horde_num == 2: - if pieces_num == 1: + if pieces_num == 1: # Two minor pieces cannot mate a lone king. return True elif knights == 2: @@ -602,45 +608,45 @@ def has_insufficient_material(self, color: chess.Color) -> bool: # pawn/bishop/knight on B2. On the other hand, if black only has # major pieces it is a draw. return not (pieces_pawns + pieces_bishops + pieces_knights >= 1) - elif has_bishop_pair(chess.WHITE): + elif has_bishop_pair(chess.WHITE): return not ( - # A king on A1 obstructed by a pawn/bishop on A2 is mated - # by the bishop pair. - pieces_pawns >= 1 or pieces_bishops >= 1 or - # A pawn/bishop/knight on B4, a pawn/bishop/rook/queen on - # A4 and the king on A3 enable Boden's mate by the bishop - # pair. In every other case white cannot win. - ( pieces_knights >= 1 and pieces_rooks + pieces_queens >= 1 ) - ) - elif bishops >= 1 and knights >= 1: + # A king on A1 obstructed by a pawn/bishop on A2 is mated + # by the bishop pair. + pieces_pawns >= 1 or pieces_bishops >= 1 or + # A pawn/bishop/knight on B4, a pawn/bishop/rook/queen on + # A4 and the king on A3 enable Boden's mate by the bishop + # pair. In every other case white cannot win. + (pieces_knights >= 1 and pieces_rooks + pieces_queens >= 1) + ) + elif bishops >= 1 and knights >= 1: # The horde has a bishop and a knight. return not ( - # A king on A1 obstructed by a pawn/opposite-color-bishop on - # A2 is mated by a knight on D2 and a bishop on C3. - pieces_pawns >= 1 or pieces_oppositeb_of(horde_bishop_co()) >= 1 or - # A king on A1 bounded by two friendly pieces on A2 and B1 is - # mated when the knight moves from D4 to C2 so that both the - # knight and the bishop deliver check. - pieces_of_type_not( pieces_sameb_as(horde_bishop_co()) ) >=3 - ) + # A king on A1 obstructed by a pawn/opposite-color-bishop on + # A2 is mated by a knight on D2 and a bishop on C3. + pieces_pawns >= 1 or pieces_oppositeb_of(horde_bishop_co()) >= 1 or + # A king on A1 bounded by two friendly pieces on A2 and B1 is + # mated when the knight moves from D4 to C2 so that both the + # knight and the bishop deliver check. + pieces_of_type_not(pieces_sameb_as(horde_bishop_co())) >= 3 + ) else: # The horde has two or more bishops on the same color. # White can only win if black has enough material to obstruct # the squares of the opposite color around the king. return not ( - # A king on A1 obstructed by a pawn/opposite-bishop/knight - # on A2 and a opposite-bishop/knight on B1 is mated by two - # bishops on B2 and C3. This position is theoretically - # achievable even when black has two pawns or when they - # have a pawn and an opposite color bishop. - ( pieces_pawns >= 1 and pieces_oppositeb_of(horde_bishop_co()) >= 1 ) or - ( pieces_pawns >= 1 and pieces_knights >= 1 ) or - ( pieces_oppositeb_of(horde_bishop_co()) >= 1 and pieces_knights >= 1 ) or - ( pieces_oppositeb_of(horde_bishop_co()) >= 2 ) or - pieces_knights >= 2 or - pieces_pawns >= 2 - # In every other case, white can only draw. - ) + # A king on A1 obstructed by a pawn/opposite-bishop/knight + # on A2 and a opposite-bishop/knight on B1 is mated by two + # bishops on B2 and C3. This position is theoretically + # achievable even when black has two pawns or when they + # have a pawn and an opposite color bishop. + (pieces_pawns >= 1 and pieces_oppositeb_of(horde_bishop_co()) >= 1) or + (pieces_pawns >= 1 and pieces_knights >= 1) or + (pieces_oppositeb_of(horde_bishop_co()) >= 1 and pieces_knights >= 1) or + (pieces_oppositeb_of(horde_bishop_co()) >= 2) or + pieces_knights >= 2 or + pieces_pawns >= 2 + # In every other case, white can only draw. + ) elif horde_num == 3: # A king in the corner is mated by two knights and a bishop or three @@ -655,8 +661,7 @@ def has_insufficient_material(self, color: chess.Color) -> bool: return pieces_num == 1 return True - - + def status(self) -> chess.Status: status = super().status() status &= ~chess.STATUS_NO_WHITE_KING From 50bde0266c3ce0e5a3d75511e35298235a449ae1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 11 May 2021 11:55:34 +0200 Subject: [PATCH 1429/1831] Eagerly compute 0-arity lambdas --- chess/variant.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index 658d7f105..5d7608030 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -475,7 +475,7 @@ def has_insufficient_material(self, color: chess.Color) -> bool: # squares around the enemy king. horde_darkb = chess.popcount(chess.BB_DARK_SQUARES & white & self.bishops) horde_lightb = chess.popcount(chess.BB_LIGHT_SQUARES & white & self.bishops) - horde_bishop_co = lambda: chess.WHITE if horde_lightb >= 1 else chess.BLACK + horde_bishop_co = chess.WHITE if horde_lightb >= 1 else chess.BLACK horde_num = ( pawns + knights + rooks + queens + (horde_darkb if horde_darkb <= 2 else 2) + @@ -488,13 +488,13 @@ def has_insufficient_material(self, color: chess.Color) -> bool: pieces_knights = chess.popcount(pieces & self.knights) pieces_rooks = chess.popcount(pieces & self.rooks) pieces_queens = chess.popcount(pieces & self.queens) - pieces_darkb = lambda: chess.popcount(chess.BB_DARK_SQUARES & pieces & self.bishops) - pieces_lightb = lambda: chess.popcount(chess.BB_LIGHT_SQUARES & pieces & self.bishops) + pieces_darkb = chess.popcount(chess.BB_DARK_SQUARES & pieces & self.bishops) + pieces_lightb = chess.popcount(chess.BB_LIGHT_SQUARES & pieces & self.bishops) pieces_num = chess.popcount(pieces) - pieces_oppositeb_of = lambda square_color: pieces_darkb() if square_color == chess.WHITE else pieces_lightb() - pieces_sameb_as = lambda square_color: pieces_lightb() if square_color == chess.WHITE else pieces_darkb() + pieces_oppositeb_of = lambda square_color: pieces_darkb if square_color == chess.WHITE else pieces_lightb + pieces_sameb_as = lambda square_color: pieces_lightb if square_color == chess.WHITE else pieces_darkb pieces_of_type_not = lambda piece: pieces_num - piece - has_bishop_pair = lambda side: (horde_lightb >= 1 and horde_darkb >= 1) if side == chess.WHITE else (pieces_lightb() >= 1 and pieces_darkb() >= 1) + has_bishop_pair = lambda side: (horde_lightb >= 1 and horde_darkb >= 1) if side == chess.WHITE else (pieces_lightb >= 1 and pieces_darkb >= 1) if horde_num == 0: return True @@ -515,7 +515,7 @@ def has_insufficient_material(self, color: chess.Color) -> bool: # friendly pawn/opposite-color-bishop/rook/queen on C2. # A rook on B8 and a bishop C3 mate a king on A1 when there is a friendly # knight on A2. - if not (horde_num == 2 and rooks == 1 and bishops == 1 and pieces_of_type_not(pieces_sameb_as(horde_bishop_co())) == 1): + if not (horde_num == 2 and rooks == 1 and bishops == 1 and pieces_of_type_not(pieces_sameb_as(horde_bishop_co)) == 1): return False if horde_num == 1: @@ -533,8 +533,8 @@ def has_insufficient_material(self, color: chess.Color) -> bool: return not ( pieces_pawns >= 1 or pieces_rooks >= 1 or - pieces_lightb() >= 2 or - pieces_darkb() >= 2 + pieces_lightb >= 2 or + pieces_darkb >= 2 ) elif pawns == 1: # Promote the pawn to a queen or a knight and check whether @@ -570,8 +570,8 @@ def has_insufficient_material(self, color: chess.Color) -> bool: # For example a king on A3 can be mated if there is # a pawn/opposite-color-bishop on A4, a pawn/opposite-color-bishop on # B3, a pawn/bishop/rook/queen on A2 and any other piece on B2. - pieces_oppositeb_of(horde_bishop_co()) >= 2 or - (pieces_oppositeb_of(horde_bishop_co()) >= 1 and pieces_pawns >= 1) or + pieces_oppositeb_of(horde_bishop_co) >= 2 or + (pieces_oppositeb_of(horde_bishop_co) >= 1 and pieces_pawns >= 1) or pieces_pawns >= 2 ) elif knights == 1: @@ -592,8 +592,8 @@ def has_insufficient_material(self, color: chess.Color) -> bool: (pieces_bishops >= 1 and pieces_pawns >= 1) or (has_bishop_pair(chess.BLACK) and pieces_pawns >= 1) ) and - (pieces_of_type_not(pieces_darkb()) >= 3 if pieces_darkb() >= 2 else True) and - (pieces_of_type_not(pieces_lightb()) >= 3 if pieces_lightb() >= 2 else True) + (pieces_of_type_not(pieces_darkb) >= 3 if pieces_darkb >= 2 else True) and + (pieces_of_type_not(pieces_lightb) >= 3 if pieces_lightb >= 2 else True) ) # By this point, we only need to deal with white's minor pieces. @@ -623,11 +623,11 @@ def has_insufficient_material(self, color: chess.Color) -> bool: return not ( # A king on A1 obstructed by a pawn/opposite-color-bishop on # A2 is mated by a knight on D2 and a bishop on C3. - pieces_pawns >= 1 or pieces_oppositeb_of(horde_bishop_co()) >= 1 or + pieces_pawns >= 1 or pieces_oppositeb_of(horde_bishop_co) >= 1 or # A king on A1 bounded by two friendly pieces on A2 and B1 is # mated when the knight moves from D4 to C2 so that both the # knight and the bishop deliver check. - pieces_of_type_not(pieces_sameb_as(horde_bishop_co())) >= 3 + pieces_of_type_not(pieces_sameb_as(horde_bishop_co)) >= 3 ) else: # The horde has two or more bishops on the same color. @@ -639,10 +639,10 @@ def has_insufficient_material(self, color: chess.Color) -> bool: # bishops on B2 and C3. This position is theoretically # achievable even when black has two pawns or when they # have a pawn and an opposite color bishop. - (pieces_pawns >= 1 and pieces_oppositeb_of(horde_bishop_co()) >= 1) or + (pieces_pawns >= 1 and pieces_oppositeb_of(horde_bishop_co) >= 1) or (pieces_pawns >= 1 and pieces_knights >= 1) or - (pieces_oppositeb_of(horde_bishop_co()) >= 1 and pieces_knights >= 1) or - (pieces_oppositeb_of(horde_bishop_co()) >= 2) or + (pieces_oppositeb_of(horde_bishop_co) >= 1 and pieces_knights >= 1) or + (pieces_oppositeb_of(horde_bishop_co) >= 2) or pieces_knights >= 2 or pieces_pawns >= 2 # In every other case, white can only draw. From ad366ca0f39f2bacef9457bcbda7e90121cf3dbe Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 11 May 2021 11:56:20 +0200 Subject: [PATCH 1430/1831] Fix false negative in Horde insufficient material test --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index d46317158..aa8e609b8 100755 --- a/test.py +++ b/test.py @@ -573,7 +573,7 @@ def _check(board, white, black): _check(chess.variant.CrazyhouseBoard("8/5k2/8/8/8/5B2/3KB3/8[] w - - 0 1"), False, False) _check(chess.variant.CrazyhouseBoard("8/8/8/8/3k4/3N~4/3K4/8 w - - 0 1"), False, False) - _check(chess.variant.HordeBoard("8/5k2/8/8/8/4NN2/8/8 w - - 0 1"), false_negative, False) + _check(chess.variant.HordeBoard("8/5k2/8/8/8/4NN2/8/8 w - - 0 1"), True, False) def test_promotion_with_check(self): board = chess.Board("8/6P1/2p5/1Pqk4/6P1/2P1RKP1/4P1P1/8 w - - 0 1") From a024d3e1381d5a6a10eef97053ab5951ff9da89a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 11 May 2021 11:58:49 +0200 Subject: [PATCH 1431/1831] flake8 does not like assigning lambdas :shrug: --- chess/variant.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index 5d7608030..4cdcd04a3 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -491,10 +491,18 @@ def has_insufficient_material(self, color: chess.Color) -> bool: pieces_darkb = chess.popcount(chess.BB_DARK_SQUARES & pieces & self.bishops) pieces_lightb = chess.popcount(chess.BB_LIGHT_SQUARES & pieces & self.bishops) pieces_num = chess.popcount(pieces) - pieces_oppositeb_of = lambda square_color: pieces_darkb if square_color == chess.WHITE else pieces_lightb - pieces_sameb_as = lambda square_color: pieces_lightb if square_color == chess.WHITE else pieces_darkb - pieces_of_type_not = lambda piece: pieces_num - piece - has_bishop_pair = lambda side: (horde_lightb >= 1 and horde_darkb >= 1) if side == chess.WHITE else (pieces_lightb >= 1 and pieces_darkb >= 1) + + def pieces_oppositeb_of(square_color: chess.Color) -> int: + return pieces_darkb if square_color == chess.WHITE else pieces_lightb + + def pieces_sameb_as(square_color: chess.Color) -> int: + return pieces_lightb if square_color == chess.WHITE else pieces_darkb + + def pieces_of_type_not(piece: int) -> int: + return pieces_num - piece + + def has_bishop_pair(side: chess.Color) -> bool: + return (horde_lightb >= 1 and horde_darkb >= 1) if side == chess.WHITE else (pieces_lightb >= 1 and pieces_darkb >= 1) if horde_num == 0: return True From fa5ab65c015b3dac7e15f8a5b9a0a93bc054adfb Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 11 May 2021 12:03:04 +0200 Subject: [PATCH 1432/1831] No need to copy HordeBoard via FEN --- chess/variant.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index 4cdcd04a3..9580d723b 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -506,16 +506,13 @@ def has_bishop_pair(side: chess.Color) -> bool: if horde_num == 0: return True - if horde_num >= 4: # Four or more white pieces can always deliver mate. return False - if (pawns >= 1 or queens >= 1) and horde_num >= 2: # Pawns/queens are never insufficient material when paired with any other # piece (a pawn promotes to a queen and delivers mate). return False - if rooks >= 1 and horde_num >= 2: # A rook is insufficient material only when it is paired with a bishop # against a lone king. The horde can mate in any other case. @@ -548,9 +545,9 @@ def has_bishop_pair(side: chess.Color) -> bool: # Promote the pawn to a queen or a knight and check whether # white can mate. pawn_square = chess.SquareSet(self.pawns & white).pop() - promote_to_queen = HordeBoard(self.fen()) + promote_to_queen = self.copy(stack=False) promote_to_queen.set_piece_at(pawn_square, chess.Piece(chess.QUEEN, chess.WHITE)) - promote_to_knight = HordeBoard(self.fen()) + promote_to_knight = self.copy(stack=False) promote_to_knight.set_piece_at(pawn_square, chess.Piece(chess.KNIGHT, chess.WHITE)) return promote_to_queen.has_insufficient_material(chess.WHITE) and promote_to_knight.has_insufficient_material(chess.WHITE) elif rooks == 1: @@ -603,11 +600,7 @@ def has_bishop_pair(side: chess.Color) -> bool: (pieces_of_type_not(pieces_darkb) >= 3 if pieces_darkb >= 2 else True) and (pieces_of_type_not(pieces_lightb) >= 3 if pieces_lightb >= 2 else True) ) - - # By this point, we only need to deal with white's minor pieces. - - elif horde_num == 2: - + elif horde_num == 2: # By this point, we only need to deal with white's minor pieces. if pieces_num == 1: # Two minor pieces cannot mate a lone king. return True @@ -655,7 +648,6 @@ def has_bishop_pair(side: chess.Color) -> bool: pieces_pawns >= 2 # In every other case, white can only draw. ) - elif horde_num == 3: # A king in the corner is mated by two knights and a bishop or three # knights or the bishop pair and a knight/bishop. From 9714059e343e4b0eaef07e24133ceb73c3e5a3d0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 11 May 2021 12:08:53 +0200 Subject: [PATCH 1433/1831] Update Python 3.10.x to 3.10.0-beta.1 for test suite --- .github/workflows/test.yml | 80 +++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 64c82e11e..f853ab976 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,58 +7,58 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.7", "3.8", "3.9", "3.10.0-alpha.2"] + python-version: ["3.7", "3.8", "3.9", "3.10.0-beta.1"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - run: .github/workflows/setup-${{ matrix.os }}.sh - shell: bash - - run: pip install -e . - - run: python test.py -v + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - run: .github/workflows/setup-${{ matrix.os }}.sh + shell: bash + - run: pip install -e . + - run: python test.py -v perft: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: "3.10.0-alpha.2" - - run: pip install -e . - - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft - - run: python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft - - run: python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft - - run: python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft - - run: python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft - - run: python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: "3.10.0-alpha.2" + - run: pip install -e . + - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 + - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft + - run: python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft + - run: python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft + - run: python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft + - run: python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft + - run: python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft mypy: strategy: matrix: - python-version: ["3.8", "3.9", "3.10.0-alpha.2"] + python-version: ["3.8", "3.9", "3.10.0-beta.1"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - run: pip install -e . - - run: pip install mypy - - run: python -m mypy --strict chess - - run: python -m mypy --strict examples/**/*.py + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - run: pip install -e . + - run: pip install mypy + - run: python -m mypy --strict chess + - run: python -m mypy --strict examples/**/*.py readme: strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10.0-alpha.2"] + python-version: ["3.7", "3.8", "3.9", "3.10.0-beta.1"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - run: sudo apt-get update && sudo apt-get install -y docutils-common - - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null - - run: pip install -e . - - run: .github/workflows/setup-ubuntu-latest.sh - - run: python -m doctest README.rst + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - run: sudo apt-get update && sudo apt-get install -y docutils-common + - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null + - run: pip install -e . + - run: .github/workflows/setup-ubuntu-latest.sh + - run: python -m doctest README.rst From 4ce322458f98dd14c20984767eae48506b414ff1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 11 May 2021 12:14:23 +0200 Subject: [PATCH 1434/1831] Doctest only on 3.10.x due to enum repr change --- .github/workflows/test.yml | 2 +- README.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f853ab976..21aac88f3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,7 +50,7 @@ jobs: readme: strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10.0-beta.1"] + python-version: ["3.10.0-beta.1"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/README.rst b/README.rst index f02d0e584..37506a259 100644 --- a/README.rst +++ b/README.rst @@ -131,7 +131,7 @@ Features >>> board.is_insufficient_material() False >>> board.outcome() - Outcome(termination=, winner=True) + Outcome(termination=Termination.CHECKMATE, winner=True) * Detects repetitions. Has a half-move clock. From 2718302abb40d7b8c07290bb2a1ff0a6d11813de Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 16 May 2021 12:51:43 -0700 Subject: [PATCH 1435/1831] Notify engines of draw offers Only works for XBoard engines since the UCI protocol has no facility for offering or accepting draws. --- chess/engine.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 729272ce7..2968a2a01 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1078,7 +1078,7 @@ async def configure(self, options: ConfigMapping) -> None: """ @abc.abstractmethod - async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: """ Plays a position. @@ -1097,6 +1097,7 @@ async def play(self, board: chess.Board, limit: Limit, *, game: object = None, i extra information. :param ponder: Whether the engine should keep analysing in the background even after the result has been returned. + :param draw_offered: Whether the engine's opponent has offered a draw. :param root_moves: Optional. Consider only root moves from this list. :param options: Optional. A dictionary of engine options for the analysis. The previous configuration will be restored after the @@ -1529,7 +1530,7 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None builder.append("0000") self.send_line(" ".join(builder)) - async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: same_game = not self.first_game and game == self.game and not options self.last_move = board.move_stack[-1] if (same_game and ponder and board.move_stack) else chess.Move.null() @@ -2070,7 +2071,7 @@ def line_received(self, engine: XBoardProtocol, line: str) -> None: return await self.communicate(XBoardPingCommand) - async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: if root_moves is not None: raise EngineError("play with root_moves, but xboard supports 'include' only in analysis mode") @@ -2111,6 +2112,9 @@ def start(self, engine: XBoardProtocol) -> None: if limit.black_clock is not None: engine.send_line("{} {}".format("otim" if board.turn else "time", max(1, int(limit.black_clock * 100)))) + if draw_offered: + engine.send_line("draw") + # Start thinking. engine.send_line("post" if info else "nopost") engine.send_line("hard" if ponder else "easy") From 750f0d6538cdf573d849c5d316803178ef1dadac Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 16 May 2021 22:55:17 +0200 Subject: [PATCH 1436/1831] UCI engines do not support draw offers (#781) --- chess/engine.py | 1 + 1 file changed, 1 insertion(+) diff --git a/chess/engine.py b/chess/engine.py index 2968a2a01..e547653c2 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1098,6 +1098,7 @@ async def play(self, board: chess.Board, limit: Limit, *, game: object = None, i :param ponder: Whether the engine should keep analysing in the background even after the result has been returned. :param draw_offered: Whether the engine's opponent has offered a draw. + Ignored by UCI engines. :param root_moves: Optional. Consider only root moves from this list. :param options: Optional. A dictionary of engine options for the analysis. The previous configuration will be restored after the From 34bcb49918360ab9910d400cb168fcbc2ca3b642 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 16 May 2021 22:45:02 -0700 Subject: [PATCH 1437/1831] Make sure engines support draw offers XBoard engines are allowed to declare `feature draw=0` to stop any notification of draw offers. --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index e547653c2..07b9d1d0c 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2113,7 +2113,7 @@ def start(self, engine: XBoardProtocol) -> None: if limit.black_clock is not None: engine.send_line("{} {}".format("otim" if board.turn else "time", max(1, int(limit.black_clock * 100)))) - if draw_offered: + if draw_offered and engine.features.get("draw", 1): engine.send_line("draw") # Start thinking. From d0b2204b345812e1f212152b4e4880bb1945c453 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 16 May 2021 23:38:55 +0200 Subject: [PATCH 1438/1831] Remove duplicate import --- chess/engine.py | 1 - 1 file changed, 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 07b9d1d0c..d36ce8fdd 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -19,7 +19,6 @@ import abc import asyncio import collections -import copy import concurrent.futures import contextlib import copy From d3fd716216cff34903390c154410e083811fd35a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 2 Jun 2021 12:35:46 +0200 Subject: [PATCH 1439/1831] Clarify that SVG Tiny version is 1.2 --- docs/svg.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/svg.rst b/docs/svg.rst index b839f10a7..2893bed63 100644 --- a/docs/svg.rst +++ b/docs/svg.rst @@ -1,12 +1,12 @@ SVG rendering ============= -The :mod:`chess.svg` module renders SVG Tiny images (mostly for IPython/Jupyter -Notebook integration). The piece images by +The :mod:`chess.svg` module renders SVG Tiny 1.2 images +(mostly for IPython/Jupyter Notebook integration). +The piece images by `Colin M.L. Burnett `_ are triple licensed under the GFDL, BSD and GPL. - .. autofunction:: chess.svg.piece .. autofunction:: chess.svg.board From 4f4ae6cdbc946968088803ebb4fb2fd615da7c06 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 2 Jun 2021 12:41:05 +0200 Subject: [PATCH 1440/1831] Forwards compatibility with SVG 2 https://www.w3.org/TR/SVG2/linking.html#XLinkRefAttrs --- chess/svg.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index 7f4f935a9..fdc713315 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -374,14 +374,17 @@ def board(board: Optional[chess.BaseBoard] = None, *, if board is not None: piece = board.piece_at(square) if piece: + href = f"#{chess.COLOR_NAMES[piece.color]}-{chess.PIECE_NAMES[piece.piece_type]}" ET.SubElement(svg, "use", { - "xlink:href": f"#{chess.COLOR_NAMES[piece.color]}-{chess.PIECE_NAMES[piece.piece_type]}", + "href": href, + "xlink:href": href, "transform": f"translate({x:d}, {y:d})", }) # Render selected squares. if squares is not None and square in squares: ET.SubElement(svg, "use", _attrs({ + "href": "#xx", "xlink:href": "#xx", "x": x, "y": y, From e7d07fd256b692e8b24d26b81f8c8e38581b71f2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 4 Jun 2021 10:59:04 +0200 Subject: [PATCH 1441/1831] Bump SVG version and specify baseProfile --- chess/svg.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index fdc713315..91dae3c60 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -166,8 +166,9 @@ def _repr_svg_(self) -> SvgWrapper: def _svg(viewbox: int, size: Optional[int]) -> ET.Element: svg = ET.Element("svg", { "xmlns": "http://www.w3.org/2000/svg", - "version": "1.1", "xmlns:xlink": "http://www.w3.org/1999/xlink", + "version": "1.2", + "baseProfile": "tiny", "viewBox": f"0 0 {viewbox:d} {viewbox:d}", }) From 1d52ea644111d638b841ca9d637d31b55e6b753f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 9 Jun 2021 14:48:47 +0200 Subject: [PATCH 1442/1831] Fix slightly off-center pawns in chess.svg --- chess/svg.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 91dae3c60..177ffe02b 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -36,13 +36,13 @@ "b": """""", # noqa: E501 "k": """""", # noqa: E501 "n": """""", # noqa: E501 - "p": """""", # noqa: E501 + "p": """""", # noqa: E501 "q": """""", # noqa: E501 "r": """""", # noqa: E501 "B": """""", # noqa: E501 "K": """""", # noqa: E501 "N": """""", # noqa: E501 - "P": """""", # noqa: E501 + "P": """""", # noqa: E501 "Q": """""", # noqa: E501 "R": """""", # noqa: E501 } From 6d36418c1ab2bc560ca800d3087314b0cedb6598 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 9 Jun 2021 15:32:16 +0200 Subject: [PATCH 1443/1831] Fix mypy error if int.bit_count exists --- chess/__init__.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 793d1aed1..0454800cc 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -281,12 +281,8 @@ def scan_reversed(bb: Bitboard) -> Iterator[Square]: yield r bb ^= BB_SQUARES[r] -try: - # Python 3.10 - popcount: Callable[[Bitboard], int] = int.bit_count # type: ignore -except AttributeError: - def popcount(bb: Bitboard) -> int: - return bin(bb).count("1") +# Python 3.10 or fallback. +popcount: Callable[[Bitboard], int] = getattr(int, "bit_count", lambda bb: bin(bb).count("1")) def flip_vertical(bb: Bitboard) -> Bitboard: # https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating#FlipVertically From 2dcc8abc20c9956a7c49e49af98522a4bca22ea0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 11 Jun 2021 16:07:59 +0200 Subject: [PATCH 1444/1831] Prepare 1.6.0 --- CHANGELOG.rst | 23 +++++++++++++++++++++++ chess/__init__.py | 2 +- release.py | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5eb6fac96..65ed73b12 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,29 @@ Changelog for python-chess ========================== +New in v1.6.0 +------------- + +New features: + +* Allow offering a draw to XBoard engines using + ``chess.engine.Protocol.play(..., draw_offered=True)``. +* Now detects insufficient material in Horde. Thanks @stevepapazis! + +Changes: + +* ``chess.engine.popen_engine(..., setpgrp=True)`` on Windows now merges + ``CREATE_NEW_PROCESS_GROUP`` into ``creationflags`` instead of overriding. + On Unix it now uses ``start_new_session`` instead of calling ``setpgrp`` in + ``preexec_fn``. +* Declare that ``chess.svg`` produces SVG Tiny 1.2, and prepare SVG 2 forwards + compatibility. + +Bugfixes: + +* Fix slightly off-center pawns in ``chess.svg``. +* Fix typing error in Python 3.10 (due to added ``int.bit_count``). + New in v1.5.0 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index 0454800cc..b3818b319 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.5.0" +__version__ = "1.6.0" import collections import copy diff --git a/release.py b/release.py index 0d0336057..099dd4a98 100755 --- a/release.py +++ b/release.py @@ -25,6 +25,7 @@ def check_git(): print(f"master is {behind} commit(s) behind origin/master") sys.exit(1) + def test(): print("--- TEST ---------------------------------------------------------") system("tox --skip-missing-interpreters") From cce37793788dd19554297bb9f60889bc19656e4f Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Fri, 11 Jun 2021 18:31:48 -0700 Subject: [PATCH 1445/1831] Handle draw offers in SimpleEngine --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index d36ce8fdd..7dcc11a53 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2723,10 +2723,10 @@ def ping(self) -> None: future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() - def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: with self._not_shut_down(): coro = asyncio.wait_for( - self.protocol.play(board, limit, game=game, info=info, ponder=ponder, root_moves=root_moves, options=options), + self.protocol.play(board, limit, game=game, info=info, ponder=ponder, draw_offered=draw_offered, root_moves=root_moves, options=options), self._timeout_for(limit)) future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() From 4156d3a7c8056432452e5a9c796b520633224dbd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 12 Jun 2021 10:20:35 +0200 Subject: [PATCH 1446/1831] Prepare 1.6.1 --- CHANGELOG.rst | 8 ++++++++ chess/__init__.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 65ed73b12..1e6f941dc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ Changelog for python-chess ========================== +New in v1.6.1 +------------- + +Bugfixes: + +* Make ``chess.engine.SimpleEngine.play(..., draw_offered=True)`` available. + Previously only added for ``chess.engine.Protocol``. + New in v1.6.0 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index b3818b319..c5cfb3900 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.6.0" +__version__ = "1.6.1" import collections import copy From 9a5f01bd42082ea77f4fdca5c5b16fb8ab48ce8d Mon Sep 17 00:00:00 2001 From: Christian Korn Date: Mon, 21 Jun 2021 10:14:54 +0200 Subject: [PATCH 1447/1831] Correcting likely copy / paste error in test (#792) * Correcting likely copy / paste error in test I think the caro kann mate is suppsoed to be tested here, not the starting position * Fixing editing error... sorry. --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index aa8e609b8..07cd0413a 100755 --- a/test.py +++ b/test.py @@ -1687,7 +1687,7 @@ def test_nonzero(self): caro_kann_mate = chess.Board("r1bqkb1r/pp1npppp/2pN1n2/8/3P4/8/PPP1QPPP/R1B1KBNR b KQkq - 4 6") self.assertFalse(caro_kann_mate.legal_moves) - self.assertTrue(chess.Board().pseudo_legal_moves) + self.assertTrue(caro_kann_mate.pseudo_legal_moves) def test_string_conversion(self): board = chess.Board("r3k1nr/ppq1pp1p/2p3p1/8/1PPR4/2N5/P3QPPP/5RK1 b kq b3 0 16") From 71816bb7e9addafa3a3f9632aaea523a70e8300f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 23 Jun 2021 11:08:27 +0200 Subject: [PATCH 1448/1831] Let tox skip doctests before Python 3.10 --- tox.ini | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tox.ini b/tox.ini index 13a3dc90a..3eeb764ba 100644 --- a/tox.ini +++ b/tox.ini @@ -10,6 +10,14 @@ commands = python test.py --verbose python -m doctest README.rst --verbose +[testenv:{py37,py38,py39}] +passenv = LD_LIBRARY_PATH +whitelist_externals = + stockfish + crafty +commands = + python test.py --verbose + [flake8] ignore = E126 E131 # Allow over-indent and unaligned indent From 5a0e0da44c96b6d5992c0e4a372bee32da236270 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 23 Jun 2021 11:11:31 +0200 Subject: [PATCH 1449/1831] Fix centipawn normalization in sf12 WDL model --- chess/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 7dcc11a53..b8d6e7aad 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -625,7 +625,8 @@ def _sf12_wins(cp: int, *, ply: int) -> int: m = min(240, max(ply, 0)) / 64 a = (((-8.24404295 * m + 64.23892342) * m + -95.73056462) * m) + 153.86478679 b = (((-3.37154371 * m + 28.44489198) * m + -56.67657741) * m) + 72.05858751 - x = min(1000, max(cp, -1000)) + pawn_value_eg = 208 + x = min(1000, max(cp * 100 / pawn_value_eg, -1000)) return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) def _lichess_raw_wins(cp: int) -> int: From 14f56f95916cedc9bd7adfa1ae8dc3fb1f1a888d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 23 Jun 2021 11:24:59 +0200 Subject: [PATCH 1450/1831] Add WDL model for Stockfish development version --- chess/engine.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index b8d6e7aad..fd07bd790 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -44,7 +44,7 @@ try: from typing import Literal - _WdlModel = Literal["sf12", "lichess"] + _WdlModel = Literal["sf14", "sf12", "lichess"] except ImportError: # Before Python 3.8. _WdlModel = str # type: ignore @@ -559,6 +559,8 @@ def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: 0.015... :param model: + * ``sf14``, the WDL model used by the current development version + of Stockfish. Still subject to change or removal. * ``sf12``, the WDL model used by Stockfish 12. * ``lichess``, the win rate model used by Lichess. Does not use *ply*, and does not consider drawing chances. @@ -620,6 +622,15 @@ def __ge__(self, other: object) -> bool: return NotImplemented +def _sf14_wins(cp: int, *, ply: int) -> int: + # TODO: When released, add permalink and update documentation. + m = min(240, max(ply, 0)) / 64 + a = (((-3.68389304 * m + 30.07065921) * m + -60.52878723) * m) + 149.53378557 + b = (((-2.01818570 * m + 15.85685038) * m + -29.83452023) * m) + 47.59078827 + pawn_value_eg = 208 + x = min(2000, max(cp * 100 / pawn_value_eg, -2000)) + return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) + def _sf12_wins(cp: int, *, ply: int) -> int: # https://github.com/official-stockfish/Stockfish/blob/sf_12/src/uci.cpp#L198-L218 m = min(240, max(ply, 0)) / 64 @@ -649,6 +660,9 @@ def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: if model == "lichess": wins = _lichess_raw_wins(max(-1000, min(self.cp, 1000))) losses = 1000 - wins + elif model == "sf14": + wins = _sf14_wins(self.cp, ply=ply) + losses = _sf14_wins(-self.cp, ply=ply) else: wins = _sf12_wins(self.cp, ply=ply) losses = _sf12_wins(-self.cp, ply=ply) From 9d1aa6eb47798041a2bbb129857ceac72d5b1a90 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 23 Jun 2021 11:38:46 +0200 Subject: [PATCH 1451/1831] Undo centipawn normalization for Stockfish WDL models --- chess/engine.py | 6 ++---- test.py | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index fd07bd790..308fb4605 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -627,8 +627,7 @@ def _sf14_wins(cp: int, *, ply: int) -> int: m = min(240, max(ply, 0)) / 64 a = (((-3.68389304 * m + 30.07065921) * m + -60.52878723) * m) + 149.53378557 b = (((-2.01818570 * m + 15.85685038) * m + -29.83452023) * m) + 47.59078827 - pawn_value_eg = 208 - x = min(2000, max(cp * 100 / pawn_value_eg, -2000)) + x = min(2000, max(cp, -2000)) return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) def _sf12_wins(cp: int, *, ply: int) -> int: @@ -636,8 +635,7 @@ def _sf12_wins(cp: int, *, ply: int) -> int: m = min(240, max(ply, 0)) / 64 a = (((-8.24404295 * m + 64.23892342) * m + -95.73056462) * m) + 153.86478679 b = (((-3.37154371 * m + 28.44489198) * m + -56.67657741) * m) + 72.05858751 - pawn_value_eg = 208 - x = min(1000, max(cp * 100 / pawn_value_eg, -1000)) + x = min(1000, max(cp, -1000)) return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) def _lichess_raw_wins(cp: int) -> int: diff --git a/test.py b/test.py index 07cd0413a..4051a8384 100755 --- a/test.py +++ b/test.py @@ -2867,6 +2867,10 @@ def test_score(self): self.assertFalse(chess.engine.Wdl(0, 0, 0)) + def test_wdl_model(self): + self.assertEqual(chess.engine.Cp(131).wdl(model="sf12", ply=25), chess.engine.Wdl(524, 467, 9)) + self.assertEqual(chess.engine.Cp(146).wdl(model="sf14", ply=25), chess.engine.Wdl(601, 398, 1)) + @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_forced_mates(self): with chess.engine.SimpleEngine.popen_uci("stockfish", debug=True) as engine: From d0cfb2415a7326a6a8a345582f958b46d6befbd0 Mon Sep 17 00:00:00 2001 From: vladimir Date: Mon, 28 Jun 2021 19:18:16 +0300 Subject: [PATCH 1452/1831] piece_map_by_color added --- chess/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index c5cfb3900..de916993f 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1023,6 +1023,15 @@ def piece_map(self) -> Dict[Square, Piece]: result[square] = typing.cast(Piece, self.piece_at(square)) return result + def piece_map_by_color(self, color: Color) -> Dict[Square, Piece]: + """ + Gets a dictionary of :class:`pieces ` by square index. + """ + result = {} + for square in scan_reversed(self.occupied_co[color]): + result[square] = typing.cast(Piece, self.piece_at(square)) + return result + def _set_piece_map(self, pieces: Mapping[Square, Piece]) -> None: self._clear_board() for square, piece in pieces.items(): From 24c39e7bd9a07a017cd2c585c0ae17ad131bfc03 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 4 Jul 2021 11:15:54 +0200 Subject: [PATCH 1453/1831] Combine piece_map methods (#793) --- chess/__init__.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index de916993f..25ca18344 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1014,21 +1014,12 @@ def set_board_fen(self, fen: str) -> None: """ self._set_board_fen(fen) - def piece_map(self) -> Dict[Square, Piece]: + def piece_map(self, *, mask: Bitboard = BB_ALL) -> Dict[Square, Piece]: """ Gets a dictionary of :class:`pieces ` by square index. """ result = {} - for square in scan_reversed(self.occupied): - result[square] = typing.cast(Piece, self.piece_at(square)) - return result - - def piece_map_by_color(self, color: Color) -> Dict[Square, Piece]: - """ - Gets a dictionary of :class:`pieces ` by square index. - """ - result = {} - for square in scan_reversed(self.occupied_co[color]): + for square in scan_reversed(self.occupied & mask): result[square] = typing.cast(Piece, self.piece_at(square)) return result From 92657ae6b9a33f0dd8db310617b28510a317a1ad Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 4 Jul 2021 11:33:10 +0200 Subject: [PATCH 1454/1831] Update default WDL model --- chess/engine.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 308fb4605..af4b12012 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -44,7 +44,7 @@ try: from typing import Literal - _WdlModel = Literal["sf14", "sf12", "lichess"] + _WdlModel = Literal["sf", "sf14", "sf12", "lichess"] except ImportError: # Before Python 3.8. _WdlModel = str # type: ignore @@ -463,7 +463,7 @@ def is_mate(self) -> bool: """Tests if this is a mate score.""" return self.relative.is_mate() - def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> PovWdl: + def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> PovWdl: """See :func:`~chess.engine.Score.wdl()`.""" return PovWdl(self.relative.wdl(), self.turn) @@ -540,7 +540,7 @@ def is_mate(self) -> bool: return self.mate() is not None @abc.abstractmethod - def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: + def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: """ Returns statistics for the expected outcome of this game, based on a *model*, given that this score is reached at *ply*. @@ -559,8 +559,9 @@ def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: 0.015... :param model: - * ``sf14``, the WDL model used by the current development version - of Stockfish. Still subject to change or removal. + * ``sf``, the WDL model used by the latest Stockfish + (currently ``sf14``). + * ``sf14``, the WDL model used by Stockfish 14. * ``sf12``, the WDL model used by Stockfish 12. * ``lichess``, the win rate model used by Lichess. Does not use *ply*, and does not consider drawing chances. @@ -623,7 +624,7 @@ def __ge__(self, other: object) -> bool: def _sf14_wins(cp: int, *, ply: int) -> int: - # TODO: When released, add permalink and update documentation. + # https://github.com/official-stockfish/Stockfish/blob/sf_14/src/uci.cpp#L200-L220 m = min(240, max(ply, 0)) / 64 a = (((-3.68389304 * m + 30.07065921) * m + -60.52878723) * m) + 149.53378557 b = (((-2.01818570 * m + 15.85685038) * m + -29.83452023) * m) + 47.59078827 @@ -654,16 +655,16 @@ def mate(self) -> None: def score(self, *, mate_score: Optional[int] = None) -> int: return self.cp - def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: + def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: if model == "lichess": wins = _lichess_raw_wins(max(-1000, min(self.cp, 1000))) losses = 1000 - wins - elif model == "sf14": - wins = _sf14_wins(self.cp, ply=ply) - losses = _sf14_wins(-self.cp, ply=ply) - else: + elif model == "sf12": wins = _sf12_wins(self.cp, ply=ply) losses = _sf12_wins(-self.cp, ply=ply) + else: + wins = _sf14_wins(self.cp, ply=ply) + losses = _sf14_wins(-self.cp, ply=ply) draws = 1000 - wins - losses return Wdl(wins, draws, losses) @@ -704,7 +705,7 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: else: return -mate_score - self.moves - def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: + def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: if model == "lichess": cp = (21 - min(10, abs(self.moves))) * 100 wins = _lichess_raw_wins(cp) @@ -741,7 +742,7 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: ... def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: return mate_score - def wdl(self, *, model: _WdlModel = "sf12", ply: int = 30) -> Wdl: + def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: return Wdl(1000, 0, 0) def __neg__(self) -> Mate: From b25ce005a8874cc7c1fe18edce7e520ae22cf3ad Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 5 Jul 2021 19:05:18 +0200 Subject: [PATCH 1455/1831] Explicitly specify default radius for check_gradient --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index 177ffe02b..9ddf044d8 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -68,7 +68,7 @@ XX = """""" # noqa: E501 -CHECK_GRADIENT = """""" # noqa: E501 +CHECK_GRADIENT = """""" # noqa: E501 DEFAULT_COLORS = { "square light": "#ffce9e", From a4bec19d905eee26e58acc549320f197fb76146b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 12 Jul 2021 22:14:31 +0200 Subject: [PATCH 1456/1831] Mention spin and combo option types (fixes #796) --- chess/engine.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index af4b12012..ec1e049a6 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -232,6 +232,10 @@ class Option: +========+=====+======+================================================+ | check | X | X | ``True`` or ``False`` | +--------+-----+------+------------------------------------------------+ + | spin | X | X | integer, between *min* and *max* | + +--------+-----+------+------------------------------------------------+ + | combo | X | X | string, one of *var* | + +--------+-----+------+------------------------------------------------+ | button | X | X | ``None`` | +--------+-----+------+------------------------------------------------+ | reset | | X | ``None`` | From 4c0c2929a3f2b580b5bfa277cc05ed2879c2ac1b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 13 Jul 2021 10:14:57 +0200 Subject: [PATCH 1457/1831] Fix 'Duplicate explicit target name: "xboard protocol"' --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index ec1e049a6..390190035 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1899,7 +1899,7 @@ def __repr__(self) -> str: class XBoardProtocol(Protocol): """ An implementation of the - `XBoard protocol `_ (CECP). + `XBoard protocol `__ (CECP). """ def __init__(self) -> None: From 3770f2500f7a71128e4f7af4eedffd7e3be19855 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 13 Jul 2021 10:22:16 +0200 Subject: [PATCH 1458/1831] Again try to update Sphinx on RTD --- .readthedocs.yml | 2 +- docs/conf.py | 11 ----------- docs/requirements.txt | 2 +- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 11760dd7d..e6efe594c 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,6 +1,6 @@ version: 1 python: - version: 3.8 + version: 3.9 install: - requirements: docs/requirements.txt - method: setuptools diff --git a/docs/conf.py b/docs/conf.py index e3fe4f737..526150026 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,5 @@ import sys import os -import typing # Do not resolve these. autodoc_type_aliases = { @@ -11,16 +10,6 @@ "IntoSquareSet": "chess.IntoSquareSet", } -# Hack to not resolve autodoc_type_aliases before Sphinx 3.3. -# See https://github.com/sphinx-doc/sphinx/issues/6518. -_get_type_hints = typing.get_type_hints -def get_type_hints(obj, globalns=None, localns=None): - if localns is None: - localns = {} - localns.update(autodoc_type_aliases) - return _get_type_hints(obj, globalns, localns) -typing.get_type_hints = get_type_hints - # Import the chess module. sys.path.insert(0, os.path.abspath("..")) import chess diff --git a/docs/requirements.txt b/docs/requirements.txt index 89eb0be0b..b0315fc3d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -sphinx==3.2.1 +Sphinx==4.1.0 From d45c02aade45cc788b14195722e2926f7d69e623 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 13 Jul 2021 10:24:39 +0200 Subject: [PATCH 1459/1831] Downgrade Python for RTD --- .readthedocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index e6efe594c..11760dd7d 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,6 +1,6 @@ version: 1 python: - version: 3.9 + version: 3.8 install: - requirements: docs/requirements.txt - method: setuptools From 57eecae5d69e8d295021b0a9555ee861fe5b2df7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 13 Jul 2021 10:32:30 +0200 Subject: [PATCH 1460/1831] Downgrade Sphinx for RTD --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index b0315fc3d..5152367fe 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -Sphinx==4.1.0 +Sphinx==3.5.4 From 17e5c8d84c0ce8c22a150849d0f98d24806a1c58 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Fri, 23 Jul 2021 16:35:23 -0500 Subject: [PATCH 1461/1831] read_game: don't pop/end_variation while skipping If the Visitor class enters a variation without skipping, then returns SKIP for a variation nested inside it, the traversal state is messed up when the inside variation ends. If our skip depth is anything greater than zero when we reach a ')' token, we should not visit the end of a variation or pop the board_stack, because it is being skipped completely. Short testcase: import chess, chess.pgn as pgn, io class MainlineW(pgn.GameBuilder): """Includes variations played by Black but not by White""" def begin_variation(self): if self.variation_stack[-1].turn() != chess.WHITE: return pgn.SKIP return super().begin_variation() g = pgn.read_game(io.StringIO( '1. e4 e5 (1... d5 2.exd5 Qxd5 3. Nc3 (3. c4) 3... Qa5)'), Visitor=MainlineW) --- chess/pgn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index d4e4c1316..17adeb04e 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1599,7 +1599,7 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: elif token == ")": if skip_variation_depth: skip_variation_depth -= 1 - if len(board_stack) > 1: + elif len(board_stack) > 1: visitor.end_variation() board_stack.pop() elif skip_variation_depth: From d8632559d88c554ab7b8769c3c124aa9c5a88cfb Mon Sep 17 00:00:00 2001 From: analog-hors <44050761+analog-hors@users.noreply.github.com> Date: Sat, 24 Jul 2021 23:24:07 +1000 Subject: [PATCH 1462/1831] Fix bratko_kopec movetime description --- examples/bratko_kopec/bratko_kopec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/bratko_kopec/bratko_kopec.py b/examples/bratko_kopec/bratko_kopec.py index 2c50ddfce..8e5210b70 100755 --- a/examples/bratko_kopec/bratko_kopec.py +++ b/examples/bratko_kopec/bratko_kopec.py @@ -104,7 +104,7 @@ async def main() -> None: parser.add_argument("-t", "--threads", default=1, type=int, help="Threads for use by the UCI engine.") parser.add_argument("-m", "--movetime", default=1.0, type=float, - help="Time to move in milliseconds.") + help="Time to move in seconds.") parser.add_argument("-s", "--simple", dest="test_epd", action="store_const", default=test_epd_with_fractional_scores, const=test_epd, From 543a4f5d5e8cce37f183ab98677c6ef0a2e7cfd5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 13 Sep 2021 11:03:32 +0200 Subject: [PATCH 1463/1831] Make Syzygy documentation more precise --- chess/syzygy.py | 33 +++++++++++++++++++++------------ docs/syzygy.rst | 6 +++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 8fe3df6a1..ef453b71f 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1675,7 +1675,9 @@ def sprobe_capts(self, board: chess.Board, alpha: int, beta: int) -> Tuple[int, def probe_wdl(self, board: chess.Board) -> int: """ - Probes WDL tables for win/draw/loss-information. + Probes WDL tables for win/draw/loss-information under the 50-move rule, + assuming the position has been reached directly after a capture or + pawn move. Probing is thread-safe when done with different *board* objects and if *board* objects are not modified during probing. @@ -1836,12 +1838,18 @@ def probe_dtz_no_ep(self, board: chess.Board) -> int: def probe_dtz(self, board: chess.Board) -> int: """ - Probes DTZ tables for distance to zero information. + Probes DTZ tables for + `DTZ50'' information with rounding `_. - Both DTZ and WDL tables are required in order to probe for DTZ. + Minmaxing the DTZ50'' values guarantees winning a won position + (and drawing a drawn position), because it makes progress keeping the + win in hand. + However the lines are not always the most straightforward ways to win. + Engines like Stockfish calculate themselves, checking with DTZ, but + only play according to DTZ if they can not manage on their own. Returns a positive value if the side to move is winning, ``0`` if the - position is a draw and a negative value if the side to move is losing. + position is a draw, and a negative value if the side to move is losing. More precisely: +-----+------------------+--------------------------------------------+ @@ -1871,15 +1879,14 @@ def probe_dtz(self, board: chess.Board) -> int: The return value can be off by one: a return value -n can mean a losing zeroing move in in n + 1 plies and a return value +n can mean a winning zeroing move in n + 1 plies. - This is guaranteed not to happen for positions exactly on the edge of - the 50-move rule, so that (with some care) this never impacts the - result of practical play. + This implies some primary tablebase lines may waste up to 1 ply. + Rounding is never used for endgame phases where it would change the + game theoretical outcome. - Minmaxing the DTZ values guarantees winning a won position (and drawing - a drawn position), because it makes progress keeping the win in hand. - However the lines are not always the most straightforward ways to win. - Engines like Stockfish calculate themselves, checking with DTZ, but - only play according to DTZ if they can not manage on their own. + This means users need to be careful in positions that are nearly drawn + under the 50-move rule! Carelessly wasting 1 more ply by not following + the tablebase recommendation, for a total of 2 wasted plies, may + change the outcome of the game. >>> import chess >>> import chess.syzygy @@ -1893,6 +1900,8 @@ def probe_dtz(self, board: chess.Board) -> int: Probing is thread-safe when done with different *board* objects and if *board* objects are not modified during probing. + Both DTZ and WDL tables are required in order to probe for DTZ. + :raises: :exc:`KeyError` (or specifically :exc:`chess.syzygy.MissingTableError`) if the position could not be found in the tablebase. Use diff --git a/docs/syzygy.rst b/docs/syzygy.rst index e168db5e7..d2ce4edb6 100644 --- a/docs/syzygy.rst +++ b/docs/syzygy.rst @@ -1,9 +1,9 @@ Syzygy endgame tablebase probing ================================ -Syzygy tablebases provide **WDL** (win/draw/loss) and **DTZ** (distance to -zero) information for all endgame positions with up to 7 pieces. -Positions with castling rights are not included. +Syzygy tablebases provide WDL\ :sub:`50` (win/draw/loss under the 50-move rule) and +DTZ\ :sub:`50`'' (distance to zeroing) information with rounding for all endgame +positions with up to 7 pieces. Positions with castling rights are not included. .. warning:: Ensure tablebase files match the known checksums. Maliciously crafted From 44cf0d0703d9ee1067dadf204865d15fd418e09e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 14 Sep 2021 22:29:56 +0200 Subject: [PATCH 1464/1831] Fix typos --- chess/syzygy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index ef453b71f..65cafbeeb 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1675,7 +1675,7 @@ def sprobe_capts(self, board: chess.Board, alpha: int, beta: int) -> Tuple[int, def probe_wdl(self, board: chess.Board) -> int: """ - Probes WDL tables for win/draw/loss-information under the 50-move rule, + Probes WDL tables for win/draw/loss information under the 50-move rule, assuming the position has been reached directly after a capture or pawn move. @@ -1844,7 +1844,7 @@ def probe_dtz(self, board: chess.Board) -> int: Minmaxing the DTZ50'' values guarantees winning a won position (and drawing a drawn position), because it makes progress keeping the win in hand. - However the lines are not always the most straightforward ways to win. + However, the lines are not always the most straightforward ways to win. Engines like Stockfish calculate themselves, checking with DTZ, but only play according to DTZ if they can not manage on their own. From 809cbd4861e9abab99c893855de850641fb5a185 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 16 Sep 2021 21:06:55 +0200 Subject: [PATCH 1465/1831] Comma --- chess/syzygy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 65cafbeeb..b818f1a8c 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1535,8 +1535,8 @@ def add_directory(self, directory: str, *, load_wdl: bool = True, load_dtz: bool """ Adds tables from a directory. - By default all available tables with the correct file names - (e.g. WDL files like ``KQvKN.rtbw`` and DTZ files like ``KRBvK.rtbz``) + By default, all available tables with the correct file names + (e.g., WDL files like ``KQvKN.rtbw`` and DTZ files like ``KRBvK.rtbz``) are added. The relevant files are lazily opened when the tablebase is actually From fb26c08c7c13fe2665b449fdfb10c5e882338ac9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 17 Sep 2021 00:11:58 +0200 Subject: [PATCH 1466/1831] Remove leftovers of old CI --- setup.py | 10 ---------- test.py | 1 - 2 files changed, 11 deletions(-) diff --git a/setup.py b/setup.py index 1bf8a4b7d..cbaa70e3e 100755 --- a/setup.py +++ b/setup.py @@ -58,16 +58,6 @@ def read_description(): "//readthedocs.org/projects/python-chess/badge/?version=latest", "//readthedocs.org/projects/python-chess/badge/?version=v{}".format(chess.__version__)) - # Show Travis CI build status of the concrete version. - description = description.replace( - "//travis-ci.org/niklasf/python-chess.svg?branch=master", - "//travis-ci.org/niklasf/python-chess.svg?branch=v{}".format(chess.__version__)) - - # Show Appveyor build status of the concrete version. - description = description.replace( - "/y9k3hdbm0f0nbum9/branch/master", - "/y9k3hdbm0f0nbum9/branch/v{}".format(chess.__version__)) - # Remove doctest comments. description = re.sub(r"\s*# doctest:.*", "", description) diff --git a/test.py b/test.py index 4051a8384..1214f1dc7 100755 --- a/test.py +++ b/test.py @@ -3777,7 +3777,6 @@ def test_suicide_dtz(self): dtz = tables.probe_dtz(board) self.assertEqual(dtz, solution["dtz"], f"Expecting dtz {solution['dtz']}, got {dtz} (in {epd})") - @unittest.skipIf(os.environ.get("TRAVIS_PYTHON_VERSION", "").startswith("pypy"), "travis pypy is very slow") @catchAndSkip(chess.syzygy.MissingTableError) def test_suicide_stats(self): board = chess.variant.SuicideBoard() From 7f7e1cb0d719064f312aea7eeda5655df3ee33e0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 2 Oct 2021 21:15:24 +0200 Subject: [PATCH 1467/1831] Document chess.pgn.Game.from_board() (for #811) --- docs/pgn.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pgn.rst b/docs/pgn.rst index 12b09ac62..9ebe96594 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -52,7 +52,7 @@ Both extend :class:`~chess.pgn.GameNode`. :members: .. autoclass:: chess.pgn.Game - :members: headers, errors, setup, accept + :members: headers, errors, setup, accept, from_board, without_tag_roster .. autoclass:: chess.pgn.ChildNode :members: parent, move, starting_comment, nags, san, uci, end From 8ac79bc34e0bfaf2f03e9ecbc1668e2f33fc3bcb Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Oct 2021 16:53:11 +0200 Subject: [PATCH 1468/1831] Use Windows paths in one engine example For https://github.com/niklasf/python-chess/discussions/809. --- docs/engine.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/engine.rst b/docs/engine.rst index 2a8a2a4c7..c83d625a8 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -30,7 +30,7 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. import chess import chess.engine - engine = chess.engine.SimpleEngine.popen_uci("/usr/bin/stockfish") + engine = chess.engine.SimpleEngine.popen_uci(r"C:\Users\xxxxx\Download\stockfish_14_win_x64\stockfish_14_win_x64_avx2.exe") board = chess.Board() while not board.is_game_over(): @@ -46,7 +46,7 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. import chess.engine async def main() -> None: - transport, engine = await chess.engine.popen_uci("/usr/bin/stockfish") + transport, engine = await chess.engine.popen_uci(r"C:\Users\xxxxx\Download\stockfish_14_win_x64\stockfish_14_win_x64_avx2.exe") board = chess.Board() while not board.is_game_over(): From 72ed47eed95e006ca68229f6db736a688015d639 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Oct 2021 17:03:15 +0200 Subject: [PATCH 1469/1831] Download -> Downloads in Windows example --- docs/engine.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/engine.rst b/docs/engine.rst index c83d625a8..979d0e915 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -30,7 +30,7 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. import chess import chess.engine - engine = chess.engine.SimpleEngine.popen_uci(r"C:\Users\xxxxx\Download\stockfish_14_win_x64\stockfish_14_win_x64_avx2.exe") + engine = chess.engine.SimpleEngine.popen_uci(r"C:\Users\xxxxx\Downloads\stockfish_14_win_x64\stockfish_14_win_x64_avx2.exe") board = chess.Board() while not board.is_game_over(): @@ -46,7 +46,7 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. import chess.engine async def main() -> None: - transport, engine = await chess.engine.popen_uci(r"C:\Users\xxxxx\Download\stockfish_14_win_x64\stockfish_14_win_x64_avx2.exe") + transport, engine = await chess.engine.popen_uci(r"C:\Users\xxxxx\Downloads\stockfish_14_win_x64\stockfish_14_win_x64_avx2.exe") board = chess.Board() while not board.is_game_over(): From e5539039ee9d9e101de9064c9f062aad3c9f0725 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Oct 2021 18:07:24 +0200 Subject: [PATCH 1470/1831] Remove contempt from test for Stockfish 14 compat --- test.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test.py b/test.py index 1214f1dc7..4a3f41d34 100755 --- a/test.py +++ b/test.py @@ -2874,8 +2874,6 @@ def test_wdl_model(self): @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_forced_mates(self): with chess.engine.SimpleEngine.popen_uci("stockfish", debug=True) as engine: - engine.configure({"Contempt": 23}) - epds = [ "1k1r4/pp1b1R2/3q2pp/4p3/2B5/4Q3/PPP2B2/2K5 b - - bm Qd1+; id \"BK.01\";", "6k1/N1p3pp/2p5/3n1P2/4K3/1P5P/P1Pr1r2/R1R5 b - - bm Rf4+; id \"Clausthal 2014\";", From 1aeba7be0f7c43552573159e3070949c8d222197 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Oct 2021 18:50:59 +0200 Subject: [PATCH 1471/1831] Add failing test for skipping nested variation (#798) --- test.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test.py b/test.py index 4a3f41d34..ff4b649ba 100755 --- a/test.py +++ b/test.py @@ -2776,6 +2776,24 @@ def test_node_turn(self): node = node.add_variation(chess.Move.from_uci("e1e2")) self.assertEqual(node.turn(), chess.BLACK) + def test_skip_inner_variation(self): + class BlackVariationsOnly(chess.pgn.GameBuilder): + def begin_variation(self): + self.skipping = self.variation_stack[-1].turn() != chess.WHITE + if self.skipping: + return chess.pgn.SKIP + else: + return super().begin_variation() + + def end_variation(self): + if self.skipping: + self.skipping = False + else: + return super().end_variation() + + game = chess.pgn.read_game(io.StringIO("1. e4 e5 (1... d5 2. exd5 Qxd5 3. Nc3 (3. c4) 3... Qa5)"), Visitor=BlackVariationsOnly) + self.assertEqual(game.accept(chess.pgn.StringExporter(headers=False)), "1. e4 e5 ( 1... d5 2. exd5 Qxd5 3. Nc3 Qa5 ) *") + @unittest.skipIf(sys.platform == "win32" and (3, 8, 0) <= sys.version_info < (3, 8, 1), "https://bugs.python.org/issue34679") class EngineTestCase(unittest.TestCase): From bcce6ccad25a94ab61d69486f671192b9db9859c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Oct 2021 18:52:47 +0200 Subject: [PATCH 1472/1831] Call matching end_variation while skipping (#798) --- chess/pgn.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 17adeb04e..fccf9f216 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1597,7 +1597,10 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: board.pop() board_stack.append(board) elif token == ")": - if skip_variation_depth: + if skip_variation_depth == 1: + skip_variation_depth = 0 + visitor.end_variation() + elif skip_variation_depth: skip_variation_depth -= 1 elif len(board_stack) > 1: visitor.end_variation() From 5587a8c1a363b930c78601f5d263a83d9f8b0cb4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Oct 2021 19:03:11 +0200 Subject: [PATCH 1473/1831] Also test skipping nested variations with Game.accept() (#798) --- test.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index ff4b649ba..1fcc13ec0 100755 --- a/test.py +++ b/test.py @@ -2791,8 +2791,16 @@ def end_variation(self): else: return super().end_variation() - game = chess.pgn.read_game(io.StringIO("1. e4 e5 (1... d5 2. exd5 Qxd5 3. Nc3 (3. c4) 3... Qa5)"), Visitor=BlackVariationsOnly) - self.assertEqual(game.accept(chess.pgn.StringExporter(headers=False)), "1. e4 e5 ( 1... d5 2. exd5 Qxd5 3. Nc3 Qa5 ) *") + pgn = "1. e4 e5 ( 1... d5 2. exd5 Qxd5 3. Nc3 ( 3. c4 ) 3... Qa5 ) *" + expected_pgn = "1. e4 e5 ( 1... d5 2. exd5 Qxd5 3. Nc3 Qa5 ) *" + + # Driven by parser. + game = chess.pgn.read_game(io.StringIO(pgn), Visitor=BlackVariationsOnly) + self.assertEqual(game.accept(chess.pgn.StringExporter(headers=False)), expected_pgn) + + # Driven by game tree traversal. + game = chess.pgn.read_game(io.StringIO(pgn)).accept(BlackVariationsOnly()) + self.assertEqual(game.accept(chess.pgn.StringExporter(headers=False)), expected_pgn) @unittest.skipIf(sys.platform == "win32" and (3, 8, 0) <= sys.version_info < (3, 8, 1), "https://bugs.python.org/issue34679") From 53a8a9e11f7401d4d689543f82b6c2b20f4c79e1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Oct 2021 19:14:05 +0200 Subject: [PATCH 1474/1831] Prepare 1.7.0 --- CHANGELOG.rst | 14 ++++++++++++++ chess/__init__.py | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1e6f941dc..68e381d50 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,20 @@ Changelog for python-chess ========================== +New in v1.7.0 +------------- + +New features: + +* Added new models for ``chess.engine.Score.wdl()``: ``sf`` (the new default) + and ``sf14``. +* Added ``chess.Board.piece_map()``. + +Bugfixes: + +* ``chess.pgn``: Fix skipping with nested variations. +* ``chess.svg``: Make check gradient compatible with QtSvg. + New in v1.6.1 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index 25ca18344..50c1a8e2a 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.6.1" +__version__ = "1.7.0" import collections import copy From 52dbcf05930e7580c3c489e71e7f51d74646eb28 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 7 Oct 2021 22:26:26 +0200 Subject: [PATCH 1475/1831] Add shallow perft tests for impossible alignment --- examples/perft/tricky.perft | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/examples/perft/tricky.perft b/examples/perft/tricky.perft index e46e9366d..f0e9d78c5 100644 --- a/examples/perft/tricky.perft +++ b/examples/perft/tricky.perft @@ -95,3 +95,31 @@ perft 1 7 perft 2 52 perft 3 4593 perft 4 50268 + +# +# Impossible checker alignment. +# + +id align-diag-1 +epd 3R4/8/q4k2/2B5/1NK5/3b4/8/8 w - - +perft 1 4 +perft 2 125 +perft 3 2854 + +id align-diag-2 +epd 2Nq4/2K5/1b6/8/7R/3k4/7P/8 w - - +perft 1 3 +perft 2 81 +perft 3 1217 + +id align-horizontal +epd 5R2/2P5/8/4k3/8/3rK2r/8/8 w - - +perft 1 2 +perft 2 56 +perft 3 1030 + +id align-ep +epd 8/8/8/1k6/3Pp3/8/8/4KQ2 b - d3 +perft 1 6 +perft 2 121 +perft 3 711 From eb7710296a23908f176b02f42f978e27fda97825 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 19 Oct 2021 12:45:39 +0200 Subject: [PATCH 1476/1831] Test atomic position with exploded king --- test.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test.py b/test.py index 1fcc13ec0..0c2c3f86b 100755 --- a/test.py +++ b/test.py @@ -4127,6 +4127,11 @@ def test_atomic960(self): self.assertEqual(game.end().parent.board().fen(), "rkr1b1n1/1pp2p2/4n1p1/p2pp2p/3P3P/Q1P3P1/PP2PP2/RK3N2 w Qkq - 0 10") self.assertEqual(game.end().board().fen(), "rkr1b1n1/1pp2p2/4n1p1/p2pp2p/3P3P/Q1P3P1/PP2PP2/2KR1N2 b kq - 1 10") + def test_atomic_king_exploded(self): + board = chess.variant.AtomicBoard("rn5r/pp4pp/2p3Nn/5p2/1b2P1PP/8/PPP2P2/R1B1KB1R b KQ - 0 9") + self.assertEqual(board.outcome().winner, chess.WHITE) + self.assertEqual(board.status(), chess.STATUS_VALID) + class RacingKingsTestCase(unittest.TestCase): From 634a7519c53485b66d3ed0f1b6546dd5a5176105 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 27 Oct 2021 12:03:35 +0200 Subject: [PATCH 1477/1831] add 3check perft --- .github/workflows/test.yml | 1 + examples/perft/3check.perft | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 examples/perft/3check.perft diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 21aac88f3..8353a4c9c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,6 +33,7 @@ jobs: - run: python examples/perft/perft.py -t 1 --variant racingkings examples/perft/racingkings.perft - run: python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft - run: python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft + - run: python examples/perft/perft.py -t 1 --variant 3check examples/perft/3check.perft mypy: strategy: matrix: diff --git a/examples/perft/3check.perft b/examples/perft/3check.perft new file mode 100644 index 000000000..7a111de78 --- /dev/null +++ b/examples/perft/3check.perft @@ -0,0 +1,5 @@ +id 3check-kiwipete +epd r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 1+1 +perft 1 48 +perft 2 2039 +perft 3 97848 From 0f534ea8f0b5b9e927a878041510696a57be17b9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 27 Oct 2021 12:20:42 +0200 Subject: [PATCH 1478/1831] Also test 3check for castling gives check --- examples/perft/3check.perft | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/perft/3check.perft b/examples/perft/3check.perft index 7a111de78..291a67865 100644 --- a/examples/perft/3check.perft +++ b/examples/perft/3check.perft @@ -3,3 +3,9 @@ epd r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 1+1 perft 1 48 perft 2 2039 perft 3 97848 + +id 3check-castling +epd r3k2r/8/8/8/8/8/8/R3K2R w KQkq - 1+1 +perft 1 26 +perft 2 562 +perft 3 13410 From a53d68d0937f554e5cf4249075d6d2360f32d4ba Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Nov 2021 15:27:01 +0100 Subject: [PATCH 1479/1831] Add "3 check" as variant alias --- chess/variant.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/variant.py b/chess/variant.py index 9580d723b..82f841648 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -694,7 +694,7 @@ def restore(self, board: ThreeCheckBoardT) -> None: class ThreeCheckBoard(chess.Board): - aliases = ["Three-check", "Three check", "Threecheck", "Three check chess", "3-check", "3check"] + aliases = ["Three-check", "Three check", "Threecheck", "Three check chess", "3-check", "3 check", "3check"] uci_variant = "3check" xboard_variant = "3check" starting_fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 3+3 0 1" From 3609397dff7983a33aaf6b5a8aec3d5f7d554b10 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 1 Nov 2021 19:54:24 +0100 Subject: [PATCH 1480/1831] Issue #815: Convert eleven statements to the usage of augmented assignments Augmented assignment statements became available with Python 2. https://docs.python.org/3/whatsnew/2.0.html#augmented-assignment Thus improve eleven source code places accordingly. Signed-off-by: Markus Elfring --- chess/__init__.py | 16 ++++++++-------- chess/gaviota.py | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 50c1a8e2a..b4ecffa36 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -303,19 +303,19 @@ def flip_diagonal(bb: Bitboard) -> Bitboard: t = (bb ^ (bb << 28)) & 0x0f0f_0f0f_0000_0000 bb = bb ^ (t ^ (t >> 28)) t = (bb ^ (bb << 14)) & 0x3333_0000_3333_0000 - bb = bb ^ (t ^ (t >> 14)) + bb ^= t ^ (t >> 14) t = (bb ^ (bb << 7)) & 0x5500_5500_5500_5500 - bb = bb ^ (t ^ (t >> 7)) + bb ^= t ^ (t >> 7) return bb def flip_anti_diagonal(bb: Bitboard) -> Bitboard: # https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating#FlipabouttheAntidiagonal t = bb ^ (bb << 36) - bb = bb ^ ((t ^ (bb >> 36)) & 0xf0f0_f0f0_0f0f_0f0f) + bb ^= (t ^ (bb >> 36)) & 0xf0f0_f0f0_0f0f_0f0f t = (bb ^ (bb << 18)) & 0xcccc_0000_cccc_0000 - bb = bb ^ (t ^ (t >> 18)) + bb ^= t ^ (t >> 18) t = (bb ^ (bb << 9)) & 0xaa00_aa00_aa00_aa00 - bb = bb ^ (t ^ (t >> 9)) + bb ^= t ^ (t >> 9) return bb @@ -3230,7 +3230,7 @@ def has_kingside_castling_rights(self, color: Color) -> bool: if rook > king_mask: return True - castling_rights = castling_rights & (castling_rights - 1) + castling_rights &= castling_rights - 1 return False @@ -3251,7 +3251,7 @@ def has_queenside_castling_rights(self, color: Color) -> bool: if rook < king_mask: return True - castling_rights = castling_rights & (castling_rights - 1) + castling_rights &= castling_rights - 1 return False @@ -3527,7 +3527,7 @@ def generate_castling_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboar backrank = BB_RANK_1 if self.turn == WHITE else BB_RANK_8 king = self.occupied_co[self.turn] & self.kings & ~self.promoted & backrank & from_mask - king = king & -king + king &= -king if not king: return diff --git a/chess/gaviota.py b/chess/gaviota.py index 360cc7120..454949795 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -102,7 +102,7 @@ def map24_b(s: int) -> int: - s = s - 8 + s -= 8 return ((s & 3) + s) >> 1 def map88(x: int) -> int: @@ -219,7 +219,7 @@ def init_ppp48_idx() -> Tuple[List[List[List[int]]], List[int], List[int], List[ ppp48_sq_x[idx] = i ppp48_sq_y[idx] = j ppp48_sq_z[idx] = k - idx = idx + 1 + idx += 1 return ppp48_idx, ppp48_sq_x, ppp48_sq_y, ppp48_sq_z @@ -253,7 +253,7 @@ def init_aaa() -> Tuple[List[int], List[List[int]]]: accum = 0 aaa_base = [0] * 64 for a in range(64 - 1): - accum = accum + comb[a] + accum += comb[a] aaa_base[a + 1] = accum # Get aaa_xyz. From 9dd2e76ac31d327225fa003a8a216beb6cc1e858 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 3 Nov 2021 14:39:18 +0100 Subject: [PATCH 1481/1831] Revert some of 3609397dff798 for ducktyping --- chess/__init__.py | 12 ++++++------ test.py | 7 +++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index b4ecffa36..35903383e 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -301,21 +301,21 @@ def flip_horizontal(bb: Bitboard) -> Bitboard: def flip_diagonal(bb: Bitboard) -> Bitboard: # https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating#FlipabouttheDiagonal t = (bb ^ (bb << 28)) & 0x0f0f_0f0f_0000_0000 - bb = bb ^ (t ^ (t >> 28)) + bb = bb ^ t ^ (t >> 28) t = (bb ^ (bb << 14)) & 0x3333_0000_3333_0000 - bb ^= t ^ (t >> 14) + bb = bb ^ t ^ (t >> 14) t = (bb ^ (bb << 7)) & 0x5500_5500_5500_5500 - bb ^= t ^ (t >> 7) + bb = bb ^ t ^ (t >> 7) return bb def flip_anti_diagonal(bb: Bitboard) -> Bitboard: # https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating#FlipabouttheAntidiagonal t = bb ^ (bb << 36) - bb ^= (t ^ (bb >> 36)) & 0xf0f0_f0f0_0f0f_0f0f + bb = bb ^ ((t ^ (bb >> 36)) & 0xf0f0_f0f0_0f0f_0f0f) t = (bb ^ (bb << 18)) & 0xcccc_0000_cccc_0000 - bb ^= t ^ (t >> 18) + bb = bb ^ t ^ (t >> 18) t = (bb ^ (bb << 9)) & 0xaa00_aa00_aa00_aa00 - bb ^= t ^ (t >> 9) + bb = bb ^ t ^ (t >> 9) return bb diff --git a/test.py b/test.py index 0c2c3f86b..4e3396fb3 100755 --- a/test.py +++ b/test.py @@ -1892,6 +1892,13 @@ def test_int_conversion(self): def test_tolist(self): self.assertEqual(chess.SquareSet(chess.BB_LIGHT_SQUARES).tolist().count(True), 32) + def test_flip_ducktyping(self): + bb = 0x1e22_2212_0e0a_1222 + squares = chess.SquareSet(bb) + for f in [chess.flip_vertical, chess.flip_horizontal, chess.flip_diagonal, chess.flip_anti_diagonal]: + self.assertEqual(int(f(squares)), f(bb)) + self.assertEqual(int(squares), bb) # Not mutated + class PolyglotTestCase(unittest.TestCase): From 9135f9392bd06dd78bdfd755630c359597cbf77c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 3 Nov 2021 14:41:10 +0100 Subject: [PATCH 1482/1831] Increase depth in test_sf_analysis for Stockfish 14.1 --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 4e3396fb3..e57d8f2cd 100755 --- a/test.py +++ b/test.py @@ -2930,7 +2930,7 @@ def test_sf_options(self): def test_sf_analysis(self): with chess.engine.SimpleEngine.popen_uci("stockfish", setpgrp=True, debug=True) as engine: board = chess.Board("8/6K1/1p1B1RB1/8/2Q5/2n1kP1N/3b4/4n3 w - - 0 1") - limit = chess.engine.Limit(depth=26) + limit = chess.engine.Limit(depth=28) analysis = engine.analysis(board, limit) with analysis: for info in iter(analysis.next, None): From 67a7e00ecd5bc64c8942a938222b28fb8265f4a8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 8 Dec 2021 15:07:04 +0100 Subject: [PATCH 1483/1831] At least mention is_fifty_moves() (closes #824) --- chess/__init__.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 35903383e..bfa4548db 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2017,10 +2017,13 @@ def can_claim_fifty_moves(self) -> bool: """ Checks if the player to move can claim a draw by the fifty-move rule. - Draw by the fifty-move rule can be claimed once the clock of halfmoves - since the last capture or pawn move becomes equal or greater to 100, - or if there is a legal move that achieves this. Other means of ending - the game take precedence. + :func:`~chess.Board.is_fifty_moves()` checks that the clock of + halfmoves since the last capture or pawn move is greater or equal + to 100, and that no other means of ending the game (like checkmate) + take precedence. + + In addition, the fifty-move rule can also be claimed if there is a + legal move that achieves this condition. """ if self.is_fifty_moves(): return True From 22b61f1e3bfa5b2c310a9b471b004c1b3fe18704 Mon Sep 17 00:00:00 2001 From: Qing Date: Fri, 17 Dec 2021 22:22:29 +0100 Subject: [PATCH 1484/1831] support of emt (Elapsed Move Time) command in pgn comments --- chess/pgn.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/chess/pgn.py b/chess/pgn.py index fccf9f216..a7269c658 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -121,6 +121,7 @@ CLOCK_REGEX = re.compile(r"""\[%clk\s(\d+):(\d+):(\d+(?:\.\d*)?)\]""") +EMT_REGEX = re.compile(r"""\[%emt\s(\d+):(\d+):(\d+(?:\.\d*)?)\]""") EVAL_REGEX = re.compile(r""" \[%eval\s(?: @@ -515,6 +516,40 @@ def set_clock(self, seconds: Optional[float]) -> None: self.comment += " " self.comment += clk + def emt(self) -> Optional[float]: + """ + Parses the first valid ``[%emt ...]`` annotation in the comment of + this node, if any. + + Returns the player's elapsed move time use for the comment of this + move, in seconds. + """ + match = EMT_REGEX.search(self.comment) + if match is None: + return None + return int(match.group(1)) * 3600 + int(match.group(2)) * 60 + float(match.group(3)) + + def set_emt(self, seconds: Optional[float]) -> None: + """ + Replaces the first valid ``[%emt ...]`` annotation in the comment of + this node or adds a new one. + """ + emt = "" + if seconds is not None: + seconds = max(0, seconds) + hours = int(seconds // 3600) + minutes = int(seconds % 3600 // 60) + seconds = seconds % 3600 % 60 + seconds_part = f"{seconds:06.3f}".rstrip("0").rstrip(".") + emt = f"[%emt {hours:d}:{minutes:02d}:{seconds_part}]" + + self.comment, found = EMT_REGEX.subn(emt, self.comment, count=1) + + if not found and emt: + if self.comment and not self.comment.endswith(" "): + self.comment += " " + self.comment += emt + @abc.abstractmethod def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: """ From fd8f10c265af76ed39c0c27bad078562a6d83b8a Mon Sep 17 00:00:00 2001 From: aipv Date: Sun, 19 Dec 2021 17:38:10 +0100 Subject: [PATCH 1485/1831] test cases for emt commmand in pgn.py --- test.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test.py b/test.py index e57d8f2cd..5adc44a64 100755 --- a/test.py +++ b/test.py @@ -2749,11 +2749,31 @@ def test_annotations(self): self.assertEqual(arrows[1].color, "red") self.assertEqual(arrows[2].color, "green") + self.assertTrue(game.emt() is None) + emt = 321 + game.set_emt(emt) + self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5] [%emt 0:05:21]") + self.assertEqual(game.emt(), emt) + + game.set_emt(None) game.set_clock(None) game.set_eval(None) game.set_arrows([]) self.assertEqual(game.comment, "foo [%bar] baz") + def test_float_emt(self): + game = chess.pgn.Game() + game.comment = "[%emt 0:00:01.234]" + self.assertEqual(game.emt(), 1.234) + + game.set_emt(6.54321) + self.assertEqual(game.comment, "[%emt 0:00:06.543]") + self.assertEqual(game.emt(), 6.543) + + game.set_emt(-70) + self.assertEqual(game.comment, "[%emt 0:00:00]") # Clamped + self.assertEqual(game.emt(), 0) + def test_float_clk(self): game = chess.pgn.Game() game.comment = "[%clk 0:00:01.234]" From 65bf7ff9a20b6d218016144ce9f77d940b8d8263 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 20 Dec 2021 11:12:56 +0100 Subject: [PATCH 1486/1831] Prefer time.perf_counter() for measurement in example --- examples/bratko_kopec/bratko_kopec.py | 1 - examples/perft/perft.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/bratko_kopec/bratko_kopec.py b/examples/bratko_kopec/bratko_kopec.py index 8e5210b70..62e3655a6 100755 --- a/examples/bratko_kopec/bratko_kopec.py +++ b/examples/bratko_kopec/bratko_kopec.py @@ -3,7 +3,6 @@ """Run an EPD test suite with a UCI engine.""" import asyncio -import time import argparse import itertools import logging diff --git a/examples/perft/perft.py b/examples/perft/perft.py index ef815c620..2c70cd2ed 100755 --- a/examples/perft/perft.py +++ b/examples/perft/perft.py @@ -60,7 +60,7 @@ def main(perft_file: TextIO, VariantBoard: Type[chess.Board], perft_f: Callable[ board = VariantBoard(chess960=True) column = 0 total_nodes = 0 - start_time = time.time() + start_time = time.perf_counter() for line in perft_file: # Skip comments and empty lines. @@ -100,14 +100,14 @@ def main(perft_file: TextIO, VariantBoard: Type[chess.Board], perft_f: Callable[ if column >= 40: column = 0 - sys.stdout.write(f" nodes {total_nodes} nps {sdiv(total_nodes, time.time() - start_time):.0f}\n") + sys.stdout.write(f" nodes {total_nodes} nps {sdiv(total_nodes, time.perf_counter() - start_time):.0f}\n") else: print() print("Unknown command:", cmd, arg) sys.exit(2) if column: - sys.stdout.write(f" nodes {total_nodes} nps {sdiv(total_nodes, time.time() - start_time):.0f}\n") + sys.stdout.write(f" nodes {total_nodes} nps {sdiv(total_nodes, time.perf_counter() - start_time):.0f}\n") if __name__ == "__main__": From b5a9cb52489ca63981490e1fa8a73eccc6ef2f86 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 22 Dec 2021 23:19:03 +0100 Subject: [PATCH 1487/1831] Test and fix SquareSet.{issuperset,issubset}() (fixes #838) --- chess/__init__.py | 4 ++-- test.py | 40 +++++++++++++++++++++++----------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index bfa4548db..c54f23997 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3869,11 +3869,11 @@ def isdisjoint(self, other: IntoSquareSet) -> bool: def issubset(self, other: IntoSquareSet) -> bool: """Tests if this square set is a subset of another.""" - return not bool(~self & other) + return not bool(self & ~SquareSet(other)) def issuperset(self, other: IntoSquareSet) -> bool: """Tests if this square set is a superset of another.""" - return not bool(self & ~SquareSet(other)) + return not bool(~self & other) def union(self, other: IntoSquareSet) -> SquareSet: return self | other diff --git a/test.py b/test.py index 5adc44a64..0aac186fb 100755 --- a/test.py +++ b/test.py @@ -1796,24 +1796,30 @@ def test_arithmetic(self): self.assertEqual(bb, chess.BB_C1) def test_immutable_set_operations(self): - self.assertTrue(chess.SquareSet(chess.BB_RANK_1).isdisjoint(chess.BB_RANK_2)) - self.assertFalse(chess.SquareSet(chess.BB_RANK_2).isdisjoint(chess.BB_FILE_E)) - - self.assertFalse(chess.SquareSet(chess.BB_A1).issubset(chess.BB_RANK_1)) - self.assertTrue(chess.SquareSet(chess.BB_RANK_1).issubset(chess.BB_A1)) - - self.assertTrue(chess.SquareSet(chess.BB_A1).issuperset(chess.BB_RANK_1)) - self.assertFalse(chess.SquareSet(chess.BB_RANK_1).issuperset(chess.BB_A1)) - - self.assertEqual(chess.SquareSet(chess.BB_A1).union(chess.BB_FILE_A), chess.BB_FILE_A) - - self.assertEqual(chess.SquareSet(chess.BB_A1).intersection(chess.BB_A2), chess.BB_EMPTY) - - self.assertEqual(chess.SquareSet(chess.BB_A1).difference(chess.BB_A2), chess.BB_A1) - - self.assertEqual(chess.SquareSet(chess.BB_A1).symmetric_difference(chess.BB_A2), chess.BB_A1 | chess.BB_A2) + examples = [ + chess.BB_EMPTY, + chess.BB_A1, + chess.BB_A2, + chess.BB_RANK_1, + chess.BB_RANK_2, + chess.BB_FILE_A, + chess.BB_FILE_E, + ] - self.assertEqual(chess.SquareSet(chess.BB_C5).copy(), chess.BB_C5) + for a in examples: + self.assertEqual(chess.SquareSet(a).copy(), a) + + for a in examples: + a = chess.SquareSet(a) + for b in examples: + b = chess.SquareSet(b) + self.assertEqual(set(a).isdisjoint(set(b)), a.isdisjoint(b)) + self.assertEqual(set(a).issubset(set(b)), a.issubset(b)) + self.assertEqual(set(a).issuperset(set(b)), a.issuperset(b)) + self.assertEqual(set(a).union(set(b)), set(a.union(b))) + self.assertEqual(set(a).intersection(set(b)), set(a.intersection(b))) + self.assertEqual(set(a).difference(set(b)), set(a.difference(b))) + self.assertEqual(set(a).symmetric_difference(set(b)), set(a.symmetric_difference(b))) def test_mutable_set_operations(self): squares = chess.SquareSet(chess.BB_A1) From 29f7bb883c810f6fecb46766b48e85253e7b9d9a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 23 Dec 2021 00:08:52 +0100 Subject: [PATCH 1488/1831] Fix typing of ChainMap iterators https://github.com/microsoft/pylance-release/issues/2097 --- chess/engine.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 390190035..7fdf7fed6 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1435,7 +1435,7 @@ def line_received(self, engine: UciProtocol, line: str) -> None: return await self.communicate(UciPingCommand) def _changed_options(self, options: ConfigMapping) -> bool: - return any(value is None or value != self.config.get(name) for name, value in collections.ChainMap(options, self.target_config).items()) + return any(value is None or value != self.config.get(name) for name, value in _chain_config(options, self.target_config)) def _setoption(self, name: str, value: ConfigValue) -> None: try: @@ -1457,7 +1457,7 @@ def _setoption(self, name: str, value: ConfigValue) -> None: self.config[name] = value def _configure(self, options: ConfigMapping) -> None: - for name, value in collections.ChainMap(options, self.target_config).items(): + for name, value in _chain_config(options, self.target_config): if name.lower() in MANAGED_OPTIONS: raise EngineError("cannot set {} which is automatically managed".format(name)) self._setoption(name, value) @@ -1845,6 +1845,14 @@ def _parse_uci_bestmove(board: chess.Board, args: str) -> BestMove: return BestMove(move, ponder) +def _chain_config(a: ConfigMapping, b: ConfigMapping) -> Iterator[Tuple[str, ConfigValue]]: + for name, value in a.items(): + yield name, value + for name, value in b.items(): + if name not in a: + yield name, value + + class UciOptionMap(MutableMapping[str, T]): """Dictionary with case-insensitive keys.""" @@ -2348,7 +2356,7 @@ def _setoption(self, name: str, value: ConfigValue) -> None: self.send_line(f"option {name}={value}") def _configure(self, options: ConfigMapping) -> None: - for name, value in collections.ChainMap(options, self.target_config).items(): + for name, value in _chain_config(options, self.target_config): if name.lower() in MANAGED_OPTIONS: raise EngineError(f"cannot set {name} which is automatically managed") self._setoption(name, value) From 78a67fd79e7b770563bca4c2ca25b73a3625bc75 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 23 Dec 2021 00:11:54 +0100 Subject: [PATCH 1489/1831] 3.10.0-beta.1 -> 3.10 in GitHub workflows --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8353a4c9c..7f3d24e5c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.7", "3.8", "3.9", "3.10.0-beta.1"] + python-version: ["3.7", "3.8", "3.9", "3.10"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 @@ -37,7 +37,7 @@ jobs: mypy: strategy: matrix: - python-version: ["3.8", "3.9", "3.10.0-beta.1"] + python-version: ["3.8", "3.9", "3.10"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -51,7 +51,7 @@ jobs: readme: strategy: matrix: - python-version: ["3.10.0-beta.1"] + python-version: ["3.10"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 0e9ac77f4431b8b8e0c154c314d03505fc01310a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 23 Dec 2021 00:29:24 +0100 Subject: [PATCH 1490/1831] Update Python version dependent output in doctest --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 37506a259..f02d0e584 100644 --- a/README.rst +++ b/README.rst @@ -131,7 +131,7 @@ Features >>> board.is_insufficient_material() False >>> board.outcome() - Outcome(termination=Termination.CHECKMATE, winner=True) + Outcome(termination=, winner=True) * Detects repetitions. Has a half-move clock. From d93c0b237b33d0652197958cd4a1cdeb72b7f7a2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 23 Dec 2021 14:37:35 +0100 Subject: [PATCH 1491/1831] Prepare 1.8.0 --- CHANGELOG.rst | 12 ++++++++++++ chess/__init__.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 68e381d50..705421688 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,18 @@ Changelog for python-chess ========================== +New in v1.8.0 +------------- + +Bugfixes: + +* Fix ``SquareSet.issuperset()`` and ``SquareSet.issubset()`` by swapping + their respective implementations. + +New features: + +* Read and write PGN comments like ``[%emt 0:05:21]``. + New in v1.7.0 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index c54f23997..72baf64a4 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.7.0" +__version__ = "1.8.0" import collections import copy From 2bbf0b55025b7f1275a27c936373ef20d318a3b8 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Fri, 24 Dec 2021 22:13:53 +1100 Subject: [PATCH 1492/1831] docs: Fix a few typos There are small typos in: - chess/__init__.py - chess/syzygy.py Fixes: - Should read `necessary` rather than `nescessary`. - Should read `occurred` rather than `occured`. --- chess/__init__.py | 4 ++-- chess/syzygy.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 72baf64a4..b5fea88e0 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2045,7 +2045,7 @@ def can_claim_threefold_repetition(self) -> bool: Checks if the player to move can claim a draw by threefold repetition. Draw by threefold repetition can be claimed if the position on the - board occured for the third time or if such a repetition is reached + board occurred for the third time or if such a repetition is reached with one of the possible legal moves. Note that checking this can be slow: In the worst case @@ -2070,7 +2070,7 @@ def can_claim_threefold_repetition(self) -> bool: while switchyard: self.push(switchyard.pop()) - # Threefold repetition occured. + # Threefold repetition occurred. if transpositions[transposition_key] >= 3: return True diff --git a/chess/syzygy.py b/chess/syzygy.py index b818f1a8c..3b477e769 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1495,7 +1495,7 @@ class Tablebase: If *max_fds* is not ``None``, will at most use *max_fds* open file descriptors at any given time. The least recently used tables are closed, - if nescessary. + if necessary. """ def __init__(self, *, max_fds: Optional[int] = 128, VariantBoard: Type[chess.Board] = chess.Board) -> None: self.variant = VariantBoard From d0f48c6f333c5132bc351317ca513d82a497990b Mon Sep 17 00:00:00 2001 From: Philipp Fruck Date: Sun, 16 Jan 2022 19:30:15 +0100 Subject: [PATCH 1493/1831] update missing documentation for `is_fifty_moves()` Co-authored-by: Anton Plagemann <54081139+antonplagemann@users.noreply.github.com> Co-authored-by: Pius Walter --- chess/__init__.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index b5fea88e0..4d58d6e32 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2011,19 +2011,20 @@ def can_claim_draw(self) -> bool: return self.can_claim_fifty_moves() or self.can_claim_threefold_repetition() def is_fifty_moves(self) -> bool: + """ + Checks that the clock of halfmoves since the last capture or pawn move + is greater or equal to 100, and that no other means of ending the game + (like checkmate) take precedence. + """ return self._is_halfmoves(100) def can_claim_fifty_moves(self) -> bool: """ Checks if the player to move can claim a draw by the fifty-move rule. - :func:`~chess.Board.is_fifty_moves()` checks that the clock of - halfmoves since the last capture or pawn move is greater or equal - to 100, and that no other means of ending the game (like checkmate) - take precedence. - - In addition, the fifty-move rule can also be claimed if there is a - legal move that achieves this condition. + In addition to :func:`~chess.Board.is_fifty_moves()`, the fifty-move + rule can also be claimed if there is a legal move that achieves this + condition. """ if self.is_fifty_moves(): return True From 457f5f4d32b8eacb9ababfa4608925a3129a372e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 28 Jan 2022 10:23:37 +0100 Subject: [PATCH 1494/1831] Try CodeQL --- .github/workflows/codeql.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..31a63b204 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,18 @@ +name: CodeQL + +on: [push, pull_request] + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - uses: actions/checkout@v2 + - uses: github/codeql-action/init@v1 + with: + languages: python + - uses: github/codeql-action/analyze@v1 From 3c3fa25caacc1dd82e03ad6ebedf5e98c860c862 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 28 Jan 2022 14:11:39 +0100 Subject: [PATCH 1495/1831] Add ascii board as description of svg The tag in SVG can store a textual description, eg. for better accessibility. For the chess board there could be the string representation (basically str(chess.Board()) and enclosed in

 it is
readable in text browsers like links or w3m when the svg is embedded in
html.
---
 chess/svg.py | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/chess/svg.py b/chess/svg.py
index 9ddf044d8..4f10c5789 100644
--- a/chess/svg.py
+++ b/chess/svg.py
@@ -286,6 +286,11 @@ def board(board: Optional[chess.BaseBoard] = None, *,
     if style:
         ET.SubElement(svg, "style").text = style
 
+    if board:
+        desc = ET.SubElement(svg, "desc")
+        asciiboard = ET.SubElement(desc, "pre")
+        asciiboard.text = str(board)
+
     defs = ET.SubElement(svg, "defs")
     if board:
         for piece_color in chess.COLORS:

From dd759f21230e280a78a0c2c15d6321e74b651476 Mon Sep 17 00:00:00 2001
From: Niklas Fiekas 
Date: Sun, 6 Feb 2022 10:08:11 +0100
Subject: [PATCH 1496/1831] Add another impossible en passant perft
 (niklasf/shakmaty#53)

---
 examples/perft/tricky.perft | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/examples/perft/tricky.perft b/examples/perft/tricky.perft
index f0e9d78c5..b3cca9fd2 100644
--- a/examples/perft/tricky.perft
+++ b/examples/perft/tricky.perft
@@ -123,3 +123,9 @@ epd 8/8/8/1k6/3Pp3/8/8/4KQ2 b - d3
 perft 1 6
 perft 2 121
 perft 3 711
+
+id ep-unrelated-check
+epd rnbqk1nr/bb3p1p/1q2r3/2pPp3/3P4/7P/1PP1NpPP/R1BQKBNR w KQkq c6
+perft 1 2
+perft 2 92
+perft 3 2528

From ad279165c78ec46ecc9a4d03004ce20b61f41ecf Mon Sep 17 00:00:00 2001
From: Niklas Fiekas 
Date: Sun, 6 Feb 2022 15:54:09 +0100
Subject: [PATCH 1497/1831] Detect impossible check due to en passant

---
 chess/__init__.py | 21 +++++++++++++++------
 chess/variant.py  |  5 +++--
 test.py           | 12 ++++++++++--
 3 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/chess/__init__.py b/chess/__init__.py
index 4d58d6e32..9ce9daa32 100644
--- a/chess/__init__.py
+++ b/chess/__init__.py
@@ -3356,12 +3356,21 @@ def status(self) -> Status:
         # More than the maximum number of possible checkers in the variant.
         checkers = self.checkers_mask()
         our_kings = self.kings & self.occupied_co[self.turn] & ~self.promoted
-        if popcount(checkers) > 2:
-            errors |= STATUS_TOO_MANY_CHECKERS
-        elif popcount(checkers) == 2 and ray(lsb(checkers), msb(checkers)) & our_kings:
-            errors |= STATUS_IMPOSSIBLE_CHECK
-        elif valid_ep_square is not None and any(ray(checker, valid_ep_square) & our_kings for checker in scan_reversed(checkers)):
-            errors |= STATUS_IMPOSSIBLE_CHECK
+        if checkers:
+            if popcount(checkers) > 2:
+                errors |= STATUS_TOO_MANY_CHECKERS
+
+            if valid_ep_square is not None:
+                pushed_to = valid_ep_square ^ A2
+                pushed_from = valid_ep_square ^ A4
+                occupied_before = (self.occupied & ~BB_SQUARES[pushed_to]) | BB_SQUARES[pushed_from]
+                if popcount(checkers) > 1 or (
+                        msb(checkers) != pushed_to and
+                        self._attacked_for_king(our_kings, occupied_before)):
+                    errors |= STATUS_IMPOSSIBLE_CHECK
+            else:
+                if popcount(checkers) > 2 or (popcount(checkers) == 2 and ray(lsb(checkers), msb(checkers)) & our_kings):
+                    errors |= STATUS_IMPOSSIBLE_CHECK
 
         return errors
 
diff --git a/chess/variant.py b/chess/variant.py
index 82f841648..9e586b79c 100644
--- a/chess/variant.py
+++ b/chess/variant.py
@@ -320,7 +320,8 @@ def status(self) -> chess.Status:
             status &= ~chess.STATUS_NO_BLACK_KING
         if chess.popcount(self.checkers_mask()) <= 14:
             status &= ~chess.STATUS_TOO_MANY_CHECKERS
-        status &= ~chess.STATUS_IMPOSSIBLE_CHECK
+        if self._valid_ep_square() is None:
+            status &= ~chess.STATUS_IMPOSSIBLE_CHECK
         return status
 
 
@@ -409,7 +410,7 @@ def has_insufficient_material(self, color: chess.Color) -> bool:
     def status(self) -> chess.Status:
         status = super().status()
         if self.is_check():
-            status |= chess.STATUS_RACE_CHECK | chess.STATUS_TOO_MANY_CHECKERS
+            status |= chess.STATUS_RACE_CHECK | chess.STATUS_TOO_MANY_CHECKERS | chess.STATUS_IMPOSSIBLE_CHECK
         if self.turn == chess.BLACK and all(self.occupied_co[co] & self.kings & chess.BB_RANK_8 for co in chess.COLORS):
             status |= chess.STATUS_RACE_OVER
         if self.pawns:
diff --git a/test.py b/test.py
index 0aac186fb..ace378c43 100755
--- a/test.py
+++ b/test.py
@@ -994,7 +994,7 @@ def test_status(self):
 
         # Triple check.
         board = chess.Board("4k3/5P2/3N4/8/8/8/4R3/4K3 b - - 0 1")
-        self.assertEqual(board.status(), chess.STATUS_TOO_MANY_CHECKERS)
+        self.assertEqual(board.status(), chess.STATUS_TOO_MANY_CHECKERS | chess.STATUS_IMPOSSIBLE_CHECK)
 
         # Impossible checker alignment.
         board = chess.Board("3R4/8/q4k2/2B5/1NK5/3b4/8/8 w - - 0 1")
@@ -1675,6 +1675,14 @@ def test_king_captures_unmoved_rook(self):
         board.push(move)
         self.assertEqual(board.fen(), "8/8/8/B2p3Q/2qPp1P1/b7/2P2P1P/4K2k w - - 0 2")
 
+    def test_impossible_check_due_to_en_passant(self):
+        board = chess.Board("rnbqk1nr/bb3p1p/1q2r3/2pPp3/3P4/7P/1PP1NpPP/R1BQKBNR w KQkq c6")
+        self.assertEqual(board.status(), chess.STATUS_IMPOSSIBLE_CHECK)
+        self.assertEqual(board.ep_square, chess.C6)
+        self.assertTrue(board.has_pseudo_legal_en_passant())
+        self.assertFalse(board.has_legal_en_passant())
+        self.assertEqual(len(list(board.legal_moves)), 2)
+
 
 class LegalMoveGeneratorTestCase(unittest.TestCase):
 
@@ -4279,7 +4287,7 @@ def test_legal_moves_after_end(self):
     def test_racing_kings_status_with_check(self):
         board = chess.variant.RacingKingsBoard("8/8/8/8/R7/8/krbnNB1K/qrbnNBRQ b - - 1 1")
         self.assertFalse(board.is_valid())
-        self.assertEqual(board.status(), chess.STATUS_RACE_CHECK | chess.STATUS_TOO_MANY_CHECKERS)
+        self.assertEqual(board.status(), chess.STATUS_RACE_CHECK | chess.STATUS_TOO_MANY_CHECKERS | chess.STATUS_IMPOSSIBLE_CHECK)
 
 
 class HordeTestCase(unittest.TestCase):

From 6451f5211aefaf55a408af78ca37cc225fedc7d6 Mon Sep 17 00:00:00 2001
From: Niklas Fiekas 
Date: Wed, 2 Mar 2022 15:02:13 +0100
Subject: [PATCH 1498/1831] Provide hint for SIGILL (#858)

---
 chess/engine.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/chess/engine.py b/chess/engine.py
index 7fdf7fed6..b82043c34 100644
--- a/chess/engine.py
+++ b/chess/engine.py
@@ -1229,7 +1229,8 @@ def __init__(self, engine: ProtocolT) -> None:
         self.finished: asyncio.Future[None] = asyncio.Future()
 
     def _engine_terminated(self, engine: ProtocolT, code: int) -> None:
-        exc = EngineTerminatedError(f"engine process died unexpectedly (exit code: {code})")
+        hint = ", binary not compatible with cpu?" if code in [-4, 0xc000001d] else ""
+        exc = EngineTerminatedError(f"engine process died unexpectedly (exit code: {code}{hint})")
         if self.state == CommandState.ACTIVE:
             self.engine_terminated(engine, exc)
         elif self.state == CommandState.CANCELLING:

From 193a3ba0994cb218be31499af2a1786bd967e645 Mon Sep 17 00:00:00 2001
From: Niklas Fiekas 
Date: Wed, 2 Mar 2022 16:38:09 +0100
Subject: [PATCH 1499/1831] Fill squares with arbitrary colors (closes #774)

---
 chess/svg.py | 50 +++++++++++++++++++++++++++++++++++++++-----------
 docs/Ne4.svg |  9 ++++++++-
 2 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/chess/svg.py b/chess/svg.py
index 4f10c5789..5a9cccc0a 100644
--- a/chess/svg.py
+++ b/chess/svg.py
@@ -183,8 +183,11 @@ def _attrs(attrs: Dict[str, Union[str, int, float, None]]) -> Dict[str, str]:
     return {k: str(v) for k, v in attrs.items() if v is not None}
 
 
-def _color(colors: Dict[str, str], color: str) -> Tuple[str, float]:
-    color = colors.get(color, DEFAULT_COLORS[color])
+def _select_color(colors: Dict[str, str], color: str) -> Tuple[str, float]:
+    return _color(colors.get(color, DEFAULT_COLORS[color]))
+
+
+def _color(color: str) -> Tuple[str, float]:
     if color.startswith("#"):
         try:
             if len(color) == 5:
@@ -236,6 +239,7 @@ def board(board: Optional[chess.BaseBoard] = None, *,
           lastmove: Optional[chess.Move] = None,
           check: Optional[Square] = None,
           arrows: Iterable[Union[Arrow, Tuple[Square, Square]]] = [],
+          fill: Dict[Square, str] = {},
           squares: Optional[IntoSquareSet] = None,
           size: Optional[int] = None,
           coordinates: bool = True,
@@ -254,7 +258,10 @@ def board(board: Optional[chess.BaseBoard] = None, *,
         ``[chess.svg.Arrow(chess.E2, chess.E4)]``, or a list of tuples, like
         ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same
         square is drawn as a circle, like ``[(chess.E2, chess.E2)]``.
-    :param squares: A :class:`chess.SquareSet` with selected squares.
+    :param fill: A dictionary mapping squares to a colors that they should be
+        filled with.
+    :param squares: A :class:`chess.SquareSet` with selected squares to mark
+        with an X.
     :param size: The size of the image in pixels (e.g., ``400`` for a 400 by
         400 board), or ``None`` (the default) for no size limit.
     :param coordinates: Pass ``False`` to disable the coordinate margin.
@@ -270,8 +277,14 @@ def board(board: Optional[chess.BaseBoard] = None, *,
     >>> import chess.svg
     >>>
     >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1")
-    >>> squares = board.attacks(chess.E4)
-    >>> chess.svg.board(board, squares=squares, size=350)  # doctest: +SKIP
+    >>>
+    >>> chess.svg.board(
+    ...     board,
+    ...     fill=dict.fromkeys(board.attacks(chess.E4), "#cc0000cc") | {chess.E4: "#00cc00cc"},
+    ...     arrows=[chess.svg.Arrow(chess.E4, chess.F6, color="#0000cccc")],
+    ...     squares=chess.SquareSet(chess.BB_DARK_SQUARES & chess.BB_FILE_B),
+    ...     size=350,
+    ... )  # doctest: +SKIP
 
     .. image:: ../docs/Ne4.svg
         :alt: 8/8/8/8/4N3/8/8/8
@@ -307,7 +320,7 @@ def board(board: Optional[chess.BaseBoard] = None, *,
 
     # Render coordinates.
     if coordinates:
-        margin_color, margin_opacity = _color(colors, "margin")
+        margin_color, margin_opacity = _select_color(colors, "margin")
         ET.SubElement(svg, "rect", _attrs({
             "x": 0,
             "y": 0,
@@ -316,7 +329,7 @@ def board(board: Optional[chess.BaseBoard] = None, *,
             "fill": margin_color,
             "opacity": margin_opacity if margin_opacity < 1.0 else None,
         }))
-        coord_color, coord_opacity = _color(colors, "coord")
+        coord_color, coord_opacity = _select_color(colors, "coord")
         for file_index, file_name in enumerate(chess.FILE_NAMES):
             x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin
             svg.append(_coord(file_name, x, 0, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity))
@@ -337,7 +350,7 @@ def board(board: Optional[chess.BaseBoard] = None, *,
         cls = ["square", "light" if chess.BB_LIGHT_SQUARES & bb else "dark"]
         if lastmove and square in [lastmove.from_square, lastmove.to_square]:
             cls.append("lastmove")
-        fill_color, fill_opacity = _color(colors, " ".join(cls))
+        square_color, square_opacity = _select_color(colors, " ".join(cls))
 
         cls.append(chess.SQUARE_NAMES[square])
 
@@ -348,10 +361,25 @@ def board(board: Optional[chess.BaseBoard] = None, *,
             "height": SQUARE_SIZE,
             "class": " ".join(cls),
             "stroke": "none",
-            "fill": fill_color,
-            "opacity": fill_opacity if fill_opacity < 1.0 else None,
+            "fill": square_color,
+            "opacity": square_opacity if square_opacity < 1.0 else None,
         }))
 
+        try:
+            fill_color, fill_opacity = _color(fill[square])
+        except KeyError:
+            pass
+        else:
+            ET.SubElement(svg, "rect", _attrs({
+                "x": x,
+                "y": y,
+                "width": SQUARE_SIZE,
+                "height": SQUARE_SIZE,
+                "stroke": "none",
+                "fill": fill_color,
+                "opacity": fill_opacity if fill_opacity < 1.0 else None,
+            }))
+
     # Render check mark.
     if check is not None:
         file_index = chess.square_file(check)
@@ -405,7 +433,7 @@ def board(board: Optional[chess.BaseBoard] = None, *,
             color = "green"
 
         try:
-            color, opacity = _color(colors, " ".join(["arrow", color]))
+            color, opacity = _select_color(colors, " ".join(["arrow", color]))
         except KeyError:
             opacity = 1.0
 
diff --git a/docs/Ne4.svg b/docs/Ne4.svg
index 65dab1125..4d97635e2 100644
--- a/docs/Ne4.svg
+++ b/docs/Ne4.svg
@@ -1 +1,8 @@
-
\ No newline at end of file
+
. . . . . . . .
+. . . . . . . .
+. . . . . . . .
+. . . . . . . .
+. . . . N . . .
+. . . . . . . .
+. . . . . . . .
+. . . . . . . .
From 197534f04e0b03df89af1642d8a091e11a5edf8e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 2 Mar 2022 18:01:19 +0100 Subject: [PATCH 1500/1831] Update GitHub actions --- .github/workflows/codeql.yml | 2 +- .github/workflows/test.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 31a63b204..a1b9e1b55 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -11,7 +11,7 @@ jobs: contents: read security-events: write steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: github/codeql-action/init@v1 with: languages: python diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7f3d24e5c..dfeeacc1f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,8 +10,8 @@ jobs: python-version: ["3.7", "3.8", "3.9", "3.10"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} - run: .github/workflows/setup-${{ matrix.os }}.sh @@ -21,8 +21,8 @@ jobs: perft: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 with: python-version: "3.10.0-alpha.2" - run: pip install -e . @@ -40,8 +40,8 @@ jobs: python-version: ["3.8", "3.9", "3.10"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} - run: pip install -e . @@ -54,8 +54,8 @@ jobs: python-version: ["3.10"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} - run: sudo apt-get update && sudo apt-get install -y docutils-common From 03509ec03108923b4a141052a99b8f23ff7a8f74 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 18 Mar 2022 11:08:32 +0100 Subject: [PATCH 1501/1831] Prepare 1.9.0 --- CHANGELOG.rst | 18 ++++++++++++++++-- chess/__init__.py | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 705421688..1575e713b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,20 @@ Changelog for python-chess ========================== +New in v1.9.0 +------------- + +Bugfixes: + +* Expand position validation to detect check conflicting with en passant + square. + +New features: + +* Add ``chess.svg.board(..., fill=...)``. +* Let ``chess.svg.board()`` add ASCII board as description of SVG. +* Add hint when engine process dies due to illegal instruction. + New in v1.8.0 ------------- @@ -18,9 +32,9 @@ New in v1.7.0 New features: -* Added new models for ``chess.engine.Score.wdl()``: ``sf`` (the new default) +* Add new models for ``chess.engine.Score.wdl()``: ``sf`` (the new default) and ``sf14``. -* Added ``chess.Board.piece_map()``. +* Add ``chess.Board.piece_map()``. Bugfixes: diff --git a/chess/__init__.py b/chess/__init__.py index 9ce9daa32..da7ff8cbc 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.8.0" +__version__ = "1.9.0" import collections import copy From a21836dafec051143573243752d83002297a4d37 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 18 Mar 2022 12:28:43 +0100 Subject: [PATCH 1502/1831] Update CI to run perft tests on stable Python --- .github/workflows/test.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dfeeacc1f..5a478ad60 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 with: - python-version: "3.10.0-alpha.2" + python-version: "3.10" - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft @@ -49,15 +49,12 @@ jobs: - run: python -m mypy --strict chess - run: python -m mypy --strict examples/**/*.py readme: - strategy: - matrix: - python-version: ["3.10"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 with: - python-version: ${{ matrix.python-version }} + python-version: "3.10" - run: sudo apt-get update && sudo apt-get install -y docutils-common - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null - run: pip install -e . From eef8a29907e91662a24a4f0a79416f14c8a6d24c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 18 Mar 2022 12:29:14 +0100 Subject: [PATCH 1503/1831] Try type-checking on Windows --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5a478ad60..73b5ea44b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,6 +37,7 @@ jobs: mypy: strategy: matrix: + os: [ubuntu-latest, windows-latest] python-version: ["3.8", "3.9", "3.10"] runs-on: ubuntu-latest steps: From f3367ea4b1402ed04be2190371ebc8c72c2276c8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 1 Apr 2022 16:16:12 +0200 Subject: [PATCH 1504/1831] Faithfully preserve whitespace in PGN comments --- chess/pgn.py | 49 +++++++++++++++++++++++++------------------------ test.py | 6 +++--- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index a7269c658..070f12f89 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1584,42 +1584,43 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: # Parse movetext. skip_variation_depth = 0 + fresh_line = True while line: - read_next_line = True - - # Ignore comments. - if line.startswith("%") or line.startswith(";"): - line = handle.readline() - continue - - # An empty line means the end of a game. - if line.isspace(): - visitor.end_game() - return visitor.result() + if fresh_line: + # Ignore comments. + if line.startswith("%") or line.startswith(";"): + line = handle.readline() + continue + # An empty line means the end of a game. + if line.isspace(): + visitor.end_game() + return visitor.result() + fresh_line = True for match in MOVETEXT_REGEX.finditer(line): token = match.group(0) if token.startswith("{"): # Consume until the end of the comment. - line = token[1:] + start_index = 2 if token.startswith("{ ") else 1 + line = token[start_index:] + comment_lines = [] while line and "}" not in line: - comment_lines.append(line.rstrip()) + comment_lines.append(line) line = handle.readline() - end_index = line.find("}") - comment_lines.append(line[:end_index]) - if "}" in line: - line = line[end_index:] - else: - line = "" + + if line: + close_index = line.find("}") + end_index = close_index - 1 if close_index > 0 and line[close_index - 1] == " " else close_index + comment_lines.append(line[:end_index]) + line = line[close_index + 1:] if not skip_variation_depth: - visitor.visit_comment("\n".join(comment_lines).strip()) + visitor.visit_comment("".join(comment_lines)) - # Continue with the current or the next line. - if line: - read_next_line = False + # Continue with the current line. + fresh_line = False break elif token == "(": if skip_variation_depth: @@ -1673,7 +1674,7 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: board_stack[-1].push(move) visitor.visit_board(board_stack[-1]) - if read_next_line: + if fresh_line: line = handle.readline() visitor.end_game() diff --git a/test.py b/test.py index ace378c43..8db8ea150 100755 --- a/test.py +++ b/test.py @@ -2189,9 +2189,9 @@ def test_read_game(self): self.assertEqual(sixth_game.headers["Result"], "1-0") def test_comment_at_eol(self): - pgn = io.StringIO(textwrap.dedent(r"""\ + pgn = io.StringIO(textwrap.dedent("""\ 1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d3 d6 6. Nbd2 a6 $6 (6... Bb6 $5 { - /\ Ne7, c6}) *""")) + /\\ Ne7, c6}) *""")) game = chess.pgn.read_game(pgn) @@ -2202,7 +2202,7 @@ def test_comment_at_eol(self): # Make sure the comment for the second variation is there. self.assertIn(5, node[1].nags) - self.assertEqual(node[1].comment, "/\\ Ne7, c6") + self.assertEqual(node[1].comment, "\n/\\ Ne7, c6") def test_promotion_without_equals(self): # Example game from https://github.com/rozim/ChessData as originally From 0ef3988c49ca8894d76f8fc7f04d3395720b39df Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 1 Apr 2022 16:40:28 +0200 Subject: [PATCH 1505/1831] Join multiple PGN comments with spaces (closes #866) --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 070f12f89..7b5994cde 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1146,11 +1146,11 @@ def visit_comment(self, comment: str) -> None: # a variation. Add as a comment for the game if the comment # starts before any move. new_comment = [self.variation_stack[-1].comment, comment] - self.variation_stack[-1].comment = "\n".join(new_comment).strip() + self.variation_stack[-1].comment = " ".join(filter(None, new_comment)) else: # Otherwise, it is a starting comment. new_comment = [self.starting_comment, comment] - self.starting_comment = "\n".join(new_comment).strip() + self.starting_comment = " ".join(filter(None, new_comment)) def visit_move(self, board: chess.Board, move: chess.Move) -> None: self.variation_stack[-1] = self.variation_stack[-1].add_variation(move) From f11c4f4a3fd307494e57a2856111cfb4ea212860 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 3 Apr 2022 16:02:01 +0200 Subject: [PATCH 1506/1831] Syzygy probing: Use list instead of dict Tests passed. Looking at the code those variables where only accessed by index so I'm not sure why they were defined as dict. Could be done for visibility purpose, then feel free to close the PR. `PawnFileData` could probably be further refractored not to use dicts at all anymore, since it looks like the rust implementation only use `ArrayVec`. --- chess/syzygy.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 3b477e769..7436520f3 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -577,8 +577,7 @@ def __init__(self, path: str, *, variant: Type[chess.Board] = chess.Board) -> No black_part, white_part = tablename.split("v") if self.has_pawns: - self.pawns = {0: white_part.count("P"), - 1: black_part.count("P")} + self.pawns = [white_part.count("P"), black_part.count("P")] if self.pawns[1] > 0 and (self.pawns[0] == 0 or self.pawns[1] < self.pawns[0]): self.pawns[0], self.pawns[1] = self.pawns[1], self.pawns[0] else: @@ -1078,11 +1077,9 @@ def init_table_wdl(self) -> None: self.precomp: Dict[int, PairsData] = {} self.pieces: Dict[int, List[int]] = {} - self.factor = {0: [0 for _ in range(TBPIECES)], - 1: [0 for _ in range(TBPIECES)]} + self.factor = [[0 for _ in range(TBPIECES)], [0 for _ in range(TBPIECES)]] - self.norm = {0: [0 for _ in range(self.num)], - 1: [0 for _ in range(self.num)]} + self.norm = [[0 for _ in range(self.num)], [0 for _ in range(self.num)]] # Used if there are pawns. self.files = [PawnFileData() for _ in range(4)] From fdb236833a5f03257f9e7be686e6a20be509ddbd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 4 Apr 2022 09:38:27 +0200 Subject: [PATCH 1507/1831] Code golf norm and factor init --- chess/syzygy.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 7436520f3..33302ba46 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1076,10 +1076,8 @@ def init_table_wdl(self) -> None: # Used if there are only pieces. self.precomp: Dict[int, PairsData] = {} self.pieces: Dict[int, List[int]] = {} - - self.factor = [[0 for _ in range(TBPIECES)], [0 for _ in range(TBPIECES)]] - - self.norm = [[0 for _ in range(self.num)], [0 for _ in range(self.num)]] + self.factor = [[0 for _ in range(TBPIECES)] for _ in range(2)] + self.norm = [[0 for _ in range(self.num)] for _ in range(2)] # Used if there are pawns. self.files = [PawnFileData() for _ in range(4)] From 5b3126e1ac6a7b8315f9b0970b800cdb1490d317 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 18 Apr 2022 12:19:19 +0200 Subject: [PATCH 1508/1831] Implement and switch to upcoming sf15 WDL model --- chess/engine.py | 18 +++++++++++++++--- test.py | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index b82043c34..7a01f6b1e 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -44,7 +44,7 @@ try: from typing import Literal - _WdlModel = Literal["sf", "sf14", "sf12", "lichess"] + _WdlModel = Literal["sf", "sf15", "sf14", "sf12", "lichess"] except ImportError: # Before Python 3.8. _WdlModel = str # type: ignore @@ -564,7 +564,8 @@ def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: :param model: * ``sf``, the WDL model used by the latest Stockfish - (currently ``sf14``). + (currently ``sf15``). + * ``sf15``, the WDL model used by Stockfish 15. * ``sf14``, the WDL model used by Stockfish 14. * ``sf12``, the WDL model used by Stockfish 12. * ``lichess``, the win rate model used by Lichess. @@ -627,6 +628,14 @@ def __ge__(self, other: object) -> bool: return NotImplemented +def _sf15_wins(cp: int, *, ply: int) -> int: + # https://github.com/official-stockfish/Stockfish/blob/sf_15/src/uci.cpp#L200-L220 + m = min(240, max(ply, 0)) / 64 + a = (((-1.17202460e-1 * m + 5.94729104e-1) * m + 1.12065546e+1) * m) + 1.22606222e+2 + b = (((-1.79066759 * m + 11.30759193) * m + -17.43677612) * m) + 36.47147479 + x = min(2000, max(cp, -2000)) + return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) + def _sf14_wins(cp: int, *, ply: int) -> int: # https://github.com/official-stockfish/Stockfish/blob/sf_14/src/uci.cpp#L200-L220 m = min(240, max(ply, 0)) / 64 @@ -666,9 +675,12 @@ def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: elif model == "sf12": wins = _sf12_wins(self.cp, ply=ply) losses = _sf12_wins(-self.cp, ply=ply) - else: + elif model == "sf14": wins = _sf14_wins(self.cp, ply=ply) losses = _sf14_wins(-self.cp, ply=ply) + else: + wins = _sf15_wins(self.cp, ply=ply) + losses = _sf15_wins(-self.cp, ply=ply) draws = 1000 - wins - losses return Wdl(wins, draws, losses) diff --git a/test.py b/test.py index 8db8ea150..004acc813 100755 --- a/test.py +++ b/test.py @@ -2937,6 +2937,7 @@ def test_score(self): def test_wdl_model(self): self.assertEqual(chess.engine.Cp(131).wdl(model="sf12", ply=25), chess.engine.Wdl(524, 467, 9)) 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)) @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_forced_mates(self): From d20c56feb85330d1fb8c11e39ea8c58781c95cad Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 18 Apr 2022 12:42:38 +0200 Subject: [PATCH 1509/1831] Reject pawn capture SAN if file not specified (fixes #870) --- chess/__init__.py | 4 ++++ test.py | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index da7ff8cbc..3a6a5ebf9 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3004,6 +3004,10 @@ def parse_san(self, san: str) -> Move: else: from_mask &= self.pawns + # Do not allow pawn captures if file is not specified. + if not match.group(2): + to_mask &= ~self.occupied + # Match legal moves. matched_move = None for move in self.generate_legal_moves(from_mask, to_mask): diff --git a/test.py b/test.py index 004acc813..19b41cc01 100755 --- a/test.py +++ b/test.py @@ -717,15 +717,17 @@ def test_lan(self): self.assertEqual(board.fen(), fen) def test_san_newline(self): - fen = "rnbqk2r/ppppppbp/5np1/8/8/5NP1/PPPPPPBP/RNBQK2R w KQkq - 2 4" - board = chess.Board(fen) - + board = chess.Board("rnbqk2r/ppppppbp/5np1/8/8/5NP1/PPPPPPBP/RNBQK2R w KQkq - 2 4") with self.assertRaises(ValueError): board.parse_san("O-O\n") - with self.assertRaises(ValueError): board.parse_san("Nc3\n") + def test_pawn_capture_san_without_file(self): + board = chess.Board("2rq1rk1/pb2bppp/1p2p3/n1ppPn2/2PP4/PP3N2/1B1NQPPP/RB3RK1 b - - 4 13") + with self.assertRaises(ValueError): + board.parse_san("c4") + def test_variation_san(self): board = chess.Board() self.assertEqual('1. e4 e5 2. Nf3', From 46b1b0a6a1a7feda89775fc861a9b15fb5581740 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 18 Apr 2022 16:55:10 +0200 Subject: [PATCH 1510/1831] Also require SAN file for ep captures (#870) --- chess/__init__.py | 2 +- test.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 3a6a5ebf9..9f3d77724 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3006,7 +3006,7 @@ def parse_san(self, san: str) -> Move: # Do not allow pawn captures if file is not specified. if not match.group(2): - to_mask &= ~self.occupied + from_mask &= BB_FILES[square_file(to_square)] # Match legal moves. matched_move = None diff --git a/test.py b/test.py index 19b41cc01..b425f9c1d 100755 --- a/test.py +++ b/test.py @@ -727,6 +727,9 @@ def test_pawn_capture_san_without_file(self): board = chess.Board("2rq1rk1/pb2bppp/1p2p3/n1ppPn2/2PP4/PP3N2/1B1NQPPP/RB3RK1 b - - 4 13") with self.assertRaises(ValueError): board.parse_san("c4") + board = chess.Board("4k3/8/8/4Pp2/8/8/8/4K3 w - f6 0 2") + with self.assertRaises(ValueError): + board.parse_san("f6") def test_variation_san(self): board = chess.Board() From 88ac4b1787010bb48ccce1b6572de09e86fbf12a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 18 Apr 2022 20:14:27 +0200 Subject: [PATCH 1511/1831] Add Crazyhouse perft involving promoted pieces --- examples/perft/crazyhouse.perft | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/perft/crazyhouse.perft b/examples/perft/crazyhouse.perft index e693ff5df..90c110092 100644 --- a/examples/perft/crazyhouse.perft +++ b/examples/perft/crazyhouse.perft @@ -16,3 +16,10 @@ perft 1 42 perft 2 1347 perft 3 58057 perft 4 2083382 + +id zh-promoted +epd 1Q~6/4k3/8/8/8/8/Kpp5/8[] w - - +perft 1 23 +perft 2 210 +perft 3 4909 +perft 4 55679 From 489b49d45ebd56a93ad42a3415bbffde2e79533c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 18 Apr 2022 20:19:09 +0200 Subject: [PATCH 1512/1831] Make recently added Crazyhouse perft more interesting --- examples/perft/crazyhouse.perft | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/perft/crazyhouse.perft b/examples/perft/crazyhouse.perft index 90c110092..cff0ba34a 100644 --- a/examples/perft/crazyhouse.perft +++ b/examples/perft/crazyhouse.perft @@ -18,8 +18,8 @@ perft 3 58057 perft 4 2083382 id zh-promoted -epd 1Q~6/4k3/8/8/8/8/Kpp5/8[] w - - -perft 1 23 -perft 2 210 -perft 3 4909 -perft 4 55679 +epd 4k3/1Q~6/8/8/4b3/8/Kpp5/8/ b - - 0 1 +perft 1 20 +perft 2 360 +perft 3 5445 +perft 4 132758 From 8acbcc89438289d2a17967a2ca3dd1350db9b68e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 22 Apr 2022 18:50:20 +0200 Subject: [PATCH 1513/1831] Optimize writing to engine stdin --- chess/engine.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 7a01f6b1e..fce9221b1 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -936,13 +936,13 @@ def write(self, data: bytes) -> None: if line.startswith("ping ") and self.expected_pings: self.expected_pings -= 1 - self.protocol.pipe_data_received(1, line.replace("ping ", "pong ").encode("utf-8") + b"\n") + self.protocol.pipe_data_received(1, (line.replace("ping ", "pong ") + "\n").encode("utf-8")) else: assert self.expectations, f"unexpected: {line!r}" expectation, responses = self.expectations.popleft() assert expectation == line, f"expected {expectation}, got: {line}" if responses: - self.protocol.pipe_data_received(1, "\n".join(responses).encode("utf-8") + b"\n") + self.protocol.pipe_data_received(1, "\n".join(responses + [""]).encode("utf-8")) def get_pid(self) -> int: return id(self) @@ -1010,8 +1010,7 @@ def send_line(self, line: str) -> None: assert self.transport is not None, "cannot send line before connection is made" stdin = self.transport.get_pipe_transport(0) # WriteTransport expected, but not checked to allow duck typing. - stdin.write(line.encode("utf-8")) # type: ignore - stdin.write(b"\n") # type: ignore + stdin.write((line + "\n").encode("utf-8")) # type: ignore def pipe_data_received(self, fd: int, data: Union[bytes, str]) -> None: self.buffer[fd].extend(data) # type: ignore From b9f5b86c36a1c6542c5df3441b80de678ebc4732 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 30 Apr 2022 23:40:16 +0200 Subject: [PATCH 1514/1831] Latest mypy requires fewer ignores --- chess/engine.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index fce9221b1..b23b45f50 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -119,8 +119,8 @@ def _init_watcher(self) -> asyncio.AbstractChildWatcher: raise NotImplementedError try: - os.close(os.pidfd_open(os.getpid())) # type: ignore - watcher: asyncio.AbstractChildWatcher = asyncio.PidfdChildWatcher() # type: ignore + os.close(os.pidfd_open(os.getpid())) + watcher: asyncio.AbstractChildWatcher = asyncio.PidfdChildWatcher() LOGGER.debug("Using PidfdChildWatcher") return watcher except (AttributeError, OSError): @@ -1222,7 +1222,7 @@ async def popen(cls: Type[ProtocolT], command: Union[str, List[str]], *, setpgrp # Unix. popen_args["start_new_session"] = True - return await asyncio.get_running_loop().subprocess_exec(cls, *command, **popen_args) # type: ignore + return await asyncio.get_running_loop().subprocess_exec(cls, *command, **popen_args) class CommandState(enum.Enum): From 2f72a7a1a94fb4615d90361d586fa555e10aff98 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 30 Apr 2022 23:47:20 +0200 Subject: [PATCH 1515/1831] Do not run mypy on 3.8 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 73b5ea44b..5e8683bdf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,7 +38,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.9", "3.10"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From 8ebc88116339815b3a755cba13011057065239fb Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 21 May 2022 09:24:59 +0200 Subject: [PATCH 1516/1831] No need to separate PGN annotations after \n --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 7b5994cde..ccc560b46 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -512,7 +512,7 @@ def set_clock(self, seconds: Optional[float]) -> None: self.comment, found = CLOCK_REGEX.subn(clk, self.comment, count=1) if not found and clk: - if self.comment and not self.comment.endswith(" "): + if self.comment and not self.comment.endswith(" ") and not self.comment.endswith("\n"): self.comment += " " self.comment += clk @@ -546,7 +546,7 @@ def set_emt(self, seconds: Optional[float]) -> None: self.comment, found = EMT_REGEX.subn(emt, self.comment, count=1) if not found and emt: - if self.comment and not self.comment.endswith(" "): + if self.comment and not self.comment.endswith(" ") and not self.comment.endswith("\n"): self.comment += " " self.comment += emt From 89c12618464676e8961838fc5d47e7912bf2ef21 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 21 May 2022 09:32:41 +0200 Subject: [PATCH 1517/1831] Use named groups for PGN annotation regexes --- chess/pgn.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index ccc560b46..7cb43d1cc 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -120,20 +120,20 @@ SKIP_MOVETEXT_REGEX = re.compile(r""";|\{|\}""") -CLOCK_REGEX = re.compile(r"""\[%clk\s(\d+):(\d+):(\d+(?:\.\d*)?)\]""") -EMT_REGEX = re.compile(r"""\[%emt\s(\d+):(\d+):(\d+(?:\.\d*)?)\]""") +CLOCK_REGEX = re.compile(r"""\[%clk\s(?P\d+):(?P\d+):(?P\d+(?:\.\d*)?)\]""") +EMT_REGEX = re.compile(r"""\[%emt\s(?P\d+):(?P\d+):(?P\d+(?:\.\d*)?)\]""") EVAL_REGEX = re.compile(r""" \[%eval\s(?: - \#([+-]?\d+) - |([+-]?(?:\d{0,10}\.\d{1,2}|\d{1,10}\.?)) + \#(?P[+-]?\d+) + |(?P[+-]?(?:\d{0,10}\.\d{1,2}|\d{1,10}\.?)) )(?: - ,(\d+) + ,(?P\d+) )?\] """, re.VERBOSE) ARROWS_REGEX = re.compile(r""" - \[%(?:csl|cal)\s( + \[%(?:csl|cal)\s(?P [RGYB][a-h][1-8](?:[a-h][1-8])? (?:,[RGYB][a-h][1-8](?:[a-h][1-8])?)* )\] @@ -399,8 +399,8 @@ def eval(self) -> Optional[chess.engine.PovScore]: turn = self.turn() - if match.group(1): - mate = int(match.group(1)) + if match.group("mate"): + mate = int(match.group("mate")) score: chess.engine.Score = chess.engine.Mate(mate) if mate == 0: # Resolve this ambiguity in the specification in favor of @@ -408,7 +408,7 @@ def eval(self) -> Optional[chess.engine.PovScore]: # who has been mated. return chess.engine.PovScore(score, turn) else: - score = chess.engine.Cp(int(float(match.group(2)) * 100)) + score = chess.engine.Cp(int(float(match.group("cp")) * 100)) return chess.engine.PovScore(score if turn else -score, turn) @@ -418,7 +418,7 @@ def eval_depth(self) -> Optional[int]: this node and returns the corresponding depth, if any. """ match = EVAL_REGEX.search(self.comment) - return int(match.group(3)) if match and match.group(3) else None + return int(match.group("depth")) if match and match.group("depth") else None def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] = None) -> None: """ @@ -450,7 +450,7 @@ def arrows(self) -> List[chess.svg.Arrow]: """ arrows = [] for match in ARROWS_REGEX.finditer(self.comment): - for group in match.group(1).split(","): + for group in match.group("arrows").split(","): arrows.append(chess.svg.Arrow.from_pgn(group)) return arrows @@ -493,7 +493,7 @@ def clock(self) -> Optional[float]: match = CLOCK_REGEX.search(self.comment) if match is None: return None - return int(match.group(1)) * 3600 + int(match.group(2)) * 60 + float(match.group(3)) + return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) def set_clock(self, seconds: Optional[float]) -> None: """ @@ -527,7 +527,7 @@ def emt(self) -> Optional[float]: match = EMT_REGEX.search(self.comment) if match is None: return None - return int(match.group(1)) * 3600 + int(match.group(2)) * 60 + float(match.group(3)) + return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) def set_emt(self, seconds: Optional[float]) -> None: """ From 1e7fcae546a51e4a03b280d3eab7ee1122a41e27 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 21 May 2022 11:39:26 +0200 Subject: [PATCH 1518/1831] Avoid extra space when removing PGN annotations --- chess/pgn.py | 30 ++++++++++++++++++++++-------- test.py | 6 +++++- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 7cb43d1cc..65c008d65 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -120,25 +120,37 @@ SKIP_MOVETEXT_REGEX = re.compile(r""";|\{|\}""") -CLOCK_REGEX = re.compile(r"""\[%clk\s(?P\d+):(?P\d+):(?P\d+(?:\.\d*)?)\]""") -EMT_REGEX = re.compile(r"""\[%emt\s(?P\d+):(?P\d+):(?P\d+(?:\.\d*)?)\]""") +CLOCK_REGEX = re.compile(r"""(?P\s?)\[%clk\s(?P\d+):(?P\d+):(?P\d+(?:\.\d*)?)\](?P\s?)""") +EMT_REGEX = re.compile(r"""(?P\s?)\[%emt\s(?P\d+):(?P\d+):(?P\d+(?:\.\d*)?)\](?P\s?)""") EVAL_REGEX = re.compile(r""" + (?P\s?) \[%eval\s(?: \#(?P[+-]?\d+) |(?P[+-]?(?:\d{0,10}\.\d{1,2}|\d{1,10}\.?)) )(?: ,(?P\d+) )?\] + (?P\s?) """, re.VERBOSE) ARROWS_REGEX = re.compile(r""" + (?P\s?) \[%(?:csl|cal)\s(?P [RGYB][a-h][1-8](?:[a-h][1-8])? (?:,[RGYB][a-h][1-8](?:[a-h][1-8])?)* )\] + (?P\s?) """, re.VERBOSE) +def _condense_affix(infix: str): + def repl(match): + if infix: + return match.group("prefix") + infix + match.group("suffix") + else: + return match.group("prefix") and match.group("suffix") + return repl + TAG_ROSTER = ["Event", "Site", "Date", "Round", "White", "Black", "Result"] @@ -434,7 +446,7 @@ def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] elif score.white().mate(): eval = f"[%eval #{score.white().mate()}{depth_suffix}]" - self.comment, found = EVAL_REGEX.subn(eval, self.comment, count=1) + self.comment, found = EVAL_REGEX.subn(_condense_affix(eval), self.comment, count=1) if not found and eval: if self.comment and not self.comment.endswith(" "): @@ -471,7 +483,7 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar pass (csl if arrow.tail == arrow.head else cal).append(arrow.pgn()) # type: ignore - self.comment = ARROWS_REGEX.sub("", self.comment).strip() + self.comment = ARROWS_REGEX.sub(_condense_affix(""), self.comment) prefix = "" if csl: @@ -479,8 +491,10 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar if cal: prefix += f"[%cal {','.join(cal)}]" - if prefix: - self.comment = prefix + " " + self.comment if self.comment else prefix + if prefix and self.comment and not self.comment.startswith(" ") and not self.comment.startswith("\n"): + self.comment = prefix + " " + self.comment + else: + self.comment = prefix + self.comment def clock(self) -> Optional[float]: """ @@ -509,7 +523,7 @@ def set_clock(self, seconds: Optional[float]) -> None: seconds_part = f"{seconds:06.3f}".rstrip("0").rstrip(".") clk = f"[%clk {hours:d}:{minutes:02d}:{seconds_part}]" - self.comment, found = CLOCK_REGEX.subn(clk, self.comment, count=1) + self.comment, found = CLOCK_REGEX.subn(_condense_affix(clk), self.comment, count=1) if not found and clk: if self.comment and not self.comment.endswith(" ") and not self.comment.endswith("\n"): @@ -543,7 +557,7 @@ def set_emt(self, seconds: Optional[float]) -> None: seconds_part = f"{seconds:06.3f}".rstrip("0").rstrip(".") emt = f"[%emt {hours:d}:{minutes:02d}:{seconds_part}]" - self.comment, found = EMT_REGEX.subn(emt, self.comment, count=1) + self.comment, found = EMT_REGEX.subn(_condense_affix(emt), self.comment, count=1) if not found and emt: if self.comment and not self.comment.endswith(" ") and not self.comment.endswith("\n"): diff --git a/test.py b/test.py index b425f9c1d..e4b3d3bf8 100755 --- a/test.py +++ b/test.py @@ -2774,9 +2774,13 @@ def test_annotations(self): self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5] [%emt 0:05:21]") self.assertEqual(game.emt(), emt) + game.set_eval(None) + self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%emt 0:05:21]") + game.set_emt(None) + self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45]") + game.set_clock(None) - game.set_eval(None) game.set_arrows([]) self.assertEqual(game.comment, "foo [%bar] baz") From 3663272b88e4b23f0c48e273741b7c1fac6b31f2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 21 May 2022 11:57:57 +0200 Subject: [PATCH 1519/1831] Add type annotations for _condense_affix() --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 65c008d65..85002140a 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -143,8 +143,8 @@ (?P\s?) """, re.VERBOSE) -def _condense_affix(infix: str): - def repl(match): +def _condense_affix(infix: str) -> Callable[[typing.Match[str]], str]: + def repl(match: typing.Match[str]) -> str: if infix: return match.group("prefix") + infix + match.group("suffix") else: From 56b2410513ff6e64305ef5caed7eda68826145ed Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 21 May 2022 11:54:48 +0200 Subject: [PATCH 1520/1831] Prepare 1.9.1 --- CHANGELOG.rst | 20 ++++++++++++++++++++ chess/__init__.py | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1575e713b..f9910db9c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,26 @@ Changelog for python-chess ========================== +New in v1.9.1 +------------- + +Bugfixes: + +* Reject pawn capture SAN if the original file is not specified, e.g., + ``d5`` will no longer match ``cxd5``. + +Changes: + +* Tweak handling of whitespace in PGN comments: When parsing, any leading + and trailing whitespace (beyond one space) is preserved. When joining + multiple PGN comments, they are now separated with a space instead of a + newline character. When removing annotations from comments, leftover + whitespace is avoided. + +New features: + +* Add model ``sf15`` for ``chess.engine.Score.wdl()``. + New in v1.9.0 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index 9f3d77724..7799bfe59 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.9.0" +__version__ = "1.9.1" import collections import copy From 26015e9990fee57d9d9c3315dfccb61b261a90b7 Mon Sep 17 00:00:00 2001 From: Neil Stoker Date: Wed, 8 Jun 2022 05:58:39 +0100 Subject: [PATCH 1521/1831] Mention Chess Match Viewer (PyScript) in README (#890) * Mention Chess Match Viewer (PyScript) in README Would it be okay to mention this PyScript demo here? Hope the formatting is suitable. * Putting back accidentally removed blank line Error indicates that a blank line is needed after the bullet list. I seem to have removed the line accidentally and the GitHub editor was more forgiving than the rst process --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index f02d0e584..7872edae3 100644 --- a/README.rst +++ b/README.rst @@ -342,6 +342,7 @@ If you like, share interesting things you are using python-chess for, for exampl * an `Alexa skill to play blindfold chess `_ – https://github.com/laynr/blindfold-chess * a chessboard widget for PySide2 – https://github.com/H-a-y-k/hichesslib * Django Rest Framework API for multiplayer chess – https://github.com/WorkShoft/capablanca-api +* a `browser based PGN viewer `_ written in PyScript – https://github.com/nmstoker/ChessMatchViewer Acknowledgements ---------------- From f9d2b0d077be956c472807561e263bab6d8977fd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 8 Jun 2022 19:14:15 +0200 Subject: [PATCH 1522/1831] Bump actions/setup-python to v4 --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5e8683bdf..656af180f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - run: .github/workflows/setup-${{ matrix.os }}.sh @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: python-version: "3.10" - run: pip install -e . @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - run: pip install -e . @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: python-version: "3.10" - run: sudo apt-get update && sudo apt-get install -y docutils-common From 34d74f94040d44f8ab89a987cad00d534cb2d196 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 8 Jun 2022 19:58:58 +0200 Subject: [PATCH 1523/1831] Document that editing board clears move stack (fixes #887) --- chess/__init__.py | 35 +++++++++++++++++++++++++---------- docs/core.rst | 1 + 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 7799bfe59..604fd31f4 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -623,7 +623,13 @@ def _reset_board(self) -> None: self.occupied = BB_RANK_1 | BB_RANK_2 | BB_RANK_7 | BB_RANK_8 def reset_board(self) -> None: - """Resets pieces to the starting position.""" + """ + Resets pieces to the starting position. + + :class:`~chess.Board` also resets the move stack, but not turn, + castling rights and move counters. Use :func:`chess.Board.reset()` to + fully restore the starting position. + """ self._reset_board() def _clear_board(self) -> None: @@ -641,7 +647,11 @@ def _clear_board(self) -> None: self.occupied = BB_EMPTY def clear_board(self) -> None: - """Clears the board.""" + """ + Clears the board. + + :class:`~chess.Board` also clears the move stack. + """ self._clear_board() def pieces_mask(self, piece_type: PieceType, color: Color) -> Bitboard: @@ -877,6 +887,8 @@ def remove_piece_at(self, square: Square) -> Optional[Piece]: """ Removes the piece from the given square. Returns the :class:`~chess.Piece` or ``None`` if the square was already empty. + + :class:`~chess.Board` also clears the move stack. """ color = bool(self.occupied_co[WHITE] & BB_SQUARES[square]) piece_type = self._remove_piece_at(square) @@ -914,6 +926,8 @@ def set_piece_at(self, square: Square, piece: Optional[Piece], promoted: bool = An existing piece is replaced. Setting *piece* to ``None`` is equivalent to :func:`~chess.Board.remove_piece_at()`. + + :class:`~chess.Board` also clears the move stack. """ if piece is None: self._remove_piece_at(square) @@ -1010,6 +1024,8 @@ def set_board_fen(self, fen: str) -> None: Parses *fen* and sets up the board, where *fen* is the board part of a FEN. + :class:`~chess.Board` also clears the move stack. + :raises: :exc:`ValueError` if syntactically invalid. """ self._set_board_fen(fen) @@ -1032,6 +1048,8 @@ def set_piece_map(self, pieces: Mapping[Square, Piece]) -> None: """ Sets up the board from a dictionary of :class:`pieces ` by square index. + + :class:`~chess.Board` also clears the move stack. """ self._set_piece_map(pieces) @@ -1283,8 +1301,8 @@ def apply_transform(self, f: Callable[[Bitboard], Bitboard]) -> None: def transform(self: BaseBoardT, f: Callable[[Bitboard], Bitboard]) -> BaseBoardT: """ - Returns a transformed copy of the board by applying a bitboard - transformation function. + Returns a transformed copy of the board (without move stack) + by applying a bitboard transformation function. Available transformations include :func:`chess.flip_vertical()`, :func:`chess.flip_horizontal()`, :func:`chess.flip_diagonal()`, @@ -1305,7 +1323,7 @@ def apply_mirror(self: BaseBoardT) -> None: def mirror(self: BaseBoardT) -> BaseBoardT: """ - Returns a mirrored copy of the board. + Returns a mirrored copy of the board (without move stack). The board is mirrored vertically and piece colors are swapped, so that the position is equivalent modulo color. @@ -1582,11 +1600,6 @@ def reset(self) -> None: self.reset_board() def reset_board(self) -> None: - """ - Resets only pieces to the starting position. Use - :func:`~chess.Board.reset()` to fully restore the starting position - (including turn, castling rights, etc.). - """ super().reset_board() self.clear_stack() @@ -2524,6 +2537,8 @@ def set_castling_fen(self, castling_fen: str) -> None: """ Sets castling rights from a string in FEN notation like ``Qqk``. + Also clears the move stack. + :raises: :exc:`ValueError` if the castling FEN is syntactically invalid. """ diff --git a/docs/core.rst b/docs/core.rst index ef7d3005a..d5790820a 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -108,6 +108,7 @@ Board .. autoclass:: chess.Board :members: + :exclude-members: set_piece_at, remove_piece_at, reset_board, set_board_fen, set_piece_map, set_chess960_pos, apply_transform .. autoclass:: chess.BaseBoard :members: From 7c44637a154ca77db9bd0cbed55822b354ffd0cc Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 8 Jun 2022 20:33:57 +0200 Subject: [PATCH 1524/1831] Add AnalysisResult.would_block() (fixes #889) --- chess/engine.py | 21 +++++++++++++++++++++ test.py | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index b23b45f50..45ff84630 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2601,6 +2601,19 @@ async def get(self) -> InfoDict: return info + def would_block(self) -> bool: + """ + Checks if calling :func:`~chess.engine.AnalysisResult.get()`, + calling :func:`~chess.engine.AnalysisResult.next()`, + calling :func:`~chess.engine.AnalysisResult.wait()`, or advancing the + iterator one step would require waiting for the engine. + + All of these functions would return immediately information is pending + (queue is not :func:`empty `) + or if the search is finished. + """ + return not self._seen_kork and self._queue.empty() + def empty(self) -> bool: """ Checks if all information has been consumed. @@ -2891,6 +2904,14 @@ def wait(self) -> BestMove: future = asyncio.run_coroutine_threadsafe(self.inner.wait(), self.simple_engine.protocol.loop) return future.result() + def would_block(self) -> bool: + async def _would_block() -> bool: + return self.inner.would_block() + + with self.simple_engine._not_shut_down(): + future = asyncio.run_coroutine_threadsafe(_would_block(), self.simple_engine.protocol.loop) + return future.result() + def empty(self) -> bool: async def _empty() -> bool: return self.inner.empty() diff --git a/test.py b/test.py index e4b3d3bf8..fdaaa6290 100755 --- a/test.py +++ b/test.py @@ -2986,7 +2986,10 @@ def test_sf_analysis(self): for info in analysis: if "score" in info and info["score"].white() >= chess.engine.Mate(+2): break + analysis.wait() + self.assertFalse(analysis.would_block()) + self.assertEqual(analysis.info["score"].relative, chess.engine.Mate(+2)) self.assertEqual(analysis.multipv[0]["score"].black(), chess.engine.Mate(-2)) @@ -2997,6 +3000,7 @@ def test_sf_analysis(self): was_really_empty = False self.assertEqual(was_really_empty, was_empty) self.assertTrue(analysis.empty()) + self.assertFalse(analysis.would_block()) for info in analysis: self.fail("all info should have been consumed") @@ -3174,8 +3178,10 @@ async def main(): mock.expect("go infinite") mock.expect("stop", ["bestmove e2e4"]) result = await protocol.analysis(chess.Board()) + self.assertTrue(result.would_block()) result.stop() best = await result.wait() + self.assertFalse(result.would_block()) self.assertEqual(best.move, chess.Move.from_uci("e2e4")) self.assertTrue(best.ponder is None) mock.assert_done() From 4fa60209f1d46f3cb6ee282cca8afcb031ba1ef9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 8 Jun 2022 20:41:22 +0200 Subject: [PATCH 1525/1831] Tweak would_block() and empty() docs --- chess/engine.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 45ff84630..efed7d89b 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2608,21 +2608,19 @@ def would_block(self) -> bool: calling :func:`~chess.engine.AnalysisResult.wait()`, or advancing the iterator one step would require waiting for the engine. - All of these functions would return immediately information is pending - (queue is not :func:`empty `) - or if the search is finished. + All of these functions would return immediately if information is + pending (queue is not + :func:`empty `) or if the search + is finished. """ return not self._seen_kork and self._queue.empty() def empty(self) -> bool: """ - Checks if all information has been consumed. + Checks if all current information has been consumed. If the queue is empty, but the analysis is still ongoing, then further information can become available in the future. - - If the queue is not empty, then the next call to - :func:`~chess.engine.AnalysisResult.get()` will return instantly. """ return self._seen_kork or self._queue.qsize() <= self._posted_kork From b93b2da69c47190d71b9628c7771c0686ab6faad Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 8 Jun 2022 23:57:28 +0200 Subject: [PATCH 1526/1831] Code golf async lambdas --- chess/engine.py | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index efed7d89b..1ea47cd0b 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2696,6 +2696,10 @@ async def popen_xboard(command: Union[str, List[str]], *, setpgrp: bool = False, return transport, protocol +async def _async(sync: Callable[[], T]) -> T: + return sync() + + class SimpleEngine: """ Synchronous wrapper around a transport and engine protocol pair. Provides @@ -2738,20 +2742,16 @@ def _not_shut_down(self) -> Generator[None, None, None]: @property def options(self) -> MutableMapping[str, Option]: - async def _get() -> MutableMapping[str, Option]: - return copy.copy(self.protocol.options) - with self._not_shut_down(): - future = asyncio.run_coroutine_threadsafe(_get(), self.protocol.loop) + coro = _async(lambda: copy.copy(self.protocol.options)) + future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() @property def id(self) -> Mapping[str, str]: - async def _get() -> Mapping[str, str]: - return self.protocol.id.copy() - with self._not_shut_down(): - future = asyncio.run_coroutine_threadsafe(_get(), self.protocol.loop) + coro = _async(lambda: self.protocol.id.copy()) + future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() def communicate(self, command_factory: Callable[[Protocol], BaseCommand[Protocol, T]]) -> T: @@ -2877,20 +2877,16 @@ def __init__(self, simple_engine: SimpleEngine, inner: AnalysisResult) -> None: @property def info(self) -> InfoDict: - async def _get() -> InfoDict: - return self.inner.info.copy() - with self.simple_engine._not_shut_down(): - future = asyncio.run_coroutine_threadsafe(_get(), self.simple_engine.protocol.loop) + coro = _async(lambda: self.inner.info.copy()) + future = asyncio.run_coroutine_threadsafe(coro, self.simple_engine.protocol.loop) return future.result() @property def multipv(self) -> List[InfoDict]: - async def _get() -> List[InfoDict]: - return [info.copy() for info in self.inner.multipv] - with self.simple_engine._not_shut_down(): - future = asyncio.run_coroutine_threadsafe(_get(), self.simple_engine.protocol.loop) + coro = _async(lambda: [info.copy() for info in self.inner.multipv]) + future = asyncio.run_coroutine_threadsafe(coro, self.simple_engine.protocol.loop) return future.result() def stop(self) -> None: @@ -2903,19 +2899,13 @@ def wait(self) -> BestMove: return future.result() def would_block(self) -> bool: - async def _would_block() -> bool: - return self.inner.would_block() - with self.simple_engine._not_shut_down(): - future = asyncio.run_coroutine_threadsafe(_would_block(), self.simple_engine.protocol.loop) + future = asyncio.run_coroutine_threadsafe(_async(self.inner.would_block), self.simple_engine.protocol.loop) return future.result() def empty(self) -> bool: - async def _empty() -> bool: - return self.inner.empty() - with self.simple_engine._not_shut_down(): - future = asyncio.run_coroutine_threadsafe(_empty(), self.simple_engine.protocol.loop) + future = asyncio.run_coroutine_threadsafe(_async(self.inner.empty), self.simple_engine.protocol.loop) return future.result() def get(self) -> InfoDict: From d9cee54ef6c66a27a5b2d27ebff01d9da43a328e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 9 Jun 2022 17:35:44 +0200 Subject: [PATCH 1527/1831] Fix would_block() docs (#889) --- chess/engine.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 1ea47cd0b..066221b98 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2574,7 +2574,7 @@ def stop(self) -> None: self._stop = None async def wait(self) -> BestMove: - """Waits until the analysis is complete (or stopped).""" + """Waits until the analysis is finished.""" return await self._finished async def get(self) -> InfoDict: @@ -2605,10 +2605,10 @@ def would_block(self) -> bool: """ Checks if calling :func:`~chess.engine.AnalysisResult.get()`, calling :func:`~chess.engine.AnalysisResult.next()`, - calling :func:`~chess.engine.AnalysisResult.wait()`, or advancing the - iterator one step would require waiting for the engine. + or advancing the iterator one step would require waiting for the + engine. - All of these functions would return immediately if information is + These functions would return immediately if information is pending (queue is not :func:`empty `) or if the search is finished. From 4376eb7d6eaf2bd217f56564073ed05469e49a73 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Jun 2022 16:57:30 +0200 Subject: [PATCH 1528/1831] Fix recursive Crazyhouse move generation (fixes #893) --- chess/variant.py | 27 ++++++++++++++------------- examples/perft/crazyhouse.perft | 7 +++++++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index 9e586b79c..7494e20fa 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -829,31 +829,32 @@ class CrazyhousePocket: """A Crazyhouse pocket with a counter for each piece type.""" def __init__(self, symbols: Iterable[str] = "") -> None: - self.pieces: Dict[chess.PieceType, int] = {} + self.reset() for symbol in symbols: self.add(chess.PIECE_SYMBOLS.index(symbol)) + def reset(self) -> None: + """Clears the pocket.""" + self._pieces = [None, 0, 0, 0, 0, 0, 0] + def add(self, piece_type: chess.PieceType) -> None: """Adds a piece of the given type to this pocket.""" - self.pieces[piece_type] = self.pieces.get(piece_type, 0) + 1 + self._pieces[piece_type] += 1 def remove(self, piece_type: chess.PieceType) -> None: """Removes a piece of the given type from this pocket.""" - self.pieces[piece_type] -= 1 + assert self._pieces[piece_type], f"cannot remove {chess.piece_symbol(piece_type)} from {self!r}" + self._pieces[piece_type] -= 1 def count(self, piece_type: chess.PieceType) -> int: """Returns the number of pieces of the given type in the pocket.""" - return self.pieces.get(piece_type, 0) - - def reset(self) -> None: - """Clears the pocket.""" - self.pieces.clear() + return self._pieces[piece_type] def __str__(self) -> str: return "".join(chess.piece_symbol(pt) * self.count(pt) for pt in reversed(chess.PIECE_TYPES)) def __len__(self) -> int: - return sum(self.pieces.values()) + return sum(self._pieces[1:]) def __repr__(self) -> str: return f"CrazyhousePocket('{self}')" @@ -861,7 +862,7 @@ def __repr__(self) -> str: def copy(self: CrazyhousePocketT) -> CrazyhousePocketT: """Returns a copy of this pocket.""" pocket = type(self)() - pocket.pieces = copy.copy(self.pieces) + pocket._pieces = self._pieces[:] return pocket class CrazyhouseBoard(chess.Board): @@ -959,9 +960,9 @@ def is_legal(self, move: chess.Move) -> bool: return super().is_legal(move) def generate_pseudo_legal_drops(self, to_mask: chess.Bitboard = chess.BB_ALL) -> Iterator[chess.Move]: - for to_square in chess.scan_forward(to_mask & ~self.occupied): - for pt, count in self.pockets[self.turn].pieces.items(): - if count and (pt != chess.PAWN or not chess.BB_BACKRANKS & chess.BB_SQUARES[to_square]): + for pt in chess.PIECE_TYPES: + if self.pockets[self.turn].count(pt): + for to_square in chess.scan_forward(to_mask & ~self.occupied & (~chess.BB_BACKRANKS if pt == chess.PAWN else chess.BB_ALL)): yield chess.Move(to_square, to_square, drop=pt) def generate_legal_drops(self, to_mask: chess.Bitboard = chess.BB_ALL) -> Iterator[chess.Move]: diff --git a/examples/perft/crazyhouse.perft b/examples/perft/crazyhouse.perft index cff0ba34a..42ccd68a6 100644 --- a/examples/perft/crazyhouse.perft +++ b/examples/perft/crazyhouse.perft @@ -23,3 +23,10 @@ perft 1 20 perft 2 360 perft 3 5445 perft 4 132758 + +id zh-midgame +epd 2rn1b1r/1pp2n1p/B1PBk1pP/5p1P/P5p1/2P2RP1/RP1QNP2/1NBK4[QPp] w - - +perft 1 99 +perft 2 3932 +perft 3 314782 +perft 4 10118606 From 0d90b5beb01b0ba2f5e9810fb4affa1d9fa6ae23 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Jun 2022 17:10:31 +0200 Subject: [PATCH 1529/1831] Use -1 instead of None as invalid pocket._pieces --- chess/variant.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/variant.py b/chess/variant.py index 7494e20fa..1384af166 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -835,7 +835,7 @@ def __init__(self, symbols: Iterable[str] = "") -> None: def reset(self) -> None: """Clears the pocket.""" - self._pieces = [None, 0, 0, 0, 0, 0, 0] + self._pieces = [-1, 0, 0, 0, 0, 0, 0] def add(self, piece_type: chess.PieceType) -> None: """Adds a piece of the given type to this pocket.""" From 614d718be06d0b9ff471e70e66cd54c2cc6f5dfb Mon Sep 17 00:00:00 2001 From: John Hammond Date: Wed, 15 Jun 2022 22:33:03 -0500 Subject: [PATCH 1530/1831] Fill the black pawn with black color This addresses #896 when rendering the board on a dark background. --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index 5a9cccc0a..9474550fe 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -36,7 +36,7 @@ "b": """""", # noqa: E501 "k": """""", # noqa: E501 "n": """""", # noqa: E501 - "p": """""", # noqa: E501 + "p": """""", # noqa: E501 "q": """""", # noqa: E501 "r": """""", # noqa: E501 "B": """""", # noqa: E501 From 3c902fde7a4744b285d933eb6116ec78a87871eb Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 17 Jun 2022 15:26:40 +0200 Subject: [PATCH 1531/1831] Prepare 1.9.2 --- CHANGELOG.rst | 13 +++++++++++++ chess/__init__.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f9910db9c..36564f56c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,19 @@ Changelog for python-chess ========================== +New in v1.9.2 +------------- + +Bugfixes: + +* Fix recursive Crazyhouse move generation sometimes failing with + with ``RuntimeError``. +* Fix rendering of black pawn SVG on dark background. + +New features: + +* Add ``chess.engine.AnalysisResult.would_block()``. + New in v1.9.1 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index 604fd31f4..6cddf13d8 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.9.1" +__version__ = "1.9.2" import collections import copy From e88f28ab9f2be7e08a6cbf6ba2bc3858f867d4a8 Mon Sep 17 00:00:00 2001 From: laniakea64 Date: Wed, 22 Jun 2022 16:07:44 -0400 Subject: [PATCH 1532/1831] pgn: Support all valid symbol continuation characters in tag names --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 85002140a..4ede56b60 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -93,9 +93,9 @@ NAG_NOVELTY = 146 -TAG_REGEX = re.compile(r"^\[([A-Za-z0-9_]+)\s+\"([^\r]*)\"\]\s*$") +TAG_REGEX = re.compile(r"^\[([A-Za-z0-9_+#=:-]+)\s+\"([^\r]*)\"\]\s*$") -TAG_NAME_REGEX = re.compile(r"^[A-Za-z0-9_]+\Z") +TAG_NAME_REGEX = re.compile(r"^[A-Za-z0-9_+#=:-]+\Z") MOVETEXT_REGEX = re.compile(r""" ( From cd6bbb1bbe9c8d6b7e8ec7765f89c47872f210e8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 23 Jun 2022 22:33:42 +0200 Subject: [PATCH 1533/1831] Test special characters in PGN tag names --- chess/pgn.py | 2 +- test.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 4ede56b60..130526ed2 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -934,7 +934,7 @@ def __setitem__(self, key: str, value: str) -> None: if key in TAG_ROSTER: self._tag_roster[key] = value elif not TAG_NAME_REGEX.match(key): - raise ValueError(f"non-alphanumeric pgn header tag: {key!r}") + raise ValueError(f"invalid pgn header tag: {key!r}") elif "\n" in value or "\r" in value: raise ValueError(f"line break in pgn header {key}: {value!r}") else: diff --git a/test.py b/test.py index fdaaa6290..7e5bacfa1 100755 --- a/test.py +++ b/test.py @@ -2252,6 +2252,16 @@ def test_header_with_paren(self): self.assertEqual(game.headers["Opening"], "St. George (Baker) defense") self.assertEqual(game.end().board(), chess.Board("8/2p2k2/1pR3p1/1P1P4/p1P2P2/P4K2/8/5r2 w - - 7 78")) + def test_special_tag_names(self): + pgn = io.StringIO("""[BlackType: "program"]""") + game = chess.pgn.read_game(pgn) + self.assertEqual(game.headers["BlackType:"], "program") + + with self.assertRaises(ValueError): + game.headers["~"] = "foo" + + game.headers["Equals="] = "bar" + def test_chess960_without_fen(self): pgn = io.StringIO(textwrap.dedent("""\ [Variant "Chess960"] From 43dc84ad41b78997a6873e9855d2d4fb57d67735 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 24 Jun 2022 20:43:29 +0200 Subject: [PATCH 1534/1831] =?UTF-8?q?Tweak=20wording=20of=20feature=20nps?= =?UTF-8?q?=3D=3F=20warning?= --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 066221b98..5194247f6 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2135,7 +2135,7 @@ def start(self, engine: XBoardProtocol) -> None: raise EngineError("xboard does not support mixing node limits with time limits") if "nps" not in engine.features: - LOGGER.warning("%s: Engine did not declare explicit support for node limits (feature nps=?)") + LOGGER.warning("%s: Engine did not explicitly declare support for node limits (feature nps=?)") elif not engine.features["nps"]: raise EngineError("xboard engine does not support node limits (feature nps=0)") From 77794ce08d7c59a663bf19b7e41c69be9ac3a965 Mon Sep 17 00:00:00 2001 From: laniakea64 Date: Thu, 7 Jul 2022 16:12:07 -0400 Subject: [PATCH 1535/1831] pgn: Improve validation of symbol tokens for tag names --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 130526ed2..ec0cbf1fd 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -93,9 +93,9 @@ NAG_NOVELTY = 146 -TAG_REGEX = re.compile(r"^\[([A-Za-z0-9_+#=:-]+)\s+\"([^\r]*)\"\]\s*$") +TAG_REGEX = re.compile(r"^\[([A-Za-z0-9][A-Za-z0-9_+#=:-]{,254})\s+\"([^\r]*)\"\]\s*$") -TAG_NAME_REGEX = re.compile(r"^[A-Za-z0-9_+#=:-]+\Z") +TAG_NAME_REGEX = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_+#=:-]{,254}\Z") MOVETEXT_REGEX = re.compile(r""" ( From 865e4674a510d2e066c683044d09962f032f8512 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Jul 2022 12:12:21 +0200 Subject: [PATCH 1536/1831] Disregard specified maximum PGN tag length --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index ec0cbf1fd..adecce1c7 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -93,9 +93,9 @@ NAG_NOVELTY = 146 -TAG_REGEX = re.compile(r"^\[([A-Za-z0-9][A-Za-z0-9_+#=:-]{,254})\s+\"([^\r]*)\"\]\s*$") +TAG_REGEX = re.compile(r"^\[([A-Za-z0-9][A-Za-z0-9_+#=:-]*)\s+\"([^\r]*)\"\]\s*$") -TAG_NAME_REGEX = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_+#=:-]{,254}\Z") +TAG_NAME_REGEX = re.compile(r"^[A-Za-z0-9][A-Za-z0-9_+#=:-]*\Z") MOVETEXT_REGEX = re.compile(r""" ( From 835c520cda91337efbfad55b74c41adcdfa21645 Mon Sep 17 00:00:00 2001 From: laniakea64 Date: Sat, 9 Jul 2022 16:51:16 -0400 Subject: [PATCH 1537/1831] pgn: Skip over invalid or malformed headers --- chess/pgn.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index adecce1c7..2257b8285 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1538,7 +1538,9 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: if unmanaged_headers is not None: unmanaged_headers[tag_match.group(1)] = tag_match.group(2) else: - break + # Ignore invalid or malformed headers. + line = handle.readline() + continue line = handle.readline() From ec50de5566d73704869fcf2e8f1c4e3a7e0e770e Mon Sep 17 00:00:00 2001 From: DonLarry Date: Wed, 20 Jul 2022 20:19:27 -0400 Subject: [PATCH 1538/1831] Adding flipped option to unicode representation --- chess/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 6cddf13d8..2f00a38b8 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1221,7 +1221,7 @@ def __str__(self) -> str: return "".join(builder) - def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_square: str = "⭘") -> str: + def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_square: str = "⭘", flipped:bool = False) -> str: """ Returns a string representation of the board with Unicode pieces. Useful for pretty-printing to a terminal. @@ -1229,6 +1229,11 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq :param invert_color: Invert color of the Unicode pieces. :param borders: Show borders and a coordinate margin. """ + board = self.copy() + if flipped: + board.apply_transform(flip_vertical) + board.apply_transform(flip_horizontal) + builder = [] for rank_index in range(7, -1, -1): if borders: @@ -1247,7 +1252,7 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq elif file_index > 0: builder.append(" ") - piece = self.piece_at(square_index) + piece = board.piece_at(square_index) if piece: builder.append(piece.unicode_symbol(invert_color=invert_color)) From aa0a04f37da9339b7d3a983aecbe9c97935fc0d3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 22 Jul 2022 11:09:43 +0200 Subject: [PATCH 1539/1831] Implement Antichess insufficient material with knights --- chess/variant.py | 27 ++++++++++++++++++--------- test.py | 5 +++++ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/chess/variant.py b/chess/variant.py index 1384af166..3fec62c3c 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -85,16 +85,25 @@ def is_variant_draw(self) -> bool: return self.is_stalemate() and self._material_balance() == 0 def has_insufficient_material(self, color: chess.Color) -> bool: - if self.occupied != self.bishops: + if not self.occupied_co[color]: + return False + elif not self.occupied_co[not color]: + return True + elif self.occupied == self.bishops: + # In a position with only bishops, check if all our bishops can be + # captured. + we_some_on_light = bool(self.occupied_co[color] & chess.BB_LIGHT_SQUARES) + we_some_on_dark = bool(self.occupied_co[color] & chess.BB_DARK_SQUARES) + they_all_on_dark = not (self.occupied_co[not color] & chess.BB_LIGHT_SQUARES) + they_all_on_light = not (self.occupied_co[not color] & chess.BB_DARK_SQUARES) + return (we_some_on_light and they_all_on_dark) or (we_some_on_dark and they_all_on_light) + elif self.occupied == self.knights and chess.popcount(self.knights) == 2: + return ( + self.turn == color ^ + bool(self.occupied_co[chess.WHITE] & chess.BB_LIGHT_SQUARES) ^ + bool(self.occupied_co[chess.BLACK] & chess.BB_DARK_SQUARES)) + else: return False - - # In a position with only bishops, check if all our bishops can be - # captured. - we_some_on_light = bool(self.occupied_co[color] & chess.BB_LIGHT_SQUARES) - we_some_on_dark = bool(self.occupied_co[color] & chess.BB_DARK_SQUARES) - they_all_on_dark = not (self.occupied_co[not color] & chess.BB_LIGHT_SQUARES) - they_all_on_light = not (self.occupied_co[not color] & chess.BB_DARK_SQUARES) - return (we_some_on_light and they_all_on_dark) or (we_some_on_dark and they_all_on_light) def generate_pseudo_legal_moves(self, from_mask: chess.Bitboard = chess.BB_ALL, to_mask: chess.Bitboard = chess.BB_ALL) -> Iterator[chess.Move]: for move in super().generate_pseudo_legal_moves(from_mask, to_mask): diff --git a/test.py b/test.py index 7e5bacfa1..9e9a4c1d5 100755 --- a/test.py +++ b/test.py @@ -561,6 +561,11 @@ def _check(board, white, black): _check(chess.variant.GiveawayBoard("8/8/8/6b1/8/3B4/4B3/5B2 w - - 0 1"), True, True) _check(chess.variant.GiveawayBoard("8/8/5b2/8/8/3B4/3B4/8 w - - 0 1"), True, False) _check(chess.variant.SuicideBoard("8/5p2/5P2/8/3B4/1bB5/8/8 b - - 0 1"), false_negative, false_negative) + _check(chess.variant.AntichessBoard("8/8/8/1n2N3/8/8/8/8 w - - 0 32"), True, False) + _check(chess.variant.AntichessBoard("8/3N4/8/1n6/8/8/8/8 b - - 1 32"), True, False) + _check(chess.variant.AntichessBoard("6n1/8/8/4N3/8/8/8/8 b - - 0 27"), False, True) + _check(chess.variant.AntichessBoard("8/8/5n2/4N3/8/8/8/8 w - - 1 28"), False, True) + _check(chess.variant.AntichessBoard("8/3n4/8/8/8/8/8/8 w - - 0 29"), False, True) _check(chess.variant.KingOfTheHillBoard("8/5k2/8/8/8/8/3K4/8 w - - 0 1"), False, False) From 5c054874619e90b8315a070aca5e46d2775cd8de Mon Sep 17 00:00:00 2001 From: DonLarry Date: Thu, 28 Jul 2022 18:59:54 -0400 Subject: [PATCH 1540/1831] Applying suggestions --- chess/__init__.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 2f00a38b8..199542491 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1221,7 +1221,7 @@ def __str__(self) -> str: return "".join(builder) - def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_square: str = "⭘", flipped:bool = False) -> str: + def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_square: str = "⭘", orientation:Color = WHITE) -> str: """ Returns a string representation of the board with Unicode pieces. Useful for pretty-printing to a terminal. @@ -1230,12 +1230,9 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq :param borders: Show borders and a coordinate margin. """ board = self.copy() - if flipped: - board.apply_transform(flip_vertical) - board.apply_transform(flip_horizontal) - builder = [] - for rank_index in range(7, -1, -1): + indexes = range(7, -1, -1) if orientation else range(8) + for rank_index in indexes: if borders: builder.append(" ") builder.append("-" * 17) @@ -1262,14 +1259,15 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq if borders: builder.append("|") - if borders or rank_index > 0: + if borders or (rank_index > 0 and orientation) or (rank_index < 7 and not orientation): builder.append("\n") if borders: builder.append(" ") builder.append("-" * 17) builder.append("\n") - builder.append(" a b c d e f g h") + letters = "a b c d e f g h" if orientation else "h g f e d c b a" + builder.append(" " + letters) return "".join(builder) From 1909f1c42b3941c89db46b41dce3a55980956246 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 29 Jul 2022 08:43:36 +0200 Subject: [PATCH 1541/1831] Code golf board.unicode() --- chess/__init__.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 199542491..6a98e2762 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1229,10 +1229,8 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq :param invert_color: Invert color of the Unicode pieces. :param borders: Show borders and a coordinate margin. """ - board = self.copy() builder = [] - indexes = range(7, -1, -1) if orientation else range(8) - for rank_index in indexes: + for rank_index in (range(7, -1, -1) if orientation else range(8)): if borders: builder.append(" ") builder.append("-" * 17) @@ -1249,7 +1247,7 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq elif file_index > 0: builder.append(" ") - piece = board.piece_at(square_index) + piece = self.piece_at(square_index) if piece: builder.append(piece.unicode_symbol(invert_color=invert_color)) @@ -1259,7 +1257,7 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq if borders: builder.append("|") - if borders or (rank_index > 0 and orientation) or (rank_index < 7 and not orientation): + if borders or (rank_index > 0 if orientation else rank_index < 7): builder.append("\n") if borders: From 3b412c53504efa4e36a75e13755244d8c3f4bd85 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 29 Jul 2022 08:43:48 +0200 Subject: [PATCH 1542/1831] Fix order of files on flipped unicode board --- chess/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 6a98e2762..b8198762b 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1239,12 +1239,12 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq builder.append(RANK_NAMES[rank_index]) builder.append(" ") - for file_index in range(8): + for i, file_index in enumerate(range(8) if orientation else range(7, -1, -1)): square_index = square(file_index, rank_index) if borders: builder.append("|") - elif file_index > 0: + elif i > 0: builder.append(" ") piece = self.piece_at(square_index) From a19cf1e5307fef1d399f2c558260363573ff817f Mon Sep 17 00:00:00 2001 From: John Doknjas <32089502+johndoknjas@users.noreply.github.com> Date: Thu, 28 Jul 2022 23:52:54 -0700 Subject: [PATCH 1543/1831] Update docs (#911) --- chess/pgn.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chess/pgn.py b/chess/pgn.py index 2257b8285..fa99be9f6 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1470,6 +1470,10 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn", encoding="utf-8") + If you get a UnicodeDecodeError, including the following parameters might help: + + >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn", 'r', errors='replace') + Use :class:`~io.StringIO` to parse games from a string. >>> import io From cff414bf33d1dc9468822995af8c9f143ac011f1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 29 Jul 2022 09:01:52 +0200 Subject: [PATCH 1544/1831] Enable intersphinx --- docs/conf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 526150026..1e00cd0d1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,8 +15,11 @@ import chess # Autodoc. -extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode"] +extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.intersphinx"] autodoc_member_order = "bysource" +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), +} # The suffix of source filenames. source_suffix = ".rst" From 2379c55bcadd6ef9f2acb2e2f7f2476094be5ec1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 29 Jul 2022 09:02:27 +0200 Subject: [PATCH 1545/1831] Link open() docs rather than recommendeing replace --- chess/pgn.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index fa99be9f6..da97866c3 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1466,14 +1466,11 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: By using text mode, the parser does not need to handle encodings. It is the caller's responsibility to open the file with the correct encoding. PGN files are usually ASCII or UTF-8 encoded, sometimes with BOM (which - this parser automatically ignores). + this parser automatically ignores). See :func:`open` for options to + deal with encoding errors. >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn", encoding="utf-8") - If you get a UnicodeDecodeError, including the following parameters might help: - - >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn", 'r', errors='replace') - Use :class:`~io.StringIO` to parse games from a string. >>> import io From 9f41b049b0266167d2b38c469cc83993f3d5e431 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 25 Apr 2022 14:47:49 +0200 Subject: [PATCH 1546/1831] Move required Python to installation section --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 7872edae3..3fb94920e 100644 --- a/README.rst +++ b/README.rst @@ -59,7 +59,7 @@ python-chess: Installing ---------- -Download and install the latest release: +Requires Python 3.7+. Download and install the latest release: :: @@ -81,7 +81,7 @@ Download and install the latest release: Features -------- -* Supports Python 3.7+. Includes mypy typings. +* Includes mypy typings. * IPython/Jupyter Notebook integration. `SVG rendering docs `_. From 9d68cef4f448c148d70102886d73844868f2df75 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 11 Aug 2022 14:36:23 +0200 Subject: [PATCH 1547/1831] Link python-chess-engine-extensions (closes #361, closes #915) --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 3fb94920e..8c85015e7 100644 --- a/README.rst +++ b/README.rst @@ -332,6 +332,7 @@ If you like, share interesting things you are using python-chess for, for exampl | :target: https://www.pettingzoo.ml/classic/chess | A multi-agent reinforcement learning environment | +------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ +* extensions to build engines (search and evaluation) – https://github.com/Mk-Chan/python-chess-engine-extensions * a stand-alone chess computer based on DGT board – http://www.picochess.org/ * a bridge between Lichess API and chess engines – https://github.com/careless25/lichess-bot * a command-line PGN annotator – https://github.com/rpdelaney/python-chess-annotator From cb65881bbd9489d1ef525cf14fedbe07a1fcf6ec Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 16 Sep 2022 14:23:26 +0200 Subject: [PATCH 1548/1831] Prepare 1.9.3 --- CHANGELOG.rst | 16 ++++++++++++++++ chess/__init__.py | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 36564f56c..6e543bcae 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,22 @@ Changelog for python-chess ========================== +New in v1.9.3 +------------- + +Bugfixes: + +* Fix some valid characters were not accepted in PGN tag names. + +Changes: + +* Skip over syntactically invalid PGN tags. +* Detect Antichess insufficient material with two opposing knights. + +New features: + +* Add `chess.Board.unicode(..., orientation=chess.WHITE)`. + New in v1.9.2 ------------- diff --git a/chess/__init__.py b/chess/__init__.py index b8198762b..c83a24c59 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.9.2" +__version__ = "1.9.3" import collections import copy @@ -1221,7 +1221,7 @@ def __str__(self) -> str: return "".join(builder) - def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_square: str = "⭘", orientation:Color = WHITE) -> str: + def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_square: str = "⭘", orientation: Color = WHITE) -> str: """ Returns a string representation of the board with Unicode pieces. Useful for pretty-printing to a terminal. From acdadb112b1d2fd1f1693f41bcd49c28ef2ed88a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 16 Sep 2022 14:27:46 +0200 Subject: [PATCH 1549/1831] Fix rst in changelog --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6e543bcae..1e51fee3f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,7 +15,7 @@ Changes: New features: -* Add `chess.Board.unicode(..., orientation=chess.WHITE)`. +* Add ``chess.Board.unicode(..., orientation=chess.WHITE)``. New in v1.9.2 ------------- From da82a9ba72e7756171a6ff1ba19b97a94aeb9308 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 16 Sep 2022 14:29:55 +0200 Subject: [PATCH 1550/1831] Subscribe to github-actions updates --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..620ae570c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 3 +updates: + - package-ecosystem: github-actions + directory: '/' + schedule: + interval: monthly From 82a608c9b75c5af1ddf7e360ee2aa22d9bda00b9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 16 Sep 2022 14:41:00 +0200 Subject: [PATCH 1551/1831] Fix dependabot.yml version --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 620ae570c..0d23a8f03 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,4 +1,4 @@ -version: 3 +version: 2 updates: - package-ecosystem: github-actions directory: '/' From 8350f9da1af68f0aeeb1bb7569b30caeb99828c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Sep 2022 12:42:06 +0000 Subject: [PATCH 1552/1831] Bump github/codeql-action from 1 to 2 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v1...v2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a1b9e1b55..a37e82933 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,7 +12,7 @@ jobs: security-events: write steps: - uses: actions/checkout@v3 - - uses: github/codeql-action/init@v1 + - uses: github/codeql-action/init@v2 with: languages: python - - uses: github/codeql-action/analyze@v1 + - uses: github/codeql-action/analyze@v2 From 9b40f8a127de56a2fbdee71aefe77e9c0402cce2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 17 Sep 2022 13:27:21 +0200 Subject: [PATCH 1553/1831] Update readthedocs.yml --- .readthedocs.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 11760dd7d..dbe71809a 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,7 +1,15 @@ -version: 1 +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.10" + +sphinx: + configuration: docs/conf.py + python: - version: 3.8 install: + - method: pip + path: . - requirements: docs/requirements.txt - - method: setuptools - path: docs From 3476c7306361c2ef481ac6c70204b5b18577ce34 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 17 Sep 2022 13:29:44 +0200 Subject: [PATCH 1554/1831] Try Sphinx 4.5.0 --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 5152367fe..c8cc7c404 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -Sphinx==3.5.4 +Sphinx==4.5.0 From 80c718489e2bdbd597f6e2c5c02663c4c9e0265d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 17 Sep 2022 13:32:06 +0200 Subject: [PATCH 1555/1831] Try Sphinx 5.1.1 --- docs/conf.py | 10 +++++----- docs/requirements.txt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1e00cd0d1..bde54010b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,10 @@ import sys import os +# Import the chess module. +sys.path.insert(0, os.path.abspath("..")) +import chess + # Do not resolve these. autodoc_type_aliases = { "Square": "chess.Square", @@ -10,10 +14,6 @@ "IntoSquareSet": "chess.IntoSquareSet", } -# Import the chess module. -sys.path.insert(0, os.path.abspath("..")) -import chess - # Autodoc. extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.intersphinx"] autodoc_member_order = "bysource" @@ -29,7 +29,7 @@ # General information about the project. project = "python-chess" -copyright = "2014–2021, Niklas Fiekas" +copyright = "2014–2022, Niklas Fiekas" # The version. version = chess.__version__ diff --git a/docs/requirements.txt b/docs/requirements.txt index c8cc7c404..baa05d40d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -Sphinx==4.5.0 +Sphinx==5.1.1 From 5498161b4de41c4b7cd31985dcaaee9457f909d0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 5 Oct 2022 20:41:10 +0200 Subject: [PATCH 1556/1831] Add known dates to changelog entries (closes #922) --- CHANGELOG-OLD.rst | 342 +++++++++++++++++++++++----------------------- CHANGELOG.rst | 80 +++++------ 2 files changed, 211 insertions(+), 211 deletions(-) diff --git a/CHANGELOG-OLD.rst b/CHANGELOG-OLD.rst index 6a9f5facf..bebcba4d0 100644 --- a/CHANGELOG-OLD.rst +++ b/CHANGELOG-OLD.rst @@ -1,8 +1,8 @@ Old Changelog for python-chess up to 1.0.0 ========================================== -New in v1.0.0 -------------- +New in v1.0.0 (24th Sep 2020) +----------------------------- Changes: @@ -38,8 +38,8 @@ New features: * Added `chess.Board.apply_mirror()`. * Added `chess.svg.board(..., colors)`, to allow overriding the default theme. -New in v0.31.4 --------------- +New in v0.31.4 (9th Aug 2020) +----------------------------- Bugfixes: @@ -53,8 +53,8 @@ New features: * Finish typing and declare support for mypy. -New in v0.31.3 --------------- +New in v0.31.3 (18th Jul 2020) +------------------------------ Bugfixes: @@ -84,8 +84,8 @@ New features: `[%eval ...]` PGN annotations. * Added `SquareSet.ray(a, b)` and `SquareSet.between(a, b)`. -New in v0.31.2 --------------- +New in v0.31.2 (2nd Jun 2020) +----------------------------- Bugfixes: @@ -99,8 +99,8 @@ Changes: `one_king`. * Take advantage of `int.bit_count()` coming in Python 3.10. -New in v0.31.1 --------------- +New in v0.31.1 (5th May 2020) +----------------------------- Bugfixes: @@ -122,8 +122,8 @@ Features: * Added `Board.find_move()`, useful for finding moves that match human input. -New in v0.31.0 --------------- +New in v0.31.0 (21st Apr 2020) +------------------------------ Changes: @@ -160,8 +160,8 @@ Features: * Added `empty_square` parameter for `chess.Board.unicode()` with better aligned default (⭘). -New in v0.30.1 --------------- +New in v0.30.1 (18th Jan 2020) +------------------------------ Changes: @@ -187,8 +187,8 @@ Features: * Added `board.checkers()`, returning a set of squares with the pieces giving check. -New in v0.30.0 --------------- +New in v0.30.0 (1st Jan 2020) +----------------------------- Changes: @@ -211,8 +211,8 @@ Features: when running on Python 3.9+ and Linux 5.3+. * Add `chess.Board.san_and_push()`. -New in v0.29.0 --------------- +New in v0.29.0 (2nd Dec 2019) +----------------------------- Changes: @@ -235,8 +235,8 @@ Features: * Support `wdl` in UCI info (usually activated with `UCI_ShowWDL`). -New in v0.28.3 --------------- +New in v0.28.3 (3rd Sep 2019) +----------------------------- Bugfixes: @@ -244,8 +244,8 @@ Bugfixes: * Handle self-reported errors by XBoard engines "Error: ..." or "Illegal move: ...". -New in v0.28.2 --------------- +New in v0.28.2 (25th Jul 2019) +------------------------------ Bugfixes: @@ -257,8 +257,8 @@ Changes: * `chess.Move.from_uci()` no longer accepts moves from and to the same square, for example `a1a1`. `0000` is now the only valid null move notation. -New in v0.28.1 --------------- +New in v0.28.1 (25th May 2019) +------------------------------ Bugfixes: @@ -273,8 +273,8 @@ Changes: * Added `chess.engine.InfoDict` class with typed shorthands for common keys. * Support `[Variant "3-check"]` (from chess.com PGNs). -New in v0.28.0 --------------- +New in v0.28.0 (20th May 2019) +------------------------------ Changes: @@ -314,8 +314,8 @@ New features: * `chess.engine.EngineProtocol` and constructors now optionally take an explicit `loop` argument. -New in v0.27.3 --------------- +New in v0.27.3 (21st Mar 2019) +------------------------------ Changes: @@ -343,8 +343,8 @@ New features: `chess.pgn.GameNode.dangling_node()` to simplify subclassing `GameNode`. * `EngineProtocol.communicate()` is now also available in the synchronous API. -New in v0.27.2 --------------- +New in v0.27.2 (16th Mar 2019) +------------------------------ Bugfixes: @@ -352,16 +352,16 @@ Bugfixes: intended when using `chess.engine.Limit.time`, and searching 100 times more nodes than intended when using `chess.engine.Limit.nodes`. Thanks @pascalgeo. -New in v0.27.1 --------------- +New in v0.27.1 (15th Mar 2019) +------------------------------ Bugfixes: * `chess.engine.XBoardProtocol.play()` was raising `KeyError` when using time controls with increment or remaining moves. Thanks @pascalgeo. -New in v0.27.0 --------------- +New in v0.27.0 (14th Mar 2019) +------------------------------ This is the second **release candidate for python-chess 1.0**. If you see the need for breaking changes, please speak up now! @@ -389,8 +389,8 @@ New features: * Document that `chess.engine.EngineProtocol` is compatible with AsyncSSH 1.16.0. -New in v0.26.0 --------------- +New in v0.26.0 (19th Feb 2019) +------------------------------ This is the first **release candidate for python-chess 1.0**. If you see the need for breaking changes, please speak up now! @@ -414,16 +414,16 @@ Bugfixes: * Properly handle delayed engine errors, for example unsupported options. -New in v0.25.1 --------------- +New in v0.25.1 (24th Jan 2019) +------------------------------ Bugfixes: * `chess.engine` did not correctly handle Windows-style line endings. Thanks @Bstylestuff. -New in v0.25.0 --------------- +New in v0.25.0 (18th Jan 2019) +------------------------------ New features: @@ -443,8 +443,8 @@ Changes: * `chess.pgn.read_game()` now ignores BOM at the start of the stream. * Removed deprecated items. -New in v0.24.2 --------------- +New in v0.24.2 (5th Jan 2019) +----------------------------- Bugfixes: @@ -469,8 +469,8 @@ Features: * Added `chess.pgn.BaseVisitor.visit_board()` and `chess.pgn.BoardCreator`. -New in v0.24.1, v0.23.11 ------------------------- +New in v0.24.1, v0.23.11 (7th Dec 2018) +--------------------------------------- Bugfixes: @@ -479,8 +479,8 @@ Bugfixes: * `chess.pgn.GameNode.uci()` was always raising an exception. Also included in v0.24.0. -New in v0.24.0 --------------- +New in v0.24.0 (3rd Dec 2018) +----------------------------- This release **drops support for Python 2**. The *0.23.x* branch will be maintained for one more month. @@ -555,16 +555,16 @@ New features: The corresponding `end_game()` or `end_variation()` will still be called. * Added `chess.svg.MARGIN`. -New in v0.23.10 ---------------- +New in v0.23.10 (31st Oct 2018) +------------------------------- Bugfixes: * `chess.SquareSet` now correctly handles negative masks. Thanks @hasnul. * `chess.pgn` now accepts `[Variant "chess 960"]` (with the space). -New in v0.23.9 --------------- +New in v0.23.9 (4th Jul 2018) +----------------------------- Changes: @@ -572,16 +572,16 @@ Changes: repetition no longer needs to occur on consecutive alternating moves. Thanks @LegionMammal978. -New in v0.23.8 --------------- +New in v0.23.8 (1st Jul 2018) +----------------------------- Bugfixes: * `chess.syzygy`: Correctly initialize wide DTZ map for experimental 7 piece table KRBBPvKQ. -New in v0.23.7 --------------- +New in v0.23.7 (26th Jun 2018) +------------------------------ Bugfixes: @@ -604,8 +604,8 @@ New features: * Added `Board.root()`. -New in v0.23.6 --------------- +New in v0.23.6 (25th May 2018) +------------------------------ Bugfixes: @@ -628,8 +628,8 @@ New features: * Added `polyglot.MemoryMappedReader.get(board, default=None)`. -New in v0.23.5 --------------- +New in v0.23.5 (11th May 2018) +------------------------------ Bugfixes: @@ -642,8 +642,8 @@ Changes: * Better error messages when parsing info from UCI engine fails. * Better error message for `b.set_board_fen(b.fen())`. -New in v0.23.4 --------------- +New in v0.23.4 (29th Apr 2018) +------------------------------ New features: @@ -655,15 +655,15 @@ Bugfixes: * Implement 16 bit DTZ mapping, which is required for some of the longest 7 piece endgames. -New in v0.23.3 --------------- +New in v0.23.3 (21st Apr 2018) +------------------------------ New features: * XBoard: Support `variant`. Thanks gbtami. -New in v0.23.2 --------------- +New in v0.23.2 (20th Apr 2018) +------------------------------ Bugfixes: @@ -671,16 +671,16 @@ Bugfixes: * XBoard: Ignore debug output prefixed with `#`. Thanks Dan Ravensloft and Manik Charan. -New in v0.23.1 --------------- +New in v0.23.1 (13th Apr 2018) +------------------------------ Bugfixes: * Fix DTZ in case of mate in 1. This is a cosmetic fix, as the previous behavior was only off by one (which is allowed by design). -New in v0.23.0 --------------- +New in v0.23.0 (8th Apr 2018) +----------------------------- New features: @@ -694,8 +694,8 @@ Changes: * The undocumented constructors of `chess.syzygy.WdlTable` and `chess.syzygy.DtzTable` have been changed. -New in v0.22.2 --------------- +New in v0.22.2 (15th Mar 2018) +------------------------------ Bugfixes: @@ -714,8 +714,8 @@ New features: * Added `Board.lan()` for long algebraic notation. -New in v0.22.1 --------------- +New in v0.22.1 (1st Jan 2018) +----------------------------- New features: @@ -734,8 +734,8 @@ Bugfixes: * `chess.pgn`: Allow games without movetext. * XBoard: Fixed draw handling. -New in v0.22.0 --------------- +New in v0.22.0 (20th Nov 2017) +------------------------------ Changes: @@ -749,16 +749,16 @@ New features: * XBoard: Added `DrawHandler`. -New in v0.21.2 --------------- +New in v0.21.2 (17th Nov 2017) +------------------------------ Changes: * `chess.svg` is now fully SVG Tiny 1.2 compatible. Removed `chess.svg.DEFAULT_STYLE` which would from now on be always empty. -New in v0.21.1 --------------- +New in v0.21.1 (14th Nov 2017) +------------------------------ Bugfixes: @@ -779,21 +779,21 @@ Changes: * Documentation fixes and tweaks by Boštjan Mejak. * Changed unicode character for empty squares in `Board.unicode()`. -New in v0.21.0 --------------- +New in v0.21.0 (13th Nov 2017) +------------------------------ Release yanked. -New in v0.20.1 --------------- +New in v0.20.1 (16th Oct 2017) +------------------------------ Bugfixes: * Fix arrow positioning on SVG boards. * Documentation fixes and improvements, making most doctests runnable. -New in v0.20.0 --------------- +New in v0.20.0 (13th Oct 2017) +------------------------------ Bugfixes: @@ -820,8 +820,8 @@ New features: * Factored out some (unstable) low level APIs: `BB_CORNERS`, `_carry_rippler()`, `_edges()`. -New in v0.19.0 --------------- +New in v0.19.0 (27th Jul 2017) +------------------------------ New features: @@ -859,23 +859,23 @@ Changes: the extra dependencies are required for both UCI and XBoard engines). * Mixed documentation fixes and improvements. -New in v0.18.4 --------------- +New in v0.18.4 (27th Jul 2017) +------------------------------ Changes: * Support `[Variant "fischerandom"]` in PGNs for Cutechess compatibility. Thanks to Steve Maughan for reporting. -New in v0.18.3 --------------- +New in v0.18.3 (28th Jun 2017) +------------------------------ Bugfixes: * `chess.gaviota.NativeTablebases.get_dtm()` and `get_wdl()` were missing. -New in v0.18.2 --------------- +New in v0.18.2 (1st Jun 2017) +----------------------------- Bugfixes: @@ -890,8 +890,8 @@ Changes: * Added more NAG constants in `chess.pgn`. -New in v0.18.1 --------------- +New in v0.18.1 (1st May 2017) +----------------------------- Bugfixes: @@ -907,8 +907,8 @@ Changes: * `ThreeCheckBoard.uci_variant` changed from `threecheck` to `3check`. -New in v0.18.0 --------------- +New in v0.18.0 (20th Apr 2017) +------------------------------ Bugfixes: @@ -947,8 +947,8 @@ New features: * SVGs now have `viewBox` and `chess.svg.board(size=None)` supports and defaults to `None` (i.e. scaling to the size of the container). -New in v0.17.0 --------------- +New in v0.17.0 (6th Mar 2017) +----------------------------- Changes: @@ -991,8 +991,8 @@ New features: * Added `msb()`, `lsb()`, `scan_reversed()` and `scan_forward()`. * Added `BB_RAYS` and `BB_BETWEEN`. -New in v0.16.2 --------------- +New in v0.16.2 (15th Jan 2017) +------------------------------ Changes: @@ -1003,16 +1003,16 @@ Changes: * `chess.svg`: Better vector graphics for knights. Thanks to ProgramFox. * Documentation improvements. -New in v0.16.1 --------------- +New in v0.16.1 (12th Dec 2016) +------------------------------ Bugfixes: * Explosions in atomic chess were not destroying castling rights. Thanks to ProgramFOX for finding this issue. -New in v0.16.0 --------------- +New in v0.16.0 (11th Dec 2016) +------------------------------ Bugfixes: @@ -1061,8 +1061,8 @@ New features: * Highlight last move and checks when rendering board SVGs. -New in v0.15.3 --------------- +New in v0.15.3 (21st Sep 2016) +------------------------------ Bugfixes: @@ -1084,8 +1084,8 @@ Bugfixes: very similar to the bug fixed in v0.15.1. Thanks to piccoloprogrammatore for reporting. -New in v0.15.1 --------------- +New in v0.15.1 (12th Sep 2016) +------------------------------ Bugfixes: @@ -1094,10 +1094,10 @@ Bugfixes: New features: -* Replaced __html__ with experimental SVG rendering for IPython. +* Replaced `__html__` with experimental SVG rendering for IPython. -New in v0.15.0 --------------- +New in v0.15.0 (11th Aug 2016) +------------------------------ Changes: @@ -1130,8 +1130,8 @@ New features: * Added `chess.BB_BACKRANKS` and `chess.BB_PAWN_ATTACKS`. -New in v0.14.1 --------------- +New in v0.14.1 (7th Jun 2016) +----------------------------- Bugfixes: @@ -1155,8 +1155,8 @@ Changes: * Documentation improvements. -New in v0.14.0 --------------- +New in v0.14.0 (7th Apr 2016) +----------------------------- Changes: @@ -1197,8 +1197,8 @@ New features: `Board.generate_legal_captures(from_mask=BB_ALL, to_mask=BB_ALL)`. -New in v0.13.3 --------------- +New in v0.13.3 (7th Apr 2016) +----------------------------- **This is a bugfix release for a move generation bug.** Other than the bugfix itself there are only minimal fully backwardscompatible changes. @@ -1228,8 +1228,8 @@ Changes: * Consistently handle tabs in UCI engine output. -New in v0.13.2 --------------- +New in v0.13.2 (19th Jan 2016) +------------------------------ Changes: @@ -1244,8 +1244,8 @@ Minor new features: * Added `chess.pgn.Game.from_board()`. -New in v0.13.1 --------------- +New in v0.13.1 (20th Dec 2015) +------------------------------ Changes: @@ -1267,8 +1267,8 @@ Minor new features: * Added `chess.SquareSet.from_square(square)`. -New in v0.13.0 --------------- +New in v0.13.0 (10th Nov 2015) +------------------------------ * `chess.pgn.Game.export()` and `chess.pgn.GameNode.export()` have been removed and replaced with a new visitor concept. @@ -1276,8 +1276,8 @@ New in v0.13.0 * `chess.pgn.read_game()` no longer takes an `error_handler` argument. Errors are now logged. Use the new visitor concept to change this behaviour. -New in v0.12.5 --------------- +New in v0.12.5 (18th Oct 2015) +------------------------------ Bugfixes: @@ -1288,8 +1288,8 @@ Bugfixes: * PGN variation start comments for variations on the very first move were assigned to the game. Thanks to Norbert Räcke for reporting. -New in v0.12.4 --------------- +New in v0.12.4 (13th Oct 2015) +------------------------------ Bugfixes: @@ -1306,24 +1306,24 @@ Changes: * Added tox.ini to specify test suite and flake8 options. -New in v0.12.3 --------------- +New in v0.12.3 (9th Oct 2015) +----------------------------- Bugfixes: * Some invalid castling rights were silently ignored by `Board.set_fen()`. Now it is ensured information is stored for retrieval using `Board.status()`. -New in v0.12.2 --------------- +New in v0.12.2 (7th Oct 2015) +----------------------------- Bugfixes: * Some Gaviota probe results were incorrect for positions where black could capture en passant. -New in v0.12.1 --------------- +New in v0.12.1 (7th Oct 2015) +----------------------------- Changes: @@ -1331,8 +1331,8 @@ Changes: method `Board.clean_castling_rights()` to get the subset of strictly valid castling rights. -New in v0.12.0 --------------- +New in v0.12.0 (3rd Oct 2015) +----------------------------- New features: @@ -1340,8 +1340,8 @@ New features: * Pure Python Gaviota tablebase probing. Thanks to Jean-Noël Avila. -New in v0.11.1 --------------- +New in v0.11.1 (7th Sep 2015) +----------------------------- Bugfixes: @@ -1352,8 +1352,8 @@ Bugfixes: * Ignore extra spaces in UCI `info` lines, as for example sent by the Hakkapeliitta engine. Thanks to Jürgen Précour for reporting. -New in v0.11.0 --------------- +New in v0.11.0 (6th Sep 2015) +----------------------------- Changes: @@ -1394,15 +1394,15 @@ New features: * Make `repr(board.legal_moves)` human readable. -New in v0.10.1 --------------- +New in v0.10.1 (30th Aug 2015) +------------------------------ Bugfixes: * Fix use-after-free in Gaviota tablebase initialization. -New in v0.10.0 --------------- +New in v0.10.0 (28th Aug 2015) +------------------------------ New dependencies: @@ -1486,8 +1486,8 @@ New features: * Support common set operations on `chess.SquareSet()`. -New in v0.9.1 -------------- +New in v0.9.1 (15th Jul 2015) +----------------------------- Bugfixes: @@ -1500,8 +1500,8 @@ Bugfixes: rank must be empty, additionally. We do not do further retrograde analysis, because these are the only cases affecting move generation. -New in v0.8.3 -------------- +New in v0.8.3 (15th Jul 2015) +----------------------------- Bugfixes: @@ -1512,8 +1512,8 @@ Bugfixes: rank must be empty, additionally. We do not do further retrograde analysis, because these are the only cases affecting move generation. -New in v0.9.0 -------------- +New in v0.9.0 (24th Jun 2015) +----------------------------- **This is a big update with quite a few breaking changes. Carefully review the changes before upgrading. It's no problem if you can not update right now. @@ -1628,8 +1628,8 @@ New features: `Board.__str__()` but with unicode pieces. * Patch by Richard C. Gerkin: Added `Board.__html__()`. -New in v0.8.2 -------------- +New in v0.8.2 (21st Jun 2015) +----------------------------- Bugfixes: @@ -1642,8 +1642,8 @@ Optimizations: * Remove `bswap()` from Syzygy decompression hot path. Directly read integers with the correct endianness. -New in v0.8.1 -------------- +New in v0.8.1 (29th May 2015) +----------------------------- * Fixed pondering mode in uci module. For example `ponderhit()` was blocking indefinitely. Thanks to Valeriy Huz for reporting this. @@ -1672,8 +1672,8 @@ New in v0.8.1 * Use containerized tests on Travis CI, test against Stockfish 6, improved test coverage amd various minor clean-ups. -New in v0.8.0 -------------- +New in v0.8.0 (25th Mar 2015) +----------------------------- * **Implement Syzygy endgame tablebase probing.** `https://syzygy-tables.info `_ @@ -1694,15 +1694,15 @@ New in v0.8.0 startup sometimes needed to be processed before the Engine object was fully initialized. -New in v0.7.0 -------------- +New in v0.7.0 (21st Feb 2015) +----------------------------- * **Implement UCI engine communication.** * Patch by Matthew Lai: `Add caching for gameNode.board()`. -New in v0.6.0 -------------- +New in v0.6.0 (8th Nov 2014) +---------------------------- * If there are comments in a game before the first move, these are now assigned to `Game.comment` instead of `Game.starting_comment`. `Game.starting_comment` @@ -1725,8 +1725,8 @@ New in v0.6.0 * Remove `next_bit()`. Now use `bit_scan()`. -New in v0.5.0 -------------- +New in v0.5.0 (28th Oct 2014) +----------------------------- * PGN parsing is now more robust: `read_game()` ignores invalid tokens. Still exceptions are going to be thrown on illegal or ambiguous moves, but @@ -1772,14 +1772,14 @@ New in v0.5.0 * Minor testcoverage improvements. -New in v0.4.2 -------------- +New in v0.4.2 (11th Oct 2014) +----------------------------- * Fix bug where `pawn_moves_from()` and consequently `is_legal()` weren't handling en passant correctly. Thanks to Norbert Naskov for reporting. -New in v0.4.1 -------------- +New in v0.4.1 (26th Aug 2014) +----------------------------- * Fix `is_fivefold_repitition()`: The new fivefold repetition rule requires the repetitions to occur on *alternating consecutive* moves. @@ -1789,8 +1789,8 @@ New in v0.4.1 * Add recently introduced features to README. -New in v0.4.0 -------------- +New in v0.4.0 (19th Aug 2014) +----------------------------- * Introduce `can_claim_draw()`, `can_claim_fifty_moves()` and `can_claim_threefold_repitition()`. @@ -1822,8 +1822,8 @@ New in v0.4.0 * Minor coding style fixes. -New in v0.3.1 -------------- +New in v0.3.1 (15th Aug 2014) +----------------------------- * `Bitboard.status()` now correctly detects `STATUS_INVALID_EP_SQUARE`, instead of errors or false reports. @@ -1832,8 +1832,8 @@ New in v0.3.1 * Minor coding style fixes, including removal of unused imports. -New in v0.3.0 -------------- +New in v0.3.0 (13th Aug 2014) +----------------------------- * Rename property `half_moves` of `Bitboard` to `halfmove_clock`. diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1e51fee3f..1c68c9f34 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,8 @@ Changelog for python-chess ========================== -New in v1.9.3 -------------- +New in v1.9.3 (16th Sep 2022) +----------------------------- Bugfixes: @@ -17,8 +17,8 @@ New features: * Add ``chess.Board.unicode(..., orientation=chess.WHITE)``. -New in v1.9.2 -------------- +New in v1.9.2 (17th Jun 2022) +----------------------------- Bugfixes: @@ -30,8 +30,8 @@ New features: * Add ``chess.engine.AnalysisResult.would_block()``. -New in v1.9.1 -------------- +New in v1.9.1 (28th May 2022) +----------------------------- Bugfixes: @@ -50,8 +50,8 @@ New features: * Add model ``sf15`` for ``chess.engine.Score.wdl()``. -New in v1.9.0 -------------- +New in v1.9.0 (18th Mar 2022) +----------------------------- Bugfixes: @@ -64,8 +64,8 @@ New features: * Let ``chess.svg.board()`` add ASCII board as description of SVG. * Add hint when engine process dies due to illegal instruction. -New in v1.8.0 -------------- +New in v1.8.0 (23rd Dec 2021) +----------------------------- Bugfixes: @@ -76,8 +76,8 @@ New features: * Read and write PGN comments like ``[%emt 0:05:21]``. -New in v1.7.0 -------------- +New in v1.7.0 (7th Oct 2021) +---------------------------- New features: @@ -90,16 +90,16 @@ Bugfixes: * ``chess.pgn``: Fix skipping with nested variations. * ``chess.svg``: Make check gradient compatible with QtSvg. -New in v1.6.1 -------------- +New in v1.6.1 (12th Jun 2021) +----------------------------- Bugfixes: * Make ``chess.engine.SimpleEngine.play(..., draw_offered=True)`` available. Previously only added for ``chess.engine.Protocol``. -New in v1.6.0 -------------- +New in v1.6.0 (11th Jun 2021) +----------------------------- New features: @@ -121,8 +121,8 @@ Bugfixes: * Fix slightly off-center pawns in ``chess.svg``. * Fix typing error in Python 3.10 (due to added ``int.bit_count``). -New in v1.5.0 -------------- +New in v1.5.0 (7th Apr 2021) +---------------------------- Bugfixes: @@ -148,8 +148,8 @@ New features: Special thanks to @MarkZH for many of the engine related changes in this release! -New in v1.4.0 -------------- +New in v1.4.0 (25th Jan 2021) +----------------------------- New features: @@ -165,8 +165,8 @@ Changes: * Recover from invalid UTF-8 sent by an UCI engine, by ignoring that (and only that) line. -New in v1.3.3 -------------- +New in v1.3.3 (27th Dec 2020) +----------------------------- Bugfixes: @@ -184,8 +184,8 @@ New features: * Implemented Lichess winning chance model for ``chess.engine.Score``: ``score.wdl(model="lichess")``. -New in v1.3.2 -------------- +New in v1.3.2 (12th Dec 2020) +----------------------------- Bugfixes: @@ -195,8 +195,8 @@ Bugfixes: on the same rank, file, or diagonal. Such positions are impossible to reach, break Stockfish, and maybe other engines. -New in v1.3.1 -------------- +New in v1.3.1 (6th Dec 2020) +---------------------------- Bugfixes: @@ -204,8 +204,8 @@ Bugfixes: castling rights (as well as mislabeled Standard Chess960 games). Previously, all castling moves in such games were rejected. -New in v1.3.0 -------------- +New in v1.3.0 (6th Nov 2020) +---------------------------- Changes: @@ -228,16 +228,16 @@ New features: * Added ``chess.pgn.GameNode.next()``. -New in v1.2.2 -------------- +New in v1.2.2 (29th Oct 2020) +----------------------------- Bugfixes: * Fixed regression where releases were uploaded without the ``py.typed`` marker. -New in v1.2.1 -------------- +New in v1.2.1 (26th Oct 2020) +----------------------------- Changes: @@ -254,8 +254,8 @@ Changes: previous versions? Run ``pip install --force-reinstall chess`` (due to https://github.com/niklasf/python-chess/issues/680). -New in v1.2.0 -------------- +New in v1.2.0 (22nd Oct 2020) +----------------------------- New features: @@ -282,8 +282,8 @@ Changes: ``chess.Board.epd()`` is now typed as ``Literal["legal", "fen", "xfen"]`` rather than ``str``. -New in v1.1.0 -------------- +New in v1.1.0 (4th Oct 2020) +---------------------------- New features: @@ -297,15 +297,15 @@ Changes: like ``e2e4``, even if that is not a pawn move, castling notation with zeros, null moves in UCI notation, and null moves in XBoard notation. -New in v1.0.1 -------------- +New in v1.0.1 (24th Sep 2020) +----------------------------- Bugfixes: * ``chess.svg``: Restored SVG Tiny compatibility by splitting colors like ``#rrggbbaa`` into a solid color and opacity. -New in v1.0.0 -------------- +New in v1.0.0 (24th Sep 2020) +----------------------------- See ``CHANGELOG-OLD.rst`` for changes up to v1.0.0. From 13f9781d515caba80e5dd60972e700e36362e3fe Mon Sep 17 00:00:00 2001 From: mush42 Date: Wed, 12 Oct 2022 19:38:54 +0200 Subject: [PATCH 1557/1831] Added chessmart: https://github.com/blindpandas/chessmart --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index 8c85015e7..3a6ed5209 100644 --- a/README.rst +++ b/README.rst @@ -344,6 +344,8 @@ If you like, share interesting things you are using python-chess for, for exampl * a chessboard widget for PySide2 – https://github.com/H-a-y-k/hichesslib * Django Rest Framework API for multiplayer chess – https://github.com/WorkShoft/capablanca-api * a `browser based PGN viewer `_ written in PyScript – https://github.com/nmstoker/ChessMatchViewer +* an accessible chessboard that allows blind and visually impaired players to play chess against Stockfish – https://github.com/blindpandas/chessmart + Acknowledgements ---------------- From a721c5bbf8eff21b12c2417ba3eaa4001a4ad466 Mon Sep 17 00:00:00 2001 From: Trevor Bayless Date: Thu, 13 Oct 2022 21:29:51 -0500 Subject: [PATCH 1558/1831] Add specific move error exceptions --- chess/__init__.py | 78 +++++++++++++++++++++++++++++++++-------------- chess/variant.py | 2 +- test.py | 43 +++++++++++++++----------- 3 files changed, 81 insertions(+), 42 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index c83a24c59..30b9a392a 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -165,6 +165,18 @@ def result(self) -> str: return "1/2-1/2" if self.winner is None else ("1-0" if self.winner else "0-1") +class InvalidMoveError(ValueError): + """Raised when the attempted move is invalid in the current position""" + + +class IllegalMoveError(ValueError): + """Raised when the attempted move is illegal in the current position""" + + +class AmbiguousMoveError(ValueError): + """Raised when the attempted move is ambiguous in the current position""" + + Square = int SQUARES = [ A1, B1, C1, D1, E1, F1, G1, H1, @@ -551,23 +563,29 @@ def from_uci(cls, uci: str) -> Move: """ Parses a UCI string. - :raises: :exc:`ValueError` if the UCI string is invalid. + :raises: :exc:`InvalidMoveError` if the UCI string is invalid. """ if uci == "0000": return cls.null() elif len(uci) == 4 and "@" == uci[1]: - drop = PIECE_SYMBOLS.index(uci[0].lower()) - square = SQUARE_NAMES.index(uci[2:]) + try: + drop = PIECE_SYMBOLS.index(uci[0].lower()) + square = SQUARE_NAMES.index(uci[2:]) + except ValueError: + raise InvalidMoveError(f"invalid uci: {uci!r}") return cls(square, square, drop=drop) elif 4 <= len(uci) <= 5: - from_square = SQUARE_NAMES.index(uci[0:2]) - to_square = SQUARE_NAMES.index(uci[2:4]) - promotion = PIECE_SYMBOLS.index(uci[4]) if len(uci) == 5 else None + try: + from_square = SQUARE_NAMES.index(uci[0:2]) + to_square = SQUARE_NAMES.index(uci[2:4]) + promotion = PIECE_SYMBOLS.index(uci[4]) if len(uci) == 5 else None + except ValueError: + raise InvalidMoveError(f"invalid uci: {uci!r}") if from_square == to_square: - raise ValueError(f"invalid uci (use 0000 for null moves): {uci!r}") + raise InvalidMoveError(f"invalid uci (use 0000 for null moves): {uci!r}") return cls(from_square, to_square, promotion=promotion) else: - raise ValueError(f"expected uci string to be of length 4 or 5: {uci!r}") + raise InvalidMoveError(f"expected uci string to be of length 4 or 5: {uci!r}") @classmethod def null(cls) -> Move: @@ -2305,14 +2323,14 @@ def find_move(self, from_square: Square, to_square: Square, promotion: Optional[ Castling moves are normalized to king moves by two steps, except in Chess960. - :raises: :exc:`ValueError` if no matching legal move is found. + :raises: :exc:`IllegalMoveError` if no matching legal move is found. """ if promotion is None and self.pawns & BB_SQUARES[from_square] and BB_SQUARES[to_square] & BB_BACKRANKS: promotion = QUEEN move = self._from_chess960(self.chess960, from_square, to_square, promotion) if not self.is_legal(move): - raise ValueError(f"no matching legal move for {move.uci()} ({SQUARE_NAMES[from_square]} -> {SQUARE_NAMES[to_square]}) in {self.fen()}") + raise IllegalMoveError(f"no matching legal move for {move.uci()} ({SQUARE_NAMES[from_square]} -> {SQUARE_NAMES[to_square]}) in {self.fen()}") return move @@ -2938,14 +2956,14 @@ def variation_san(self, variation: Iterable[Move]) -> str: The board will not be modified as a result of calling this. - :raises: :exc:`ValueError` if any moves in the sequence are illegal. + :raises: :exc:`IllegalMoveError` if any moves in the sequence are illegal. """ board = self.copy(stack=False) san = [] for move in variation: if not board.is_legal(move): - raise ValueError(f"illegal move {move} in position {board.fen()}") + raise IllegalMoveError(f"illegal move {move} in position {board.fen()}") if board.turn == WHITE: san.append(f"{board.fullmove_number}. {board.san_and_push(move)}") @@ -2966,7 +2984,11 @@ def parse_san(self, san: str) -> Move: The returned move is guaranteed to be either legal or a null move. - :raises: :exc:`ValueError` if the SAN is invalid, illegal or ambiguous. + :raises: + :exc:`ValueError` (or specifically an exception specified below) if the SAN is invalid, illegal or ambiguous. + - :exc:`InvalidMoveError` if the SAN is invalid. + - :exc:`IllegalMoveError` if the SAN is illegal. + - :exc:`AmbiguousMoveError` if the SAN is ambiguous. """ # Castling. try: @@ -2975,7 +2997,7 @@ def parse_san(self, san: str) -> Move: elif san in ["O-O-O", "O-O-O+", "O-O-O#", "0-0-0", "0-0-0+", "0-0-0#"]: return next(move for move in self.generate_castling_moves() if self.is_queenside_castling(move)) except StopIteration: - raise ValueError(f"illegal san: {san!r} in {self.fen()}") + raise IllegalMoveError(f"illegal san: {san!r} in {self.fen()}") # Match normal moves. match = SAN_REGEX.match(san) @@ -2984,9 +3006,9 @@ def parse_san(self, san: str) -> Move: if san in ["--", "Z0", "0000", "@@@@"]: return Move.null() elif "," in san: - raise ValueError(f"unsupported multi-leg move: {san!r}") + raise InvalidMoveError(f"unsupported multi-leg move: {san!r}") else: - raise ValueError(f"invalid san: {san!r}") + raise InvalidMoveError(f"invalid san: {san!r}") # Get target square. Mask our own pieces to exclude castling moves. to_square = SQUARE_NAMES.index(match.group(4)) @@ -3016,7 +3038,7 @@ def parse_san(self, san: str) -> Move: if move.promotion == promotion: return move else: - raise ValueError(f"missing promotion piece type: {san!r} in {self.fen()}") + raise IllegalMoveError(f"missing promotion piece type: {san!r} in {self.fen()}") else: from_mask &= self.pawns @@ -3031,12 +3053,12 @@ def parse_san(self, san: str) -> Move: continue if matched_move: - raise ValueError(f"ambiguous san: {san!r} in {self.fen()}") + raise AmbiguousMoveError(f"ambiguous san: {san!r} in {self.fen()}") matched_move = move if not matched_move: - raise ValueError(f"illegal san: {san!r} in {self.fen()}") + raise IllegalMoveError(f"illegal san: {san!r} in {self.fen()}") return matched_move @@ -3047,7 +3069,11 @@ def push_san(self, san: str) -> Move: Returns the move. - :raises: :exc:`ValueError` if neither legal nor a null move. + :raises: + :exc:`ValueError` (or specifically an exception specified below) if neither legal nor a null move. + - :exc:`InvalidMoveError` if the SAN is invalid. + - :exc:`IllegalMoveError` if the SAN is illegal. + - :exc:`AmbiguousMoveError` if the SAN is ambiguous. """ move = self.parse_san(san) self.push(move) @@ -3075,8 +3101,11 @@ def parse_uci(self, uci: str) -> Move: The returned move is guaranteed to be either legal or a null move. - :raises: :exc:`ValueError` if the move is invalid or illegal in the + :raises: + :exc:`ValueError` (or specifically an exception specified below) if the move is invalid or illegal in the current position (but not a null move). + - :exc:`InvalidMoveError` if the UCI is invalid. + - :exc:`IllegalMoveError` if the UCI is illegal. """ move = Move.from_uci(uci) @@ -3087,7 +3116,7 @@ def parse_uci(self, uci: str) -> Move: move = self._from_chess960(self.chess960, move.from_square, move.to_square, move.promotion, move.drop) if not self.is_legal(move): - raise ValueError(f"illegal uci: {uci!r} in {self.fen()}") + raise IllegalMoveError(f"illegal uci: {uci!r} in {self.fen()}") return move @@ -3097,8 +3126,11 @@ def push_uci(self, uci: str) -> Move: Returns the move. - :raises: :exc:`ValueError` if the move is invalid or illegal in the + :raises: + :exc:`ValueError` (or specifically an exception specified below) if the move is invalid or illegal in the current position (but not a null move). + - :exc:`InvalidMoveError` if the UCI is invalid. + - :exc:`IllegalMoveError` if the UCI is illegal. """ move = self.parse_uci(uci) self.push(move) diff --git a/chess/variant.py b/chess/variant.py index 3fec62c3c..bda312c6d 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -989,7 +989,7 @@ def parse_san(self, san: str) -> chess.Move: uci = "P" + uci move = chess.Move.from_uci(uci) if not self.is_legal(move): - raise ValueError(f"illegal drop san: {san!r} in {self.fen()}") + raise chess.IllegalMoveError(f"illegal drop san: {san!r} in {self.fen()}") return move else: return super().parse_san(san) diff --git a/test.py b/test.py index 9e9a4c1d5..19ac0e65e 100755 --- a/test.py +++ b/test.py @@ -120,16 +120,16 @@ def test_uci_parsing(self): self.assertEqual(chess.Move.from_uci("0000").uci(), "0000") def test_invalid_uci(self): - with self.assertRaises(ValueError): + with self.assertRaises(chess.InvalidMoveError): chess.Move.from_uci("") - with self.assertRaises(ValueError): + with self.assertRaises(chess.InvalidMoveError): chess.Move.from_uci("N") - with self.assertRaises(ValueError): + with self.assertRaises(chess.InvalidMoveError): chess.Move.from_uci("z1g3") - with self.assertRaises(ValueError): + with self.assertRaises(chess.InvalidMoveError): chess.Move.from_uci("Q@g9") def test_xboard_move(self): @@ -383,9 +383,9 @@ def test_castling(self): def test_castling_san(self): board = chess.Board("4k3/8/8/8/8/8/8/4K2R w K - 0 1") self.assertEqual(board.parse_san("O-O"), chess.Move.from_uci("e1g1")) - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.parse_san("Kg1") - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.parse_san("Kh1") def test_ninesixty_castling(self): @@ -503,9 +503,9 @@ def test_find_move(self): self.assertEqual(board.find_move(chess.B7, chess.B8, chess.KNIGHT), chess.Move.from_uci("b7b8n")) # Illegal moves. - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.find_move(chess.D2, chess.D8) - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.find_move(chess.E1, chess.A1) # Castling. @@ -590,6 +590,13 @@ def test_promotion_with_check(self): board.push_san("d1=Q+") self.assertEqual(board.fen(), "8/8/8/3R1P2/8/2k2K2/8/r2q4 w - - 0 83") + def test_ambiguous_move(self): + board = chess.Board("8/8/1n6/3R1P2/1n6/2k2K2/3p4/r6r b - - 0 82") + with self.assertRaises(chess.AmbiguousMoveError): + board.parse_san("Rf1") + with self.assertRaises(chess.AmbiguousMoveError): + board.parse_san("Nd5") + def test_scholars_mate(self): board = chess.Board() @@ -723,17 +730,17 @@ def test_lan(self): def test_san_newline(self): board = chess.Board("rnbqk2r/ppppppbp/5np1/8/8/5NP1/PPPPPPBP/RNBQK2R w KQkq - 2 4") - with self.assertRaises(ValueError): + with self.assertRaises(chess.InvalidMoveError): board.parse_san("O-O\n") - with self.assertRaises(ValueError): + with self.assertRaises(chess.InvalidMoveError): board.parse_san("Nc3\n") def test_pawn_capture_san_without_file(self): board = chess.Board("2rq1rk1/pb2bppp/1p2p3/n1ppPn2/2PP4/PP3N2/1B1NQPPP/RB3RK1 b - - 4 13") - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.parse_san("c4") board = chess.Board("4k3/8/8/4Pp2/8/8/8/4K3 w - f6 0 2") - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.parse_san("f6") def test_variation_san(self): @@ -763,7 +770,7 @@ def test_variation_san(self): illegal_variation = ['d3h7', 'g8h7', 'f3h6', 'h7g8'] board = chess.Board(fen) - with self.assertRaises(ValueError) as err: + with self.assertRaises(chess.IllegalMoveError) as err: board.variation_san([chess.Move.from_uci(m) for m in illegal_variation]) message = str(err.exception) self.assertIn('illegal move', message.lower(), @@ -4018,7 +4025,7 @@ def test_parse_san(self): board.push_san("d5") # Capture is mandatory. - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.push_san("Nf3") def test_is_legal(self): @@ -4159,15 +4166,15 @@ def test_atomic_castle_with_kings_touching(self): self.assertEqual(board.fen(), "8/8/8/8/8/8/4k3/2KR3q b - - 1 1") board = chess.variant.AtomicBoard("8/8/8/8/8/8/5k2/R3K2r w Q - 0 1") - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.push_san("O-O-O") board = chess.variant.AtomicBoard("8/8/8/8/8/8/6k1/R5Kr w Q - 0 1", chess960=True) - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.push_san("O-O-O") board = chess.variant.AtomicBoard("8/8/8/8/8/8/4k3/r2RK2r w D - 0 1", chess960=True) - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.push_san("O-O-O") def test_castling_rights_explode_with_king(self): @@ -4495,7 +4502,7 @@ def test_capture_with_promotion(self): def test_illegal_drop_uci(self): board = chess.variant.CrazyhouseBoard() - with self.assertRaises(ValueError): + with self.assertRaises(chess.IllegalMoveError): board.parse_uci("N@f3") def test_crazyhouse_fen(self): From 76903846bf6e91cf2a7090be4c9c3abcec78eb80 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 15 Oct 2022 17:15:56 +0200 Subject: [PATCH 1559/1831] InvalidMoveError does not depend on the position --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 30b9a392a..20deb1b4d 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -166,7 +166,7 @@ def result(self) -> str: class InvalidMoveError(ValueError): - """Raised when the attempted move is invalid in the current position""" + """Raised when move notation is not syntactically valid""" class IllegalMoveError(ValueError): From 38ab554ff1a84c5defdde6761673600e1a259c8b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 15 Oct 2022 17:24:06 +0200 Subject: [PATCH 1560/1831] Slightly tweak wording of new exception docs --- chess/__init__.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 20deb1b4d..4dca9d590 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2985,8 +2985,8 @@ def parse_san(self, san: str) -> Move: The returned move is guaranteed to be either legal or a null move. :raises: - :exc:`ValueError` (or specifically an exception specified below) if the SAN is invalid, illegal or ambiguous. - - :exc:`InvalidMoveError` if the SAN is invalid. + :exc:`ValueError` (specifically an exception specified below) if the SAN is invalid, illegal or ambiguous. + - :exc:`InvalidMoveError` if the SAN is syntactically invalid. - :exc:`IllegalMoveError` if the SAN is illegal. - :exc:`AmbiguousMoveError` if the SAN is ambiguous. """ @@ -3070,8 +3070,8 @@ def push_san(self, san: str) -> Move: Returns the move. :raises: - :exc:`ValueError` (or specifically an exception specified below) if neither legal nor a null move. - - :exc:`InvalidMoveError` if the SAN is invalid. + :exc:`ValueError` (specifically an exception specified below) if neither legal nor a null move. + - :exc:`InvalidMoveError` if the SAN is syntactically invalid. - :exc:`IllegalMoveError` if the SAN is illegal. - :exc:`AmbiguousMoveError` if the SAN is ambiguous. """ @@ -3102,9 +3102,9 @@ def parse_uci(self, uci: str) -> Move: The returned move is guaranteed to be either legal or a null move. :raises: - :exc:`ValueError` (or specifically an exception specified below) if the move is invalid or illegal in the + :exc:`ValueError` (specifically an exception specified below) if the move is invalid or illegal in the current position (but not a null move). - - :exc:`InvalidMoveError` if the UCI is invalid. + - :exc:`InvalidMoveError` if the UCI is syntactically invalid. - :exc:`IllegalMoveError` if the UCI is illegal. """ move = Move.from_uci(uci) @@ -3127,9 +3127,9 @@ def push_uci(self, uci: str) -> Move: Returns the move. :raises: - :exc:`ValueError` (or specifically an exception specified below) if the move is invalid or illegal in the + :exc:`ValueError` (specifically an exception specified below) if the move is invalid or illegal in the current position (but not a null move). - - :exc:`InvalidMoveError` if the UCI is invalid. + - :exc:`InvalidMoveError` if the UCI is syntactically invalid. - :exc:`IllegalMoveError` if the UCI is illegal. """ move = self.parse_uci(uci) From 5fc7298a1920d175061f9dae83373330be0b1035 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 16 Oct 2022 13:06:28 +0200 Subject: [PATCH 1561/1831] Bump to Sphinx 5.3.0 --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index baa05d40d..dd8706637 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -Sphinx==5.1.1 +Sphinx==5.3.0 From f96a87c79bdc58856328507ebb9dfd139af9ab97 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 17 Oct 2022 19:45:55 +0200 Subject: [PATCH 1562/1831] Check that board matches tablebase variant (#929) --- chess/syzygy.py | 17 +++++++++-------- test.py | 7 +++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 33302ba46..0266ea422 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1585,6 +1585,15 @@ def probe_wdl_table(self, board: chess.Board) -> int: return table.probe_wdl_table(board) def probe_ab(self, board: chess.Board, alpha: int, beta: int, threats: bool = False) -> Tuple[int, int]: + # Check preconditions. + if board.uci_variant != self.variant.uci_variant: + raise KeyError(f"tablebase has been opened for {self.variant.uci_variant}, probed with: {board.uci_variant}") + if board.castling_rights: + raise KeyError(f"syzygy tables do not contain positions with castling rights: {board.fen()}") + if chess.popcount(board.occupied) > TBPIECES: + raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {chess.popcount(board.occupied)}: {board.fen()}") + + # Special case: Variant with compulsory captures. if self.variant.captures_compulsory: if board.is_variant_win(): return 2, 2 @@ -1701,14 +1710,6 @@ def probe_wdl(self, board: chess.Board) -> int: Note that probing corrupted table files is undefined behavior. """ - # Positions with castling rights are not in the tablebase. - if board.castling_rights: - raise KeyError(f"syzygy tables do not contain positions with castling rights: {board.fen()}") - - # Validate piece count. - if chess.popcount(board.occupied) > TBPIECES: - raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {chess.popcount(board.occupied)}: {board.fen()}") - # Probe. v, _ = self.probe_ab(board, -2, 2) diff --git a/test.py b/test.py index 19ac0e65e..3ed890dcb 100755 --- a/test.py +++ b/test.py @@ -3892,6 +3892,13 @@ def test_suicide_stats(self): self.assertAlmostEqual(dtz, solution["dtz"], delta=1, msg=f"Expected dtz {solution['dtz']}, got {dtz} (in l. {l + 1}, fen: {board.fen()})") + def test_antichess_kvk(self): + kvk = chess.variant.AntichessBoard("8/8/8/8/8/3K4/8/4k3 w - - 0 30") + + tables = chess.syzygy.Tablebase() + with self.assertRaises(KeyError): + tables.probe_dtz(kvk) + class NativeGaviotaTestCase(unittest.TestCase): From 13e674c13095c0e03f96b439a20e0864eb27cb60 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 17 Oct 2022 19:51:52 +0200 Subject: [PATCH 1563/1831] Use default for chess.AtomicBoard.one_king --- chess/variant.py | 1 - 1 file changed, 1 deletion(-) diff --git a/chess/variant.py b/chess/variant.py index bda312c6d..cd1670480 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -210,7 +210,6 @@ class AtomicBoard(chess.Board): tbw_magic = b"\x55\x8d\xa4\x49" tbz_magic = b"\x91\xa9\x5e\xeb" connected_kings = True - one_king = True def is_variant_end(self) -> bool: return not all(self.kings & side for side in self.occupied_co) From c6e7e4961b32a7f4ad855598ce6d7103a76a7b32 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 17 Oct 2022 19:52:09 +0200 Subject: [PATCH 1564/1831] Test Antichess KvK that cannot be resolved by search (#929) --- test.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index 3ed890dcb..4c8db196e 100755 --- a/test.py +++ b/test.py @@ -3893,12 +3893,16 @@ def test_suicide_stats(self): msg=f"Expected dtz {solution['dtz']}, got {dtz} (in l. {l + 1}, fen: {board.fen()})") def test_antichess_kvk(self): - kvk = chess.variant.AntichessBoard("8/8/8/8/8/3K4/8/4k3 w - - 0 30") + kvk = chess.variant.AntichessBoard("4k3/8/8/8/8/8/8/4K3 w - - 0 1") tables = chess.syzygy.Tablebase() with self.assertRaises(KeyError): tables.probe_dtz(kvk) + tables = chess.syzygy.Tablebase(VariantBoard=chess.variant.AntichessBoard) + with self.assertRaises(chess.syzygy.MissingTableError): + tables.probe_dtz(kvk) + class NativeGaviotaTestCase(unittest.TestCase): From 7ab1acb8880d013f5cd92257bf3f9350219101e0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 25 Oct 2022 22:01:19 +0200 Subject: [PATCH 1565/1831] Try Python 3.11 --- .github/workflows/test.yml | 8 ++++---- setup.py | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 656af180f..68ab5bb19 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft @@ -38,7 +38,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.9", "3.10"] + python-version: ["3.9", "3.11"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -55,7 +55,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - run: sudo apt-get update && sudo apt-get install -y docutils-common - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null - run: pip install -e . diff --git a/setup.py b/setup.py index cbaa70e3e..bc6a8af51 100755 --- a/setup.py +++ b/setup.py @@ -93,6 +93,7 @@ def read_description(): "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Games/Entertainment :: Board Games", "Topic :: Games/Entertainment :: Turn Based Strategy", "Topic :: Software Development :: Libraries :: Python Modules", From feb8c82b6218fc8cd46e736f9a56caf9383c0122 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 22 Nov 2022 19:07:47 +0100 Subject: [PATCH 1566/1831] PettingZoo now on https://pettingzoo.farama.org (fixes #940) --- README.rst | 62 +++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/README.rst b/README.rst index 3a6ed5209..aae81e788 100644 --- a/README.rst +++ b/README.rst @@ -300,37 +300,37 @@ Selected projects If you like, share interesting things you are using python-chess for, for example: -+------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info/ | -| :height: 64 | | -| :width: 64 | | -| :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | -+------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/maia.png?raw=true | https://maiachess.com/ | -| :height: 64 | | -| :width: 64 | | -| :target: https://maiachess.com/ | A human-like neural network chess engine | -+------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | `clente/chess `_ | -| :height: 64 | | -| :width: 64 | | -| :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | -+------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://crazyara.org/ | -| :height: 64 | | -| :width: 64 | | -| :target: https://crazyara.org/ | Deep learning for Crazyhouse | -+------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | `http://johncheetham.com `_ | -| :height: 64 | | -| :width: 64 | | -| :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | -+------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ -| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | `https://www.pettingzoo.ml `_ | -| :width: 64 | | -| :height: 64 | | -| :target: https://www.pettingzoo.ml/classic/chess | A multi-agent reinforcement learning environment | -+------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/syzygy.png?raw=true | https://syzygy-tables.info/ | +| :height: 64 | | +| :width: 64 | | +| :target: https://syzygy-tables.info/ | A website to probe Syzygy endgame tablebases | ++------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/maia.png?raw=true | https://maiachess.com/ | +| :height: 64 | | +| :width: 64 | | +| :target: https://maiachess.com/ | A human-like neural network chess engine | ++------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | `clente/chess `_ | +| :height: 64 | | +| :width: 64 | | +| :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | ++------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://crazyara.org/ | +| :height: 64 | | +| :width: 64 | | +| :target: https://crazyara.org/ | Deep learning for Crazyhouse | ++------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/jcchess.png?raw=true | `http://johncheetham.com `_ | +| :height: 64 | | +| :width: 64 | | +| :target: http://johncheetham.com/projects/jcchess/ | A GUI to play against UCI chess engines | ++------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/pettingzoo.png?raw=true | `https://pettingzoo.farama.org `_ | +| :width: 64 | | +| :height: 64 | | +| :target: https://pettingzoo.farama.org/environments/classic/chess/ | A multi-agent reinforcement learning environment | ++------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ * extensions to build engines (search and evaluation) – https://github.com/Mk-Chan/python-chess-engine-extensions * a stand-alone chess computer based on DGT board – http://www.picochess.org/ From 553506719ecc2535ca1b06962792186681307624 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 22 Nov 2022 19:56:55 +0100 Subject: [PATCH 1567/1831] Simplify SVG board fill example for Python 3.8 compat (fixes #936) --- chess/svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/svg.py b/chess/svg.py index 9474550fe..6021e2054 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -280,7 +280,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, >>> >>> chess.svg.board( ... board, - ... fill=dict.fromkeys(board.attacks(chess.E4), "#cc0000cc") | {chess.E4: "#00cc00cc"}, + ... fill=dict.fromkeys(board.attacks(chess.E4), "#cc0000cc"), ... arrows=[chess.svg.Arrow(chess.E4, chess.F6, color="#0000cccc")], ... squares=chess.SquareSet(chess.BB_DARK_SQUARES & chess.BB_FILE_B), ... size=350, From 5673479edcd225a59506a7ec9127201cdf10492c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 27 Nov 2022 10:08:44 +0100 Subject: [PATCH 1568/1831] Mention that parse_san is not strict (#931) --- chess/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 4dca9d590..c1a2978a9 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2980,7 +2980,8 @@ def parse_san(self, san: str) -> Move: algebraic notation and returns the corresponding move object. Ambiguous moves are rejected. Overspecified moves (including long - algebraic notation) are accepted. + algebraic notation) are accepted. Some common syntactical deviations + are also accepted. The returned move is guaranteed to be either legal or a null move. From b1de45e7d78532f7ed4cb7264c3a0faa2ccda508 Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Sun, 18 Dec 2022 13:28:43 +0100 Subject: [PATCH 1569/1831] Add SF 15.1 win rate model And make it the default. --- chess/engine.py | 20 +++++++++++++++++--- test.py | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 5194247f6..ad61bc580 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -44,7 +44,7 @@ try: from typing import Literal - _WdlModel = Literal["sf", "sf15", "sf14", "sf12", "lichess"] + _WdlModel = Literal["sf", "sf15.1", "sf15", "sf14", "sf12", "lichess"] except ImportError: # Before Python 3.8. _WdlModel = str # type: ignore @@ -564,7 +564,8 @@ def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: :param model: * ``sf``, the WDL model used by the latest Stockfish - (currently ``sf15``). + (currently ``sf15.1``). + * ``sf15.1``, the WDL model used by Stockfish 15.1. * ``sf15``, the WDL model used by Stockfish 15. * ``sf14``, the WDL model used by Stockfish 14. * ``sf12``, the WDL model used by Stockfish 12. @@ -628,6 +629,16 @@ def __ge__(self, other: object) -> bool: return NotImplemented +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 + 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 + x = min(4000, max(cp * NormalizeToPawnValue / 100, -4000)) + return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) + def _sf15_wins(cp: int, *, ply: int) -> int: # https://github.com/official-stockfish/Stockfish/blob/sf_15/src/uci.cpp#L200-L220 m = min(240, max(ply, 0)) / 64 @@ -678,9 +689,12 @@ def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: elif model == "sf14": wins = _sf14_wins(self.cp, ply=ply) losses = _sf14_wins(-self.cp, ply=ply) - else: + elif model == "sf15": wins = _sf15_wins(self.cp, ply=ply) losses = _sf15_wins(-self.cp, ply=ply) + else: + wins = _sf15_1_wins(self.cp, ply=ply) + losses = _sf15_1_wins(-self.cp, ply=ply) draws = 1000 - wins - losses return Wdl(wins, draws, losses) diff --git a/test.py b/test.py index 4c8db196e..9bb575802 100755 --- a/test.py +++ b/test.py @@ -2969,6 +2969,7 @@ def test_wdl_model(self): self.assertEqual(chess.engine.Cp(131).wdl(model="sf12", ply=25), chess.engine.Wdl(524, 467, 9)) 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)) @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_forced_mates(self): From beb68d3d85ee6a044a902998d314785223b2362e Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Sun, 18 Dec 2022 17:20:51 +0100 Subject: [PATCH 1570/1831] Make relative WDL consider model and ply --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index ad61bc580..a431df7da 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -469,7 +469,7 @@ def is_mate(self) -> bool: def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> PovWdl: """See :func:`~chess.engine.Score.wdl()`.""" - return PovWdl(self.relative.wdl(), self.turn) + return PovWdl(self.relative.wdl(model=model, ply=ply), self.turn) def __repr__(self) -> str: return "PovScore({!r}, {})".format(self.relative, "WHITE" if self.turn else "BLACK") From 0a2075d6438a36c8cb694e4bfa31b71f2497f693 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Dec 2022 11:54:09 +0100 Subject: [PATCH 1571/1831] Fix test suite with Stockfish 15.1 --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 9bb575802..b9be057e1 100755 --- a/test.py +++ b/test.py @@ -2997,7 +2997,7 @@ def test_sf_options(self): def test_sf_analysis(self): with chess.engine.SimpleEngine.popen_uci("stockfish", setpgrp=True, debug=True) as engine: board = chess.Board("8/6K1/1p1B1RB1/8/2Q5/2n1kP1N/3b4/4n3 w - - 0 1") - limit = chess.engine.Limit(depth=28) + limit = chess.engine.Limit(depth=40) analysis = engine.analysis(board, limit) with analysis: for info in iter(analysis.next, None): From b04275aa415f5783118feb1732ec16e468bb9c06 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 22 Dec 2022 12:27:20 +0100 Subject: [PATCH 1572/1831] Prepare 1.9.4 --- CHANGELOG.rst | 14 ++++++++++++++ chess/__init__.py | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1c68c9f34..2580c841c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,20 @@ Changelog for python-chess ========================== +New in v1.9.4 (22nd Dec 2022) +----------------------------- + +Bugfixes: + +* Fix ``PovScore.wdl()`` ignored ``model`` and ``ply`` parameters. +* ``chess.syzygy``: Check that board matches tablebase variant. + +New features: + +* Add model ``sf15.1`` for ``chess.engine.Score.wdl()``. +* Raise more specific exceptions: ``chess.IllegalMoveError``, + ``chess.AmbiguousMoveError``, and ``chess.InvalidMoveError``. + New in v1.9.3 (16th Sep 2022) ----------------------------- diff --git a/chess/__init__.py b/chess/__init__.py index c1a2978a9..883d5fbda 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.9.3" +__version__ = "1.9.4" import collections import copy From cc079b6683aa7b597530de247e08b2326941898e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 26 Dec 2022 10:40:49 +0100 Subject: [PATCH 1573/1831] Fix %eval sometimes off by one centipawn --- chess/engine.py | 14 +++++++------- chess/pgn.py | 2 +- test.py | 6 ++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index a431df7da..f319d09bf 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1538,16 +1538,16 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None builder.append("ponder") if limit.white_clock is not None: builder.append("wtime") - builder.append(str(max(1, int(limit.white_clock * 1000)))) + builder.append(str(max(1, round(limit.white_clock * 1000)))) if limit.black_clock is not None: builder.append("btime") - builder.append(str(max(1, int(limit.black_clock * 1000)))) + builder.append(str(max(1, round(limit.black_clock * 1000)))) if limit.white_inc is not None: builder.append("winc") - builder.append(str(int(limit.white_inc * 1000))) + builder.append(str(round(limit.white_inc * 1000))) if limit.black_inc is not None: builder.append("binc") - builder.append(str(int(limit.black_inc * 1000))) + builder.append(str(round(limit.black_inc * 1000))) if limit.remaining_moves is not None and int(limit.remaining_moves) > 0: builder.append("movestogo") builder.append(str(int(limit.remaining_moves))) @@ -1562,7 +1562,7 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None builder.append(str(max(1, int(limit.mate)))) if limit.time is not None: builder.append("movetime") - builder.append(str(max(1, int(limit.time * 1000)))) + builder.append(str(max(1, round(limit.time * 1000)))) if infinite: builder.append("infinite") if root_moves is not None: @@ -2160,9 +2160,9 @@ def start(self, engine: XBoardProtocol) -> None: if limit.depth is not None: engine.send_line(f"sd {max(1, int(limit.depth))}") if limit.white_clock is not None: - engine.send_line("{} {}".format("time" if board.turn else "otim", max(1, int(limit.white_clock * 100)))) + engine.send_line("{} {}".format("time" if board.turn else "otim", max(1, round(limit.white_clock * 100)))) if limit.black_clock is not None: - engine.send_line("{} {}".format("otim" if board.turn else "time", max(1, int(limit.black_clock * 100)))) + engine.send_line("{} {}".format("otim" if board.turn else "time", max(1, round(limit.black_clock * 100)))) if draw_offered and engine.features.get("draw", 1): engine.send_line("draw") diff --git a/chess/pgn.py b/chess/pgn.py index da97866c3..f802a780f 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -420,7 +420,7 @@ def eval(self) -> Optional[chess.engine.PovScore]: # who has been mated. return chess.engine.PovScore(score, turn) else: - score = chess.engine.Cp(int(float(match.group("cp")) * 100)) + score = chess.engine.Cp(round(float(match.group("cp")) * 100)) return chess.engine.PovScore(score if turn else -score, turn) diff --git a/test.py b/test.py index b9be057e1..29ea02749 100755 --- a/test.py +++ b/test.py @@ -2806,6 +2806,12 @@ def test_annotations(self): game.set_arrows([]) self.assertEqual(game.comment, "foo [%bar] baz") + def test_eval(self): + game = chess.pgn.Game() + for cp in range(199, 220): + game.set_eval(chess.engine.PovScore(chess.engine.Cp(cp), chess.WHITE)) + self.assertEqual(game.eval().white().cp, cp) + def test_float_emt(self): game = chess.pgn.Game() game.comment = "[%emt 0:00:01.234]" From 8628abbb65386f6622cf38d519209e123a654b8b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 29 Dec 2022 21:50:24 +0100 Subject: [PATCH 1574/1831] Keep misc PGN headers in insertion order --- chess/pgn.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index f802a780f..1a01b034e 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -810,11 +810,11 @@ def setup(self, board: Union[chess.Board, str]) -> None: fen = setup.fen() if fen == type(setup).starting_fen: - self.headers.pop("SetUp", None) self.headers.pop("FEN", None) + self.headers.pop("SetUp", None) else: - self.headers["SetUp"] = "1" self.headers["FEN"] = fen + self.headers["SetUp"] = "1" if type(setup).aliases[0] == "Standard" and setup.chess960: self.headers["Variant"] = "Chess960" @@ -957,7 +957,7 @@ def __iter__(self) -> Iterator[str]: if key in self._tag_roster: yield key - yield from sorted(self._others) + yield from self._others def __len__(self) -> int: return len(self._tag_roster) + len(self._others) From 6e1f435ba60536a1d36728b9309427777f2c5198 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 5 Jan 2023 20:16:10 +0100 Subject: [PATCH 1575/1831] Try Sphinx 6.x --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index dd8706637..f18b82961 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -Sphinx==5.3.0 +Sphinx==6.1.1 From b3e634d21e7b0c4262da89a766f1dd1a00a2baa2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 5 Jan 2023 20:21:27 +0100 Subject: [PATCH 1576/1831] Fix indent of :raises: lists --- chess/__init__.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 883d5fbda..e205bba8e 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2987,9 +2987,10 @@ def parse_san(self, san: str) -> Move: :raises: :exc:`ValueError` (specifically an exception specified below) if the SAN is invalid, illegal or ambiguous. - - :exc:`InvalidMoveError` if the SAN is syntactically invalid. - - :exc:`IllegalMoveError` if the SAN is illegal. - - :exc:`AmbiguousMoveError` if the SAN is ambiguous. + + - :exc:`InvalidMoveError` if the SAN is syntactically invalid. + - :exc:`IllegalMoveError` if the SAN is illegal. + - :exc:`AmbiguousMoveError` if the SAN is ambiguous. """ # Castling. try: @@ -3072,9 +3073,10 @@ def push_san(self, san: str) -> Move: :raises: :exc:`ValueError` (specifically an exception specified below) if neither legal nor a null move. - - :exc:`InvalidMoveError` if the SAN is syntactically invalid. - - :exc:`IllegalMoveError` if the SAN is illegal. - - :exc:`AmbiguousMoveError` if the SAN is ambiguous. + + - :exc:`InvalidMoveError` if the SAN is syntactically invalid. + - :exc:`IllegalMoveError` if the SAN is illegal. + - :exc:`AmbiguousMoveError` if the SAN is ambiguous. """ move = self.parse_san(san) self.push(move) @@ -3105,8 +3107,9 @@ def parse_uci(self, uci: str) -> Move: :raises: :exc:`ValueError` (specifically an exception specified below) if the move is invalid or illegal in the current position (but not a null move). - - :exc:`InvalidMoveError` if the UCI is syntactically invalid. - - :exc:`IllegalMoveError` if the UCI is illegal. + + - :exc:`InvalidMoveError` if the UCI is syntactically invalid. + - :exc:`IllegalMoveError` if the UCI is illegal. """ move = Move.from_uci(uci) @@ -3130,8 +3133,9 @@ def push_uci(self, uci: str) -> Move: :raises: :exc:`ValueError` (specifically an exception specified below) if the move is invalid or illegal in the current position (but not a null move). - - :exc:`InvalidMoveError` if the UCI is syntactically invalid. - - :exc:`IllegalMoveError` if the UCI is illegal. + + - :exc:`InvalidMoveError` if the UCI is syntactically invalid. + - :exc:`IllegalMoveError` if the UCI is illegal. """ move = self.parse_uci(uci) self.push(move) From d7c3edb0e69fe42db978982e93f0694a9e519f7b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Jan 2023 20:02:27 +0100 Subject: [PATCH 1577/1831] Close Syzygy table file descriptors after mmap --- chess/syzygy.py | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 0266ea422..28cc9c4d0 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -559,7 +559,6 @@ def __init__(self, path: str, *, variant: Type[chess.Board] = chess.Board) -> No self.write_lock = threading.RLock() self.initialized = False - self.fd: Optional[int] = None self.data: Optional[mmap.mmap] = None self.read_condition = threading.Condition() @@ -602,23 +601,29 @@ def __init__(self, path: str, *, variant: Type[chess.Board] = chess.Board) -> No self.enc_type = 1 + j def init_mmap(self) -> None: + if self.data is not None: + return + with self.write_lock: - # Open fd. - if self.fd is None: - self.fd = os.open(self.path, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) + if self.data is not None: + return + + fd = os.open(self.path, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) + try: + data = mmap.mmap(fd, 0, access=mmap.ACCESS_READ) + finally: + os.close(fd) - # Open mmap. - if self.data is None: - data = mmap.mmap(self.fd, 0, access=mmap.ACCESS_READ) - if data.size() % 64 != 16: - raise IOError(f"invalid file size: ensure {self.path!r} is a valid syzygy tablebase file") - self.data = data + if data.size() % 64 != 16: + raise IOError(f"invalid file size: ensure {self.path!r} is a valid syzygy tablebase file") - try: - # Python 3.8 - self.data.madvise(mmap.MADV_RANDOM) - except AttributeError: - pass + try: + # Python 3.8 + data.madvise(mmap.MADV_RANDOM) + except AttributeError: + pass + + self.data = data def check_magic(self, magic: Optional[bytes], pawnless_magic: Optional[bytes]) -> None: assert self.data @@ -1045,10 +1050,6 @@ def close(self) -> None: self.data.close() self.data = None - if self.fd is not None: - os.close(self.fd) - self.fd = None - def __enter__(self: TableT) -> TableT: return self From 9cb8d3ba11183713314f817f6b6ccef18d1bde88 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Jan 2023 20:05:56 +0100 Subject: [PATCH 1578/1831] Close PolyGlot file descriptors after mmap --- chess/polyglot.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/chess/polyglot.py b/chess/polyglot.py index 1562d5306..c56c5ecfb 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -337,12 +337,13 @@ class MemoryMappedReader: """Maps a Polyglot opening book to memory.""" def __init__(self, filename: PathLike) -> None: - self.fd = os.open(filename, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) - + fd = os.open(filename, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) try: - self.mmap: Union[mmap.mmap, _EmptyMmap] = mmap.mmap(self.fd, 0, access=mmap.ACCESS_READ) + self.mmap: Union[mmap.mmap, _EmptyMmap] = mmap.mmap(fd, 0, access=mmap.ACCESS_READ) except (ValueError, OSError): self.mmap = _EmptyMmap() # Workaround for empty opening books. + finally: + os.close(fd) if self.mmap.size() % ENTRY_STRUCT.size != 0: raise IOError(f"invalid file size: ensure {filename!r} is a valid polyglot opening book") @@ -514,11 +515,6 @@ def close(self) -> None: """Closes the reader.""" self.mmap.close() - try: - os.close(self.fd) - except OSError: - pass - def open_reader(path: PathLike) -> MemoryMappedReader: """ From 3fd11884ee0ae114ab243d9f66da500dff6b9bf6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Jan 2023 20:20:28 +0100 Subject: [PATCH 1579/1831] Simplify syzygy.Table.init_mmap() --- chess/syzygy.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 28cc9c4d0..4fe070c91 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -601,13 +601,7 @@ def __init__(self, path: str, *, variant: Type[chess.Board] = chess.Board) -> No self.enc_type = 1 + j def init_mmap(self) -> None: - if self.data is not None: - return - - with self.write_lock: - if self.data is not None: - return - + if self.data is None: fd = os.open(self.path, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) try: data = mmap.mmap(fd, 0, access=mmap.ACCESS_READ) From ebb7b3987715a889f18d0d65382a1f162c261901 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Jan 2023 20:56:50 +0100 Subject: [PATCH 1580/1831] Change default of Tablebase.max_fds to None This is compatible thanks to the new implementation, which does not keep open file descriptors around in any case. --- chess/syzygy.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 4fe070c91..45eb963d0 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1482,12 +1482,8 @@ def setup_pieces_pawn_dtz(self, p_data: int, p_tb_size: int, f: int) -> None: class Tablebase: """ Manages a collection of tablebase files for probing. - - If *max_fds* is not ``None``, will at most use *max_fds* open file - descriptors at any given time. The least recently used tables are closed, - if necessary. """ - def __init__(self, *, max_fds: Optional[int] = 128, VariantBoard: Type[chess.Board] = chess.Board) -> None: + def __init__(self, *, max_fds: Optional[int] = None, VariantBoard: Type[chess.Board] = chess.Board) -> None: self.variant = VariantBoard self.max_fds = max_fds @@ -1967,7 +1963,7 @@ def __exit__(self, exc_type: Optional[Type[BaseException]], exc_value: Optional[ self.close() -def open_tablebase(directory: str, *, load_wdl: bool = True, load_dtz: bool = True, max_fds: Optional[int] = 128, VariantBoard: Type[chess.Board] = chess.Board) -> Tablebase: +def open_tablebase(directory: str, *, load_wdl: bool = True, load_dtz: bool = True, max_fds: Optional[int] = None, VariantBoard: Type[chess.Board] = chess.Board) -> Tablebase: """ Opens a collection of tables for probing. See :class:`~chess.syzygy.Tablebase`. @@ -1981,6 +1977,10 @@ def open_tablebase(directory: str, *, load_wdl: bool = True, load_dtz: bool = Tr are often distributed separately, but are both required for 6-piece positions. Use :func:`~chess.syzygy.Tablebase.add_directory()` to load tables from additional directories. + + :param max_fds: If *max_fds* is not ``None``, will at most use *max_fds* + open file descriptors at any given time. The least recently used tables + are closed, if necessary. """ tables = Tablebase(max_fds=max_fds, VariantBoard=VariantBoard) tables.add_directory(directory, load_wdl=load_wdl, load_dtz=load_dtz) From 1985e6d5acce645354c5c6c8d7d65c0499715953 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 7 Jan 2023 21:09:58 +0100 Subject: [PATCH 1581/1831] Bump Sphinx to 6.1.2 --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index f18b82961..8f65fe1fd 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -Sphinx==6.1.1 +Sphinx==6.1.2 From 57fce306c93a22c00d3b91cea68c618683987df3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 20 Jan 2023 20:53:24 +0100 Subject: [PATCH 1582/1831] Add chess960.perft --- .github/workflows/test.yml | 1 + examples/perft/chess960.perft | 8641 +++++++++++++++++++++++++++++++++ 2 files changed, 8642 insertions(+) create mode 100644 examples/perft/chess960.perft diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 68ab5bb19..95e9a3728 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,6 +27,7 @@ jobs: python-version: "3.11" - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 + - run: python examples/perft/perft.py -t 1 examples/perft/chess960.perft --max-nodes 100000 - run: python examples/perft/perft.py -t 1 examples/perft/tricky.perft - run: python examples/perft/perft.py -t 1 --variant giveaway examples/perft/giveaway.perft - run: python examples/perft/perft.py -t 1 --variant atomic examples/perft/atomic.perft diff --git a/examples/perft/chess960.perft b/examples/perft/chess960.perft new file mode 100644 index 000000000..0d14d5da0 --- /dev/null +++ b/examples/perft/chess960.perft @@ -0,0 +1,8641 @@ +# https://www.chessprogramming.org/Chess960_Perft_Results + +id 1 +epd bqnb1rkr/pp3ppp/3ppn2/2p5/5P2/P2P4/NPP1P1PP/BQ1BNRKR w HFhf - 2 9 +perft 1 21 +perft 2 528 +perft 3 12189 +perft 4 326672 +perft 5 8146062 +perft 6 227689589 + +id 1 +epd 2nnrbkr/p1qppppp/8/1ppb4/6PP/3PP3/PPP2P2/BQNNRBKR w HEhe - 1 9 +perft 1 21 +perft 2 807 +perft 3 18002 +perft 4 667366 +perft 5 16253601 +perft 6 590751109 + +id 1 +epd b1q1rrkb/pppppppp/3nn3/8/P7/1PPP4/4PPPP/BQNNRKRB w GE - 1 9 +perft 1 20 +perft 2 479 +perft 3 10471 +perft 4 273318 +perft 5 6417013 +perft 6 177654692 + +id 1 +epd qbbnnrkr/2pp2pp/p7/1p2pp2/8/P3PP2/1PPP1KPP/QBBNNR1R w hf - 0 9 +perft 1 22 +perft 2 593 +perft 3 13440 +perft 4 382958 +perft 5 9183776 +perft 6 274103539 + +id 1 +epd 1nbbnrkr/p1p1ppp1/3p4/1p3P1p/3Pq2P/8/PPP1P1P1/QNBBNRKR w HFhf - 0 9 +perft 1 28 +perft 2 1120 +perft 3 31058 +perft 4 1171749 +perft 5 34030312 +perft 6 1250970898 + +id 1 +epd qnbnr1kr/ppp1b1pp/4p3/3p1p2/8/2NPP3/PPP1BPPP/QNB1R1KR w HEhe - 1 9 +perft 1 29 +perft 2 899 +perft 3 26578 +perft 4 824055 +perft 5 24851983 +perft 6 775718317 + +id 1 +epd q1bnrkr1/ppppp2p/2n2p2/4b1p1/2NP4/8/PPP1PPPP/QNB1RRKB w ge - 1 9 +perft 1 30 +perft 2 860 +perft 3 24566 +perft 4 732757 +perft 5 21093346 +perft 6 649209803 + +id 1 +epd qbn1brkr/ppp1p1p1/2n4p/3p1p2/P7/6PP/QPPPPP2/1BNNBRKR w HFhf - 0 9 +perft 1 25 +perft 2 635 +perft 3 17054 +perft 4 465806 +perft 5 13203304 +perft 6 377184252 + +id 1 +epd qnnbbrkr/1p2ppp1/2pp3p/p7/1P5P/2NP4/P1P1PPP1/Q1NBBRKR w HFhf - 0 9 +perft 1 24 +perft 2 572 +perft 3 15243 +perft 4 384260 +perft 5 11110203 +perft 6 293989890 + +id 1 +epd qn1rbbkr/ppp2p1p/1n1pp1p1/8/3P4/P6P/1PP1PPPK/QNNRBB1R w hd - 2 9 +perft 1 28 +perft 2 811 +perft 3 23175 +perft 4 679699 +perft 5 19836606 +perft 6 594527992 + +id 1 +epd qnr1bkrb/pppp2pp/3np3/5p2/8/P2P2P1/NPP1PP1P/QN1RBKRB w GDg - 3 9 +perft 1 33 +perft 2 823 +perft 3 26895 +perft 4 713420 +perft 5 23114629 +perft 6 646390782 + +id 1 +epd qb1nrkbr/1pppp1p1/1n3p2/p1B4p/8/3P1P1P/PPP1P1P1/QBNNRK1R w HEhe - 0 9 +perft 1 31 +perft 2 855 +perft 3 25620 +perft 4 735703 +perft 5 21796206 +perft 6 651054626 + +id 1 +epd qnnbrk1r/1p1ppbpp/2p5/p4p2/2NP3P/8/PPP1PPP1/Q1NBRKBR w HEhe - 0 9 +perft 1 26 +perft 2 790 +perft 3 21238 +perft 4 642367 +perft 5 17819770 +perft 6 544866674 + +id 1 +epd 1qnrkbbr/1pppppp1/p1n4p/8/P7/1P1N1P2/2PPP1PP/QN1RKBBR w HDhd - 0 9 +perft 1 37 +perft 2 883 +perft 3 32187 +perft 4 815535 +perft 5 29370838 +perft 6 783201510 + +id 1 +epd qn1rkrbb/pp1p1ppp/2p1p3/3n4/4P2P/2NP4/PPP2PP1/Q1NRKRBB w FDfd - 1 9 +perft 1 24 +perft 2 585 +perft 3 14769 +perft 4 356950 +perft 5 9482310 +perft 6 233468620 + +id 1 +epd bb1qnrkr/pp1p1pp1/1np1p3/4N2p/8/1P4P1/P1PPPP1P/BBNQ1RKR w HFhf - 0 9 +perft 1 29 +perft 2 864 +perft 3 25747 +perft 4 799727 +perft 5 24219627 +perft 6 776836316 + +id 1 +epd bnqbnr1r/p1p1ppkp/3p4/1p4p1/P7/3NP2P/1PPP1PP1/BNQB1RKR w HF - 0 9 +perft 1 26 +perft 2 889 +perft 3 24353 +perft 4 832956 +perft 5 23701014 +perft 6 809194268 + +id 1 +epd bnqnrbkr/1pp2pp1/p7/3pP2p/4P1P1/8/PPPP3P/BNQNRBKR w HEhe d6 0 9 +perft 1 31 +perft 2 984 +perft 3 28677 +perft 4 962591 +perft 5 29032175 +perft 6 1008880643 + +id 1 +epd b1qnrrkb/ppp1pp1p/n2p1Pp1/8/8/P7/1PPPP1PP/BNQNRKRB w GE - 0 9 +perft 1 20 +perft 2 484 +perft 3 10532 +perft 4 281606 +perft 5 6718715 +perft 6 193594729 + +id 1 +epd n1bqnrkr/pp1ppp1p/2p5/6p1/2P2b2/PN6/1PNPPPPP/1BBQ1RKR w HFhf - 2 9 +perft 1 23 +perft 2 732 +perft 3 17746 +perft 4 558191 +perft 5 14481581 +perft 6 457140569 + +id 1 +epd n1bb1rkr/qpnppppp/2p5/p7/P1P5/5P2/1P1PPRPP/NQBBN1KR w Hhf - 1 9 +perft 1 27 +perft 2 697 +perft 3 18724 +perft 4 505089 +perft 5 14226907 +perft 6 400942568 + +id 1 +epd nqb1rbkr/pppppp1p/4n3/6p1/4P3/1NP4P/PP1P1PP1/1QBNRBKR w HEhe - 1 9 +perft 1 28 +perft 2 641 +perft 3 18811 +perft 4 456916 +perft 5 13780398 +perft 6 354122358 + +id 1 +epd n1bnrrkb/pp1pp2p/2p2p2/6p1/5B2/3P4/PPP1PPPP/NQ1NRKRB w GE - 2 9 +perft 1 28 +perft 2 606 +perft 3 16883 +perft 4 381646 +perft 5 10815324 +perft 6 254026570 + +id 1 +epd nbqnbrkr/2ppp1p1/pp3p1p/8/4N2P/1N6/PPPPPPP1/1BQ1BRKR w HFhf - 0 9 +perft 1 26 +perft 2 626 +perft 3 17268 +perft 4 437525 +perft 5 12719546 +perft 6 339132046 + +id 1 +epd nq1bbrkr/pp2nppp/2pp4/4p3/1PP1P3/1B6/P2P1PPP/NQN1BRKR w HFhf - 2 9 +perft 1 21 +perft 2 504 +perft 3 11812 +perft 4 302230 +perft 5 7697880 +perft 6 207028745 + +id 1 +epd nqnrb1kr/2pp1ppp/1p1bp3/p1B5/5P2/3N4/PPPPP1PP/NQ1R1BKR w HDhd - 0 9 +perft 1 30 +perft 2 672 +perft 3 19307 +perft 4 465317 +perft 5 13454573 +perft 6 345445468 + +id 1 +epd nqn2krb/p1prpppp/1pbp4/7P/5P2/8/PPPPPKP1/NQNRB1RB w g - 3 9 +perft 1 21 +perft 2 461 +perft 3 10608 +perft 4 248069 +perft 5 6194124 +perft 6 152861936 + +id 1 +epd nb1n1kbr/ppp1rppp/3pq3/P3p3/8/4P3/1PPPRPPP/NBQN1KBR w Hh - 1 9 +perft 1 19 +perft 2 566 +perft 3 11786 +perft 4 358337 +perft 5 8047916 +perft 6 249171636 + +id 1 +epd nqnbrkbr/1ppppp1p/p7/6p1/6P1/P6P/1PPPPP2/NQNBRKBR w HEhe - 1 9 +perft 1 20 +perft 2 382 +perft 3 8694 +perft 4 187263 +perft 5 4708975 +perft 6 112278808 + +id 1 +epd nq1rkb1r/pp1pp1pp/1n2bp1B/2p5/8/5P1P/PPPPP1P1/NQNRKB1R w HDhd - 2 9 +perft 1 24 +perft 2 809 +perft 3 20090 +perft 4 673811 +perft 5 17647882 +perft 6 593457788 + +id 1 +epd nqnrkrb1/pppppp2/7p/4b1p1/8/PN1NP3/1PPP1PPP/1Q1RKRBB w FDfd - 1 9 +perft 1 26 +perft 2 683 +perft 3 18102 +perft 4 473911 +perft 5 13055173 +perft 6 352398011 + +id 1 +epd bb1nqrkr/1pp1ppp1/pn5p/3p4/8/P2NNP2/1PPPP1PP/BB2QRKR w HFhf - 0 9 +perft 1 29 +perft 2 695 +perft 3 21193 +perft 4 552634 +perft 5 17454857 +perft 6 483785639 + +id 1 +epd bnn1qrkr/pp1ppp1p/2p5/b3Q1p1/8/5P1P/PPPPP1P1/BNNB1RKR w HFhf - 2 9 +perft 1 44 +perft 2 920 +perft 3 35830 +perft 4 795317 +perft 5 29742670 +perft 6 702867204 + +id 1 +epd bnnqrbkr/pp1p2p1/2p1p2p/5p2/1P5P/1R6/P1PPPPP1/BNNQRBK1 w Ehe - 0 9 +perft 1 33 +perft 2 1022 +perft 3 32724 +perft 4 1024721 +perft 5 32898113 +perft 6 1047360456 + +id 1 +epd b1nqrkrb/2pppppp/p7/1P6/1n6/P4P2/1P1PP1PP/BNNQRKRB w GEge - 0 9 +perft 1 23 +perft 2 638 +perft 3 15744 +perft 4 446539 +perft 5 11735969 +perft 6 344211589 + +id 1 +epd n1bnqrkr/3ppppp/1p6/pNp1b3/2P3P1/8/PP1PPP1P/NBB1QRKR w HFhf - 1 9 +perft 1 29 +perft 2 728 +perft 3 20768 +perft 4 532084 +perft 5 15621236 +perft 6 415766465 + +id 1 +epd n2bqrkr/p1p1pppp/1pn5/3p1b2/P6P/1NP5/1P1PPPP1/1NBBQRKR w HFhf - 3 9 +perft 1 20 +perft 2 533 +perft 3 12152 +perft 4 325059 +perft 5 8088751 +perft 6 223068417 + +id 1 +epd nnbqrbkr/1pp1p1p1/p2p4/5p1p/2P1P3/N7/PPQP1PPP/N1B1RBKR w HEhe - 0 9 +perft 1 27 +perft 2 619 +perft 3 18098 +perft 4 444421 +perft 5 13755384 +perft 6 357222394 + +id 1 +epd nnbqrkr1/pp1pp2p/2p2b2/5pp1/1P5P/4P1P1/P1PP1P2/NNBQRKRB w GEge - 1 9 +perft 1 32 +perft 2 1046 +perft 3 33721 +perft 4 1111186 +perft 5 36218182 +perft 6 1202830851 + +id 1 +epd nb1qbrkr/p1pppp2/1p1n2pp/8/1P6/2PN3P/P2PPPP1/NB1QBRKR w HFhf - 0 9 +perft 1 25 +perft 2 521 +perft 3 14021 +perft 4 306427 +perft 5 8697700 +perft 6 201455191 + +id 1 +epd nnq1brkr/pp1pppp1/8/2p4P/8/5K2/PPPbPP1P/NNQBBR1R w hf - 0 9 +perft 1 23 +perft 2 724 +perft 3 18263 +perft 4 571072 +perft 5 15338230 +perft 6 484638597 + +id 1 +epd nnqrbb1r/pppppk2/5pp1/7p/1P6/3P2PP/P1P1PP2/NNQRBBKR w HD - 0 9 +perft 1 30 +perft 2 717 +perft 3 21945 +perft 4 547145 +perft 5 17166700 +perft 6 450069742 + +id 1 +epd nnqr1krb/p1p1pppp/2bp4/8/1p1P4/4P3/PPP2PPP/NNQRBKRB w GDgd - 0 9 +perft 1 25 +perft 2 873 +perft 3 20796 +perft 4 728628 +perft 5 18162741 +perft 6 641708630 + +id 1 +epd nbnqrkbr/p2ppp2/1p4p1/2p4p/3P3P/3N4/PPP1PPPR/NB1QRKB1 w Ehe - 0 9 +perft 1 24 +perft 2 589 +perft 3 15190 +perft 4 382317 +perft 5 10630667 +perft 6 279474189 + +id 1 +epd n1qbrkbr/p1ppp2p/2n2pp1/1p6/1P6/2P3P1/P2PPP1P/NNQBRKBR w HEhe - 0 9 +perft 1 22 +perft 2 592 +perft 3 14269 +perft 4 401976 +perft 5 10356818 +perft 6 301583306 + +id 1 +epd 2qrkbbr/ppn1pppp/n1p5/3p4/5P2/P1PP4/1P2P1PP/NNQRKBBR w HDhd - 1 9 +perft 1 27 +perft 2 750 +perft 3 20584 +perft 4 605458 +perft 5 16819085 +perft 6 516796736 + +id 1 +epd 1nqr1rbb/pppkp1pp/1n3p2/3p4/1P6/5P1P/P1PPPKP1/NNQR1RBB w - - 1 9 +perft 1 24 +perft 2 623 +perft 3 15921 +perft 4 429446 +perft 5 11594634 +perft 6 322745925 + +id 1 +epd bbn1rqkr/pp1pp2p/4npp1/2p5/1P6/2BPP3/P1P2PPP/1BNNRQKR w HEhe - 0 9 +perft 1 23 +perft 2 730 +perft 3 17743 +perft 4 565340 +perft 5 14496370 +perft 6 468608864 + +id 1 +epd bn1brqkr/pppp2p1/3npp2/7p/PPP5/8/3PPPPP/BNNBRQKR w HEhe - 0 9 +perft 1 25 +perft 2 673 +perft 3 17835 +perft 4 513696 +perft 5 14284338 +perft 6 434008567 + +id 1 +epd bn1rqbkr/ppp1ppp1/1n6/2p4p/7P/3P4/PPP1PPP1/BN1RQBKR w HDhd - 0 9 +perft 1 25 +perft 2 776 +perft 3 20562 +perft 4 660217 +perft 5 18486027 +perft 6 616653869 + +id 1 +epd bnnr1krb/ppp2ppp/3p4/3Bp3/q1P3PP/8/PP1PPP2/BNNRQKR1 w GDgd - 0 9 +perft 1 29 +perft 2 1040 +perft 3 30772 +perft 4 1053113 +perft 5 31801525 +perft 6 1075147725 + +id 1 +epd 1bbnrqkr/pp1ppppp/8/2p5/n7/3PNPP1/PPP1P2P/NBB1RQKR w HEhe - 1 9 +perft 1 24 +perft 2 598 +perft 3 15673 +perft 4 409766 +perft 5 11394778 +perft 6 310589129 + +id 1 +epd nnbbrqkr/p2ppp1p/1pp5/8/6p1/N1P5/PPBPPPPP/N1B1RQKR w HEhe - 0 9 +perft 1 26 +perft 2 530 +perft 3 14031 +perft 4 326312 +perft 5 8846766 +perft 6 229270702 + +id 1 +epd nnbrqbkr/2p1p1pp/p4p2/1p1p4/8/NP6/P1PPPPPP/N1BRQBKR w HDhd - 0 9 +perft 1 17 +perft 2 496 +perft 3 10220 +perft 4 303310 +perft 5 7103549 +perft 6 217108001 + +id 1 +epd nnbrqk1b/pp2pprp/2pp2p1/8/3PP1P1/8/PPP2P1P/NNBRQRKB w d - 1 9 +perft 1 33 +perft 2 820 +perft 3 27856 +perft 4 706784 +perft 5 24714401 +perft 6 645835197 + +id 1 +epd 1bnrbqkr/ppnpp1p1/2p2p1p/8/1P6/4PPP1/P1PP3P/NBNRBQKR w HDhd - 0 9 +perft 1 27 +perft 2 705 +perft 3 19760 +perft 4 548680 +perft 5 15964771 +perft 6 464662032 + +id 1 +epd n1rbbqkr/pp1pppp1/7p/P1p5/1n6/2PP4/1P2PPPP/NNRBBQKR w HChc - 0 9 +perft 1 22 +perft 2 631 +perft 3 14978 +perft 4 431801 +perft 5 10911545 +perft 6 320838556 + +id 1 +epd n1rqb1kr/p1pppp1p/1pn4b/3P2p1/P7/1P6/2P1PPPP/NNRQBBKR w HChc - 0 9 +perft 1 24 +perft 2 477 +perft 3 12506 +perft 4 263189 +perft 5 7419372 +perft 6 165945904 + +id 1 +epd nnrqbkrb/pppp1pp1/7p/4p3/6P1/2N2B2/PPPPPP1P/NR1QBKR1 w Ggc - 2 9 +perft 1 29 +perft 2 658 +perft 3 19364 +perft 4 476620 +perft 5 14233587 +perft 6 373744834 + +id 1 +epd n1nrqkbr/ppb2ppp/3pp3/2p5/2P3P1/5P2/PP1PPB1P/NBNRQK1R w HDhd - 1 9 +perft 1 32 +perft 2 801 +perft 3 25861 +perft 4 681428 +perft 5 22318948 +perft 6 619857455 + +id 1 +epd 2rbqkbr/p1pppppp/1nn5/1p6/7P/P4P2/1PPPP1PB/NNRBQK1R w HChc - 2 9 +perft 1 27 +perft 2 647 +perft 3 18030 +perft 4 458057 +perft 5 13189156 +perft 6 354689323 + +id 1 +epd nn1qkbbr/pp2ppp1/2rp4/2p4p/P2P4/1N5P/1PP1PPP1/1NRQKBBR w HCh - 1 9 +perft 1 24 +perft 2 738 +perft 3 18916 +perft 4 586009 +perft 5 16420659 +perft 6 519075930 + +id 1 +epd nnrqk1bb/p1ppp2p/5rp1/1p3p2/1P4P1/5P1P/P1PPP3/NNRQKRBB w FCc - 1 9 +perft 1 25 +perft 2 795 +perft 3 20510 +perft 4 648945 +perft 5 17342527 +perft 6 556144017 + +id 1 +epd bb1nrkqr/ppppn2p/4ppp1/8/1P4P1/4P3/P1PPKP1P/BBNNR1QR w he - 0 9 +perft 1 29 +perft 2 664 +perft 3 20024 +perft 4 498376 +perft 5 15373803 +perft 6 406016364 + +id 1 +epd bnnbrkqr/1p1ppp2/8/p1p3pp/1P6/N4P2/PBPPP1PP/2NBRKQR w HEhe - 0 9 +perft 1 31 +perft 2 770 +perft 3 24850 +perft 4 677212 +perft 5 22562080 +perft 6 662029574 + +id 1 +epd 1nnrkbqr/p1pp1ppp/4p3/1p6/1Pb1P3/6PB/P1PP1P1P/BNNRK1QR w HDhd - 0 9 +perft 1 27 +perft 2 776 +perft 3 22133 +perft 4 641002 +perft 5 19153245 +perft 6 562738257 + +id 1 +epd bnr1kqrb/pppp1pp1/1n5p/4p3/P3P3/3P2P1/1PP2P1P/BNNRKQRB w GDg - 0 9 +perft 1 26 +perft 2 624 +perft 3 16411 +perft 4 435426 +perft 5 11906515 +perft 6 338092952 + +id 1 +epd nbbnrkqr/p1ppp1pp/1p3p2/8/2P5/4P3/PP1P1PPP/NBBNRKQR w HEhe - 1 9 +perft 1 25 +perft 2 624 +perft 3 15561 +perft 4 419635 +perft 5 10817378 +perft 6 311138112 + +id 1 +epd nn1brkqr/pp1bpppp/8/2pp4/P4P2/1PN5/2PPP1PP/N1BBRKQR w HEhe - 1 9 +perft 1 23 +perft 2 659 +perft 3 16958 +perft 4 476567 +perft 5 13242252 +perft 6 373557073 + +id 1 +epd n1brkbqr/ppp1pp1p/6pB/3p4/2Pn4/8/PP2PPPP/NN1RKBQR w HDhd - 0 9 +perft 1 32 +perft 2 1026 +perft 3 30360 +perft 4 978278 +perft 5 29436320 +perft 6 957904151 + +id 1 +epd nnbrkqrb/p2ppp2/Q5pp/1pp5/4PP2/2N5/PPPP2PP/N1BRK1RB w GDgd - 0 9 +perft 1 36 +perft 2 843 +perft 3 29017 +perft 4 715537 +perft 5 24321197 +perft 6 630396940 + +id 1 +epd nbnrbk1r/pppppppq/8/7p/8/1N2QPP1/PPPPP2P/NB1RBK1R w HDhd - 2 9 +perft 1 36 +perft 2 973 +perft 3 35403 +perft 4 1018054 +perft 5 37143354 +perft 6 1124883780 + +id 1 +epd nnrbbkqr/2pppp1p/p7/6p1/1p2P3/4QPP1/PPPP3P/NNRBBK1R w HChc - 0 9 +perft 1 36 +perft 2 649 +perft 3 22524 +perft 4 489526 +perft 5 16836636 +perft 6 416139320 + +id 1 +epd nnrkbbqr/1p2pppp/p2p4/2p5/8/1N2P1P1/PPPP1P1P/1NKRBBQR w hc - 0 9 +perft 1 26 +perft 2 672 +perft 3 18136 +perft 4 477801 +perft 5 13342771 +perft 6 363074681 + +id 1 +epd n1rkbqrb/pp1ppp2/2n3p1/2p4p/P5PP/1P6/2PPPP2/NNRKBQRB w GCgc - 0 9 +perft 1 24 +perft 2 804 +perft 3 20712 +perft 4 684001 +perft 5 18761475 +perft 6 617932151 + +id 1 +epd nbkr1qbr/1pp1pppp/pn1p4/8/3P2P1/5R2/PPP1PP1P/NBN1KQBR w H - 2 9 +perft 1 30 +perft 2 627 +perft 3 18669 +perft 4 423329 +perft 5 12815016 +perft 6 312798696 + +id 1 +epd nnr1kqbr/pp1pp1p1/2p5/b4p1p/P7/1PNP4/2P1PPPP/N1RBKQBR w HChc - 1 9 +perft 1 12 +perft 2 421 +perft 3 6530 +perft 4 227044 +perft 5 4266410 +perft 6 149176979 + +id 1 +epd n1rkqbbr/p1pp1pp1/np2p2p/8/8/N4PP1/PPPPP1BP/N1RKQ1BR w HChc - 0 9 +perft 1 27 +perft 2 670 +perft 3 19119 +perft 4 494690 +perft 5 14708490 +perft 6 397268628 + +id 1 +epd nnr1qrbb/p2kpppp/1p1p4/2p5/6P1/PP1P4/2P1PP1P/NNRKQRBB w FC - 0 9 +perft 1 27 +perft 2 604 +perft 3 17043 +perft 4 409665 +perft 5 11993332 +perft 6 308518181 + +id 1 +epd bbnnrkrq/ppp1pp2/6p1/3p4/7p/7P/PPPPPPP1/BBNNRRKQ w ge - 0 9 +perft 1 20 +perft 2 559 +perft 3 12242 +perft 4 355326 +perft 5 8427161 +perft 6 252274233 + +id 1 +epd bnnbrkr1/ppp2p1p/5q2/3pp1p1/4P3/1N4P1/PPPPRP1P/BN1B1KRQ w Gge - 0 9 +perft 1 26 +perft 2 1036 +perft 3 27228 +perft 4 1028084 +perft 5 28286576 +perft 6 1042120495 + +id 1 +epd bn1rkbrq/1pppppp1/p6p/1n6/3P4/6PP/PPPRPP2/BNN1KBRQ w Ggd - 2 9 +perft 1 29 +perft 2 633 +perft 3 19278 +perft 4 455476 +perft 5 14333034 +perft 6 361900466 + +id 1 +epd b1nrkrqb/1p1npppp/p2p4/2p5/5P2/4P2P/PPPP1RP1/BNNRK1QB w Dfd - 1 9 +perft 1 25 +perft 2 475 +perft 3 12603 +perft 4 270909 +perft 5 7545536 +perft 6 179579818 + +id 1 +epd 1bbnrkrq/ppppppp1/8/7p/1n4P1/1PN5/P1PPPP1P/NBBR1KRQ w Gge - 0 9 +perft 1 30 +perft 2 803 +perft 3 25473 +perft 4 709716 +perft 5 23443854 +perft 6 686365049 + +id 1 +epd nnbbrkrq/2pp1pp1/1p5p/pP2p3/7P/N7/P1PPPPP1/N1BBRKRQ w GEge - 0 9 +perft 1 18 +perft 2 432 +perft 3 9638 +perft 4 242350 +perft 5 6131124 +perft 6 160393505 + +id 1 +epd nnbrkbrq/1pppp1p1/p7/7p/1P2Pp2/BN6/P1PP1PPP/1N1RKBRQ w GDgd - 0 9 +perft 1 27 +perft 2 482 +perft 3 13441 +perft 4 282259 +perft 5 8084701 +perft 6 193484216 + +id 1 +epd n1brkrqb/pppp3p/n3pp2/6p1/3P1P2/N1P5/PP2P1PP/N1BRKRQB w FDfd - 0 9 +perft 1 28 +perft 2 642 +perft 3 19005 +perft 4 471729 +perft 5 14529434 +perft 6 384837696 + +id 1 +epd nbnrbk2/p1pppp1p/1p3qr1/6p1/1B1P4/1N6/PPP1PPPP/1BNR1RKQ w d - 2 9 +perft 1 30 +perft 2 796 +perft 3 22780 +perft 4 687302 +perft 5 20120565 +perft 6 641832725 + +id 1 +epd nnrbbrkq/1pp2ppp/3p4/p3p3/3P1P2/1P2P3/P1P3PP/NNRBBKRQ w GC - 1 9 +perft 1 31 +perft 2 827 +perft 3 24538 +perft 4 663082 +perft 5 19979594 +perft 6 549437308 + +id 1 +epd nnrkbbrq/1pp2p1p/p2pp1p1/2P5/8/8/PP1PPPPP/NNRKBBRQ w Ggc - 0 9 +perft 1 24 +perft 2 762 +perft 3 19283 +perft 4 624598 +perft 5 16838099 +perft 6 555230555 + +id 1 +epd nnr1brqb/1ppkp1pp/8/p2p1p2/1P1P4/N1P5/P3PPPP/N1RKBRQB w FC - 1 9 +perft 1 23 +perft 2 640 +perft 3 15471 +perft 4 444905 +perft 5 11343507 +perft 6 334123513 + +id 1 +epd nbnrkrbq/2ppp2p/p4p2/1P4p1/4PP2/8/1PPP2PP/NBNRKRBQ w FDfd - 0 9 +perft 1 31 +perft 2 826 +perft 3 26137 +perft 4 732175 +perft 5 23555139 +perft 6 686250413 + +id 1 +epd 1nrbkr1q/1pppp1pp/1n6/p4p2/N1b4P/8/PPPPPPPB/N1RBKR1Q w FCfc - 2 9 +perft 1 27 +perft 2 862 +perft 3 24141 +perft 4 755171 +perft 5 22027695 +perft 6 696353497 + +id 1 +epd nnrkrbbq/pppp2pp/8/4pp2/4P3/P7/1PPPBPPP/NNKRR1BQ w c - 0 9 +perft 1 25 +perft 2 792 +perft 3 19883 +perft 4 636041 +perft 5 16473376 +perft 6 532214177 + +id 1 +epd n1rk1qbb/pppprpp1/2n4p/4p3/2PP3P/8/PP2PPP1/NNRKRQBB w ECc - 1 9 +perft 1 25 +perft 2 622 +perft 3 16031 +perft 4 425247 +perft 5 11420973 +perft 6 321855685 + +id 1 +epd bbq1rnkr/pnp1pp1p/1p1p4/6p1/2P5/2Q1P2P/PP1P1PP1/BB1NRNKR w HEhe - 2 9 +perft 1 36 +perft 2 870 +perft 3 30516 +perft 4 811047 +perft 5 28127620 +perft 6 799738334 + +id 1 +epd bq1brnkr/1p1ppp1p/1np5/p5p1/8/1N5P/PPPPPPP1/BQ1BRNKR w HEhe - 0 9 +perft 1 22 +perft 2 588 +perft 3 13524 +perft 4 380068 +perft 5 9359618 +perft 6 273795898 + +id 1 +epd bq1rn1kr/1pppppbp/Nn4p1/8/8/P7/1PPPPPPP/BQ1RNBKR w HDhd - 1 9 +perft 1 24 +perft 2 711 +perft 3 18197 +perft 4 542570 +perft 5 14692779 +perft 6 445827351 + +id 1 +epd bqnr1kr1/pppppp1p/6p1/5n2/4B3/3N2PP/PbPPPP2/BQNR1KR1 w GDgd - 2 9 +perft 1 31 +perft 2 1132 +perft 3 36559 +perft 4 1261476 +perft 5 43256823 +perft 6 1456721391 + +id 1 +epd qbb1rnkr/ppp3pp/4n3/3ppp2/1P3PP1/8/P1PPPN1P/QBB1RNKR w HEhe - 0 9 +perft 1 28 +perft 2 696 +perft 3 20502 +perft 4 541886 +perft 5 16492398 +perft 6 456983120 + +id 1 +epd qnbbr1kr/pp1ppp1p/4n3/6p1/2p3P1/2PP1P2/PP2P2P/QNBBRNKR w HEhe - 0 9 +perft 1 25 +perft 2 655 +perft 3 16520 +perft 4 450189 +perft 5 11767038 +perft 6 335414976 + +id 1 +epd 1nbrnbkr/p1ppp1pp/1p6/5p2/4q1PP/3P4/PPP1PP2/QNBRNBKR w HDhd - 1 9 +perft 1 30 +perft 2 1162 +perft 3 33199 +perft 4 1217278 +perft 5 36048727 +perft 6 1290346802 + +id 1 +epd q1brnkrb/p1pppppp/n7/1p6/P7/3P1P2/QPP1P1PP/1NBRNKRB w GDgd - 0 9 +perft 1 32 +perft 2 827 +perft 3 26106 +perft 4 718243 +perft 5 23143989 +perft 6 673147648 + +id 1 +epd qbnrb1kr/ppp1pp1p/3p4/2n3p1/1P6/6N1/P1PPPPPP/QBNRB1KR w HDhd - 2 9 +perft 1 29 +perft 2 751 +perft 3 23132 +perft 4 610397 +perft 5 19555214 +perft 6 530475036 + +id 1 +epd q1rbbnkr/pppp1p2/2n3pp/2P1p3/3P4/8/PP1NPPPP/Q1RBBNKR w HChc - 2 9 +perft 1 29 +perft 2 806 +perft 3 24540 +perft 4 687251 +perft 5 21694330 +perft 6 619907316 + +id 1 +epd q1r1bbkr/pnpp1ppp/2n1p3/1p6/2P2P2/2N1N3/PP1PP1PP/Q1R1BBKR w HChc - 2 9 +perft 1 32 +perft 2 1017 +perft 3 32098 +perft 4 986028 +perft 5 31204371 +perft 6 958455898 + +id 1 +epd 2rnbkrb/pqppppp1/1pn5/7p/2P5/P1R5/QP1PPPPP/1N1NBKRB w Ggc - 4 9 +perft 1 26 +perft 2 625 +perft 3 16506 +perft 4 434635 +perft 5 11856964 +perft 6 336672890 + +id 1 +epd qbnr1kbr/p2ppppp/2p5/1p6/4n2P/P4N2/1PPP1PP1/QBNR1KBR w HDhd - 0 9 +perft 1 27 +perft 2 885 +perft 3 23828 +perft 4 767273 +perft 5 21855658 +perft 6 706272554 + +id 1 +epd qnrbnk1r/pp1pp2p/5p2/2pbP1p1/3P4/1P6/P1P2PPP/QNRBNKBR w HChc - 0 9 +perft 1 26 +perft 2 954 +perft 3 24832 +perft 4 892456 +perft 5 24415089 +perft 6 866744329 + +id 1 +epd qnrnk1br/p1p2ppp/8/1pbpp3/8/PP2N3/1QPPPPPP/1NR1KBBR w HChc - 0 9 +perft 1 26 +perft 2 783 +perft 3 20828 +perft 4 634267 +perft 5 17477825 +perft 6 539674275 + +id 1 +epd qnrnkrbb/Bpppp2p/6p1/5p2/5P2/3PP3/PPP3PP/QNRNKR1B w FCfc - 1 9 +perft 1 28 +perft 2 908 +perft 3 25730 +perft 4 861240 +perft 5 25251641 +perft 6 869525254 + +id 1 +epd bbnqrn1r/ppppp2k/5p2/6pp/7P/1QP5/PP1PPPP1/B1N1RNKR w HE - 0 9 +perft 1 33 +perft 2 643 +perft 3 21790 +perft 4 487109 +perft 5 16693640 +perft 6 410115900 + +id 1 +epd b1qbrnkr/ppp1pp2/2np4/6pp/4P3/2N4P/PPPP1PP1/BQ1BRNKR w HEhe - 0 9 +perft 1 28 +perft 2 837 +perft 3 24253 +perft 4 745617 +perft 5 22197063 +perft 6 696399065 + +id 1 +epd bnqr1bkr/pp1ppppp/2p5/4N3/5P2/P7/1PPPPnPP/BNQR1BKR w HDhd - 3 9 +perft 1 25 +perft 2 579 +perft 3 13909 +perft 4 341444 +perft 5 8601011 +perft 6 225530258 + +id 1 +epd b1qr1krb/pp1ppppp/n2n4/8/2p5/2P3P1/PP1PPP1P/BNQRNKRB w GDgd - 0 9 +perft 1 28 +perft 2 707 +perft 3 19721 +perft 4 549506 +perft 5 15583376 +perft 6 468399900 + +id 1 +epd nbbqr1kr/1pppp1pp/8/p1n2p2/4P3/PN6/1PPPQPPP/1BB1RNKR w HEhe - 0 9 +perft 1 30 +perft 2 745 +perft 3 23416 +perft 4 597858 +perft 5 19478789 +perft 6 515473678 + +id 1 +epd nqbbrn1r/p1pppp1k/1p4p1/7p/4P3/1R3B2/PPPP1PPP/NQB2NKR w H - 0 9 +perft 1 24 +perft 2 504 +perft 3 13512 +perft 4 317355 +perft 5 9002073 +perft 6 228726497 + +id 1 +epd nqbr1bkr/p1p1ppp1/1p1n4/3pN2p/1P6/8/P1PPPPPP/NQBR1BKR w HDhd - 0 9 +perft 1 29 +perft 2 898 +perft 3 26532 +perft 4 809605 +perft 5 24703467 +perft 6 757166494 + +id 1 +epd nqbrn1rb/pppp1kp1/5p1p/4p3/P4B2/3P2P1/1PP1PP1P/NQ1RNKRB w GD - 0 9 +perft 1 34 +perft 2 671 +perft 3 22332 +perft 4 473110 +perft 5 15556806 +perft 6 353235120 + +id 1 +epd nb1r1nkr/ppp1ppp1/2bp4/7p/3P2qP/P6R/1PP1PPP1/NBQRBNK1 w Dhd - 1 9 +perft 1 38 +perft 2 1691 +perft 3 60060 +perft 4 2526992 +perft 5 88557078 +perft 6 3589649998 + +id 1 +epd n1rbbnkr/1p1pp1pp/p7/2p1qp2/1B3P2/3P4/PPP1P1PP/NQRB1NKR w HChc - 0 9 +perft 1 24 +perft 2 913 +perft 3 21595 +perft 4 807544 +perft 5 19866918 +perft 6 737239330 + +id 1 +epd nqrnbbkr/p2p1p1p/1pp5/1B2p1p1/1P3P2/4P3/P1PP2PP/NQRNB1KR w HChc - 0 9 +perft 1 33 +perft 2 913 +perft 3 30159 +perft 4 843874 +perft 5 28053260 +perft 6 804687975 + +id 1 +epd nqr1bkrb/ppp1pp2/2np2p1/P6p/8/2P4P/1P1PPPP1/NQRNBKRB w GCgc - 0 9 +perft 1 24 +perft 2 623 +perft 3 16569 +perft 4 442531 +perft 5 12681936 +perft 6 351623879 + +id 1 +epd nb1rnkbr/pqppppp1/1p5p/8/1PP4P/8/P2PPPP1/NBQRNKBR w HDhd - 1 9 +perft 1 31 +perft 2 798 +perft 3 24862 +perft 4 694386 +perft 5 22616076 +perft 6 666227466 + +id 1 +epd nqrbnkbr/2p1p1pp/3p4/pp3p2/6PP/3P1N2/PPP1PP2/NQRB1KBR w HChc - 0 9 +perft 1 24 +perft 2 590 +perft 3 14409 +perft 4 383690 +perft 5 9698432 +perft 6 274064911 + +id 1 +epd nqrnkbbr/pp1p1p1p/4p1p1/1p6/8/5P1P/P1PPP1P1/NQRNKBBR w HChc - 0 9 +perft 1 30 +perft 2 1032 +perft 3 31481 +perft 4 1098116 +perft 5 34914919 +perft 6 1233362066 + +id 1 +epd nqrnkrbb/p2ppppp/1p6/2p5/2P3P1/5P2/PP1PPN1P/NQR1KRBB w FCfc - 1 9 +perft 1 30 +perft 2 775 +perft 3 23958 +perft 4 668000 +perft 5 21141738 +perft 6 621142773 + +id 1 +epd bbnrqrk1/pp2pppp/4n3/2pp4/P7/1N5P/BPPPPPP1/B2RQNKR w HD - 2 9 +perft 1 23 +perft 2 708 +perft 3 17164 +perft 4 554089 +perft 5 14343443 +perft 6 481405144 + +id 1 +epd bnr1qnkr/p1pp1p1p/1p4p1/4p1b1/2P1P3/1P6/PB1P1PPP/1NRBQNKR w HChc - 1 9 +perft 1 30 +perft 2 931 +perft 3 29249 +perft 4 921746 +perft 5 30026687 +perft 6 968109774 + +id 1 +epd b1rqnbkr/ppp1ppp1/3p3p/2n5/P3P3/2NP4/1PP2PPP/B1RQNBKR w HChc - 0 9 +perft 1 24 +perft 2 596 +perft 3 15533 +perft 4 396123 +perft 5 11099382 +perft 6 294180723 + +id 1 +epd bnrqnr1b/pp1pkppp/2p1p3/P7/2P5/7P/1P1PPPP1/BNRQNKRB w GC - 0 9 +perft 1 24 +perft 2 572 +perft 3 15293 +perft 4 390903 +perft 5 11208688 +perft 6 302955778 + +id 1 +epd n1brq1kr/bppppppp/p7/8/4P1Pn/8/PPPP1P2/NBBRQNKR w HDhd - 0 9 +perft 1 20 +perft 2 570 +perft 3 13139 +perft 4 371247 +perft 5 9919113 +perft 6 284592289 + +id 1 +epd 1rbbqnkr/ppn1ppp1/3p3p/2p5/3P4/1N4P1/PPPBPP1P/1R1BQNKR w HBhb - 0 9 +perft 1 29 +perft 2 1009 +perft 3 29547 +perft 4 1040816 +perft 5 31059587 +perft 6 1111986835 + +id 1 +epd nrbq2kr/ppppppb1/5n1p/5Pp1/8/P5P1/1PPPP2P/NRBQNBKR w HBhb - 1 9 +perft 1 20 +perft 2 520 +perft 3 11745 +perft 4 316332 +perft 5 7809837 +perft 6 216997152 + +id 1 +epd nrb1nkrb/pp3ppp/1qBpp3/2p5/8/P5P1/1PPPPP1P/NRBQNKR1 w GBgb - 2 9 +perft 1 32 +perft 2 850 +perft 3 25642 +perft 4 734088 +perft 5 21981567 +perft 6 664886187 + +id 1 +epd 1br1bnkr/ppqppp1p/1np3p1/8/1PP4P/4N3/P2PPPP1/NBRQB1KR w HChc - 1 9 +perft 1 32 +perft 2 798 +perft 3 24765 +perft 4 691488 +perft 5 22076141 +perft 6 670296871 + +id 1 +epd nrqbb1kr/1p1pp1pp/2p3n1/p4p2/3PP3/P5N1/1PP2PPP/NRQBB1KR w HBhb - 0 9 +perft 1 32 +perft 2 791 +perft 3 26213 +perft 4 684890 +perft 5 23239122 +perft 6 634260266 + +id 1 +epd nrqn1bkr/ppppp1pp/4b3/8/4P1p1/5P2/PPPP3P/NRQNBBKR w HBhb - 0 9 +perft 1 29 +perft 2 687 +perft 3 20223 +perft 4 506088 +perft 5 15236287 +perft 6 398759980 + +id 1 +epd nrqnbrkb/pppp1p2/4p2p/3B2p1/8/1P4P1/PQPPPP1P/NR1NBKR1 w GB - 0 9 +perft 1 37 +perft 2 764 +perft 3 27073 +perft 4 610950 +perft 5 21284835 +perft 6 514864869 + +id 1 +epd nbrq1kbr/Bp3ppp/2pnp3/3p4/5P2/2P4P/PP1PP1P1/NBRQNK1R w HChc - 0 9 +perft 1 40 +perft 2 1271 +perft 3 48022 +perft 4 1547741 +perft 5 56588117 +perft 6 1850696281 + +id 1 +epd nrqbnkbr/1p2ppp1/p1p4p/3p4/1P6/8/PQPPPPPP/1RNBNKBR w HBhb - 0 9 +perft 1 28 +perft 2 757 +perft 3 23135 +perft 4 668025 +perft 5 21427496 +perft 6 650939962 + +id 1 +epd nrqn1bbr/2ppkppp/4p3/pB6/8/2P1P3/PP1P1PPP/NRQNK1BR w HB - 1 9 +perft 1 27 +perft 2 642 +perft 3 17096 +perft 4 442653 +perft 5 11872805 +perft 6 327545120 + +id 1 +epd nrqnkrb1/p1ppp2p/1p4p1/4bp2/4PP1P/4N3/PPPP2P1/NRQ1KRBB w FBfb - 1 9 +perft 1 27 +perft 2 958 +perft 3 27397 +perft 4 960350 +perft 5 28520172 +perft 6 995356563 + +id 1 +epd 1bnrnqkr/pbpp2pp/8/1p2pp2/P6P/3P1N2/1PP1PPP1/BBNR1QKR w HDhd - 0 9 +perft 1 27 +perft 2 859 +perft 3 23475 +perft 4 773232 +perft 5 21581178 +perft 6 732696327 + +id 1 +epd b1rbnqkr/1pp1ppp1/2n4p/p2p4/5P2/1PBP4/P1P1P1PP/1NRBNQKR w HChc - 0 9 +perft 1 26 +perft 2 545 +perft 3 14817 +perft 4 336470 +perft 5 9537260 +perft 6 233549184 + +id 1 +epd 1nrnqbkr/p1pppppp/1p6/8/2b2P2/P1N5/1PP1P1PP/BNR1QBKR w HChc - 2 9 +perft 1 24 +perft 2 668 +perft 3 17716 +perft 4 494866 +perft 5 14216070 +perft 6 406225409 + +id 1 +epd 1nrnqkrb/2ppp1pp/p7/1p3p2/5P2/N5K1/PPPPP2P/B1RNQ1RB w gc - 0 9 +perft 1 33 +perft 2 725 +perft 3 23572 +perft 4 559823 +perft 5 18547476 +perft 6 471443091 + +id 1 +epd nbbr1qkr/p1pppppp/8/1p1n4/3P4/1N3PP1/PPP1P2P/1BBRNQKR w HDhd - 1 9 +perft 1 28 +perft 2 698 +perft 3 20527 +perft 4 539625 +perft 5 16555068 +perft 6 458045505 + +id 1 +epd 1rbbnqkr/1pnppp1p/p5p1/2p5/2P4P/5P2/PP1PP1PR/NRBBNQK1 w Bhb - 1 9 +perft 1 24 +perft 2 554 +perft 3 14221 +perft 4 362516 +perft 5 9863080 +perft 6 269284081 + +id 1 +epd nrb1qbkr/2pppppp/2n5/p7/2p5/4P3/PPNP1PPP/1RBNQBKR w HBhb - 0 9 +perft 1 23 +perft 2 618 +perft 3 15572 +perft 4 443718 +perft 5 12044358 +perft 6 360311412 + +id 1 +epd nrb1qkrb/2ppppp1/p3n3/1p1B3p/2P5/6P1/PP1PPPRP/NRBNQK2 w Bgb - 2 9 +perft 1 27 +perft 2 593 +perft 3 16770 +perft 4 401967 +perft 5 11806808 +perft 6 303338935 + +id 1 +epd nbrn1qkr/ppp1pp2/3p2p1/3Q3P/b7/8/PPPPPP1P/NBRNB1KR w HChc - 2 9 +perft 1 39 +perft 2 1056 +perft 3 40157 +perft 4 1133446 +perft 5 42201531 +perft 6 1239888683 + +id 1 +epd nr1bbqkr/pp1pp2p/1n3pp1/2p5/8/1P4P1/P1PPPPQP/NRNBBK1R w hb - 0 9 +perft 1 25 +perft 2 585 +perft 3 15719 +perft 4 406544 +perft 5 11582539 +perft 6 320997679 + +id 1 +epd nr2bbkr/ppp1pppp/1n1p4/8/6PP/1NP4q/PP1PPP2/1RNQBBKR w HBhb - 1 9 +perft 1 22 +perft 2 742 +perft 3 15984 +perft 4 545231 +perft 5 13287051 +perft 6 457010195 + +id 1 +epd 1rnqbkrb/ppp1p1p1/1n3p2/3p3p/P6P/4P3/1PPP1PP1/NRNQBRKB w gb - 0 9 +perft 1 22 +perft 2 574 +perft 3 14044 +perft 4 379648 +perft 5 9968830 +perft 6 281344367 + +id 1 +epd nb1rqkbr/1pppp1pp/4n3/p4p2/6PP/5P2/PPPPPN2/NBR1QKBR w HCh - 0 9 +perft 1 25 +perft 2 621 +perft 3 16789 +perft 4 462600 +perft 5 13378840 +perft 6 396575613 + +id 1 +epd nrnbqkbr/2pp2pp/4pp2/pp6/8/1P3P2/P1PPPBPP/NRNBQ1KR w hb - 0 9 +perft 1 25 +perft 2 656 +perft 3 16951 +perft 4 466493 +perft 5 12525939 +perft 6 358763789 + +id 1 +epd nrnqkbbr/ppppp1p1/7p/5p2/8/P4PP1/NPPPP2P/NR1QKBBR w HBhb - 0 9 +perft 1 28 +perft 2 723 +perft 3 20621 +perft 4 547522 +perft 5 15952533 +perft 6 439046803 + +id 1 +epd 1rnqkr1b/ppppp2p/1n3pp1/8/2P3P1/Pb1N4/1P1PPP1P/NR1QKRBB w FBfb - 0 9 +perft 1 26 +perft 2 713 +perft 3 19671 +perft 4 548875 +perft 5 15865528 +perft 6 454532806 + +id 1 +epd bbnrnkqr/1pppp1pp/5p2/p7/7P/1P6/PBPPPPPR/1BNRNKQ1 w D - 2 9 +perft 1 26 +perft 2 649 +perft 3 17834 +perft 4 502279 +perft 5 14375839 +perft 6 435585252 + +id 1 +epd bnrbk1qr/1ppp1ppp/p2np3/8/P7/2N2P2/1PPPP1PP/B1RBNKQR w HC - 0 9 +perft 1 26 +perft 2 621 +perft 3 17569 +perft 4 451452 +perft 5 13514201 +perft 6 364421088 + +id 1 +epd br1nkbqr/ppppppp1/8/n6p/8/N1P2PP1/PP1PP2P/B1RNKBQR w HCh - 1 9 +perft 1 29 +perft 2 664 +perft 3 20182 +perft 4 512316 +perft 5 16125924 +perft 6 442508159 + +id 1 +epd bnr1kqrb/pp1pppp1/2n5/2p5/1P4Pp/4N3/P1PPPP1P/BNKR1QRB w gc - 0 9 +perft 1 36 +perft 2 888 +perft 3 31630 +perft 4 789863 +perft 5 27792175 +perft 6 719015345 + +id 1 +epd 1bbrnkqr/pp1p1ppp/2p1p3/1n6/5P2/3Q4/PPPPP1PP/NBBRNK1R w HDhd - 2 9 +perft 1 36 +perft 2 891 +perft 3 31075 +perft 4 781792 +perft 5 26998966 +perft 6 702903862 + +id 1 +epd nrbbnk1r/pp2pppq/8/2pp3p/3P2P1/1N6/PPP1PP1P/1RBBNKQR w HBhb - 0 9 +perft 1 29 +perft 2 1036 +perft 3 31344 +perft 4 1139166 +perft 5 35627310 +perft 6 1310683359 + +id 1 +epd nr1nkbqr/ppp3pp/5p2/3pp3/6b1/3PP3/PPP2PPP/NRBNKBQR w hb - 0 9 +perft 1 18 +perft 2 664 +perft 3 13306 +perft 4 483892 +perft 5 10658989 +perft 6 386307449 + +id 1 +epd nrbnk1rb/ppp1pq1p/3p4/5pp1/2P1P3/1N6/PP1PKPPP/1RBN1QRB w gb - 2 9 +perft 1 25 +perft 2 966 +perft 3 24026 +perft 4 920345 +perft 5 23957242 +perft 6 913710194 + +id 1 +epd 1brnbkqr/pppppp2/6p1/7p/1Pn5/P1NP4/2P1PPPP/NBR1BKQR w HChc - 0 9 +perft 1 22 +perft 2 627 +perft 3 13760 +perft 4 395829 +perft 5 9627826 +perft 6 285900573 + +id 1 +epd nrnbbk1r/p1pppppq/8/7p/1p6/P5PP/1PPPPPQ1/NRNBBK1R w HBhb - 2 9 +perft 1 29 +perft 2 888 +perft 3 26742 +perft 4 874270 +perft 5 27229468 +perft 6 930799376 + +id 1 +epd n1nkb1qr/prppppbp/6p1/1p6/2P2P2/P7/1P1PP1PP/NRNKBBQR w HBh - 1 9 +perft 1 29 +perft 2 804 +perft 3 24701 +perft 4 688520 +perft 5 21952444 +perft 6 623156747 + +id 1 +epd nr2bqrb/ppkpp1pp/1np5/5p1P/5P2/2P5/PP1PP1P1/NRNKBQRB w GB - 0 9 +perft 1 22 +perft 2 530 +perft 3 13055 +perft 4 347657 +perft 5 9244693 +perft 6 264088392 + +id 1 +epd nbr1kqbr/p3pppp/2ppn3/1p4P1/4P3/1P6/P1PP1P1P/NBRNKQBR w HChc - 1 9 +perft 1 23 +perft 2 555 +perft 3 14291 +perft 4 350917 +perft 5 9692630 +perft 6 247479180 + +id 1 +epd nr1bkqbr/1p1pp1pp/pnp2p2/8/6P1/P1PP4/1P2PP1P/NRNBKQBR w HBhb - 0 9 +perft 1 22 +perft 2 565 +perft 3 13343 +perft 4 365663 +perft 5 9305533 +perft 6 268612479 + +id 1 +epd nr1kqbbr/np2pppp/p1p5/1B1p1P2/8/4P3/PPPP2PP/NRNKQ1BR w HBhb - 0 9 +perft 1 32 +perft 2 730 +perft 3 23391 +perft 4 556995 +perft 5 18103280 +perft 6 454569900 + +id 1 +epd nrnk1rbb/p1p2ppp/3pq3/Qp2p3/1P1P4/8/P1P1PPPP/NRN1KRBB w fb - 2 9 +perft 1 28 +perft 2 873 +perft 3 25683 +perft 4 791823 +perft 5 23868737 +perft 6 747991356 + +id 1 +epd bbnrnkrq/pp1ppp1p/6p1/2p5/6P1/P5RP/1PPPPP2/BBNRNK1Q w Dgd - 3 9 +perft 1 37 +perft 2 1260 +perft 3 45060 +perft 4 1542086 +perft 5 54843403 +perft 6 1898432768 + +id 1 +epd bnrb1rkq/ppnpppp1/3Q4/2p4p/7P/N7/PPPPPPP1/B1RBNKR1 w GC - 2 9 +perft 1 38 +perft 2 878 +perft 3 31944 +perft 4 800440 +perft 5 28784300 +perft 6 784569826 + +id 1 +epd bnrnkbrq/p1ppppp1/1p5p/8/P2PP3/5P2/1PP3PP/BNRNKBRQ w GCgc - 1 9 +perft 1 26 +perft 2 617 +perft 3 16992 +perft 4 419099 +perft 5 11965544 +perft 6 311309576 + +id 1 +epd bnrnkrqb/pp2p2p/2pp1pp1/8/P7/2PP1P2/1P2P1PP/BNRNKRQB w FCfc - 0 9 +perft 1 26 +perft 2 721 +perft 3 19726 +perft 4 560824 +perft 5 15966934 +perft 6 467132503 + +id 1 +epd nbbrnkr1/1pppp1p1/p6q/P4p1p/8/5P2/1PPPP1PP/NBBRNRKQ w gd - 2 9 +perft 1 18 +perft 2 556 +perft 3 10484 +perft 4 316634 +perft 5 6629293 +perft 6 202528241 + +id 1 +epd nrb1nkrq/2pp1ppp/p4b2/1p2p3/P4B2/3P4/1PP1PPPP/NR1BNRKQ w gb - 0 9 +perft 1 24 +perft 2 562 +perft 3 14017 +perft 4 355433 +perft 5 9227883 +perft 6 247634489 + +id 1 +epd nrbnkbrq/p3p1pp/1p6/2pp1P2/8/3PP3/PPP2P1P/NRBNKBRQ w GBgb - 0 9 +perft 1 31 +perft 2 746 +perft 3 24819 +perft 4 608523 +perft 5 21019301 +perft 6 542954168 + +id 1 +epd nrbnkrqb/pppp1p1p/4p1p1/8/7P/2P1P3/PPNP1PP1/1RBNKRQB w FBfb - 0 9 +perft 1 20 +perft 2 459 +perft 3 9998 +perft 4 242762 +perft 5 5760165 +perft 6 146614723 + +id 1 +epd nbrn1krq/ppp1p2p/6b1/3p1pp1/8/4N1PP/PPPPPP2/NBR1BRKQ w gc - 1 9 +perft 1 27 +perft 2 835 +perft 3 23632 +perft 4 766397 +perft 5 22667987 +perft 6 760795567 + +id 1 +epd nrnbbkrq/p1pp2pp/5p2/1p6/2P1pP1B/1P6/P2PP1PP/NRNB1KRQ w GBgb - 0 9 +perft 1 24 +perft 2 646 +perft 3 16102 +perft 4 444472 +perft 5 11489727 +perft 6 324948755 + +id 1 +epd nrn1bbrq/1ppkppp1/p2p3p/8/1P3N2/4P3/P1PP1PPP/NR1KBBRQ w GB - 2 9 +perft 1 32 +perft 2 591 +perft 3 18722 +perft 4 381683 +perft 5 12069159 +perft 6 269922838 + +id 1 +epd n1krbrqb/1ppppppp/p7/8/4n3/P4P1P/1PPPPQP1/NRNKBR1B w FB - 2 9 +perft 1 26 +perft 2 639 +perft 3 16988 +perft 4 417190 +perft 5 12167153 +perft 6 312633873 + +id 1 +epd n1rnkrbq/1p1ppp1p/8/p1p1b1p1/3PQ1P1/4N3/PPP1PP1P/NBR1KRB1 w FCfc - 0 9 +perft 1 35 +perft 2 1027 +perft 3 35731 +perft 4 1040417 +perft 5 35738410 +perft 6 1060661628 + +id 1 +epd nrnbkrbq/2pp1pp1/pp6/4p2p/P7/5PPP/1PPPP3/NRNBKRBQ w FBfb - 0 9 +perft 1 26 +perft 2 628 +perft 3 16731 +perft 4 436075 +perft 5 11920087 +perft 6 331498921 + +id 1 +epd 1rnkrbbq/pp1p2pp/1n3p2/1Bp1p3/1P6/1N2P3/P1PP1PPP/1RNKR1BQ w EBeb - 0 9 +perft 1 33 +perft 2 992 +perft 3 32244 +perft 4 983481 +perft 5 31703749 +perft 6 980306735 + +id 1 +epd nr1krqbb/p1ppppp1/8/1p5p/1Pn5/5P2/P1PPP1PP/NRNKRQBB w EBeb - 0 9 +perft 1 24 +perft 2 670 +perft 3 15985 +perft 4 445492 +perft 5 11371067 +perft 6 325556465 + +id 1 +epd bbq1rkr1/1ppppppp/p1n2n2/8/2P2P2/1P6/PQ1PP1PP/BB1NRKNR w HEe - 3 9 +perft 1 32 +perft 2 794 +perft 3 26846 +perft 4 689334 +perft 5 24085223 +perft 6 645633370 + +id 1 +epd b1nbrknr/1qppp1pp/p4p2/1p6/6P1/P2NP3/1PPP1P1P/BQ1BRKNR w HEhe - 1 9 +perft 1 25 +perft 2 663 +perft 3 17138 +perft 4 482994 +perft 5 13157826 +perft 6 389603029 + +id 1 +epd bqnrk1nr/pp2ppbp/6p1/2pp4/2P5/5P2/PPQPP1PP/B1NRKBNR w HDhd - 0 9 +perft 1 26 +perft 2 850 +perft 3 22876 +perft 4 759768 +perft 5 21341087 +perft 6 719712622 + +id 1 +epd bqnrknrb/1ppp1p1p/p7/6p1/1P2p3/P1PN4/3PPPPP/BQ1RKNRB w GDgd - 0 9 +perft 1 25 +perft 2 721 +perft 3 19290 +perft 4 581913 +perft 5 16391601 +perft 6 511725087 + +id 1 +epd q1b1rknr/pp1pppp1/4n2p/2p1b3/1PP5/4P3/PQ1P1PPP/1BBNRKNR w HEhe - 1 9 +perft 1 32 +perft 2 975 +perft 3 32566 +perft 4 955493 +perft 5 32649943 +perft 6 962536105 + +id 1 +epd qnbbrknr/1p1ppppp/8/p1p5/5P2/PP1P4/2P1P1PP/QNBBRKNR w HEhe - 0 9 +perft 1 27 +perft 2 573 +perft 3 16331 +perft 4 391656 +perft 5 11562434 +perft 6 301166330 + +id 1 +epd q1brkb1r/p1pppppp/np3B2/8/6n1/1P5N/P1PPPPPP/QN1RKB1R w HDhd - 0 9 +perft 1 32 +perft 2 984 +perft 3 31549 +perft 4 1007217 +perft 5 32597704 +perft 6 1075429389 + +id 1 +epd qn1rk1rb/p1pppppp/1p2n3/8/2b5/4NPP1/PPPPP1RP/QNBRK2B w Dgd - 4 9 +perft 1 22 +perft 2 802 +perft 3 19156 +perft 4 697722 +perft 5 17761431 +perft 6 650603534 + +id 1 +epd qbnrbknr/ppp2p1p/8/3pp1p1/1PP1B3/5N2/P2PPPPP/Q1NRBK1R w HDhd - 0 9 +perft 1 34 +perft 2 943 +perft 3 32506 +perft 4 930619 +perft 5 32523099 +perft 6 955802240 + +id 1 +epd qnrbb1nr/pp1p1ppp/2p2k2/4p3/4P3/5PPP/PPPP4/QNRBBKNR w HC - 0 9 +perft 1 20 +perft 2 460 +perft 3 10287 +perft 4 241640 +perft 5 5846781 +perft 6 140714047 + +id 1 +epd qnr1bbnr/ppk1p1pp/3p4/2p2p2/8/2P5/PP1PPPPP/QNKRBBNR w - - 1 9 +perft 1 19 +perft 2 572 +perft 3 11834 +perft 4 357340 +perft 5 7994547 +perft 6 243724815 + +id 1 +epd qnrkbnrb/1p1p1ppp/2p5/4p3/p7/N1BP4/PPP1PPPP/Q1R1KNRB w gc - 0 9 +perft 1 27 +perft 2 579 +perft 3 16233 +perft 4 375168 +perft 5 10845146 +perft 6 268229097 + +id 1 +epd qbnrkn1r/1pppp1p1/p3bp2/2BN3p/8/5P2/PPPPP1PP/QBNRK2R w HDhd - 0 9 +perft 1 40 +perft 2 1027 +perft 3 38728 +perft 4 1059229 +perft 5 38511307 +perft 6 1104094381 + +id 1 +epd qnrbknbr/1pp2ppp/4p3/p6N/2p5/8/PPPPPPPP/Q1RBK1BR w HChc - 0 9 +perft 1 22 +perft 2 510 +perft 3 11844 +perft 4 300180 +perft 5 7403327 +perft 6 200581103 + +id 1 +epd 1qkrnbbr/p1pppppp/2n5/1p6/8/5NP1/PPPPPP1P/QNRK1BBR w HC - 4 9 +perft 1 24 +perft 2 549 +perft 3 13987 +perft 4 352037 +perft 5 9396521 +perft 6 255676649 + +id 1 +epd q1rknr1b/1ppppppb/2n5/p2B3p/8/1PN3P1/P1PPPP1P/Q1RKNRB1 w FCfc - 3 9 +perft 1 31 +perft 2 924 +perft 3 28520 +perft 4 861944 +perft 5 27463479 +perft 6 847726572 + +id 1 +epd bbnqrk1r/pp1pppp1/2p4p/8/6n1/1N1P1P2/PPP1P1PP/BBQ1RKNR w HEhe - 4 9 +perft 1 24 +perft 2 804 +perft 3 20147 +perft 4 666341 +perft 5 18024195 +perft 6 595947631 + +id 1 +epd bn1brknr/ppp1p1pp/5p2/3p4/6qQ/3P3P/PPP1PPP1/BN1BRKNR w HEhe - 4 9 +perft 1 25 +perft 2 854 +perft 3 22991 +perft 4 704173 +perft 5 20290974 +perft 6 600195008 + +id 1 +epd 1nqrkbnr/2pp1ppp/pp2p3/3b4/2P5/N7/PP1PPPPP/B1QRKBNR w HDhd - 0 9 +perft 1 22 +perft 2 651 +perft 3 16173 +perft 4 479152 +perft 5 13133439 +perft 6 390886040 + +id 1 +epd bnqrk1rb/1pp1pppp/p2p4/4n3/2PPP3/8/PP3PPP/BNQRKNRB w GDgd - 1 9 +perft 1 30 +perft 2 950 +perft 3 28169 +perft 4 889687 +perft 5 27610213 +perft 6 880739164 + +id 1 +epd nbb1rknr/1ppq1ppp/3p4/p3p3/4P3/1N2R3/PPPP1PPP/1BBQ1KNR w Hhe - 2 9 +perft 1 33 +perft 2 988 +perft 3 31293 +perft 4 967575 +perft 5 30894863 +perft 6 985384035 + +id 1 +epd nqbbrknr/2ppp2p/pp4p1/5p2/7P/3P1P2/PPPBP1P1/NQ1BRKNR w HEhe - 0 9 +perft 1 27 +perft 2 492 +perft 3 13266 +perft 4 276569 +perft 5 7583292 +perft 6 175376176 + +id 1 +epd 1qbrkb1r/pppppppp/8/3n4/4P1n1/PN6/1PPP1P1P/1QBRKBNR w HDhd - 3 9 +perft 1 28 +perft 2 800 +perft 3 21982 +perft 4 630374 +perft 5 17313279 +perft 6 507140861 + +id 1 +epd 1qbrknrb/1p1ppppp/1np5/8/p4P1P/4P1N1/PPPP2P1/NQBRK1RB w GDgd - 0 9 +perft 1 21 +perft 2 482 +perft 3 10581 +perft 4 267935 +perft 5 6218644 +perft 6 168704845 + +id 1 +epd nbqrbkr1/ppp1pppp/8/3p4/6n1/2P2PPN/PP1PP2P/NBQRBK1R w HDd - 1 9 +perft 1 29 +perft 2 921 +perft 3 25748 +perft 4 840262 +perft 5 24138518 +perft 6 806554650 + +id 1 +epd nqrb1knr/1ppbpp1p/p7/3p2p1/2P3P1/5P1P/PP1PP3/NQRBBKNR w HChc - 1 9 +perft 1 31 +perft 2 803 +perft 3 25857 +perft 4 665799 +perft 5 21998733 +perft 6 583349773 + +id 1 +epd 1qrkbbr1/pppp1ppp/1n3n2/4p3/5P2/1N6/PPPPP1PP/1QRKBBNR w HCc - 0 9 +perft 1 25 +perft 2 715 +perft 3 19118 +perft 4 556325 +perft 5 15514933 +perft 6 459533767 + +id 1 +epd nqrkb1rb/pp2pppp/2p1n3/3p4/3PP1N1/8/PPP2PPP/NQRKB1RB w GCgc - 0 9 +perft 1 26 +perft 2 795 +perft 3 21752 +perft 4 679387 +perft 5 19185851 +perft 6 616508881 + +id 1 +epd nb1rknbr/pp2ppp1/8/2Bp3p/6P1/2P2P1q/PP1PP2P/NBQRKN1R w HDhd - 0 9 +perft 1 35 +perft 2 1391 +perft 3 43025 +perft 4 1726888 +perft 5 53033675 +perft 6 2139267832 + +id 1 +epd nqrbkn1r/pp1pp1pp/8/2p2p2/5P2/P3B2P/1PbPP1P1/NQRBKN1R w HChc - 0 9 +perft 1 23 +perft 2 758 +perft 3 19439 +perft 4 653854 +perft 5 18296195 +perft 6 628403401 + +id 1 +epd nqrknbbr/pp1pppp1/7p/2p5/7P/1P1N4/P1PPPPPB/NQRK1B1R w HChc - 2 9 +perft 1 29 +perft 2 824 +perft 3 23137 +perft 4 683686 +perft 5 19429491 +perft 6 595493802 + +id 1 +epd 1qrknrbb/B1p1pppp/8/1p1p4/2n2P2/1P6/P1PPP1PP/NQRKNR1B w FCfc - 0 9 +perft 1 28 +perft 2 771 +perft 3 20237 +perft 4 581721 +perft 5 16065378 +perft 6 483037840 + +id 1 +epd bbnrqk1r/1ppppppp/8/7n/1p6/P6P/1BPPPPP1/1BNRQKNR w HDhd - 0 9 +perft 1 25 +perft 2 601 +perft 3 15471 +perft 4 396661 +perft 5 10697065 +perft 6 289472497 + +id 1 +epd bnrbqknr/ppp3p1/3ppp1Q/7p/3P4/1P6/P1P1PPPP/BNRB1KNR w HChc - 0 9 +perft 1 32 +perft 2 845 +perft 3 26876 +perft 4 742888 +perft 5 23717883 +perft 6 682154649 + +id 1 +epd bn1qkb1r/pprppppp/8/2p5/2PPP1n1/8/PPR2PPP/BN1QKBNR w Hh - 1 9 +perft 1 32 +perft 2 856 +perft 3 27829 +perft 4 768595 +perft 5 25245957 +perft 6 727424329 + +id 1 +epd 1nrqknrb/p1pp1ppp/1p2p3/3N4/5P1P/5b2/PPPPP3/B1RQKNRB w GCgc - 2 9 +perft 1 33 +perft 2 873 +perft 3 27685 +perft 4 779473 +perft 5 25128076 +perft 6 745401024 + +id 1 +epd nbbrqrk1/pppppppp/8/2N1n3/P7/6P1/1PPPPP1P/1BBRQKNR w HD - 3 9 +perft 1 25 +perft 2 555 +perft 3 14339 +perft 4 342296 +perft 5 9153089 +perft 6 234841945 + +id 1 +epd 1rbbqknr/1ppp1pp1/1n2p3/p6p/4P1P1/P6N/1PPP1P1P/NRBBQK1R w HBhb - 0 9 +perft 1 25 +perft 2 693 +perft 3 18652 +perft 4 528070 +perft 5 15133381 +perft 6 439344945 + +id 1 +epd nrq1kbnr/p1pbpppp/3p4/1p6/6P1/1N3N2/PPPPPP1P/1RBQKB1R w HBhb - 4 9 +perft 1 24 +perft 2 648 +perft 3 16640 +perft 4 471192 +perft 5 12871967 +perft 6 380436777 + +id 1 +epd nr1qknr1/p1pppp1p/b5p1/1p6/8/P4PP1/1bPPP1RP/NRBQKN1B w Bgb - 0 9 +perft 1 18 +perft 2 533 +perft 3 11215 +perft 4 331243 +perft 5 7777833 +perft 6 234905172 + +id 1 +epd nbrqbknr/1ppp2pp/8/4pp2/p2PP1P1/7N/PPP2P1P/NBRQBK1R w HChc - 0 9 +perft 1 29 +perft 2 803 +perft 3 24416 +perft 4 706648 +perft 5 22305910 +perft 6 672322762 + +id 1 +epd nr1b1k1r/ppp1pppp/2bp1n2/6P1/2P3q1/5P2/PP1PP2P/NRQBBKNR w HBhb - 1 9 +perft 1 27 +perft 2 1199 +perft 3 30908 +perft 4 1296241 +perft 5 35121759 +perft 6 1418677099 + +id 1 +epd nrqkbbnr/2pppp1p/p7/1p6/2P1Pp2/8/PPNP2PP/1RQKBBNR w HBhb - 0 9 +perft 1 28 +perft 2 613 +perft 3 17874 +perft 4 432750 +perft 5 13097064 +perft 6 345294379 + +id 1 +epd 1rqkbnrb/pp1ppp1p/1n4p1/B1p5/3PP3/4N3/PPP2PPP/NRQK2RB w GBgb - 0 9 +perft 1 33 +perft 2 723 +perft 3 23991 +perft 4 590970 +perft 5 19715083 +perft 6 535650233 + +id 1 +epd nbrqkn1r/1pppp2p/5pp1/p2b4/5P2/P2PN3/1PP1P1PP/NBRQK1BR w HChc - 2 9 +perft 1 23 +perft 2 607 +perft 3 15482 +perft 4 400970 +perft 5 11026383 +perft 6 290708878 + +id 1 +epd nrqbknbr/pp1pppp1/8/2p4p/P3PP2/8/1PPP2PP/NRQBKNBR w HBhb - 1 9 +perft 1 26 +perft 2 700 +perft 3 19371 +perft 4 556026 +perft 5 16058815 +perft 6 485460242 + +id 1 +epd nrqknbbr/p2pppp1/1pp5/6Qp/3P4/1P3P2/P1P1P1PP/NR1KNBBR w HBhb - 0 9 +perft 1 40 +perft 2 905 +perft 3 32932 +perft 4 829746 +perft 5 29263502 +perft 6 791963709 + +id 1 +epd nrqknrbb/1p3ppp/p2p4/2p1p3/1P6/3PP1P1/P1P2P1P/NRQKNRBB w FBfb - 0 9 +perft 1 29 +perft 2 780 +perft 3 22643 +perft 4 654495 +perft 5 19532077 +perft 6 593181101 + +id 1 +epd 1bnrkqnr/p1pppp2/7p/1p4p1/4b3/7N/PPPP1PPP/BBNRKQ1R w HDhd - 0 9 +perft 1 25 +perft 2 725 +perft 3 19808 +perft 4 565006 +perft 5 16661676 +perft 6 487354613 + +id 1 +epd bnrbkq1r/pp2p1pp/5n2/2pp1p2/P7/N1PP4/1P2PPPP/B1RBKQNR w HChc - 1 9 +perft 1 24 +perft 2 745 +perft 3 18494 +perft 4 584015 +perft 5 15079602 +perft 6 488924040 + +id 1 +epd 2rkqbnr/p1pppppp/2b5/1pn5/1P3P1Q/2B5/P1PPP1PP/1NRK1BNR w HChc - 3 9 +perft 1 33 +perft 2 904 +perft 3 30111 +perft 4 840025 +perft 5 28194726 +perft 6 801757709 + +id 1 +epd bnrkqnrb/2pppp2/8/pp4pp/1P5P/6P1/P1PPPPB1/BNRKQNR1 w GCgc - 0 9 +perft 1 34 +perft 2 1059 +perft 3 34090 +perft 4 1054311 +perft 5 33195397 +perft 6 1036498304 + +id 1 +epd 1bbrkq1r/pppp2pp/1n2pp1n/8/2PP4/1N4P1/PP2PP1P/1BBRKQNR w HDhd - 1 9 +perft 1 33 +perft 2 891 +perft 3 28907 +perft 4 814247 +perft 5 26970098 +perft 6 788040469 + +id 1 +epd nrbbkqnr/1p2pp1p/p1p3p1/3p4/8/1PP5/P2PPPPP/NRBBKQNR w HBhb - 0 9 +perft 1 21 +perft 2 567 +perft 3 13212 +perft 4 376487 +perft 5 9539687 +perft 6 284426039 + +id 1 +epd 1rbkqbr1/ppp1pppp/1n5n/3p4/3P4/1PP3P1/P3PP1P/NRBKQBNR w HBb - 1 9 +perft 1 27 +perft 2 752 +perft 3 20686 +perft 4 606783 +perft 5 16986290 +perft 6 521817800 + +id 1 +epd nrbkq1rb/1ppp1pp1/4p1n1/p6p/2PP4/5P2/PPK1P1PP/NRB1QNRB w gb - 0 9 +perft 1 35 +perft 2 697 +perft 3 23678 +perft 4 505836 +perft 5 16906409 +perft 6 390324794 + +id 1 +epd nbrkbqnr/p2pp1p1/5p2/1pp4p/7P/3P2P1/PPP1PP2/NBKRBQNR w hc - 0 9 +perft 1 25 +perft 2 679 +perft 3 17223 +perft 4 484921 +perft 5 12879258 +perft 6 376652259 + +id 1 +epd nrkb1qnr/ppppp1p1/6bp/5p2/1PP1P1P1/8/P2P1P1P/NRKBBQNR w HBhb - 1 9 +perft 1 32 +perft 2 761 +perft 3 24586 +perft 4 632916 +perft 5 20671433 +perft 6 568524724 + +id 1 +epd nrk1bbnr/p1q1pppp/1ppp4/8/3P3P/4K3/PPP1PPP1/NR1QBBNR w hb - 0 9 +perft 1 30 +perft 2 719 +perft 3 21683 +perft 4 541389 +perft 5 16278120 +perft 6 423649784 + +id 1 +epd nrkqbr1b/1pppp1pp/5pn1/p6N/1P3P2/8/P1PPP1PP/NRKQB1RB w GBb - 0 9 +perft 1 26 +perft 2 494 +perft 3 13815 +perft 4 296170 +perft 5 8763742 +perft 6 206993496 + +id 1 +epd nbrkq2r/pppp1bpp/4p1n1/5p2/7P/2P3N1/PP1PPPP1/NBKRQ1BR w hc - 0 9 +perft 1 27 +perft 2 701 +perft 3 19536 +perft 4 535052 +perft 5 15394667 +perft 6 443506342 + +id 1 +epd nrkbqnbr/2ppp2p/pp6/5pp1/P1P5/8/1P1PPPPP/NRKBQNBR w HBhb - 0 9 +perft 1 21 +perft 2 487 +perft 3 11341 +perft 4 285387 +perft 5 7218486 +perft 6 193586674 + +id 1 +epd nr1qnbbr/pk1pppp1/1pp4p/8/3P4/5P1P/PPP1P1P1/NRKQNBBR w HB - 0 9 +perft 1 22 +perft 2 546 +perft 3 13615 +perft 4 352855 +perft 5 9587439 +perft 6 259830255 + +id 1 +epd nrkq1rbb/pp1ppp1p/2pn4/8/PP3Pp1/7P/2PPP1P1/NRKQNRBB w FBfb - 0 9 +perft 1 26 +perft 2 839 +perft 3 22075 +perft 4 723845 +perft 5 19867117 +perft 6 658535326 + +id 1 +epd b2rknqr/pp1ppppp/8/2P5/n7/P7/1PPNPPPb/BBNRK1QR w HDhd - 2 9 +perft 1 24 +perft 2 699 +perft 3 19523 +perft 4 575172 +perft 5 17734818 +perft 6 535094237 + +id 1 +epd bnrbknqr/pp2p2p/2p3p1/3p1p2/8/3P4/PPPNPPPP/B1RBKNQR w HChc - 0 9 +perft 1 23 +perft 2 580 +perft 3 14320 +perft 4 385917 +perft 5 10133092 +perft 6 288041554 + +id 1 +epd bnrknb1r/pppp2pp/8/4pp2/6P1/3P3P/qPP1PPQ1/BNRKNB1R w HChc - 0 9 +perft 1 28 +perft 2 1100 +perft 3 31813 +perft 4 1217514 +perft 5 36142423 +perft 6 1361341249 + +id 1 +epd b1rknqrb/ppp1p1p1/2np1p1p/8/4N3/6PQ/PPPPPP1P/B1RKN1RB w GCgc - 0 9 +perft 1 36 +perft 2 629 +perft 3 23082 +perft 4 453064 +perft 5 16897544 +perft 6 367503974 + +id 1 +epd nb1rknqr/pbppp2p/6p1/1p3p2/5P2/3KP3/PPPP2PP/NBBR1NQR w hd - 2 9 +perft 1 18 +perft 2 557 +perft 3 9779 +perft 4 300744 +perft 5 5822387 +perft 6 180936551 + +id 1 +epd nr1bknqr/1ppb1ppp/p7/3pp3/B7/2P3NP/PP1PPPP1/NRB1K1QR w HBhb - 2 9 +perft 1 28 +perft 2 688 +perft 3 19541 +perft 4 519785 +perft 5 15153092 +perft 6 425149249 + +id 1 +epd nrbkn2r/pppp1pqp/4p1p1/8/3P2P1/P3B3/P1P1PP1P/NR1KNBQR w HBhb - 1 9 +perft 1 32 +perft 2 808 +perft 3 25578 +perft 4 676525 +perft 5 22094260 +perft 6 609377239 + +id 1 +epd nrbknqrb/2p1ppp1/1p6/p2p2Bp/1P6/3P1P2/P1P1P1PP/NR1KNQRB w GBgb - 0 9 +perft 1 30 +perft 2 625 +perft 3 18288 +perft 4 418895 +perft 5 12225742 +perft 6 301834282 + +id 1 +epd nbr1knqr/1pp1p1pp/3p1pb1/8/7P/5P2/PPPPPQP1/NBRKBN1R w HC - 2 9 +perft 1 29 +perft 2 863 +perft 3 25767 +perft 4 800239 +perft 5 24965592 +perft 6 799182442 + +id 1 +epd n1kbbnqr/prp2ppp/1p1p4/4p3/1P2P3/3P1B2/P1P2PPP/NRK1BNQR w HBh - 2 9 +perft 1 26 +perft 2 653 +perft 3 17020 +perft 4 449719 +perft 5 12187583 +perft 6 336872952 + +id 1 +epd nrknbbqr/pp3p1p/B3p1p1/2pp4/4P3/2N3P1/PPPP1P1P/NRK1B1QR w HBhb - 0 9 +perft 1 29 +perft 2 683 +perft 3 19755 +perft 4 501807 +perft 5 14684565 +perft 6 394951291 + +id 1 +epd n1knbqrb/pr1p1ppp/Qp6/2p1p3/4P3/6P1/PPPP1P1P/NRKNB1RB w GBg - 2 9 +perft 1 31 +perft 2 552 +perft 3 17197 +perft 4 371343 +perft 5 11663330 +perft 6 283583340 + +id 1 +epd nbrknqbr/p3p1pp/1p1p1p2/2p5/2Q1PP2/8/PPPP2PP/NBRKN1BR w HChc - 0 9 +perft 1 37 +perft 2 913 +perft 3 32470 +perft 4 825748 +perft 5 28899548 +perft 6 759875563 + +id 1 +epd nrkb1qbr/pp1pppp1/5n2/7p/2p5/1N1NPP2/PPPP2PP/1RKB1QBR w HBhb - 0 9 +perft 1 25 +perft 2 712 +perft 3 18813 +perft 4 543870 +perft 5 15045589 +perft 6 445074372 + +id 1 +epd nrk2bbr/pppqpppp/3p4/8/1P3nP1/3P4/P1P1PP1P/NRKNQBBR w HBhb - 1 9 +perft 1 24 +perft 2 814 +perft 3 19954 +perft 4 670162 +perft 5 17603960 +perft 6 592121050 + +id 1 +epd nrknqrbb/1p2ppp1/2pp4/Q6p/P2P3P/8/1PP1PPP1/NRKN1RBB w FBfb - 0 9 +perft 1 34 +perft 2 513 +perft 3 16111 +perft 4 303908 +perft 5 9569590 +perft 6 206509331 + +id 1 +epd bbnrk1rq/pp2p1pp/2ppn3/5p2/8/3NNP1P/PPPPP1P1/BB1RK1RQ w GDgd - 1 9 +perft 1 28 +perft 2 697 +perft 3 20141 +perft 4 517917 +perft 5 15301879 +perft 6 410843713 + +id 1 +epd bnrbknrq/ppppp2p/6p1/5p2/4QPP1/8/PPPPP2P/BNRBKNR1 w GCgc - 0 9 +perft 1 37 +perft 2 901 +perft 3 32612 +perft 4 877372 +perft 5 31385912 +perft 6 903831981 + +id 1 +epd bnkrnbrq/ppppp1p1/B6p/5p2/8/4P3/PPPP1PPP/BNKRN1RQ w - - 0 9 +perft 1 26 +perft 2 417 +perft 3 11124 +perft 4 217095 +perft 5 5980981 +perft 6 133080499 + +id 1 +epd bnrk1rqb/2pppp1p/3n4/pp4p1/3Q1P2/2N3P1/PPPPP2P/B1RKNR1B w FCfc - 0 9 +perft 1 49 +perft 2 1655 +perft 3 74590 +perft 4 2512003 +perft 5 107234294 +perft 6 3651608327 + +id 1 +epd nbbrk1rq/pp2pppp/2pp4/8/2P2n2/6N1/PP1PP1PP/NBBRKR1Q w Dgd - 0 9 +perft 1 28 +perft 2 960 +perft 3 26841 +perft 4 884237 +perft 5 26083252 +perft 6 846682836 + +id 1 +epd nrbb2rq/pppk1ppp/4p1n1/3p4/6P1/1BP5/PP1PPPQP/NRB1KNR1 w GB - 0 9 +perft 1 28 +perft 2 735 +perft 3 22048 +perft 4 593839 +perft 5 18588316 +perft 6 512048946 + +id 1 +epd nrbk1brq/p1ppppp1/7p/1p6/4P1nP/P7/1PPP1PP1/NRBKNBRQ w GBgb - 0 9 +perft 1 22 +perft 2 572 +perft 3 12739 +perft 4 351494 +perft 5 8525056 +perft 6 247615348 + +id 1 +epd nrbk1rqb/1pp2ppp/5n2/p2pp3/5B2/1N1P2P1/PPP1PP1P/1R1KNRQB w FBfb - 0 9 +perft 1 35 +perft 2 927 +perft 3 31559 +perft 4 849932 +perft 5 28465693 +perft 6 783048748 + +id 1 +epd nbrkb1rq/p1pp1ppp/4n3/4p3/Pp6/6N1/1PPPPPPP/NBRKBRQ1 w Cgc - 0 9 +perft 1 20 +perft 2 456 +perft 3 10271 +perft 4 247733 +perft 5 6124625 +perft 6 154766108 + +id 1 +epd nrkb1nrq/p2pp1pp/1pp2p2/7b/6PP/5P2/PPPPP2N/NRKBB1RQ w GBgb - 0 9 +perft 1 21 +perft 2 479 +perft 3 11152 +perft 4 264493 +perft 5 6696458 +perft 6 165253524 + +id 1 +epd nr1nbbr1/pppkpp1p/6p1/3p4/P6P/1P6/1RPPPPP1/N1KNBBRQ w G - 1 9 +perft 1 20 +perft 2 498 +perft 3 11304 +perft 4 288813 +perft 5 7197322 +perft 6 188021682 + +id 1 +epd nrknbrqb/3p1ppp/ppN1p3/8/6P1/8/PPPPPP1P/1RKNBRQB w FBfb - 0 9 +perft 1 32 +perft 2 526 +perft 3 17267 +perft 4 319836 +perft 5 10755190 +perft 6 220058991 + +id 1 +epd nbrkn1bq/p1pppr1p/1p6/5pp1/8/1N2PP2/PPPP2PP/1BKRNRBQ w c - 1 9 +perft 1 19 +perft 2 491 +perft 3 10090 +perft 4 277313 +perft 5 6230616 +perft 6 180748649 + +id 1 +epd nrkbnrbq/ppppppp1/8/8/7p/PP3P2/2PPPRPP/NRKBN1BQ w Bfb - 0 9 +perft 1 16 +perft 2 353 +perft 3 6189 +perft 4 156002 +perft 5 3008668 +perft 6 82706705 + +id 1 +epd nrknrbbq/p4ppp/2p1p3/1p1p4/1P2P3/2P5/P1NP1PPP/1RKNRBBQ w EBeb - 0 9 +perft 1 29 +perft 2 728 +perft 3 21915 +perft 4 587668 +perft 5 18231199 +perft 6 511686397 + +id 1 +epd nrknr1bb/pppp1p2/7p/2qPp1p1/8/1P5P/P1P1PPP1/NRKNRQBB w EBeb - 0 9 +perft 1 20 +perft 2 714 +perft 3 14336 +perft 4 500458 +perft 5 11132758 +perft 6 386064577 + +id 1 +epd bbqnrrkn/ppp2p1p/3pp1p1/8/1PP5/2Q5/P1BPPPPP/B2NRKRN w GE - 0 9 +perft 1 39 +perft 2 593 +perft 3 23446 +perft 4 424799 +perft 5 16764576 +perft 6 346185058 + +id 1 +epd bqn1rkrn/p1p2ppp/1p1p4/4p3/3PP2b/8/PPP2PPP/BQNBRKRN w GEge - 2 9 +perft 1 25 +perft 2 773 +perft 3 20042 +perft 4 616817 +perft 5 16632403 +perft 6 515838333 + +id 1 +epd bqnrkb1n/p1p1pprp/3p4/1p2P1p1/2PP4/8/PP3PPP/BQNRKBRN w GDd - 1 9 +perft 1 31 +perft 2 860 +perft 3 28102 +perft 4 810379 +perft 5 27233018 +perft 6 813751250 + +id 1 +epd bqr1krnb/ppppppp1/7p/3n4/1P4P1/P4N2/2PPPP1P/BQNRKR1B w FDf - 3 9 +perft 1 31 +perft 2 709 +perft 3 22936 +perft 4 559830 +perft 5 18608857 +perft 6 480498340 + +id 1 +epd qbbn1krn/pp3ppp/4r3/2ppp3/P1P4P/8/1P1PPPP1/QBBNRKRN w GEg - 1 9 +perft 1 26 +perft 2 775 +perft 3 21100 +perft 4 649673 +perft 5 18476807 +perft 6 582542257 + +id 1 +epd qnbbrkrn/1p1pp2p/p7/2p2pp1/8/4P2P/PPPP1PPK/QNBBRR1N w ge - 0 9 +perft 1 25 +perft 2 599 +perft 3 15139 +perft 4 389104 +perft 5 10260500 +perft 6 279222412 + +id 1 +epd qnbrkbrn/1ppp2p1/p3p2p/5p2/P4P2/1P6/2PPP1PP/QNBRKBRN w GDgd - 0 9 +perft 1 27 +perft 2 588 +perft 3 16735 +perft 4 394829 +perft 5 11640416 +perft 6 293541380 + +id 1 +epd 1nbrkrnb/p1pppp1p/1pq3p1/8/4P3/P1P4N/1P1P1PPP/QNBRKR1B w FDfd - 1 9 +perft 1 18 +perft 2 609 +perft 3 11789 +perft 4 406831 +perft 5 8604788 +perft 6 299491047 + +id 1 +epd qb1r1krn/pppp2pp/1n2ppb1/4P3/7P/8/PPPP1PP1/QBNRBKRN w GDgd - 0 9 +perft 1 20 +perft 2 578 +perft 3 12205 +perft 4 349453 +perft 5 7939483 +perft 6 229142178 + +id 1 +epd qnr1bkrn/p3pppp/1bpp4/1p6/2P2PP1/8/PP1PPN1P/QNRBBKR1 w GCgc - 0 9 +perft 1 30 +perft 2 865 +perft 3 26617 +perft 4 771705 +perft 5 24475596 +perft 6 719842237 + +id 1 +epd 1nkrbbrn/qppppppp/8/8/p2P4/1P5P/P1P1PPP1/QNKRBBRN w - - 0 9 +perft 1 27 +perft 2 672 +perft 3 18371 +perft 4 505278 +perft 5 14065717 +perft 6 410130412 + +id 1 +epd 1qrkbrnb/ppp1p1pp/n2p4/5p2/4N3/8/PPPPPPPP/Q1RKBRNB w Ffc - 2 9 +perft 1 25 +perft 2 718 +perft 3 18573 +perft 4 536771 +perft 5 14404324 +perft 6 424279467 + +id 1 +epd q1nrkrbn/pp1pppp1/2p4p/8/P7/5Pb1/BPPPPNPP/Q1NRKRB1 w FDfd - 0 9 +perft 1 22 +perft 2 558 +perft 3 12911 +perft 4 336042 +perft 5 8516966 +perft 6 228074630 + +id 1 +epd qnrbkrbn/1p1p1pp1/p1p5/4p2p/8/3P1P2/PPP1P1PP/QNRBKRBN w FCfc - 0 9 +perft 1 28 +perft 2 669 +perft 3 17713 +perft 4 440930 +perft 5 12055174 +perft 6 313276304 + +id 1 +epd qnrkr1bn/p1pp1ppp/8/1p2p3/3P1P2/bP4P1/P1P1P2P/QNRKRBBN w ECec - 1 9 +perft 1 23 +perft 2 845 +perft 3 20973 +perft 4 759778 +perft 5 19939053 +perft 6 718075943 + +id 1 +epd q1krrnbb/p1p1pppp/2np4/1pB5/5P2/8/PPPPP1PP/QNRKRN1B w EC - 0 9 +perft 1 29 +perft 2 776 +perft 3 21966 +perft 4 631941 +perft 5 18110831 +perft 6 549019739 + +id 1 +epd bbn1rkrn/pp1p1ppp/8/2p1p1q1/6P1/P7/BPPPPP1P/B1NQRKRN w GEge - 0 9 +perft 1 26 +perft 2 936 +perft 3 25177 +perft 4 906801 +perft 5 24984621 +perft 6 901444251 + +id 1 +epd bn1brkrn/pp1qpp1p/2p3p1/3p4/1PPP4/P7/4PPPP/BNQBRKRN w GEge - 1 9 +perft 1 29 +perft 2 755 +perft 3 22858 +perft 4 645963 +perft 5 20128587 +perft 6 600207069 + +id 1 +epd b2rkbrn/p1pppppp/qp6/8/1n6/2B2P2/P1PPP1PP/1NQRKBRN w GDgd - 0 9 +perft 1 24 +perft 2 878 +perft 3 21440 +perft 4 791007 +perft 5 20840078 +perft 6 775795187 + +id 1 +epd b2rkrnb/pqp1pppp/n7/1p1p4/P7/N1P2N2/1P1PPPPP/B1QRKR1B w FDfd - 4 9 +perft 1 26 +perft 2 724 +perft 3 19558 +perft 4 571891 +perft 5 16109522 +perft 6 492933398 + +id 1 +epd 1bbqrkrn/ppppp1p1/8/5p1p/P1n3P1/3P4/1PP1PP1P/NBBQRRKN w ge - 1 9 +perft 1 25 +perft 2 678 +perft 3 17351 +perft 4 461211 +perft 5 12173245 +perft 6 329661421 + +id 1 +epd nqb1rrkn/ppp1bppp/3pp3/8/3P4/1P6/PQP1PPPP/N1BBRRKN w - - 1 9 +perft 1 23 +perft 2 503 +perft 3 12465 +perft 4 290341 +perft 5 7626054 +perft 6 188215608 + +id 1 +epd nqbrkbr1/p1pppppp/1p6/2N2n2/2P5/5P2/PP1PP1PP/1QBRKBRN w GDgd - 1 9 +perft 1 29 +perft 2 688 +perft 3 20289 +perft 4 506302 +perft 5 15167248 +perft 6 399015237 + +id 1 +epd nqbrkrn1/1ppppp2/6pp/p7/1P6/2Q5/P1PPPPPP/N1BRKRNB w FDfd - 0 9 +perft 1 36 +perft 2 602 +perft 3 20985 +perft 4 397340 +perft 5 13706856 +perft 6 291708797 + +id 1 +epd nbqrbrkn/pp1p1pp1/2p5/4p2p/2P3P1/1P3P2/P2PP2P/NBQRBKRN w GD - 0 9 +perft 1 34 +perft 2 655 +perft 3 22581 +perft 4 474396 +perft 5 16613630 +perft 6 379344541 + +id 1 +epd nqrbbrkn/1p1pppp1/8/p1p4p/4P2P/1N4P1/PPPP1P2/1QRBBKRN w GC - 0 9 +perft 1 23 +perft 2 597 +perft 3 14468 +perft 4 400357 +perft 5 10096863 +perft 6 294900903 + +id 1 +epd nqrkbbrn/2p1p1pp/pp1p1p2/8/P2N4/2P5/1P1PPPPP/1QRKBBRN w GCgc - 0 9 +perft 1 32 +perft 2 744 +perft 3 23310 +perft 4 550728 +perft 5 17597164 +perft 6 428786656 + +id 1 +epd n1krbrnb/q1pppppp/p7/1p6/3Q4/2P2P2/PP1PP1PP/N1RKBRNB w FC - 1 9 +perft 1 43 +perft 2 1038 +perft 3 41327 +perft 4 1074450 +perft 5 40918952 +perft 6 1126603824 + +id 1 +epd nb1rkrbn/p1pp1p1p/qp6/4p1p1/5PP1/P7/1PPPPB1P/NBQRKR1N w FDfd - 2 9 +perft 1 26 +perft 2 645 +perft 3 16463 +perft 4 445464 +perft 5 11911314 +perft 6 342563372 + +id 1 +epd nqr1krbn/pppp1ppp/8/8/3pP3/5P2/PPPb1NPP/NQRBKRB1 w FCfc - 3 9 +perft 1 2 +perft 2 51 +perft 3 1047 +perft 4 27743 +perft 5 612305 +perft 6 17040200 + +id 1 +epd n1rkrbbn/pqppppp1/7p/1p6/8/1NPP4/PP1KPPPP/1QR1RBBN w ec - 0 9 +perft 1 25 +perft 2 674 +perft 3 17553 +perft 4 505337 +perft 5 13421727 +perft 6 403551903 + +id 1 +epd 1qrkrnbb/1p1p1ppp/pnp1p3/8/3PP3/P6P/1PP2PP1/NQRKRNBB w ECec - 0 9 +perft 1 24 +perft 2 688 +perft 3 17342 +perft 4 511444 +perft 5 13322502 +perft 6 403441498 + +id 1 +epd 1bnrqkrn/2ppppp1/p7/1p1b3p/3PP1P1/8/PPPQ1P1P/BBNR1KRN w GDgd - 1 9 +perft 1 35 +perft 2 925 +perft 3 32238 +perft 4 857060 +perft 5 30458921 +perft 6 824344087 + +id 1 +epd bnrbqkr1/ppp2pp1/6n1/3pp2p/1P6/2N3N1/P1PPPPPP/B1RBQRK1 w gc - 0 9 +perft 1 23 +perft 2 704 +perft 3 17345 +perft 4 539587 +perft 5 14154852 +perft 6 450893738 + +id 1 +epd 1nrqkbrn/p1pppppp/8/1p1b4/P6P/5P2/1PPPP1P1/BNRQKBRN w GCgc - 1 9 +perft 1 19 +perft 2 505 +perft 3 10619 +perft 4 281422 +perft 5 6450025 +perft 6 175593967 + +id 1 +epd b1rqkrnb/ppppppp1/8/6p1/3n4/NP6/P1PPPP1P/B1RQKRNB w FCfc - 0 9 +perft 1 25 +perft 2 614 +perft 3 15578 +perft 4 377660 +perft 5 10391021 +perft 6 259629603 + +id 1 +epd nbbrqkrn/ppp3p1/3pp3/5p1p/1P2P3/P7/2PPQPPP/NBBR1KRN w GDgd - 0 9 +perft 1 30 +perft 2 833 +perft 3 25719 +perft 4 717713 +perft 5 22873901 +perft 6 649556666 + +id 1 +epd nr1bqrk1/ppp1pppp/6n1/3pP3/8/5PQb/PPPP2PP/NRBB1KRN w GB - 3 9 +perft 1 26 +perft 2 734 +perft 3 20161 +perft 4 582591 +perft 5 17199594 +perft 6 512134836 + +id 1 +epd 1rbqkbr1/ppppp1pp/1n6/4np2/3P1P2/6P1/PPPQP2P/NRB1KBRN w GBgb - 1 9 +perft 1 27 +perft 2 662 +perft 3 17897 +perft 4 447464 +perft 5 13038519 +perft 6 338365642 + +id 1 +epd nr1qkr1b/ppp1pp1p/4bn2/3p2p1/4P3/1Q6/PPPP1PPP/NRB1KRNB w FBfb - 4 9 +perft 1 33 +perft 2 939 +perft 3 30923 +perft 4 942138 +perft 5 30995969 +perft 6 991509814 + +id 1 +epd nb1qbkrn/pprp1pp1/7p/2p1pB2/Q1PP4/8/PP2PPPP/N1R1BKRN w GCg - 2 9 +perft 1 47 +perft 2 1128 +perft 3 50723 +perft 4 1306753 +perft 5 56747878 +perft 6 1560584212 + +id 1 +epd nrqb1rkn/pp2pppp/2bp4/2p5/6P1/2P3N1/PP1PPP1P/NRQBBRK1 w - - 3 9 +perft 1 24 +perft 2 828 +perft 3 21148 +perft 4 723705 +perft 5 19506135 +perft 6 668969549 + +id 1 +epd nrq1bbrn/ppkpp2p/2p3p1/P4p2/8/4P1N1/1PPP1PPP/NRQKBBR1 w GB - 0 9 +perft 1 25 +perft 2 525 +perft 3 13533 +perft 4 309994 +perft 5 8250997 +perft 6 201795680 + +id 1 +epd Br1kbrn1/pqpppp2/8/6pp/3b2P1/1N6/PPPPPP1P/1RQKBRN1 w FBfb - 3 9 +perft 1 20 +perft 2 790 +perft 3 18175 +perft 4 695905 +perft 5 17735648 +perft 6 669854148 + +id 1 +epd nbrqkrbn/2p1p1pp/p7/1p1p1p2/4P1P1/5P2/PPPP3P/NBRQKRBN w FCfc - 0 9 +perft 1 29 +perft 2 771 +perft 3 22489 +perft 4 647106 +perft 5 19192982 +perft 6 591335970 + +id 1 +epd 1rqbkrbn/1ppppp1p/1n6/p1N3p1/8/2P4P/PP1PPPP1/1RQBKRBN w FBfb - 0 9 +perft 1 29 +perft 2 502 +perft 3 14569 +perft 4 287739 +perft 5 8652810 +perft 6 191762235 + +id 1 +epd 1rqkrbbn/ppnpp1pp/8/2p5/6p1/3P4/PPP1PPPP/NRK1RBBN w eb - 0 9 +perft 1 19 +perft 2 531 +perft 3 10812 +perft 4 300384 +perft 5 6506674 +perft 6 184309316 + +id 1 +epd nrqkrnbb/p1pp2pp/5p2/4P3/2p5/4N3/PP1PP1PP/NRQKR1BB w EBeb - 0 9 +perft 1 26 +perft 2 800 +perft 3 23256 +perft 4 756695 +perft 5 23952941 +perft 6 809841274 + +id 1 +epd bbnrkqrn/pp3pp1/4p2p/2pp4/4P1P1/1PB5/P1PP1P1P/1BNRKQRN w GDgd - 0 9 +perft 1 33 +perft 2 915 +perft 3 30536 +perft 4 878648 +perft 5 29602610 +perft 6 881898159 + +id 1 +epd bnrbkqr1/1p2pppp/6n1/p1pp4/7P/P3P3/1PPPKPP1/BNRB1QRN w gc - 0 9 +perft 1 19 +perft 2 457 +perft 3 9332 +perft 4 238944 +perft 5 5356253 +perft 6 144653627 + +id 1 +epd b1rkqbrn/pp1p2pp/2n1p3/2p2p2/3P2PP/8/PPP1PP2/BNKRQBRN w gc - 0 9 +perft 1 30 +perft 2 985 +perft 3 30831 +perft 4 1011700 +perft 5 32684185 +perft 6 1080607773 + +id 1 +epd b1rkqrnb/2ppppp1/np6/p6p/1P6/P2P3P/2P1PPP1/BNRKQRNB w FCfc - 0 9 +perft 1 26 +perft 2 692 +perft 3 18732 +perft 4 517703 +perft 5 14561181 +perft 6 413226841 + +id 1 +epd nbbrkqrn/1ppp1p2/p6p/4p1p1/5P2/1P5P/P1PPPNP1/NBBRKQR1 w GDgd - 0 9 +perft 1 22 +perft 2 561 +perft 3 13222 +perft 4 367487 +perft 5 9307003 +perft 6 273928315 + +id 1 +epd nrbbkqrn/p1pppppp/8/1p6/4P3/7Q/PPPP1PPP/NRBBK1RN w GBgb - 0 9 +perft 1 38 +perft 2 769 +perft 3 28418 +perft 4 632310 +perft 5 23091070 +perft 6 560139600 + +id 1 +epd nrbkqbrn/1pppp2p/8/p4pp1/P4PQ1/8/1PPPP1PP/NRBK1BRN w GBgb - 0 9 +perft 1 23 +perft 2 507 +perft 3 13067 +perft 4 321423 +perft 5 8887567 +perft 6 237475184 + +id 1 +epd nr1kqr1b/pp2pppp/5n2/2pp4/P5b1/5P2/1PPPPRPP/NRBK1QNB w Bfb - 2 9 +perft 1 18 +perft 2 626 +perft 3 12386 +perft 4 434138 +perft 5 9465555 +perft 6 335004239 + +id 1 +epd nbkrbqrn/1pppppp1/8/4P2p/pP6/P7/2PP1PPP/NBRKBQRN w GC - 0 9 +perft 1 22 +perft 2 329 +perft 3 8475 +perft 4 148351 +perft 5 4160034 +perft 6 82875306 + +id 1 +epd nrkb1qrn/pp1pp1pp/8/5p1b/P1p4P/6N1/1PPPPPP1/NRKBBQR1 w GBgb - 2 9 +perft 1 16 +perft 2 479 +perft 3 9037 +perft 4 275354 +perft 5 5862341 +perft 6 184959796 + +id 1 +epd 1rkq1brn/ppppp1pp/1n6/3b1p2/3N3P/5P2/PPPPP1P1/1RKQBBRN w GBgb - 3 9 +perft 1 23 +perft 2 614 +perft 3 15324 +perft 4 418395 +perft 5 11090645 +perft 6 313526088 + +id 1 +epd nrk1brnb/pp1ppppp/2p5/3q4/5P2/PP6/1KPPP1PP/NR1QBRNB w fb - 1 9 +perft 1 25 +perft 2 942 +perft 3 21765 +perft 4 792179 +perft 5 19318837 +perft 6 685549171 + +id 1 +epd nbrkqr1n/1pppp2p/p4pp1/2Bb4/5P2/6P1/PPPPP2P/NBRKQ1RN w Cfc - 2 9 +perft 1 30 +perft 2 841 +perft 3 24775 +perft 4 677876 +perft 5 20145765 +perft 6 557578726 + +id 1 +epd n1kbqrbn/2p1pppp/1r6/pp1p4/P7/3P4/1PP1PPPP/NRKBQRBN w FBf - 2 9 +perft 1 21 +perft 2 591 +perft 3 14101 +perft 4 394289 +perft 5 10295086 +perft 6 292131422 + +id 1 +epd nrkqrbb1/ppp1pppp/3p4/8/4P3/2Pn1P2/PP4PP/NRKQRBBN w EBeb - 0 9 +perft 1 4 +perft 2 88 +perft 3 3090 +perft 4 73414 +perft 5 2640555 +perft 6 66958031 + +id 1 +epd nrkqrnbb/ppppp1p1/7p/1P3p2/3P4/2P5/P3PPPP/NRKQRNBB w EBeb - 0 9 +perft 1 29 +perft 2 689 +perft 3 21091 +perft 4 508789 +perft 5 16226660 +perft 6 408570219 + +id 1 +epd bbnr1rqn/pp2pkpp/2pp1p2/8/4P1P1/8/PPPP1P1P/BBNRKRQN w FD - 0 9 +perft 1 21 +perft 2 463 +perft 3 11135 +perft 4 256244 +perft 5 6826249 +perft 6 165025370 + +id 1 +epd bnrbk1qn/1pppprpp/8/p4p1P/6P1/3P4/PPP1PP2/BNRBKRQN w FCc - 0 9 +perft 1 22 +perft 2 459 +perft 3 11447 +perft 4 268157 +perft 5 7371098 +perft 6 190583454 + +id 1 +epd 1nrkrbqn/p1pp1ppp/4p3/1p6/1PP5/6PB/P2PPPbP/BNRKR1QN w ECec - 0 9 +perft 1 30 +perft 2 931 +perft 3 29012 +perft 4 887414 +perft 5 28412902 +perft 6 869228014 + +id 1 +epd b1rkr1nb/pppppqp1/n4B2/7p/8/1P4P1/P1PPPP1P/1NKRRQNB w ec - 1 9 +perft 1 36 +perft 2 934 +perft 3 31790 +perft 4 930926 +perft 5 30392925 +perft 6 952871799 + +id 1 +epd nbbrkrqn/p1ppp1p1/8/1p3p1p/2P3PP/8/PP1PPPQ1/NBBRKR1N w FDfd - 0 9 +perft 1 34 +perft 2 938 +perft 3 31848 +perft 4 921716 +perft 5 31185844 +perft 6 944483246 + +id 1 +epd 1rbbkrqn/ppp1pp2/1n1p2p1/7p/P3P1P1/3P4/1PP2P1P/NRBBKRQN w FBfb - 0 9 +perft 1 26 +perft 2 646 +perft 3 18083 +perft 4 472744 +perft 5 14006203 +perft 6 384101783 + +id 1 +epd nrbkrbq1/Qpppp1pp/2n5/5p2/P4P2/6N1/1PPPP1PP/NRBKRB2 w EBeb - 1 9 +perft 1 27 +perft 2 619 +perft 3 16713 +perft 4 421845 +perft 5 11718463 +perft 6 313794027 + +id 1 +epd 1rbkr1nb/pppp1qpp/1n6/4pp2/1PP1P3/8/PB1P1PPP/NR1KRQNB w EBeb - 1 9 +perft 1 32 +perft 2 1029 +perft 3 32970 +perft 4 1080977 +perft 5 35483796 +perft 6 1181835398 + +id 1 +epd nbrk1rqn/p1ppp2p/1p6/5ppb/8/1N2P2P/PPPP1PP1/1BKRBRQN w fc - 0 9 +perft 1 18 +perft 2 594 +perft 3 12350 +perft 4 408544 +perft 5 9329122 +perft 6 315021712 + +id 1 +epd nrkbbrqn/3pppp1/7p/ppp5/P7/1N5P/1PPPPPP1/1RKBBRQN w FBfb - 0 9 +perft 1 19 +perft 2 417 +perft 3 9026 +perft 4 218513 +perft 5 5236331 +perft 6 137024458 + +id 1 +epd nrkr1bqn/ppp1pppp/3p4/1b6/7P/P7/1PPPPPP1/NRKRBBQN w DBdb - 1 9 +perft 1 17 +perft 2 457 +perft 3 9083 +perft 4 243872 +perft 5 5503579 +perft 6 150091997 + +id 1 +epd nrkrbqnb/p4ppp/1p2p3/2pp4/6P1/2P2N2/PPNPPP1P/1RKRBQ1B w DBdb - 0 9 +perft 1 27 +perft 2 755 +perft 3 21012 +perft 4 620093 +perft 5 17883987 +perft 6 547233320 + +id 1 +epd nbkrr1bn/ppB2ppp/4p3/2qp4/4P3/5P2/PPPP2PP/NBRKRQ1N w EC - 1 9 +perft 1 37 +perft 2 1473 +perft 3 51939 +perft 4 1956521 +perft 5 68070015 +perft 6 2490912491 + +id 1 +epd n1kbrqbn/p1pp1pp1/4p2p/2B5/1r3P2/8/PPPPP1PP/NRKBRQ1N w EBe - 2 9 +perft 1 30 +perft 2 1029 +perft 3 30874 +perft 4 1053163 +perft 5 32318550 +perft 6 1106487743 + +id 1 +epd nrkrqbbn/2pppp1p/8/pp6/1P1P2p1/P5P1/2P1PP1P/NRKRQBBN w DBdb - 0 9 +perft 1 22 +perft 2 421 +perft 3 10034 +perft 4 221927 +perft 5 5754555 +perft 6 141245633 + +id 1 +epd nrkr1nbb/1ppp2pp/p3q3/4pp2/2P5/P3P3/1PKP1PPP/NR1RQNBB w db - 0 9 +perft 1 22 +perft 2 619 +perft 3 13953 +perft 4 411392 +perft 5 9905109 +perft 6 301403003 + +id 1 +epd bbnrkrnq/1pp1p2p/6p1/p2p1p2/8/1P2P3/P1PP1PPP/BBNRKRNQ w FDfd - 0 9 +perft 1 27 +perft 2 805 +perft 3 21915 +perft 4 688224 +perft 5 19133881 +perft 6 620749189 + +id 1 +epd bnrbkrn1/pp1ppp2/2p3pp/8/2Pq4/P4PP1/1P1PP2P/BNRBKRNQ w FCfc - 1 9 +perft 1 20 +perft 2 770 +perft 3 16593 +perft 4 577980 +perft 5 13581691 +perft 6 456736500 + +id 1 +epd b1rkrbnq/1pp1pppp/2np4/p5N1/8/1P2P3/P1PP1PPP/BNRKRB1Q w ECec - 0 9 +perft 1 37 +perft 2 740 +perft 3 27073 +perft 4 581744 +perft 5 21156664 +perft 6 485803600 + +id 1 +epd b1krrnqb/pp1ppp1p/n1p3p1/2N5/6P1/8/PPPPPP1P/B1RKRNQB w EC - 0 9 +perft 1 34 +perft 2 850 +perft 3 28494 +perft 4 752350 +perft 5 25360295 +perft 6 698159474 + +id 1 +epd 1bbr1rnq/ppppkppp/8/3np3/4P3/3P4/PPP1KPPP/NBBRR1NQ w - - 1 9 +perft 1 27 +perft 2 704 +perft 3 18290 +perft 4 480474 +perft 5 12817011 +perft 6 341026662 + +id 1 +epd nrbbk1nq/p1p1prpp/1p6/N2p1p2/P7/8/1PPPPPPP/R1BBKRNQ w Fb - 2 9 +perft 1 23 +perft 2 552 +perft 3 13710 +perft 4 348593 +perft 5 9236564 +perft 6 248469879 + +id 1 +epd 1rbkrb1q/1pppp1pp/1n5n/p4p2/P3P3/1P6/2PPNPPP/NRBKRB1Q w EBeb - 1 9 +perft 1 22 +perft 2 415 +perft 3 10198 +perft 4 217224 +perft 5 5735644 +perft 6 135295774 + +id 1 +epd nrbkr1qb/1pp1pppp/6n1/p2p4/2P1P3/1N4N1/PP1P1PPP/1RBKR1QB w EBeb - 0 9 +perft 1 27 +perft 2 709 +perft 3 19126 +perft 4 506214 +perft 5 14192779 +perft 6 380516508 + +id 1 +epd nbrkbrnq/p3p1pp/1pp2p2/3p4/1PP5/4P3/P1KP1PPP/NBR1BRNQ w fc - 0 9 +perft 1 24 +perft 2 715 +perft 3 18009 +perft 4 535054 +perft 5 14322279 +perft 6 427269976 + +id 1 +epd nrk1brnq/pp1p1pp1/7p/b1p1p3/1P6/6P1/P1PPPPQP/NRKBBRN1 w FBfb - 2 9 +perft 1 29 +perft 2 675 +perft 3 20352 +perft 4 492124 +perft 5 15316285 +perft 6 389051744 + +id 1 +epd nrkr1bnq/1p2pppp/p2p4/1bp5/PP6/1R5N/2PPPPPP/N1KRBB1Q w Ddb - 2 9 +perft 1 27 +perft 2 744 +perft 3 20494 +perft 4 571209 +perft 5 16188945 +perft 6 458900901 + +id 1 +epd nrk1b1qb/pppn1ppp/3rp3/3p4/2P3P1/3P4/PPN1PP1P/1RKRBNQB w DBb - 3 9 +perft 1 35 +perft 2 941 +perft 3 33203 +perft 4 935791 +perft 5 33150360 +perft 6 968024386 + +id 1 +epd nb1rrnbq/ppkp1ppp/8/2p1p3/P7/1N2P3/1PPP1PPP/1BKRRNBQ w - - 1 9 +perft 1 19 +perft 2 451 +perft 3 9655 +perft 4 235472 +perft 5 5506897 +perft 6 139436165 + +id 1 +epd nrkbrnbq/4pppp/1ppp4/p7/2P1P3/3P2N1/PP3PPP/NRKBR1BQ w EBeb - 0 9 +perft 1 29 +perft 2 591 +perft 3 17132 +perft 4 384358 +perft 5 11245508 +perft 6 270967202 + +id 1 +epd nrkrnbbq/3p1ppp/1p6/p1p1p3/3P2P1/P4Q2/1PP1PP1P/NRKRNBB1 w DBdb - 0 9 +perft 1 38 +perft 2 792 +perft 3 28597 +perft 4 640961 +perft 5 22654797 +perft 6 540864616 + +id 1 +epd nr1rnqbb/ppp1pp1p/3k2p1/3p4/1P5P/3P1N2/P1P1PPP1/NRKR1QBB w DB - 1 9 +perft 1 25 +perft 2 758 +perft 3 18547 +perft 4 543643 +perft 5 13890077 +perft 6 402109399 + +id 1 +epd bbqrnnkr/1ppp1p1p/5p2/p5p1/P7/1P4P1/2PPPP1P/1BQRNNKR w HDhd - 0 9 +perft 1 20 +perft 2 322 +perft 3 7224 +perft 4 145818 +perft 5 3588435 +perft 6 82754650 + +id 1 +epd bqrb2k1/pppppppr/5nnp/8/3P1P2/4P1N1/PPP3PP/BQRBN1KR w HCc - 1 9 +perft 1 25 +perft 2 597 +perft 3 15872 +perft 4 397970 +perft 5 11162476 +perft 6 295682250 + +id 1 +epd bqrnn1kr/1pppbppp/8/4p3/1p6/2P1N2P/P2PPPP1/BQR1NBKR w HChc - 1 9 +perft 1 34 +perft 2 921 +perft 3 31695 +perft 4 864023 +perft 5 30126510 +perft 6 850296236 + +id 1 +epd bqr1nkr1/pppppp2/2n3p1/7p/1P1b1P2/8/PQP1P1PP/B1RNNKRB w GCgc - 0 9 +perft 1 23 +perft 2 788 +perft 3 21539 +perft 4 686795 +perft 5 20849374 +perft 6 645694580 + +id 1 +epd qbbrnn1r/1pppp1pk/p7/5p1p/P2P3P/3N4/1PP1PPP1/QBBR1NKR w HD - 0 9 +perft 1 34 +perft 2 713 +perft 3 24475 +perft 4 562189 +perft 5 19494094 +perft 6 482645160 + +id 1 +epd qrbb2kr/p1pppppp/1p1n4/8/1P3n2/P7/Q1PPP1PP/1RBBNNKR w HBhb - 0 9 +perft 1 28 +perft 2 977 +perft 3 26955 +perft 4 949925 +perft 5 27802999 +perft 6 992109168 + +id 1 +epd qrb2bkr/1pp1pppp/2np1n2/pN6/3P4/4B3/PPP1PPPP/QR2NBKR w HBhb - 0 9 +perft 1 27 +perft 2 730 +perft 3 20534 +perft 4 585091 +perft 5 17005916 +perft 6 507008968 + +id 1 +epd qrbnnkrb/pp2pp1p/8/2pp2p1/7P/P1P5/QP1PPPP1/1RBNNKRB w GBgb - 0 9 +perft 1 24 +perft 2 813 +perft 3 21142 +perft 4 707925 +perft 5 19615756 +perft 6 655850285 + +id 1 +epd 1brnb1kr/p1pppppp/1p6/8/4q2n/1P2P1P1/PNPP1P1P/QBR1BNKR w HChc - 3 9 +perft 1 17 +perft 2 734 +perft 3 13462 +perft 4 530809 +perft 5 11032633 +perft 6 416356876 + +id 1 +epd 1rnbbnkr/1pp1pppp/1q1p4/p7/4P3/5PN1/PPPP1BPP/QRNB2KR w HBhb - 1 9 +perft 1 26 +perft 2 809 +perft 3 21764 +perft 4 706677 +perft 5 20292750 +perft 6 675408811 + +id 1 +epd qrnnbb1Q/ppp1pk1p/3p2p1/5p2/PP6/5P2/2PPP1PP/1RNNBBKR w HB - 0 9 +perft 1 37 +perft 2 751 +perft 3 27902 +perft 4 603931 +perft 5 22443036 +perft 6 515122176 + +id 1 +epd qrnnbkrb/p3p1pp/3p1p2/1pp5/PP2P3/8/2PP1PPP/QRNNBRKB w gb - 0 9 +perft 1 30 +perft 2 906 +perft 3 27955 +perft 4 872526 +perft 5 27658191 +perft 6 890966633 + +id 1 +epd qbrnnkbr/1p2pp1p/p1p3p1/3p4/6P1/P1N4P/1PPPPP2/QBR1NKBR w HChc - 0 9 +perft 1 26 +perft 2 701 +perft 3 18930 +perft 4 521377 +perft 5 14733245 +perft 6 416881799 + +id 1 +epd qr1b1kbr/1p1ppppp/1n1n4/p1p5/4P3/5NPP/PPPP1P2/QRNB1KBR w HBhb - 1 9 +perft 1 26 +perft 2 649 +perft 3 17235 +perft 4 451997 +perft 5 12367604 +perft 6 342165821 + +id 1 +epd qrnnkb1r/1pppppp1/7p/p4b2/4P3/5P1P/PPPP2PR/QRNNKBB1 w Bhb - 1 9 +perft 1 34 +perft 2 941 +perft 3 31720 +perft 4 901240 +perft 5 30307554 +perft 6 888709821 + +id 1 +epd qr1nkrbb/p2ppppp/1pp5/8/3Pn3/1NP3P1/PP2PP1P/QR1NKRBB w FBfb - 1 9 +perft 1 19 +perft 2 505 +perft 3 11107 +perft 4 294251 +perft 5 7046501 +perft 6 190414579 + +id 1 +epd bbrqn1kr/1pppp1pp/4n3/5p2/p5P1/3P4/PPP1PPKP/BBRQNN1R w hc - 0 9 +perft 1 24 +perft 2 573 +perft 3 12963 +perft 4 335845 +perft 5 8191054 +perft 6 227555387 + +id 1 +epd brqb1nkr/pppppp1p/8/4N1pn/5P2/6P1/PPPPP2P/BRQB1NKR w HBhb - 0 9 +perft 1 26 +perft 2 550 +perft 3 14338 +perft 4 331666 +perft 5 8903754 +perft 6 223437427 + +id 1 +epd brqnn1kr/pp3ppp/2pbp3/3p4/8/2NPP3/PPP1BPPP/BRQ1N1KR w HBhb - 0 9 +perft 1 27 +perft 2 780 +perft 3 20760 +perft 4 589328 +perft 5 16243731 +perft 6 463883447 + +id 1 +epd brq1nkrb/ppp2ppp/8/n2pp2P/P7/4P3/1PPP1PP1/BRQNNKRB w GBgb - 1 9 +perft 1 17 +perft 2 426 +perft 3 8295 +perft 4 235162 +perft 5 5048497 +perft 6 153986034 + +id 1 +epd rbbqn1kr/pp2p1pp/6n1/2pp1p2/2P4P/P7/BP1PPPP1/R1BQNNKR w HAha - 0 9 +perft 1 27 +perft 2 916 +perft 3 25798 +perft 4 890435 +perft 5 26302461 +perft 6 924181432 + +id 1 +epd 1qbbn1kr/1ppppppp/r3n3/8/p1P5/P7/1P1PPPPP/RQBBNNKR w HAh - 1 9 +perft 1 29 +perft 2 817 +perft 3 24530 +perft 4 720277 +perft 5 22147642 +perft 6 670707652 + +id 1 +epd rqbnnbkr/ppp1ppp1/7p/3p4/PP6/7P/1NPPPPP1/RQB1NBKR w HAa - 1 9 +perft 1 23 +perft 2 572 +perft 3 14509 +perft 4 381474 +perft 5 10416981 +perft 6 288064942 + +id 1 +epd r1bnnkrb/q1ppp1pp/p7/1p3pB1/2P1P3/3P4/PP3PPP/RQ1NNKRB w GAga - 2 9 +perft 1 31 +perft 2 925 +perft 3 27776 +perft 4 860969 +perft 5 26316355 +perft 6 843078864 + +id 1 +epd rbqnb1kr/ppppp1pp/5p2/5N2/7P/1n3P2/PPPPP1P1/RBQNB1KR w HAha - 1 9 +perft 1 32 +perft 2 864 +perft 3 27633 +perft 4 766551 +perft 5 24738875 +perft 6 707188107 + +id 1 +epd rqnbbn1r/ppppppp1/6k1/8/6Pp/2PN4/PP1PPPKP/RQ1BBN1R w - - 0 9 +perft 1 27 +perft 2 566 +perft 3 15367 +perft 4 347059 +perft 5 9714509 +perft 6 234622128 + +id 1 +epd rqnnbbkr/p1p2pp1/1p1p3p/4p3/4NP2/6P1/PPPPP2P/RQN1BBKR w HAha - 0 9 +perft 1 27 +perft 2 631 +perft 3 17923 +perft 4 452734 +perft 5 13307890 +perft 6 356279813 + +id 1 +epd 1qnnbrkb/rppp1ppp/p3p3/8/4P3/2PP1P2/PP4PP/RQNNBKRB w GA - 1 9 +perft 1 24 +perft 2 479 +perft 3 12135 +perft 4 271469 +perft 5 7204345 +perft 6 175460841 + +id 1 +epd rbqnn1br/p1pppk1p/1p4p1/5p2/8/P1P2P2/1PBPP1PP/R1QNNKBR w HA - 0 9 +perft 1 31 +perft 2 756 +perft 3 23877 +perft 4 625194 +perft 5 20036784 +perft 6 554292502 + +id 1 +epd rqnbnkbr/1ppppp2/p5p1/8/1P4p1/4PP2/P1PP3P/RQNBNKBR w HAha - 0 9 +perft 1 24 +perft 2 715 +perft 3 18536 +perft 4 575589 +perft 5 16013189 +perft 6 515078271 + +id 1 +epd rq1nkbbr/1p2pppp/p2n4/2pp4/1P4P1/P2N4/2PPPP1P/RQ1NKBBR w HAha - 1 9 +perft 1 27 +perft 2 694 +perft 3 19840 +perft 4 552904 +perft 5 16685687 +perft 6 494574415 + +id 1 +epd r1nnkrbb/pp1pppp1/2p3q1/7p/8/1PPP3P/P3PPP1/RQNNKRBB w FAfa - 1 9 +perft 1 18 +perft 2 520 +perft 3 10808 +perft 4 329085 +perft 5 7508201 +perft 6 235103697 + +id 1 +epd bbrnqk1r/pppp3p/6p1/4pp2/3P2P1/8/PPP1PP1P/BBRN1NKR w HC - 0 9 +perft 1 22 +perft 2 566 +perft 3 12965 +perft 4 362624 +perft 5 8721079 +perft 6 259069471 + +id 1 +epd brnb1nkr/pppqpp2/3p2pp/8/3PP3/1P6/PBP2PPP/1RNBQNKR w HBhb - 0 9 +perft 1 32 +perft 2 859 +perft 3 28517 +perft 4 817464 +perft 5 27734108 +perft 6 829785474 + +id 1 +epd brnq1b1r/ppp1ppkp/3p1np1/8/8/5P1P/PPPPPKPR/BRNQNB2 w - - 0 9 +perft 1 21 +perft 2 511 +perft 3 10951 +perft 4 273756 +perft 5 6372681 +perft 6 167139732 + +id 1 +epd brnq1rkb/1pppppp1/3n3p/p7/8/P4NP1/1PPPPPRP/BRNQ1K1B w B - 0 9 +perft 1 25 +perft 2 548 +perft 3 14049 +perft 4 341208 +perft 5 9015901 +perft 6 235249649 + +id 1 +epd rbb1qnkr/p1ppp1pp/1p3p2/6n1/8/1PN1P2P/P1PP1PP1/RBB1QNKR w HAha - 0 9 +perft 1 25 +perft 2 673 +perft 3 16412 +perft 4 467660 +perft 5 12099119 +perft 6 361714466 + +id 1 +epd rnbb1nkr/1ppp1ppp/4p3/p5q1/6P1/1PP5/PB1PPP1P/RN1BQNKR w HAha - 1 9 +perft 1 19 +perft 2 663 +perft 3 14149 +perft 4 489653 +perft 5 11491355 +perft 6 399135495 + +id 1 +epd rnbqnbkr/1pp1p2p/3p1p2/p5p1/5PP1/2P5/PPNPP2P/RNBQ1BKR w HAha - 0 9 +perft 1 24 +perft 2 647 +perft 3 16679 +perft 4 461931 +perft 5 12649636 +perft 6 361157611 + +id 1 +epd rnb2krb/pppqppnp/8/3p2p1/1P4P1/7P/P1PPPPB1/RNBQNKR1 w GAga - 1 9 +perft 1 24 +perft 2 722 +perft 3 18749 +perft 4 605229 +perft 5 16609220 +perft 6 563558512 + +id 1 +epd rbnqb1kr/pppn1pp1/3p3p/4p3/1P6/P7/R1PPPPPP/1BNQBNKR w Hha - 1 9 +perft 1 20 +perft 2 538 +perft 3 12277 +perft 4 345704 +perft 5 8687621 +perft 6 255304141 + +id 1 +epd rnqb1nkr/p1pbp1pp/8/1pPp1p2/P2P4/8/1P2PPPP/RNQBBNKR w HAha - 1 9 +perft 1 35 +perft 2 764 +perft 3 26952 +perft 4 632796 +perft 5 22592380 +perft 6 564255328 + +id 1 +epd rnq1bbkr/1p1ppp1p/4n3/p1p3p1/P1PP4/8/RP2PPPP/1NQNBBKR w Hha - 0 9 +perft 1 29 +perft 2 709 +perft 3 21296 +perft 4 570580 +perft 5 17597398 +perft 6 506140370 + +id 1 +epd 1nqnbkrb/1pppp2p/r7/p4pp1/3P4/8/PPPBPPPP/RNQNK1RB w g - 0 9 +perft 1 27 +perft 2 1028 +perft 3 28534 +perft 4 1050834 +perft 5 30251988 +perft 6 1096869832 + +id 1 +epd rbnqnkbr/p1pp1p1p/8/1p2p3/3P2pP/2P5/PP2PPP1/RBNQNKBR w HAha - 0 9 +perft 1 32 +perft 2 832 +perft 3 27120 +perft 4 750336 +perft 5 24945574 +perft 6 724171581 + +id 1 +epd rnq1nkbr/1p1p1ppp/2p1pb2/p7/7P/2P5/PPNPPPPB/RNQB1K1R w HAha - 2 9 +perft 1 31 +perft 2 779 +perft 3 24010 +perft 4 638640 +perft 5 19919434 +perft 6 551494771 + +id 1 +epd rnqnk1br/p1ppp1bp/1p3p2/6p1/4N3/P5P1/1PPPPP1P/R1QNKBBR w HAha - 2 9 +perft 1 25 +perft 2 717 +perft 3 19396 +perft 4 576577 +perft 5 16525239 +perft 6 507175842 + +id 1 +epd rnq1krbb/p1p1pppp/8/1p1p4/1n5B/2N2P2/PPPPP1PP/RNQ1KR1B w FAfa - 0 9 +perft 1 28 +perft 2 867 +perft 3 24029 +perft 4 735686 +perft 5 21112751 +perft 6 654808184 + +id 1 +epd bbrnnqkr/1pp1pppp/3p4/p7/P3P3/7P/1PPP1PP1/BBRNNQKR w HChc - 0 9 +perft 1 24 +perft 2 405 +perft 3 11025 +perft 4 210557 +perft 5 6196438 +perft 6 131401224 + +id 1 +epd brnbnqkr/p1ppp3/1p5p/5Pp1/5P2/3N4/PPPPP2P/BRNB1QKR w HBhb g6 0 9 +perft 1 25 +perft 2 785 +perft 3 21402 +perft 4 698331 +perft 5 20687969 +perft 6 695850727 + +id 1 +epd br1nqbkr/1ppppp2/pn6/6pp/2PP4/1N4P1/PP2PP1P/BR1NQBKR w HBhb - 0 9 +perft 1 25 +perft 2 596 +perft 3 16220 +perft 4 421882 +perft 5 12185361 +perft 6 337805606 + +id 1 +epd 1rnnqkrb/p2ppp1p/1pp5/2N3p1/8/1P6/P1PPPPKP/BR1NQ1RB w gb - 0 9 +perft 1 38 +perft 2 960 +perft 3 34831 +perft 4 913665 +perft 5 32490040 +perft 6 880403591 + +id 1 +epd rbbnnqkr/pp3pp1/2p1p3/3p3p/3P3P/1PP5/P3PPP1/RBBNNQKR w HAha - 0 9 +perft 1 30 +perft 2 785 +perft 3 23079 +perft 4 656618 +perft 5 19885037 +perft 6 599219582 + +id 1 +epd rn1bnqkr/p1ppppp1/8/1p5p/P4P1P/3N4/1PPPP1b1/RNBB1QKR w HAha - 0 9 +perft 1 27 +perft 2 752 +perft 3 21735 +perft 4 613194 +perft 5 18862234 +perft 6 547415271 + +id 1 +epd 1nbnqbkr/1p1p1ppp/r3p3/p1p5/P3P3/3Q4/1PPP1PPP/RNBN1BKR w HAh - 2 9 +perft 1 33 +perft 2 721 +perft 3 24278 +perft 4 572535 +perft 5 19648535 +perft 6 496023732 + +id 1 +epd rnbnqkrb/2pppppp/1p6/p7/1PP5/4N2P/P2PPPP1/RNB1QKRB w GAg - 0 9 +perft 1 23 +perft 2 570 +perft 3 14225 +perft 4 374196 +perft 5 10022614 +perft 6 279545007 + +id 1 +epd rbnnbq1r/ppppppkp/6p1/N7/4P3/P7/1PPP1PPP/RB1NBQKR w HA - 5 9 +perft 1 27 +perft 2 620 +perft 3 18371 +perft 4 440594 +perft 5 13909432 +perft 6 349478320 + +id 1 +epd r1nbbqkr/pppppp1p/8/8/1n3Pp1/3N1QP1/PPPPP2P/RN1BB1KR w HAha - 0 9 +perft 1 31 +perft 2 791 +perft 3 25431 +perft 4 682579 +perft 5 22408813 +perft 6 636779732 + +id 1 +epd rnq1bbkr/pp1p1ppp/2pnp3/8/7P/1QP5/PP1PPPPR/RNN1BBK1 w Aha - 2 9 +perft 1 28 +perft 2 559 +perft 3 16838 +perft 4 390887 +perft 5 12242780 +perft 6 315431511 + +id 1 +epd rnnqbrkb/2ppppp1/1p1N4/p6p/4P3/8/PPPP1PPP/R1NQBKRB w GA - 0 9 +perft 1 32 +perft 2 638 +perft 3 20591 +perft 4 438792 +perft 5 14395828 +perft 6 331782223 + +id 1 +epd rbnnq1br/pppp1kp1/4pp2/7p/PP6/2PP4/4PPPP/RBNNQKBR w HA - 0 9 +perft 1 21 +perft 2 521 +perft 3 12201 +perft 4 320429 +perft 5 8239159 +perft 6 227346638 + +id 1 +epd rnnbqkbr/p2ppp2/7p/1pp3p1/2P2N2/8/PP1PPPPP/RN1BQKBR w HAha - 0 9 +perft 1 25 +perft 2 528 +perft 3 13896 +perft 4 326094 +perft 5 9079829 +perft 6 232750602 + +id 1 +epd rnn1kbbr/ppppqp2/6p1/2N1p2p/P7/2P5/1P1PPPPP/RN1QKBBR w HAha - 2 9 +perft 1 27 +perft 2 801 +perft 3 22088 +perft 4 707078 +perft 5 20334071 +perft 6 682580976 + +id 1 +epd rnnqkrbb/p1p1p1pp/1p3p2/8/3p2Q1/P1P1P3/1P1P1PPP/RNN1KRBB w FAfa - 0 9 +perft 1 37 +perft 2 1014 +perft 3 34735 +perft 4 998999 +perft 5 32921537 +perft 6 988770109 + +id 1 +epd bbrnk1qr/1pppppp1/p4n1p/8/P2P2N1/8/1PP1PPPP/BBR1NKQR w HC - 1 9 +perft 1 21 +perft 2 481 +perft 3 11213 +perft 4 279993 +perft 5 7015419 +perft 6 187564853 + +id 1 +epd brnbnkqr/1pp1p1p1/p2p1p2/7p/1P4PP/8/PBPPPP2/1RNBNKQR w HBhb - 0 9 +perft 1 31 +perft 2 743 +perft 3 24260 +perft 4 660177 +perft 5 22391185 +perft 6 653721389 + +id 1 +epd br2kbqr/ppppp1pp/3n1p2/3P4/3n3P/3N4/PPP1PPP1/BR1NKBQR w HBhb - 3 9 +perft 1 25 +perft 2 872 +perft 3 22039 +perft 4 748726 +perft 5 20281962 +perft 6 685749952 + +id 1 +epd br1nkqrb/ppppppp1/8/7p/4P3/n1P2PP1/PP1P3P/BRNNKQRB w GBgb - 0 9 +perft 1 28 +perft 2 607 +perft 3 16934 +perft 4 396483 +perft 5 11607818 +perft 6 294181806 + +id 1 +epd rbbn1kqr/pp1pp1p1/2pn3p/5p2/5P2/1P1N4/PNPPP1PP/RBB2KQR w HAha - 1 9 +perft 1 27 +perft 2 725 +perft 3 21543 +perft 4 616082 +perft 5 19239812 +perft 6 581716972 + +id 1 +epd rnbbnk1r/pp1ppp1p/6q1/2p5/PP4p1/4P3/2PP1PPP/RNBBNKQR w HAha - 1 9 +perft 1 25 +perft 2 1072 +perft 3 26898 +perft 4 1088978 +perft 5 28469879 +perft 6 1122703887 + +id 1 +epd rnbnkbqr/1pp3pp/3p4/p3pp2/3P2P1/2N1N3/PPP1PP1P/R1B1KBQR w HAha - 0 9 +perft 1 31 +perft 2 1028 +perft 3 32907 +perft 4 1095472 +perft 5 36025223 +perft 6 1211187800 + +id 1 +epd r1bnkqrb/1ppppppp/p3n3/8/6P1/4N3/PPPPPPRP/RNB1KQ1B w Aga - 1 9 +perft 1 23 +perft 2 457 +perft 3 11416 +perft 4 250551 +perft 5 6666787 +perft 6 159759052 + +id 1 +epd rbn1bkqr/p1pp1pp1/1pn5/4p2p/7P/1PBP4/P1P1PPP1/RBNN1KQR w HAha - 0 9 +perft 1 23 +perft 2 470 +perft 3 11649 +perft 4 264274 +perft 5 6963287 +perft 6 172833738 + +id 1 +epd rnnbbkqr/3ppppp/p7/1pp5/P6P/6P1/1PPPPP2/RNNBBKQR w HAha - 0 9 +perft 1 26 +perft 2 569 +perft 3 15733 +perft 4 375556 +perft 5 11008114 +perft 6 284485303 + +id 1 +epd r1nk1bqr/1pppp1pp/2n5/p4p1b/5P2/1N4B1/PPPPP1PP/RN1K1BQR w HAha - 2 9 +perft 1 25 +perft 2 824 +perft 3 21983 +perft 4 738366 +perft 5 20904119 +perft 6 716170771 + +id 1 +epd r1nkbqrb/p2pppp1/npp4p/8/4PP2/2N4P/PPPP2P1/R1NKBQRB w GAga - 0 9 +perft 1 31 +perft 2 548 +perft 3 17480 +perft 4 349633 +perft 5 11469548 +perft 6 255067638 + +id 1 +epd rbnnkqbr/ppppp2p/5p2/6p1/2P1B3/P6P/1P1PPPP1/R1NNKQBR w HAha - 1 9 +perft 1 31 +perft 2 809 +perft 3 24956 +perft 4 680747 +perft 5 21247414 +perft 6 606221516 + +id 1 +epd 1r1bkqbr/pppp1ppp/2nnp3/8/2P5/N4P2/PP1PP1PP/1RNBKQBR w Hh - 0 9 +perft 1 28 +perft 2 810 +perft 3 22844 +perft 4 694599 +perft 5 20188622 +perft 6 636748147 + +id 1 +epd rn1kqbbr/p1pppp1p/1p4p1/1n6/1P2P3/4Q2P/P1PP1PP1/RNNK1BBR w HAha - 1 9 +perft 1 39 +perft 2 848 +perft 3 30100 +perft 4 724426 +perft 5 25594662 +perft 6 659615710 + +id 1 +epd rn1kqrbb/pppppppp/8/8/2nP2P1/1P2P3/P1P2P1P/RNNKQRBB w FAfa - 1 9 +perft 1 29 +perft 2 766 +perft 3 21701 +perft 4 567971 +perft 5 16944425 +perft 6 456898648 + +id 1 +epd b1rnnkrq/bpppppp1/7p/8/1p6/2B5/PNPPPPPP/1BR1NKRQ w GCgc - 2 9 +perft 1 25 +perft 2 667 +perft 3 17253 +perft 4 472678 +perft 5 12865247 +perft 6 365621294 + +id 1 +epd brnb1krq/pppppppp/8/5P2/2P1n2P/8/PP1PP1P1/BRNBNKRQ w GBgb - 1 9 +perft 1 23 +perft 2 620 +perft 3 14882 +perft 4 402561 +perft 5 10776855 +perft 6 300125003 + +id 1 +epd b1nnkbrq/pr1pppp1/1p5p/2p5/P2N1P2/8/1PPPP1PP/BR1NKBRQ w GBg - 0 9 +perft 1 24 +perft 2 472 +perft 3 12181 +perft 4 267398 +perft 5 7370758 +perft 6 178605165 + +id 1 +epd br1nkrqb/p1p1p1pp/3n4/1p1p1p2/5N1P/4P3/PPPP1PP1/BR1NKRQB w FBfb - 0 9 +perft 1 24 +perft 2 775 +perft 3 19398 +perft 4 624309 +perft 5 16429837 +perft 6 539767605 + +id 1 +epd rbbnnkrq/p2pp1pp/2p5/5p2/1pPP1B2/P7/1P2PPPP/RB1NNKRQ w GAga - 0 9 +perft 1 34 +perft 2 921 +perft 3 30474 +perft 4 849933 +perft 5 28095833 +perft 6 806446436 + +id 1 +epd rnbbnkr1/1p1ppp1p/2p3p1/p7/2Pq4/1P1P4/P2BPPPP/RN1BNKRQ w GAga - 2 9 +perft 1 26 +perft 2 1139 +perft 3 29847 +perft 4 1204863 +perft 5 32825932 +perft 6 1281760240 + +id 1 +epd 1rbnkbrq/pppppp2/n5pp/2P5/P7/4N3/1P1PPPPP/RNB1KBRQ w GAg - 2 9 +perft 1 23 +perft 2 574 +perft 3 14146 +perft 4 391413 +perft 5 10203438 +perft 6 301874034 + +id 1 +epd 1nbnkr1b/rppppppq/p7/7p/1P5P/3P2P1/P1P1PP2/RNBNKRQB w FAf - 1 9 +perft 1 33 +perft 2 823 +perft 3 26696 +perft 4 724828 +perft 5 23266182 +perft 6 672294132 + +id 1 +epd rbn1bkrq/ppppp3/4n2p/5pp1/1PN5/2P5/P2PPPPP/RBN1BKRQ w GAga - 0 9 +perft 1 27 +perft 2 859 +perft 3 24090 +perft 4 796482 +perft 5 23075785 +perft 6 789152120 + +id 1 +epd r1nbbkrq/1ppp2pp/2n2p2/p3p3/5P2/1N4BP/PPPPP1P1/RN1B1KRQ w GAga - 0 9 +perft 1 25 +perft 2 774 +perft 3 20141 +perft 4 618805 +perft 5 16718577 +perft 6 515864053 + +id 1 +epd rnnkbbrq/1pppp1p1/5p2/7p/p6P/3N1P2/PPPPP1PQ/RN1KBBR1 w GAga - 0 9 +perft 1 29 +perft 2 673 +perft 3 20098 +perft 4 504715 +perft 5 15545590 +perft 6 416359581 + +id 1 +epd r1nkbrqb/pppp1p2/n3p1p1/7p/2P2P2/1P6/P2PPQPP/RNNKBR1B w FAfa - 0 9 +perft 1 27 +perft 2 722 +perft 3 21397 +perft 4 593762 +perft 5 18742426 +perft 6 537750982 + +id 1 +epd rbnnkr1q/1ppp2pp/p4p2/P2bp3/4P2P/8/1PPP1PP1/RBNNKRBQ w FAfa - 1 9 +perft 1 26 +perft 2 848 +perft 3 23387 +perft 4 741674 +perft 5 21591790 +perft 6 675163653 + +id 1 +epd rn1bkrb1/1ppppp1p/pn4p1/8/P2q3P/3P4/NPP1PPP1/RN1BKRBQ w FAfa - 1 9 +perft 1 22 +perft 2 803 +perft 3 18322 +perft 4 632920 +perft 5 15847763 +perft 6 536419559 + +id 1 +epd rn1krbbq/pppp1npp/4pp2/8/4P2P/3P2P1/PPP2P2/RNNKRBBQ w EAea - 1 9 +perft 1 29 +perft 2 810 +perft 3 23968 +perft 4 670500 +perft 5 20361517 +perft 6 575069358 + +id 1 +epd rnn1rqbb/ppkp1pp1/2p1p2p/2P5/8/3P1P2/PP2P1PP/RNNKRQBB w EA - 0 9 +perft 1 22 +perft 2 506 +perft 3 11973 +perft 4 292344 +perft 5 7287368 +perft 6 189865944 + +id 1 +epd bbqr1knr/pppppp1p/8/4n1p1/2P1P3/6P1/PPQP1P1P/BB1RNKNR w HDhd - 0 9 +perft 1 26 +perft 2 650 +perft 3 18253 +perft 4 481200 +perft 5 14301029 +perft 6 394943978 + +id 1 +epd bq1bnknr/pprppp1p/8/2p3p1/4PPP1/8/PPPP3P/BQRBNKNR w HCh - 0 9 +perft 1 24 +perft 2 548 +perft 3 14021 +perft 4 347611 +perft 5 9374021 +perft 6 250988458 + +id 1 +epd bqrnkb1r/1p2pppp/p1pp3n/5Q2/2P4P/5N2/PP1PPPP1/B1RNKB1R w HChc - 0 9 +perft 1 46 +perft 2 823 +perft 3 33347 +perft 4 673905 +perft 5 26130444 +perft 6 582880996 + +id 1 +epd bq1rknrb/pppppp1p/4n3/6p1/4P1P1/3P1P2/PPP4P/BQRNKNRB w GCg - 0 9 +perft 1 23 +perft 2 618 +perft 3 14815 +perft 4 419474 +perft 5 10606831 +perft 6 315124518 + +id 1 +epd q1brnknr/pp1pp1p1/8/2p2p1p/5b2/P4N2/1PPPP1PP/QBBRK1NR w hd - 0 9 +perft 1 22 +perft 2 675 +perft 3 15778 +perft 4 473994 +perft 5 12077228 +perft 6 368479752 + +id 1 +epd qrbbnknr/1p1ppp1p/p1p5/8/1P2P1p1/3P1B2/P1P2PPP/QRB1NKNR w HBhb - 0 9 +perft 1 32 +perft 2 722 +perft 3 24049 +perft 4 569905 +perft 5 19584539 +perft 6 484814878 + +id 1 +epd qrb1kbnr/p3pppp/2n5/1ppp4/7P/3P1P2/PPP1P1PR/QRBNKBN1 w Bhb - 0 9 +perft 1 26 +perft 2 831 +perft 3 22606 +perft 4 724505 +perft 5 20500804 +perft 6 662608969 + +id 1 +epd qrbnknrb/ppp1pp2/6p1/7p/PPNp4/8/2PPPPPP/QRB1KNRB w GBgb - 0 9 +perft 1 31 +perft 2 840 +perft 3 26762 +perft 4 742772 +perft 5 24422614 +perft 6 701363800 + +id 1 +epd qbrnbknr/pp1pp1pp/8/2p2p2/3Q4/PP6/2PPPPPP/1BRNBKNR w HChc - 0 9 +perft 1 38 +perft 2 1121 +perft 3 39472 +perft 4 1198438 +perft 5 41108769 +perft 6 1285503872 + +id 1 +epd qr1bbk1r/pppppp1p/1n6/5np1/4B3/1PP5/P2PPPPP/QRN1BKNR w HBhb - 0 9 +perft 1 25 +perft 2 694 +perft 3 16938 +perft 4 472950 +perft 5 12164609 +perft 6 345122090 + +id 1 +epd qrnkbbnr/1p1pp2p/p7/2p1Npp1/6P1/7P/PPPPPP2/QR1KBBNR w HBhb - 0 9 +perft 1 27 +perft 2 586 +perft 3 16348 +perft 4 393391 +perft 5 11409633 +perft 6 298054792 + +id 1 +epd qrnkbnrb/pp1p1p2/2p1p1pp/4N3/P4P2/8/1PPPP1PP/QR1KBNRB w GBgb - 0 9 +perft 1 32 +perft 2 645 +perft 3 20737 +perft 4 460319 +perft 5 15037464 +perft 6 358531599 + +id 1 +epd qbrnknbr/1pppppp1/p6p/8/1P6/3PP3/PQP2PPP/1BRNKNBR w HChc - 3 9 +perft 1 26 +perft 2 595 +perft 3 16755 +perft 4 415022 +perft 5 12214768 +perft 6 323518628 + +id 1 +epd qrnbk1br/1ppppp1p/p5p1/8/4Pn2/4K1P1/PPPP1P1P/QRNB1NBR w hb - 0 9 +perft 1 24 +perft 2 609 +perft 3 13776 +perft 4 359415 +perft 5 8538539 +perft 6 230364479 + +id 1 +epd qrnk1bbr/1pnp1ppp/p1p1p3/8/3Q4/1P1N3P/P1PPPPP1/1RNK1BBR w HBhb - 0 9 +perft 1 43 +perft 2 1106 +perft 3 42898 +perft 4 1123080 +perft 5 41695761 +perft 6 1113836402 + +id 1 +epd qrnknrb1/pppppp2/8/6pp/4P2P/3P1P2/PbP3P1/QRNKNRBB w FBfb - 0 9 +perft 1 24 +perft 2 658 +perft 3 17965 +perft 4 488373 +perft 5 14457245 +perft 6 400971226 + +id 1 +epd bbrqnrk1/ppp2ppp/7n/3pp3/8/P4N1N/1PPPPPPP/BBRQ1RK1 w - - 1 9 +perft 1 22 +perft 2 503 +perft 3 12078 +perft 4 310760 +perft 5 8080951 +perft 6 224960353 + +id 1 +epd brqbnk1r/1ppp1ppp/8/p3pn2/8/2PP1P2/PP2PKPP/BRQBN1NR w hb - 1 9 +perft 1 25 +perft 2 745 +perft 3 19387 +perft 4 570459 +perft 5 15520298 +perft 6 460840861 + +id 1 +epd brqnkbnr/pp2pp1p/3p4/2p5/5p2/3P3P/PPP1PPP1/B1RNKBNR w Hhb - 0 9 +perft 1 19 +perft 2 516 +perft 3 10755 +perft 4 312996 +perft 5 6995034 +perft 6 214340699 + +id 1 +epd brq1kn1b/1ppppprp/2n3p1/p7/P1N5/6P1/1PPPPP1P/BRQNK1RB w GBb - 2 9 +perft 1 29 +perft 2 557 +perft 3 16739 +perft 4 352277 +perft 5 10840256 +perft 6 249999654 + +id 1 +epd rbbq1k1r/ppp1pppp/7n/1n1p4/5P2/P2P4/1PPBP1PP/RB1QNKNR w HAha - 1 9 +perft 1 25 +perft 2 769 +perft 3 20110 +perft 4 638340 +perft 5 17438715 +perft 6 570893953 + +id 1 +epd r1bbnk1r/qpp1pppp/p6n/3p4/1P6/5N1P/P1PPPPP1/RQBBK1NR w ha - 0 9 +perft 1 23 +perft 2 728 +perft 3 18209 +perft 4 587364 +perft 5 16053564 +perft 6 529082811 + +id 1 +epd rqbnkbnr/1pp2p1p/3p4/p3p1p1/8/2P2P2/PP1PPNPP/RQBNKB1R w HAha - 0 9 +perft 1 26 +perft 2 772 +perft 3 21903 +perft 4 653704 +perft 5 19571559 +perft 6 593915677 + +id 1 +epd r1bnknrb/pqppp1p1/1p5p/5p2/7P/3P2N1/PPP1PPP1/RQBNK1RB w GAga - 2 9 +perft 1 27 +perft 2 748 +perft 3 20291 +perft 4 597105 +perft 5 16324542 +perft 6 506453626 + +id 1 +epd rbqnbknr/pp1pppp1/8/2p5/3P3p/5N1P/PPP1PPPR/RBQNBK2 w Aha - 0 9 +perft 1 30 +perft 2 859 +perft 3 26785 +perft 4 819631 +perft 5 26363334 +perft 6 842796987 + +id 1 +epd rqnbbrk1/ppppppp1/8/5n1p/3P3P/2B3P1/PPP1PP2/RQNB1KNR w HA - 0 9 +perft 1 22 +perft 2 505 +perft 3 11452 +perft 4 283464 +perft 5 7055215 +perft 6 186760784 + +id 1 +epd rqnkbbnr/pp2p1p1/8/2pp1p1p/3PPP2/8/PPP1N1PP/RQNKBB1R w HAha - 0 9 +perft 1 28 +perft 2 832 +perft 3 23142 +perft 4 722857 +perft 5 20429246 +perft 6 663183060 + +id 1 +epd rqnkbnr1/pppp2bp/6p1/4pp2/1P2P3/3NN3/P1PP1PPP/RQ1KB1RB w GAga - 0 9 +perft 1 28 +perft 2 641 +perft 3 18835 +perft 4 459993 +perft 5 14038570 +perft 6 364210162 + +id 1 +epd rbq2kbr/pppppppp/2n5/P7/3P1n2/2P5/1P2PPPP/RBQNKNBR w HA - 1 9 +perft 1 31 +perft 2 889 +perft 3 27028 +perft 4 766181 +perft 5 24299415 +perft 6 692180754 + +id 1 +epd rq1bkn1r/ppppp2p/3n4/5pp1/2b3P1/1N1P1P2/PPP1P2P/RQ1BKNBR w HAha - 1 9 +perft 1 28 +perft 2 810 +perft 3 22667 +perft 4 657520 +perft 5 18719949 +perft 6 556282676 + +id 1 +epd r1nknbbr/p2ppp1p/1pp3p1/8/1P6/4P3/P1PPNPPq/R1QKNBBR w HAha - 0 9 +perft 1 24 +perft 2 797 +perft 3 22144 +perft 4 719069 +perft 5 21862776 +perft 6 716521139 + +id 1 +epd rqnknrbb/ppp1p3/5ppp/2Np4/2P5/4P3/PP1P1PPP/RQNK1RBB w FAfa - 0 9 +perft 1 34 +perft 2 686 +perft 3 23277 +perft 4 515541 +perft 5 17664543 +perft 6 423574794 + +id 1 +epd 1brnqknr/2p1pppp/p2p4/1P6/6P1/4Nb2/PP1PPP1P/BBR1QKNR w HChc - 1 9 +perft 1 34 +perft 2 1019 +perft 3 32982 +perft 4 1003103 +perft 5 33322477 +perft 6 1043293394 + +id 1 +epd brn1qknr/1p1pppp1/pb5p/Q1p5/3P3P/8/PPP1PPPR/BRNB1KN1 w Bhb - 2 9 +perft 1 32 +perft 2 642 +perft 3 20952 +perft 4 464895 +perft 5 15454749 +perft 6 371861782 + +id 1 +epd brnqkbnr/pppppp2/8/6pp/6P1/P2P1P2/1PP1P2P/BRNQKBNR w HBhb - 0 9 +perft 1 20 +perft 2 441 +perft 3 9782 +perft 4 240220 +perft 5 5770284 +perft 6 153051835 + +id 1 +epd 2nqknrb/1rpppppp/5B2/pp6/1PP1b3/3P4/P3PPPP/1RNQKNRB w GBg - 1 9 +perft 1 35 +perft 2 1042 +perft 3 36238 +perft 4 1101159 +perft 5 38505058 +perft 6 1202668717 + +id 1 +epd rb1nqknr/1pp1pppp/8/3p4/p2P4/6PN/PPPQPP1P/RBBN1K1R w HAha - 0 9 +perft 1 29 +perft 2 692 +perft 3 21237 +perft 4 555018 +perft 5 17820605 +perft 6 497251206 + +id 1 +epd rnbbqknr/pppp4/5p2/4p1pp/P7/2N2PP1/1PPPP2P/R1BBQKNR w HAha - 0 9 +perft 1 23 +perft 2 595 +perft 3 14651 +perft 4 415772 +perft 5 10881112 +perft 6 329010121 + +id 1 +epd rn1qkbnr/p1p1pp1p/bp4p1/3p4/1P6/4P3/P1PP1PPP/RNBQKBNR w HAha - 0 9 +perft 1 30 +perft 2 794 +perft 3 24319 +perft 4 690811 +perft 5 21657601 +perft 6 647745807 + +id 1 +epd r1bqk1rb/pppnpppp/5n2/3p4/2P3PP/2N5/PP1PPP2/R1BQKNRB w GAga - 1 9 +perft 1 32 +perft 2 821 +perft 3 27121 +perft 4 733155 +perft 5 24923473 +perft 6 710765657 + +id 1 +epd rbnqbknr/1p1ppp1p/6p1/p1p5/7P/3P4/PPP1PPP1/RBNQBKNR w HAha - 0 9 +perft 1 24 +perft 2 720 +perft 3 18842 +perft 4 575027 +perft 5 15992882 +perft 6 501093456 + +id 1 +epd r1qbbk1r/pp1ppppp/n1p5/5n2/B1P3P1/8/PP1PPP1P/RNQ1BKNR w HAha - 0 9 +perft 1 27 +perft 2 831 +perft 3 22293 +perft 4 698986 +perft 5 19948650 +perft 6 637973209 + +id 1 +epd rnqkbb1r/p1pppppp/8/8/1p4n1/PP4PP/2PPPP2/RNQKBBNR w HAha - 0 9 +perft 1 18 +perft 2 463 +perft 3 9519 +perft 4 256152 +perft 5 6065231 +perft 6 172734380 + +id 1 +epd rnqk1nrb/pppbpp2/7p/3p2p1/4B3/2N1N1P1/PPPPPP1P/R1QKB1R1 w GAga - 0 9 +perft 1 34 +perft 2 1171 +perft 3 38128 +perft 4 1318217 +perft 5 42109356 +perft 6 1465473753 + +id 1 +epd rbnqknbr/1pp1ppp1/3p4/7p/p2P2PP/2P5/PP2PP2/RBNQKNBR w HAha - 0 9 +perft 1 32 +perft 2 867 +perft 3 28342 +perft 4 798722 +perft 5 26632459 +perft 6 781067145 + +id 1 +epd rn1bknbr/pq2pppp/1p6/2pp4/P7/1P1P4/2PNPPPP/RNQBK1BR w HAha - 0 9 +perft 1 24 +perft 2 627 +perft 3 16652 +perft 4 462942 +perft 5 13200921 +perft 6 385193532 + +id 1 +epd r1qk1bbr/ppp1pp1p/2np1n2/6p1/2PP4/3BP3/PP3PPP/RNQKN1BR w HAha - 2 9 +perft 1 31 +perft 2 992 +perft 3 30213 +perft 4 986631 +perft 5 30397368 +perft 6 1011631987 + +id 1 +epd r1qknrbb/pppp1p2/2n3p1/4p2p/8/QPP5/P1NPPPPP/RN1K1RBB w FAfa - 2 9 +perft 1 30 +perft 2 702 +perft 3 21563 +perft 4 532939 +perft 5 16813114 +perft 6 438096194 + +id 1 +epd bbkr1qnr/2pppppp/2n5/pp6/8/PPN5/1BPPPPPP/1BR1KQNR w HC - 2 9 +perft 1 25 +perft 2 573 +perft 3 15183 +perft 4 380910 +perft 5 10554668 +perft 6 283975400 + +id 1 +epd 1rnbkqnr/1bpppppp/1p6/7P/p2P4/5P2/PPP1P1P1/BRNBKQNR w HBhb - 0 9 +perft 1 21 +perft 2 503 +perft 3 11790 +perft 4 301084 +perft 5 7679979 +perft 6 207799378 + +id 1 +epd brnkqbnr/2p1pppp/1p6/3p4/1pP5/P6P/3PPPP1/BRNKQBNR w HBhb - 0 9 +perft 1 28 +perft 2 743 +perft 3 21054 +perft 4 587192 +perft 5 17354516 +perft 6 507176753 + +id 1 +epd br1kqnrb/npp1pppp/8/3p4/p4N2/PP6/2PPPPPP/BR1KQNRB w GBgb - 0 9 +perft 1 31 +perft 2 808 +perft 3 25585 +perft 4 698475 +perft 5 22376575 +perft 6 640362920 + +id 1 +epd rbbnkq1r/pppppp1p/7n/6p1/P5P1/2P2N2/1P1PPP1P/RBBNKQ1R w HAha - 1 9 +perft 1 29 +perft 2 580 +perft 3 17585 +perft 4 404831 +perft 5 12730970 +perft 6 325226128 + +id 1 +epd rnbbk1nr/pp2qppp/2ppp3/8/3P4/P1N4N/1PP1PPPP/R1BBKQ1R w HAha - 0 9 +perft 1 29 +perft 2 838 +perft 3 24197 +perft 4 721884 +perft 5 21100580 +perft 6 646624429 + +id 1 +epd rnbk1b1r/ppppn1pp/4pp2/7q/7P/P5PB/1PPPPP2/RNBKQ1NR w HAha - 3 9 +perft 1 20 +perft 2 729 +perft 3 16633 +perft 4 576199 +perft 5 14507076 +perft 6 498621813 + +id 1 +epd r2kqnrb/pbppppp1/np5p/8/4Q1P1/3P4/PPP1PP1P/RNBK1NRB w GAga - 2 9 +perft 1 47 +perft 2 1219 +perft 3 55009 +perft 4 1486353 +perft 5 65239153 +perft 6 1834391369 + +id 1 +epd rbnkbq1r/p1p2ppp/1p2pn2/3p4/P3P3/3P4/1PP1KPPP/RBN1BQNR w ha - 2 9 +perft 1 29 +perft 2 923 +perft 3 27179 +perft 4 883866 +perft 5 26202752 +perft 6 868565895 + +id 1 +epd rk1bb1nr/ppppqppp/n7/1N2p3/6P1/7N/PPPPPP1P/R1KBBQ1R w HA - 6 9 +perft 1 27 +perft 2 703 +perft 3 19478 +perft 4 559525 +perft 5 16049807 +perft 6 492966455 + +id 1 +epd rnkqbbnr/p1ppp2p/1p4p1/8/1B3p1P/2NP4/PPP1PPP1/R1KQ1BNR w HAha - 0 9 +perft 1 29 +perft 2 610 +perft 3 18855 +perft 4 438277 +perft 5 14020041 +perft 6 355083962 + +id 1 +epd rnkqb1rb/pp1p1ppp/4p3/2P3n1/8/1PP5/P3PPPP/RNKQBNRB w GAga - 0 9 +perft 1 29 +perft 2 675 +perft 3 20699 +perft 4 535821 +perft 5 17000613 +perft 6 476598337 + +id 1 +epd rb1kqnbr/pp1pp1p1/1np2p2/7p/P1P3PP/8/1P1PPP2/RBNKQNBR w HAha - 0 9 +perft 1 31 +perft 2 1077 +perft 3 33661 +perft 4 1183381 +perft 5 37415304 +perft 6 1328374620 + +id 1 +epd rnkbq1br/ppp2ppp/3p4/Q3p1n1/5P2/3P2P1/PPP1P2P/RNKB1NBR w HAha - 0 9 +perft 1 41 +perft 2 1201 +perft 3 46472 +perft 4 1420367 +perft 5 52991625 +perft 6 1675608008 + +id 1 +epd rn1qnbbr/pp2pppp/2ppk3/8/2PP4/3Q1N2/PP2PPPP/RNK2BBR w HA - 1 9 +perft 1 34 +perft 2 666 +perft 3 22474 +perft 4 472299 +perft 5 15860369 +perft 6 353831792 + +id 1 +epd rnkqnr1b/ppppp1pp/5p2/8/Q1P2P2/8/PP1P2PP/RbK1NRBB w FAfa - 0 9 +perft 1 36 +perft 2 876 +perft 3 31987 +perft 4 788580 +perft 5 29022529 +perft 6 736717252 + +id 1 +epd bbrn1nqr/ppp1k1pp/5p2/3pp3/7P/3PN3/PPP1PPP1/BBRK1NQR w - - 1 9 +perft 1 24 +perft 2 583 +perft 3 15063 +perft 4 383532 +perft 5 10522064 +perft 6 280707118 + +id 1 +epd brnbkn1r/1pppp1p1/4q3/p4p1p/7P/1N3P2/PPPPP1PQ/BR1BKN1R w HBhb - 2 9 +perft 1 27 +perft 2 935 +perft 3 26120 +perft 4 885699 +perft 5 26000648 +perft 6 873063158 + +id 1 +epd br1knbqr/pp2p1pp/1n6/2pp1p2/6P1/2P4B/PP1PPPQP/BRNKN2R w HBhb - 0 9 +perft 1 27 +perft 2 681 +perft 3 19202 +perft 4 510687 +perft 5 14954779 +perft 6 415624943 + +id 1 +epd brnk1qrb/p1ppppp1/1p5p/8/P3n3/1N4P1/1PPPPPRP/BR1KNQ1B w Bgb - 0 9 +perft 1 22 +perft 2 638 +perft 3 13991 +perft 4 412346 +perft 5 9760752 +perft 6 293499724 + +id 1 +epd rbbnknqr/pppp3p/5pp1/8/1P1pP3/7P/P1P2PP1/RBBNKNQR w HAha - 0 9 +perft 1 29 +perft 2 756 +perft 3 21616 +perft 4 614074 +perft 5 17602252 +perft 6 528140595 + +id 1 +epd 1nbbknqr/rpp1ppp1/1Q1p3p/p7/2P2PP1/8/PP1PP2P/RNBBKN1R w HAh - 2 9 +perft 1 37 +perft 2 977 +perft 3 34977 +perft 4 944867 +perft 5 33695089 +perft 6 940198007 + +id 1 +epd rnb2bqr/ppkpppp1/3n3p/2p5/6PP/2N2P2/PPPPP3/R1BKNBQR w HA - 2 9 +perft 1 30 +perft 2 647 +perft 3 20365 +perft 4 467780 +perft 5 15115531 +perft 6 369257622 + +id 1 +epd rn1k1qrb/p1pppppp/bp6/8/4n3/P4BPP/1PPPPP2/RNBKNQR1 w GAga - 2 9 +perft 1 22 +perft 2 670 +perft 3 14998 +perft 4 451517 +perft 5 11199653 +perft 6 339919682 + +id 1 +epd rb2bnqr/nppkpppp/3p4/p7/1P6/P2N2P1/2PPPP1P/RB1KBNQR w HA - 3 9 +perft 1 22 +perft 2 479 +perft 3 11475 +perft 4 264739 +perft 5 6831555 +perft 6 167329117 + +id 1 +epd r1kbb1qr/2pppppp/np2n3/p7/2P3P1/8/PP1PPPQP/RNKBBN1R w HAha - 1 9 +perft 1 32 +perft 2 723 +perft 3 23953 +perft 4 581832 +perft 5 19472074 +perft 6 504622114 + +id 1 +epd rnknbb1r/p1ppp1pp/8/1p1P1p1q/8/P1P5/1P2PPPP/RNKNBBQR w HAha - 1 9 +perft 1 19 +perft 2 607 +perft 3 12733 +perft 4 417451 +perft 5 9753617 +perft 6 325177085 + +id 1 +epd rnkn1qrb/pp1bp1pp/2p5/1N1p1p2/8/2P5/PPKPPPPP/R2NBQRB w ga - 2 9 +perft 1 27 +perft 2 533 +perft 3 14549 +perft 4 330747 +perft 5 9206957 +perft 6 232664675 + +id 1 +epd r1nknqbr/pp2p1pp/2p2p2/3p4/6P1/PP1P4/2P1PP1b/RBNKNQBR w HAha - 0 9 +perft 1 20 +perft 2 582 +perft 3 13777 +perft 4 409166 +perft 5 10708639 +perft 6 326565393 + +id 1 +epd rnkb1qbr/p1pp1p1p/1p2pn2/1Q4p1/4P3/N4P2/PPPP2PP/R1KBN1BR w HAha - 0 9 +perft 1 40 +perft 2 1038 +perft 3 39356 +perft 4 1051441 +perft 5 39145902 +perft 6 1079612614 + +id 1 +epd rn2qbbr/1pkppp1p/p3n1p1/8/8/2P2P2/PP1PP1PP/RNKN1BBR w HA - 0 9 +perft 1 24 +perft 2 605 +perft 3 14888 +perft 4 385964 +perft 5 9687507 +perft 6 260874068 + +id 1 +epd rn1nqrbb/p1kppp1p/8/1pp3p1/1P6/2N1P3/P1PP1PPP/RK1NQRBB w - - 0 9 +perft 1 21 +perft 2 540 +perft 3 12489 +perft 4 337997 +perft 5 8436136 +perft 6 237525904 + +id 1 +epd bbrnknrq/1pp3pp/p2p1p2/4p3/P7/1P2N3/2PPPPPP/BBRN1RKQ w gc - 0 9 +perft 1 24 +perft 2 527 +perft 3 13900 +perft 4 326175 +perft 5 9139962 +perft 6 226253685 + +id 1 +epd brnb1nrq/pppp1kpp/4p3/8/5p1P/P1P3P1/1P1PPP2/BRNBKNRQ w GB - 1 9 +perft 1 29 +perft 2 773 +perft 3 23904 +perft 4 638768 +perft 5 20503775 +perft 6 560338709 + +id 1 +epd br1k1brq/ppppp2p/1n1n1pp1/8/P1P5/3P2P1/1P2PP1P/BRNKNBRQ w GBgb - 0 9 +perft 1 28 +perft 2 811 +perft 3 23550 +perft 4 664880 +perft 5 19913758 +perft 6 565143976 + +id 1 +epd 1r1knrqb/n1pppppp/p1b5/1p6/8/3N1P2/PPPPP1PP/BRNK1RQB w fb - 3 9 +perft 1 29 +perft 2 753 +perft 3 23210 +perft 4 620019 +perft 5 20044474 +perft 6 558383603 + +id 1 +epd rbbnk1rq/pppppppp/8/3Pn3/8/4P1P1/PPP2P1P/RBBNKNRQ w GAga - 1 9 +perft 1 22 +perft 2 551 +perft 3 12619 +perft 4 324608 +perft 5 8204171 +perft 6 217689974 + +id 1 +epd rnbbk1rq/2pppp1p/p3n1p1/1p6/P3N3/8/1PPPPPPP/RNBB1KRQ w ga - 0 9 +perft 1 26 +perft 2 742 +perft 3 20061 +perft 4 599527 +perft 5 16787080 +perft 6 525678162 + +id 1 +epd rnbkn1rq/ppppppb1/6p1/7p/2B2P2/1P2P3/P1PP2PP/RNBKN1RQ w GAga - 1 9 +perft 1 28 +perft 2 799 +perft 3 23210 +perft 4 689436 +perft 5 20755098 +perft 6 639632905 + +id 1 +epd rn1knrqb/p2pppp1/b1p5/1p5p/2P2P2/1P6/P2PP1PP/RNBKNRQB w FAfa - 1 9 +perft 1 30 +perft 2 579 +perft 3 18481 +perft 4 397545 +perft 5 13257198 +perft 6 311282465 + +id 1 +epd rbnkbnrq/pp2p1Np/2p2p2/8/3p4/8/PPPPPPPP/RBNKBR1Q w Aga - 0 9 +perft 1 23 +perft 2 670 +perft 3 16435 +perft 4 501883 +perft 5 13012378 +perft 6 411860744 + +id 1 +epd rk1bbnrq/ppp1pppp/n7/3p4/5P2/3P2NP/PPP1P1P1/RNKBB1RQ w GA - 0 9 +perft 1 26 +perft 2 597 +perft 3 16238 +perft 4 402506 +perft 5 11269462 +perft 6 296701249 + +id 1 +epd r1knbbrq/pppp2p1/2n1p2p/5p2/4P3/P1PP4/1P3PPP/RNKNBBRQ w GAga - 1 9 +perft 1 20 +perft 2 596 +perft 3 13091 +perft 4 399069 +perft 5 9416862 +perft 6 293659781 + +id 1 +epd rnknbrqb/p1p1pp1p/3p4/1p1N2p1/8/N7/PPPPPPPP/1RK1BRQB w Ffa - 0 9 +perft 1 26 +perft 2 724 +perft 3 18942 +perft 4 552040 +perft 5 15257204 +perft 6 461293885 + +id 1 +epd rbnknrb1/1p1ppp1p/p1p3p1/8/1P3P2/1R6/PqPPP1PP/RBNKN1BQ w Afa - 0 9 +perft 1 31 +perft 2 1183 +perft 3 34723 +perft 4 1289502 +perft 5 38722152 +perft 6 1421492227 + +id 1 +epd rnkbnrbq/2p1ppp1/p7/1p1p3p/3P4/1P4P1/P1P1PP1P/RNKBNRBQ w FAfa - 0 9 +perft 1 24 +perft 2 506 +perft 3 12748 +perft 4 301464 +perft 5 8086100 +perft 6 207129256 + +id 1 +epd r1knrbbq/pp1ppppp/2p1n3/8/2P3P1/P7/1PKPPP1P/RN1NRBBQ w ea - 0 9 +perft 1 28 +perft 2 570 +perft 3 16037 +perft 4 352471 +perft 5 10278695 +perft 6 242592363 + +id 1 +epd rnknrq1b/ppp1p1p1/4b3/3p1p1p/6P1/P4P2/1PPPPQ1P/RNKNR1BB w EAea - 2 9 +perft 1 30 +perft 2 739 +perft 3 23124 +perft 4 594962 +perft 5 19252739 +perft 6 521629794 + +id 1 +epd bbqr1krn/pppp1p1p/5n2/4p1p1/3P4/P3QP2/1PP1P1PP/BB1RNKRN w GDgd - 0 9 +perft 1 31 +perft 2 799 +perft 3 25627 +perft 4 674913 +perft 5 22172123 +perft 6 609277274 + +id 1 +epd bq1b1krn/pp1ppppp/3n4/2r5/3p3N/6N1/PPP1PPPP/BQRB1KR1 w GCg - 2 9 +perft 1 21 +perft 2 798 +perft 3 18571 +perft 4 688429 +perft 5 17546069 +perft 6 647165916 + +id 1 +epd bqrnkbrn/2pp1pp1/p7/1p2p2p/1P6/4N3/P1PPPPPP/BQR1KBRN w GCgc - 0 9 +perft 1 27 +perft 2 783 +perft 3 22327 +perft 4 670798 +perft 5 20059741 +perft 6 624462073 + +id 1 +epd bqr1krnb/1np1pppp/8/pp1p4/8/2P2N2/PP1PPPPP/BQRNKR1B w FCfc - 0 9 +perft 1 28 +perft 2 636 +perft 3 18874 +perft 4 461104 +perft 5 14237097 +perft 6 372181570 + +id 1 +epd qbb1rkrn/1ppppppp/p7/7n/8/P2P4/1PP1PPPP/QBBRNKRN w Gg - 0 9 +perft 1 25 +perft 2 547 +perft 3 13837 +perft 4 332918 +perft 5 8849383 +perft 6 229112926 + +id 1 +epd 1rbbnkrn/p1p1pp1p/2q5/1p1p2p1/8/2P3P1/PP1PPP1P/QRBBNKRN w GBgb - 2 9 +perft 1 24 +perft 2 1010 +perft 3 24370 +perft 4 983770 +perft 5 24328258 +perft 6 961371180 + +id 1 +epd qrb1kbrn/ppp1p2p/4npp1/3p4/8/1PP4P/PR1PPPP1/Q1BNKBRN w Ggb - 1 9 +perft 1 18 +perft 2 451 +perft 3 9291 +perft 4 247310 +perft 5 5568106 +perft 6 155744022 + +id 1 +epd qr2krnb/p1p1pppp/b1np4/1p6/3NP3/7P/PPPP1PP1/QRBNKR1B w FBfb - 2 9 +perft 1 25 +perft 2 667 +perft 3 17081 +perft 4 476030 +perft 5 12458875 +perft 6 361495148 + +id 1 +epd qbrnbkrn/ppp3pp/3p4/5p2/2P1pP2/6PP/PP1PP3/QBRNBKRN w GCgc - 0 9 +perft 1 24 +perft 2 650 +perft 3 16835 +perft 4 445263 +perft 5 12187382 +perft 6 326834539 + +id 1 +epd qrnb1krn/ppp1p1pp/5p2/2Np4/b2P4/2P5/PP2PPPP/QR1BBKRN w GBgb - 0 9 +perft 1 27 +perft 2 641 +perft 3 17490 +perft 4 432041 +perft 5 12103076 +perft 6 310695797 + +id 1 +epd qrnkbbrn/pp2pp2/8/2pp2pp/6PP/3P4/PPPKPP2/QRN1BBRN w gb - 0 9 +perft 1 22 +perft 2 554 +perft 3 13116 +perft 4 357404 +perft 5 9014737 +perft 6 258925091 + +id 1 +epd qrnkbrnb/p1p1ppp1/1p6/3p4/3P3p/5N1P/PPP1PPP1/QRNKBR1B w FBfb - 0 9 +perft 1 24 +perft 2 529 +perft 3 13205 +perft 4 318722 +perft 5 8295874 +perft 6 213856651 + +id 1 +epd qbr1krbn/1pppp1pp/p7/5pn1/2PP4/8/PPB1PPPP/Q1RNKRBN w FCfc - 0 9 +perft 1 26 +perft 2 831 +perft 3 21651 +perft 4 696830 +perft 5 18961456 +perft 6 621884383 + +id 1 +epd 1rnbkrbn/1qp1pppp/3p4/pp6/4P3/1NP4P/PP1P1PP1/QR1BKRBN w FBfb - 0 9 +perft 1 24 +perft 2 597 +perft 3 15089 +perft 4 404761 +perft 5 10832084 +perft 6 307793179 + +id 1 +epd q1rkrbbn/ppp1pppp/8/3p4/1PnP4/P7/1RP1PPPP/Q1NKRBBN w Ee - 1 9 +perft 1 20 +perft 2 520 +perft 3 10769 +perft 4 278067 +perft 5 6452205 +perft 6 170268300 + +id 1 +epd qrnkrn1b/ppppp1pp/4b3/7P/6p1/P7/1PPPPP2/QRNKRNBB w EBeb - 0 9 +perft 1 26 +perft 2 566 +perft 3 15623 +perft 4 381312 +perft 5 10940750 +perft 6 287987207 + +id 1 +epd bbr1nkrn/ppp1pppp/3q4/3p4/8/P7/1PPPPPPP/BBRQNRKN w gc - 5 9 +perft 1 19 +perft 2 661 +perft 3 13895 +perft 4 460396 +perft 5 10870247 +perft 6 356399665 + +id 1 +epd brqbnkrn/pp1pp2p/5pp1/2p5/4P3/P2P1N2/1PP2PPP/BRQB1KRN w GBgb - 0 9 +perft 1 27 +perft 2 679 +perft 3 19916 +perft 4 527306 +perft 5 16391730 +perft 6 455940859 + +id 1 +epd 2qnkbrn/p1pppppp/8/1r6/1p2bP2/7N/PPPPP1PP/BR1QKBRN w GBg - 4 9 +perft 1 18 +perft 2 774 +perft 3 15713 +perft 4 635461 +perft 5 14371755 +perft 6 559579332 + +id 1 +epd r1qnkr1b/p1pppppp/7n/1p6/8/1P3b1N/PRPPPPPP/B1QNK1RB w f - 5 9 +perft 1 21 +perft 2 677 +perft 3 15437 +perft 4 501520 +perft 5 12463801 +perft 6 410795298 + +id 1 +epd rbbqn1rn/pppp1pp1/3k4/4p2Q/2PPP3/8/PP3PPP/RBB1NKRN w GA - 1 9 +perft 1 40 +perft 2 742 +perft 3 28757 +perft 4 579833 +perft 5 21852196 +perft 6 471452088 + +id 1 +epd rqbbnkrn/3pppp1/p1p4p/1p6/5P2/P2N4/1PPPP1PP/RQBBK1RN w ga - 0 9 +perft 1 23 +perft 2 665 +perft 3 16400 +perft 4 492544 +perft 5 12794736 +perft 6 396640086 + +id 1 +epd r2nkbrn/pp2pppp/8/2ppqb2/2P3P1/5P2/PP1PPN1P/RQB1KBRN w GAga - 3 9 +perft 1 28 +perft 2 1108 +perft 3 31164 +perft 4 1194581 +perft 5 34780853 +perft 6 1292405738 + +id 1 +epd rqbnk1nb/p1pppr1p/5p2/1p4p1/1PP1P3/8/P2P1PPP/RQBNKRNB w FAa - 1 9 +perft 1 26 +perft 2 650 +perft 3 18208 +perft 4 491403 +perft 5 14565370 +perft 6 416833400 + +id 1 +epd rbqnb1rn/p1pp1kpp/1p2pp2/8/4P2P/P5P1/1PPP1P2/RBQNBKRN w GA - 0 9 +perft 1 20 +perft 2 437 +perft 3 9423 +perft 4 222154 +perft 5 5282124 +perft 6 132309824 + +id 1 +epd rqnbbkrn/p1p1pppp/3p4/1p5B/8/1P1NP3/P1PP1PPP/RQ2BKRN w GAga - 0 9 +perft 1 30 +perft 2 606 +perft 3 18382 +perft 4 422491 +perft 5 12989786 +perft 6 326601372 + +id 1 +epd rqnkbbr1/ppppp1pp/5p2/7n/8/2PNP2P/PP1P1PP1/RQ1KBBRN w GAga - 1 9 +perft 1 23 +perft 2 482 +perft 3 12506 +perft 4 297869 +perft 5 8430874 +perft 6 217797292 + +id 1 +epd r1nkbrnb/2ppppp1/1q6/pp5p/1P6/P3P3/2PPKPPP/RQN1BRNB w fa - 2 9 +perft 1 25 +perft 2 827 +perft 3 21518 +perft 4 701071 +perft 5 19290675 +perft 6 632892337 + +id 1 +epd rbqnkrbn/p1ppppp1/7p/1p6/7P/2N1P3/PPPP1PPB/RBQ1KR1N w FAfa - 1 9 +perft 1 30 +perft 2 627 +perft 3 18566 +perft 4 440217 +perft 5 12976682 +perft 6 337377291 + +id 1 +epd r1nbkrbn/p1qp1ppp/8/1pp1p3/2P1P3/6P1/PP1PBP1P/RQN1KRBN w FAfa - 2 9 +perft 1 22 +perft 2 616 +perft 3 14503 +perft 4 431199 +perft 5 10850952 +perft 6 335943324 + +id 1 +epd rqnkr1bn/ppp1ppb1/3p2pp/8/P7/2P2P2/1PKPP1PP/RQN1RBBN w ea - 1 9 +perft 1 31 +perft 2 679 +perft 3 21365 +perft 4 493500 +perft 5 15661072 +perft 6 379844460 + +id 1 +epd r2krnbb/qppp1ppp/1n6/p3p3/PP6/4N3/N1PPPPPP/RQ1KR1BB w EAea - 4 9 +perft 1 24 +perft 2 645 +perft 3 17054 +perft 4 487028 +perft 5 13837270 +perft 6 416239106 + +id 1 +epd bbr1qk1n/1ppppp1p/2n5/p7/P7/1P2P3/2PP1PrP/1BRNQKRN w GCc - 0 9 +perft 1 18 +perft 2 520 +perft 3 10680 +perft 4 304462 +perft 5 7215306 +perft 6 207612575 + +id 1 +epd brnbq1rn/2ppppkp/p5p1/1p6/8/1BP3P1/PP1PPP1P/BRN1QRKN w - - 0 9 +perft 1 21 +perft 2 625 +perft 3 13989 +perft 4 419667 +perft 5 9929336 +perft 6 300902534 + +id 1 +epd brn1kbrn/pp2p1pp/3p4/q1p2p2/2P4P/6P1/PP1PPP2/BRNQKBRN w GBgb - 1 9 +perft 1 18 +perft 2 477 +perft 3 10205 +perft 4 273925 +perft 5 6720181 +perft 6 187205941 + +id 1 +epd brn1krnb/p3pppp/1qpp4/1p6/2P3P1/1P6/P2PPP1P/BRNQKRNB w FBfb - 1 9 +perft 1 30 +perft 2 835 +perft 3 24761 +perft 4 716151 +perft 5 21806428 +perft 6 654487872 + +id 1 +epd r1b1qkrn/1p1ppppp/p1p1n3/8/4P3/1PN5/P1PPQPPb/RBB2KRN w GAga - 0 9 +perft 1 28 +perft 2 825 +perft 3 24536 +perft 4 716585 +perft 5 22079005 +perft 6 647939781 + +id 1 +epd r1bbqk1n/p1pppprp/n7/1p4p1/5P2/2N3N1/PPPPP1PP/1RBBQKR1 w Ga - 4 9 +perft 1 25 +perft 2 545 +perft 3 14657 +perft 4 358854 +perft 5 10271111 +perft 6 273864588 + +id 1 +epd rnbqkbrn/p1pp1pp1/4p3/7p/2p4P/2P5/PP1PPPP1/R1BQKBRN w GAga - 0 9 +perft 1 17 +perft 2 445 +perft 3 9076 +perft 4 255098 +perft 5 5918310 +perft 6 174733195 + +id 1 +epd rnbqkrnb/1p1pp1p1/2p4p/p4p2/3P2P1/7N/PPPBPP1P/RN1QKR1B w FAfa - 0 9 +perft 1 34 +perft 2 746 +perft 3 25319 +perft 4 623133 +perft 5 21285553 +perft 6 569141201 + +id 1 +epd rbnqbkr1/1ppppp2/p5n1/6pp/4P3/1N6/PPPP1PPP/RBQ1BRKN w ga - 2 9 +perft 1 18 +perft 2 466 +perft 3 9683 +perft 4 260864 +perft 5 6051500 +perft 6 170135726 + +id 1 +epd rnqb1krn/ppppp1p1/7p/7b/P1P2pPP/8/1P1PPP2/RNQBBKRN w GAga - 0 9 +perft 1 24 +perft 2 575 +perft 3 15400 +perft 4 385825 +perft 5 11039042 +perft 6 291243811 + +id 1 +epd rnqkbbr1/p1pp1ppp/4p3/1p6/P3P2n/5P2/1PPP1NPP/RNQKBBR1 w GAga - 2 9 +perft 1 27 +perft 2 803 +perft 3 22883 +perft 4 694449 +perft 5 20666099 +perft 6 638696065 + +id 1 +epd rn1kbrnb/1qppp1pp/1p6/p4p2/1B1P4/1P5N/P1P1PPPP/RNQK1R1B w FAfa - 0 9 +perft 1 37 +perft 2 1209 +perft 3 43015 +perft 4 1425600 +perft 5 49748034 +perft 6 1671593862 + +id 1 +epd rbnqkrbn/Bppp1p2/p5pp/4p3/5P2/6PP/PPPPP3/RBNQKR1N w FAfa - 0 9 +perft 1 29 +perft 2 720 +perft 3 20434 +perft 4 534148 +perft 5 15384362 +perft 6 421343249 + +id 1 +epd rnqbkr1n/1p1ppbpp/3p1p2/p7/8/1P6/P1PPPPPP/R1QBKRBN w FAfa - 0 9 +perft 1 20 +perft 2 657 +perft 3 14424 +perft 4 492678 +perft 5 11843134 +perft 6 413965054 + +id 1 +epd rnqkrb1n/ppppp3/6p1/5p1p/2b2P2/P1N5/1PPPP1PP/RQ1KRBBN w EAea - 1 9 +perft 1 28 +perft 2 749 +perft 3 20684 +perft 4 543151 +perft 5 15379233 +perft 6 417191461 + +id 1 +epd rnqk1nbb/1pp2ppp/3pr3/p3p3/3P1P2/2N3N1/PPP1P1PP/R1QKR1BB w EAa - 1 9 +perft 1 29 +perft 2 883 +perft 3 26412 +perft 4 815098 +perft 5 25144295 +perft 6 789705382 + +id 1 +epd bbr1kqrn/p1p1ppp1/1p2n2p/3p4/1P1P4/2N5/P1P1PPPP/BBR1KQRN w GCgc - 0 9 +perft 1 22 +perft 2 485 +perft 3 11475 +perft 4 271271 +perft 5 6825123 +perft 6 171793012 + +id 1 +epd brnbkq1n/ppp1ppr1/7p/3p2p1/2P3PP/8/PPBPPP2/BRN1KQRN w GBb - 2 9 +perft 1 30 +perft 2 634 +perft 3 19017 +perft 4 442537 +perft 5 13674310 +perft 6 345386924 + +id 1 +epd brnkqbr1/1pppp1pp/5p2/p7/P1P1P2n/8/1P1P1PP1/BRNKQBRN w GBgb - 0 9 +perft 1 21 +perft 2 504 +perft 3 11672 +perft 4 305184 +perft 5 7778289 +perft 6 217596497 + +id 1 +epd b1rkqrnb/p1ppp1pp/1p1n4/5p2/5P2/PN5P/1PPPP1P1/BR1KQRNB w FBf - 0 9 +perft 1 23 +perft 2 688 +perft 3 17259 +perft 4 531592 +perft 5 14228372 +perft 6 451842354 + +id 1 +epd 1bbnkqrn/rppppp2/p5p1/7p/7P/P1P1P3/1P1P1PP1/RBBNKQRN w GAg - 1 9 +perft 1 25 +perft 2 450 +perft 3 12391 +perft 4 263946 +perft 5 7752404 +perft 6 185393913 + +id 1 +epd rnbbkqr1/1pppppp1/7p/p3n3/PP5P/8/1BPPPPP1/RN1BKQRN w GAga - 0 9 +perft 1 23 +perft 2 543 +perft 3 12224 +perft 4 305812 +perft 5 7549008 +perft 6 199883770 + +id 1 +epd r1bkqbrn/ppppp1pp/8/5p2/3nPP2/1P4N1/P1PP2PP/RNBKQBR1 w GAga - 1 9 +perft 1 27 +perft 2 751 +perft 3 21158 +perft 4 600417 +perft 5 17989920 +perft 6 527273615 + +id 1 +epd rnbkqr1b/1p1pp1pp/p4p1n/2p5/1P5P/N4P2/P1PPP1P1/R1BKQRNB w FAfa - 0 9 +perft 1 21 +perft 2 498 +perft 3 11738 +perft 4 302278 +perft 5 7808375 +perft 6 216224115 + +id 1 +epd rbnkbqrn/p1p3pp/1p1p4/B3pp2/3P2P1/6N1/PPP1PP1P/RBNK1QR1 w GAga - 0 9 +perft 1 34 +perft 2 977 +perft 3 33464 +perft 4 961128 +perft 5 33318567 +perft 6 978991050 + +id 1 +epd r1kbbqrn/ppp3pp/2np1p2/1P2p3/3P1P2/8/P1P1P1PP/RNKBBQRN w GAga - 0 9 +perft 1 32 +perft 2 920 +perft 3 28916 +perft 4 844881 +perft 5 26763259 +perft 6 797524786 + +id 1 +epd rk1qbbrn/p2npppp/1p6/2p4Q/8/4P3/PPPP1PPP/RNK1B1RN w GA - 2 9 +perft 1 35 +perft 2 657 +perft 3 22359 +perft 4 495406 +perft 5 16662477 +perft 6 419496845 + +id 1 +epd rnk1brnb/pp1p1pp1/8/q1p1p2p/5P2/NP6/P1PPP1PP/R1KQBRNB w FAfa - 1 9 +perft 1 26 +perft 2 774 +perft 3 20215 +perft 4 610661 +perft 5 16987110 +perft 6 523437649 + +id 1 +epd rb1kqrbn/npp1ppp1/p7/3P3p/2PP4/8/PP3PPP/RBNKQRBN w FAfa - 0 9 +perft 1 35 +perft 2 775 +perft 3 27395 +perft 4 661118 +perft 5 23983464 +perft 6 625669222 + +id 1 +epd rnkb1rbn/pp1p2pp/8/2p1pp1q/P6P/1PN5/2PPPPP1/R1KBQRBN w FAfa - 1 9 +perft 1 22 +perft 2 899 +perft 3 21188 +perft 4 850597 +perft 5 21518343 +perft 6 857951339 + +id 1 +epd rnkqrbbn/1pppp1p1/8/p2N1p1p/2P4P/8/PP1PPPP1/R1KQRBBN w EAea - 0 9 +perft 1 29 +perft 2 585 +perft 3 17571 +perft 4 393221 +perft 5 12238776 +perft 6 299752383 + +id 1 +epd rnk1r1bb/pp1ppppp/1q4n1/2p5/5P1P/3PP3/PPP3P1/RNKQRNBB w EAea - 1 9 +perft 1 27 +perft 2 884 +perft 3 24613 +perft 4 811915 +perft 5 23698701 +perft 6 790239502 + +id 1 +epd bbrnkrqn/1ppp1p2/6pp/p3p3/5PP1/2PB4/PP1PP2P/B1RNKRQN w FCfc - 0 9 +perft 1 37 +perft 2 693 +perft 3 25425 +perft 4 550527 +perft 5 20138432 +perft 6 481498664 + +id 1 +epd b1rbkrqn/ppp2ppp/1n2p3/3p4/6P1/2PP4/PP2PP1P/BRNBKRQN w FBf - 1 9 +perft 1 21 +perft 2 463 +perft 3 10610 +perft 4 253204 +perft 5 6307276 +perft 6 159025909 + +id 1 +epd brnkrb1n/1pp1p1pp/3p4/p1Nq1p2/2P5/8/PP1PPPPP/BRK1RBQN w eb - 2 9 +perft 1 27 +perft 2 725 +perft 3 17842 +perft 4 496072 +perft 5 12604078 +perft 6 362747791 + +id 1 +epd brn1r1nb/ppppkppp/4p3/8/2PP1P2/8/PP1KP1PP/BRN1RQNB w - - 1 9 +perft 1 25 +perft 2 623 +perft 3 16874 +perft 4 426659 +perft 5 12290985 +perft 6 317097424 + +id 1 +epd rbb1krqn/1pp1pp1p/p3n1p1/3pP3/8/1PN5/P1PP1PPP/RBB1KRQN w FAfa d6 0 9 +perft 1 23 +perft 2 529 +perft 3 12641 +perft 4 310277 +perft 5 7861413 +perft 6 202594556 + +id 1 +epd r1bbkrqn/p1pppppp/8/4n3/1p5P/P2P2P1/1PP1PP2/RNBBKRQN w FAfa - 0 9 +perft 1 23 +perft 2 571 +perft 3 13133 +perft 4 346793 +perft 5 8699448 +perft 6 243460643 + +id 1 +epd rnbkrbqn/p1pp1ppp/4p3/1p6/8/BPN3P1/P1PPPP1P/R2KRBQN w EAea - 2 9 +perft 1 29 +perft 2 692 +perft 3 20014 +perft 4 500375 +perft 5 14904192 +perft 6 386694739 + +id 1 +epd rnbkrqn1/pppppp2/8/1Q2b1pp/P3P3/5P2/1PPP2PP/RNBKR1NB w EAea - 0 9 +perft 1 37 +perft 2 1001 +perft 3 36440 +perft 4 987842 +perft 5 35626426 +perft 6 993747544 + +id 1 +epd rbnkbrqn/p1pppp2/7p/1p4pP/3P1P2/8/PPP1P1P1/RBNKBRQN w FAfa - 0 9 +perft 1 30 +perft 2 564 +perft 3 17143 +perft 4 381364 +perft 5 11859538 +perft 6 293703269 + +id 1 +epd 1nkbbrqn/3ppppp/r1p5/pp6/8/4PP2/PPPPN1PP/RNKBBRQ1 w FAf - 2 9 +perft 1 26 +perft 2 546 +perft 3 14641 +perft 4 344592 +perft 5 9556962 +perft 6 245137199 + +id 1 +epd rnkrbbq1/pppppnp1/7p/8/1B1Q1p2/3P1P2/PPP1P1PP/RNKR1B1N w DAda - 2 9 +perft 1 43 +perft 2 887 +perft 3 36240 +perft 4 846858 +perft 5 33185346 +perft 6 851927292 + +id 1 +epd 1rkrbqnb/pppppp2/2n3p1/7p/3P3P/P4N2/1PP1PPP1/RNKRBQ1B w DAd - 0 9 +perft 1 26 +perft 2 622 +perft 3 16049 +perft 4 403921 +perft 5 10786140 +perft 6 285233838 + +id 1 +epd rbnkr1bn/pp1pqp1p/2p1p3/6p1/3P4/7P/PPP1PPP1/RBNKRQBN w EAea - 0 9 +perft 1 19 +perft 2 566 +perft 3 12257 +perft 4 381197 +perft 5 9107175 +perft 6 293397389 + +id 1 +epd r1kbrqb1/pppp2pp/2n1p1n1/5p1B/4PP2/P7/1PPP2PP/RNK1RQBN w EAea - 2 9 +perft 1 39 +perft 2 1359 +perft 3 53626 +perft 4 1876028 +perft 5 73871486 +perft 6 2633945690 + +id 1 +epd rnkrqbbn/p1p3pp/1p1ppp2/8/1P6/3P2P1/PKP1PP1P/RN1RQBBN w da - 0 9 +perft 1 26 +perft 2 776 +perft 3 20735 +perft 4 611907 +perft 5 16884013 +perft 6 503561996 + +id 1 +epd rnkrqnbb/ppp2p1p/3p4/4p1p1/3P3P/N1Q5/PPP1PPP1/R1KR1NBB w DAda - 0 9 +perft 1 40 +perft 2 1175 +perft 3 45637 +perft 4 1375884 +perft 5 52620163 +perft 6 1633655838 + +id 1 +epd bbrnkrn1/p1pppp2/1p6/6pp/3q4/1P3QP1/P1PPPP1P/BBRNKRN1 w FCfc - 0 9 +perft 1 34 +perft 2 1398 +perft 3 45749 +perft 4 1712950 +perft 5 57268492 +perft 6 2059942014 + +id 1 +epd br1bkrnq/1p2pppp/pnp5/3p4/P1P5/5P2/1P1PPKPP/BRNB1RNQ w fb - 2 9 +perft 1 24 +perft 2 501 +perft 3 12237 +perft 4 284936 +perft 5 7049659 +perft 6 177940764 + +id 1 +epd brnkrbn1/pppppp1q/B6p/6p1/8/1P2PP2/P1PP2PP/BRNKR1NQ w EBeb - 0 9 +perft 1 34 +perft 2 815 +perft 3 25868 +perft 4 700970 +perft 5 22006883 +perft 6 639803952 + +id 1 +epd br1krnqb/pppppp1p/1n4p1/8/8/P2NN3/2PPPPPP/BR1K1RQB w Beb - 2 9 +perft 1 37 +perft 2 1029 +perft 3 36748 +perft 4 1025712 +perft 5 36214583 +perft 6 1026195877 + +id 1 +epd rbbnkr1q/p1p2ppp/1p1ppn2/8/1PP4P/8/P2PPPP1/RBBNKRNQ w FAfa - 0 9 +perft 1 28 +perft 2 755 +perft 3 22623 +perft 4 605106 +perft 5 18972778 +perft 6 513486101 + +id 1 +epd r1b1krnq/pp2pppp/1bn5/2pp4/4N3/5P2/PPPPPRPP/R1BBK1NQ w Afa - 0 9 +perft 1 24 +perft 2 705 +perft 3 17427 +perft 4 532521 +perft 5 13532966 +perft 6 426443376 + +id 1 +epd 1nbkrbn1/rpppppqp/p7/6p1/4P3/3P2P1/PPP1KP1P/RNB1RBNQ w e - 1 9 +perft 1 31 +perft 2 800 +perft 3 24748 +perft 4 693366 +perft 5 21193292 +perft 6 625757852 + +id 1 +epd r1bkrnqb/pp3ppp/n1ppp3/8/1P5P/P7/R1PPPPP1/1NBKRNQB w Eea - 0 9 +perft 1 21 +perft 2 482 +perft 3 11417 +perft 4 275339 +perft 5 7112890 +perft 6 180378139 + +id 1 +epd rbnkbrnq/ppp1p2p/5p2/3p2p1/1B1P4/1N4P1/PPP1PP1P/RB1K1RNQ w FAfa - 0 9 +perft 1 33 +perft 2 780 +perft 3 25532 +perft 4 628945 +perft 5 20756770 +perft 6 535497008 + +id 1 +epd rnk1brnq/pp1ppppp/2p5/b7/8/1P2P2P/P1PP1PPQ/RNKBBRN1 w FAfa - 3 9 +perft 1 29 +perft 2 648 +perft 3 19043 +perft 4 449637 +perft 5 13722785 +perft 6 341389148 + +id 1 +epd rnkrbbnq/p1p3pp/5p2/1p1pp3/P7/1PN2P2/2PPP1PP/R1KRBBNQ w DAda - 0 9 +perft 1 26 +perft 2 827 +perft 3 21865 +perft 4 683167 +perft 5 18916370 +perft 6 589161126 + +id 1 +epd r1krbnqb/p1pp1ppp/2n1p3/8/1p4P1/PPP5/3PPP1P/RNKRBNQB w DAda - 1 9 +perft 1 25 +perft 2 540 +perft 3 14709 +perft 4 331332 +perft 5 9491817 +perft 6 225389422 + +id 1 +epd rbnkrnbq/ppp1pp2/3p2p1/2N5/P6p/2P5/1P1PPPPP/RB1KRNBQ w EAea - 0 9 +perft 1 32 +perft 2 790 +perft 3 25107 +perft 4 661207 +perft 5 20906017 +perft 6 578332225 + +id 1 +epd rnkbrn1q/1ppppppb/8/p4N1p/8/P1N5/1PPPPPPP/R1KBR1BQ w EAea - 0 9 +perft 1 31 +perft 2 691 +perft 3 20813 +perft 4 510665 +perft 5 15308408 +perft 6 404129987 + +id 1 +epd rnkrnbbq/p1p2ppp/3pp3/1p6/6P1/4PQ1B/PPPP1P1P/RNKRN1B1 w DAda - 0 9 +perft 1 29 +perft 2 558 +perft 3 16800 +perft 4 352887 +perft 5 10825379 +perft 6 246965507 + +id 1 +epd rnkrnqbb/pp2p1p1/3p3p/2p2p2/5P2/1P1N4/P1PPPQPP/RNKR2BB w DAda - 0 9 +perft 1 29 +perft 2 762 +perft 3 23210 +perft 4 644936 +perft 5 20522675 +perft 6 596067005 + +id 1 +epd bb1rknnr/ppqppppp/8/2p5/3P1N2/1P6/P1P1PPPP/BBQRKN1R w HDhd - 1 9 +perft 1 33 +perft 2 963 +perft 3 32279 +perft 4 1000890 +perft 5 34552118 +perft 6 1124738493 + +id 1 +epd bqrbknnr/ppp1p2p/8/3p1p2/5p2/P3N2P/1PPPP1P1/BQRBK1NR w HChc - 0 9 +perft 1 20 +perft 2 398 +perft 3 9009 +perft 4 194859 +perft 5 4834319 +perft 6 113660536 + +id 1 +epd b1rk1bnr/qpp1pppp/p4n2/3p4/3PPP2/7N/PPP3PP/BQRKNB1R w HChc - 1 9 +perft 1 25 +perft 2 648 +perft 3 16587 +perft 4 455720 +perft 5 12200870 +perft 6 351766307 + +id 1 +epd bqkrnnrb/pppp2p1/4pp2/4P2p/6P1/7P/PPPP1P2/BQRKNNRB w GC - 1 9 +perft 1 30 +perft 2 493 +perft 3 15118 +perft 4 280726 +perft 5 8786998 +perft 6 181492621 + +id 1 +epd q1brknnr/1p1ppppp/p7/2p5/8/1PPP4/P2RPPPP/QBB1KNNR w Hhd - 0 9 +perft 1 25 +perft 2 501 +perft 3 13206 +perft 4 290463 +perft 5 7982978 +perft 6 192717198 + +id 1 +epd qrb1k1nr/ppppb1pp/6n1/4ppN1/3P4/4N3/PPP1PPPP/QRBBK2R w HBhb - 2 9 +perft 1 31 +perft 2 872 +perft 3 26191 +perft 4 739276 +perft 5 22493014 +perft 6 646855304 + +id 1 +epd 1rbknbnr/1ppp1pp1/q6p/p3p3/5P2/2PPB3/PP2P1PP/QR1KNBNR w HBhb - 0 9 +perft 1 28 +perft 2 1020 +perft 3 28147 +perft 4 984000 +perft 5 27484692 +perft 6 947786800 + +id 1 +epd qrbk2rb/1ppp1ppp/5nn1/p3p3/1N6/P7/1PPPPPPP/QRB1KNRB w gb - 0 9 +perft 1 23 +perft 2 592 +perft 3 14398 +perft 4 395716 +perft 5 10098215 +perft 6 293988585 + +id 1 +epd qbrk1nnr/1pp1pppp/2b5/p2p4/P2P2P1/8/1PP1PP1P/QBKRBNNR w hc - 1 9 +perft 1 26 +perft 2 654 +perft 3 18103 +perft 4 471653 +perft 5 13740891 +perft 6 373081138 + +id 1 +epd qrkbbnnr/ppp2p1p/4p3/3p2p1/P7/2PP4/1P2PPPP/QRKBBNNR w HBhb - 0 9 +perft 1 25 +perft 2 626 +perft 3 16616 +perft 4 431634 +perft 5 12079406 +perft 6 324006164 + +id 1 +epd qr1kbbnr/ppp1pp1p/4n1p1/2Pp4/6P1/4N3/PP1PPP1P/QRK1BBNR w HB d6 0 9 +perft 1 26 +perft 2 699 +perft 3 18068 +perft 4 497152 +perft 5 13353359 +perft 6 375702908 + +id 1 +epd qrk1b1rb/p1pppppp/3nnQ2/1p6/1P3P2/3P4/P1P1P1PP/1RKNBNRB w GBgb - 3 9 +perft 1 43 +perft 2 1369 +perft 3 55463 +perft 4 1831200 +perft 5 71514365 +perft 6 2427477375 + +id 1 +epd qbrk1nbr/pppp3p/5n2/4ppp1/3P1P2/4N3/PPP1P1PP/QBKRN1BR w hc - 0 9 +perft 1 25 +perft 2 752 +perft 3 20165 +perft 4 615263 +perft 5 17493373 +perft 6 543180234 + +id 1 +epd qrkb1nbr/1pppppQp/3n4/p7/5p2/1P1N4/P1PPP1PP/1RKB1NBR w HBhb - 0 9 +perft 1 45 +perft 2 946 +perft 3 40100 +perft 4 966903 +perft 5 39736157 +perft 6 1051910977 + +id 1 +epd qrk1nbbr/ppp1p1p1/4n2p/3p1p2/1P5P/3P2P1/P1P1PP2/QRKNNBBR w HBhb - 1 9 +perft 1 32 +perft 2 770 +perft 3 25367 +perft 4 646977 +perft 5 21717615 +perft 6 577979364 + +id 1 +epd qrkn1rbb/pp2pppp/2p5/3p4/P2Qn1P1/1P6/2PPPP1P/1RKNNRBB w FBfb - 0 9 +perft 1 38 +perft 2 943 +perft 3 35335 +perft 4 868165 +perft 5 31909835 +perft 6 798405123 + +id 1 +epd bbrqknnr/ppp4p/3pp3/5pp1/4PP2/5Q2/PPPP2PP/BBR1KNNR w HChc - 0 9 +perft 1 36 +perft 2 843 +perft 3 29974 +perft 4 758528 +perft 5 26828059 +perft 6 723306114 + +id 1 +epd 1rqbkn1r/p1p1pppp/1p5n/P2p4/3Pb1P1/8/1PP1PP1P/BRQBKNNR w HBhb - 0 9 +perft 1 23 +perft 2 778 +perft 3 19482 +perft 4 649789 +perft 5 17337683 +perft 6 579112676 + +id 1 +epd br1knbnr/1qp1pppp/pp1p4/8/8/PP6/2PPPPPP/BRQKNBNR w HBhb - 2 9 +perft 1 26 +perft 2 697 +perft 3 18835 +perft 4 546622 +perft 5 15280079 +perft 6 473071890 + +id 1 +epd brqk2rb/ppppp1pp/4np2/8/2n5/3P1Q2/PP2PPPP/BR1KNNRB w GBgb - 0 9 +perft 1 32 +perft 2 948 +perft 3 30434 +perft 4 885713 +perft 5 29821322 +perft 6 874251866 + +id 1 +epd r1bqknnr/pp1pp1p1/5p1p/2p1b2N/2P5/8/PPQPPPPP/RBB1K1NR w HAha - 0 9 +perft 1 31 +perft 2 785 +perft 3 25549 +perft 4 659952 +perft 5 22244193 +perft 6 592797491 + +id 1 +epd rqbbknnr/ppppp2p/5pp1/8/8/1P3PP1/PQPPP2P/R1BBKNNR w HAha - 0 9 +perft 1 23 +perft 2 391 +perft 3 10163 +perft 4 198450 +perft 5 5576671 +perft 6 121267576 + +id 1 +epd rqbknbnr/1pp1p2p/p7/3p1pp1/7N/1PP5/P2PPPPP/RQBK1BNR w HAha - 0 9 +perft 1 27 +perft 2 676 +perft 3 19606 +perft 4 522428 +perft 5 15955388 +perft 6 448477218 + +id 1 +epd rqb1nnrb/2ppkppp/1p2p3/p7/2PPP3/1P6/P4PPP/RQBKNNRB w GA - 1 9 +perft 1 31 +perft 2 727 +perft 3 22895 +perft 4 570647 +perft 5 18361051 +perft 6 483248153 + +id 1 +epd rb1kbn1r/p1ppppp1/qp5n/7p/P7/RPP5/3PPPPP/1BQKBNNR w Hha - 2 9 +perft 1 29 +perft 2 837 +perft 3 23815 +perft 4 730083 +perft 5 21279560 +perft 6 682863811 + +id 1 +epd rqkbb1nr/p1p2ppp/1p1p2n1/3Np3/4P3/5N2/PPPP1PPP/RQKBB2R w HAha - 0 9 +perft 1 28 +perft 2 717 +perft 3 20663 +perft 4 550987 +perft 5 16347343 +perft 6 453153783 + +id 1 +epd rqknbbr1/p1pppp1p/1p3np1/8/4P3/2P2P1P/PP1P2P1/RQKNBBNR w HAa - 0 9 +perft 1 27 +perft 2 650 +perft 3 18231 +perft 4 475303 +perft 5 13847463 +perft 6 383256006 + +id 1 +epd r1k1bnrb/1qpppppp/1p2n3/p7/1P5P/6P1/P1PPPP2/RQKNBNR1 w GAga - 1 9 +perft 1 24 +perft 2 806 +perft 3 20693 +perft 4 713220 +perft 5 19382263 +perft 6 686009788 + +id 1 +epd rb1knnbr/1pp1ppp1/p2p3p/5q2/3B2P1/3P1P2/PPP1P2P/RBQKNN1R w HAha - 0 9 +perft 1 34 +perft 2 1360 +perft 3 44096 +perft 4 1605706 +perft 5 51973672 +perft 6 1837704407 + +id 1 +epd rqkb1nbr/p1p1ppp1/1p3n1p/2Qp4/8/2P5/PP1PPPPP/R1KBNNBR w HAha - 2 9 +perft 1 39 +perft 2 983 +perft 3 38218 +perft 4 940989 +perft 5 36347815 +perft 6 918801645 + +id 1 +epd rqknnbbr/2pppp2/pp5p/6p1/1P1P4/4PP2/P1P3PP/RQKNNBBR w HAha - 0 9 +perft 1 26 +perft 2 628 +perft 3 17638 +perft 4 464924 +perft 5 13787303 +perft 6 386125234 + +id 1 +epd rqkn1rbb/1pp1pppp/p7/3p4/3Pn3/2P1PP2/PP4PP/RQKNNRBB w FAfa - 1 9 +perft 1 20 +perft 2 527 +perft 3 12216 +perft 4 321533 +perft 5 8082183 +perft 6 219311659 + +id 1 +epd bbrkqn1r/1pppppp1/5n2/p7/1PP2P1p/7N/P2PP1PP/BBRKQN1R w HChc - 1 9 +perft 1 36 +perft 2 963 +perft 3 35291 +perft 4 973839 +perft 5 35907489 +perft 6 1034223364 + +id 1 +epd brkbqn1r/p2ppppp/7n/1p6/P1p3PP/8/1PPPPP1N/BRKBQ1NR w HBhb - 0 9 +perft 1 18 +perft 2 583 +perft 3 11790 +perft 4 394603 +perft 5 8858385 +perft 6 304339862 + +id 1 +epd brkq1bnr/pp1ppp1p/8/2p2np1/P7/8/1PPPPPPP/BRKQNBNR w HBhb - 0 9 +perft 1 19 +perft 2 552 +perft 3 11811 +perft 4 354260 +perft 5 8432183 +perft 6 262293169 + +id 1 +epd brkqnnrb/1ppppppp/8/8/p3P3/5N2/PPPP1PPP/BRKQ1NRB w GBgb - 3 9 +perft 1 21 +perft 2 397 +perft 3 9653 +perft 4 204350 +perft 5 5489836 +perft 6 128389738 + +id 1 +epd rbbkq1nr/1p2pppp/p1p3nB/3p4/1Q1P4/6N1/PPP1PPPP/RB1K2NR w HAha - 0 9 +perft 1 40 +perft 2 1132 +perft 3 43404 +perft 4 1260470 +perft 5 47425783 +perft 6 1415578783 + +id 1 +epd rkbbq1nr/1pppp1p1/4np2/p6p/8/PP3P2/1KPPP1PP/R1BBQNNR w ha - 0 9 +perft 1 24 +perft 2 596 +perft 3 15220 +perft 4 402121 +perft 5 10822049 +perft 6 302056813 + +id 1 +epd r1bqn1nr/pkpppp1p/1p4pb/8/PN6/R7/1PPPPPPP/1KBQ1BNR w H - 2 9 +perft 1 33 +perft 2 794 +perft 3 25450 +perft 4 649150 +perft 5 20919309 +perft 6 561073410 + +id 1 +epd rkb1nnrb/1pppq1pp/p4p2/4p3/5P2/1P1PB3/P1P1P1PP/RK1QNNRB w GAga - 0 9 +perft 1 26 +perft 2 625 +perft 3 17050 +perft 4 442036 +perft 5 12515042 +perft 6 342967558 + +id 1 +epd rbkqbn1r/pppp1p1p/2n1p1p1/8/8/1P1PP1N1/P1P2PPP/RBKQB1NR w HAha - 1 9 +perft 1 30 +perft 2 660 +perft 3 20308 +perft 4 492714 +perft 5 15348335 +perft 6 403323883 + +id 1 +epd rkqbb1n1/pppppppr/8/6np/5P2/8/PPPPP1PP/RKQBBNNR w HAa - 6 9 +perft 1 23 +perft 2 500 +perft 3 12154 +perft 4 292936 +perft 5 7519117 +perft 6 196524441 + +id 1 +epd rkqnbbnr/ppppppp1/8/7p/3N4/6PP/PPPPPP2/RKQNBB1R w HAa - 0 9 +perft 1 24 +perft 2 484 +perft 3 12495 +perft 4 284570 +perft 5 7775173 +perft 6 193947530 + +id 1 +epd rkqnb1rb/p1p1pppp/1p1p4/2n5/3P4/2P1N1N1/PP2PPPP/RKQ1B1RB w GAga - 0 9 +perft 1 28 +perft 2 1020 +perft 3 29124 +perft 4 1027904 +perft 5 30515456 +perft 6 1073711823 + +id 1 +epd rbk1nnbr/1ppq1ppp/p2p4/4p3/P3B2P/2P5/1P1PPPP1/R1KQNNBR w HAha - 2 9 +perft 1 38 +perft 2 998 +perft 3 37265 +perft 4 1047592 +perft 5 38552638 +perft 6 1139322479 + +id 1 +epd r1qbn1br/k1pppppp/6n1/pp6/5P1P/P7/1PPPP1PB/RKQBNN1R w HA - 1 9 +perft 1 22 +perft 2 549 +perft 3 12867 +perft 4 348574 +perft 5 8725809 +perft 6 251613569 + +id 1 +epd rkqnn1br/pppp3p/4p1pb/5p2/P2P4/7P/1PP1PPPB/RKQNNB1R w HAha - 1 9 +perft 1 32 +perft 2 659 +perft 3 21249 +perft 4 469701 +perft 5 15434721 +perft 6 365761521 + +id 1 +epd rk1nnrbb/p1p1pppp/1p6/3p1q2/P3P3/2NN4/1PPP1PPP/RKQ2RBB w FAfa - 3 9 +perft 1 29 +perft 2 989 +perft 3 29087 +perft 4 980477 +perft 5 29643404 +perft 6 998848556 + +id 1 +epd bbrk1q1r/ppppppp1/3n4/7p/3Pn3/6PN/PPP1PPNP/BBRK1Q1R w HChc - 2 9 +perft 1 23 +perft 2 712 +perft 3 16551 +perft 4 516177 +perft 5 12995202 +perft 6 411077508 + +id 1 +epd brkbnq1r/p1ppp2p/5ppn/1p6/5P2/1P1P2P1/P1P1P2P/BRKBNQNR w HBhb - 0 9 +perft 1 28 +perft 2 856 +perft 3 24984 +perft 4 780503 +perft 5 23529352 +perft 6 754501112 + +id 1 +epd br1k1bnr/ppppp1pp/4np2/1B2P2q/3P4/8/PPP2PPP/BRKNQ1NR w HB - 3 9 +perft 1 36 +perft 2 1214 +perft 3 40615 +perft 4 1328331 +perft 5 45096834 +perft 6 1470987023 + +id 1 +epd brk1qnrb/pnppp1p1/1p6/5p1p/8/5PPP/PPPPP1R1/BRKNQN1B w Bgb - 0 9 +perft 1 22 +perft 2 551 +perft 3 13111 +perft 4 353317 +perft 5 9040545 +perft 6 259643605 + +id 1 +epd rbbkn1nr/1ppp2pp/p3p3/2q2p2/3P4/6P1/PPPBPP1P/RB1KNQNR w HAha - 0 9 +perft 1 31 +perft 2 1060 +perft 3 31332 +perft 4 1015099 +perft 5 30314172 +perft 6 976268967 + +id 1 +epd rkbbn1nr/ppppp1pp/8/6N1/5p2/1q6/P1PPPPPP/RKBBN1QR w HAha - 0 9 +perft 1 3 +perft 2 72 +perft 3 1919 +perft 4 50827 +perft 5 1400832 +perft 6 39654253 + +id 1 +epd rkb2bnr/pp2pppp/2p1n3/3p4/q2P4/5NP1/PPP1PP1P/RKBNQBR1 w Aha - 0 9 +perft 1 29 +perft 2 861 +perft 3 24504 +perft 4 763454 +perft 5 22763215 +perft 6 731511256 + +id 1 +epd rkbq1nrb/ppppppp1/7p/8/1P1n4/P4P1P/2PPP1P1/RKBNQNRB w GAga - 0 9 +perft 1 25 +perft 2 672 +perft 3 17631 +perft 4 473864 +perft 5 12954224 +perft 6 361237536 + +id 1 +epd rbknb1nr/ppp1qp1p/6p1/3pp3/3P3P/2B1P3/PPP2PP1/RBKN1QNR w HAha - 1 9 +perft 1 27 +perft 2 857 +perft 3 24688 +perft 4 792538 +perft 5 23790033 +perft 6 768247869 + +id 1 +epd rknbbq1r/p1pppppp/1p2N3/8/3n4/2P5/PP1PPPPP/RK1BBQNR w HAha - 4 9 +perft 1 29 +perft 2 763 +perft 3 22138 +perft 4 574054 +perft 5 16926075 +perft 6 447896703 + +id 1 +epd r1nqbbnr/1pppp1pp/1k6/p4p2/8/4P3/PPPP1PPP/RKN1BBNR w HA - 0 9 +perft 1 26 +perft 2 658 +perft 3 17302 +perft 4 464039 +perft 5 12380488 +perft 6 349047256 + +id 1 +epd rkn2qrb/ppp1pppp/6n1/1b1p4/1P6/4PPB1/P1PP2PP/RKNQ1NRB w GAga - 3 9 +perft 1 23 +perft 2 574 +perft 3 14070 +perft 4 370324 +perft 5 9501401 +perft 6 263870337 + +id 1 +epd rbkn2br/ppppp1p1/4np1p/1P5q/8/2P1N3/P2PPPPP/RBK1QNBR w HAha - 1 9 +perft 1 29 +perft 2 992 +perft 3 29506 +perft 4 999564 +perft 5 30148787 +perft 6 1045942540 + +id 1 +epd 1knbqnbr/1ppppp1p/r5p1/p7/7P/2PN2P1/PP1PPP2/RK1BQNBR w HAh - 2 9 +perft 1 26 +perft 2 698 +perft 3 19395 +perft 4 512023 +perft 5 14848229 +perft 6 402599313 + +id 1 +epd rk1qnbbr/pnpppp1p/6p1/1p6/3P4/1P6/P1P1PPPP/RKNQNBBR w HAha - 1 9 +perft 1 20 +perft 2 480 +perft 3 11159 +perft 4 287539 +perft 5 7425917 +perft 6 203194521 + +id 1 +epd rknqnrbb/pp1p2p1/5p1p/2p1p3/2P1P3/P2P4/1P3PPP/RKNQNRBB w FAfa - 0 9 +perft 1 26 +perft 2 679 +perft 3 18116 +perft 4 494953 +perft 5 13790137 +perft 6 392629571 + +id 1 +epd bbrk2qr/pp1p1ppp/3n2n1/2p1p3/3P1P2/6N1/PPP1P1PP/BBRKN1QR w HChc - 0 9 +perft 1 26 +perft 2 790 +perft 3 21521 +perft 4 673269 +perft 5 19259490 +perft 6 617563700 + +id 1 +epd b1krnnqr/1p1ppppp/p1p5/b6B/P7/4P1N1/1PPP1PPP/BRK1N1QR w HB - 2 9 +perft 1 26 +perft 2 625 +perft 3 16451 +perft 4 415452 +perft 5 11490615 +perft 6 304805107 + +id 1 +epd 1rknnbqr/3ppppp/p7/1pp5/4b2P/P4P2/1PPPP1PR/BRKNNBQ1 w Bhb - 1 9 +perft 1 24 +perft 2 757 +perft 3 19746 +perft 4 618777 +perft 5 17275100 +perft 6 544309489 + +id 1 +epd br1nn1rb/pppkpqpp/3p1p2/8/PP6/4N3/1KPPPPPP/BR2NQRB w - - 3 9 +perft 1 24 +perft 2 682 +perft 3 17129 +perft 4 482711 +perft 5 13057308 +perft 6 375033550 + +id 1 +epd rbbkn1qr/pppp2p1/6np/4pp2/7N/7P/PPPPPPPR/RBBK1NQ1 w Aha - 0 9 +perft 1 22 +perft 2 586 +perft 3 14158 +perft 4 409891 +perft 5 10607781 +perft 6 324452612 + +id 1 +epd rk1bn1qr/pppbpppp/4n3/4p3/4P3/5P2/PPPP2PP/RKBB1NQR w HAha - 1 9 +perft 1 22 +perft 2 530 +perft 3 13440 +perft 4 348004 +perft 5 9514787 +perft 6 259898748 + +id 1 +epd rkbnnbqr/1ppp1ppp/p7/4p3/8/QP3P2/P1PPP1PP/RKBNNB1R w HAha - 0 9 +perft 1 29 +perft 2 705 +perft 3 21511 +perft 4 551042 +perft 5 17524731 +perft 6 472356665 + +id 1 +epd 1kbnnqrb/1pp1p1pp/r4p2/p2p4/N4P2/3P4/PPP1P1PP/RKB1NQRB w GAg - 2 9 +perft 1 21 +perft 2 623 +perft 3 14979 +perft 4 437554 +perft 5 11601134 +perft 6 343214006 + +id 1 +epd rbknbn1r/pppp1p1p/4p1q1/8/P1P3Pp/8/1P1PPP2/RBKNBNQR w HAha - 0 9 +perft 1 30 +perft 2 813 +perft 3 24959 +perft 4 708454 +perft 5 23379040 +perft 6 692576573 + +id 1 +epd rk1bb1qr/2pppppp/p2nn3/1p4P1/6QP/8/PPPPPP2/RKNBBN1R w HAha - 2 9 +perft 1 36 +perft 2 857 +perft 3 30124 +perft 4 757524 +perft 5 26485812 +perft 6 696999449 + +id 1 +epd rkn1bbqr/p2ppppp/2p1n3/1p6/4PP2/6PP/PPPP4/RKNNBBQR w HAha - 0 9 +perft 1 33 +perft 2 687 +perft 3 22744 +perft 4 511018 +perft 5 17101732 +perft 6 412778368 + +id 1 +epd rkn1bqrb/pnp1pppp/3p4/8/Pp6/1N2NP2/1PPPP1PP/RK2BQRB w GAga - 0 9 +perft 1 28 +perft 2 591 +perft 3 17174 +perft 4 406025 +perft 5 12182448 +perft 6 312575205 + +id 1 +epd rbk1n1br/ppp1ppqp/2n5/2Np2p1/8/2P5/PPBPPPPP/R1KN1QBR w HAha - 4 9 +perft 1 35 +perft 2 930 +perft 3 30663 +perft 4 844433 +perft 5 27160490 +perft 6 780616047 + +id 1 +epd rknbn1br/1ppp1ppp/p3p3/8/1q6/2P2N1P/P2PPPP1/RKNB1QBR w HAha - 0 9 +perft 1 4 +perft 2 157 +perft 3 3697 +perft 4 138102 +perft 5 3454704 +perft 6 125373395 + +id 1 +epd rkn1qbbr/pp3ppp/4n3/2ppp3/4P1P1/P2P4/1PP2P1P/RKNNQBBR w HAha - 0 9 +perft 1 28 +perft 2 840 +perft 3 24437 +perft 4 771328 +perft 5 23200961 +perft 6 756489357 + +id 1 +epd rkn1qrbb/pp1ppp2/2p1n1p1/7p/2P2P1P/6P1/PP1PP3/RKNNQRBB w FAfa - 1 9 +perft 1 32 +perft 2 867 +perft 3 27595 +perft 4 757836 +perft 5 24485663 +perft 6 688115847 + +id 1 +epd b1rknnrq/bpppp1p1/p6p/5p1P/6P1/4N3/PPPPPP2/BBRKN1RQ w GCgc - 1 9 +perft 1 33 +perft 2 851 +perft 3 28888 +perft 4 763967 +perft 5 26686205 +perft 6 731944177 + +id 1 +epd brkb1nr1/pppppp2/3n2pp/3B4/1P6/4P3/PqPP1PPP/BRK1NNRQ w GBgb - 2 9 +perft 1 4 +perft 2 98 +perft 3 2965 +perft 4 76143 +perft 5 2352530 +perft 6 64251468 + +id 1 +epd brk1nbrq/1ppppn1p/6p1/p4p2/P5P1/5R2/1PPPPP1P/BRKNNB1Q w Bgb - 0 9 +perft 1 29 +perft 2 922 +perft 3 27709 +perft 4 879527 +perft 5 27463717 +perft 6 888881062 + +id 1 +epd brkn1rqb/1p1ppppp/3n4/p1p5/1P3P2/8/PNPPP1PP/BR1KNRQB w fb - 1 9 +perft 1 29 +perft 2 633 +perft 3 19399 +perft 4 469818 +perft 5 15076198 +perft 6 396737074 + +id 1 +epd rb1k1nrq/pbp1pppp/1p1p1n2/8/5P2/4NN1P/PPPPP1P1/RBBK2RQ w GAga - 2 9 +perft 1 28 +perft 2 841 +perft 3 24056 +perft 4 710751 +perft 5 20772996 +perft 6 613798447 + +id 1 +epd rkbbnnrq/p1pp3p/4p1p1/1p3p2/P6P/1P6/1BPPPPP1/RK1BNNRQ w GAga - 0 9 +perft 1 33 +perft 2 957 +perft 3 30668 +perft 4 907217 +perft 5 29735654 +perft 6 903933626 + +id 1 +epd rk2nbrq/p1ppppp1/bpn5/7p/6P1/2N2P2/PPPPP1QP/RKB1NBR1 w GAga - 2 9 +perft 1 24 +perft 2 687 +perft 3 18206 +perft 4 544627 +perft 5 15518417 +perft 6 484217179 + +id 1 +epd rkbn1r1b/pp1pppnp/6q1/2p3p1/5P1P/4N3/PPPPP1P1/RKB1NRQB w FAfa - 1 9 +perft 1 23 +perft 2 831 +perft 3 21254 +perft 4 754622 +perft 5 21126103 +perft 6 744755212 + +id 1 +epd rbknb1rq/ppp1p1p1/3pnp1p/8/6PP/2PP4/PP2PP2/RBKNBNRQ w GAga - 0 9 +perft 1 31 +perft 2 838 +perft 3 26800 +perft 4 736910 +perft 5 24008129 +perft 6 677776408 + +id 1 +epd rknbb1rq/p1pn1ppp/4p3/1p1p4/2P5/1P2N1P1/P2PPP1P/RKNBB1RQ w GAga - 1 9 +perft 1 29 +perft 2 830 +perft 3 24798 +perft 4 721630 +perft 5 22243832 +perft 6 660040360 + +id 1 +epd rk1nbbrq/pp1p1ppp/3n4/P3p3/2p4P/8/1PPPPPP1/RKNNBBRQ w GAga - 1 9 +perft 1 24 +perft 2 484 +perft 3 12776 +perft 4 297419 +perft 5 8379748 +perft 6 214004367 + +id 1 +epd rknnbr1b/ppp2pqp/3p4/4p1p1/7P/3P1P2/PPP1P1P1/RKNNBRQB w FAfa - 0 9 +perft 1 32 +perft 2 838 +perft 3 26408 +perft 4 740701 +perft 5 23472124 +perft 6 699211365 + +id 1 +epd rb1k1rbq/ppppN1pp/2nn4/5p2/7P/8/PPPPPPP1/RBK1NRBQ w FA - 1 9 +perft 1 27 +perft 2 800 +perft 3 22785 +perft 4 701742 +perft 5 20804424 +perft 6 660917073 + +id 1 +epd r1nbnrbq/kppppp1p/6p1/8/p1PP1P2/4P3/PP4PP/RKNBNRBQ w FA - 1 9 +perft 1 28 +perft 2 757 +perft 3 21198 +perft 4 602699 +perft 5 17180857 +perft 6 507618340 + +id 1 +epd rkn1rbbq/p1pppppp/2n5/1pP5/8/1N2P3/PP1P1PPP/RK1NRBBQ w EAea - 1 9 +perft 1 22 +perft 2 483 +perft 3 11890 +perft 4 283679 +perft 5 7497674 +perft 6 191130942 + +id 1 +epd rknnrqbb/2pppppp/8/p7/Np3P2/3P4/PPP1P1PP/RKN1RQBB w EAea - 0 9 +perft 1 25 +perft 2 536 +perft 3 14456 +perft 4 339180 +perft 5 9694947 +perft 6 245669668 + +id 1 +epd bb1rknrn/1qppppp1/1p4B1/p6N/8/2P5/PP1PPPPP/B1QRK1RN w GDgd - 1 9 +perft 1 32 +perft 2 715 +perft 3 22421 +perft 4 575008 +perft 5 17860156 +perft 6 502410909 + +id 1 +epd b1rbknrn/qpp1ppp1/p6p/3p4/2P5/1P1P1P2/P3P1PP/BQRBKNRN w GCgc - 0 9 +perft 1 30 +perft 2 818 +perft 3 24421 +perft 4 688711 +perft 5 20981488 +perft 6 611986786 + +id 1 +epd bqkrnbrn/1pp1pp1p/p7/1B1p2p1/4P3/7P/PPPP1PP1/BQKRN1RN w - - 0 9 +perft 1 28 +perft 2 676 +perft 3 18366 +perft 4 478054 +perft 5 13126287 +perft 6 363765666 + +id 1 +epd bqrknrnb/1p2ppp1/p1pp3p/8/3P1P2/1PP5/P3P1PP/BQRKNRNB w FCfc - 0 9 +perft 1 31 +perft 2 646 +perft 3 20686 +perft 4 455607 +perft 5 14984618 +perft 6 349082278 + +id 1 +epd qbbrkn1r/pppppp1p/8/6p1/2P1Pn1P/6N1/PP1P1PP1/QBBRKNR1 w GDd - 3 9 +perft 1 20 +perft 2 532 +perft 3 11581 +perft 4 303586 +perft 5 7512432 +perft 6 202967948 + +id 1 +epd 1rbbknr1/p1ppp1pp/1pq2pn1/8/3P4/P3P3/QPP2PPP/1RBBKNRN w GBgb - 3 9 +perft 1 31 +perft 2 1002 +perft 3 30581 +perft 4 999607 +perft 5 30642468 +perft 6 1009228283 + +id 1 +epd qrbkn1rn/pppp1ppp/8/6b1/P1P1Pp2/8/1P1P2PP/QRBKNBRN w GBgb - 0 9 +perft 1 22 +perft 2 505 +perft 3 12447 +perft 4 304863 +perft 5 8192621 +perft 6 214730959 + +id 1 +epd qrbk1rnb/p2ppp1p/5n2/1pp3p1/8/7P/PPPPPPPN/QRBKR1NB w Bfb - 0 9 +perft 1 20 +perft 2 619 +perft 3 13448 +perft 4 449630 +perft 5 10571176 +perft 6 369603424 + +id 1 +epd qbrkb1r1/ppp2ppp/3pn1n1/P3p3/4P3/3P4/1PP2PPP/QBRKBNRN w GCgc - 1 9 +perft 1 26 +perft 2 755 +perft 3 20596 +perft 4 604483 +perft 5 17164382 +perft 6 510878835 + +id 1 +epd qrkbb1r1/ppp1pnpp/3p2n1/5p2/1P3P2/2Q3N1/P1PPP1PP/1RKBB1RN w GBgb - 0 9 +perft 1 35 +perft 2 918 +perft 3 32244 +perft 4 870888 +perft 5 30933394 +perft 6 867833733 + +id 1 +epd qrknbbrn/ppp1ppp1/8/7p/2Bp4/4PPP1/PPPP3P/QRKNB1RN w GBgb - 0 9 +perft 1 27 +perft 2 593 +perft 3 16168 +perft 4 376808 +perft 5 10422676 +perft 6 258348640 + +id 1 +epd qrk1brnb/ppppp3/4n2p/5pp1/2PP4/2N4P/PP2PPP1/QRK1BRNB w FBfb - 2 9 +perft 1 24 +perft 2 672 +perft 3 17447 +perft 4 506189 +perft 5 13765777 +perft 6 414930519 + +id 1 +epd qbrknrb1/p2ppppp/2p3n1/8/p4P2/6PP/1PPPP3/QBRKNRBN w FCfc - 0 9 +perft 1 29 +perft 2 759 +perft 3 23235 +perft 4 634493 +perft 5 20416668 +perft 6 584870558 + +id 1 +epd 1rkb1rbn/p1pp1ppp/3np3/1p6/4qP2/3NB3/PPPPPRPP/QRKB3N w Bfb - 0 9 +perft 1 22 +perft 2 923 +perft 3 22585 +perft 4 914106 +perft 5 24049880 +perft 6 957218571 + +id 1 +epd 1rknrbbn/p1pp1p1p/8/1p2p1p1/4qPP1/2P5/PP1PP1BP/QRKNR1BN w EBeb - 0 9 +perft 1 28 +perft 2 1309 +perft 3 36355 +perft 4 1568968 +perft 5 44576409 +perft 6 1846382333 + +id 1 +epd qrk1rn1b/ppppp2p/4n3/3b1pp1/4P2P/5BP1/PPPP1P2/QRKNRNB1 w EBeb - 3 9 +perft 1 26 +perft 2 839 +perft 3 22189 +perft 4 726354 +perft 5 19978260 +perft 6 661207281 + +id 1 +epd bbrqk1rn/pp1ppppp/8/2p5/2P1P3/5n1P/PPBP1PP1/B1RQKNRN w GCgc - 1 9 +perft 1 3 +perft 2 95 +perft 3 2690 +perft 4 85038 +perft 5 2518864 +perft 6 80775549 + +id 1 +epd brqbk2n/pppppprp/8/6p1/1P3n2/5P2/P1PPP1PP/R1QBKNRN w Gb - 2 9 +perft 1 22 +perft 2 593 +perft 3 13255 +perft 4 362760 +perft 5 8922397 +perft 6 253271592 + +id 1 +epd brqknbr1/pp3ppp/3p2n1/2p1p3/2P5/5P2/PPKPP1PP/BRQ1NBRN w gb - 0 9 +perft 1 21 +perft 2 590 +perft 3 13190 +perft 4 397355 +perft 5 9581695 +perft 6 304103516 + +id 1 +epd 1rqknrnb/2pp1ppp/p3p3/1p6/P2P4/5bP1/1PP1PP1P/BRQKNRNB w FBfb - 0 9 +perft 1 24 +perft 2 737 +perft 3 20052 +perft 4 598439 +perft 5 17948681 +perft 6 536330341 + +id 1 +epd rbb1k1rn/p1pqpppp/6n1/1p1p4/5P2/3PP3/PPP1K1PP/RBBQ1NRN w ga - 3 9 +perft 1 24 +perft 2 694 +perft 3 16773 +perft 4 513782 +perft 5 13094823 +perft 6 419402704 + +id 1 +epd rqbbknr1/1ppp2pp/p5n1/4pp2/P7/1PP5/1Q1PPPPP/R1BBKNRN w GAga - 0 9 +perft 1 24 +perft 2 600 +perft 3 15347 +perft 4 408207 +perft 5 11029596 +perft 6 308553169 + +id 1 +epd rqbknbrn/2pppppp/6Q1/pp6/8/2P5/PP1PPPPP/R1BKNBRN w GAga - 2 9 +perft 1 40 +perft 2 949 +perft 3 34100 +perft 4 889887 +perft 5 31296485 +perft 6 881529007 + +id 1 +epd rqbknr1b/pp1ppp2/2p2n1p/6p1/8/3P1PPP/PPP1P3/RQBKNRNB w FAfa - 0 9 +perft 1 20 +perft 2 560 +perft 3 12275 +perft 4 373921 +perft 5 8687544 +perft 6 277906201 + +id 1 +epd rbqkbnrn/p3pppp/1p6/3p4/P1p3P1/1P6/1QPPPP1P/RB1KBNRN w GAga - 0 9 +perft 1 30 +perft 2 1155 +perft 3 35865 +perft 4 1351455 +perft 5 43092716 +perft 6 1614019629 + +id 1 +epd rqkbb1rn/p1p1pppn/1p1p4/7p/4PP2/7P/PPPPB1P1/RQK1BNRN w GAga - 1 9 +perft 1 30 +perft 2 701 +perft 3 20804 +perft 4 515942 +perft 5 15450970 +perft 6 401499189 + +id 1 +epd rqknbbrn/1p2pp1p/3p2p1/p1p5/P2P4/1P6/1KP1PPPP/RQ1NBBRN w ga - 0 9 +perft 1 28 +perft 2 756 +perft 3 21655 +perft 4 610320 +perft 5 17989811 +perft 6 525585996 + +id 1 +epd rqknbrnb/1pp3pp/5p2/p2pp3/P7/3PPN2/1PP2PPP/RQKNBR1B w FAfa - 0 9 +perft 1 26 +perft 2 731 +perft 3 19509 +perft 4 550395 +perft 5 15209404 +perft 6 439767476 + +id 1 +epd rbqkr1bn/p1pppp1p/1p1n4/6p1/7P/3P1PP1/PPP1P3/RBQKNRBN w FAa - 0 9 +perft 1 27 +perft 2 586 +perft 3 16282 +perft 4 381604 +perft 5 10905865 +perft 6 274364342 + +id 1 +epd rqk1nrb1/ppbp1ppp/4p1n1/2p5/7P/1PP5/P2PPPP1/RQKBNRBN w FAfa - 1 9 +perft 1 27 +perft 2 749 +perft 3 21480 +perft 4 602318 +perft 5 18084787 +perft 6 520547029 + +id 1 +epd rqknrbbn/pp1p1ppp/4p3/2p5/3P2P1/7P/PPP1PP2/RQKNRBBN w EAa - 0 9 +perft 1 20 +perft 2 533 +perft 3 11829 +perft 4 336248 +perft 5 8230417 +perft 6 245871540 + +id 1 +epd rqknrnbb/pp1ppp1p/2p3p1/8/8/1P2P1NP/P1PP1PP1/RQKNR1BB w EAea - 0 9 +perft 1 22 +perft 2 633 +perft 3 14480 +perft 4 441877 +perft 5 10827868 +perft 6 343525739 + +id 1 +epd 1brkq1rn/2pppppp/1p2n3/p2bN3/8/7P/PPPPPPP1/BBRKQ1RN w GCgc - 2 9 +perft 1 27 +perft 2 748 +perft 3 20134 +perft 4 580054 +perft 5 16010135 +perft 6 475206624 + +id 1 +epd brkbqnrn/2pp1ppp/8/1p2p3/Pp2N3/8/2PPPPPP/BRKBQNR1 w GBgb - 0 9 +perft 1 30 +perft 2 827 +perft 3 25308 +perft 4 757837 +perft 5 23746165 +perft 6 751690068 + +id 1 +epd brk1nbrn/pp1ppppp/2p5/7P/5P2/q2P4/PPP1P1P1/BRKQNBRN w GBgb - 1 9 +perft 1 15 +perft 2 471 +perft 3 8716 +perft 4 276424 +perft 5 5960901 +perft 6 190316951 + +id 1 +epd brkqnrnb/1p1pp1p1/p4p2/2p4p/8/P2PP3/1PP1QPPP/BRK1NRNB w FBfb - 0 9 +perft 1 24 +perft 2 479 +perft 3 12584 +perft 4 280081 +perft 5 7830230 +perft 6 190419716 + +id 1 +epd rbbkqnrn/2ppp2p/pp3p2/6p1/P6P/8/RPPPPPP1/1BBKQNRN w Gga - 0 9 +perft 1 21 +perft 2 523 +perft 3 12125 +perft 4 328733 +perft 5 8322614 +perft 6 242240658 + +id 1 +epd rkbbqr1n/1ppppppn/7p/p7/4P3/2P2P2/PP1PB1PP/RKB1QNRN w GAa - 3 9 +perft 1 27 +perft 2 563 +perft 3 16026 +perft 4 372148 +perft 5 11105151 +perft 6 283211800 + +id 1 +epd rkbqnbrn/ppppp3/8/5ppp/2P3P1/7P/PPQPPP2/RKB1NBRN w GAga - 0 9 +perft 1 28 +perft 2 639 +perft 3 19250 +perft 4 469250 +perft 5 14872172 +perft 6 384663405 + +id 1 +epd rkb1nrnb/pppp1pp1/5q1p/8/P3p3/4R1P1/1PPPPP1P/1KBQNRNB w Ffa - 0 9 +perft 1 28 +perft 2 873 +perft 3 23690 +perft 4 720814 +perft 5 20209424 +perft 6 625281937 + +id 1 +epd rbkqb1rn/1p1ppppp/4n3/p1p5/8/3PBP2/PPP1P1PP/RBKQ1NRN w GAga - 0 9 +perft 1 26 +perft 2 798 +perft 3 21416 +perft 4 667496 +perft 5 18475618 +perft 6 591681956 + +id 1 +epd rk1qbnrn/1p1ppppp/1b6/p1p5/P7/2P3NP/1P1PPPP1/RKQBB1RN w GAga - 0 9 +perft 1 22 +perft 2 506 +perft 3 12313 +perft 4 301029 +perft 5 7891676 +perft 6 205739580 + +id 1 +epd rk1nbbrn/ppp1ppp1/8/3p3p/1P1P2q1/5PB1/P1P1P1PP/RKQN1BRN w GAga - 1 9 +perft 1 31 +perft 2 956 +perft 3 29219 +perft 4 903799 +perft 5 27827461 +perft 6 876341492 + +id 1 +epd rkqnbr1b/pp1pppp1/7p/2p2n2/P2P4/7N/RPP1PPPP/1KQNBR1B w Ffa - 0 9 +perft 1 31 +perft 2 750 +perft 3 24267 +perft 4 646252 +perft 5 21639104 +perft 6 617064197 + +id 1 +epd rbkq1rbn/2p1pppp/pp3n2/3p4/5P2/3N2N1/PPPPP1PP/RBKQR1B1 w Afa - 2 9 +perft 1 26 +perft 2 647 +perft 3 18027 +perft 4 465119 +perft 5 13643783 +perft 6 369702807 + +id 1 +epd rkqbr1bn/p2ppppp/1pp2n2/8/5P2/3P1N2/PPP1PRPP/RKQB2BN w Aa - 3 9 +perft 1 24 +perft 2 574 +perft 3 14593 +perft 4 371597 +perft 5 10066892 +perft 6 271121237 + +id 1 +epd rk1qrbbn/p1ppp1pp/1p2n3/5p2/1P6/K3N3/P1PPPPPP/R1Q1RBBN w ea - 0 9 +perft 1 25 +perft 2 548 +perft 3 14069 +perft 4 340734 +perft 5 9043111 +perft 6 235545764 + +id 1 +epd rkqnrnbb/pp1pp3/2p5/5ppp/8/PP4NP/2PPPPP1/RKQNR1BB w EAea - 0 9 +perft 1 23 +perft 2 727 +perft 3 18228 +perft 4 566572 +perft 5 15078056 +perft 6 471296844 + +id 1 +epd bbrknq1r/ppppppp1/8/7p/5n2/3P4/PPP1PNPP/BBKRNQR1 w c - 0 9 +perft 1 21 +perft 2 610 +perft 3 13300 +perft 4 394705 +perft 5 9605845 +perft 6 293532398 + +id 1 +epd brkbnqr1/2pppnpp/pp3p2/8/4PPPP/8/PPPP4/BRKBNQRN w GBgb - 1 9 +perft 1 30 +perft 2 757 +perft 3 23908 +perft 4 621332 +perft 5 20360394 +perft 6 548380577 + +id 1 +epd brk1qb1n/ppppppr1/2n3pp/8/2P3P1/2N5/PP1PPP1P/BR1KQBRN w b - 1 9 +perft 1 26 +perft 2 570 +perft 3 15537 +perft 4 352883 +perft 5 10081351 +perft 6 242864559 + +id 1 +epd brknq1nb/pp2prpp/8/2pP1p2/6P1/2N5/PPPP1P1P/BRK1QRNB w FBb - 1 9 +perft 1 33 +perft 2 830 +perft 3 27897 +perft 4 764915 +perft 5 26262884 +perft 6 765831403 + +id 1 +epd rbbk1qrn/ppp1p1pp/5p2/3p1n2/7N/P7/1PPPPPPP/RBB1KQRN w ga - 0 9 +perft 1 21 +perft 2 562 +perft 3 13060 +perft 4 378883 +perft 5 9520963 +perft 6 290579255 + +id 1 +epd rk1b1qrn/ppp1pppp/5n2/3pN3/P6P/7b/1PPPPPP1/RKBB1QRN w GAga - 4 9 +perft 1 28 +perft 2 677 +perft 3 19235 +perft 4 488740 +perft 5 14354779 +perft 6 383207197 + +id 1 +epd rkbnqbrn/pp1ppp1p/2p5/6p1/P7/4P3/KPPPQPPP/R1BN1BRN w - - 3 9 +perft 1 28 +perft 2 585 +perft 3 17443 +perft 4 401483 +perft 5 12574541 +perft 6 310495538 + +id 1 +epd rk1nqrnb/pbpppp2/1p4p1/7p/P7/5NP1/1PPPPPBP/RKBNQR2 w FAfa - 2 9 +perft 1 26 +perft 2 774 +perft 3 21626 +perft 4 645200 +perft 5 19093408 +perft 6 576325868 + +id 1 +epd rbknb1rn/p1pp2pp/1p6/4pp2/1q3P1B/2N5/PPPPPNPP/RBK2QR1 w GAga - 2 9 +perft 1 31 +perft 2 1206 +perft 3 36940 +perft 4 1374158 +perft 5 42849564 +perft 6 1555711209 + +id 1 +epd rk1bbqrn/pp1pp1pp/3n4/5p2/3p4/1PP5/PK2PPPP/R1NBBQRN w ga - 0 9 +perft 1 21 +perft 2 629 +perft 3 14059 +perft 4 429667 +perft 5 10587910 +perft 6 332632033 + +id 1 +epd rknqbbr1/p1pp1pp1/1p4n1/4p2p/4P1P1/6RB/PPPP1P1P/RKNQB2N w Aga - 0 9 +perft 1 27 +perft 2 753 +perft 3 20918 +perft 4 593155 +perft 5 17318772 +perft 6 507563675 + +id 1 +epd rknqbr1b/pppp1ppp/4p2n/8/1P3P2/4P3/P1PPN1PP/RKNQBR1B w FAfa - 2 9 +perft 1 26 +perft 2 623 +perft 3 17177 +perft 4 460663 +perft 5 13389799 +perft 6 383508368 + +id 1 +epd r2kqrbn/bppppppp/2n5/p4B2/5P2/2P5/PP1PP1PP/1RKNQRBN w F - 2 9 +perft 1 39 +perft 2 1026 +perft 3 37800 +perft 4 1011922 +perft 5 35946987 +perft 6 992756232 + +id 1 +epd rk1bqrb1/ppppppp1/1n6/7p/2P2P1n/4P1Q1/PP1P2PP/RKNB1RBN w FAfa - 0 9 +perft 1 35 +perft 2 760 +perft 3 25817 +perft 4 610557 +perft 5 21014787 +perft 6 536852043 + +id 1 +epd rkq1rb1n/ppppp1pp/1n6/5p2/PPb2P2/8/1KPPP1PP/R1NQRBBN w ea - 1 9 +perft 1 27 +perft 2 754 +perft 3 21009 +perft 4 568788 +perft 5 16461795 +perft 6 448313956 + +id 1 +epd rknqr2b/pppnp1pp/3p4/3b1p2/8/1N1P2N1/PPP1PPPP/RKQ1R1BB w EAea - 1 9 +perft 1 27 +perft 2 803 +perft 3 23708 +perft 4 700453 +perft 5 21875031 +perft 6 654754840 + +id 1 +epd bbrknrqn/ppppp1pB/8/2P2p1p/8/5N2/PP1PPPPP/B1RK1RQN w FCfc - 0 9 +perft 1 30 +perft 2 799 +perft 3 23923 +perft 4 671112 +perft 5 20532790 +perft 6 603059376 + +id 1 +epd brkbnrq1/1pppp1p1/6np/p4p2/4P3/1PP5/P1KP1PPP/BR1BNRQN w fb - 1 9 +perft 1 27 +perft 2 726 +perft 3 19329 +perft 4 555622 +perft 5 15156662 +perft 6 457601127 + +id 1 +epd brknrbq1/1p1p1ppp/p3p1n1/2p5/8/1P1BPP2/P1PP2PP/BRKNR1QN w EBeb - 0 9 +perft 1 36 +perft 2 786 +perft 3 27868 +perft 4 655019 +perft 5 22852433 +perft 6 577223409 + +id 1 +epd brknrqnb/p2ppp1p/2p5/1p6/3P2p1/P1P1N3/1P2PPPP/BRK1RQNB w EBeb - 0 9 +perft 1 23 +perft 2 649 +perft 3 15169 +perft 4 440504 +perft 5 10687843 +perft 6 320881984 + +id 1 +epd rbbk1rqn/1ppppppp/3n4/p7/2P5/3N4/PP1PPPPP/RBB1KRQN w fa - 1 9 +perft 1 20 +perft 2 478 +perft 3 11094 +perft 4 275250 +perft 5 7094988 +perft 6 185488058 + +id 1 +epd rkbbnrqn/p2p1ppp/1p2p3/8/P1p1P3/1BP5/1P1P1PPP/RKB1NRQN w FAfa - 0 9 +perft 1 22 +perft 2 570 +perft 3 13295 +perft 4 346811 +perft 5 8671852 +perft 6 229898448 + +id 1 +epd rkb1rb1n/ppppppqp/8/2n3p1/2P1P1P1/8/PP1P1P1P/RKBNRBQN w EAea - 1 9 +perft 1 23 +perft 2 663 +perft 3 16212 +perft 4 490748 +perft 5 12900485 +perft 6 404944553 + +id 1 +epd rkb1rqnb/pppp3p/2n3p1/4pp2/P2P3P/2P5/1P2PPP1/RKBNRQNB w EAea - 0 9 +perft 1 25 +perft 2 845 +perft 3 22188 +perft 4 741972 +perft 5 20276176 +perft 6 683290790 + +id 1 +epd rbk1brqn/ppp1pppp/8/3p4/7P/1P4P1/2PPPP2/RBKNBRQN w FAfa - 0 9 +perft 1 24 +perft 2 526 +perft 3 13862 +perft 4 322175 +perft 5 9054028 +perft 6 222704171 + +id 1 +epd rknbbrqn/pp3pp1/4p3/2pp3p/2P5/8/PPBPPPPP/RKN1BRQN w FAfa - 0 9 +perft 1 26 +perft 2 756 +perft 3 19280 +perft 4 559186 +perft 5 14697705 +perft 6 433719427 + +id 1 +epd 1knrbbqn/rp1p1ppp/p3p3/2p5/8/5P1P/PPPPP1P1/RKNRBBQN w DAd - 0 9 +perft 1 26 +perft 2 539 +perft 3 15194 +perft 4 345070 +perft 5 10223443 +perft 6 248715580 + +id 1 +epd rknr1qnb/ppp1p1pp/3p2b1/8/4p3/1P3P1P/P1PP2P1/RKNRBQNB w DAda - 0 9 +perft 1 25 +perft 2 701 +perft 3 18969 +perft 4 561369 +perft 5 16047041 +perft 6 496340789 + +id 1 +epd rbk1r1bn/ppppp1pp/4n3/5p2/1P3P2/4N2P/PqPPP1P1/RBK1RQBN w EAea - 1 9 +perft 1 2 +perft 2 60 +perft 3 1319 +perft 4 41765 +perft 5 1017864 +perft 6 33183408 + +id 1 +epd r1nbrqbn/k1ppp1pp/1p6/p4p2/2P5/6PQ/PP1PPP1P/RKNBR1BN w EA - 0 9 +perft 1 27 +perft 2 699 +perft 3 20436 +perft 4 561765 +perft 5 17192121 +perft 6 499247248 + +id 1 +epd rknrqbbn/1pp1pp2/p5p1/3p3p/6P1/PN5P/1PPPPP2/RK1RQBBN w DAda - 0 9 +perft 1 23 +perft 2 611 +perft 3 15515 +perft 4 435927 +perft 5 11917036 +perft 6 352885930 + +id 1 +epd rknrqn1b/p1pp1ppb/8/1p2p1Qp/3P4/3N4/PPP1PPPP/RK1R1NBB w DAda - 0 9 +perft 1 45 +perft 2 1170 +perft 3 48283 +perft 4 1320341 +perft 5 52213677 +perft 6 1500007485 + +id 1 +epd bbkrnrnq/p2p1ppp/2p1p3/1p6/1P2Q3/6P1/P1PPPP1P/BBKRNRN1 w - - 0 9 +perft 1 41 +perft 2 1035 +perft 3 39895 +perft 4 1035610 +perft 5 38555608 +perft 6 1037686769 + +id 1 +epd brkbnr2/1ppppp1p/7n/p5N1/P2q4/8/1PPPPPPP/BRKBNRQ1 w FBfb - 1 9 +perft 1 22 +perft 2 869 +perft 3 19234 +perft 4 679754 +perft 5 16453359 +perft 6 567287944 + +id 1 +epd brknrbnq/p1ppppp1/1p6/7p/2PP4/5P2/PPK1P1PP/BR1NRBNQ w eb - 1 9 +perft 1 23 +perft 2 641 +perft 3 14748 +perft 4 422240 +perft 5 10192718 +perft 6 302864305 + +id 1 +epd brk1r1qb/pp1ppnpp/2p2pn1/8/6N1/2N3P1/PPPPPP1P/BRK1R1QB w EBeb - 3 9 +perft 1 32 +perft 2 863 +perft 3 28379 +perft 4 773191 +perft 5 25848794 +perft 6 720443112 + +id 1 +epd rbbk1rnq/pppp1pp1/4p2p/8/3P2n1/4BN1P/PPP1PPP1/RB1K1RNQ w FAfa - 3 9 +perft 1 26 +perft 2 628 +perft 3 16151 +perft 4 411995 +perft 5 11237919 +perft 6 300314373 + +id 1 +epd rkbbnr1q/p1pppppp/5n2/1p5B/PP6/4P3/2PP1PPP/RKB1NRNQ w FAfa - 0 9 +perft 1 30 +perft 2 692 +perft 3 21036 +perft 4 519283 +perft 5 16025428 +perft 6 420887328 + +id 1 +epd rkb1rbnq/1pppp1pp/5p2/p7/5n1P/1PN3P1/P1PPPP2/RKB1RBNQ w EAea - 0 9 +perft 1 32 +perft 2 825 +perft 3 27130 +perft 4 697251 +perft 5 23593363 +perft 6 622249676 + +id 1 +epd rkbnrnqb/1ppp1p1p/p5p1/4p3/4P3/2N2P2/PPPP2PP/RKBR1NQB w Aea - 0 9 +perft 1 24 +perft 2 487 +perft 3 13300 +perft 4 301989 +perft 5 8782713 +perft 6 215787079 + +id 1 +epd rbknbr1q/pppp2pp/4p3/5p1n/1P2P2N/8/P1PP1PPP/RBKNBR1Q w FAfa - 0 9 +perft 1 23 +perft 2 571 +perft 3 13799 +perft 4 365272 +perft 5 9224232 +perft 6 257288920 + +id 1 +epd rknbb1nq/pppppr2/5pp1/7p/8/1N4P1/PPPPPP1P/RK1BBRNQ w FAa - 2 9 +perft 1 26 +perft 2 548 +perft 3 15618 +perft 4 350173 +perft 5 10587626 +perft 6 253006082 + +id 1 +epd rknr1bnq/p2pp1pp/1p3p2/2p4b/6PP/2P2N2/PP1PPP2/RKNRBB1Q w DAda - 1 9 +perft 1 25 +perft 2 502 +perft 3 13150 +perft 4 279098 +perft 5 7824941 +perft 6 175766730 + +id 1 +epd rknrb1qb/ppp1pppp/3p4/8/4P1nP/2P5/PPKP1PP1/R1NRBNQB w da - 1 9 +perft 1 23 +perft 2 643 +perft 3 14849 +perft 4 426616 +perft 5 10507328 +perft 6 312096061 + +id 1 +epd rbk1rnbq/pppp1npp/4p3/5p2/4P1P1/7P/PPPP1P1N/RBKNR1BQ w EAea - 1 9 +perft 1 24 +perft 2 591 +perft 3 15178 +perft 4 376988 +perft 5 10251465 +perft 6 263574861 + +id 1 +epd rknbrnb1/p1pppp1p/1p6/3N2p1/P3q1P1/8/1PPPPP1P/RKNBR1BQ w EAea - 1 9 +perft 1 28 +perft 2 948 +perft 3 27343 +perft 4 864588 +perft 5 26241141 +perft 6 812343987 + +id 1 +epd rknrn1b1/ppppppqp/8/6p1/2P5/2P1BP2/PP2P1PP/RKNRNB1Q w DAda - 1 9 +perft 1 31 +perft 2 807 +perft 3 24360 +perft 4 672973 +perft 5 20455205 +perft 6 588518645 + +id 1 +epd 1k1rnqbb/npppppp1/r7/p2B3p/5P2/1N4P1/PPPPP2P/RK1RNQB1 w DAd - 0 9 +perft 1 40 +perft 2 1122 +perft 3 44297 +perft 4 1249989 +perft 5 48711073 +perft 6 1412437357 + +id 1 +epd bbqr1rkn/pp1ppppp/8/2p5/1P2P1n1/7N/P1PP1P1P/BBQRKR1N w FD - 0 9 +perft 1 26 +perft 2 841 +perft 3 22986 +perft 4 746711 +perft 5 21328001 +perft 6 705170410 + +id 1 +epd bqkr1rnn/1ppp1ppp/p4b2/4p3/P7/3PP2N/1PP2PPP/BQRBKR1N w FC - 3 9 +perft 1 24 +perft 2 500 +perft 3 12802 +perft 4 293824 +perft 5 7928916 +perft 6 197806842 + +id 1 +epd bqrkrbnn/1pp1ppp1/8/p6p/3p4/P3P2P/QPPP1PP1/B1RKRBNN w ECec - 0 9 +perft 1 31 +perft 2 592 +perft 3 18585 +perft 4 396423 +perft 5 12607528 +perft 6 298629240 + +id 1 +epd bqkrrnnb/2p1pppp/p7/1P1p4/8/2R3P1/PP1PPP1P/BQ1KRNNB w E - 0 9 +perft 1 42 +perft 2 1124 +perft 3 45187 +perft 4 1276664 +perft 5 50052573 +perft 6 1483524894 + +id 1 +epd qbbrkrn1/p1pppn1p/8/1p3Pp1/2P5/8/PP1PPP1P/QBBRKRNN w FDfd - 0 9 +perft 1 21 +perft 2 577 +perft 3 13244 +perft 4 392131 +perft 5 9683808 +perft 6 300294295 + +id 1 +epd qrbbkrnn/pp1p2pp/4p3/5p2/2p2P1P/2P5/PP1PP1P1/QRBBKRNN w FBfb - 0 9 +perft 1 21 +perft 2 571 +perft 3 12736 +perft 4 345681 +perft 5 8239872 +perft 6 228837930 + +id 1 +epd qrbkrbn1/1pp1pppp/p2p4/8/5PPn/2P5/PP1PP3/QRBKRBNN w EBeb - 0 9 +perft 1 18 +perft 2 466 +perft 3 9443 +perft 4 257776 +perft 5 5679073 +perft 6 162883949 + +id 1 +epd qrb1rnnb/pp1p1ppp/2pk4/4p3/1P2P3/1R6/P1PP1PPP/Q1BKRNNB w E - 4 9 +perft 1 37 +perft 2 760 +perft 3 26863 +perft 4 562201 +perft 5 19486022 +perft 6 421740856 + +id 1 +epd qbrkbrn1/p1pppp1p/6n1/1p4p1/1P6/5P2/P1PPPBPP/QBRK1RNN w FCfc - 1 9 +perft 1 33 +perft 2 824 +perft 3 27385 +perft 4 750924 +perft 5 25176664 +perft 6 734656217 + +id 1 +epd qrkbbr2/2pppppp/5nn1/pp1Q4/P7/3P4/1PP1PPPP/1RKBBRNN w FBfb - 0 9 +perft 1 42 +perft 2 1147 +perft 3 44012 +perft 4 1311247 +perft 5 48216013 +perft 6 1522548864 + +id 1 +epd qrkrbbnn/pp2pp2/2pp2pp/1B6/P7/4P3/1PPP1PPP/QRKRB1NN w DBdb - 0 9 +perft 1 26 +perft 2 464 +perft 3 12653 +perft 4 242892 +perft 5 6928220 +perft 6 142507795 + +id 1 +epd qrkrbnnb/p1pp1pp1/1p5p/4p3/1P6/6PN/PKPPPP1P/QR1RBN1B w db - 0 9 +perft 1 29 +perft 2 705 +perft 3 20000 +perft 4 529810 +perft 5 15055365 +perft 6 419552571 + +id 1 +epd qbrkr1bn/p1p1pp1p/1p1p2n1/6p1/3P1P2/4P3/PPP3PP/QBKRRNBN w ec - 2 9 +perft 1 23 +perft 2 613 +perft 3 14835 +perft 4 426484 +perft 5 10747407 +perft 6 323905533 + +id 1 +epd qrk1rnb1/p1pp1ppp/1p2Bbn1/8/4P3/6P1/PPPP1P1P/QRK1RNBN w EBeb - 1 9 +perft 1 28 +perft 2 927 +perft 3 24887 +perft 4 846839 +perft 5 23063284 +perft 6 807913585 + +id 1 +epd 1qkrnbbn/1rpppppp/pp6/5N2/P4P2/8/1PPPP1PP/QRKRNBB1 w DBd - 3 9 +perft 1 30 +perft 2 542 +perft 3 16646 +perft 4 345172 +perft 5 10976745 +perft 6 251694423 + +id 1 +epd qrkr2bb/pppppppp/8/1n2n3/1N5P/1P6/P1PPPPP1/QRKR1NBB w DBdb - 1 9 +perft 1 28 +perft 2 719 +perft 3 21048 +perft 4 562015 +perft 5 17351761 +perft 6 479400272 + +id 1 +epd bbrqkrnn/3ppppp/8/ppp5/6P1/4P2N/PPPPKP1P/BBRQ1R1N w fc - 0 9 +perft 1 21 +perft 2 704 +perft 3 16119 +perft 4 546215 +perft 5 13676371 +perft 6 470796854 + +id 1 +epd brqbkrnn/1pp2p1p/3pp1p1/p5N1/8/1P6/P1PPPPPP/BRQBK1RN w Bfb - 0 9 +perft 1 34 +perft 2 688 +perft 3 22827 +perft 4 505618 +perft 5 16639723 +perft 6 402140795 + +id 1 +epd br1krb1n/2qppppp/pp3n2/8/1P4P1/8/P1PPPP1P/1RQKRBNN w EBeb - 0 9 +perft 1 24 +perft 2 945 +perft 3 23943 +perft 4 926427 +perft 5 25019636 +perft 6 959651619 + +id 1 +epd brqkr1nb/2ppp1pp/1p2np2/p7/2P1PN2/8/PP1P1PPP/BRQKRN1B w EBeb - 0 9 +perft 1 28 +perft 2 675 +perft 3 19728 +perft 4 504128 +perft 5 15516491 +perft 6 417396563 + +id 1 +epd rbbqkrnn/3pppp1/p7/1pp4p/2P1P2P/8/PP1P1PP1/RBBQKRNN w FAfa - 0 9 +perft 1 26 +perft 2 671 +perft 3 18164 +perft 4 496806 +perft 5 14072641 +perft 6 404960259 + +id 1 +epd rqbbkr1n/pp1p1p1p/4pn2/2p3p1/4P1P1/3P3P/PPP2P2/RQBBKRNN w FAfa - 0 9 +perft 1 22 +perft 2 633 +perft 3 14629 +perft 4 441809 +perft 5 10776416 +perft 6 335689685 + +id 1 +epd rqbkrbnn/p1ppp3/1p3pp1/7p/3P4/P1P5/1PQ1PPPP/R1BKRBNN w EAea - 0 9 +perft 1 32 +perft 2 607 +perft 3 20339 +perft 4 454319 +perft 5 15586203 +perft 6 383515709 + +id 1 +epd rqbkrnn1/pp2ppbp/3p4/2p3p1/2P5/1P3N1P/P2PPPP1/RQBKRN1B w EAea - 1 9 +perft 1 29 +perft 2 943 +perft 3 28732 +perft 4 908740 +perft 5 28761841 +perft 6 907579129 + +id 1 +epd rbqkb1nn/1ppppr1p/p5p1/5p2/1P6/2P4P/P1KPPPP1/RBQ1BRNN w a - 1 9 +perft 1 22 +perft 2 441 +perft 3 10403 +perft 4 231273 +perft 5 5784206 +perft 6 140934555 + +id 1 +epd rqkb1rnn/1pp1pp1p/p5p1/1b1p4/3P4/P5P1/RPP1PP1P/1QKBBRNN w Ffa - 1 9 +perft 1 21 +perft 2 505 +perft 3 11592 +perft 4 290897 +perft 5 7147063 +perft 6 188559137 + +id 1 +epd rq1rbbnn/pkp1ppp1/3p3p/1p2N1P1/8/8/PPPPPP1P/RQKRBB1N w DA - 0 9 +perft 1 27 +perft 2 608 +perft 3 16419 +perft 4 387751 +perft 5 10808908 +perft 6 268393274 + +id 1 +epd rqkrb2b/p2ppppp/2p3nn/1p6/5P2/PP1P4/2P1P1PP/RQKRBNNB w DAda - 1 9 +perft 1 30 +perft 2 749 +perft 3 21563 +perft 4 581531 +perft 5 16916813 +perft 6 485406712 + +id 1 +epd rbqkr1bn/pp1ppp2/2p1n2p/6p1/8/4BPNP/PPPPP1P1/RBQKRN2 w EAea - 0 9 +perft 1 23 +perft 2 600 +perft 3 15082 +perft 4 410057 +perft 5 11041820 +perft 6 314327867 + +id 1 +epd rqkbrnb1/2ppp1pp/pp3pn1/8/5P2/B2P4/PPP1P1PP/RQKBRN1N w EAea - 2 9 +perft 1 22 +perft 2 569 +perft 3 13541 +perft 4 371471 +perft 5 9395816 +perft 6 269460607 + +id 1 +epd rqkrnbb1/p1p1pppp/1p4n1/3p4/7P/P3P3/1PPPBPP1/RQKRN1BN w DAda - 0 9 +perft 1 27 +perft 2 579 +perft 3 15565 +perft 4 373079 +perft 5 10238486 +perft 6 266047417 + +id 1 +epd rqkrn1bb/p1ppp1pp/4n3/1p6/6p1/4N3/PPPPPPPP/RQKR2BB w DAda - 0 9 +perft 1 20 +perft 2 462 +perft 3 10234 +perft 4 274162 +perft 5 6563859 +perft 6 193376359 + +id 1 +epd bbrkqr2/pppp1ppp/6nn/8/2P1p3/3PP2N/PP3PPP/BBRKQR1N w FCfc - 0 9 +perft 1 28 +perft 2 724 +perft 3 21688 +perft 4 619064 +perft 5 19318355 +perft 6 593204629 + +id 1 +epd brk1qrnn/1pppbppp/4p3/8/1p6/P1P4P/3PPPP1/BRKBQRNN w FBfb - 1 9 +perft 1 24 +perft 2 662 +perft 3 16920 +perft 4 468215 +perft 5 12610387 +perft 6 355969349 + +id 1 +epd 1r1qrbnn/p1pkpppp/1p1p4/8/3P1PP1/P4b2/1PP1P2P/BRKQRBNN w EB - 1 9 +perft 1 22 +perft 2 696 +perft 3 17021 +perft 4 510247 +perft 5 13697382 +perft 6 401903030 + +id 1 +epd 1rkqrnnb/p1p1p1pp/1p1p4/3b1p1N/4P3/5N2/PPPP1PPP/BRKQR2B w EBeb - 1 9 +perft 1 29 +perft 2 887 +perft 3 27035 +perft 4 816176 +perft 5 26051242 +perft 6 791718847 + +id 1 +epd rbbkq1rn/pppppppp/7n/8/P7/3P3P/1PPKPPP1/RBB1QRNN w a - 3 9 +perft 1 22 +perft 2 417 +perft 3 9900 +perft 4 216855 +perft 5 5505063 +perft 6 134818483 + +id 1 +epd rkbbqr1n/1p1pppp1/2p2n2/p4NBp/8/3P4/PPP1PPPP/RK1BQRN1 w FAfa - 0 9 +perft 1 37 +perft 2 832 +perft 3 30533 +perft 4 728154 +perft 5 26676373 +perft 6 673756141 + +id 1 +epd rkbqrb1n/3pBppp/ppp2n2/8/8/P2P4/1PP1PPPP/RK1QRBNN w EAea - 0 9 +perft 1 28 +perft 2 685 +perft 3 19718 +perft 4 543069 +perft 5 16033316 +perft 6 482288814 + +id 1 +epd rkb1rn1b/ppppqppp/4p3/8/1P2n1P1/5Q2/P1PP1P1P/RKB1RNNB w EAea - 2 9 +perft 1 37 +perft 2 1158 +perft 3 40114 +perft 4 1234768 +perft 5 44672979 +perft 6 1389312729 + +id 1 +epd r1kqbrnn/pp1pp1p1/7p/2P2p2/5b2/3P4/P1P1P1PP/RBKQBRNN w FAfa - 0 9 +perft 1 5 +perft 2 161 +perft 3 4745 +perft 4 154885 +perft 5 4734999 +perft 6 157499039 + +id 1 +epd rkqbbr1n/ppp1ppp1/8/Q2p3p/4n3/3P1P2/PPP1P1PP/RK1BBRNN w FAfa - 2 9 +perft 1 38 +perft 2 1144 +perft 3 40433 +perft 4 1236877 +perft 5 43832975 +perft 6 1366087771 + +id 1 +epd rkqrbbn1/p1ppppp1/Bp5p/8/P6n/2P1P3/1P1P1PPP/RKQRB1NN w DAda - 0 9 +perft 1 28 +perft 2 551 +perft 3 15488 +perft 4 350861 +perft 5 9944107 +perft 6 251179183 + +id 1 +epd rkqrb1nb/1ppp1ppp/p7/4p3/5n2/3P2N1/PPPQPPPP/RK1RB1NB w DAda - 0 9 +perft 1 26 +perft 2 690 +perft 3 19877 +perft 4 513628 +perft 5 15965907 +perft 6 418191735 + +id 1 +epd rbkqrnbn/pppp1p2/4p1p1/7p/7P/P2P4/BPP1PPP1/R1KQRNBN w EAea - 0 9 +perft 1 27 +perft 2 515 +perft 3 13992 +perft 4 309727 +perft 5 8792550 +perft 6 218658292 + +id 1 +epd rkqbrnbn/pp1ppp2/8/2p3p1/P1P4p/5P2/1PKPP1PP/R1QBRNBN w ea - 0 9 +perft 1 27 +perft 2 627 +perft 3 16843 +perft 4 431101 +perft 5 11978698 +perft 6 328434174 + +id 1 +epd rkqrnbbn/1p2pp1p/3p2p1/p1p5/P5PP/3N4/1PPPPP2/RKQR1BBN w DAda - 0 9 +perft 1 23 +perft 2 624 +perft 3 15512 +perft 4 451860 +perft 5 11960861 +perft 6 367311176 + +id 1 +epd rk2rnbb/ppqppppp/2pn4/8/1P3P2/6P1/P1PPP1NP/RKQR1NBB w DAa - 1 9 +perft 1 27 +perft 2 727 +perft 3 20206 +perft 4 581003 +perft 5 16633696 +perft 6 505212747 + +id 1 +epd b1krrqnn/pp1ppp1p/2p3p1/8/P3Pb1P/1P6/2PP1PP1/BBRKRQNN w EC - 0 9 +perft 1 32 +perft 2 943 +perft 3 30759 +perft 4 865229 +perft 5 28672582 +perft 6 800922511 + +id 1 +epd 1rkbrqnn/p1pp1ppp/1p6/8/P2Pp3/8/1PPKPPQP/BR1BR1NN w eb - 0 9 +perft 1 28 +perft 2 916 +perft 3 24892 +perft 4 817624 +perft 5 22840279 +perft 6 759318058 + +id 1 +epd brkrqb1n/1pppp1pp/p7/3n1p2/P5P1/3PP3/1PP2P1P/BRKRQBNN w DBdb - 0 9 +perft 1 27 +perft 2 669 +perft 3 18682 +perft 4 484259 +perft 5 13956472 +perft 6 380267099 + +id 1 +epd brkrqnnb/3pppp1/1p6/p1p4p/2P3P1/6N1/PP1PPP1P/BRKRQ1NB w DBdb - 0 9 +perft 1 29 +perft 2 699 +perft 3 20042 +perft 4 512639 +perft 5 15093909 +perft 6 406594531 + +id 1 +epd r1bkrq1n/pp2pppp/3b1n2/2pp2B1/6P1/3P1P2/PPP1P2P/RB1KRQNN w EAea - 2 9 +perft 1 27 +perft 2 835 +perft 3 22848 +perft 4 713550 +perft 5 19867800 +perft 6 631209313 + +id 1 +epd rk1brq1n/p1p1pppp/3p1n2/1p3b2/4P3/2NQ4/PPPP1PPP/RKBBR2N w EAea - 4 9 +perft 1 36 +perft 2 1004 +perft 3 35774 +perft 4 979608 +perft 5 35143142 +perft 6 966310885 + +id 1 +epd rkbrqbnn/1p2ppp1/B1p5/p2p3p/4P2P/8/PPPP1PP1/RKBRQ1NN w DAda - 0 9 +perft 1 27 +perft 2 748 +perft 3 21005 +perft 4 597819 +perft 5 17597073 +perft 6 515304215 + +id 1 +epd rkbrqn1b/pp1pp1pp/2p2p2/5n2/8/2P2P2/PP1PP1PP/RKBRQ1NB w DAda - 0 9 +perft 1 20 +perft 2 479 +perft 3 10485 +perft 4 266446 +perft 5 6253775 +perft 6 167767913 + +id 1 +epd rbkrbnn1/ppppp1pp/5q2/5p2/5P2/P3P2N/1PPP2PP/RBKRBQ1N w DAda - 3 9 +perft 1 28 +perft 2 947 +perft 3 26900 +perft 4 876068 +perft 5 26007841 +perft 6 838704143 + +id 1 +epd rkr1bqnn/1ppp1p1p/p5p1/4p3/3PP2b/2P2P2/PP4PP/RKRBBQNN w CAca - 0 9 +perft 1 31 +perft 2 1004 +perft 3 32006 +perft 4 1006830 +perft 5 32688124 +perft 6 1024529879 + +id 1 +epd rkrqbbnn/pppp3p/8/4ppp1/1PP4P/8/P2PPPP1/RKRQBBNN w CAca - 0 9 +perft 1 24 +perft 2 717 +perft 3 18834 +perft 4 564137 +perft 5 15844525 +perft 6 484884485 + +id 1 +epd rkrqbn1b/pppp2pp/8/4pp2/1P1P2n1/5N2/P1P1PP1P/RKRQBN1B w CAca - 0 9 +perft 1 25 +perft 2 718 +perft 3 19654 +perft 4 587666 +perft 5 17257753 +perft 6 537354146 + +id 1 +epd rbkrqnbn/p1p1ppp1/1p1p4/8/3PP2p/2PB4/PP3PPP/R1KRQNBN w DAda - 0 9 +perft 1 30 +perft 2 754 +perft 3 23298 +perft 4 611322 +perft 5 19338246 +perft 6 532603566 + +id 1 +epd 1krbqnbn/1p2pppp/r1pp4/p7/8/1P1P2PP/P1P1PP2/RKRBQNBN w CAc - 0 9 +perft 1 21 +perft 2 566 +perft 3 13519 +perft 4 375128 +perft 5 9700847 +perft 6 279864836 + +id 1 +epd rkrq1b2/pppppppb/3n2np/2N5/4P3/7P/PPPP1PP1/RKRQ1BBN w CAca - 1 9 +perft 1 33 +perft 2 654 +perft 3 21708 +perft 4 479678 +perft 5 15990307 +perft 6 382218272 + +id 1 +epd rkr1nnbb/ppp2p1p/3p1qp1/4p3/P5P1/3PN3/1PP1PP1P/RKRQN1BB w CAca - 1 9 +perft 1 28 +perft 2 715 +perft 3 20361 +perft 4 555328 +perft 5 16303092 +perft 6 468666425 + +id 1 +epd bbrkrnqn/1p1ppppp/8/8/p2pP3/PP6/2P2PPP/BBRKRNQN w ECec - 0 9 +perft 1 24 +perft 2 757 +perft 3 19067 +perft 4 603231 +perft 5 15957628 +perft 6 509307623 + +id 1 +epd brkbrnqn/ppp2p2/4p3/P2p2pp/6P1/5P2/1PPPP2P/BRKBRNQN w EBeb - 0 9 +perft 1 25 +perft 2 548 +perft 3 14563 +perft 4 348259 +perft 5 9688526 +perft 6 247750144 + +id 1 +epd brkr1bqn/1pppppp1/3n3p/1p6/P7/4P1P1/1PPP1P1P/BRKRN1QN w DBdb - 0 9 +perft 1 19 +perft 2 359 +perft 3 7430 +perft 4 157099 +perft 5 3521652 +perft 6 81787718 + +id 1 +epd brkr1qnb/pppp2pp/2B1p3/5p2/2n5/6PP/PPPPPPN1/BRKR1QN1 w DBdb - 1 9 +perft 1 27 +perft 2 854 +perft 3 23303 +perft 4 741626 +perft 5 20558538 +perft 6 667089231 + +id 1 +epd rbbkrnqn/p1p1p1pp/8/1p1p4/1P1Pp3/6N1/P1P2PPP/RBBKRNQ1 w EAea - 0 9 +perft 1 28 +perft 2 723 +perft 3 19844 +perft 4 514440 +perft 5 14621108 +perft 6 397454100 + +id 1 +epd rkbbrn1n/pppppp2/5q1p/6p1/3P3P/4P3/PPP2PP1/RKBBRNQN w EAea - 1 9 +perft 1 25 +perft 2 741 +perft 3 19224 +perft 4 585198 +perft 5 15605840 +perft 6 485037906 + +id 1 +epd rkbr1bq1/ppnppppp/6n1/2p5/2P1N2P/8/PP1PPPP1/RKBRNBQ1 w DAda - 3 9 +perft 1 24 +perft 2 547 +perft 3 14359 +perft 4 339497 +perft 5 9410221 +perft 6 234041078 + +id 1 +epd 1kbrnqnb/r1ppppp1/8/pp5p/8/1P1NP3/P1PP1PPP/RKB1RQNB w Ad - 2 9 +perft 1 26 +perft 2 618 +perft 3 17305 +perft 4 442643 +perft 5 13112297 +perft 6 357030697 + +id 1 +epd rbkrb1qn/1pp1ppp1/3pn2p/pP6/8/4N1P1/P1PPPP1P/RBKRB1QN w DAda - 0 9 +perft 1 21 +perft 2 544 +perft 3 12492 +perft 4 338832 +perft 5 8381483 +perft 6 236013157 + +id 1 +epd rkrbbnqn/ppppp3/5p2/6pp/5PBP/4P3/PPPP2P1/RKR1BNQN w CAca - 0 9 +perft 1 30 +perft 2 891 +perft 3 25435 +perft 4 764356 +perft 5 21894752 +perft 6 669256602 + +id 1 +epd rkr1bb1n/ppppp1pp/5p2/4n3/3QP3/5P2/RPPP2PP/1KRNBB1N w Cca - 1 9 +perft 1 45 +perft 2 1172 +perft 3 51766 +perft 4 1332060 +perft 5 57856784 +perft 6 1501852662 + +id 1 +epd rkr1bqnb/pp1ppppp/8/2pN4/1P6/5N2/P1PPnPPP/RKR1BQ1B w CAca - 0 9 +perft 1 28 +perft 2 730 +perft 3 20511 +perft 4 559167 +perft 5 16323242 +perft 6 463032124 + +id 1 +epd rbkrnqb1/2ppppp1/p5np/1p6/8/3N4/PPPPPPPP/RBKRQNB1 w DAda - 2 9 +perft 1 20 +perft 2 417 +perft 3 9159 +perft 4 217390 +perft 5 5180716 +perft 6 133936564 + +id 1 +epd rkrbnqb1/p1pppnpp/5p2/1p6/2P5/1P1P1N2/P3PPPP/RKRB1QBN w CAca - 0 9 +perft 1 25 +perft 2 546 +perft 3 14039 +perft 4 330316 +perft 5 8813781 +perft 6 222026485 + +id 1 +epd rkr1qbbn/ppppppp1/4n3/7p/8/P7/KPPPPPPP/R1RNQBBN w ca - 0 9 +perft 1 22 +perft 2 484 +perft 3 11458 +perft 4 267495 +perft 5 6633319 +perft 6 163291279 + +id 1 +epd rkrnqnb1/1ppppp2/p5p1/7p/8/P1bPP3/1PP1QPPP/RKRN1NBB w CAca - 0 9 +perft 1 22 +perft 2 636 +perft 3 15526 +perft 4 441001 +perft 5 11614241 +perft 6 331083405 + +id 1 +epd b2krn1q/p1rppppp/1Q3n2/2p1b3/1P4P1/8/P1PPPP1P/BBRKRNN1 w ECe - 3 9 +perft 1 36 +perft 2 1192 +perft 3 42945 +perft 4 1406795 +perft 5 50382104 +perft 6 1650202838 + +id 1 +epd brkbrnn1/pp1pppp1/7q/2p5/6Pp/4P1NP/PPPP1P2/BRKBR1NQ w EBeb - 2 9 +perft 1 30 +perft 2 978 +perft 3 29593 +perft 4 942398 +perft 5 29205057 +perft 6 936568065 + +id 1 +epd brkrnb1q/pp1p1ppp/2p1p3/5n2/1P6/5N1N/P1PPPPPP/BRKR1B1Q w DBdb - 1 9 +perft 1 31 +perft 2 897 +perft 3 27830 +perft 4 810187 +perft 5 25423729 +perft 6 755334868 + +id 1 +epd brkr1nqb/pp1p1pp1/2pn3p/P3p3/4P3/6P1/1PPP1P1P/BRKRNNQB w DBdb - 0 9 +perft 1 19 +perft 2 382 +perft 3 8052 +perft 4 182292 +perft 5 4232274 +perft 6 103537333 + +id 1 +epd r1bkrn1q/ppbppppp/5n2/2p5/3P4/P6N/1PP1PPPP/RBBKRNQ1 w EAea - 3 9 +perft 1 27 +perft 2 822 +perft 3 22551 +perft 4 678880 +perft 5 19115128 +perft 6 578210135 + +id 1 +epd rkbbrnnq/pp2pppp/8/2pp4/P1P5/1P3P2/3PP1PP/RKBBRNNQ w EAea - 1 9 +perft 1 23 +perft 2 643 +perft 3 15410 +perft 4 442070 +perft 5 11170489 +perft 6 329615708 + +id 1 +epd rkbr1b1q/p1pppppp/1p1n4/7n/5QP1/3N4/PPPPPP1P/RKBR1BN1 w DAda - 4 9 +perft 1 37 +perft 2 943 +perft 3 34382 +perft 4 880474 +perft 5 31568111 +perft 6 842265141 + +id 1 +epd rkbr1nqb/pppp2np/8/4ppp1/1P6/6N1/P1PPPPPP/RKBRN1QB w DAda - 1 9 +perft 1 23 +perft 2 574 +perft 3 13260 +perft 4 362306 +perft 5 9020291 +perft 6 261247606 + +id 1 +epd rbkr1nnq/p1p1pp1p/1p4p1/3p4/b3P3/4N3/PPPPNPPP/RBKRB1Q1 w DAda - 0 9 +perft 1 26 +perft 2 900 +perft 3 23414 +perft 4 805006 +perft 5 21653203 +perft 6 745802405 + +id 1 +epd rkrbb1nq/p2pppp1/1p4n1/2p4p/3N4/4P1P1/PPPP1P1P/RKRBBN1Q w CAca - 0 9 +perft 1 32 +perft 2 697 +perft 3 22231 +perft 4 531121 +perft 5 17150175 +perft 6 441578567 + +id 1 +epd rkrnbb1q/pp2pp1p/6pn/2pp4/2B1P2P/8/PPPP1PP1/RKRNB1NQ w CAca - 0 9 +perft 1 28 +perft 2 854 +perft 3 23853 +perft 4 755990 +perft 5 21823412 +perft 6 712787248 + +id 1 +epd rk2bnqb/pprpppp1/4n2p/2p5/P7/3P2NP/1PP1PPP1/RKRNB1QB w CAa - 1 9 +perft 1 26 +perft 2 596 +perft 3 16251 +perft 4 414862 +perft 5 11758184 +perft 6 323043654 + +id 1 +epd r1krnnbq/pp1ppp1p/6p1/2p5/2P5/P3P3/Rb1P1PPP/1BKRNNBQ w Dda - 0 9 +perft 1 2 +perft 2 61 +perft 3 1312 +perft 4 40072 +perft 5 937188 +perft 6 28753562 + +id 1 +epd 1krbnnbq/1pp1p1pp/r7/p2p1p2/3PP3/2P3P1/PP3P1P/RKRBNNBQ w CAc - 0 9 +perft 1 30 +perft 2 953 +perft 3 28033 +perft 4 860530 +perft 5 25531358 +perft 6 787205262 + +id 1 +epd rkr1nbbq/2ppp1pp/1pn5/p4p2/P6P/3P4/1PP1PPPB/RKRNNB1Q w CAca - 1 9 +perft 1 24 +perft 2 645 +perft 3 15689 +perft 4 446423 +perft 5 11484012 +perft 6 341262639 + +id 1 +epd rkrnnqbb/p1ppp2p/Qp6/4Pp2/5p2/8/PPPP2PP/RKRNN1BB w CAca - 0 9 +perft 1 35 +perft 2 929 +perft 3 32020 +perft 4 896130 +perft 5 31272517 +perft 6 915268405 + +id 1 +epd bbq1nr1r/pppppk1p/2n2p2/6p1/P4P2/4P1P1/1PPP3P/BBQNNRKR w HF - 1 9 +perft 1 23 +perft 2 589 +perft 3 14744 +perft 4 387556 +perft 5 10316716 +perft 6 280056112 From 57c9f87cbf8d57d13dce787fe243500adac4a67c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 20 Jan 2023 21:56:17 +0100 Subject: [PATCH 1583/1831] Fix ids in chess960.perft --- examples/perft/chess960.perft | 1919 +++++++++++++++++---------------- 1 file changed, 960 insertions(+), 959 deletions(-) diff --git a/examples/perft/chess960.perft b/examples/perft/chess960.perft index 0d14d5da0..76be26eed 100644 --- a/examples/perft/chess960.perft +++ b/examples/perft/chess960.perft @@ -1,6 +1,7 @@ # https://www.chessprogramming.org/Chess960_Perft_Results +# https://github.com/AndyGrant/Ethereal/blob/master/src/perft/fischer.epd -id 1 +id 0 epd bqnb1rkr/pp3ppp/3ppn2/2p5/5P2/P2P4/NPP1P1PP/BQ1BNRKR w HFhf - 2 9 perft 1 21 perft 2 528 @@ -18,7 +19,7 @@ perft 4 667366 perft 5 16253601 perft 6 590751109 -id 1 +id 2 epd b1q1rrkb/pppppppp/3nn3/8/P7/1PPP4/4PPPP/BQNNRKRB w GE - 1 9 perft 1 20 perft 2 479 @@ -27,7 +28,7 @@ perft 4 273318 perft 5 6417013 perft 6 177654692 -id 1 +id 3 epd qbbnnrkr/2pp2pp/p7/1p2pp2/8/P3PP2/1PPP1KPP/QBBNNR1R w hf - 0 9 perft 1 22 perft 2 593 @@ -36,7 +37,7 @@ perft 4 382958 perft 5 9183776 perft 6 274103539 -id 1 +id 4 epd 1nbbnrkr/p1p1ppp1/3p4/1p3P1p/3Pq2P/8/PPP1P1P1/QNBBNRKR w HFhf - 0 9 perft 1 28 perft 2 1120 @@ -45,7 +46,7 @@ perft 4 1171749 perft 5 34030312 perft 6 1250970898 -id 1 +id 5 epd qnbnr1kr/ppp1b1pp/4p3/3p1p2/8/2NPP3/PPP1BPPP/QNB1R1KR w HEhe - 1 9 perft 1 29 perft 2 899 @@ -54,7 +55,7 @@ perft 4 824055 perft 5 24851983 perft 6 775718317 -id 1 +id 6 epd q1bnrkr1/ppppp2p/2n2p2/4b1p1/2NP4/8/PPP1PPPP/QNB1RRKB w ge - 1 9 perft 1 30 perft 2 860 @@ -63,7 +64,7 @@ perft 4 732757 perft 5 21093346 perft 6 649209803 -id 1 +id 7 epd qbn1brkr/ppp1p1p1/2n4p/3p1p2/P7/6PP/QPPPPP2/1BNNBRKR w HFhf - 0 9 perft 1 25 perft 2 635 @@ -72,7 +73,7 @@ perft 4 465806 perft 5 13203304 perft 6 377184252 -id 1 +id 8 epd qnnbbrkr/1p2ppp1/2pp3p/p7/1P5P/2NP4/P1P1PPP1/Q1NBBRKR w HFhf - 0 9 perft 1 24 perft 2 572 @@ -81,7 +82,7 @@ perft 4 384260 perft 5 11110203 perft 6 293989890 -id 1 +id 9 epd qn1rbbkr/ppp2p1p/1n1pp1p1/8/3P4/P6P/1PP1PPPK/QNNRBB1R w hd - 2 9 perft 1 28 perft 2 811 @@ -90,7 +91,7 @@ perft 4 679699 perft 5 19836606 perft 6 594527992 -id 1 +id 10 epd qnr1bkrb/pppp2pp/3np3/5p2/8/P2P2P1/NPP1PP1P/QN1RBKRB w GDg - 3 9 perft 1 33 perft 2 823 @@ -99,7 +100,7 @@ perft 4 713420 perft 5 23114629 perft 6 646390782 -id 1 +id 11 epd qb1nrkbr/1pppp1p1/1n3p2/p1B4p/8/3P1P1P/PPP1P1P1/QBNNRK1R w HEhe - 0 9 perft 1 31 perft 2 855 @@ -108,7 +109,7 @@ perft 4 735703 perft 5 21796206 perft 6 651054626 -id 1 +id 12 epd qnnbrk1r/1p1ppbpp/2p5/p4p2/2NP3P/8/PPP1PPP1/Q1NBRKBR w HEhe - 0 9 perft 1 26 perft 2 790 @@ -117,7 +118,7 @@ perft 4 642367 perft 5 17819770 perft 6 544866674 -id 1 +id 13 epd 1qnrkbbr/1pppppp1/p1n4p/8/P7/1P1N1P2/2PPP1PP/QN1RKBBR w HDhd - 0 9 perft 1 37 perft 2 883 @@ -126,7 +127,7 @@ perft 4 815535 perft 5 29370838 perft 6 783201510 -id 1 +id 14 epd qn1rkrbb/pp1p1ppp/2p1p3/3n4/4P2P/2NP4/PPP2PP1/Q1NRKRBB w FDfd - 1 9 perft 1 24 perft 2 585 @@ -135,7 +136,7 @@ perft 4 356950 perft 5 9482310 perft 6 233468620 -id 1 +id 15 epd bb1qnrkr/pp1p1pp1/1np1p3/4N2p/8/1P4P1/P1PPPP1P/BBNQ1RKR w HFhf - 0 9 perft 1 29 perft 2 864 @@ -144,7 +145,7 @@ perft 4 799727 perft 5 24219627 perft 6 776836316 -id 1 +id 16 epd bnqbnr1r/p1p1ppkp/3p4/1p4p1/P7/3NP2P/1PPP1PP1/BNQB1RKR w HF - 0 9 perft 1 26 perft 2 889 @@ -153,7 +154,7 @@ perft 4 832956 perft 5 23701014 perft 6 809194268 -id 1 +id 17 epd bnqnrbkr/1pp2pp1/p7/3pP2p/4P1P1/8/PPPP3P/BNQNRBKR w HEhe d6 0 9 perft 1 31 perft 2 984 @@ -162,7 +163,7 @@ perft 4 962591 perft 5 29032175 perft 6 1008880643 -id 1 +id 18 epd b1qnrrkb/ppp1pp1p/n2p1Pp1/8/8/P7/1PPPP1PP/BNQNRKRB w GE - 0 9 perft 1 20 perft 2 484 @@ -171,7 +172,7 @@ perft 4 281606 perft 5 6718715 perft 6 193594729 -id 1 +id 19 epd n1bqnrkr/pp1ppp1p/2p5/6p1/2P2b2/PN6/1PNPPPPP/1BBQ1RKR w HFhf - 2 9 perft 1 23 perft 2 732 @@ -180,7 +181,7 @@ perft 4 558191 perft 5 14481581 perft 6 457140569 -id 1 +id 20 epd n1bb1rkr/qpnppppp/2p5/p7/P1P5/5P2/1P1PPRPP/NQBBN1KR w Hhf - 1 9 perft 1 27 perft 2 697 @@ -189,7 +190,7 @@ perft 4 505089 perft 5 14226907 perft 6 400942568 -id 1 +id 21 epd nqb1rbkr/pppppp1p/4n3/6p1/4P3/1NP4P/PP1P1PP1/1QBNRBKR w HEhe - 1 9 perft 1 28 perft 2 641 @@ -198,7 +199,7 @@ perft 4 456916 perft 5 13780398 perft 6 354122358 -id 1 +id 22 epd n1bnrrkb/pp1pp2p/2p2p2/6p1/5B2/3P4/PPP1PPPP/NQ1NRKRB w GE - 2 9 perft 1 28 perft 2 606 @@ -207,7 +208,7 @@ perft 4 381646 perft 5 10815324 perft 6 254026570 -id 1 +id 23 epd nbqnbrkr/2ppp1p1/pp3p1p/8/4N2P/1N6/PPPPPPP1/1BQ1BRKR w HFhf - 0 9 perft 1 26 perft 2 626 @@ -216,7 +217,7 @@ perft 4 437525 perft 5 12719546 perft 6 339132046 -id 1 +id 24 epd nq1bbrkr/pp2nppp/2pp4/4p3/1PP1P3/1B6/P2P1PPP/NQN1BRKR w HFhf - 2 9 perft 1 21 perft 2 504 @@ -225,7 +226,7 @@ perft 4 302230 perft 5 7697880 perft 6 207028745 -id 1 +id 25 epd nqnrb1kr/2pp1ppp/1p1bp3/p1B5/5P2/3N4/PPPPP1PP/NQ1R1BKR w HDhd - 0 9 perft 1 30 perft 2 672 @@ -234,7 +235,7 @@ perft 4 465317 perft 5 13454573 perft 6 345445468 -id 1 +id 26 epd nqn2krb/p1prpppp/1pbp4/7P/5P2/8/PPPPPKP1/NQNRB1RB w g - 3 9 perft 1 21 perft 2 461 @@ -243,7 +244,7 @@ perft 4 248069 perft 5 6194124 perft 6 152861936 -id 1 +id 27 epd nb1n1kbr/ppp1rppp/3pq3/P3p3/8/4P3/1PPPRPPP/NBQN1KBR w Hh - 1 9 perft 1 19 perft 2 566 @@ -252,7 +253,7 @@ perft 4 358337 perft 5 8047916 perft 6 249171636 -id 1 +id 28 epd nqnbrkbr/1ppppp1p/p7/6p1/6P1/P6P/1PPPPP2/NQNBRKBR w HEhe - 1 9 perft 1 20 perft 2 382 @@ -261,7 +262,7 @@ perft 4 187263 perft 5 4708975 perft 6 112278808 -id 1 +id 29 epd nq1rkb1r/pp1pp1pp/1n2bp1B/2p5/8/5P1P/PPPPP1P1/NQNRKB1R w HDhd - 2 9 perft 1 24 perft 2 809 @@ -270,7 +271,7 @@ perft 4 673811 perft 5 17647882 perft 6 593457788 -id 1 +id 30 epd nqnrkrb1/pppppp2/7p/4b1p1/8/PN1NP3/1PPP1PPP/1Q1RKRBB w FDfd - 1 9 perft 1 26 perft 2 683 @@ -279,7 +280,7 @@ perft 4 473911 perft 5 13055173 perft 6 352398011 -id 1 +id 31 epd bb1nqrkr/1pp1ppp1/pn5p/3p4/8/P2NNP2/1PPPP1PP/BB2QRKR w HFhf - 0 9 perft 1 29 perft 2 695 @@ -288,7 +289,7 @@ perft 4 552634 perft 5 17454857 perft 6 483785639 -id 1 +id 32 epd bnn1qrkr/pp1ppp1p/2p5/b3Q1p1/8/5P1P/PPPPP1P1/BNNB1RKR w HFhf - 2 9 perft 1 44 perft 2 920 @@ -297,7 +298,7 @@ perft 4 795317 perft 5 29742670 perft 6 702867204 -id 1 +id 33 epd bnnqrbkr/pp1p2p1/2p1p2p/5p2/1P5P/1R6/P1PPPPP1/BNNQRBK1 w Ehe - 0 9 perft 1 33 perft 2 1022 @@ -306,7 +307,7 @@ perft 4 1024721 perft 5 32898113 perft 6 1047360456 -id 1 +id 34 epd b1nqrkrb/2pppppp/p7/1P6/1n6/P4P2/1P1PP1PP/BNNQRKRB w GEge - 0 9 perft 1 23 perft 2 638 @@ -315,7 +316,7 @@ perft 4 446539 perft 5 11735969 perft 6 344211589 -id 1 +id 35 epd n1bnqrkr/3ppppp/1p6/pNp1b3/2P3P1/8/PP1PPP1P/NBB1QRKR w HFhf - 1 9 perft 1 29 perft 2 728 @@ -324,7 +325,7 @@ perft 4 532084 perft 5 15621236 perft 6 415766465 -id 1 +id 36 epd n2bqrkr/p1p1pppp/1pn5/3p1b2/P6P/1NP5/1P1PPPP1/1NBBQRKR w HFhf - 3 9 perft 1 20 perft 2 533 @@ -333,7 +334,7 @@ perft 4 325059 perft 5 8088751 perft 6 223068417 -id 1 +id 37 epd nnbqrbkr/1pp1p1p1/p2p4/5p1p/2P1P3/N7/PPQP1PPP/N1B1RBKR w HEhe - 0 9 perft 1 27 perft 2 619 @@ -342,7 +343,7 @@ perft 4 444421 perft 5 13755384 perft 6 357222394 -id 1 +id 38 epd nnbqrkr1/pp1pp2p/2p2b2/5pp1/1P5P/4P1P1/P1PP1P2/NNBQRKRB w GEge - 1 9 perft 1 32 perft 2 1046 @@ -351,7 +352,7 @@ perft 4 1111186 perft 5 36218182 perft 6 1202830851 -id 1 +id 39 epd nb1qbrkr/p1pppp2/1p1n2pp/8/1P6/2PN3P/P2PPPP1/NB1QBRKR w HFhf - 0 9 perft 1 25 perft 2 521 @@ -360,7 +361,7 @@ perft 4 306427 perft 5 8697700 perft 6 201455191 -id 1 +id 40 epd nnq1brkr/pp1pppp1/8/2p4P/8/5K2/PPPbPP1P/NNQBBR1R w hf - 0 9 perft 1 23 perft 2 724 @@ -369,7 +370,7 @@ perft 4 571072 perft 5 15338230 perft 6 484638597 -id 1 +id 41 epd nnqrbb1r/pppppk2/5pp1/7p/1P6/3P2PP/P1P1PP2/NNQRBBKR w HD - 0 9 perft 1 30 perft 2 717 @@ -378,7 +379,7 @@ perft 4 547145 perft 5 17166700 perft 6 450069742 -id 1 +id 42 epd nnqr1krb/p1p1pppp/2bp4/8/1p1P4/4P3/PPP2PPP/NNQRBKRB w GDgd - 0 9 perft 1 25 perft 2 873 @@ -387,7 +388,7 @@ perft 4 728628 perft 5 18162741 perft 6 641708630 -id 1 +id 43 epd nbnqrkbr/p2ppp2/1p4p1/2p4p/3P3P/3N4/PPP1PPPR/NB1QRKB1 w Ehe - 0 9 perft 1 24 perft 2 589 @@ -396,7 +397,7 @@ perft 4 382317 perft 5 10630667 perft 6 279474189 -id 1 +id 44 epd n1qbrkbr/p1ppp2p/2n2pp1/1p6/1P6/2P3P1/P2PPP1P/NNQBRKBR w HEhe - 0 9 perft 1 22 perft 2 592 @@ -405,7 +406,7 @@ perft 4 401976 perft 5 10356818 perft 6 301583306 -id 1 +id 45 epd 2qrkbbr/ppn1pppp/n1p5/3p4/5P2/P1PP4/1P2P1PP/NNQRKBBR w HDhd - 1 9 perft 1 27 perft 2 750 @@ -414,7 +415,7 @@ perft 4 605458 perft 5 16819085 perft 6 516796736 -id 1 +id 46 epd 1nqr1rbb/pppkp1pp/1n3p2/3p4/1P6/5P1P/P1PPPKP1/NNQR1RBB w - - 1 9 perft 1 24 perft 2 623 @@ -423,7 +424,7 @@ perft 4 429446 perft 5 11594634 perft 6 322745925 -id 1 +id 47 epd bbn1rqkr/pp1pp2p/4npp1/2p5/1P6/2BPP3/P1P2PPP/1BNNRQKR w HEhe - 0 9 perft 1 23 perft 2 730 @@ -432,7 +433,7 @@ perft 4 565340 perft 5 14496370 perft 6 468608864 -id 1 +id 48 epd bn1brqkr/pppp2p1/3npp2/7p/PPP5/8/3PPPPP/BNNBRQKR w HEhe - 0 9 perft 1 25 perft 2 673 @@ -441,7 +442,7 @@ perft 4 513696 perft 5 14284338 perft 6 434008567 -id 1 +id 49 epd bn1rqbkr/ppp1ppp1/1n6/2p4p/7P/3P4/PPP1PPP1/BN1RQBKR w HDhd - 0 9 perft 1 25 perft 2 776 @@ -450,7 +451,7 @@ perft 4 660217 perft 5 18486027 perft 6 616653869 -id 1 +id 50 epd bnnr1krb/ppp2ppp/3p4/3Bp3/q1P3PP/8/PP1PPP2/BNNRQKR1 w GDgd - 0 9 perft 1 29 perft 2 1040 @@ -459,7 +460,7 @@ perft 4 1053113 perft 5 31801525 perft 6 1075147725 -id 1 +id 51 epd 1bbnrqkr/pp1ppppp/8/2p5/n7/3PNPP1/PPP1P2P/NBB1RQKR w HEhe - 1 9 perft 1 24 perft 2 598 @@ -468,7 +469,7 @@ perft 4 409766 perft 5 11394778 perft 6 310589129 -id 1 +id 52 epd nnbbrqkr/p2ppp1p/1pp5/8/6p1/N1P5/PPBPPPPP/N1B1RQKR w HEhe - 0 9 perft 1 26 perft 2 530 @@ -477,7 +478,7 @@ perft 4 326312 perft 5 8846766 perft 6 229270702 -id 1 +id 53 epd nnbrqbkr/2p1p1pp/p4p2/1p1p4/8/NP6/P1PPPPPP/N1BRQBKR w HDhd - 0 9 perft 1 17 perft 2 496 @@ -486,7 +487,7 @@ perft 4 303310 perft 5 7103549 perft 6 217108001 -id 1 +id 54 epd nnbrqk1b/pp2pprp/2pp2p1/8/3PP1P1/8/PPP2P1P/NNBRQRKB w d - 1 9 perft 1 33 perft 2 820 @@ -495,7 +496,7 @@ perft 4 706784 perft 5 24714401 perft 6 645835197 -id 1 +id 55 epd 1bnrbqkr/ppnpp1p1/2p2p1p/8/1P6/4PPP1/P1PP3P/NBNRBQKR w HDhd - 0 9 perft 1 27 perft 2 705 @@ -504,7 +505,7 @@ perft 4 548680 perft 5 15964771 perft 6 464662032 -id 1 +id 56 epd n1rbbqkr/pp1pppp1/7p/P1p5/1n6/2PP4/1P2PPPP/NNRBBQKR w HChc - 0 9 perft 1 22 perft 2 631 @@ -513,7 +514,7 @@ perft 4 431801 perft 5 10911545 perft 6 320838556 -id 1 +id 57 epd n1rqb1kr/p1pppp1p/1pn4b/3P2p1/P7/1P6/2P1PPPP/NNRQBBKR w HChc - 0 9 perft 1 24 perft 2 477 @@ -522,7 +523,7 @@ perft 4 263189 perft 5 7419372 perft 6 165945904 -id 1 +id 58 epd nnrqbkrb/pppp1pp1/7p/4p3/6P1/2N2B2/PPPPPP1P/NR1QBKR1 w Ggc - 2 9 perft 1 29 perft 2 658 @@ -531,7 +532,7 @@ perft 4 476620 perft 5 14233587 perft 6 373744834 -id 1 +id 59 epd n1nrqkbr/ppb2ppp/3pp3/2p5/2P3P1/5P2/PP1PPB1P/NBNRQK1R w HDhd - 1 9 perft 1 32 perft 2 801 @@ -540,7 +541,7 @@ perft 4 681428 perft 5 22318948 perft 6 619857455 -id 1 +id 60 epd 2rbqkbr/p1pppppp/1nn5/1p6/7P/P4P2/1PPPP1PB/NNRBQK1R w HChc - 2 9 perft 1 27 perft 2 647 @@ -549,7 +550,7 @@ perft 4 458057 perft 5 13189156 perft 6 354689323 -id 1 +id 61 epd nn1qkbbr/pp2ppp1/2rp4/2p4p/P2P4/1N5P/1PP1PPP1/1NRQKBBR w HCh - 1 9 perft 1 24 perft 2 738 @@ -558,7 +559,7 @@ perft 4 586009 perft 5 16420659 perft 6 519075930 -id 1 +id 62 epd nnrqk1bb/p1ppp2p/5rp1/1p3p2/1P4P1/5P1P/P1PPP3/NNRQKRBB w FCc - 1 9 perft 1 25 perft 2 795 @@ -567,7 +568,7 @@ perft 4 648945 perft 5 17342527 perft 6 556144017 -id 1 +id 63 epd bb1nrkqr/ppppn2p/4ppp1/8/1P4P1/4P3/P1PPKP1P/BBNNR1QR w he - 0 9 perft 1 29 perft 2 664 @@ -576,7 +577,7 @@ perft 4 498376 perft 5 15373803 perft 6 406016364 -id 1 +id 64 epd bnnbrkqr/1p1ppp2/8/p1p3pp/1P6/N4P2/PBPPP1PP/2NBRKQR w HEhe - 0 9 perft 1 31 perft 2 770 @@ -585,7 +586,7 @@ perft 4 677212 perft 5 22562080 perft 6 662029574 -id 1 +id 65 epd 1nnrkbqr/p1pp1ppp/4p3/1p6/1Pb1P3/6PB/P1PP1P1P/BNNRK1QR w HDhd - 0 9 perft 1 27 perft 2 776 @@ -594,7 +595,7 @@ perft 4 641002 perft 5 19153245 perft 6 562738257 -id 1 +id 66 epd bnr1kqrb/pppp1pp1/1n5p/4p3/P3P3/3P2P1/1PP2P1P/BNNRKQRB w GDg - 0 9 perft 1 26 perft 2 624 @@ -603,7 +604,7 @@ perft 4 435426 perft 5 11906515 perft 6 338092952 -id 1 +id 67 epd nbbnrkqr/p1ppp1pp/1p3p2/8/2P5/4P3/PP1P1PPP/NBBNRKQR w HEhe - 1 9 perft 1 25 perft 2 624 @@ -612,7 +613,7 @@ perft 4 419635 perft 5 10817378 perft 6 311138112 -id 1 +id 68 epd nn1brkqr/pp1bpppp/8/2pp4/P4P2/1PN5/2PPP1PP/N1BBRKQR w HEhe - 1 9 perft 1 23 perft 2 659 @@ -621,7 +622,7 @@ perft 4 476567 perft 5 13242252 perft 6 373557073 -id 1 +id 69 epd n1brkbqr/ppp1pp1p/6pB/3p4/2Pn4/8/PP2PPPP/NN1RKBQR w HDhd - 0 9 perft 1 32 perft 2 1026 @@ -630,7 +631,7 @@ perft 4 978278 perft 5 29436320 perft 6 957904151 -id 1 +id 70 epd nnbrkqrb/p2ppp2/Q5pp/1pp5/4PP2/2N5/PPPP2PP/N1BRK1RB w GDgd - 0 9 perft 1 36 perft 2 843 @@ -639,7 +640,7 @@ perft 4 715537 perft 5 24321197 perft 6 630396940 -id 1 +id 71 epd nbnrbk1r/pppppppq/8/7p/8/1N2QPP1/PPPPP2P/NB1RBK1R w HDhd - 2 9 perft 1 36 perft 2 973 @@ -648,7 +649,7 @@ perft 4 1018054 perft 5 37143354 perft 6 1124883780 -id 1 +id 72 epd nnrbbkqr/2pppp1p/p7/6p1/1p2P3/4QPP1/PPPP3P/NNRBBK1R w HChc - 0 9 perft 1 36 perft 2 649 @@ -657,7 +658,7 @@ perft 4 489526 perft 5 16836636 perft 6 416139320 -id 1 +id 73 epd nnrkbbqr/1p2pppp/p2p4/2p5/8/1N2P1P1/PPPP1P1P/1NKRBBQR w hc - 0 9 perft 1 26 perft 2 672 @@ -666,7 +667,7 @@ perft 4 477801 perft 5 13342771 perft 6 363074681 -id 1 +id 74 epd n1rkbqrb/pp1ppp2/2n3p1/2p4p/P5PP/1P6/2PPPP2/NNRKBQRB w GCgc - 0 9 perft 1 24 perft 2 804 @@ -675,7 +676,7 @@ perft 4 684001 perft 5 18761475 perft 6 617932151 -id 1 +id 75 epd nbkr1qbr/1pp1pppp/pn1p4/8/3P2P1/5R2/PPP1PP1P/NBN1KQBR w H - 2 9 perft 1 30 perft 2 627 @@ -684,7 +685,7 @@ perft 4 423329 perft 5 12815016 perft 6 312798696 -id 1 +id 76 epd nnr1kqbr/pp1pp1p1/2p5/b4p1p/P7/1PNP4/2P1PPPP/N1RBKQBR w HChc - 1 9 perft 1 12 perft 2 421 @@ -693,7 +694,7 @@ perft 4 227044 perft 5 4266410 perft 6 149176979 -id 1 +id 77 epd n1rkqbbr/p1pp1pp1/np2p2p/8/8/N4PP1/PPPPP1BP/N1RKQ1BR w HChc - 0 9 perft 1 27 perft 2 670 @@ -702,7 +703,7 @@ perft 4 494690 perft 5 14708490 perft 6 397268628 -id 1 +id 78 epd nnr1qrbb/p2kpppp/1p1p4/2p5/6P1/PP1P4/2P1PP1P/NNRKQRBB w FC - 0 9 perft 1 27 perft 2 604 @@ -711,7 +712,7 @@ perft 4 409665 perft 5 11993332 perft 6 308518181 -id 1 +id 79 epd bbnnrkrq/ppp1pp2/6p1/3p4/7p/7P/PPPPPPP1/BBNNRRKQ w ge - 0 9 perft 1 20 perft 2 559 @@ -720,7 +721,7 @@ perft 4 355326 perft 5 8427161 perft 6 252274233 -id 1 +id 80 epd bnnbrkr1/ppp2p1p/5q2/3pp1p1/4P3/1N4P1/PPPPRP1P/BN1B1KRQ w Gge - 0 9 perft 1 26 perft 2 1036 @@ -729,7 +730,7 @@ perft 4 1028084 perft 5 28286576 perft 6 1042120495 -id 1 +id 81 epd bn1rkbrq/1pppppp1/p6p/1n6/3P4/6PP/PPPRPP2/BNN1KBRQ w Ggd - 2 9 perft 1 29 perft 2 633 @@ -738,7 +739,7 @@ perft 4 455476 perft 5 14333034 perft 6 361900466 -id 1 +id 82 epd b1nrkrqb/1p1npppp/p2p4/2p5/5P2/4P2P/PPPP1RP1/BNNRK1QB w Dfd - 1 9 perft 1 25 perft 2 475 @@ -747,7 +748,7 @@ perft 4 270909 perft 5 7545536 perft 6 179579818 -id 1 +id 83 epd 1bbnrkrq/ppppppp1/8/7p/1n4P1/1PN5/P1PPPP1P/NBBR1KRQ w Gge - 0 9 perft 1 30 perft 2 803 @@ -756,7 +757,7 @@ perft 4 709716 perft 5 23443854 perft 6 686365049 -id 1 +id 84 epd nnbbrkrq/2pp1pp1/1p5p/pP2p3/7P/N7/P1PPPPP1/N1BBRKRQ w GEge - 0 9 perft 1 18 perft 2 432 @@ -765,7 +766,7 @@ perft 4 242350 perft 5 6131124 perft 6 160393505 -id 1 +id 85 epd nnbrkbrq/1pppp1p1/p7/7p/1P2Pp2/BN6/P1PP1PPP/1N1RKBRQ w GDgd - 0 9 perft 1 27 perft 2 482 @@ -774,7 +775,7 @@ perft 4 282259 perft 5 8084701 perft 6 193484216 -id 1 +id 86 epd n1brkrqb/pppp3p/n3pp2/6p1/3P1P2/N1P5/PP2P1PP/N1BRKRQB w FDfd - 0 9 perft 1 28 perft 2 642 @@ -783,7 +784,7 @@ perft 4 471729 perft 5 14529434 perft 6 384837696 -id 1 +id 87 epd nbnrbk2/p1pppp1p/1p3qr1/6p1/1B1P4/1N6/PPP1PPPP/1BNR1RKQ w d - 2 9 perft 1 30 perft 2 796 @@ -792,7 +793,7 @@ perft 4 687302 perft 5 20120565 perft 6 641832725 -id 1 +id 88 epd nnrbbrkq/1pp2ppp/3p4/p3p3/3P1P2/1P2P3/P1P3PP/NNRBBKRQ w GC - 1 9 perft 1 31 perft 2 827 @@ -801,7 +802,7 @@ perft 4 663082 perft 5 19979594 perft 6 549437308 -id 1 +id 89 epd nnrkbbrq/1pp2p1p/p2pp1p1/2P5/8/8/PP1PPPPP/NNRKBBRQ w Ggc - 0 9 perft 1 24 perft 2 762 @@ -810,7 +811,7 @@ perft 4 624598 perft 5 16838099 perft 6 555230555 -id 1 +id 90 epd nnr1brqb/1ppkp1pp/8/p2p1p2/1P1P4/N1P5/P3PPPP/N1RKBRQB w FC - 1 9 perft 1 23 perft 2 640 @@ -819,7 +820,7 @@ perft 4 444905 perft 5 11343507 perft 6 334123513 -id 1 +id 91 epd nbnrkrbq/2ppp2p/p4p2/1P4p1/4PP2/8/1PPP2PP/NBNRKRBQ w FDfd - 0 9 perft 1 31 perft 2 826 @@ -828,7 +829,7 @@ perft 4 732175 perft 5 23555139 perft 6 686250413 -id 1 +id 92 epd 1nrbkr1q/1pppp1pp/1n6/p4p2/N1b4P/8/PPPPPPPB/N1RBKR1Q w FCfc - 2 9 perft 1 27 perft 2 862 @@ -837,7 +838,7 @@ perft 4 755171 perft 5 22027695 perft 6 696353497 -id 1 +id 93 epd nnrkrbbq/pppp2pp/8/4pp2/4P3/P7/1PPPBPPP/NNKRR1BQ w c - 0 9 perft 1 25 perft 2 792 @@ -846,7 +847,7 @@ perft 4 636041 perft 5 16473376 perft 6 532214177 -id 1 +id 94 epd n1rk1qbb/pppprpp1/2n4p/4p3/2PP3P/8/PP2PPP1/NNRKRQBB w ECc - 1 9 perft 1 25 perft 2 622 @@ -855,7 +856,7 @@ perft 4 425247 perft 5 11420973 perft 6 321855685 -id 1 +id 95 epd bbq1rnkr/pnp1pp1p/1p1p4/6p1/2P5/2Q1P2P/PP1P1PP1/BB1NRNKR w HEhe - 2 9 perft 1 36 perft 2 870 @@ -864,7 +865,7 @@ perft 4 811047 perft 5 28127620 perft 6 799738334 -id 1 +id 96 epd bq1brnkr/1p1ppp1p/1np5/p5p1/8/1N5P/PPPPPPP1/BQ1BRNKR w HEhe - 0 9 perft 1 22 perft 2 588 @@ -873,7 +874,7 @@ perft 4 380068 perft 5 9359618 perft 6 273795898 -id 1 +id 97 epd bq1rn1kr/1pppppbp/Nn4p1/8/8/P7/1PPPPPPP/BQ1RNBKR w HDhd - 1 9 perft 1 24 perft 2 711 @@ -882,7 +883,7 @@ perft 4 542570 perft 5 14692779 perft 6 445827351 -id 1 +id 98 epd bqnr1kr1/pppppp1p/6p1/5n2/4B3/3N2PP/PbPPPP2/BQNR1KR1 w GDgd - 2 9 perft 1 31 perft 2 1132 @@ -891,7 +892,7 @@ perft 4 1261476 perft 5 43256823 perft 6 1456721391 -id 1 +id 99 epd qbb1rnkr/ppp3pp/4n3/3ppp2/1P3PP1/8/P1PPPN1P/QBB1RNKR w HEhe - 0 9 perft 1 28 perft 2 696 @@ -900,7 +901,7 @@ perft 4 541886 perft 5 16492398 perft 6 456983120 -id 1 +id 100 epd qnbbr1kr/pp1ppp1p/4n3/6p1/2p3P1/2PP1P2/PP2P2P/QNBBRNKR w HEhe - 0 9 perft 1 25 perft 2 655 @@ -909,7 +910,7 @@ perft 4 450189 perft 5 11767038 perft 6 335414976 -id 1 +id 101 epd 1nbrnbkr/p1ppp1pp/1p6/5p2/4q1PP/3P4/PPP1PP2/QNBRNBKR w HDhd - 1 9 perft 1 30 perft 2 1162 @@ -918,7 +919,7 @@ perft 4 1217278 perft 5 36048727 perft 6 1290346802 -id 1 +id 102 epd q1brnkrb/p1pppppp/n7/1p6/P7/3P1P2/QPP1P1PP/1NBRNKRB w GDgd - 0 9 perft 1 32 perft 2 827 @@ -927,7 +928,7 @@ perft 4 718243 perft 5 23143989 perft 6 673147648 -id 1 +id 103 epd qbnrb1kr/ppp1pp1p/3p4/2n3p1/1P6/6N1/P1PPPPPP/QBNRB1KR w HDhd - 2 9 perft 1 29 perft 2 751 @@ -936,7 +937,7 @@ perft 4 610397 perft 5 19555214 perft 6 530475036 -id 1 +id 104 epd q1rbbnkr/pppp1p2/2n3pp/2P1p3/3P4/8/PP1NPPPP/Q1RBBNKR w HChc - 2 9 perft 1 29 perft 2 806 @@ -945,7 +946,7 @@ perft 4 687251 perft 5 21694330 perft 6 619907316 -id 1 +id 105 epd q1r1bbkr/pnpp1ppp/2n1p3/1p6/2P2P2/2N1N3/PP1PP1PP/Q1R1BBKR w HChc - 2 9 perft 1 32 perft 2 1017 @@ -954,7 +955,7 @@ perft 4 986028 perft 5 31204371 perft 6 958455898 -id 1 +id 106 epd 2rnbkrb/pqppppp1/1pn5/7p/2P5/P1R5/QP1PPPPP/1N1NBKRB w Ggc - 4 9 perft 1 26 perft 2 625 @@ -963,7 +964,7 @@ perft 4 434635 perft 5 11856964 perft 6 336672890 -id 1 +id 107 epd qbnr1kbr/p2ppppp/2p5/1p6/4n2P/P4N2/1PPP1PP1/QBNR1KBR w HDhd - 0 9 perft 1 27 perft 2 885 @@ -972,7 +973,7 @@ perft 4 767273 perft 5 21855658 perft 6 706272554 -id 1 +id 108 epd qnrbnk1r/pp1pp2p/5p2/2pbP1p1/3P4/1P6/P1P2PPP/QNRBNKBR w HChc - 0 9 perft 1 26 perft 2 954 @@ -981,7 +982,7 @@ perft 4 892456 perft 5 24415089 perft 6 866744329 -id 1 +id 109 epd qnrnk1br/p1p2ppp/8/1pbpp3/8/PP2N3/1QPPPPPP/1NR1KBBR w HChc - 0 9 perft 1 26 perft 2 783 @@ -990,7 +991,7 @@ perft 4 634267 perft 5 17477825 perft 6 539674275 -id 1 +id 110 epd qnrnkrbb/Bpppp2p/6p1/5p2/5P2/3PP3/PPP3PP/QNRNKR1B w FCfc - 1 9 perft 1 28 perft 2 908 @@ -999,7 +1000,7 @@ perft 4 861240 perft 5 25251641 perft 6 869525254 -id 1 +id 111 epd bbnqrn1r/ppppp2k/5p2/6pp/7P/1QP5/PP1PPPP1/B1N1RNKR w HE - 0 9 perft 1 33 perft 2 643 @@ -1008,7 +1009,7 @@ perft 4 487109 perft 5 16693640 perft 6 410115900 -id 1 +id 112 epd b1qbrnkr/ppp1pp2/2np4/6pp/4P3/2N4P/PPPP1PP1/BQ1BRNKR w HEhe - 0 9 perft 1 28 perft 2 837 @@ -1017,7 +1018,7 @@ perft 4 745617 perft 5 22197063 perft 6 696399065 -id 1 +id 113 epd bnqr1bkr/pp1ppppp/2p5/4N3/5P2/P7/1PPPPnPP/BNQR1BKR w HDhd - 3 9 perft 1 25 perft 2 579 @@ -1026,7 +1027,7 @@ perft 4 341444 perft 5 8601011 perft 6 225530258 -id 1 +id 114 epd b1qr1krb/pp1ppppp/n2n4/8/2p5/2P3P1/PP1PPP1P/BNQRNKRB w GDgd - 0 9 perft 1 28 perft 2 707 @@ -1035,7 +1036,7 @@ perft 4 549506 perft 5 15583376 perft 6 468399900 -id 1 +id 115 epd nbbqr1kr/1pppp1pp/8/p1n2p2/4P3/PN6/1PPPQPPP/1BB1RNKR w HEhe - 0 9 perft 1 30 perft 2 745 @@ -1044,7 +1045,7 @@ perft 4 597858 perft 5 19478789 perft 6 515473678 -id 1 +id 116 epd nqbbrn1r/p1pppp1k/1p4p1/7p/4P3/1R3B2/PPPP1PPP/NQB2NKR w H - 0 9 perft 1 24 perft 2 504 @@ -1053,7 +1054,7 @@ perft 4 317355 perft 5 9002073 perft 6 228726497 -id 1 +id 117 epd nqbr1bkr/p1p1ppp1/1p1n4/3pN2p/1P6/8/P1PPPPPP/NQBR1BKR w HDhd - 0 9 perft 1 29 perft 2 898 @@ -1062,7 +1063,7 @@ perft 4 809605 perft 5 24703467 perft 6 757166494 -id 1 +id 118 epd nqbrn1rb/pppp1kp1/5p1p/4p3/P4B2/3P2P1/1PP1PP1P/NQ1RNKRB w GD - 0 9 perft 1 34 perft 2 671 @@ -1071,7 +1072,7 @@ perft 4 473110 perft 5 15556806 perft 6 353235120 -id 1 +id 119 epd nb1r1nkr/ppp1ppp1/2bp4/7p/3P2qP/P6R/1PP1PPP1/NBQRBNK1 w Dhd - 1 9 perft 1 38 perft 2 1691 @@ -1080,7 +1081,7 @@ perft 4 2526992 perft 5 88557078 perft 6 3589649998 -id 1 +id 120 epd n1rbbnkr/1p1pp1pp/p7/2p1qp2/1B3P2/3P4/PPP1P1PP/NQRB1NKR w HChc - 0 9 perft 1 24 perft 2 913 @@ -1089,7 +1090,7 @@ perft 4 807544 perft 5 19866918 perft 6 737239330 -id 1 +id 121 epd nqrnbbkr/p2p1p1p/1pp5/1B2p1p1/1P3P2/4P3/P1PP2PP/NQRNB1KR w HChc - 0 9 perft 1 33 perft 2 913 @@ -1098,7 +1099,7 @@ perft 4 843874 perft 5 28053260 perft 6 804687975 -id 1 +id 122 epd nqr1bkrb/ppp1pp2/2np2p1/P6p/8/2P4P/1P1PPPP1/NQRNBKRB w GCgc - 0 9 perft 1 24 perft 2 623 @@ -1107,7 +1108,7 @@ perft 4 442531 perft 5 12681936 perft 6 351623879 -id 1 +id 123 epd nb1rnkbr/pqppppp1/1p5p/8/1PP4P/8/P2PPPP1/NBQRNKBR w HDhd - 1 9 perft 1 31 perft 2 798 @@ -1116,7 +1117,7 @@ perft 4 694386 perft 5 22616076 perft 6 666227466 -id 1 +id 124 epd nqrbnkbr/2p1p1pp/3p4/pp3p2/6PP/3P1N2/PPP1PP2/NQRB1KBR w HChc - 0 9 perft 1 24 perft 2 590 @@ -1125,7 +1126,7 @@ perft 4 383690 perft 5 9698432 perft 6 274064911 -id 1 +id 125 epd nqrnkbbr/pp1p1p1p/4p1p1/1p6/8/5P1P/P1PPP1P1/NQRNKBBR w HChc - 0 9 perft 1 30 perft 2 1032 @@ -1134,7 +1135,7 @@ perft 4 1098116 perft 5 34914919 perft 6 1233362066 -id 1 +id 126 epd nqrnkrbb/p2ppppp/1p6/2p5/2P3P1/5P2/PP1PPN1P/NQR1KRBB w FCfc - 1 9 perft 1 30 perft 2 775 @@ -1143,7 +1144,7 @@ perft 4 668000 perft 5 21141738 perft 6 621142773 -id 1 +id 127 epd bbnrqrk1/pp2pppp/4n3/2pp4/P7/1N5P/BPPPPPP1/B2RQNKR w HD - 2 9 perft 1 23 perft 2 708 @@ -1152,7 +1153,7 @@ perft 4 554089 perft 5 14343443 perft 6 481405144 -id 1 +id 128 epd bnr1qnkr/p1pp1p1p/1p4p1/4p1b1/2P1P3/1P6/PB1P1PPP/1NRBQNKR w HChc - 1 9 perft 1 30 perft 2 931 @@ -1161,7 +1162,7 @@ perft 4 921746 perft 5 30026687 perft 6 968109774 -id 1 +id 129 epd b1rqnbkr/ppp1ppp1/3p3p/2n5/P3P3/2NP4/1PP2PPP/B1RQNBKR w HChc - 0 9 perft 1 24 perft 2 596 @@ -1170,7 +1171,7 @@ perft 4 396123 perft 5 11099382 perft 6 294180723 -id 1 +id 130 epd bnrqnr1b/pp1pkppp/2p1p3/P7/2P5/7P/1P1PPPP1/BNRQNKRB w GC - 0 9 perft 1 24 perft 2 572 @@ -1179,7 +1180,7 @@ perft 4 390903 perft 5 11208688 perft 6 302955778 -id 1 +id 131 epd n1brq1kr/bppppppp/p7/8/4P1Pn/8/PPPP1P2/NBBRQNKR w HDhd - 0 9 perft 1 20 perft 2 570 @@ -1188,7 +1189,7 @@ perft 4 371247 perft 5 9919113 perft 6 284592289 -id 1 +id 132 epd 1rbbqnkr/ppn1ppp1/3p3p/2p5/3P4/1N4P1/PPPBPP1P/1R1BQNKR w HBhb - 0 9 perft 1 29 perft 2 1009 @@ -1197,7 +1198,7 @@ perft 4 1040816 perft 5 31059587 perft 6 1111986835 -id 1 +id 133 epd nrbq2kr/ppppppb1/5n1p/5Pp1/8/P5P1/1PPPP2P/NRBQNBKR w HBhb - 1 9 perft 1 20 perft 2 520 @@ -1206,7 +1207,7 @@ perft 4 316332 perft 5 7809837 perft 6 216997152 -id 1 +id 134 epd nrb1nkrb/pp3ppp/1qBpp3/2p5/8/P5P1/1PPPPP1P/NRBQNKR1 w GBgb - 2 9 perft 1 32 perft 2 850 @@ -1215,7 +1216,7 @@ perft 4 734088 perft 5 21981567 perft 6 664886187 -id 1 +id 135 epd 1br1bnkr/ppqppp1p/1np3p1/8/1PP4P/4N3/P2PPPP1/NBRQB1KR w HChc - 1 9 perft 1 32 perft 2 798 @@ -1224,7 +1225,7 @@ perft 4 691488 perft 5 22076141 perft 6 670296871 -id 1 +id 136 epd nrqbb1kr/1p1pp1pp/2p3n1/p4p2/3PP3/P5N1/1PP2PPP/NRQBB1KR w HBhb - 0 9 perft 1 32 perft 2 791 @@ -1233,7 +1234,7 @@ perft 4 684890 perft 5 23239122 perft 6 634260266 -id 1 +id 137 epd nrqn1bkr/ppppp1pp/4b3/8/4P1p1/5P2/PPPP3P/NRQNBBKR w HBhb - 0 9 perft 1 29 perft 2 687 @@ -1242,7 +1243,7 @@ perft 4 506088 perft 5 15236287 perft 6 398759980 -id 1 +id 138 epd nrqnbrkb/pppp1p2/4p2p/3B2p1/8/1P4P1/PQPPPP1P/NR1NBKR1 w GB - 0 9 perft 1 37 perft 2 764 @@ -1251,7 +1252,7 @@ perft 4 610950 perft 5 21284835 perft 6 514864869 -id 1 +id 139 epd nbrq1kbr/Bp3ppp/2pnp3/3p4/5P2/2P4P/PP1PP1P1/NBRQNK1R w HChc - 0 9 perft 1 40 perft 2 1271 @@ -1260,7 +1261,7 @@ perft 4 1547741 perft 5 56588117 perft 6 1850696281 -id 1 +id 140 epd nrqbnkbr/1p2ppp1/p1p4p/3p4/1P6/8/PQPPPPPP/1RNBNKBR w HBhb - 0 9 perft 1 28 perft 2 757 @@ -1269,7 +1270,7 @@ perft 4 668025 perft 5 21427496 perft 6 650939962 -id 1 +id 141 epd nrqn1bbr/2ppkppp/4p3/pB6/8/2P1P3/PP1P1PPP/NRQNK1BR w HB - 1 9 perft 1 27 perft 2 642 @@ -1278,7 +1279,7 @@ perft 4 442653 perft 5 11872805 perft 6 327545120 -id 1 +id 142 epd nrqnkrb1/p1ppp2p/1p4p1/4bp2/4PP1P/4N3/PPPP2P1/NRQ1KRBB w FBfb - 1 9 perft 1 27 perft 2 958 @@ -1287,7 +1288,7 @@ perft 4 960350 perft 5 28520172 perft 6 995356563 -id 1 +id 143 epd 1bnrnqkr/pbpp2pp/8/1p2pp2/P6P/3P1N2/1PP1PPP1/BBNR1QKR w HDhd - 0 9 perft 1 27 perft 2 859 @@ -1296,7 +1297,7 @@ perft 4 773232 perft 5 21581178 perft 6 732696327 -id 1 +id 144 epd b1rbnqkr/1pp1ppp1/2n4p/p2p4/5P2/1PBP4/P1P1P1PP/1NRBNQKR w HChc - 0 9 perft 1 26 perft 2 545 @@ -1305,7 +1306,7 @@ perft 4 336470 perft 5 9537260 perft 6 233549184 -id 1 +id 145 epd 1nrnqbkr/p1pppppp/1p6/8/2b2P2/P1N5/1PP1P1PP/BNR1QBKR w HChc - 2 9 perft 1 24 perft 2 668 @@ -1314,7 +1315,7 @@ perft 4 494866 perft 5 14216070 perft 6 406225409 -id 1 +id 146 epd 1nrnqkrb/2ppp1pp/p7/1p3p2/5P2/N5K1/PPPPP2P/B1RNQ1RB w gc - 0 9 perft 1 33 perft 2 725 @@ -1323,7 +1324,7 @@ perft 4 559823 perft 5 18547476 perft 6 471443091 -id 1 +id 147 epd nbbr1qkr/p1pppppp/8/1p1n4/3P4/1N3PP1/PPP1P2P/1BBRNQKR w HDhd - 1 9 perft 1 28 perft 2 698 @@ -1332,7 +1333,7 @@ perft 4 539625 perft 5 16555068 perft 6 458045505 -id 1 +id 148 epd 1rbbnqkr/1pnppp1p/p5p1/2p5/2P4P/5P2/PP1PP1PR/NRBBNQK1 w Bhb - 1 9 perft 1 24 perft 2 554 @@ -1341,7 +1342,7 @@ perft 4 362516 perft 5 9863080 perft 6 269284081 -id 1 +id 149 epd nrb1qbkr/2pppppp/2n5/p7/2p5/4P3/PPNP1PPP/1RBNQBKR w HBhb - 0 9 perft 1 23 perft 2 618 @@ -1350,7 +1351,7 @@ perft 4 443718 perft 5 12044358 perft 6 360311412 -id 1 +id 150 epd nrb1qkrb/2ppppp1/p3n3/1p1B3p/2P5/6P1/PP1PPPRP/NRBNQK2 w Bgb - 2 9 perft 1 27 perft 2 593 @@ -1359,7 +1360,7 @@ perft 4 401967 perft 5 11806808 perft 6 303338935 -id 1 +id 151 epd nbrn1qkr/ppp1pp2/3p2p1/3Q3P/b7/8/PPPPPP1P/NBRNB1KR w HChc - 2 9 perft 1 39 perft 2 1056 @@ -1368,7 +1369,7 @@ perft 4 1133446 perft 5 42201531 perft 6 1239888683 -id 1 +id 152 epd nr1bbqkr/pp1pp2p/1n3pp1/2p5/8/1P4P1/P1PPPPQP/NRNBBK1R w hb - 0 9 perft 1 25 perft 2 585 @@ -1377,7 +1378,7 @@ perft 4 406544 perft 5 11582539 perft 6 320997679 -id 1 +id 153 epd nr2bbkr/ppp1pppp/1n1p4/8/6PP/1NP4q/PP1PPP2/1RNQBBKR w HBhb - 1 9 perft 1 22 perft 2 742 @@ -1386,7 +1387,7 @@ perft 4 545231 perft 5 13287051 perft 6 457010195 -id 1 +id 154 epd 1rnqbkrb/ppp1p1p1/1n3p2/3p3p/P6P/4P3/1PPP1PP1/NRNQBRKB w gb - 0 9 perft 1 22 perft 2 574 @@ -1395,7 +1396,7 @@ perft 4 379648 perft 5 9968830 perft 6 281344367 -id 1 +id 155 epd nb1rqkbr/1pppp1pp/4n3/p4p2/6PP/5P2/PPPPPN2/NBR1QKBR w HCh - 0 9 perft 1 25 perft 2 621 @@ -1404,7 +1405,7 @@ perft 4 462600 perft 5 13378840 perft 6 396575613 -id 1 +id 156 epd nrnbqkbr/2pp2pp/4pp2/pp6/8/1P3P2/P1PPPBPP/NRNBQ1KR w hb - 0 9 perft 1 25 perft 2 656 @@ -1413,7 +1414,7 @@ perft 4 466493 perft 5 12525939 perft 6 358763789 -id 1 +id 157 epd nrnqkbbr/ppppp1p1/7p/5p2/8/P4PP1/NPPPP2P/NR1QKBBR w HBhb - 0 9 perft 1 28 perft 2 723 @@ -1422,7 +1423,7 @@ perft 4 547522 perft 5 15952533 perft 6 439046803 -id 1 +id 158 epd 1rnqkr1b/ppppp2p/1n3pp1/8/2P3P1/Pb1N4/1P1PPP1P/NR1QKRBB w FBfb - 0 9 perft 1 26 perft 2 713 @@ -1431,7 +1432,7 @@ perft 4 548875 perft 5 15865528 perft 6 454532806 -id 1 +id 159 epd bbnrnkqr/1pppp1pp/5p2/p7/7P/1P6/PBPPPPPR/1BNRNKQ1 w D - 2 9 perft 1 26 perft 2 649 @@ -1440,7 +1441,7 @@ perft 4 502279 perft 5 14375839 perft 6 435585252 -id 1 +id 160 epd bnrbk1qr/1ppp1ppp/p2np3/8/P7/2N2P2/1PPPP1PP/B1RBNKQR w HC - 0 9 perft 1 26 perft 2 621 @@ -1449,7 +1450,7 @@ perft 4 451452 perft 5 13514201 perft 6 364421088 -id 1 +id 161 epd br1nkbqr/ppppppp1/8/n6p/8/N1P2PP1/PP1PP2P/B1RNKBQR w HCh - 1 9 perft 1 29 perft 2 664 @@ -1458,7 +1459,7 @@ perft 4 512316 perft 5 16125924 perft 6 442508159 -id 1 +id 162 epd bnr1kqrb/pp1pppp1/2n5/2p5/1P4Pp/4N3/P1PPPP1P/BNKR1QRB w gc - 0 9 perft 1 36 perft 2 888 @@ -1467,7 +1468,7 @@ perft 4 789863 perft 5 27792175 perft 6 719015345 -id 1 +id 163 epd 1bbrnkqr/pp1p1ppp/2p1p3/1n6/5P2/3Q4/PPPPP1PP/NBBRNK1R w HDhd - 2 9 perft 1 36 perft 2 891 @@ -1476,7 +1477,7 @@ perft 4 781792 perft 5 26998966 perft 6 702903862 -id 1 +id 164 epd nrbbnk1r/pp2pppq/8/2pp3p/3P2P1/1N6/PPP1PP1P/1RBBNKQR w HBhb - 0 9 perft 1 29 perft 2 1036 @@ -1485,7 +1486,7 @@ perft 4 1139166 perft 5 35627310 perft 6 1310683359 -id 1 +id 165 epd nr1nkbqr/ppp3pp/5p2/3pp3/6b1/3PP3/PPP2PPP/NRBNKBQR w hb - 0 9 perft 1 18 perft 2 664 @@ -1494,7 +1495,7 @@ perft 4 483892 perft 5 10658989 perft 6 386307449 -id 1 +id 166 epd nrbnk1rb/ppp1pq1p/3p4/5pp1/2P1P3/1N6/PP1PKPPP/1RBN1QRB w gb - 2 9 perft 1 25 perft 2 966 @@ -1503,7 +1504,7 @@ perft 4 920345 perft 5 23957242 perft 6 913710194 -id 1 +id 167 epd 1brnbkqr/pppppp2/6p1/7p/1Pn5/P1NP4/2P1PPPP/NBR1BKQR w HChc - 0 9 perft 1 22 perft 2 627 @@ -1512,7 +1513,7 @@ perft 4 395829 perft 5 9627826 perft 6 285900573 -id 1 +id 168 epd nrnbbk1r/p1pppppq/8/7p/1p6/P5PP/1PPPPPQ1/NRNBBK1R w HBhb - 2 9 perft 1 29 perft 2 888 @@ -1521,7 +1522,7 @@ perft 4 874270 perft 5 27229468 perft 6 930799376 -id 1 +id 169 epd n1nkb1qr/prppppbp/6p1/1p6/2P2P2/P7/1P1PP1PP/NRNKBBQR w HBh - 1 9 perft 1 29 perft 2 804 @@ -1530,7 +1531,7 @@ perft 4 688520 perft 5 21952444 perft 6 623156747 -id 1 +id 170 epd nr2bqrb/ppkpp1pp/1np5/5p1P/5P2/2P5/PP1PP1P1/NRNKBQRB w GB - 0 9 perft 1 22 perft 2 530 @@ -1539,7 +1540,7 @@ perft 4 347657 perft 5 9244693 perft 6 264088392 -id 1 +id 171 epd nbr1kqbr/p3pppp/2ppn3/1p4P1/4P3/1P6/P1PP1P1P/NBRNKQBR w HChc - 1 9 perft 1 23 perft 2 555 @@ -1548,7 +1549,7 @@ perft 4 350917 perft 5 9692630 perft 6 247479180 -id 1 +id 172 epd nr1bkqbr/1p1pp1pp/pnp2p2/8/6P1/P1PP4/1P2PP1P/NRNBKQBR w HBhb - 0 9 perft 1 22 perft 2 565 @@ -1557,7 +1558,7 @@ perft 4 365663 perft 5 9305533 perft 6 268612479 -id 1 +id 173 epd nr1kqbbr/np2pppp/p1p5/1B1p1P2/8/4P3/PPPP2PP/NRNKQ1BR w HBhb - 0 9 perft 1 32 perft 2 730 @@ -1566,7 +1567,7 @@ perft 4 556995 perft 5 18103280 perft 6 454569900 -id 1 +id 174 epd nrnk1rbb/p1p2ppp/3pq3/Qp2p3/1P1P4/8/P1P1PPPP/NRN1KRBB w fb - 2 9 perft 1 28 perft 2 873 @@ -1575,7 +1576,7 @@ perft 4 791823 perft 5 23868737 perft 6 747991356 -id 1 +id 175 epd bbnrnkrq/pp1ppp1p/6p1/2p5/6P1/P5RP/1PPPPP2/BBNRNK1Q w Dgd - 3 9 perft 1 37 perft 2 1260 @@ -1584,7 +1585,7 @@ perft 4 1542086 perft 5 54843403 perft 6 1898432768 -id 1 +id 176 epd bnrb1rkq/ppnpppp1/3Q4/2p4p/7P/N7/PPPPPPP1/B1RBNKR1 w GC - 2 9 perft 1 38 perft 2 878 @@ -1593,7 +1594,7 @@ perft 4 800440 perft 5 28784300 perft 6 784569826 -id 1 +id 177 epd bnrnkbrq/p1ppppp1/1p5p/8/P2PP3/5P2/1PP3PP/BNRNKBRQ w GCgc - 1 9 perft 1 26 perft 2 617 @@ -1602,7 +1603,7 @@ perft 4 419099 perft 5 11965544 perft 6 311309576 -id 1 +id 178 epd bnrnkrqb/pp2p2p/2pp1pp1/8/P7/2PP1P2/1P2P1PP/BNRNKRQB w FCfc - 0 9 perft 1 26 perft 2 721 @@ -1611,7 +1612,7 @@ perft 4 560824 perft 5 15966934 perft 6 467132503 -id 1 +id 179 epd nbbrnkr1/1pppp1p1/p6q/P4p1p/8/5P2/1PPPP1PP/NBBRNRKQ w gd - 2 9 perft 1 18 perft 2 556 @@ -1620,7 +1621,7 @@ perft 4 316634 perft 5 6629293 perft 6 202528241 -id 1 +id 180 epd nrb1nkrq/2pp1ppp/p4b2/1p2p3/P4B2/3P4/1PP1PPPP/NR1BNRKQ w gb - 0 9 perft 1 24 perft 2 562 @@ -1629,7 +1630,7 @@ perft 4 355433 perft 5 9227883 perft 6 247634489 -id 1 +id 181 epd nrbnkbrq/p3p1pp/1p6/2pp1P2/8/3PP3/PPP2P1P/NRBNKBRQ w GBgb - 0 9 perft 1 31 perft 2 746 @@ -1638,7 +1639,7 @@ perft 4 608523 perft 5 21019301 perft 6 542954168 -id 1 +id 182 epd nrbnkrqb/pppp1p1p/4p1p1/8/7P/2P1P3/PPNP1PP1/1RBNKRQB w FBfb - 0 9 perft 1 20 perft 2 459 @@ -1647,7 +1648,7 @@ perft 4 242762 perft 5 5760165 perft 6 146614723 -id 1 +id 183 epd nbrn1krq/ppp1p2p/6b1/3p1pp1/8/4N1PP/PPPPPP2/NBR1BRKQ w gc - 1 9 perft 1 27 perft 2 835 @@ -1656,7 +1657,7 @@ perft 4 766397 perft 5 22667987 perft 6 760795567 -id 1 +id 184 epd nrnbbkrq/p1pp2pp/5p2/1p6/2P1pP1B/1P6/P2PP1PP/NRNB1KRQ w GBgb - 0 9 perft 1 24 perft 2 646 @@ -1665,7 +1666,7 @@ perft 4 444472 perft 5 11489727 perft 6 324948755 -id 1 +id 185 epd nrn1bbrq/1ppkppp1/p2p3p/8/1P3N2/4P3/P1PP1PPP/NR1KBBRQ w GB - 2 9 perft 1 32 perft 2 591 @@ -1674,7 +1675,7 @@ perft 4 381683 perft 5 12069159 perft 6 269922838 -id 1 +id 186 epd n1krbrqb/1ppppppp/p7/8/4n3/P4P1P/1PPPPQP1/NRNKBR1B w FB - 2 9 perft 1 26 perft 2 639 @@ -1683,7 +1684,7 @@ perft 4 417190 perft 5 12167153 perft 6 312633873 -id 1 +id 187 epd n1rnkrbq/1p1ppp1p/8/p1p1b1p1/3PQ1P1/4N3/PPP1PP1P/NBR1KRB1 w FCfc - 0 9 perft 1 35 perft 2 1027 @@ -1692,7 +1693,7 @@ perft 4 1040417 perft 5 35738410 perft 6 1060661628 -id 1 +id 188 epd nrnbkrbq/2pp1pp1/pp6/4p2p/P7/5PPP/1PPPP3/NRNBKRBQ w FBfb - 0 9 perft 1 26 perft 2 628 @@ -1701,7 +1702,7 @@ perft 4 436075 perft 5 11920087 perft 6 331498921 -id 1 +id 189 epd 1rnkrbbq/pp1p2pp/1n3p2/1Bp1p3/1P6/1N2P3/P1PP1PPP/1RNKR1BQ w EBeb - 0 9 perft 1 33 perft 2 992 @@ -1710,7 +1711,7 @@ perft 4 983481 perft 5 31703749 perft 6 980306735 -id 1 +id 190 epd nr1krqbb/p1ppppp1/8/1p5p/1Pn5/5P2/P1PPP1PP/NRNKRQBB w EBeb - 0 9 perft 1 24 perft 2 670 @@ -1719,7 +1720,7 @@ perft 4 445492 perft 5 11371067 perft 6 325556465 -id 1 +id 191 epd bbq1rkr1/1ppppppp/p1n2n2/8/2P2P2/1P6/PQ1PP1PP/BB1NRKNR w HEe - 3 9 perft 1 32 perft 2 794 @@ -1728,7 +1729,7 @@ perft 4 689334 perft 5 24085223 perft 6 645633370 -id 1 +id 192 epd b1nbrknr/1qppp1pp/p4p2/1p6/6P1/P2NP3/1PPP1P1P/BQ1BRKNR w HEhe - 1 9 perft 1 25 perft 2 663 @@ -1737,7 +1738,7 @@ perft 4 482994 perft 5 13157826 perft 6 389603029 -id 1 +id 193 epd bqnrk1nr/pp2ppbp/6p1/2pp4/2P5/5P2/PPQPP1PP/B1NRKBNR w HDhd - 0 9 perft 1 26 perft 2 850 @@ -1746,7 +1747,7 @@ perft 4 759768 perft 5 21341087 perft 6 719712622 -id 1 +id 194 epd bqnrknrb/1ppp1p1p/p7/6p1/1P2p3/P1PN4/3PPPPP/BQ1RKNRB w GDgd - 0 9 perft 1 25 perft 2 721 @@ -1755,7 +1756,7 @@ perft 4 581913 perft 5 16391601 perft 6 511725087 -id 1 +id 195 epd q1b1rknr/pp1pppp1/4n2p/2p1b3/1PP5/4P3/PQ1P1PPP/1BBNRKNR w HEhe - 1 9 perft 1 32 perft 2 975 @@ -1764,7 +1765,7 @@ perft 4 955493 perft 5 32649943 perft 6 962536105 -id 1 +id 196 epd qnbbrknr/1p1ppppp/8/p1p5/5P2/PP1P4/2P1P1PP/QNBBRKNR w HEhe - 0 9 perft 1 27 perft 2 573 @@ -1773,7 +1774,7 @@ perft 4 391656 perft 5 11562434 perft 6 301166330 -id 1 +id 197 epd q1brkb1r/p1pppppp/np3B2/8/6n1/1P5N/P1PPPPPP/QN1RKB1R w HDhd - 0 9 perft 1 32 perft 2 984 @@ -1782,7 +1783,7 @@ perft 4 1007217 perft 5 32597704 perft 6 1075429389 -id 1 +id 198 epd qn1rk1rb/p1pppppp/1p2n3/8/2b5/4NPP1/PPPPP1RP/QNBRK2B w Dgd - 4 9 perft 1 22 perft 2 802 @@ -1791,7 +1792,7 @@ perft 4 697722 perft 5 17761431 perft 6 650603534 -id 1 +id 199 epd qbnrbknr/ppp2p1p/8/3pp1p1/1PP1B3/5N2/P2PPPPP/Q1NRBK1R w HDhd - 0 9 perft 1 34 perft 2 943 @@ -1800,7 +1801,7 @@ perft 4 930619 perft 5 32523099 perft 6 955802240 -id 1 +id 200 epd qnrbb1nr/pp1p1ppp/2p2k2/4p3/4P3/5PPP/PPPP4/QNRBBKNR w HC - 0 9 perft 1 20 perft 2 460 @@ -1809,7 +1810,7 @@ perft 4 241640 perft 5 5846781 perft 6 140714047 -id 1 +id 201 epd qnr1bbnr/ppk1p1pp/3p4/2p2p2/8/2P5/PP1PPPPP/QNKRBBNR w - - 1 9 perft 1 19 perft 2 572 @@ -1818,7 +1819,7 @@ perft 4 357340 perft 5 7994547 perft 6 243724815 -id 1 +id 202 epd qnrkbnrb/1p1p1ppp/2p5/4p3/p7/N1BP4/PPP1PPPP/Q1R1KNRB w gc - 0 9 perft 1 27 perft 2 579 @@ -1827,7 +1828,7 @@ perft 4 375168 perft 5 10845146 perft 6 268229097 -id 1 +id 203 epd qbnrkn1r/1pppp1p1/p3bp2/2BN3p/8/5P2/PPPPP1PP/QBNRK2R w HDhd - 0 9 perft 1 40 perft 2 1027 @@ -1836,7 +1837,7 @@ perft 4 1059229 perft 5 38511307 perft 6 1104094381 -id 1 +id 204 epd qnrbknbr/1pp2ppp/4p3/p6N/2p5/8/PPPPPPPP/Q1RBK1BR w HChc - 0 9 perft 1 22 perft 2 510 @@ -1845,7 +1846,7 @@ perft 4 300180 perft 5 7403327 perft 6 200581103 -id 1 +id 205 epd 1qkrnbbr/p1pppppp/2n5/1p6/8/5NP1/PPPPPP1P/QNRK1BBR w HC - 4 9 perft 1 24 perft 2 549 @@ -1854,7 +1855,7 @@ perft 4 352037 perft 5 9396521 perft 6 255676649 -id 1 +id 206 epd q1rknr1b/1ppppppb/2n5/p2B3p/8/1PN3P1/P1PPPP1P/Q1RKNRB1 w FCfc - 3 9 perft 1 31 perft 2 924 @@ -1863,7 +1864,7 @@ perft 4 861944 perft 5 27463479 perft 6 847726572 -id 1 +id 207 epd bbnqrk1r/pp1pppp1/2p4p/8/6n1/1N1P1P2/PPP1P1PP/BBQ1RKNR w HEhe - 4 9 perft 1 24 perft 2 804 @@ -1872,7 +1873,7 @@ perft 4 666341 perft 5 18024195 perft 6 595947631 -id 1 +id 208 epd bn1brknr/ppp1p1pp/5p2/3p4/6qQ/3P3P/PPP1PPP1/BN1BRKNR w HEhe - 4 9 perft 1 25 perft 2 854 @@ -1881,7 +1882,7 @@ perft 4 704173 perft 5 20290974 perft 6 600195008 -id 1 +id 209 epd 1nqrkbnr/2pp1ppp/pp2p3/3b4/2P5/N7/PP1PPPPP/B1QRKBNR w HDhd - 0 9 perft 1 22 perft 2 651 @@ -1890,7 +1891,7 @@ perft 4 479152 perft 5 13133439 perft 6 390886040 -id 1 +id 210 epd bnqrk1rb/1pp1pppp/p2p4/4n3/2PPP3/8/PP3PPP/BNQRKNRB w GDgd - 1 9 perft 1 30 perft 2 950 @@ -1899,7 +1900,7 @@ perft 4 889687 perft 5 27610213 perft 6 880739164 -id 1 +id 211 epd nbb1rknr/1ppq1ppp/3p4/p3p3/4P3/1N2R3/PPPP1PPP/1BBQ1KNR w Hhe - 2 9 perft 1 33 perft 2 988 @@ -1908,7 +1909,7 @@ perft 4 967575 perft 5 30894863 perft 6 985384035 -id 1 +id 212 epd nqbbrknr/2ppp2p/pp4p1/5p2/7P/3P1P2/PPPBP1P1/NQ1BRKNR w HEhe - 0 9 perft 1 27 perft 2 492 @@ -1917,7 +1918,7 @@ perft 4 276569 perft 5 7583292 perft 6 175376176 -id 1 +id 213 epd 1qbrkb1r/pppppppp/8/3n4/4P1n1/PN6/1PPP1P1P/1QBRKBNR w HDhd - 3 9 perft 1 28 perft 2 800 @@ -1926,7 +1927,7 @@ perft 4 630374 perft 5 17313279 perft 6 507140861 -id 1 +id 214 epd 1qbrknrb/1p1ppppp/1np5/8/p4P1P/4P1N1/PPPP2P1/NQBRK1RB w GDgd - 0 9 perft 1 21 perft 2 482 @@ -1935,7 +1936,7 @@ perft 4 267935 perft 5 6218644 perft 6 168704845 -id 1 +id 215 epd nbqrbkr1/ppp1pppp/8/3p4/6n1/2P2PPN/PP1PP2P/NBQRBK1R w HDd - 1 9 perft 1 29 perft 2 921 @@ -1944,7 +1945,7 @@ perft 4 840262 perft 5 24138518 perft 6 806554650 -id 1 +id 216 epd nqrb1knr/1ppbpp1p/p7/3p2p1/2P3P1/5P1P/PP1PP3/NQRBBKNR w HChc - 1 9 perft 1 31 perft 2 803 @@ -1953,7 +1954,7 @@ perft 4 665799 perft 5 21998733 perft 6 583349773 -id 1 +id 217 epd 1qrkbbr1/pppp1ppp/1n3n2/4p3/5P2/1N6/PPPPP1PP/1QRKBBNR w HCc - 0 9 perft 1 25 perft 2 715 @@ -1962,7 +1963,7 @@ perft 4 556325 perft 5 15514933 perft 6 459533767 -id 1 +id 218 epd nqrkb1rb/pp2pppp/2p1n3/3p4/3PP1N1/8/PPP2PPP/NQRKB1RB w GCgc - 0 9 perft 1 26 perft 2 795 @@ -1971,7 +1972,7 @@ perft 4 679387 perft 5 19185851 perft 6 616508881 -id 1 +id 219 epd nb1rknbr/pp2ppp1/8/2Bp3p/6P1/2P2P1q/PP1PP2P/NBQRKN1R w HDhd - 0 9 perft 1 35 perft 2 1391 @@ -1980,7 +1981,7 @@ perft 4 1726888 perft 5 53033675 perft 6 2139267832 -id 1 +id 220 epd nqrbkn1r/pp1pp1pp/8/2p2p2/5P2/P3B2P/1PbPP1P1/NQRBKN1R w HChc - 0 9 perft 1 23 perft 2 758 @@ -1989,7 +1990,7 @@ perft 4 653854 perft 5 18296195 perft 6 628403401 -id 1 +id 221 epd nqrknbbr/pp1pppp1/7p/2p5/7P/1P1N4/P1PPPPPB/NQRK1B1R w HChc - 2 9 perft 1 29 perft 2 824 @@ -1998,7 +1999,7 @@ perft 4 683686 perft 5 19429491 perft 6 595493802 -id 1 +id 222 epd 1qrknrbb/B1p1pppp/8/1p1p4/2n2P2/1P6/P1PPP1PP/NQRKNR1B w FCfc - 0 9 perft 1 28 perft 2 771 @@ -2007,7 +2008,7 @@ perft 4 581721 perft 5 16065378 perft 6 483037840 -id 1 +id 223 epd bbnrqk1r/1ppppppp/8/7n/1p6/P6P/1BPPPPP1/1BNRQKNR w HDhd - 0 9 perft 1 25 perft 2 601 @@ -2016,7 +2017,7 @@ perft 4 396661 perft 5 10697065 perft 6 289472497 -id 1 +id 224 epd bnrbqknr/ppp3p1/3ppp1Q/7p/3P4/1P6/P1P1PPPP/BNRB1KNR w HChc - 0 9 perft 1 32 perft 2 845 @@ -2025,7 +2026,7 @@ perft 4 742888 perft 5 23717883 perft 6 682154649 -id 1 +id 225 epd bn1qkb1r/pprppppp/8/2p5/2PPP1n1/8/PPR2PPP/BN1QKBNR w Hh - 1 9 perft 1 32 perft 2 856 @@ -2034,7 +2035,7 @@ perft 4 768595 perft 5 25245957 perft 6 727424329 -id 1 +id 226 epd 1nrqknrb/p1pp1ppp/1p2p3/3N4/5P1P/5b2/PPPPP3/B1RQKNRB w GCgc - 2 9 perft 1 33 perft 2 873 @@ -2043,7 +2044,7 @@ perft 4 779473 perft 5 25128076 perft 6 745401024 -id 1 +id 227 epd nbbrqrk1/pppppppp/8/2N1n3/P7/6P1/1PPPPP1P/1BBRQKNR w HD - 3 9 perft 1 25 perft 2 555 @@ -2052,7 +2053,7 @@ perft 4 342296 perft 5 9153089 perft 6 234841945 -id 1 +id 228 epd 1rbbqknr/1ppp1pp1/1n2p3/p6p/4P1P1/P6N/1PPP1P1P/NRBBQK1R w HBhb - 0 9 perft 1 25 perft 2 693 @@ -2061,7 +2062,7 @@ perft 4 528070 perft 5 15133381 perft 6 439344945 -id 1 +id 229 epd nrq1kbnr/p1pbpppp/3p4/1p6/6P1/1N3N2/PPPPPP1P/1RBQKB1R w HBhb - 4 9 perft 1 24 perft 2 648 @@ -2070,7 +2071,7 @@ perft 4 471192 perft 5 12871967 perft 6 380436777 -id 1 +id 230 epd nr1qknr1/p1pppp1p/b5p1/1p6/8/P4PP1/1bPPP1RP/NRBQKN1B w Bgb - 0 9 perft 1 18 perft 2 533 @@ -2079,7 +2080,7 @@ perft 4 331243 perft 5 7777833 perft 6 234905172 -id 1 +id 231 epd nbrqbknr/1ppp2pp/8/4pp2/p2PP1P1/7N/PPP2P1P/NBRQBK1R w HChc - 0 9 perft 1 29 perft 2 803 @@ -2088,7 +2089,7 @@ perft 4 706648 perft 5 22305910 perft 6 672322762 -id 1 +id 232 epd nr1b1k1r/ppp1pppp/2bp1n2/6P1/2P3q1/5P2/PP1PP2P/NRQBBKNR w HBhb - 1 9 perft 1 27 perft 2 1199 @@ -2097,7 +2098,7 @@ perft 4 1296241 perft 5 35121759 perft 6 1418677099 -id 1 +id 233 epd nrqkbbnr/2pppp1p/p7/1p6/2P1Pp2/8/PPNP2PP/1RQKBBNR w HBhb - 0 9 perft 1 28 perft 2 613 @@ -2106,7 +2107,7 @@ perft 4 432750 perft 5 13097064 perft 6 345294379 -id 1 +id 234 epd 1rqkbnrb/pp1ppp1p/1n4p1/B1p5/3PP3/4N3/PPP2PPP/NRQK2RB w GBgb - 0 9 perft 1 33 perft 2 723 @@ -2115,7 +2116,7 @@ perft 4 590970 perft 5 19715083 perft 6 535650233 -id 1 +id 235 epd nbrqkn1r/1pppp2p/5pp1/p2b4/5P2/P2PN3/1PP1P1PP/NBRQK1BR w HChc - 2 9 perft 1 23 perft 2 607 @@ -2124,7 +2125,7 @@ perft 4 400970 perft 5 11026383 perft 6 290708878 -id 1 +id 236 epd nrqbknbr/pp1pppp1/8/2p4p/P3PP2/8/1PPP2PP/NRQBKNBR w HBhb - 1 9 perft 1 26 perft 2 700 @@ -2133,7 +2134,7 @@ perft 4 556026 perft 5 16058815 perft 6 485460242 -id 1 +id 237 epd nrqknbbr/p2pppp1/1pp5/6Qp/3P4/1P3P2/P1P1P1PP/NR1KNBBR w HBhb - 0 9 perft 1 40 perft 2 905 @@ -2142,7 +2143,7 @@ perft 4 829746 perft 5 29263502 perft 6 791963709 -id 1 +id 238 epd nrqknrbb/1p3ppp/p2p4/2p1p3/1P6/3PP1P1/P1P2P1P/NRQKNRBB w FBfb - 0 9 perft 1 29 perft 2 780 @@ -2151,7 +2152,7 @@ perft 4 654495 perft 5 19532077 perft 6 593181101 -id 1 +id 239 epd 1bnrkqnr/p1pppp2/7p/1p4p1/4b3/7N/PPPP1PPP/BBNRKQ1R w HDhd - 0 9 perft 1 25 perft 2 725 @@ -2160,7 +2161,7 @@ perft 4 565006 perft 5 16661676 perft 6 487354613 -id 1 +id 240 epd bnrbkq1r/pp2p1pp/5n2/2pp1p2/P7/N1PP4/1P2PPPP/B1RBKQNR w HChc - 1 9 perft 1 24 perft 2 745 @@ -2169,7 +2170,7 @@ perft 4 584015 perft 5 15079602 perft 6 488924040 -id 1 +id 241 epd 2rkqbnr/p1pppppp/2b5/1pn5/1P3P1Q/2B5/P1PPP1PP/1NRK1BNR w HChc - 3 9 perft 1 33 perft 2 904 @@ -2178,7 +2179,7 @@ perft 4 840025 perft 5 28194726 perft 6 801757709 -id 1 +id 242 epd bnrkqnrb/2pppp2/8/pp4pp/1P5P/6P1/P1PPPPB1/BNRKQNR1 w GCgc - 0 9 perft 1 34 perft 2 1059 @@ -2187,7 +2188,7 @@ perft 4 1054311 perft 5 33195397 perft 6 1036498304 -id 1 +id 243 epd 1bbrkq1r/pppp2pp/1n2pp1n/8/2PP4/1N4P1/PP2PP1P/1BBRKQNR w HDhd - 1 9 perft 1 33 perft 2 891 @@ -2196,7 +2197,7 @@ perft 4 814247 perft 5 26970098 perft 6 788040469 -id 1 +id 244 epd nrbbkqnr/1p2pp1p/p1p3p1/3p4/8/1PP5/P2PPPPP/NRBBKQNR w HBhb - 0 9 perft 1 21 perft 2 567 @@ -2205,7 +2206,7 @@ perft 4 376487 perft 5 9539687 perft 6 284426039 -id 1 +id 245 epd 1rbkqbr1/ppp1pppp/1n5n/3p4/3P4/1PP3P1/P3PP1P/NRBKQBNR w HBb - 1 9 perft 1 27 perft 2 752 @@ -2214,7 +2215,7 @@ perft 4 606783 perft 5 16986290 perft 6 521817800 -id 1 +id 246 epd nrbkq1rb/1ppp1pp1/4p1n1/p6p/2PP4/5P2/PPK1P1PP/NRB1QNRB w gb - 0 9 perft 1 35 perft 2 697 @@ -2223,7 +2224,7 @@ perft 4 505836 perft 5 16906409 perft 6 390324794 -id 1 +id 247 epd nbrkbqnr/p2pp1p1/5p2/1pp4p/7P/3P2P1/PPP1PP2/NBKRBQNR w hc - 0 9 perft 1 25 perft 2 679 @@ -2232,7 +2233,7 @@ perft 4 484921 perft 5 12879258 perft 6 376652259 -id 1 +id 248 epd nrkb1qnr/ppppp1p1/6bp/5p2/1PP1P1P1/8/P2P1P1P/NRKBBQNR w HBhb - 1 9 perft 1 32 perft 2 761 @@ -2241,7 +2242,7 @@ perft 4 632916 perft 5 20671433 perft 6 568524724 -id 1 +id 249 epd nrk1bbnr/p1q1pppp/1ppp4/8/3P3P/4K3/PPP1PPP1/NR1QBBNR w hb - 0 9 perft 1 30 perft 2 719 @@ -2250,7 +2251,7 @@ perft 4 541389 perft 5 16278120 perft 6 423649784 -id 1 +id 250 epd nrkqbr1b/1pppp1pp/5pn1/p6N/1P3P2/8/P1PPP1PP/NRKQB1RB w GBb - 0 9 perft 1 26 perft 2 494 @@ -2259,7 +2260,7 @@ perft 4 296170 perft 5 8763742 perft 6 206993496 -id 1 +id 251 epd nbrkq2r/pppp1bpp/4p1n1/5p2/7P/2P3N1/PP1PPPP1/NBKRQ1BR w hc - 0 9 perft 1 27 perft 2 701 @@ -2268,7 +2269,7 @@ perft 4 535052 perft 5 15394667 perft 6 443506342 -id 1 +id 252 epd nrkbqnbr/2ppp2p/pp6/5pp1/P1P5/8/1P1PPPPP/NRKBQNBR w HBhb - 0 9 perft 1 21 perft 2 487 @@ -2277,7 +2278,7 @@ perft 4 285387 perft 5 7218486 perft 6 193586674 -id 1 +id 253 epd nr1qnbbr/pk1pppp1/1pp4p/8/3P4/5P1P/PPP1P1P1/NRKQNBBR w HB - 0 9 perft 1 22 perft 2 546 @@ -2286,7 +2287,7 @@ perft 4 352855 perft 5 9587439 perft 6 259830255 -id 1 +id 254 epd nrkq1rbb/pp1ppp1p/2pn4/8/PP3Pp1/7P/2PPP1P1/NRKQNRBB w FBfb - 0 9 perft 1 26 perft 2 839 @@ -2295,7 +2296,7 @@ perft 4 723845 perft 5 19867117 perft 6 658535326 -id 1 +id 255 epd b2rknqr/pp1ppppp/8/2P5/n7/P7/1PPNPPPb/BBNRK1QR w HDhd - 2 9 perft 1 24 perft 2 699 @@ -2304,7 +2305,7 @@ perft 4 575172 perft 5 17734818 perft 6 535094237 -id 1 +id 256 epd bnrbknqr/pp2p2p/2p3p1/3p1p2/8/3P4/PPPNPPPP/B1RBKNQR w HChc - 0 9 perft 1 23 perft 2 580 @@ -2313,7 +2314,7 @@ perft 4 385917 perft 5 10133092 perft 6 288041554 -id 1 +id 257 epd bnrknb1r/pppp2pp/8/4pp2/6P1/3P3P/qPP1PPQ1/BNRKNB1R w HChc - 0 9 perft 1 28 perft 2 1100 @@ -2322,7 +2323,7 @@ perft 4 1217514 perft 5 36142423 perft 6 1361341249 -id 1 +id 258 epd b1rknqrb/ppp1p1p1/2np1p1p/8/4N3/6PQ/PPPPPP1P/B1RKN1RB w GCgc - 0 9 perft 1 36 perft 2 629 @@ -2331,7 +2332,7 @@ perft 4 453064 perft 5 16897544 perft 6 367503974 -id 1 +id 259 epd nb1rknqr/pbppp2p/6p1/1p3p2/5P2/3KP3/PPPP2PP/NBBR1NQR w hd - 2 9 perft 1 18 perft 2 557 @@ -2340,7 +2341,7 @@ perft 4 300744 perft 5 5822387 perft 6 180936551 -id 1 +id 260 epd nr1bknqr/1ppb1ppp/p7/3pp3/B7/2P3NP/PP1PPPP1/NRB1K1QR w HBhb - 2 9 perft 1 28 perft 2 688 @@ -2349,7 +2350,7 @@ perft 4 519785 perft 5 15153092 perft 6 425149249 -id 1 +id 261 epd nrbkn2r/pppp1pqp/4p1p1/8/3P2P1/P3B3/P1P1PP1P/NR1KNBQR w HBhb - 1 9 perft 1 32 perft 2 808 @@ -2358,7 +2359,7 @@ perft 4 676525 perft 5 22094260 perft 6 609377239 -id 1 +id 262 epd nrbknqrb/2p1ppp1/1p6/p2p2Bp/1P6/3P1P2/P1P1P1PP/NR1KNQRB w GBgb - 0 9 perft 1 30 perft 2 625 @@ -2367,7 +2368,7 @@ perft 4 418895 perft 5 12225742 perft 6 301834282 -id 1 +id 263 epd nbr1knqr/1pp1p1pp/3p1pb1/8/7P/5P2/PPPPPQP1/NBRKBN1R w HC - 2 9 perft 1 29 perft 2 863 @@ -2376,7 +2377,7 @@ perft 4 800239 perft 5 24965592 perft 6 799182442 -id 1 +id 264 epd n1kbbnqr/prp2ppp/1p1p4/4p3/1P2P3/3P1B2/P1P2PPP/NRK1BNQR w HBh - 2 9 perft 1 26 perft 2 653 @@ -2385,7 +2386,7 @@ perft 4 449719 perft 5 12187583 perft 6 336872952 -id 1 +id 265 epd nrknbbqr/pp3p1p/B3p1p1/2pp4/4P3/2N3P1/PPPP1P1P/NRK1B1QR w HBhb - 0 9 perft 1 29 perft 2 683 @@ -2394,7 +2395,7 @@ perft 4 501807 perft 5 14684565 perft 6 394951291 -id 1 +id 266 epd n1knbqrb/pr1p1ppp/Qp6/2p1p3/4P3/6P1/PPPP1P1P/NRKNB1RB w GBg - 2 9 perft 1 31 perft 2 552 @@ -2403,7 +2404,7 @@ perft 4 371343 perft 5 11663330 perft 6 283583340 -id 1 +id 267 epd nbrknqbr/p3p1pp/1p1p1p2/2p5/2Q1PP2/8/PPPP2PP/NBRKN1BR w HChc - 0 9 perft 1 37 perft 2 913 @@ -2412,7 +2413,7 @@ perft 4 825748 perft 5 28899548 perft 6 759875563 -id 1 +id 268 epd nrkb1qbr/pp1pppp1/5n2/7p/2p5/1N1NPP2/PPPP2PP/1RKB1QBR w HBhb - 0 9 perft 1 25 perft 2 712 @@ -2421,7 +2422,7 @@ perft 4 543870 perft 5 15045589 perft 6 445074372 -id 1 +id 269 epd nrk2bbr/pppqpppp/3p4/8/1P3nP1/3P4/P1P1PP1P/NRKNQBBR w HBhb - 1 9 perft 1 24 perft 2 814 @@ -2430,7 +2431,7 @@ perft 4 670162 perft 5 17603960 perft 6 592121050 -id 1 +id 270 epd nrknqrbb/1p2ppp1/2pp4/Q6p/P2P3P/8/1PP1PPP1/NRKN1RBB w FBfb - 0 9 perft 1 34 perft 2 513 @@ -2439,7 +2440,7 @@ perft 4 303908 perft 5 9569590 perft 6 206509331 -id 1 +id 271 epd bbnrk1rq/pp2p1pp/2ppn3/5p2/8/3NNP1P/PPPPP1P1/BB1RK1RQ w GDgd - 1 9 perft 1 28 perft 2 697 @@ -2448,7 +2449,7 @@ perft 4 517917 perft 5 15301879 perft 6 410843713 -id 1 +id 272 epd bnrbknrq/ppppp2p/6p1/5p2/4QPP1/8/PPPPP2P/BNRBKNR1 w GCgc - 0 9 perft 1 37 perft 2 901 @@ -2457,7 +2458,7 @@ perft 4 877372 perft 5 31385912 perft 6 903831981 -id 1 +id 273 epd bnkrnbrq/ppppp1p1/B6p/5p2/8/4P3/PPPP1PPP/BNKRN1RQ w - - 0 9 perft 1 26 perft 2 417 @@ -2466,7 +2467,7 @@ perft 4 217095 perft 5 5980981 perft 6 133080499 -id 1 +id 274 epd bnrk1rqb/2pppp1p/3n4/pp4p1/3Q1P2/2N3P1/PPPPP2P/B1RKNR1B w FCfc - 0 9 perft 1 49 perft 2 1655 @@ -2475,7 +2476,7 @@ perft 4 2512003 perft 5 107234294 perft 6 3651608327 -id 1 +id 275 epd nbbrk1rq/pp2pppp/2pp4/8/2P2n2/6N1/PP1PP1PP/NBBRKR1Q w Dgd - 0 9 perft 1 28 perft 2 960 @@ -2484,7 +2485,7 @@ perft 4 884237 perft 5 26083252 perft 6 846682836 -id 1 +id 276 epd nrbb2rq/pppk1ppp/4p1n1/3p4/6P1/1BP5/PP1PPPQP/NRB1KNR1 w GB - 0 9 perft 1 28 perft 2 735 @@ -2493,7 +2494,7 @@ perft 4 593839 perft 5 18588316 perft 6 512048946 -id 1 +id 277 epd nrbk1brq/p1ppppp1/7p/1p6/4P1nP/P7/1PPP1PP1/NRBKNBRQ w GBgb - 0 9 perft 1 22 perft 2 572 @@ -2502,7 +2503,7 @@ perft 4 351494 perft 5 8525056 perft 6 247615348 -id 1 +id 278 epd nrbk1rqb/1pp2ppp/5n2/p2pp3/5B2/1N1P2P1/PPP1PP1P/1R1KNRQB w FBfb - 0 9 perft 1 35 perft 2 927 @@ -2511,7 +2512,7 @@ perft 4 849932 perft 5 28465693 perft 6 783048748 -id 1 +id 279 epd nbrkb1rq/p1pp1ppp/4n3/4p3/Pp6/6N1/1PPPPPPP/NBRKBRQ1 w Cgc - 0 9 perft 1 20 perft 2 456 @@ -2520,7 +2521,7 @@ perft 4 247733 perft 5 6124625 perft 6 154766108 -id 1 +id 280 epd nrkb1nrq/p2pp1pp/1pp2p2/7b/6PP/5P2/PPPPP2N/NRKBB1RQ w GBgb - 0 9 perft 1 21 perft 2 479 @@ -2529,7 +2530,7 @@ perft 4 264493 perft 5 6696458 perft 6 165253524 -id 1 +id 281 epd nr1nbbr1/pppkpp1p/6p1/3p4/P6P/1P6/1RPPPPP1/N1KNBBRQ w G - 1 9 perft 1 20 perft 2 498 @@ -2538,7 +2539,7 @@ perft 4 288813 perft 5 7197322 perft 6 188021682 -id 1 +id 282 epd nrknbrqb/3p1ppp/ppN1p3/8/6P1/8/PPPPPP1P/1RKNBRQB w FBfb - 0 9 perft 1 32 perft 2 526 @@ -2547,7 +2548,7 @@ perft 4 319836 perft 5 10755190 perft 6 220058991 -id 1 +id 283 epd nbrkn1bq/p1pppr1p/1p6/5pp1/8/1N2PP2/PPPP2PP/1BKRNRBQ w c - 1 9 perft 1 19 perft 2 491 @@ -2556,7 +2557,7 @@ perft 4 277313 perft 5 6230616 perft 6 180748649 -id 1 +id 284 epd nrkbnrbq/ppppppp1/8/8/7p/PP3P2/2PPPRPP/NRKBN1BQ w Bfb - 0 9 perft 1 16 perft 2 353 @@ -2565,7 +2566,7 @@ perft 4 156002 perft 5 3008668 perft 6 82706705 -id 1 +id 285 epd nrknrbbq/p4ppp/2p1p3/1p1p4/1P2P3/2P5/P1NP1PPP/1RKNRBBQ w EBeb - 0 9 perft 1 29 perft 2 728 @@ -2574,7 +2575,7 @@ perft 4 587668 perft 5 18231199 perft 6 511686397 -id 1 +id 286 epd nrknr1bb/pppp1p2/7p/2qPp1p1/8/1P5P/P1P1PPP1/NRKNRQBB w EBeb - 0 9 perft 1 20 perft 2 714 @@ -2583,7 +2584,7 @@ perft 4 500458 perft 5 11132758 perft 6 386064577 -id 1 +id 287 epd bbqnrrkn/ppp2p1p/3pp1p1/8/1PP5/2Q5/P1BPPPPP/B2NRKRN w GE - 0 9 perft 1 39 perft 2 593 @@ -2592,7 +2593,7 @@ perft 4 424799 perft 5 16764576 perft 6 346185058 -id 1 +id 288 epd bqn1rkrn/p1p2ppp/1p1p4/4p3/3PP2b/8/PPP2PPP/BQNBRKRN w GEge - 2 9 perft 1 25 perft 2 773 @@ -2601,7 +2602,7 @@ perft 4 616817 perft 5 16632403 perft 6 515838333 -id 1 +id 289 epd bqnrkb1n/p1p1pprp/3p4/1p2P1p1/2PP4/8/PP3PPP/BQNRKBRN w GDd - 1 9 perft 1 31 perft 2 860 @@ -2610,7 +2611,7 @@ perft 4 810379 perft 5 27233018 perft 6 813751250 -id 1 +id 290 epd bqr1krnb/ppppppp1/7p/3n4/1P4P1/P4N2/2PPPP1P/BQNRKR1B w FDf - 3 9 perft 1 31 perft 2 709 @@ -2619,7 +2620,7 @@ perft 4 559830 perft 5 18608857 perft 6 480498340 -id 1 +id 291 epd qbbn1krn/pp3ppp/4r3/2ppp3/P1P4P/8/1P1PPPP1/QBBNRKRN w GEg - 1 9 perft 1 26 perft 2 775 @@ -2628,7 +2629,7 @@ perft 4 649673 perft 5 18476807 perft 6 582542257 -id 1 +id 292 epd qnbbrkrn/1p1pp2p/p7/2p2pp1/8/4P2P/PPPP1PPK/QNBBRR1N w ge - 0 9 perft 1 25 perft 2 599 @@ -2637,7 +2638,7 @@ perft 4 389104 perft 5 10260500 perft 6 279222412 -id 1 +id 293 epd qnbrkbrn/1ppp2p1/p3p2p/5p2/P4P2/1P6/2PPP1PP/QNBRKBRN w GDgd - 0 9 perft 1 27 perft 2 588 @@ -2646,7 +2647,7 @@ perft 4 394829 perft 5 11640416 perft 6 293541380 -id 1 +id 294 epd 1nbrkrnb/p1pppp1p/1pq3p1/8/4P3/P1P4N/1P1P1PPP/QNBRKR1B w FDfd - 1 9 perft 1 18 perft 2 609 @@ -2655,7 +2656,7 @@ perft 4 406831 perft 5 8604788 perft 6 299491047 -id 1 +id 295 epd qb1r1krn/pppp2pp/1n2ppb1/4P3/7P/8/PPPP1PP1/QBNRBKRN w GDgd - 0 9 perft 1 20 perft 2 578 @@ -2664,7 +2665,7 @@ perft 4 349453 perft 5 7939483 perft 6 229142178 -id 1 +id 296 epd qnr1bkrn/p3pppp/1bpp4/1p6/2P2PP1/8/PP1PPN1P/QNRBBKR1 w GCgc - 0 9 perft 1 30 perft 2 865 @@ -2673,7 +2674,7 @@ perft 4 771705 perft 5 24475596 perft 6 719842237 -id 1 +id 297 epd 1nkrbbrn/qppppppp/8/8/p2P4/1P5P/P1P1PPP1/QNKRBBRN w - - 0 9 perft 1 27 perft 2 672 @@ -2682,7 +2683,7 @@ perft 4 505278 perft 5 14065717 perft 6 410130412 -id 1 +id 298 epd 1qrkbrnb/ppp1p1pp/n2p4/5p2/4N3/8/PPPPPPPP/Q1RKBRNB w Ffc - 2 9 perft 1 25 perft 2 718 @@ -2691,7 +2692,7 @@ perft 4 536771 perft 5 14404324 perft 6 424279467 -id 1 +id 299 epd q1nrkrbn/pp1pppp1/2p4p/8/P7/5Pb1/BPPPPNPP/Q1NRKRB1 w FDfd - 0 9 perft 1 22 perft 2 558 @@ -2700,7 +2701,7 @@ perft 4 336042 perft 5 8516966 perft 6 228074630 -id 1 +id 300 epd qnrbkrbn/1p1p1pp1/p1p5/4p2p/8/3P1P2/PPP1P1PP/QNRBKRBN w FCfc - 0 9 perft 1 28 perft 2 669 @@ -2709,7 +2710,7 @@ perft 4 440930 perft 5 12055174 perft 6 313276304 -id 1 +id 301 epd qnrkr1bn/p1pp1ppp/8/1p2p3/3P1P2/bP4P1/P1P1P2P/QNRKRBBN w ECec - 1 9 perft 1 23 perft 2 845 @@ -2718,7 +2719,7 @@ perft 4 759778 perft 5 19939053 perft 6 718075943 -id 1 +id 302 epd q1krrnbb/p1p1pppp/2np4/1pB5/5P2/8/PPPPP1PP/QNRKRN1B w EC - 0 9 perft 1 29 perft 2 776 @@ -2727,7 +2728,7 @@ perft 4 631941 perft 5 18110831 perft 6 549019739 -id 1 +id 303 epd bbn1rkrn/pp1p1ppp/8/2p1p1q1/6P1/P7/BPPPPP1P/B1NQRKRN w GEge - 0 9 perft 1 26 perft 2 936 @@ -2736,7 +2737,7 @@ perft 4 906801 perft 5 24984621 perft 6 901444251 -id 1 +id 304 epd bn1brkrn/pp1qpp1p/2p3p1/3p4/1PPP4/P7/4PPPP/BNQBRKRN w GEge - 1 9 perft 1 29 perft 2 755 @@ -2745,7 +2746,7 @@ perft 4 645963 perft 5 20128587 perft 6 600207069 -id 1 +id 305 epd b2rkbrn/p1pppppp/qp6/8/1n6/2B2P2/P1PPP1PP/1NQRKBRN w GDgd - 0 9 perft 1 24 perft 2 878 @@ -2754,7 +2755,7 @@ perft 4 791007 perft 5 20840078 perft 6 775795187 -id 1 +id 306 epd b2rkrnb/pqp1pppp/n7/1p1p4/P7/N1P2N2/1P1PPPPP/B1QRKR1B w FDfd - 4 9 perft 1 26 perft 2 724 @@ -2763,7 +2764,7 @@ perft 4 571891 perft 5 16109522 perft 6 492933398 -id 1 +id 307 epd 1bbqrkrn/ppppp1p1/8/5p1p/P1n3P1/3P4/1PP1PP1P/NBBQRRKN w ge - 1 9 perft 1 25 perft 2 678 @@ -2772,7 +2773,7 @@ perft 4 461211 perft 5 12173245 perft 6 329661421 -id 1 +id 308 epd nqb1rrkn/ppp1bppp/3pp3/8/3P4/1P6/PQP1PPPP/N1BBRRKN w - - 1 9 perft 1 23 perft 2 503 @@ -2781,7 +2782,7 @@ perft 4 290341 perft 5 7626054 perft 6 188215608 -id 1 +id 309 epd nqbrkbr1/p1pppppp/1p6/2N2n2/2P5/5P2/PP1PP1PP/1QBRKBRN w GDgd - 1 9 perft 1 29 perft 2 688 @@ -2790,7 +2791,7 @@ perft 4 506302 perft 5 15167248 perft 6 399015237 -id 1 +id 310 epd nqbrkrn1/1ppppp2/6pp/p7/1P6/2Q5/P1PPPPPP/N1BRKRNB w FDfd - 0 9 perft 1 36 perft 2 602 @@ -2799,7 +2800,7 @@ perft 4 397340 perft 5 13706856 perft 6 291708797 -id 1 +id 311 epd nbqrbrkn/pp1p1pp1/2p5/4p2p/2P3P1/1P3P2/P2PP2P/NBQRBKRN w GD - 0 9 perft 1 34 perft 2 655 @@ -2808,7 +2809,7 @@ perft 4 474396 perft 5 16613630 perft 6 379344541 -id 1 +id 312 epd nqrbbrkn/1p1pppp1/8/p1p4p/4P2P/1N4P1/PPPP1P2/1QRBBKRN w GC - 0 9 perft 1 23 perft 2 597 @@ -2817,7 +2818,7 @@ perft 4 400357 perft 5 10096863 perft 6 294900903 -id 1 +id 313 epd nqrkbbrn/2p1p1pp/pp1p1p2/8/P2N4/2P5/1P1PPPPP/1QRKBBRN w GCgc - 0 9 perft 1 32 perft 2 744 @@ -2826,7 +2827,7 @@ perft 4 550728 perft 5 17597164 perft 6 428786656 -id 1 +id 314 epd n1krbrnb/q1pppppp/p7/1p6/3Q4/2P2P2/PP1PP1PP/N1RKBRNB w FC - 1 9 perft 1 43 perft 2 1038 @@ -2835,7 +2836,7 @@ perft 4 1074450 perft 5 40918952 perft 6 1126603824 -id 1 +id 315 epd nb1rkrbn/p1pp1p1p/qp6/4p1p1/5PP1/P7/1PPPPB1P/NBQRKR1N w FDfd - 2 9 perft 1 26 perft 2 645 @@ -2844,7 +2845,7 @@ perft 4 445464 perft 5 11911314 perft 6 342563372 -id 1 +id 316 epd nqr1krbn/pppp1ppp/8/8/3pP3/5P2/PPPb1NPP/NQRBKRB1 w FCfc - 3 9 perft 1 2 perft 2 51 @@ -2853,7 +2854,7 @@ perft 4 27743 perft 5 612305 perft 6 17040200 -id 1 +id 317 epd n1rkrbbn/pqppppp1/7p/1p6/8/1NPP4/PP1KPPPP/1QR1RBBN w ec - 0 9 perft 1 25 perft 2 674 @@ -2862,7 +2863,7 @@ perft 4 505337 perft 5 13421727 perft 6 403551903 -id 1 +id 318 epd 1qrkrnbb/1p1p1ppp/pnp1p3/8/3PP3/P6P/1PP2PP1/NQRKRNBB w ECec - 0 9 perft 1 24 perft 2 688 @@ -2871,7 +2872,7 @@ perft 4 511444 perft 5 13322502 perft 6 403441498 -id 1 +id 319 epd 1bnrqkrn/2ppppp1/p7/1p1b3p/3PP1P1/8/PPPQ1P1P/BBNR1KRN w GDgd - 1 9 perft 1 35 perft 2 925 @@ -2880,7 +2881,7 @@ perft 4 857060 perft 5 30458921 perft 6 824344087 -id 1 +id 320 epd bnrbqkr1/ppp2pp1/6n1/3pp2p/1P6/2N3N1/P1PPPPPP/B1RBQRK1 w gc - 0 9 perft 1 23 perft 2 704 @@ -2889,7 +2890,7 @@ perft 4 539587 perft 5 14154852 perft 6 450893738 -id 1 +id 321 epd 1nrqkbrn/p1pppppp/8/1p1b4/P6P/5P2/1PPPP1P1/BNRQKBRN w GCgc - 1 9 perft 1 19 perft 2 505 @@ -2898,7 +2899,7 @@ perft 4 281422 perft 5 6450025 perft 6 175593967 -id 1 +id 322 epd b1rqkrnb/ppppppp1/8/6p1/3n4/NP6/P1PPPP1P/B1RQKRNB w FCfc - 0 9 perft 1 25 perft 2 614 @@ -2907,7 +2908,7 @@ perft 4 377660 perft 5 10391021 perft 6 259629603 -id 1 +id 323 epd nbbrqkrn/ppp3p1/3pp3/5p1p/1P2P3/P7/2PPQPPP/NBBR1KRN w GDgd - 0 9 perft 1 30 perft 2 833 @@ -2916,7 +2917,7 @@ perft 4 717713 perft 5 22873901 perft 6 649556666 -id 1 +id 324 epd nr1bqrk1/ppp1pppp/6n1/3pP3/8/5PQb/PPPP2PP/NRBB1KRN w GB - 3 9 perft 1 26 perft 2 734 @@ -2925,7 +2926,7 @@ perft 4 582591 perft 5 17199594 perft 6 512134836 -id 1 +id 325 epd 1rbqkbr1/ppppp1pp/1n6/4np2/3P1P2/6P1/PPPQP2P/NRB1KBRN w GBgb - 1 9 perft 1 27 perft 2 662 @@ -2934,7 +2935,7 @@ perft 4 447464 perft 5 13038519 perft 6 338365642 -id 1 +id 326 epd nr1qkr1b/ppp1pp1p/4bn2/3p2p1/4P3/1Q6/PPPP1PPP/NRB1KRNB w FBfb - 4 9 perft 1 33 perft 2 939 @@ -2943,7 +2944,7 @@ perft 4 942138 perft 5 30995969 perft 6 991509814 -id 1 +id 327 epd nb1qbkrn/pprp1pp1/7p/2p1pB2/Q1PP4/8/PP2PPPP/N1R1BKRN w GCg - 2 9 perft 1 47 perft 2 1128 @@ -2952,7 +2953,7 @@ perft 4 1306753 perft 5 56747878 perft 6 1560584212 -id 1 +id 328 epd nrqb1rkn/pp2pppp/2bp4/2p5/6P1/2P3N1/PP1PPP1P/NRQBBRK1 w - - 3 9 perft 1 24 perft 2 828 @@ -2961,7 +2962,7 @@ perft 4 723705 perft 5 19506135 perft 6 668969549 -id 1 +id 329 epd nrq1bbrn/ppkpp2p/2p3p1/P4p2/8/4P1N1/1PPP1PPP/NRQKBBR1 w GB - 0 9 perft 1 25 perft 2 525 @@ -2970,7 +2971,7 @@ perft 4 309994 perft 5 8250997 perft 6 201795680 -id 1 +id 330 epd Br1kbrn1/pqpppp2/8/6pp/3b2P1/1N6/PPPPPP1P/1RQKBRN1 w FBfb - 3 9 perft 1 20 perft 2 790 @@ -2979,7 +2980,7 @@ perft 4 695905 perft 5 17735648 perft 6 669854148 -id 1 +id 331 epd nbrqkrbn/2p1p1pp/p7/1p1p1p2/4P1P1/5P2/PPPP3P/NBRQKRBN w FCfc - 0 9 perft 1 29 perft 2 771 @@ -2988,7 +2989,7 @@ perft 4 647106 perft 5 19192982 perft 6 591335970 -id 1 +id 332 epd 1rqbkrbn/1ppppp1p/1n6/p1N3p1/8/2P4P/PP1PPPP1/1RQBKRBN w FBfb - 0 9 perft 1 29 perft 2 502 @@ -2997,7 +2998,7 @@ perft 4 287739 perft 5 8652810 perft 6 191762235 -id 1 +id 333 epd 1rqkrbbn/ppnpp1pp/8/2p5/6p1/3P4/PPP1PPPP/NRK1RBBN w eb - 0 9 perft 1 19 perft 2 531 @@ -3006,7 +3007,7 @@ perft 4 300384 perft 5 6506674 perft 6 184309316 -id 1 +id 334 epd nrqkrnbb/p1pp2pp/5p2/4P3/2p5/4N3/PP1PP1PP/NRQKR1BB w EBeb - 0 9 perft 1 26 perft 2 800 @@ -3015,7 +3016,7 @@ perft 4 756695 perft 5 23952941 perft 6 809841274 -id 1 +id 335 epd bbnrkqrn/pp3pp1/4p2p/2pp4/4P1P1/1PB5/P1PP1P1P/1BNRKQRN w GDgd - 0 9 perft 1 33 perft 2 915 @@ -3024,7 +3025,7 @@ perft 4 878648 perft 5 29602610 perft 6 881898159 -id 1 +id 336 epd bnrbkqr1/1p2pppp/6n1/p1pp4/7P/P3P3/1PPPKPP1/BNRB1QRN w gc - 0 9 perft 1 19 perft 2 457 @@ -3033,7 +3034,7 @@ perft 4 238944 perft 5 5356253 perft 6 144653627 -id 1 +id 337 epd b1rkqbrn/pp1p2pp/2n1p3/2p2p2/3P2PP/8/PPP1PP2/BNKRQBRN w gc - 0 9 perft 1 30 perft 2 985 @@ -3042,7 +3043,7 @@ perft 4 1011700 perft 5 32684185 perft 6 1080607773 -id 1 +id 338 epd b1rkqrnb/2ppppp1/np6/p6p/1P6/P2P3P/2P1PPP1/BNRKQRNB w FCfc - 0 9 perft 1 26 perft 2 692 @@ -3051,7 +3052,7 @@ perft 4 517703 perft 5 14561181 perft 6 413226841 -id 1 +id 339 epd nbbrkqrn/1ppp1p2/p6p/4p1p1/5P2/1P5P/P1PPPNP1/NBBRKQR1 w GDgd - 0 9 perft 1 22 perft 2 561 @@ -3060,7 +3061,7 @@ perft 4 367487 perft 5 9307003 perft 6 273928315 -id 1 +id 340 epd nrbbkqrn/p1pppppp/8/1p6/4P3/7Q/PPPP1PPP/NRBBK1RN w GBgb - 0 9 perft 1 38 perft 2 769 @@ -3069,7 +3070,7 @@ perft 4 632310 perft 5 23091070 perft 6 560139600 -id 1 +id 341 epd nrbkqbrn/1pppp2p/8/p4pp1/P4PQ1/8/1PPPP1PP/NRBK1BRN w GBgb - 0 9 perft 1 23 perft 2 507 @@ -3078,7 +3079,7 @@ perft 4 321423 perft 5 8887567 perft 6 237475184 -id 1 +id 342 epd nr1kqr1b/pp2pppp/5n2/2pp4/P5b1/5P2/1PPPPRPP/NRBK1QNB w Bfb - 2 9 perft 1 18 perft 2 626 @@ -3087,7 +3088,7 @@ perft 4 434138 perft 5 9465555 perft 6 335004239 -id 1 +id 343 epd nbkrbqrn/1pppppp1/8/4P2p/pP6/P7/2PP1PPP/NBRKBQRN w GC - 0 9 perft 1 22 perft 2 329 @@ -3096,7 +3097,7 @@ perft 4 148351 perft 5 4160034 perft 6 82875306 -id 1 +id 344 epd nrkb1qrn/pp1pp1pp/8/5p1b/P1p4P/6N1/1PPPPPP1/NRKBBQR1 w GBgb - 2 9 perft 1 16 perft 2 479 @@ -3105,7 +3106,7 @@ perft 4 275354 perft 5 5862341 perft 6 184959796 -id 1 +id 345 epd 1rkq1brn/ppppp1pp/1n6/3b1p2/3N3P/5P2/PPPPP1P1/1RKQBBRN w GBgb - 3 9 perft 1 23 perft 2 614 @@ -3114,7 +3115,7 @@ perft 4 418395 perft 5 11090645 perft 6 313526088 -id 1 +id 346 epd nrk1brnb/pp1ppppp/2p5/3q4/5P2/PP6/1KPPP1PP/NR1QBRNB w fb - 1 9 perft 1 25 perft 2 942 @@ -3123,7 +3124,7 @@ perft 4 792179 perft 5 19318837 perft 6 685549171 -id 1 +id 347 epd nbrkqr1n/1pppp2p/p4pp1/2Bb4/5P2/6P1/PPPPP2P/NBRKQ1RN w Cfc - 2 9 perft 1 30 perft 2 841 @@ -3132,7 +3133,7 @@ perft 4 677876 perft 5 20145765 perft 6 557578726 -id 1 +id 348 epd n1kbqrbn/2p1pppp/1r6/pp1p4/P7/3P4/1PP1PPPP/NRKBQRBN w FBf - 2 9 perft 1 21 perft 2 591 @@ -3141,7 +3142,7 @@ perft 4 394289 perft 5 10295086 perft 6 292131422 -id 1 +id 349 epd nrkqrbb1/ppp1pppp/3p4/8/4P3/2Pn1P2/PP4PP/NRKQRBBN w EBeb - 0 9 perft 1 4 perft 2 88 @@ -3150,7 +3151,7 @@ perft 4 73414 perft 5 2640555 perft 6 66958031 -id 1 +id 350 epd nrkqrnbb/ppppp1p1/7p/1P3p2/3P4/2P5/P3PPPP/NRKQRNBB w EBeb - 0 9 perft 1 29 perft 2 689 @@ -3159,7 +3160,7 @@ perft 4 508789 perft 5 16226660 perft 6 408570219 -id 1 +id 351 epd bbnr1rqn/pp2pkpp/2pp1p2/8/4P1P1/8/PPPP1P1P/BBNRKRQN w FD - 0 9 perft 1 21 perft 2 463 @@ -3168,7 +3169,7 @@ perft 4 256244 perft 5 6826249 perft 6 165025370 -id 1 +id 352 epd bnrbk1qn/1pppprpp/8/p4p1P/6P1/3P4/PPP1PP2/BNRBKRQN w FCc - 0 9 perft 1 22 perft 2 459 @@ -3177,7 +3178,7 @@ perft 4 268157 perft 5 7371098 perft 6 190583454 -id 1 +id 353 epd 1nrkrbqn/p1pp1ppp/4p3/1p6/1PP5/6PB/P2PPPbP/BNRKR1QN w ECec - 0 9 perft 1 30 perft 2 931 @@ -3186,7 +3187,7 @@ perft 4 887414 perft 5 28412902 perft 6 869228014 -id 1 +id 354 epd b1rkr1nb/pppppqp1/n4B2/7p/8/1P4P1/P1PPPP1P/1NKRRQNB w ec - 1 9 perft 1 36 perft 2 934 @@ -3195,7 +3196,7 @@ perft 4 930926 perft 5 30392925 perft 6 952871799 -id 1 +id 355 epd nbbrkrqn/p1ppp1p1/8/1p3p1p/2P3PP/8/PP1PPPQ1/NBBRKR1N w FDfd - 0 9 perft 1 34 perft 2 938 @@ -3204,7 +3205,7 @@ perft 4 921716 perft 5 31185844 perft 6 944483246 -id 1 +id 356 epd 1rbbkrqn/ppp1pp2/1n1p2p1/7p/P3P1P1/3P4/1PP2P1P/NRBBKRQN w FBfb - 0 9 perft 1 26 perft 2 646 @@ -3213,7 +3214,7 @@ perft 4 472744 perft 5 14006203 perft 6 384101783 -id 1 +id 357 epd nrbkrbq1/Qpppp1pp/2n5/5p2/P4P2/6N1/1PPPP1PP/NRBKRB2 w EBeb - 1 9 perft 1 27 perft 2 619 @@ -3222,7 +3223,7 @@ perft 4 421845 perft 5 11718463 perft 6 313794027 -id 1 +id 358 epd 1rbkr1nb/pppp1qpp/1n6/4pp2/1PP1P3/8/PB1P1PPP/NR1KRQNB w EBeb - 1 9 perft 1 32 perft 2 1029 @@ -3231,7 +3232,7 @@ perft 4 1080977 perft 5 35483796 perft 6 1181835398 -id 1 +id 359 epd nbrk1rqn/p1ppp2p/1p6/5ppb/8/1N2P2P/PPPP1PP1/1BKRBRQN w fc - 0 9 perft 1 18 perft 2 594 @@ -3240,7 +3241,7 @@ perft 4 408544 perft 5 9329122 perft 6 315021712 -id 1 +id 360 epd nrkbbrqn/3pppp1/7p/ppp5/P7/1N5P/1PPPPPP1/1RKBBRQN w FBfb - 0 9 perft 1 19 perft 2 417 @@ -3249,7 +3250,7 @@ perft 4 218513 perft 5 5236331 perft 6 137024458 -id 1 +id 361 epd nrkr1bqn/ppp1pppp/3p4/1b6/7P/P7/1PPPPPP1/NRKRBBQN w DBdb - 1 9 perft 1 17 perft 2 457 @@ -3258,7 +3259,7 @@ perft 4 243872 perft 5 5503579 perft 6 150091997 -id 1 +id 362 epd nrkrbqnb/p4ppp/1p2p3/2pp4/6P1/2P2N2/PPNPPP1P/1RKRBQ1B w DBdb - 0 9 perft 1 27 perft 2 755 @@ -3267,7 +3268,7 @@ perft 4 620093 perft 5 17883987 perft 6 547233320 -id 1 +id 363 epd nbkrr1bn/ppB2ppp/4p3/2qp4/4P3/5P2/PPPP2PP/NBRKRQ1N w EC - 1 9 perft 1 37 perft 2 1473 @@ -3276,7 +3277,7 @@ perft 4 1956521 perft 5 68070015 perft 6 2490912491 -id 1 +id 364 epd n1kbrqbn/p1pp1pp1/4p2p/2B5/1r3P2/8/PPPPP1PP/NRKBRQ1N w EBe - 2 9 perft 1 30 perft 2 1029 @@ -3285,7 +3286,7 @@ perft 4 1053163 perft 5 32318550 perft 6 1106487743 -id 1 +id 365 epd nrkrqbbn/2pppp1p/8/pp6/1P1P2p1/P5P1/2P1PP1P/NRKRQBBN w DBdb - 0 9 perft 1 22 perft 2 421 @@ -3294,7 +3295,7 @@ perft 4 221927 perft 5 5754555 perft 6 141245633 -id 1 +id 366 epd nrkr1nbb/1ppp2pp/p3q3/4pp2/2P5/P3P3/1PKP1PPP/NR1RQNBB w db - 0 9 perft 1 22 perft 2 619 @@ -3303,7 +3304,7 @@ perft 4 411392 perft 5 9905109 perft 6 301403003 -id 1 +id 367 epd bbnrkrnq/1pp1p2p/6p1/p2p1p2/8/1P2P3/P1PP1PPP/BBNRKRNQ w FDfd - 0 9 perft 1 27 perft 2 805 @@ -3312,7 +3313,7 @@ perft 4 688224 perft 5 19133881 perft 6 620749189 -id 1 +id 368 epd bnrbkrn1/pp1ppp2/2p3pp/8/2Pq4/P4PP1/1P1PP2P/BNRBKRNQ w FCfc - 1 9 perft 1 20 perft 2 770 @@ -3321,7 +3322,7 @@ perft 4 577980 perft 5 13581691 perft 6 456736500 -id 1 +id 369 epd b1rkrbnq/1pp1pppp/2np4/p5N1/8/1P2P3/P1PP1PPP/BNRKRB1Q w ECec - 0 9 perft 1 37 perft 2 740 @@ -3330,7 +3331,7 @@ perft 4 581744 perft 5 21156664 perft 6 485803600 -id 1 +id 370 epd b1krrnqb/pp1ppp1p/n1p3p1/2N5/6P1/8/PPPPPP1P/B1RKRNQB w EC - 0 9 perft 1 34 perft 2 850 @@ -3339,7 +3340,7 @@ perft 4 752350 perft 5 25360295 perft 6 698159474 -id 1 +id 371 epd 1bbr1rnq/ppppkppp/8/3np3/4P3/3P4/PPP1KPPP/NBBRR1NQ w - - 1 9 perft 1 27 perft 2 704 @@ -3348,7 +3349,7 @@ perft 4 480474 perft 5 12817011 perft 6 341026662 -id 1 +id 372 epd nrbbk1nq/p1p1prpp/1p6/N2p1p2/P7/8/1PPPPPPP/R1BBKRNQ w Fb - 2 9 perft 1 23 perft 2 552 @@ -3357,7 +3358,7 @@ perft 4 348593 perft 5 9236564 perft 6 248469879 -id 1 +id 373 epd 1rbkrb1q/1pppp1pp/1n5n/p4p2/P3P3/1P6/2PPNPPP/NRBKRB1Q w EBeb - 1 9 perft 1 22 perft 2 415 @@ -3366,7 +3367,7 @@ perft 4 217224 perft 5 5735644 perft 6 135295774 -id 1 +id 374 epd nrbkr1qb/1pp1pppp/6n1/p2p4/2P1P3/1N4N1/PP1P1PPP/1RBKR1QB w EBeb - 0 9 perft 1 27 perft 2 709 @@ -3375,7 +3376,7 @@ perft 4 506214 perft 5 14192779 perft 6 380516508 -id 1 +id 375 epd nbrkbrnq/p3p1pp/1pp2p2/3p4/1PP5/4P3/P1KP1PPP/NBR1BRNQ w fc - 0 9 perft 1 24 perft 2 715 @@ -3384,7 +3385,7 @@ perft 4 535054 perft 5 14322279 perft 6 427269976 -id 1 +id 376 epd nrk1brnq/pp1p1pp1/7p/b1p1p3/1P6/6P1/P1PPPPQP/NRKBBRN1 w FBfb - 2 9 perft 1 29 perft 2 675 @@ -3393,7 +3394,7 @@ perft 4 492124 perft 5 15316285 perft 6 389051744 -id 1 +id 377 epd nrkr1bnq/1p2pppp/p2p4/1bp5/PP6/1R5N/2PPPPPP/N1KRBB1Q w Ddb - 2 9 perft 1 27 perft 2 744 @@ -3402,7 +3403,7 @@ perft 4 571209 perft 5 16188945 perft 6 458900901 -id 1 +id 378 epd nrk1b1qb/pppn1ppp/3rp3/3p4/2P3P1/3P4/PPN1PP1P/1RKRBNQB w DBb - 3 9 perft 1 35 perft 2 941 @@ -3411,7 +3412,7 @@ perft 4 935791 perft 5 33150360 perft 6 968024386 -id 1 +id 379 epd nb1rrnbq/ppkp1ppp/8/2p1p3/P7/1N2P3/1PPP1PPP/1BKRRNBQ w - - 1 9 perft 1 19 perft 2 451 @@ -3420,7 +3421,7 @@ perft 4 235472 perft 5 5506897 perft 6 139436165 -id 1 +id 380 epd nrkbrnbq/4pppp/1ppp4/p7/2P1P3/3P2N1/PP3PPP/NRKBR1BQ w EBeb - 0 9 perft 1 29 perft 2 591 @@ -3429,7 +3430,7 @@ perft 4 384358 perft 5 11245508 perft 6 270967202 -id 1 +id 381 epd nrkrnbbq/3p1ppp/1p6/p1p1p3/3P2P1/P4Q2/1PP1PP1P/NRKRNBB1 w DBdb - 0 9 perft 1 38 perft 2 792 @@ -3438,7 +3439,7 @@ perft 4 640961 perft 5 22654797 perft 6 540864616 -id 1 +id 382 epd nr1rnqbb/ppp1pp1p/3k2p1/3p4/1P5P/3P1N2/P1P1PPP1/NRKR1QBB w DB - 1 9 perft 1 25 perft 2 758 @@ -3447,7 +3448,7 @@ perft 4 543643 perft 5 13890077 perft 6 402109399 -id 1 +id 383 epd bbqrnnkr/1ppp1p1p/5p2/p5p1/P7/1P4P1/2PPPP1P/1BQRNNKR w HDhd - 0 9 perft 1 20 perft 2 322 @@ -3456,7 +3457,7 @@ perft 4 145818 perft 5 3588435 perft 6 82754650 -id 1 +id 384 epd bqrb2k1/pppppppr/5nnp/8/3P1P2/4P1N1/PPP3PP/BQRBN1KR w HCc - 1 9 perft 1 25 perft 2 597 @@ -3465,7 +3466,7 @@ perft 4 397970 perft 5 11162476 perft 6 295682250 -id 1 +id 385 epd bqrnn1kr/1pppbppp/8/4p3/1p6/2P1N2P/P2PPPP1/BQR1NBKR w HChc - 1 9 perft 1 34 perft 2 921 @@ -3474,7 +3475,7 @@ perft 4 864023 perft 5 30126510 perft 6 850296236 -id 1 +id 386 epd bqr1nkr1/pppppp2/2n3p1/7p/1P1b1P2/8/PQP1P1PP/B1RNNKRB w GCgc - 0 9 perft 1 23 perft 2 788 @@ -3483,7 +3484,7 @@ perft 4 686795 perft 5 20849374 perft 6 645694580 -id 1 +id 387 epd qbbrnn1r/1pppp1pk/p7/5p1p/P2P3P/3N4/1PP1PPP1/QBBR1NKR w HD - 0 9 perft 1 34 perft 2 713 @@ -3492,7 +3493,7 @@ perft 4 562189 perft 5 19494094 perft 6 482645160 -id 1 +id 388 epd qrbb2kr/p1pppppp/1p1n4/8/1P3n2/P7/Q1PPP1PP/1RBBNNKR w HBhb - 0 9 perft 1 28 perft 2 977 @@ -3501,7 +3502,7 @@ perft 4 949925 perft 5 27802999 perft 6 992109168 -id 1 +id 389 epd qrb2bkr/1pp1pppp/2np1n2/pN6/3P4/4B3/PPP1PPPP/QR2NBKR w HBhb - 0 9 perft 1 27 perft 2 730 @@ -3510,7 +3511,7 @@ perft 4 585091 perft 5 17005916 perft 6 507008968 -id 1 +id 390 epd qrbnnkrb/pp2pp1p/8/2pp2p1/7P/P1P5/QP1PPPP1/1RBNNKRB w GBgb - 0 9 perft 1 24 perft 2 813 @@ -3519,7 +3520,7 @@ perft 4 707925 perft 5 19615756 perft 6 655850285 -id 1 +id 391 epd 1brnb1kr/p1pppppp/1p6/8/4q2n/1P2P1P1/PNPP1P1P/QBR1BNKR w HChc - 3 9 perft 1 17 perft 2 734 @@ -3528,7 +3529,7 @@ perft 4 530809 perft 5 11032633 perft 6 416356876 -id 1 +id 392 epd 1rnbbnkr/1pp1pppp/1q1p4/p7/4P3/5PN1/PPPP1BPP/QRNB2KR w HBhb - 1 9 perft 1 26 perft 2 809 @@ -3537,7 +3538,7 @@ perft 4 706677 perft 5 20292750 perft 6 675408811 -id 1 +id 393 epd qrnnbb1Q/ppp1pk1p/3p2p1/5p2/PP6/5P2/2PPP1PP/1RNNBBKR w HB - 0 9 perft 1 37 perft 2 751 @@ -3546,7 +3547,7 @@ perft 4 603931 perft 5 22443036 perft 6 515122176 -id 1 +id 394 epd qrnnbkrb/p3p1pp/3p1p2/1pp5/PP2P3/8/2PP1PPP/QRNNBRKB w gb - 0 9 perft 1 30 perft 2 906 @@ -3555,7 +3556,7 @@ perft 4 872526 perft 5 27658191 perft 6 890966633 -id 1 +id 395 epd qbrnnkbr/1p2pp1p/p1p3p1/3p4/6P1/P1N4P/1PPPPP2/QBR1NKBR w HChc - 0 9 perft 1 26 perft 2 701 @@ -3564,7 +3565,7 @@ perft 4 521377 perft 5 14733245 perft 6 416881799 -id 1 +id 396 epd qr1b1kbr/1p1ppppp/1n1n4/p1p5/4P3/5NPP/PPPP1P2/QRNB1KBR w HBhb - 1 9 perft 1 26 perft 2 649 @@ -3573,7 +3574,7 @@ perft 4 451997 perft 5 12367604 perft 6 342165821 -id 1 +id 397 epd qrnnkb1r/1pppppp1/7p/p4b2/4P3/5P1P/PPPP2PR/QRNNKBB1 w Bhb - 1 9 perft 1 34 perft 2 941 @@ -3582,7 +3583,7 @@ perft 4 901240 perft 5 30307554 perft 6 888709821 -id 1 +id 398 epd qr1nkrbb/p2ppppp/1pp5/8/3Pn3/1NP3P1/PP2PP1P/QR1NKRBB w FBfb - 1 9 perft 1 19 perft 2 505 @@ -3591,7 +3592,7 @@ perft 4 294251 perft 5 7046501 perft 6 190414579 -id 1 +id 399 epd bbrqn1kr/1pppp1pp/4n3/5p2/p5P1/3P4/PPP1PPKP/BBRQNN1R w hc - 0 9 perft 1 24 perft 2 573 @@ -3600,7 +3601,7 @@ perft 4 335845 perft 5 8191054 perft 6 227555387 -id 1 +id 400 epd brqb1nkr/pppppp1p/8/4N1pn/5P2/6P1/PPPPP2P/BRQB1NKR w HBhb - 0 9 perft 1 26 perft 2 550 @@ -3609,7 +3610,7 @@ perft 4 331666 perft 5 8903754 perft 6 223437427 -id 1 +id 401 epd brqnn1kr/pp3ppp/2pbp3/3p4/8/2NPP3/PPP1BPPP/BRQ1N1KR w HBhb - 0 9 perft 1 27 perft 2 780 @@ -3618,7 +3619,7 @@ perft 4 589328 perft 5 16243731 perft 6 463883447 -id 1 +id 402 epd brq1nkrb/ppp2ppp/8/n2pp2P/P7/4P3/1PPP1PP1/BRQNNKRB w GBgb - 1 9 perft 1 17 perft 2 426 @@ -3627,7 +3628,7 @@ perft 4 235162 perft 5 5048497 perft 6 153986034 -id 1 +id 403 epd rbbqn1kr/pp2p1pp/6n1/2pp1p2/2P4P/P7/BP1PPPP1/R1BQNNKR w HAha - 0 9 perft 1 27 perft 2 916 @@ -3636,7 +3637,7 @@ perft 4 890435 perft 5 26302461 perft 6 924181432 -id 1 +id 404 epd 1qbbn1kr/1ppppppp/r3n3/8/p1P5/P7/1P1PPPPP/RQBBNNKR w HAh - 1 9 perft 1 29 perft 2 817 @@ -3645,7 +3646,7 @@ perft 4 720277 perft 5 22147642 perft 6 670707652 -id 1 +id 405 epd rqbnnbkr/ppp1ppp1/7p/3p4/PP6/7P/1NPPPPP1/RQB1NBKR w HAa - 1 9 perft 1 23 perft 2 572 @@ -3654,7 +3655,7 @@ perft 4 381474 perft 5 10416981 perft 6 288064942 -id 1 +id 406 epd r1bnnkrb/q1ppp1pp/p7/1p3pB1/2P1P3/3P4/PP3PPP/RQ1NNKRB w GAga - 2 9 perft 1 31 perft 2 925 @@ -3663,7 +3664,7 @@ perft 4 860969 perft 5 26316355 perft 6 843078864 -id 1 +id 407 epd rbqnb1kr/ppppp1pp/5p2/5N2/7P/1n3P2/PPPPP1P1/RBQNB1KR w HAha - 1 9 perft 1 32 perft 2 864 @@ -3672,7 +3673,7 @@ perft 4 766551 perft 5 24738875 perft 6 707188107 -id 1 +id 408 epd rqnbbn1r/ppppppp1/6k1/8/6Pp/2PN4/PP1PPPKP/RQ1BBN1R w - - 0 9 perft 1 27 perft 2 566 @@ -3681,7 +3682,7 @@ perft 4 347059 perft 5 9714509 perft 6 234622128 -id 1 +id 409 epd rqnnbbkr/p1p2pp1/1p1p3p/4p3/4NP2/6P1/PPPPP2P/RQN1BBKR w HAha - 0 9 perft 1 27 perft 2 631 @@ -3690,7 +3691,7 @@ perft 4 452734 perft 5 13307890 perft 6 356279813 -id 1 +id 410 epd 1qnnbrkb/rppp1ppp/p3p3/8/4P3/2PP1P2/PP4PP/RQNNBKRB w GA - 1 9 perft 1 24 perft 2 479 @@ -3699,7 +3700,7 @@ perft 4 271469 perft 5 7204345 perft 6 175460841 -id 1 +id 411 epd rbqnn1br/p1pppk1p/1p4p1/5p2/8/P1P2P2/1PBPP1PP/R1QNNKBR w HA - 0 9 perft 1 31 perft 2 756 @@ -3708,7 +3709,7 @@ perft 4 625194 perft 5 20036784 perft 6 554292502 -id 1 +id 412 epd rqnbnkbr/1ppppp2/p5p1/8/1P4p1/4PP2/P1PP3P/RQNBNKBR w HAha - 0 9 perft 1 24 perft 2 715 @@ -3717,7 +3718,7 @@ perft 4 575589 perft 5 16013189 perft 6 515078271 -id 1 +id 413 epd rq1nkbbr/1p2pppp/p2n4/2pp4/1P4P1/P2N4/2PPPP1P/RQ1NKBBR w HAha - 1 9 perft 1 27 perft 2 694 @@ -3726,7 +3727,7 @@ perft 4 552904 perft 5 16685687 perft 6 494574415 -id 1 +id 414 epd r1nnkrbb/pp1pppp1/2p3q1/7p/8/1PPP3P/P3PPP1/RQNNKRBB w FAfa - 1 9 perft 1 18 perft 2 520 @@ -3735,7 +3736,7 @@ perft 4 329085 perft 5 7508201 perft 6 235103697 -id 1 +id 415 epd bbrnqk1r/pppp3p/6p1/4pp2/3P2P1/8/PPP1PP1P/BBRN1NKR w HC - 0 9 perft 1 22 perft 2 566 @@ -3744,7 +3745,7 @@ perft 4 362624 perft 5 8721079 perft 6 259069471 -id 1 +id 416 epd brnb1nkr/pppqpp2/3p2pp/8/3PP3/1P6/PBP2PPP/1RNBQNKR w HBhb - 0 9 perft 1 32 perft 2 859 @@ -3753,7 +3754,7 @@ perft 4 817464 perft 5 27734108 perft 6 829785474 -id 1 +id 417 epd brnq1b1r/ppp1ppkp/3p1np1/8/8/5P1P/PPPPPKPR/BRNQNB2 w - - 0 9 perft 1 21 perft 2 511 @@ -3762,7 +3763,7 @@ perft 4 273756 perft 5 6372681 perft 6 167139732 -id 1 +id 418 epd brnq1rkb/1pppppp1/3n3p/p7/8/P4NP1/1PPPPPRP/BRNQ1K1B w B - 0 9 perft 1 25 perft 2 548 @@ -3771,7 +3772,7 @@ perft 4 341208 perft 5 9015901 perft 6 235249649 -id 1 +id 419 epd rbb1qnkr/p1ppp1pp/1p3p2/6n1/8/1PN1P2P/P1PP1PP1/RBB1QNKR w HAha - 0 9 perft 1 25 perft 2 673 @@ -3780,7 +3781,7 @@ perft 4 467660 perft 5 12099119 perft 6 361714466 -id 1 +id 420 epd rnbb1nkr/1ppp1ppp/4p3/p5q1/6P1/1PP5/PB1PPP1P/RN1BQNKR w HAha - 1 9 perft 1 19 perft 2 663 @@ -3789,7 +3790,7 @@ perft 4 489653 perft 5 11491355 perft 6 399135495 -id 1 +id 421 epd rnbqnbkr/1pp1p2p/3p1p2/p5p1/5PP1/2P5/PPNPP2P/RNBQ1BKR w HAha - 0 9 perft 1 24 perft 2 647 @@ -3798,7 +3799,7 @@ perft 4 461931 perft 5 12649636 perft 6 361157611 -id 1 +id 422 epd rnb2krb/pppqppnp/8/3p2p1/1P4P1/7P/P1PPPPB1/RNBQNKR1 w GAga - 1 9 perft 1 24 perft 2 722 @@ -3807,7 +3808,7 @@ perft 4 605229 perft 5 16609220 perft 6 563558512 -id 1 +id 423 epd rbnqb1kr/pppn1pp1/3p3p/4p3/1P6/P7/R1PPPPPP/1BNQBNKR w Hha - 1 9 perft 1 20 perft 2 538 @@ -3816,7 +3817,7 @@ perft 4 345704 perft 5 8687621 perft 6 255304141 -id 1 +id 424 epd rnqb1nkr/p1pbp1pp/8/1pPp1p2/P2P4/8/1P2PPPP/RNQBBNKR w HAha - 1 9 perft 1 35 perft 2 764 @@ -3825,7 +3826,7 @@ perft 4 632796 perft 5 22592380 perft 6 564255328 -id 1 +id 425 epd rnq1bbkr/1p1ppp1p/4n3/p1p3p1/P1PP4/8/RP2PPPP/1NQNBBKR w Hha - 0 9 perft 1 29 perft 2 709 @@ -3834,7 +3835,7 @@ perft 4 570580 perft 5 17597398 perft 6 506140370 -id 1 +id 426 epd 1nqnbkrb/1pppp2p/r7/p4pp1/3P4/8/PPPBPPPP/RNQNK1RB w g - 0 9 perft 1 27 perft 2 1028 @@ -3843,7 +3844,7 @@ perft 4 1050834 perft 5 30251988 perft 6 1096869832 -id 1 +id 427 epd rbnqnkbr/p1pp1p1p/8/1p2p3/3P2pP/2P5/PP2PPP1/RBNQNKBR w HAha - 0 9 perft 1 32 perft 2 832 @@ -3852,7 +3853,7 @@ perft 4 750336 perft 5 24945574 perft 6 724171581 -id 1 +id 428 epd rnq1nkbr/1p1p1ppp/2p1pb2/p7/7P/2P5/PPNPPPPB/RNQB1K1R w HAha - 2 9 perft 1 31 perft 2 779 @@ -3861,7 +3862,7 @@ perft 4 638640 perft 5 19919434 perft 6 551494771 -id 1 +id 429 epd rnqnk1br/p1ppp1bp/1p3p2/6p1/4N3/P5P1/1PPPPP1P/R1QNKBBR w HAha - 2 9 perft 1 25 perft 2 717 @@ -3870,7 +3871,7 @@ perft 4 576577 perft 5 16525239 perft 6 507175842 -id 1 +id 430 epd rnq1krbb/p1p1pppp/8/1p1p4/1n5B/2N2P2/PPPPP1PP/RNQ1KR1B w FAfa - 0 9 perft 1 28 perft 2 867 @@ -3879,7 +3880,7 @@ perft 4 735686 perft 5 21112751 perft 6 654808184 -id 1 +id 431 epd bbrnnqkr/1pp1pppp/3p4/p7/P3P3/7P/1PPP1PP1/BBRNNQKR w HChc - 0 9 perft 1 24 perft 2 405 @@ -3888,7 +3889,7 @@ perft 4 210557 perft 5 6196438 perft 6 131401224 -id 1 +id 432 epd brnbnqkr/p1ppp3/1p5p/5Pp1/5P2/3N4/PPPPP2P/BRNB1QKR w HBhb g6 0 9 perft 1 25 perft 2 785 @@ -3897,7 +3898,7 @@ perft 4 698331 perft 5 20687969 perft 6 695850727 -id 1 +id 433 epd br1nqbkr/1ppppp2/pn6/6pp/2PP4/1N4P1/PP2PP1P/BR1NQBKR w HBhb - 0 9 perft 1 25 perft 2 596 @@ -3906,7 +3907,7 @@ perft 4 421882 perft 5 12185361 perft 6 337805606 -id 1 +id 434 epd 1rnnqkrb/p2ppp1p/1pp5/2N3p1/8/1P6/P1PPPPKP/BR1NQ1RB w gb - 0 9 perft 1 38 perft 2 960 @@ -3915,7 +3916,7 @@ perft 4 913665 perft 5 32490040 perft 6 880403591 -id 1 +id 435 epd rbbnnqkr/pp3pp1/2p1p3/3p3p/3P3P/1PP5/P3PPP1/RBBNNQKR w HAha - 0 9 perft 1 30 perft 2 785 @@ -3924,7 +3925,7 @@ perft 4 656618 perft 5 19885037 perft 6 599219582 -id 1 +id 436 epd rn1bnqkr/p1ppppp1/8/1p5p/P4P1P/3N4/1PPPP1b1/RNBB1QKR w HAha - 0 9 perft 1 27 perft 2 752 @@ -3933,7 +3934,7 @@ perft 4 613194 perft 5 18862234 perft 6 547415271 -id 1 +id 437 epd 1nbnqbkr/1p1p1ppp/r3p3/p1p5/P3P3/3Q4/1PPP1PPP/RNBN1BKR w HAh - 2 9 perft 1 33 perft 2 721 @@ -3942,7 +3943,7 @@ perft 4 572535 perft 5 19648535 perft 6 496023732 -id 1 +id 438 epd rnbnqkrb/2pppppp/1p6/p7/1PP5/4N2P/P2PPPP1/RNB1QKRB w GAg - 0 9 perft 1 23 perft 2 570 @@ -3951,7 +3952,7 @@ perft 4 374196 perft 5 10022614 perft 6 279545007 -id 1 +id 439 epd rbnnbq1r/ppppppkp/6p1/N7/4P3/P7/1PPP1PPP/RB1NBQKR w HA - 5 9 perft 1 27 perft 2 620 @@ -3960,7 +3961,7 @@ perft 4 440594 perft 5 13909432 perft 6 349478320 -id 1 +id 440 epd r1nbbqkr/pppppp1p/8/8/1n3Pp1/3N1QP1/PPPPP2P/RN1BB1KR w HAha - 0 9 perft 1 31 perft 2 791 @@ -3969,7 +3970,7 @@ perft 4 682579 perft 5 22408813 perft 6 636779732 -id 1 +id 441 epd rnq1bbkr/pp1p1ppp/2pnp3/8/7P/1QP5/PP1PPPPR/RNN1BBK1 w Aha - 2 9 perft 1 28 perft 2 559 @@ -3978,7 +3979,7 @@ perft 4 390887 perft 5 12242780 perft 6 315431511 -id 1 +id 442 epd rnnqbrkb/2ppppp1/1p1N4/p6p/4P3/8/PPPP1PPP/R1NQBKRB w GA - 0 9 perft 1 32 perft 2 638 @@ -3987,7 +3988,7 @@ perft 4 438792 perft 5 14395828 perft 6 331782223 -id 1 +id 443 epd rbnnq1br/pppp1kp1/4pp2/7p/PP6/2PP4/4PPPP/RBNNQKBR w HA - 0 9 perft 1 21 perft 2 521 @@ -3996,7 +3997,7 @@ perft 4 320429 perft 5 8239159 perft 6 227346638 -id 1 +id 444 epd rnnbqkbr/p2ppp2/7p/1pp3p1/2P2N2/8/PP1PPPPP/RN1BQKBR w HAha - 0 9 perft 1 25 perft 2 528 @@ -4005,7 +4006,7 @@ perft 4 326094 perft 5 9079829 perft 6 232750602 -id 1 +id 445 epd rnn1kbbr/ppppqp2/6p1/2N1p2p/P7/2P5/1P1PPPPP/RN1QKBBR w HAha - 2 9 perft 1 27 perft 2 801 @@ -4014,7 +4015,7 @@ perft 4 707078 perft 5 20334071 perft 6 682580976 -id 1 +id 446 epd rnnqkrbb/p1p1p1pp/1p3p2/8/3p2Q1/P1P1P3/1P1P1PPP/RNN1KRBB w FAfa - 0 9 perft 1 37 perft 2 1014 @@ -4023,7 +4024,7 @@ perft 4 998999 perft 5 32921537 perft 6 988770109 -id 1 +id 447 epd bbrnk1qr/1pppppp1/p4n1p/8/P2P2N1/8/1PP1PPPP/BBR1NKQR w HC - 1 9 perft 1 21 perft 2 481 @@ -4032,7 +4033,7 @@ perft 4 279993 perft 5 7015419 perft 6 187564853 -id 1 +id 448 epd brnbnkqr/1pp1p1p1/p2p1p2/7p/1P4PP/8/PBPPPP2/1RNBNKQR w HBhb - 0 9 perft 1 31 perft 2 743 @@ -4041,7 +4042,7 @@ perft 4 660177 perft 5 22391185 perft 6 653721389 -id 1 +id 449 epd br2kbqr/ppppp1pp/3n1p2/3P4/3n3P/3N4/PPP1PPP1/BR1NKBQR w HBhb - 3 9 perft 1 25 perft 2 872 @@ -4050,7 +4051,7 @@ perft 4 748726 perft 5 20281962 perft 6 685749952 -id 1 +id 450 epd br1nkqrb/ppppppp1/8/7p/4P3/n1P2PP1/PP1P3P/BRNNKQRB w GBgb - 0 9 perft 1 28 perft 2 607 @@ -4059,7 +4060,7 @@ perft 4 396483 perft 5 11607818 perft 6 294181806 -id 1 +id 451 epd rbbn1kqr/pp1pp1p1/2pn3p/5p2/5P2/1P1N4/PNPPP1PP/RBB2KQR w HAha - 1 9 perft 1 27 perft 2 725 @@ -4068,7 +4069,7 @@ perft 4 616082 perft 5 19239812 perft 6 581716972 -id 1 +id 452 epd rnbbnk1r/pp1ppp1p/6q1/2p5/PP4p1/4P3/2PP1PPP/RNBBNKQR w HAha - 1 9 perft 1 25 perft 2 1072 @@ -4077,7 +4078,7 @@ perft 4 1088978 perft 5 28469879 perft 6 1122703887 -id 1 +id 453 epd rnbnkbqr/1pp3pp/3p4/p3pp2/3P2P1/2N1N3/PPP1PP1P/R1B1KBQR w HAha - 0 9 perft 1 31 perft 2 1028 @@ -4086,7 +4087,7 @@ perft 4 1095472 perft 5 36025223 perft 6 1211187800 -id 1 +id 454 epd r1bnkqrb/1ppppppp/p3n3/8/6P1/4N3/PPPPPPRP/RNB1KQ1B w Aga - 1 9 perft 1 23 perft 2 457 @@ -4095,7 +4096,7 @@ perft 4 250551 perft 5 6666787 perft 6 159759052 -id 1 +id 455 epd rbn1bkqr/p1pp1pp1/1pn5/4p2p/7P/1PBP4/P1P1PPP1/RBNN1KQR w HAha - 0 9 perft 1 23 perft 2 470 @@ -4104,7 +4105,7 @@ perft 4 264274 perft 5 6963287 perft 6 172833738 -id 1 +id 456 epd rnnbbkqr/3ppppp/p7/1pp5/P6P/6P1/1PPPPP2/RNNBBKQR w HAha - 0 9 perft 1 26 perft 2 569 @@ -4113,7 +4114,7 @@ perft 4 375556 perft 5 11008114 perft 6 284485303 -id 1 +id 457 epd r1nk1bqr/1pppp1pp/2n5/p4p1b/5P2/1N4B1/PPPPP1PP/RN1K1BQR w HAha - 2 9 perft 1 25 perft 2 824 @@ -4122,7 +4123,7 @@ perft 4 738366 perft 5 20904119 perft 6 716170771 -id 1 +id 458 epd r1nkbqrb/p2pppp1/npp4p/8/4PP2/2N4P/PPPP2P1/R1NKBQRB w GAga - 0 9 perft 1 31 perft 2 548 @@ -4131,7 +4132,7 @@ perft 4 349633 perft 5 11469548 perft 6 255067638 -id 1 +id 459 epd rbnnkqbr/ppppp2p/5p2/6p1/2P1B3/P6P/1P1PPPP1/R1NNKQBR w HAha - 1 9 perft 1 31 perft 2 809 @@ -4140,7 +4141,7 @@ perft 4 680747 perft 5 21247414 perft 6 606221516 -id 1 +id 460 epd 1r1bkqbr/pppp1ppp/2nnp3/8/2P5/N4P2/PP1PP1PP/1RNBKQBR w Hh - 0 9 perft 1 28 perft 2 810 @@ -4149,7 +4150,7 @@ perft 4 694599 perft 5 20188622 perft 6 636748147 -id 1 +id 461 epd rn1kqbbr/p1pppp1p/1p4p1/1n6/1P2P3/4Q2P/P1PP1PP1/RNNK1BBR w HAha - 1 9 perft 1 39 perft 2 848 @@ -4158,7 +4159,7 @@ perft 4 724426 perft 5 25594662 perft 6 659615710 -id 1 +id 462 epd rn1kqrbb/pppppppp/8/8/2nP2P1/1P2P3/P1P2P1P/RNNKQRBB w FAfa - 1 9 perft 1 29 perft 2 766 @@ -4167,7 +4168,7 @@ perft 4 567971 perft 5 16944425 perft 6 456898648 -id 1 +id 463 epd b1rnnkrq/bpppppp1/7p/8/1p6/2B5/PNPPPPPP/1BR1NKRQ w GCgc - 2 9 perft 1 25 perft 2 667 @@ -4176,7 +4177,7 @@ perft 4 472678 perft 5 12865247 perft 6 365621294 -id 1 +id 464 epd brnb1krq/pppppppp/8/5P2/2P1n2P/8/PP1PP1P1/BRNBNKRQ w GBgb - 1 9 perft 1 23 perft 2 620 @@ -4185,7 +4186,7 @@ perft 4 402561 perft 5 10776855 perft 6 300125003 -id 1 +id 465 epd b1nnkbrq/pr1pppp1/1p5p/2p5/P2N1P2/8/1PPPP1PP/BR1NKBRQ w GBg - 0 9 perft 1 24 perft 2 472 @@ -4194,7 +4195,7 @@ perft 4 267398 perft 5 7370758 perft 6 178605165 -id 1 +id 466 epd br1nkrqb/p1p1p1pp/3n4/1p1p1p2/5N1P/4P3/PPPP1PP1/BR1NKRQB w FBfb - 0 9 perft 1 24 perft 2 775 @@ -4203,7 +4204,7 @@ perft 4 624309 perft 5 16429837 perft 6 539767605 -id 1 +id 467 epd rbbnnkrq/p2pp1pp/2p5/5p2/1pPP1B2/P7/1P2PPPP/RB1NNKRQ w GAga - 0 9 perft 1 34 perft 2 921 @@ -4212,7 +4213,7 @@ perft 4 849933 perft 5 28095833 perft 6 806446436 -id 1 +id 468 epd rnbbnkr1/1p1ppp1p/2p3p1/p7/2Pq4/1P1P4/P2BPPPP/RN1BNKRQ w GAga - 2 9 perft 1 26 perft 2 1139 @@ -4221,7 +4222,7 @@ perft 4 1204863 perft 5 32825932 perft 6 1281760240 -id 1 +id 469 epd 1rbnkbrq/pppppp2/n5pp/2P5/P7/4N3/1P1PPPPP/RNB1KBRQ w GAg - 2 9 perft 1 23 perft 2 574 @@ -4230,7 +4231,7 @@ perft 4 391413 perft 5 10203438 perft 6 301874034 -id 1 +id 470 epd 1nbnkr1b/rppppppq/p7/7p/1P5P/3P2P1/P1P1PP2/RNBNKRQB w FAf - 1 9 perft 1 33 perft 2 823 @@ -4239,7 +4240,7 @@ perft 4 724828 perft 5 23266182 perft 6 672294132 -id 1 +id 471 epd rbn1bkrq/ppppp3/4n2p/5pp1/1PN5/2P5/P2PPPPP/RBN1BKRQ w GAga - 0 9 perft 1 27 perft 2 859 @@ -4248,7 +4249,7 @@ perft 4 796482 perft 5 23075785 perft 6 789152120 -id 1 +id 472 epd r1nbbkrq/1ppp2pp/2n2p2/p3p3/5P2/1N4BP/PPPPP1P1/RN1B1KRQ w GAga - 0 9 perft 1 25 perft 2 774 @@ -4257,7 +4258,7 @@ perft 4 618805 perft 5 16718577 perft 6 515864053 -id 1 +id 473 epd rnnkbbrq/1pppp1p1/5p2/7p/p6P/3N1P2/PPPPP1PQ/RN1KBBR1 w GAga - 0 9 perft 1 29 perft 2 673 @@ -4266,7 +4267,7 @@ perft 4 504715 perft 5 15545590 perft 6 416359581 -id 1 +id 474 epd r1nkbrqb/pppp1p2/n3p1p1/7p/2P2P2/1P6/P2PPQPP/RNNKBR1B w FAfa - 0 9 perft 1 27 perft 2 722 @@ -4275,7 +4276,7 @@ perft 4 593762 perft 5 18742426 perft 6 537750982 -id 1 +id 475 epd rbnnkr1q/1ppp2pp/p4p2/P2bp3/4P2P/8/1PPP1PP1/RBNNKRBQ w FAfa - 1 9 perft 1 26 perft 2 848 @@ -4284,7 +4285,7 @@ perft 4 741674 perft 5 21591790 perft 6 675163653 -id 1 +id 476 epd rn1bkrb1/1ppppp1p/pn4p1/8/P2q3P/3P4/NPP1PPP1/RN1BKRBQ w FAfa - 1 9 perft 1 22 perft 2 803 @@ -4293,7 +4294,7 @@ perft 4 632920 perft 5 15847763 perft 6 536419559 -id 1 +id 477 epd rn1krbbq/pppp1npp/4pp2/8/4P2P/3P2P1/PPP2P2/RNNKRBBQ w EAea - 1 9 perft 1 29 perft 2 810 @@ -4302,7 +4303,7 @@ perft 4 670500 perft 5 20361517 perft 6 575069358 -id 1 +id 478 epd rnn1rqbb/ppkp1pp1/2p1p2p/2P5/8/3P1P2/PP2P1PP/RNNKRQBB w EA - 0 9 perft 1 22 perft 2 506 @@ -4311,7 +4312,7 @@ perft 4 292344 perft 5 7287368 perft 6 189865944 -id 1 +id 479 epd bbqr1knr/pppppp1p/8/4n1p1/2P1P3/6P1/PPQP1P1P/BB1RNKNR w HDhd - 0 9 perft 1 26 perft 2 650 @@ -4320,7 +4321,7 @@ perft 4 481200 perft 5 14301029 perft 6 394943978 -id 1 +id 480 epd bq1bnknr/pprppp1p/8/2p3p1/4PPP1/8/PPPP3P/BQRBNKNR w HCh - 0 9 perft 1 24 perft 2 548 @@ -4329,7 +4330,7 @@ perft 4 347611 perft 5 9374021 perft 6 250988458 -id 1 +id 481 epd bqrnkb1r/1p2pppp/p1pp3n/5Q2/2P4P/5N2/PP1PPPP1/B1RNKB1R w HChc - 0 9 perft 1 46 perft 2 823 @@ -4338,7 +4339,7 @@ perft 4 673905 perft 5 26130444 perft 6 582880996 -id 1 +id 482 epd bq1rknrb/pppppp1p/4n3/6p1/4P1P1/3P1P2/PPP4P/BQRNKNRB w GCg - 0 9 perft 1 23 perft 2 618 @@ -4347,7 +4348,7 @@ perft 4 419474 perft 5 10606831 perft 6 315124518 -id 1 +id 483 epd q1brnknr/pp1pp1p1/8/2p2p1p/5b2/P4N2/1PPPP1PP/QBBRK1NR w hd - 0 9 perft 1 22 perft 2 675 @@ -4356,7 +4357,7 @@ perft 4 473994 perft 5 12077228 perft 6 368479752 -id 1 +id 484 epd qrbbnknr/1p1ppp1p/p1p5/8/1P2P1p1/3P1B2/P1P2PPP/QRB1NKNR w HBhb - 0 9 perft 1 32 perft 2 722 @@ -4365,7 +4366,7 @@ perft 4 569905 perft 5 19584539 perft 6 484814878 -id 1 +id 485 epd qrb1kbnr/p3pppp/2n5/1ppp4/7P/3P1P2/PPP1P1PR/QRBNKBN1 w Bhb - 0 9 perft 1 26 perft 2 831 @@ -4374,7 +4375,7 @@ perft 4 724505 perft 5 20500804 perft 6 662608969 -id 1 +id 486 epd qrbnknrb/ppp1pp2/6p1/7p/PPNp4/8/2PPPPPP/QRB1KNRB w GBgb - 0 9 perft 1 31 perft 2 840 @@ -4383,7 +4384,7 @@ perft 4 742772 perft 5 24422614 perft 6 701363800 -id 1 +id 487 epd qbrnbknr/pp1pp1pp/8/2p2p2/3Q4/PP6/2PPPPPP/1BRNBKNR w HChc - 0 9 perft 1 38 perft 2 1121 @@ -4392,7 +4393,7 @@ perft 4 1198438 perft 5 41108769 perft 6 1285503872 -id 1 +id 488 epd qr1bbk1r/pppppp1p/1n6/5np1/4B3/1PP5/P2PPPPP/QRN1BKNR w HBhb - 0 9 perft 1 25 perft 2 694 @@ -4401,7 +4402,7 @@ perft 4 472950 perft 5 12164609 perft 6 345122090 -id 1 +id 489 epd qrnkbbnr/1p1pp2p/p7/2p1Npp1/6P1/7P/PPPPPP2/QR1KBBNR w HBhb - 0 9 perft 1 27 perft 2 586 @@ -4410,7 +4411,7 @@ perft 4 393391 perft 5 11409633 perft 6 298054792 -id 1 +id 490 epd qrnkbnrb/pp1p1p2/2p1p1pp/4N3/P4P2/8/1PPPP1PP/QR1KBNRB w GBgb - 0 9 perft 1 32 perft 2 645 @@ -4419,7 +4420,7 @@ perft 4 460319 perft 5 15037464 perft 6 358531599 -id 1 +id 491 epd qbrnknbr/1pppppp1/p6p/8/1P6/3PP3/PQP2PPP/1BRNKNBR w HChc - 3 9 perft 1 26 perft 2 595 @@ -4428,7 +4429,7 @@ perft 4 415022 perft 5 12214768 perft 6 323518628 -id 1 +id 492 epd qrnbk1br/1ppppp1p/p5p1/8/4Pn2/4K1P1/PPPP1P1P/QRNB1NBR w hb - 0 9 perft 1 24 perft 2 609 @@ -4437,7 +4438,7 @@ perft 4 359415 perft 5 8538539 perft 6 230364479 -id 1 +id 493 epd qrnk1bbr/1pnp1ppp/p1p1p3/8/3Q4/1P1N3P/P1PPPPP1/1RNK1BBR w HBhb - 0 9 perft 1 43 perft 2 1106 @@ -4446,7 +4447,7 @@ perft 4 1123080 perft 5 41695761 perft 6 1113836402 -id 1 +id 494 epd qrnknrb1/pppppp2/8/6pp/4P2P/3P1P2/PbP3P1/QRNKNRBB w FBfb - 0 9 perft 1 24 perft 2 658 @@ -4455,7 +4456,7 @@ perft 4 488373 perft 5 14457245 perft 6 400971226 -id 1 +id 495 epd bbrqnrk1/ppp2ppp/7n/3pp3/8/P4N1N/1PPPPPPP/BBRQ1RK1 w - - 1 9 perft 1 22 perft 2 503 @@ -4464,7 +4465,7 @@ perft 4 310760 perft 5 8080951 perft 6 224960353 -id 1 +id 496 epd brqbnk1r/1ppp1ppp/8/p3pn2/8/2PP1P2/PP2PKPP/BRQBN1NR w hb - 1 9 perft 1 25 perft 2 745 @@ -4473,7 +4474,7 @@ perft 4 570459 perft 5 15520298 perft 6 460840861 -id 1 +id 497 epd brqnkbnr/pp2pp1p/3p4/2p5/5p2/3P3P/PPP1PPP1/B1RNKBNR w Hhb - 0 9 perft 1 19 perft 2 516 @@ -4482,7 +4483,7 @@ perft 4 312996 perft 5 6995034 perft 6 214340699 -id 1 +id 498 epd brq1kn1b/1ppppprp/2n3p1/p7/P1N5/6P1/1PPPPP1P/BRQNK1RB w GBb - 2 9 perft 1 29 perft 2 557 @@ -4491,7 +4492,7 @@ perft 4 352277 perft 5 10840256 perft 6 249999654 -id 1 +id 499 epd rbbq1k1r/ppp1pppp/7n/1n1p4/5P2/P2P4/1PPBP1PP/RB1QNKNR w HAha - 1 9 perft 1 25 perft 2 769 @@ -4500,7 +4501,7 @@ perft 4 638340 perft 5 17438715 perft 6 570893953 -id 1 +id 500 epd r1bbnk1r/qpp1pppp/p6n/3p4/1P6/5N1P/P1PPPPP1/RQBBK1NR w ha - 0 9 perft 1 23 perft 2 728 @@ -4509,7 +4510,7 @@ perft 4 587364 perft 5 16053564 perft 6 529082811 -id 1 +id 501 epd rqbnkbnr/1pp2p1p/3p4/p3p1p1/8/2P2P2/PP1PPNPP/RQBNKB1R w HAha - 0 9 perft 1 26 perft 2 772 @@ -4518,7 +4519,7 @@ perft 4 653704 perft 5 19571559 perft 6 593915677 -id 1 +id 502 epd r1bnknrb/pqppp1p1/1p5p/5p2/7P/3P2N1/PPP1PPP1/RQBNK1RB w GAga - 2 9 perft 1 27 perft 2 748 @@ -4527,7 +4528,7 @@ perft 4 597105 perft 5 16324542 perft 6 506453626 -id 1 +id 503 epd rbqnbknr/pp1pppp1/8/2p5/3P3p/5N1P/PPP1PPPR/RBQNBK2 w Aha - 0 9 perft 1 30 perft 2 859 @@ -4536,7 +4537,7 @@ perft 4 819631 perft 5 26363334 perft 6 842796987 -id 1 +id 504 epd rqnbbrk1/ppppppp1/8/5n1p/3P3P/2B3P1/PPP1PP2/RQNB1KNR w HA - 0 9 perft 1 22 perft 2 505 @@ -4545,7 +4546,7 @@ perft 4 283464 perft 5 7055215 perft 6 186760784 -id 1 +id 505 epd rqnkbbnr/pp2p1p1/8/2pp1p1p/3PPP2/8/PPP1N1PP/RQNKBB1R w HAha - 0 9 perft 1 28 perft 2 832 @@ -4554,7 +4555,7 @@ perft 4 722857 perft 5 20429246 perft 6 663183060 -id 1 +id 506 epd rqnkbnr1/pppp2bp/6p1/4pp2/1P2P3/3NN3/P1PP1PPP/RQ1KB1RB w GAga - 0 9 perft 1 28 perft 2 641 @@ -4563,7 +4564,7 @@ perft 4 459993 perft 5 14038570 perft 6 364210162 -id 1 +id 507 epd rbq2kbr/pppppppp/2n5/P7/3P1n2/2P5/1P2PPPP/RBQNKNBR w HA - 1 9 perft 1 31 perft 2 889 @@ -4572,7 +4573,7 @@ perft 4 766181 perft 5 24299415 perft 6 692180754 -id 1 +id 508 epd rq1bkn1r/ppppp2p/3n4/5pp1/2b3P1/1N1P1P2/PPP1P2P/RQ1BKNBR w HAha - 1 9 perft 1 28 perft 2 810 @@ -4581,7 +4582,7 @@ perft 4 657520 perft 5 18719949 perft 6 556282676 -id 1 +id 509 epd r1nknbbr/p2ppp1p/1pp3p1/8/1P6/4P3/P1PPNPPq/R1QKNBBR w HAha - 0 9 perft 1 24 perft 2 797 @@ -4590,7 +4591,7 @@ perft 4 719069 perft 5 21862776 perft 6 716521139 -id 1 +id 510 epd rqnknrbb/ppp1p3/5ppp/2Np4/2P5/4P3/PP1P1PPP/RQNK1RBB w FAfa - 0 9 perft 1 34 perft 2 686 @@ -4599,7 +4600,7 @@ perft 4 515541 perft 5 17664543 perft 6 423574794 -id 1 +id 511 epd 1brnqknr/2p1pppp/p2p4/1P6/6P1/4Nb2/PP1PPP1P/BBR1QKNR w HChc - 1 9 perft 1 34 perft 2 1019 @@ -4608,7 +4609,7 @@ perft 4 1003103 perft 5 33322477 perft 6 1043293394 -id 1 +id 512 epd brn1qknr/1p1pppp1/pb5p/Q1p5/3P3P/8/PPP1PPPR/BRNB1KN1 w Bhb - 2 9 perft 1 32 perft 2 642 @@ -4617,7 +4618,7 @@ perft 4 464895 perft 5 15454749 perft 6 371861782 -id 1 +id 513 epd brnqkbnr/pppppp2/8/6pp/6P1/P2P1P2/1PP1P2P/BRNQKBNR w HBhb - 0 9 perft 1 20 perft 2 441 @@ -4626,7 +4627,7 @@ perft 4 240220 perft 5 5770284 perft 6 153051835 -id 1 +id 514 epd 2nqknrb/1rpppppp/5B2/pp6/1PP1b3/3P4/P3PPPP/1RNQKNRB w GBg - 1 9 perft 1 35 perft 2 1042 @@ -4635,7 +4636,7 @@ perft 4 1101159 perft 5 38505058 perft 6 1202668717 -id 1 +id 515 epd rb1nqknr/1pp1pppp/8/3p4/p2P4/6PN/PPPQPP1P/RBBN1K1R w HAha - 0 9 perft 1 29 perft 2 692 @@ -4644,7 +4645,7 @@ perft 4 555018 perft 5 17820605 perft 6 497251206 -id 1 +id 516 epd rnbbqknr/pppp4/5p2/4p1pp/P7/2N2PP1/1PPPP2P/R1BBQKNR w HAha - 0 9 perft 1 23 perft 2 595 @@ -4653,7 +4654,7 @@ perft 4 415772 perft 5 10881112 perft 6 329010121 -id 1 +id 517 epd rn1qkbnr/p1p1pp1p/bp4p1/3p4/1P6/4P3/P1PP1PPP/RNBQKBNR w HAha - 0 9 perft 1 30 perft 2 794 @@ -4662,7 +4663,7 @@ perft 4 690811 perft 5 21657601 perft 6 647745807 -id 1 +id 518 epd r1bqk1rb/pppnpppp/5n2/3p4/2P3PP/2N5/PP1PPP2/R1BQKNRB w GAga - 1 9 perft 1 32 perft 2 821 @@ -4671,7 +4672,7 @@ perft 4 733155 perft 5 24923473 perft 6 710765657 -id 1 +id 519 epd rbnqbknr/1p1ppp1p/6p1/p1p5/7P/3P4/PPP1PPP1/RBNQBKNR w HAha - 0 9 perft 1 24 perft 2 720 @@ -4680,7 +4681,7 @@ perft 4 575027 perft 5 15992882 perft 6 501093456 -id 1 +id 520 epd r1qbbk1r/pp1ppppp/n1p5/5n2/B1P3P1/8/PP1PPP1P/RNQ1BKNR w HAha - 0 9 perft 1 27 perft 2 831 @@ -4689,7 +4690,7 @@ perft 4 698986 perft 5 19948650 perft 6 637973209 -id 1 +id 521 epd rnqkbb1r/p1pppppp/8/8/1p4n1/PP4PP/2PPPP2/RNQKBBNR w HAha - 0 9 perft 1 18 perft 2 463 @@ -4698,7 +4699,7 @@ perft 4 256152 perft 5 6065231 perft 6 172734380 -id 1 +id 522 epd rnqk1nrb/pppbpp2/7p/3p2p1/4B3/2N1N1P1/PPPPPP1P/R1QKB1R1 w GAga - 0 9 perft 1 34 perft 2 1171 @@ -4707,7 +4708,7 @@ perft 4 1318217 perft 5 42109356 perft 6 1465473753 -id 1 +id 523 epd rbnqknbr/1pp1ppp1/3p4/7p/p2P2PP/2P5/PP2PP2/RBNQKNBR w HAha - 0 9 perft 1 32 perft 2 867 @@ -4716,7 +4717,7 @@ perft 4 798722 perft 5 26632459 perft 6 781067145 -id 1 +id 524 epd rn1bknbr/pq2pppp/1p6/2pp4/P7/1P1P4/2PNPPPP/RNQBK1BR w HAha - 0 9 perft 1 24 perft 2 627 @@ -4725,7 +4726,7 @@ perft 4 462942 perft 5 13200921 perft 6 385193532 -id 1 +id 525 epd r1qk1bbr/ppp1pp1p/2np1n2/6p1/2PP4/3BP3/PP3PPP/RNQKN1BR w HAha - 2 9 perft 1 31 perft 2 992 @@ -4734,7 +4735,7 @@ perft 4 986631 perft 5 30397368 perft 6 1011631987 -id 1 +id 526 epd r1qknrbb/pppp1p2/2n3p1/4p2p/8/QPP5/P1NPPPPP/RN1K1RBB w FAfa - 2 9 perft 1 30 perft 2 702 @@ -4743,7 +4744,7 @@ perft 4 532939 perft 5 16813114 perft 6 438096194 -id 1 +id 527 epd bbkr1qnr/2pppppp/2n5/pp6/8/PPN5/1BPPPPPP/1BR1KQNR w HC - 2 9 perft 1 25 perft 2 573 @@ -4752,7 +4753,7 @@ perft 4 380910 perft 5 10554668 perft 6 283975400 -id 1 +id 528 epd 1rnbkqnr/1bpppppp/1p6/7P/p2P4/5P2/PPP1P1P1/BRNBKQNR w HBhb - 0 9 perft 1 21 perft 2 503 @@ -4761,7 +4762,7 @@ perft 4 301084 perft 5 7679979 perft 6 207799378 -id 1 +id 529 epd brnkqbnr/2p1pppp/1p6/3p4/1pP5/P6P/3PPPP1/BRNKQBNR w HBhb - 0 9 perft 1 28 perft 2 743 @@ -4770,7 +4771,7 @@ perft 4 587192 perft 5 17354516 perft 6 507176753 -id 1 +id 530 epd br1kqnrb/npp1pppp/8/3p4/p4N2/PP6/2PPPPPP/BR1KQNRB w GBgb - 0 9 perft 1 31 perft 2 808 @@ -4779,7 +4780,7 @@ perft 4 698475 perft 5 22376575 perft 6 640362920 -id 1 +id 531 epd rbbnkq1r/pppppp1p/7n/6p1/P5P1/2P2N2/1P1PPP1P/RBBNKQ1R w HAha - 1 9 perft 1 29 perft 2 580 @@ -4788,7 +4789,7 @@ perft 4 404831 perft 5 12730970 perft 6 325226128 -id 1 +id 532 epd rnbbk1nr/pp2qppp/2ppp3/8/3P4/P1N4N/1PP1PPPP/R1BBKQ1R w HAha - 0 9 perft 1 29 perft 2 838 @@ -4797,7 +4798,7 @@ perft 4 721884 perft 5 21100580 perft 6 646624429 -id 1 +id 533 epd rnbk1b1r/ppppn1pp/4pp2/7q/7P/P5PB/1PPPPP2/RNBKQ1NR w HAha - 3 9 perft 1 20 perft 2 729 @@ -4806,7 +4807,7 @@ perft 4 576199 perft 5 14507076 perft 6 498621813 -id 1 +id 534 epd r2kqnrb/pbppppp1/np5p/8/4Q1P1/3P4/PPP1PP1P/RNBK1NRB w GAga - 2 9 perft 1 47 perft 2 1219 @@ -4815,7 +4816,7 @@ perft 4 1486353 perft 5 65239153 perft 6 1834391369 -id 1 +id 535 epd rbnkbq1r/p1p2ppp/1p2pn2/3p4/P3P3/3P4/1PP1KPPP/RBN1BQNR w ha - 2 9 perft 1 29 perft 2 923 @@ -4824,7 +4825,7 @@ perft 4 883866 perft 5 26202752 perft 6 868565895 -id 1 +id 536 epd rk1bb1nr/ppppqppp/n7/1N2p3/6P1/7N/PPPPPP1P/R1KBBQ1R w HA - 6 9 perft 1 27 perft 2 703 @@ -4833,7 +4834,7 @@ perft 4 559525 perft 5 16049807 perft 6 492966455 -id 1 +id 537 epd rnkqbbnr/p1ppp2p/1p4p1/8/1B3p1P/2NP4/PPP1PPP1/R1KQ1BNR w HAha - 0 9 perft 1 29 perft 2 610 @@ -4842,7 +4843,7 @@ perft 4 438277 perft 5 14020041 perft 6 355083962 -id 1 +id 538 epd rnkqb1rb/pp1p1ppp/4p3/2P3n1/8/1PP5/P3PPPP/RNKQBNRB w GAga - 0 9 perft 1 29 perft 2 675 @@ -4851,7 +4852,7 @@ perft 4 535821 perft 5 17000613 perft 6 476598337 -id 1 +id 539 epd rb1kqnbr/pp1pp1p1/1np2p2/7p/P1P3PP/8/1P1PPP2/RBNKQNBR w HAha - 0 9 perft 1 31 perft 2 1077 @@ -4860,7 +4861,7 @@ perft 4 1183381 perft 5 37415304 perft 6 1328374620 -id 1 +id 540 epd rnkbq1br/ppp2ppp/3p4/Q3p1n1/5P2/3P2P1/PPP1P2P/RNKB1NBR w HAha - 0 9 perft 1 41 perft 2 1201 @@ -4869,7 +4870,7 @@ perft 4 1420367 perft 5 52991625 perft 6 1675608008 -id 1 +id 541 epd rn1qnbbr/pp2pppp/2ppk3/8/2PP4/3Q1N2/PP2PPPP/RNK2BBR w HA - 1 9 perft 1 34 perft 2 666 @@ -4878,7 +4879,7 @@ perft 4 472299 perft 5 15860369 perft 6 353831792 -id 1 +id 542 epd rnkqnr1b/ppppp1pp/5p2/8/Q1P2P2/8/PP1P2PP/RbK1NRBB w FAfa - 0 9 perft 1 36 perft 2 876 @@ -4887,7 +4888,7 @@ perft 4 788580 perft 5 29022529 perft 6 736717252 -id 1 +id 543 epd bbrn1nqr/ppp1k1pp/5p2/3pp3/7P/3PN3/PPP1PPP1/BBRK1NQR w - - 1 9 perft 1 24 perft 2 583 @@ -4896,7 +4897,7 @@ perft 4 383532 perft 5 10522064 perft 6 280707118 -id 1 +id 544 epd brnbkn1r/1pppp1p1/4q3/p4p1p/7P/1N3P2/PPPPP1PQ/BR1BKN1R w HBhb - 2 9 perft 1 27 perft 2 935 @@ -4905,7 +4906,7 @@ perft 4 885699 perft 5 26000648 perft 6 873063158 -id 1 +id 545 epd br1knbqr/pp2p1pp/1n6/2pp1p2/6P1/2P4B/PP1PPPQP/BRNKN2R w HBhb - 0 9 perft 1 27 perft 2 681 @@ -4914,7 +4915,7 @@ perft 4 510687 perft 5 14954779 perft 6 415624943 -id 1 +id 546 epd brnk1qrb/p1ppppp1/1p5p/8/P3n3/1N4P1/1PPPPPRP/BR1KNQ1B w Bgb - 0 9 perft 1 22 perft 2 638 @@ -4923,7 +4924,7 @@ perft 4 412346 perft 5 9760752 perft 6 293499724 -id 1 +id 547 epd rbbnknqr/pppp3p/5pp1/8/1P1pP3/7P/P1P2PP1/RBBNKNQR w HAha - 0 9 perft 1 29 perft 2 756 @@ -4932,7 +4933,7 @@ perft 4 614074 perft 5 17602252 perft 6 528140595 -id 1 +id 548 epd 1nbbknqr/rpp1ppp1/1Q1p3p/p7/2P2PP1/8/PP1PP2P/RNBBKN1R w HAh - 2 9 perft 1 37 perft 2 977 @@ -4941,7 +4942,7 @@ perft 4 944867 perft 5 33695089 perft 6 940198007 -id 1 +id 549 epd rnb2bqr/ppkpppp1/3n3p/2p5/6PP/2N2P2/PPPPP3/R1BKNBQR w HA - 2 9 perft 1 30 perft 2 647 @@ -4950,7 +4951,7 @@ perft 4 467780 perft 5 15115531 perft 6 369257622 -id 1 +id 550 epd rn1k1qrb/p1pppppp/bp6/8/4n3/P4BPP/1PPPPP2/RNBKNQR1 w GAga - 2 9 perft 1 22 perft 2 670 @@ -4959,7 +4960,7 @@ perft 4 451517 perft 5 11199653 perft 6 339919682 -id 1 +id 551 epd rb2bnqr/nppkpppp/3p4/p7/1P6/P2N2P1/2PPPP1P/RB1KBNQR w HA - 3 9 perft 1 22 perft 2 479 @@ -4968,7 +4969,7 @@ perft 4 264739 perft 5 6831555 perft 6 167329117 -id 1 +id 552 epd r1kbb1qr/2pppppp/np2n3/p7/2P3P1/8/PP1PPPQP/RNKBBN1R w HAha - 1 9 perft 1 32 perft 2 723 @@ -4977,7 +4978,7 @@ perft 4 581832 perft 5 19472074 perft 6 504622114 -id 1 +id 553 epd rnknbb1r/p1ppp1pp/8/1p1P1p1q/8/P1P5/1P2PPPP/RNKNBBQR w HAha - 1 9 perft 1 19 perft 2 607 @@ -4986,7 +4987,7 @@ perft 4 417451 perft 5 9753617 perft 6 325177085 -id 1 +id 554 epd rnkn1qrb/pp1bp1pp/2p5/1N1p1p2/8/2P5/PPKPPPPP/R2NBQRB w ga - 2 9 perft 1 27 perft 2 533 @@ -4995,7 +4996,7 @@ perft 4 330747 perft 5 9206957 perft 6 232664675 -id 1 +id 555 epd r1nknqbr/pp2p1pp/2p2p2/3p4/6P1/PP1P4/2P1PP1b/RBNKNQBR w HAha - 0 9 perft 1 20 perft 2 582 @@ -5004,7 +5005,7 @@ perft 4 409166 perft 5 10708639 perft 6 326565393 -id 1 +id 556 epd rnkb1qbr/p1pp1p1p/1p2pn2/1Q4p1/4P3/N4P2/PPPP2PP/R1KBN1BR w HAha - 0 9 perft 1 40 perft 2 1038 @@ -5013,7 +5014,7 @@ perft 4 1051441 perft 5 39145902 perft 6 1079612614 -id 1 +id 557 epd rn2qbbr/1pkppp1p/p3n1p1/8/8/2P2P2/PP1PP1PP/RNKN1BBR w HA - 0 9 perft 1 24 perft 2 605 @@ -5022,7 +5023,7 @@ perft 4 385964 perft 5 9687507 perft 6 260874068 -id 1 +id 558 epd rn1nqrbb/p1kppp1p/8/1pp3p1/1P6/2N1P3/P1PP1PPP/RK1NQRBB w - - 0 9 perft 1 21 perft 2 540 @@ -5031,7 +5032,7 @@ perft 4 337997 perft 5 8436136 perft 6 237525904 -id 1 +id 559 epd bbrnknrq/1pp3pp/p2p1p2/4p3/P7/1P2N3/2PPPPPP/BBRN1RKQ w gc - 0 9 perft 1 24 perft 2 527 @@ -5040,7 +5041,7 @@ perft 4 326175 perft 5 9139962 perft 6 226253685 -id 1 +id 560 epd brnb1nrq/pppp1kpp/4p3/8/5p1P/P1P3P1/1P1PPP2/BRNBKNRQ w GB - 1 9 perft 1 29 perft 2 773 @@ -5049,7 +5050,7 @@ perft 4 638768 perft 5 20503775 perft 6 560338709 -id 1 +id 561 epd br1k1brq/ppppp2p/1n1n1pp1/8/P1P5/3P2P1/1P2PP1P/BRNKNBRQ w GBgb - 0 9 perft 1 28 perft 2 811 @@ -5058,7 +5059,7 @@ perft 4 664880 perft 5 19913758 perft 6 565143976 -id 1 +id 562 epd 1r1knrqb/n1pppppp/p1b5/1p6/8/3N1P2/PPPPP1PP/BRNK1RQB w fb - 3 9 perft 1 29 perft 2 753 @@ -5067,7 +5068,7 @@ perft 4 620019 perft 5 20044474 perft 6 558383603 -id 1 +id 563 epd rbbnk1rq/pppppppp/8/3Pn3/8/4P1P1/PPP2P1P/RBBNKNRQ w GAga - 1 9 perft 1 22 perft 2 551 @@ -5076,7 +5077,7 @@ perft 4 324608 perft 5 8204171 perft 6 217689974 -id 1 +id 564 epd rnbbk1rq/2pppp1p/p3n1p1/1p6/P3N3/8/1PPPPPPP/RNBB1KRQ w ga - 0 9 perft 1 26 perft 2 742 @@ -5085,7 +5086,7 @@ perft 4 599527 perft 5 16787080 perft 6 525678162 -id 1 +id 565 epd rnbkn1rq/ppppppb1/6p1/7p/2B2P2/1P2P3/P1PP2PP/RNBKN1RQ w GAga - 1 9 perft 1 28 perft 2 799 @@ -5094,7 +5095,7 @@ perft 4 689436 perft 5 20755098 perft 6 639632905 -id 1 +id 566 epd rn1knrqb/p2pppp1/b1p5/1p5p/2P2P2/1P6/P2PP1PP/RNBKNRQB w FAfa - 1 9 perft 1 30 perft 2 579 @@ -5103,7 +5104,7 @@ perft 4 397545 perft 5 13257198 perft 6 311282465 -id 1 +id 567 epd rbnkbnrq/pp2p1Np/2p2p2/8/3p4/8/PPPPPPPP/RBNKBR1Q w Aga - 0 9 perft 1 23 perft 2 670 @@ -5112,7 +5113,7 @@ perft 4 501883 perft 5 13012378 perft 6 411860744 -id 1 +id 568 epd rk1bbnrq/ppp1pppp/n7/3p4/5P2/3P2NP/PPP1P1P1/RNKBB1RQ w GA - 0 9 perft 1 26 perft 2 597 @@ -5121,7 +5122,7 @@ perft 4 402506 perft 5 11269462 perft 6 296701249 -id 1 +id 569 epd r1knbbrq/pppp2p1/2n1p2p/5p2/4P3/P1PP4/1P3PPP/RNKNBBRQ w GAga - 1 9 perft 1 20 perft 2 596 @@ -5130,7 +5131,7 @@ perft 4 399069 perft 5 9416862 perft 6 293659781 -id 1 +id 570 epd rnknbrqb/p1p1pp1p/3p4/1p1N2p1/8/N7/PPPPPPPP/1RK1BRQB w Ffa - 0 9 perft 1 26 perft 2 724 @@ -5139,7 +5140,7 @@ perft 4 552040 perft 5 15257204 perft 6 461293885 -id 1 +id 571 epd rbnknrb1/1p1ppp1p/p1p3p1/8/1P3P2/1R6/PqPPP1PP/RBNKN1BQ w Afa - 0 9 perft 1 31 perft 2 1183 @@ -5148,7 +5149,7 @@ perft 4 1289502 perft 5 38722152 perft 6 1421492227 -id 1 +id 572 epd rnkbnrbq/2p1ppp1/p7/1p1p3p/3P4/1P4P1/P1P1PP1P/RNKBNRBQ w FAfa - 0 9 perft 1 24 perft 2 506 @@ -5157,7 +5158,7 @@ perft 4 301464 perft 5 8086100 perft 6 207129256 -id 1 +id 573 epd r1knrbbq/pp1ppppp/2p1n3/8/2P3P1/P7/1PKPPP1P/RN1NRBBQ w ea - 0 9 perft 1 28 perft 2 570 @@ -5166,7 +5167,7 @@ perft 4 352471 perft 5 10278695 perft 6 242592363 -id 1 +id 574 epd rnknrq1b/ppp1p1p1/4b3/3p1p1p/6P1/P4P2/1PPPPQ1P/RNKNR1BB w EAea - 2 9 perft 1 30 perft 2 739 @@ -5175,7 +5176,7 @@ perft 4 594962 perft 5 19252739 perft 6 521629794 -id 1 +id 575 epd bbqr1krn/pppp1p1p/5n2/4p1p1/3P4/P3QP2/1PP1P1PP/BB1RNKRN w GDgd - 0 9 perft 1 31 perft 2 799 @@ -5184,7 +5185,7 @@ perft 4 674913 perft 5 22172123 perft 6 609277274 -id 1 +id 576 epd bq1b1krn/pp1ppppp/3n4/2r5/3p3N/6N1/PPP1PPPP/BQRB1KR1 w GCg - 2 9 perft 1 21 perft 2 798 @@ -5193,7 +5194,7 @@ perft 4 688429 perft 5 17546069 perft 6 647165916 -id 1 +id 577 epd bqrnkbrn/2pp1pp1/p7/1p2p2p/1P6/4N3/P1PPPPPP/BQR1KBRN w GCgc - 0 9 perft 1 27 perft 2 783 @@ -5202,7 +5203,7 @@ perft 4 670798 perft 5 20059741 perft 6 624462073 -id 1 +id 578 epd bqr1krnb/1np1pppp/8/pp1p4/8/2P2N2/PP1PPPPP/BQRNKR1B w FCfc - 0 9 perft 1 28 perft 2 636 @@ -5211,7 +5212,7 @@ perft 4 461104 perft 5 14237097 perft 6 372181570 -id 1 +id 579 epd qbb1rkrn/1ppppppp/p7/7n/8/P2P4/1PP1PPPP/QBBRNKRN w Gg - 0 9 perft 1 25 perft 2 547 @@ -5220,7 +5221,7 @@ perft 4 332918 perft 5 8849383 perft 6 229112926 -id 1 +id 580 epd 1rbbnkrn/p1p1pp1p/2q5/1p1p2p1/8/2P3P1/PP1PPP1P/QRBBNKRN w GBgb - 2 9 perft 1 24 perft 2 1010 @@ -5229,7 +5230,7 @@ perft 4 983770 perft 5 24328258 perft 6 961371180 -id 1 +id 581 epd qrb1kbrn/ppp1p2p/4npp1/3p4/8/1PP4P/PR1PPPP1/Q1BNKBRN w Ggb - 1 9 perft 1 18 perft 2 451 @@ -5238,7 +5239,7 @@ perft 4 247310 perft 5 5568106 perft 6 155744022 -id 1 +id 582 epd qr2krnb/p1p1pppp/b1np4/1p6/3NP3/7P/PPPP1PP1/QRBNKR1B w FBfb - 2 9 perft 1 25 perft 2 667 @@ -5247,7 +5248,7 @@ perft 4 476030 perft 5 12458875 perft 6 361495148 -id 1 +id 583 epd qbrnbkrn/ppp3pp/3p4/5p2/2P1pP2/6PP/PP1PP3/QBRNBKRN w GCgc - 0 9 perft 1 24 perft 2 650 @@ -5256,7 +5257,7 @@ perft 4 445263 perft 5 12187382 perft 6 326834539 -id 1 +id 584 epd qrnb1krn/ppp1p1pp/5p2/2Np4/b2P4/2P5/PP2PPPP/QR1BBKRN w GBgb - 0 9 perft 1 27 perft 2 641 @@ -5265,7 +5266,7 @@ perft 4 432041 perft 5 12103076 perft 6 310695797 -id 1 +id 585 epd qrnkbbrn/pp2pp2/8/2pp2pp/6PP/3P4/PPPKPP2/QRN1BBRN w gb - 0 9 perft 1 22 perft 2 554 @@ -5274,7 +5275,7 @@ perft 4 357404 perft 5 9014737 perft 6 258925091 -id 1 +id 586 epd qrnkbrnb/p1p1ppp1/1p6/3p4/3P3p/5N1P/PPP1PPP1/QRNKBR1B w FBfb - 0 9 perft 1 24 perft 2 529 @@ -5283,7 +5284,7 @@ perft 4 318722 perft 5 8295874 perft 6 213856651 -id 1 +id 587 epd qbr1krbn/1pppp1pp/p7/5pn1/2PP4/8/PPB1PPPP/Q1RNKRBN w FCfc - 0 9 perft 1 26 perft 2 831 @@ -5292,7 +5293,7 @@ perft 4 696830 perft 5 18961456 perft 6 621884383 -id 1 +id 588 epd 1rnbkrbn/1qp1pppp/3p4/pp6/4P3/1NP4P/PP1P1PP1/QR1BKRBN w FBfb - 0 9 perft 1 24 perft 2 597 @@ -5301,7 +5302,7 @@ perft 4 404761 perft 5 10832084 perft 6 307793179 -id 1 +id 589 epd q1rkrbbn/ppp1pppp/8/3p4/1PnP4/P7/1RP1PPPP/Q1NKRBBN w Ee - 1 9 perft 1 20 perft 2 520 @@ -5310,7 +5311,7 @@ perft 4 278067 perft 5 6452205 perft 6 170268300 -id 1 +id 590 epd qrnkrn1b/ppppp1pp/4b3/7P/6p1/P7/1PPPPP2/QRNKRNBB w EBeb - 0 9 perft 1 26 perft 2 566 @@ -5319,7 +5320,7 @@ perft 4 381312 perft 5 10940750 perft 6 287987207 -id 1 +id 591 epd bbr1nkrn/ppp1pppp/3q4/3p4/8/P7/1PPPPPPP/BBRQNRKN w gc - 5 9 perft 1 19 perft 2 661 @@ -5328,7 +5329,7 @@ perft 4 460396 perft 5 10870247 perft 6 356399665 -id 1 +id 592 epd brqbnkrn/pp1pp2p/5pp1/2p5/4P3/P2P1N2/1PP2PPP/BRQB1KRN w GBgb - 0 9 perft 1 27 perft 2 679 @@ -5337,7 +5338,7 @@ perft 4 527306 perft 5 16391730 perft 6 455940859 -id 1 +id 593 epd 2qnkbrn/p1pppppp/8/1r6/1p2bP2/7N/PPPPP1PP/BR1QKBRN w GBg - 4 9 perft 1 18 perft 2 774 @@ -5346,7 +5347,7 @@ perft 4 635461 perft 5 14371755 perft 6 559579332 -id 1 +id 594 epd r1qnkr1b/p1pppppp/7n/1p6/8/1P3b1N/PRPPPPPP/B1QNK1RB w f - 5 9 perft 1 21 perft 2 677 @@ -5355,7 +5356,7 @@ perft 4 501520 perft 5 12463801 perft 6 410795298 -id 1 +id 595 epd rbbqn1rn/pppp1pp1/3k4/4p2Q/2PPP3/8/PP3PPP/RBB1NKRN w GA - 1 9 perft 1 40 perft 2 742 @@ -5364,7 +5365,7 @@ perft 4 579833 perft 5 21852196 perft 6 471452088 -id 1 +id 596 epd rqbbnkrn/3pppp1/p1p4p/1p6/5P2/P2N4/1PPPP1PP/RQBBK1RN w ga - 0 9 perft 1 23 perft 2 665 @@ -5373,7 +5374,7 @@ perft 4 492544 perft 5 12794736 perft 6 396640086 -id 1 +id 597 epd r2nkbrn/pp2pppp/8/2ppqb2/2P3P1/5P2/PP1PPN1P/RQB1KBRN w GAga - 3 9 perft 1 28 perft 2 1108 @@ -5382,7 +5383,7 @@ perft 4 1194581 perft 5 34780853 perft 6 1292405738 -id 1 +id 598 epd rqbnk1nb/p1pppr1p/5p2/1p4p1/1PP1P3/8/P2P1PPP/RQBNKRNB w FAa - 1 9 perft 1 26 perft 2 650 @@ -5391,7 +5392,7 @@ perft 4 491403 perft 5 14565370 perft 6 416833400 -id 1 +id 599 epd rbqnb1rn/p1pp1kpp/1p2pp2/8/4P2P/P5P1/1PPP1P2/RBQNBKRN w GA - 0 9 perft 1 20 perft 2 437 @@ -5400,7 +5401,7 @@ perft 4 222154 perft 5 5282124 perft 6 132309824 -id 1 +id 600 epd rqnbbkrn/p1p1pppp/3p4/1p5B/8/1P1NP3/P1PP1PPP/RQ2BKRN w GAga - 0 9 perft 1 30 perft 2 606 @@ -5409,7 +5410,7 @@ perft 4 422491 perft 5 12989786 perft 6 326601372 -id 1 +id 601 epd rqnkbbr1/ppppp1pp/5p2/7n/8/2PNP2P/PP1P1PP1/RQ1KBBRN w GAga - 1 9 perft 1 23 perft 2 482 @@ -5418,7 +5419,7 @@ perft 4 297869 perft 5 8430874 perft 6 217797292 -id 1 +id 602 epd r1nkbrnb/2ppppp1/1q6/pp5p/1P6/P3P3/2PPKPPP/RQN1BRNB w fa - 2 9 perft 1 25 perft 2 827 @@ -5427,7 +5428,7 @@ perft 4 701071 perft 5 19290675 perft 6 632892337 -id 1 +id 603 epd rbqnkrbn/p1ppppp1/7p/1p6/7P/2N1P3/PPPP1PPB/RBQ1KR1N w FAfa - 1 9 perft 1 30 perft 2 627 @@ -5436,7 +5437,7 @@ perft 4 440217 perft 5 12976682 perft 6 337377291 -id 1 +id 604 epd r1nbkrbn/p1qp1ppp/8/1pp1p3/2P1P3/6P1/PP1PBP1P/RQN1KRBN w FAfa - 2 9 perft 1 22 perft 2 616 @@ -5445,7 +5446,7 @@ perft 4 431199 perft 5 10850952 perft 6 335943324 -id 1 +id 605 epd rqnkr1bn/ppp1ppb1/3p2pp/8/P7/2P2P2/1PKPP1PP/RQN1RBBN w ea - 1 9 perft 1 31 perft 2 679 @@ -5454,7 +5455,7 @@ perft 4 493500 perft 5 15661072 perft 6 379844460 -id 1 +id 606 epd r2krnbb/qppp1ppp/1n6/p3p3/PP6/4N3/N1PPPPPP/RQ1KR1BB w EAea - 4 9 perft 1 24 perft 2 645 @@ -5463,7 +5464,7 @@ perft 4 487028 perft 5 13837270 perft 6 416239106 -id 1 +id 607 epd bbr1qk1n/1ppppp1p/2n5/p7/P7/1P2P3/2PP1PrP/1BRNQKRN w GCc - 0 9 perft 1 18 perft 2 520 @@ -5472,7 +5473,7 @@ perft 4 304462 perft 5 7215306 perft 6 207612575 -id 1 +id 608 epd brnbq1rn/2ppppkp/p5p1/1p6/8/1BP3P1/PP1PPP1P/BRN1QRKN w - - 0 9 perft 1 21 perft 2 625 @@ -5481,7 +5482,7 @@ perft 4 419667 perft 5 9929336 perft 6 300902534 -id 1 +id 609 epd brn1kbrn/pp2p1pp/3p4/q1p2p2/2P4P/6P1/PP1PPP2/BRNQKBRN w GBgb - 1 9 perft 1 18 perft 2 477 @@ -5490,7 +5491,7 @@ perft 4 273925 perft 5 6720181 perft 6 187205941 -id 1 +id 610 epd brn1krnb/p3pppp/1qpp4/1p6/2P3P1/1P6/P2PPP1P/BRNQKRNB w FBfb - 1 9 perft 1 30 perft 2 835 @@ -5499,7 +5500,7 @@ perft 4 716151 perft 5 21806428 perft 6 654487872 -id 1 +id 611 epd r1b1qkrn/1p1ppppp/p1p1n3/8/4P3/1PN5/P1PPQPPb/RBB2KRN w GAga - 0 9 perft 1 28 perft 2 825 @@ -5508,7 +5509,7 @@ perft 4 716585 perft 5 22079005 perft 6 647939781 -id 1 +id 612 epd r1bbqk1n/p1pppprp/n7/1p4p1/5P2/2N3N1/PPPPP1PP/1RBBQKR1 w Ga - 4 9 perft 1 25 perft 2 545 @@ -5517,7 +5518,7 @@ perft 4 358854 perft 5 10271111 perft 6 273864588 -id 1 +id 613 epd rnbqkbrn/p1pp1pp1/4p3/7p/2p4P/2P5/PP1PPPP1/R1BQKBRN w GAga - 0 9 perft 1 17 perft 2 445 @@ -5526,7 +5527,7 @@ perft 4 255098 perft 5 5918310 perft 6 174733195 -id 1 +id 614 epd rnbqkrnb/1p1pp1p1/2p4p/p4p2/3P2P1/7N/PPPBPP1P/RN1QKR1B w FAfa - 0 9 perft 1 34 perft 2 746 @@ -5535,7 +5536,7 @@ perft 4 623133 perft 5 21285553 perft 6 569141201 -id 1 +id 615 epd rbnqbkr1/1ppppp2/p5n1/6pp/4P3/1N6/PPPP1PPP/RBQ1BRKN w ga - 2 9 perft 1 18 perft 2 466 @@ -5544,7 +5545,7 @@ perft 4 260864 perft 5 6051500 perft 6 170135726 -id 1 +id 616 epd rnqb1krn/ppppp1p1/7p/7b/P1P2pPP/8/1P1PPP2/RNQBBKRN w GAga - 0 9 perft 1 24 perft 2 575 @@ -5553,7 +5554,7 @@ perft 4 385825 perft 5 11039042 perft 6 291243811 -id 1 +id 617 epd rnqkbbr1/p1pp1ppp/4p3/1p6/P3P2n/5P2/1PPP1NPP/RNQKBBR1 w GAga - 2 9 perft 1 27 perft 2 803 @@ -5562,7 +5563,7 @@ perft 4 694449 perft 5 20666099 perft 6 638696065 -id 1 +id 618 epd rn1kbrnb/1qppp1pp/1p6/p4p2/1B1P4/1P5N/P1P1PPPP/RNQK1R1B w FAfa - 0 9 perft 1 37 perft 2 1209 @@ -5571,7 +5572,7 @@ perft 4 1425600 perft 5 49748034 perft 6 1671593862 -id 1 +id 619 epd rbnqkrbn/Bppp1p2/p5pp/4p3/5P2/6PP/PPPPP3/RBNQKR1N w FAfa - 0 9 perft 1 29 perft 2 720 @@ -5580,7 +5581,7 @@ perft 4 534148 perft 5 15384362 perft 6 421343249 -id 1 +id 620 epd rnqbkr1n/1p1ppbpp/3p1p2/p7/8/1P6/P1PPPPPP/R1QBKRBN w FAfa - 0 9 perft 1 20 perft 2 657 @@ -5589,7 +5590,7 @@ perft 4 492678 perft 5 11843134 perft 6 413965054 -id 1 +id 621 epd rnqkrb1n/ppppp3/6p1/5p1p/2b2P2/P1N5/1PPPP1PP/RQ1KRBBN w EAea - 1 9 perft 1 28 perft 2 749 @@ -5598,7 +5599,7 @@ perft 4 543151 perft 5 15379233 perft 6 417191461 -id 1 +id 622 epd rnqk1nbb/1pp2ppp/3pr3/p3p3/3P1P2/2N3N1/PPP1P1PP/R1QKR1BB w EAa - 1 9 perft 1 29 perft 2 883 @@ -5607,7 +5608,7 @@ perft 4 815098 perft 5 25144295 perft 6 789705382 -id 1 +id 623 epd bbr1kqrn/p1p1ppp1/1p2n2p/3p4/1P1P4/2N5/P1P1PPPP/BBR1KQRN w GCgc - 0 9 perft 1 22 perft 2 485 @@ -5616,7 +5617,7 @@ perft 4 271271 perft 5 6825123 perft 6 171793012 -id 1 +id 624 epd brnbkq1n/ppp1ppr1/7p/3p2p1/2P3PP/8/PPBPPP2/BRN1KQRN w GBb - 2 9 perft 1 30 perft 2 634 @@ -5625,7 +5626,7 @@ perft 4 442537 perft 5 13674310 perft 6 345386924 -id 1 +id 625 epd brnkqbr1/1pppp1pp/5p2/p7/P1P1P2n/8/1P1P1PP1/BRNKQBRN w GBgb - 0 9 perft 1 21 perft 2 504 @@ -5634,7 +5635,7 @@ perft 4 305184 perft 5 7778289 perft 6 217596497 -id 1 +id 626 epd b1rkqrnb/p1ppp1pp/1p1n4/5p2/5P2/PN5P/1PPPP1P1/BR1KQRNB w FBf - 0 9 perft 1 23 perft 2 688 @@ -5643,7 +5644,7 @@ perft 4 531592 perft 5 14228372 perft 6 451842354 -id 1 +id 627 epd 1bbnkqrn/rppppp2/p5p1/7p/7P/P1P1P3/1P1P1PP1/RBBNKQRN w GAg - 1 9 perft 1 25 perft 2 450 @@ -5652,7 +5653,7 @@ perft 4 263946 perft 5 7752404 perft 6 185393913 -id 1 +id 628 epd rnbbkqr1/1pppppp1/7p/p3n3/PP5P/8/1BPPPPP1/RN1BKQRN w GAga - 0 9 perft 1 23 perft 2 543 @@ -5661,7 +5662,7 @@ perft 4 305812 perft 5 7549008 perft 6 199883770 -id 1 +id 629 epd r1bkqbrn/ppppp1pp/8/5p2/3nPP2/1P4N1/P1PP2PP/RNBKQBR1 w GAga - 1 9 perft 1 27 perft 2 751 @@ -5670,7 +5671,7 @@ perft 4 600417 perft 5 17989920 perft 6 527273615 -id 1 +id 630 epd rnbkqr1b/1p1pp1pp/p4p1n/2p5/1P5P/N4P2/P1PPP1P1/R1BKQRNB w FAfa - 0 9 perft 1 21 perft 2 498 @@ -5679,7 +5680,7 @@ perft 4 302278 perft 5 7808375 perft 6 216224115 -id 1 +id 631 epd rbnkbqrn/p1p3pp/1p1p4/B3pp2/3P2P1/6N1/PPP1PP1P/RBNK1QR1 w GAga - 0 9 perft 1 34 perft 2 977 @@ -5688,7 +5689,7 @@ perft 4 961128 perft 5 33318567 perft 6 978991050 -id 1 +id 632 epd r1kbbqrn/ppp3pp/2np1p2/1P2p3/3P1P2/8/P1P1P1PP/RNKBBQRN w GAga - 0 9 perft 1 32 perft 2 920 @@ -5697,7 +5698,7 @@ perft 4 844881 perft 5 26763259 perft 6 797524786 -id 1 +id 633 epd rk1qbbrn/p2npppp/1p6/2p4Q/8/4P3/PPPP1PPP/RNK1B1RN w GA - 2 9 perft 1 35 perft 2 657 @@ -5706,7 +5707,7 @@ perft 4 495406 perft 5 16662477 perft 6 419496845 -id 1 +id 634 epd rnk1brnb/pp1p1pp1/8/q1p1p2p/5P2/NP6/P1PPP1PP/R1KQBRNB w FAfa - 1 9 perft 1 26 perft 2 774 @@ -5715,7 +5716,7 @@ perft 4 610661 perft 5 16987110 perft 6 523437649 -id 1 +id 635 epd rb1kqrbn/npp1ppp1/p7/3P3p/2PP4/8/PP3PPP/RBNKQRBN w FAfa - 0 9 perft 1 35 perft 2 775 @@ -5724,7 +5725,7 @@ perft 4 661118 perft 5 23983464 perft 6 625669222 -id 1 +id 636 epd rnkb1rbn/pp1p2pp/8/2p1pp1q/P6P/1PN5/2PPPPP1/R1KBQRBN w FAfa - 1 9 perft 1 22 perft 2 899 @@ -5733,7 +5734,7 @@ perft 4 850597 perft 5 21518343 perft 6 857951339 -id 1 +id 637 epd rnkqrbbn/1pppp1p1/8/p2N1p1p/2P4P/8/PP1PPPP1/R1KQRBBN w EAea - 0 9 perft 1 29 perft 2 585 @@ -5742,7 +5743,7 @@ perft 4 393221 perft 5 12238776 perft 6 299752383 -id 1 +id 638 epd rnk1r1bb/pp1ppppp/1q4n1/2p5/5P1P/3PP3/PPP3P1/RNKQRNBB w EAea - 1 9 perft 1 27 perft 2 884 @@ -5751,7 +5752,7 @@ perft 4 811915 perft 5 23698701 perft 6 790239502 -id 1 +id 639 epd bbrnkrqn/1ppp1p2/6pp/p3p3/5PP1/2PB4/PP1PP2P/B1RNKRQN w FCfc - 0 9 perft 1 37 perft 2 693 @@ -5760,7 +5761,7 @@ perft 4 550527 perft 5 20138432 perft 6 481498664 -id 1 +id 640 epd b1rbkrqn/ppp2ppp/1n2p3/3p4/6P1/2PP4/PP2PP1P/BRNBKRQN w FBf - 1 9 perft 1 21 perft 2 463 @@ -5769,7 +5770,7 @@ perft 4 253204 perft 5 6307276 perft 6 159025909 -id 1 +id 641 epd brnkrb1n/1pp1p1pp/3p4/p1Nq1p2/2P5/8/PP1PPPPP/BRK1RBQN w eb - 2 9 perft 1 27 perft 2 725 @@ -5778,7 +5779,7 @@ perft 4 496072 perft 5 12604078 perft 6 362747791 -id 1 +id 642 epd brn1r1nb/ppppkppp/4p3/8/2PP1P2/8/PP1KP1PP/BRN1RQNB w - - 1 9 perft 1 25 perft 2 623 @@ -5787,7 +5788,7 @@ perft 4 426659 perft 5 12290985 perft 6 317097424 -id 1 +id 643 epd rbb1krqn/1pp1pp1p/p3n1p1/3pP3/8/1PN5/P1PP1PPP/RBB1KRQN w FAfa d6 0 9 perft 1 23 perft 2 529 @@ -5796,7 +5797,7 @@ perft 4 310277 perft 5 7861413 perft 6 202594556 -id 1 +id 644 epd r1bbkrqn/p1pppppp/8/4n3/1p5P/P2P2P1/1PP1PP2/RNBBKRQN w FAfa - 0 9 perft 1 23 perft 2 571 @@ -5805,7 +5806,7 @@ perft 4 346793 perft 5 8699448 perft 6 243460643 -id 1 +id 645 epd rnbkrbqn/p1pp1ppp/4p3/1p6/8/BPN3P1/P1PPPP1P/R2KRBQN w EAea - 2 9 perft 1 29 perft 2 692 @@ -5814,7 +5815,7 @@ perft 4 500375 perft 5 14904192 perft 6 386694739 -id 1 +id 646 epd rnbkrqn1/pppppp2/8/1Q2b1pp/P3P3/5P2/1PPP2PP/RNBKR1NB w EAea - 0 9 perft 1 37 perft 2 1001 @@ -5823,7 +5824,7 @@ perft 4 987842 perft 5 35626426 perft 6 993747544 -id 1 +id 647 epd rbnkbrqn/p1pppp2/7p/1p4pP/3P1P2/8/PPP1P1P1/RBNKBRQN w FAfa - 0 9 perft 1 30 perft 2 564 @@ -5832,7 +5833,7 @@ perft 4 381364 perft 5 11859538 perft 6 293703269 -id 1 +id 648 epd 1nkbbrqn/3ppppp/r1p5/pp6/8/4PP2/PPPPN1PP/RNKBBRQ1 w FAf - 2 9 perft 1 26 perft 2 546 @@ -5841,7 +5842,7 @@ perft 4 344592 perft 5 9556962 perft 6 245137199 -id 1 +id 649 epd rnkrbbq1/pppppnp1/7p/8/1B1Q1p2/3P1P2/PPP1P1PP/RNKR1B1N w DAda - 2 9 perft 1 43 perft 2 887 @@ -5850,7 +5851,7 @@ perft 4 846858 perft 5 33185346 perft 6 851927292 -id 1 +id 650 epd 1rkrbqnb/pppppp2/2n3p1/7p/3P3P/P4N2/1PP1PPP1/RNKRBQ1B w DAd - 0 9 perft 1 26 perft 2 622 @@ -5859,7 +5860,7 @@ perft 4 403921 perft 5 10786140 perft 6 285233838 -id 1 +id 651 epd rbnkr1bn/pp1pqp1p/2p1p3/6p1/3P4/7P/PPP1PPP1/RBNKRQBN w EAea - 0 9 perft 1 19 perft 2 566 @@ -5868,7 +5869,7 @@ perft 4 381197 perft 5 9107175 perft 6 293397389 -id 1 +id 652 epd r1kbrqb1/pppp2pp/2n1p1n1/5p1B/4PP2/P7/1PPP2PP/RNK1RQBN w EAea - 2 9 perft 1 39 perft 2 1359 @@ -5877,7 +5878,7 @@ perft 4 1876028 perft 5 73871486 perft 6 2633945690 -id 1 +id 653 epd rnkrqbbn/p1p3pp/1p1ppp2/8/1P6/3P2P1/PKP1PP1P/RN1RQBBN w da - 0 9 perft 1 26 perft 2 776 @@ -5886,7 +5887,7 @@ perft 4 611907 perft 5 16884013 perft 6 503561996 -id 1 +id 654 epd rnkrqnbb/ppp2p1p/3p4/4p1p1/3P3P/N1Q5/PPP1PPP1/R1KR1NBB w DAda - 0 9 perft 1 40 perft 2 1175 @@ -5895,7 +5896,7 @@ perft 4 1375884 perft 5 52620163 perft 6 1633655838 -id 1 +id 655 epd bbrnkrn1/p1pppp2/1p6/6pp/3q4/1P3QP1/P1PPPP1P/BBRNKRN1 w FCfc - 0 9 perft 1 34 perft 2 1398 @@ -5904,7 +5905,7 @@ perft 4 1712950 perft 5 57268492 perft 6 2059942014 -id 1 +id 656 epd br1bkrnq/1p2pppp/pnp5/3p4/P1P5/5P2/1P1PPKPP/BRNB1RNQ w fb - 2 9 perft 1 24 perft 2 501 @@ -5913,7 +5914,7 @@ perft 4 284936 perft 5 7049659 perft 6 177940764 -id 1 +id 657 epd brnkrbn1/pppppp1q/B6p/6p1/8/1P2PP2/P1PP2PP/BRNKR1NQ w EBeb - 0 9 perft 1 34 perft 2 815 @@ -5922,7 +5923,7 @@ perft 4 700970 perft 5 22006883 perft 6 639803952 -id 1 +id 658 epd br1krnqb/pppppp1p/1n4p1/8/8/P2NN3/2PPPPPP/BR1K1RQB w Beb - 2 9 perft 1 37 perft 2 1029 @@ -5931,7 +5932,7 @@ perft 4 1025712 perft 5 36214583 perft 6 1026195877 -id 1 +id 659 epd rbbnkr1q/p1p2ppp/1p1ppn2/8/1PP4P/8/P2PPPP1/RBBNKRNQ w FAfa - 0 9 perft 1 28 perft 2 755 @@ -5940,7 +5941,7 @@ perft 4 605106 perft 5 18972778 perft 6 513486101 -id 1 +id 660 epd r1b1krnq/pp2pppp/1bn5/2pp4/4N3/5P2/PPPPPRPP/R1BBK1NQ w Afa - 0 9 perft 1 24 perft 2 705 @@ -5949,7 +5950,7 @@ perft 4 532521 perft 5 13532966 perft 6 426443376 -id 1 +id 661 epd 1nbkrbn1/rpppppqp/p7/6p1/4P3/3P2P1/PPP1KP1P/RNB1RBNQ w e - 1 9 perft 1 31 perft 2 800 @@ -5958,7 +5959,7 @@ perft 4 693366 perft 5 21193292 perft 6 625757852 -id 1 +id 662 epd r1bkrnqb/pp3ppp/n1ppp3/8/1P5P/P7/R1PPPPP1/1NBKRNQB w Eea - 0 9 perft 1 21 perft 2 482 @@ -5967,7 +5968,7 @@ perft 4 275339 perft 5 7112890 perft 6 180378139 -id 1 +id 663 epd rbnkbrnq/ppp1p2p/5p2/3p2p1/1B1P4/1N4P1/PPP1PP1P/RB1K1RNQ w FAfa - 0 9 perft 1 33 perft 2 780 @@ -5976,7 +5977,7 @@ perft 4 628945 perft 5 20756770 perft 6 535497008 -id 1 +id 664 epd rnk1brnq/pp1ppppp/2p5/b7/8/1P2P2P/P1PP1PPQ/RNKBBRN1 w FAfa - 3 9 perft 1 29 perft 2 648 @@ -5985,7 +5986,7 @@ perft 4 449637 perft 5 13722785 perft 6 341389148 -id 1 +id 665 epd rnkrbbnq/p1p3pp/5p2/1p1pp3/P7/1PN2P2/2PPP1PP/R1KRBBNQ w DAda - 0 9 perft 1 26 perft 2 827 @@ -5994,7 +5995,7 @@ perft 4 683167 perft 5 18916370 perft 6 589161126 -id 1 +id 666 epd r1krbnqb/p1pp1ppp/2n1p3/8/1p4P1/PPP5/3PPP1P/RNKRBNQB w DAda - 1 9 perft 1 25 perft 2 540 @@ -6003,7 +6004,7 @@ perft 4 331332 perft 5 9491817 perft 6 225389422 -id 1 +id 667 epd rbnkrnbq/ppp1pp2/3p2p1/2N5/P6p/2P5/1P1PPPPP/RB1KRNBQ w EAea - 0 9 perft 1 32 perft 2 790 @@ -6012,7 +6013,7 @@ perft 4 661207 perft 5 20906017 perft 6 578332225 -id 1 +id 668 epd rnkbrn1q/1ppppppb/8/p4N1p/8/P1N5/1PPPPPPP/R1KBR1BQ w EAea - 0 9 perft 1 31 perft 2 691 @@ -6021,7 +6022,7 @@ perft 4 510665 perft 5 15308408 perft 6 404129987 -id 1 +id 669 epd rnkrnbbq/p1p2ppp/3pp3/1p6/6P1/4PQ1B/PPPP1P1P/RNKRN1B1 w DAda - 0 9 perft 1 29 perft 2 558 @@ -6030,7 +6031,7 @@ perft 4 352887 perft 5 10825379 perft 6 246965507 -id 1 +id 670 epd rnkrnqbb/pp2p1p1/3p3p/2p2p2/5P2/1P1N4/P1PPPQPP/RNKR2BB w DAda - 0 9 perft 1 29 perft 2 762 @@ -6039,7 +6040,7 @@ perft 4 644936 perft 5 20522675 perft 6 596067005 -id 1 +id 671 epd bb1rknnr/ppqppppp/8/2p5/3P1N2/1P6/P1P1PPPP/BBQRKN1R w HDhd - 1 9 perft 1 33 perft 2 963 @@ -6048,7 +6049,7 @@ perft 4 1000890 perft 5 34552118 perft 6 1124738493 -id 1 +id 672 epd bqrbknnr/ppp1p2p/8/3p1p2/5p2/P3N2P/1PPPP1P1/BQRBK1NR w HChc - 0 9 perft 1 20 perft 2 398 @@ -6057,7 +6058,7 @@ perft 4 194859 perft 5 4834319 perft 6 113660536 -id 1 +id 673 epd b1rk1bnr/qpp1pppp/p4n2/3p4/3PPP2/7N/PPP3PP/BQRKNB1R w HChc - 1 9 perft 1 25 perft 2 648 @@ -6066,7 +6067,7 @@ perft 4 455720 perft 5 12200870 perft 6 351766307 -id 1 +id 674 epd bqkrnnrb/pppp2p1/4pp2/4P2p/6P1/7P/PPPP1P2/BQRKNNRB w GC - 1 9 perft 1 30 perft 2 493 @@ -6075,7 +6076,7 @@ perft 4 280726 perft 5 8786998 perft 6 181492621 -id 1 +id 675 epd q1brknnr/1p1ppppp/p7/2p5/8/1PPP4/P2RPPPP/QBB1KNNR w Hhd - 0 9 perft 1 25 perft 2 501 @@ -6084,7 +6085,7 @@ perft 4 290463 perft 5 7982978 perft 6 192717198 -id 1 +id 676 epd qrb1k1nr/ppppb1pp/6n1/4ppN1/3P4/4N3/PPP1PPPP/QRBBK2R w HBhb - 2 9 perft 1 31 perft 2 872 @@ -6093,7 +6094,7 @@ perft 4 739276 perft 5 22493014 perft 6 646855304 -id 1 +id 677 epd 1rbknbnr/1ppp1pp1/q6p/p3p3/5P2/2PPB3/PP2P1PP/QR1KNBNR w HBhb - 0 9 perft 1 28 perft 2 1020 @@ -6102,7 +6103,7 @@ perft 4 984000 perft 5 27484692 perft 6 947786800 -id 1 +id 678 epd qrbk2rb/1ppp1ppp/5nn1/p3p3/1N6/P7/1PPPPPPP/QRB1KNRB w gb - 0 9 perft 1 23 perft 2 592 @@ -6111,7 +6112,7 @@ perft 4 395716 perft 5 10098215 perft 6 293988585 -id 1 +id 679 epd qbrk1nnr/1pp1pppp/2b5/p2p4/P2P2P1/8/1PP1PP1P/QBKRBNNR w hc - 1 9 perft 1 26 perft 2 654 @@ -6120,7 +6121,7 @@ perft 4 471653 perft 5 13740891 perft 6 373081138 -id 1 +id 680 epd qrkbbnnr/ppp2p1p/4p3/3p2p1/P7/2PP4/1P2PPPP/QRKBBNNR w HBhb - 0 9 perft 1 25 perft 2 626 @@ -6129,7 +6130,7 @@ perft 4 431634 perft 5 12079406 perft 6 324006164 -id 1 +id 681 epd qr1kbbnr/ppp1pp1p/4n1p1/2Pp4/6P1/4N3/PP1PPP1P/QRK1BBNR w HB d6 0 9 perft 1 26 perft 2 699 @@ -6138,7 +6139,7 @@ perft 4 497152 perft 5 13353359 perft 6 375702908 -id 1 +id 682 epd qrk1b1rb/p1pppppp/3nnQ2/1p6/1P3P2/3P4/P1P1P1PP/1RKNBNRB w GBgb - 3 9 perft 1 43 perft 2 1369 @@ -6147,7 +6148,7 @@ perft 4 1831200 perft 5 71514365 perft 6 2427477375 -id 1 +id 683 epd qbrk1nbr/pppp3p/5n2/4ppp1/3P1P2/4N3/PPP1P1PP/QBKRN1BR w hc - 0 9 perft 1 25 perft 2 752 @@ -6156,7 +6157,7 @@ perft 4 615263 perft 5 17493373 perft 6 543180234 -id 1 +id 684 epd qrkb1nbr/1pppppQp/3n4/p7/5p2/1P1N4/P1PPP1PP/1RKB1NBR w HBhb - 0 9 perft 1 45 perft 2 946 @@ -6165,7 +6166,7 @@ perft 4 966903 perft 5 39736157 perft 6 1051910977 -id 1 +id 685 epd qrk1nbbr/ppp1p1p1/4n2p/3p1p2/1P5P/3P2P1/P1P1PP2/QRKNNBBR w HBhb - 1 9 perft 1 32 perft 2 770 @@ -6174,7 +6175,7 @@ perft 4 646977 perft 5 21717615 perft 6 577979364 -id 1 +id 686 epd qrkn1rbb/pp2pppp/2p5/3p4/P2Qn1P1/1P6/2PPPP1P/1RKNNRBB w FBfb - 0 9 perft 1 38 perft 2 943 @@ -6183,7 +6184,7 @@ perft 4 868165 perft 5 31909835 perft 6 798405123 -id 1 +id 687 epd bbrqknnr/ppp4p/3pp3/5pp1/4PP2/5Q2/PPPP2PP/BBR1KNNR w HChc - 0 9 perft 1 36 perft 2 843 @@ -6192,7 +6193,7 @@ perft 4 758528 perft 5 26828059 perft 6 723306114 -id 1 +id 688 epd 1rqbkn1r/p1p1pppp/1p5n/P2p4/3Pb1P1/8/1PP1PP1P/BRQBKNNR w HBhb - 0 9 perft 1 23 perft 2 778 @@ -6201,7 +6202,7 @@ perft 4 649789 perft 5 17337683 perft 6 579112676 -id 1 +id 689 epd br1knbnr/1qp1pppp/pp1p4/8/8/PP6/2PPPPPP/BRQKNBNR w HBhb - 2 9 perft 1 26 perft 2 697 @@ -6210,7 +6211,7 @@ perft 4 546622 perft 5 15280079 perft 6 473071890 -id 1 +id 690 epd brqk2rb/ppppp1pp/4np2/8/2n5/3P1Q2/PP2PPPP/BR1KNNRB w GBgb - 0 9 perft 1 32 perft 2 948 @@ -6219,7 +6220,7 @@ perft 4 885713 perft 5 29821322 perft 6 874251866 -id 1 +id 691 epd r1bqknnr/pp1pp1p1/5p1p/2p1b2N/2P5/8/PPQPPPPP/RBB1K1NR w HAha - 0 9 perft 1 31 perft 2 785 @@ -6228,7 +6229,7 @@ perft 4 659952 perft 5 22244193 perft 6 592797491 -id 1 +id 692 epd rqbbknnr/ppppp2p/5pp1/8/8/1P3PP1/PQPPP2P/R1BBKNNR w HAha - 0 9 perft 1 23 perft 2 391 @@ -6237,7 +6238,7 @@ perft 4 198450 perft 5 5576671 perft 6 121267576 -id 1 +id 693 epd rqbknbnr/1pp1p2p/p7/3p1pp1/7N/1PP5/P2PPPPP/RQBK1BNR w HAha - 0 9 perft 1 27 perft 2 676 @@ -6246,7 +6247,7 @@ perft 4 522428 perft 5 15955388 perft 6 448477218 -id 1 +id 694 epd rqb1nnrb/2ppkppp/1p2p3/p7/2PPP3/1P6/P4PPP/RQBKNNRB w GA - 1 9 perft 1 31 perft 2 727 @@ -6255,7 +6256,7 @@ perft 4 570647 perft 5 18361051 perft 6 483248153 -id 1 +id 695 epd rb1kbn1r/p1ppppp1/qp5n/7p/P7/RPP5/3PPPPP/1BQKBNNR w Hha - 2 9 perft 1 29 perft 2 837 @@ -6264,7 +6265,7 @@ perft 4 730083 perft 5 21279560 perft 6 682863811 -id 1 +id 696 epd rqkbb1nr/p1p2ppp/1p1p2n1/3Np3/4P3/5N2/PPPP1PPP/RQKBB2R w HAha - 0 9 perft 1 28 perft 2 717 @@ -6273,7 +6274,7 @@ perft 4 550987 perft 5 16347343 perft 6 453153783 -id 1 +id 697 epd rqknbbr1/p1pppp1p/1p3np1/8/4P3/2P2P1P/PP1P2P1/RQKNBBNR w HAa - 0 9 perft 1 27 perft 2 650 @@ -6282,7 +6283,7 @@ perft 4 475303 perft 5 13847463 perft 6 383256006 -id 1 +id 698 epd r1k1bnrb/1qpppppp/1p2n3/p7/1P5P/6P1/P1PPPP2/RQKNBNR1 w GAga - 1 9 perft 1 24 perft 2 806 @@ -6291,7 +6292,7 @@ perft 4 713220 perft 5 19382263 perft 6 686009788 -id 1 +id 699 epd rb1knnbr/1pp1ppp1/p2p3p/5q2/3B2P1/3P1P2/PPP1P2P/RBQKNN1R w HAha - 0 9 perft 1 34 perft 2 1360 @@ -6300,7 +6301,7 @@ perft 4 1605706 perft 5 51973672 perft 6 1837704407 -id 1 +id 700 epd rqkb1nbr/p1p1ppp1/1p3n1p/2Qp4/8/2P5/PP1PPPPP/R1KBNNBR w HAha - 2 9 perft 1 39 perft 2 983 @@ -6309,7 +6310,7 @@ perft 4 940989 perft 5 36347815 perft 6 918801645 -id 1 +id 701 epd rqknnbbr/2pppp2/pp5p/6p1/1P1P4/4PP2/P1P3PP/RQKNNBBR w HAha - 0 9 perft 1 26 perft 2 628 @@ -6318,7 +6319,7 @@ perft 4 464924 perft 5 13787303 perft 6 386125234 -id 1 +id 702 epd rqkn1rbb/1pp1pppp/p7/3p4/3Pn3/2P1PP2/PP4PP/RQKNNRBB w FAfa - 1 9 perft 1 20 perft 2 527 @@ -6327,7 +6328,7 @@ perft 4 321533 perft 5 8082183 perft 6 219311659 -id 1 +id 703 epd bbrkqn1r/1pppppp1/5n2/p7/1PP2P1p/7N/P2PP1PP/BBRKQN1R w HChc - 1 9 perft 1 36 perft 2 963 @@ -6336,7 +6337,7 @@ perft 4 973839 perft 5 35907489 perft 6 1034223364 -id 1 +id 704 epd brkbqn1r/p2ppppp/7n/1p6/P1p3PP/8/1PPPPP1N/BRKBQ1NR w HBhb - 0 9 perft 1 18 perft 2 583 @@ -6345,7 +6346,7 @@ perft 4 394603 perft 5 8858385 perft 6 304339862 -id 1 +id 705 epd brkq1bnr/pp1ppp1p/8/2p2np1/P7/8/1PPPPPPP/BRKQNBNR w HBhb - 0 9 perft 1 19 perft 2 552 @@ -6354,7 +6355,7 @@ perft 4 354260 perft 5 8432183 perft 6 262293169 -id 1 +id 706 epd brkqnnrb/1ppppppp/8/8/p3P3/5N2/PPPP1PPP/BRKQ1NRB w GBgb - 3 9 perft 1 21 perft 2 397 @@ -6363,7 +6364,7 @@ perft 4 204350 perft 5 5489836 perft 6 128389738 -id 1 +id 707 epd rbbkq1nr/1p2pppp/p1p3nB/3p4/1Q1P4/6N1/PPP1PPPP/RB1K2NR w HAha - 0 9 perft 1 40 perft 2 1132 @@ -6372,7 +6373,7 @@ perft 4 1260470 perft 5 47425783 perft 6 1415578783 -id 1 +id 708 epd rkbbq1nr/1pppp1p1/4np2/p6p/8/PP3P2/1KPPP1PP/R1BBQNNR w ha - 0 9 perft 1 24 perft 2 596 @@ -6381,7 +6382,7 @@ perft 4 402121 perft 5 10822049 perft 6 302056813 -id 1 +id 709 epd r1bqn1nr/pkpppp1p/1p4pb/8/PN6/R7/1PPPPPPP/1KBQ1BNR w H - 2 9 perft 1 33 perft 2 794 @@ -6390,7 +6391,7 @@ perft 4 649150 perft 5 20919309 perft 6 561073410 -id 1 +id 710 epd rkb1nnrb/1pppq1pp/p4p2/4p3/5P2/1P1PB3/P1P1P1PP/RK1QNNRB w GAga - 0 9 perft 1 26 perft 2 625 @@ -6399,7 +6400,7 @@ perft 4 442036 perft 5 12515042 perft 6 342967558 -id 1 +id 711 epd rbkqbn1r/pppp1p1p/2n1p1p1/8/8/1P1PP1N1/P1P2PPP/RBKQB1NR w HAha - 1 9 perft 1 30 perft 2 660 @@ -6408,7 +6409,7 @@ perft 4 492714 perft 5 15348335 perft 6 403323883 -id 1 +id 712 epd rkqbb1n1/pppppppr/8/6np/5P2/8/PPPPP1PP/RKQBBNNR w HAa - 6 9 perft 1 23 perft 2 500 @@ -6417,7 +6418,7 @@ perft 4 292936 perft 5 7519117 perft 6 196524441 -id 1 +id 713 epd rkqnbbnr/ppppppp1/8/7p/3N4/6PP/PPPPPP2/RKQNBB1R w HAa - 0 9 perft 1 24 perft 2 484 @@ -6426,7 +6427,7 @@ perft 4 284570 perft 5 7775173 perft 6 193947530 -id 1 +id 714 epd rkqnb1rb/p1p1pppp/1p1p4/2n5/3P4/2P1N1N1/PP2PPPP/RKQ1B1RB w GAga - 0 9 perft 1 28 perft 2 1020 @@ -6435,7 +6436,7 @@ perft 4 1027904 perft 5 30515456 perft 6 1073711823 -id 1 +id 715 epd rbk1nnbr/1ppq1ppp/p2p4/4p3/P3B2P/2P5/1P1PPPP1/R1KQNNBR w HAha - 2 9 perft 1 38 perft 2 998 @@ -6444,7 +6445,7 @@ perft 4 1047592 perft 5 38552638 perft 6 1139322479 -id 1 +id 716 epd r1qbn1br/k1pppppp/6n1/pp6/5P1P/P7/1PPPP1PB/RKQBNN1R w HA - 1 9 perft 1 22 perft 2 549 @@ -6453,7 +6454,7 @@ perft 4 348574 perft 5 8725809 perft 6 251613569 -id 1 +id 717 epd rkqnn1br/pppp3p/4p1pb/5p2/P2P4/7P/1PP1PPPB/RKQNNB1R w HAha - 1 9 perft 1 32 perft 2 659 @@ -6462,7 +6463,7 @@ perft 4 469701 perft 5 15434721 perft 6 365761521 -id 1 +id 718 epd rk1nnrbb/p1p1pppp/1p6/3p1q2/P3P3/2NN4/1PPP1PPP/RKQ2RBB w FAfa - 3 9 perft 1 29 perft 2 989 @@ -6471,7 +6472,7 @@ perft 4 980477 perft 5 29643404 perft 6 998848556 -id 1 +id 719 epd bbrk1q1r/ppppppp1/3n4/7p/3Pn3/6PN/PPP1PPNP/BBRK1Q1R w HChc - 2 9 perft 1 23 perft 2 712 @@ -6480,7 +6481,7 @@ perft 4 516177 perft 5 12995202 perft 6 411077508 -id 1 +id 720 epd brkbnq1r/p1ppp2p/5ppn/1p6/5P2/1P1P2P1/P1P1P2P/BRKBNQNR w HBhb - 0 9 perft 1 28 perft 2 856 @@ -6489,7 +6490,7 @@ perft 4 780503 perft 5 23529352 perft 6 754501112 -id 1 +id 721 epd br1k1bnr/ppppp1pp/4np2/1B2P2q/3P4/8/PPP2PPP/BRKNQ1NR w HB - 3 9 perft 1 36 perft 2 1214 @@ -6498,7 +6499,7 @@ perft 4 1328331 perft 5 45096834 perft 6 1470987023 -id 1 +id 722 epd brk1qnrb/pnppp1p1/1p6/5p1p/8/5PPP/PPPPP1R1/BRKNQN1B w Bgb - 0 9 perft 1 22 perft 2 551 @@ -6507,7 +6508,7 @@ perft 4 353317 perft 5 9040545 perft 6 259643605 -id 1 +id 723 epd rbbkn1nr/1ppp2pp/p3p3/2q2p2/3P4/6P1/PPPBPP1P/RB1KNQNR w HAha - 0 9 perft 1 31 perft 2 1060 @@ -6516,7 +6517,7 @@ perft 4 1015099 perft 5 30314172 perft 6 976268967 -id 1 +id 724 epd rkbbn1nr/ppppp1pp/8/6N1/5p2/1q6/P1PPPPPP/RKBBN1QR w HAha - 0 9 perft 1 3 perft 2 72 @@ -6525,7 +6526,7 @@ perft 4 50827 perft 5 1400832 perft 6 39654253 -id 1 +id 725 epd rkb2bnr/pp2pppp/2p1n3/3p4/q2P4/5NP1/PPP1PP1P/RKBNQBR1 w Aha - 0 9 perft 1 29 perft 2 861 @@ -6534,7 +6535,7 @@ perft 4 763454 perft 5 22763215 perft 6 731511256 -id 1 +id 726 epd rkbq1nrb/ppppppp1/7p/8/1P1n4/P4P1P/2PPP1P1/RKBNQNRB w GAga - 0 9 perft 1 25 perft 2 672 @@ -6543,7 +6544,7 @@ perft 4 473864 perft 5 12954224 perft 6 361237536 -id 1 +id 727 epd rbknb1nr/ppp1qp1p/6p1/3pp3/3P3P/2B1P3/PPP2PP1/RBKN1QNR w HAha - 1 9 perft 1 27 perft 2 857 @@ -6552,7 +6553,7 @@ perft 4 792538 perft 5 23790033 perft 6 768247869 -id 1 +id 728 epd rknbbq1r/p1pppppp/1p2N3/8/3n4/2P5/PP1PPPPP/RK1BBQNR w HAha - 4 9 perft 1 29 perft 2 763 @@ -6561,7 +6562,7 @@ perft 4 574054 perft 5 16926075 perft 6 447896703 -id 1 +id 729 epd r1nqbbnr/1pppp1pp/1k6/p4p2/8/4P3/PPPP1PPP/RKN1BBNR w HA - 0 9 perft 1 26 perft 2 658 @@ -6570,7 +6571,7 @@ perft 4 464039 perft 5 12380488 perft 6 349047256 -id 1 +id 730 epd rkn2qrb/ppp1pppp/6n1/1b1p4/1P6/4PPB1/P1PP2PP/RKNQ1NRB w GAga - 3 9 perft 1 23 perft 2 574 @@ -6579,7 +6580,7 @@ perft 4 370324 perft 5 9501401 perft 6 263870337 -id 1 +id 731 epd rbkn2br/ppppp1p1/4np1p/1P5q/8/2P1N3/P2PPPPP/RBK1QNBR w HAha - 1 9 perft 1 29 perft 2 992 @@ -6588,7 +6589,7 @@ perft 4 999564 perft 5 30148787 perft 6 1045942540 -id 1 +id 732 epd 1knbqnbr/1ppppp1p/r5p1/p7/7P/2PN2P1/PP1PPP2/RK1BQNBR w HAh - 2 9 perft 1 26 perft 2 698 @@ -6597,7 +6598,7 @@ perft 4 512023 perft 5 14848229 perft 6 402599313 -id 1 +id 733 epd rk1qnbbr/pnpppp1p/6p1/1p6/3P4/1P6/P1P1PPPP/RKNQNBBR w HAha - 1 9 perft 1 20 perft 2 480 @@ -6606,7 +6607,7 @@ perft 4 287539 perft 5 7425917 perft 6 203194521 -id 1 +id 734 epd rknqnrbb/pp1p2p1/5p1p/2p1p3/2P1P3/P2P4/1P3PPP/RKNQNRBB w FAfa - 0 9 perft 1 26 perft 2 679 @@ -6615,7 +6616,7 @@ perft 4 494953 perft 5 13790137 perft 6 392629571 -id 1 +id 735 epd bbrk2qr/pp1p1ppp/3n2n1/2p1p3/3P1P2/6N1/PPP1P1PP/BBRKN1QR w HChc - 0 9 perft 1 26 perft 2 790 @@ -6624,7 +6625,7 @@ perft 4 673269 perft 5 19259490 perft 6 617563700 -id 1 +id 736 epd b1krnnqr/1p1ppppp/p1p5/b6B/P7/4P1N1/1PPP1PPP/BRK1N1QR w HB - 2 9 perft 1 26 perft 2 625 @@ -6633,7 +6634,7 @@ perft 4 415452 perft 5 11490615 perft 6 304805107 -id 1 +id 737 epd 1rknnbqr/3ppppp/p7/1pp5/4b2P/P4P2/1PPPP1PR/BRKNNBQ1 w Bhb - 1 9 perft 1 24 perft 2 757 @@ -6642,7 +6643,7 @@ perft 4 618777 perft 5 17275100 perft 6 544309489 -id 1 +id 738 epd br1nn1rb/pppkpqpp/3p1p2/8/PP6/4N3/1KPPPPPP/BR2NQRB w - - 3 9 perft 1 24 perft 2 682 @@ -6651,7 +6652,7 @@ perft 4 482711 perft 5 13057308 perft 6 375033550 -id 1 +id 739 epd rbbkn1qr/pppp2p1/6np/4pp2/7N/7P/PPPPPPPR/RBBK1NQ1 w Aha - 0 9 perft 1 22 perft 2 586 @@ -6660,7 +6661,7 @@ perft 4 409891 perft 5 10607781 perft 6 324452612 -id 1 +id 740 epd rk1bn1qr/pppbpppp/4n3/4p3/4P3/5P2/PPPP2PP/RKBB1NQR w HAha - 1 9 perft 1 22 perft 2 530 @@ -6669,7 +6670,7 @@ perft 4 348004 perft 5 9514787 perft 6 259898748 -id 1 +id 741 epd rkbnnbqr/1ppp1ppp/p7/4p3/8/QP3P2/P1PPP1PP/RKBNNB1R w HAha - 0 9 perft 1 29 perft 2 705 @@ -6678,7 +6679,7 @@ perft 4 551042 perft 5 17524731 perft 6 472356665 -id 1 +id 742 epd 1kbnnqrb/1pp1p1pp/r4p2/p2p4/N4P2/3P4/PPP1P1PP/RKB1NQRB w GAg - 2 9 perft 1 21 perft 2 623 @@ -6687,7 +6688,7 @@ perft 4 437554 perft 5 11601134 perft 6 343214006 -id 1 +id 743 epd rbknbn1r/pppp1p1p/4p1q1/8/P1P3Pp/8/1P1PPP2/RBKNBNQR w HAha - 0 9 perft 1 30 perft 2 813 @@ -6696,7 +6697,7 @@ perft 4 708454 perft 5 23379040 perft 6 692576573 -id 1 +id 744 epd rk1bb1qr/2pppppp/p2nn3/1p4P1/6QP/8/PPPPPP2/RKNBBN1R w HAha - 2 9 perft 1 36 perft 2 857 @@ -6705,7 +6706,7 @@ perft 4 757524 perft 5 26485812 perft 6 696999449 -id 1 +id 745 epd rkn1bbqr/p2ppppp/2p1n3/1p6/4PP2/6PP/PPPP4/RKNNBBQR w HAha - 0 9 perft 1 33 perft 2 687 @@ -6714,7 +6715,7 @@ perft 4 511018 perft 5 17101732 perft 6 412778368 -id 1 +id 746 epd rkn1bqrb/pnp1pppp/3p4/8/Pp6/1N2NP2/1PPPP1PP/RK2BQRB w GAga - 0 9 perft 1 28 perft 2 591 @@ -6723,7 +6724,7 @@ perft 4 406025 perft 5 12182448 perft 6 312575205 -id 1 +id 747 epd rbk1n1br/ppp1ppqp/2n5/2Np2p1/8/2P5/PPBPPPPP/R1KN1QBR w HAha - 4 9 perft 1 35 perft 2 930 @@ -6732,7 +6733,7 @@ perft 4 844433 perft 5 27160490 perft 6 780616047 -id 1 +id 748 epd rknbn1br/1ppp1ppp/p3p3/8/1q6/2P2N1P/P2PPPP1/RKNB1QBR w HAha - 0 9 perft 1 4 perft 2 157 @@ -6741,7 +6742,7 @@ perft 4 138102 perft 5 3454704 perft 6 125373395 -id 1 +id 749 epd rkn1qbbr/pp3ppp/4n3/2ppp3/4P1P1/P2P4/1PP2P1P/RKNNQBBR w HAha - 0 9 perft 1 28 perft 2 840 @@ -6750,7 +6751,7 @@ perft 4 771328 perft 5 23200961 perft 6 756489357 -id 1 +id 750 epd rkn1qrbb/pp1ppp2/2p1n1p1/7p/2P2P1P/6P1/PP1PP3/RKNNQRBB w FAfa - 1 9 perft 1 32 perft 2 867 @@ -6759,7 +6760,7 @@ perft 4 757836 perft 5 24485663 perft 6 688115847 -id 1 +id 751 epd b1rknnrq/bpppp1p1/p6p/5p1P/6P1/4N3/PPPPPP2/BBRKN1RQ w GCgc - 1 9 perft 1 33 perft 2 851 @@ -6768,7 +6769,7 @@ perft 4 763967 perft 5 26686205 perft 6 731944177 -id 1 +id 752 epd brkb1nr1/pppppp2/3n2pp/3B4/1P6/4P3/PqPP1PPP/BRK1NNRQ w GBgb - 2 9 perft 1 4 perft 2 98 @@ -6777,7 +6778,7 @@ perft 4 76143 perft 5 2352530 perft 6 64251468 -id 1 +id 753 epd brk1nbrq/1ppppn1p/6p1/p4p2/P5P1/5R2/1PPPPP1P/BRKNNB1Q w Bgb - 0 9 perft 1 29 perft 2 922 @@ -6786,7 +6787,7 @@ perft 4 879527 perft 5 27463717 perft 6 888881062 -id 1 +id 754 epd brkn1rqb/1p1ppppp/3n4/p1p5/1P3P2/8/PNPPP1PP/BR1KNRQB w fb - 1 9 perft 1 29 perft 2 633 @@ -6795,7 +6796,7 @@ perft 4 469818 perft 5 15076198 perft 6 396737074 -id 1 +id 755 epd rb1k1nrq/pbp1pppp/1p1p1n2/8/5P2/4NN1P/PPPPP1P1/RBBK2RQ w GAga - 2 9 perft 1 28 perft 2 841 @@ -6804,7 +6805,7 @@ perft 4 710751 perft 5 20772996 perft 6 613798447 -id 1 +id 756 epd rkbbnnrq/p1pp3p/4p1p1/1p3p2/P6P/1P6/1BPPPPP1/RK1BNNRQ w GAga - 0 9 perft 1 33 perft 2 957 @@ -6813,7 +6814,7 @@ perft 4 907217 perft 5 29735654 perft 6 903933626 -id 1 +id 757 epd rk2nbrq/p1ppppp1/bpn5/7p/6P1/2N2P2/PPPPP1QP/RKB1NBR1 w GAga - 2 9 perft 1 24 perft 2 687 @@ -6822,7 +6823,7 @@ perft 4 544627 perft 5 15518417 perft 6 484217179 -id 1 +id 758 epd rkbn1r1b/pp1pppnp/6q1/2p3p1/5P1P/4N3/PPPPP1P1/RKB1NRQB w FAfa - 1 9 perft 1 23 perft 2 831 @@ -6831,7 +6832,7 @@ perft 4 754622 perft 5 21126103 perft 6 744755212 -id 1 +id 759 epd rbknb1rq/ppp1p1p1/3pnp1p/8/6PP/2PP4/PP2PP2/RBKNBNRQ w GAga - 0 9 perft 1 31 perft 2 838 @@ -6840,7 +6841,7 @@ perft 4 736910 perft 5 24008129 perft 6 677776408 -id 1 +id 760 epd rknbb1rq/p1pn1ppp/4p3/1p1p4/2P5/1P2N1P1/P2PPP1P/RKNBB1RQ w GAga - 1 9 perft 1 29 perft 2 830 @@ -6849,7 +6850,7 @@ perft 4 721630 perft 5 22243832 perft 6 660040360 -id 1 +id 761 epd rk1nbbrq/pp1p1ppp/3n4/P3p3/2p4P/8/1PPPPPP1/RKNNBBRQ w GAga - 1 9 perft 1 24 perft 2 484 @@ -6858,7 +6859,7 @@ perft 4 297419 perft 5 8379748 perft 6 214004367 -id 1 +id 762 epd rknnbr1b/ppp2pqp/3p4/4p1p1/7P/3P1P2/PPP1P1P1/RKNNBRQB w FAfa - 0 9 perft 1 32 perft 2 838 @@ -6867,7 +6868,7 @@ perft 4 740701 perft 5 23472124 perft 6 699211365 -id 1 +id 763 epd rb1k1rbq/ppppN1pp/2nn4/5p2/7P/8/PPPPPPP1/RBK1NRBQ w FA - 1 9 perft 1 27 perft 2 800 @@ -6876,7 +6877,7 @@ perft 4 701742 perft 5 20804424 perft 6 660917073 -id 1 +id 764 epd r1nbnrbq/kppppp1p/6p1/8/p1PP1P2/4P3/PP4PP/RKNBNRBQ w FA - 1 9 perft 1 28 perft 2 757 @@ -6885,7 +6886,7 @@ perft 4 602699 perft 5 17180857 perft 6 507618340 -id 1 +id 765 epd rkn1rbbq/p1pppppp/2n5/1pP5/8/1N2P3/PP1P1PPP/RK1NRBBQ w EAea - 1 9 perft 1 22 perft 2 483 @@ -6894,7 +6895,7 @@ perft 4 283679 perft 5 7497674 perft 6 191130942 -id 1 +id 766 epd rknnrqbb/2pppppp/8/p7/Np3P2/3P4/PPP1P1PP/RKN1RQBB w EAea - 0 9 perft 1 25 perft 2 536 @@ -6903,7 +6904,7 @@ perft 4 339180 perft 5 9694947 perft 6 245669668 -id 1 +id 767 epd bb1rknrn/1qppppp1/1p4B1/p6N/8/2P5/PP1PPPPP/B1QRK1RN w GDgd - 1 9 perft 1 32 perft 2 715 @@ -6912,7 +6913,7 @@ perft 4 575008 perft 5 17860156 perft 6 502410909 -id 1 +id 768 epd b1rbknrn/qpp1ppp1/p6p/3p4/2P5/1P1P1P2/P3P1PP/BQRBKNRN w GCgc - 0 9 perft 1 30 perft 2 818 @@ -6921,7 +6922,7 @@ perft 4 688711 perft 5 20981488 perft 6 611986786 -id 1 +id 769 epd bqkrnbrn/1pp1pp1p/p7/1B1p2p1/4P3/7P/PPPP1PP1/BQKRN1RN w - - 0 9 perft 1 28 perft 2 676 @@ -6930,7 +6931,7 @@ perft 4 478054 perft 5 13126287 perft 6 363765666 -id 1 +id 770 epd bqrknrnb/1p2ppp1/p1pp3p/8/3P1P2/1PP5/P3P1PP/BQRKNRNB w FCfc - 0 9 perft 1 31 perft 2 646 @@ -6939,7 +6940,7 @@ perft 4 455607 perft 5 14984618 perft 6 349082278 -id 1 +id 771 epd qbbrkn1r/pppppp1p/8/6p1/2P1Pn1P/6N1/PP1P1PP1/QBBRKNR1 w GDd - 3 9 perft 1 20 perft 2 532 @@ -6948,7 +6949,7 @@ perft 4 303586 perft 5 7512432 perft 6 202967948 -id 1 +id 772 epd 1rbbknr1/p1ppp1pp/1pq2pn1/8/3P4/P3P3/QPP2PPP/1RBBKNRN w GBgb - 3 9 perft 1 31 perft 2 1002 @@ -6957,7 +6958,7 @@ perft 4 999607 perft 5 30642468 perft 6 1009228283 -id 1 +id 773 epd qrbkn1rn/pppp1ppp/8/6b1/P1P1Pp2/8/1P1P2PP/QRBKNBRN w GBgb - 0 9 perft 1 22 perft 2 505 @@ -6966,7 +6967,7 @@ perft 4 304863 perft 5 8192621 perft 6 214730959 -id 1 +id 774 epd qrbk1rnb/p2ppp1p/5n2/1pp3p1/8/7P/PPPPPPPN/QRBKR1NB w Bfb - 0 9 perft 1 20 perft 2 619 @@ -6975,7 +6976,7 @@ perft 4 449630 perft 5 10571176 perft 6 369603424 -id 1 +id 775 epd qbrkb1r1/ppp2ppp/3pn1n1/P3p3/4P3/3P4/1PP2PPP/QBRKBNRN w GCgc - 1 9 perft 1 26 perft 2 755 @@ -6984,7 +6985,7 @@ perft 4 604483 perft 5 17164382 perft 6 510878835 -id 1 +id 776 epd qrkbb1r1/ppp1pnpp/3p2n1/5p2/1P3P2/2Q3N1/P1PPP1PP/1RKBB1RN w GBgb - 0 9 perft 1 35 perft 2 918 @@ -6993,7 +6994,7 @@ perft 4 870888 perft 5 30933394 perft 6 867833733 -id 1 +id 777 epd qrknbbrn/ppp1ppp1/8/7p/2Bp4/4PPP1/PPPP3P/QRKNB1RN w GBgb - 0 9 perft 1 27 perft 2 593 @@ -7002,7 +7003,7 @@ perft 4 376808 perft 5 10422676 perft 6 258348640 -id 1 +id 778 epd qrk1brnb/ppppp3/4n2p/5pp1/2PP4/2N4P/PP2PPP1/QRK1BRNB w FBfb - 2 9 perft 1 24 perft 2 672 @@ -7011,7 +7012,7 @@ perft 4 506189 perft 5 13765777 perft 6 414930519 -id 1 +id 779 epd qbrknrb1/p2ppppp/2p3n1/8/p4P2/6PP/1PPPP3/QBRKNRBN w FCfc - 0 9 perft 1 29 perft 2 759 @@ -7020,7 +7021,7 @@ perft 4 634493 perft 5 20416668 perft 6 584870558 -id 1 +id 780 epd 1rkb1rbn/p1pp1ppp/3np3/1p6/4qP2/3NB3/PPPPPRPP/QRKB3N w Bfb - 0 9 perft 1 22 perft 2 923 @@ -7029,7 +7030,7 @@ perft 4 914106 perft 5 24049880 perft 6 957218571 -id 1 +id 781 epd 1rknrbbn/p1pp1p1p/8/1p2p1p1/4qPP1/2P5/PP1PP1BP/QRKNR1BN w EBeb - 0 9 perft 1 28 perft 2 1309 @@ -7038,7 +7039,7 @@ perft 4 1568968 perft 5 44576409 perft 6 1846382333 -id 1 +id 782 epd qrk1rn1b/ppppp2p/4n3/3b1pp1/4P2P/5BP1/PPPP1P2/QRKNRNB1 w EBeb - 3 9 perft 1 26 perft 2 839 @@ -7047,7 +7048,7 @@ perft 4 726354 perft 5 19978260 perft 6 661207281 -id 1 +id 783 epd bbrqk1rn/pp1ppppp/8/2p5/2P1P3/5n1P/PPBP1PP1/B1RQKNRN w GCgc - 1 9 perft 1 3 perft 2 95 @@ -7056,7 +7057,7 @@ perft 4 85038 perft 5 2518864 perft 6 80775549 -id 1 +id 784 epd brqbk2n/pppppprp/8/6p1/1P3n2/5P2/P1PPP1PP/R1QBKNRN w Gb - 2 9 perft 1 22 perft 2 593 @@ -7065,7 +7066,7 @@ perft 4 362760 perft 5 8922397 perft 6 253271592 -id 1 +id 785 epd brqknbr1/pp3ppp/3p2n1/2p1p3/2P5/5P2/PPKPP1PP/BRQ1NBRN w gb - 0 9 perft 1 21 perft 2 590 @@ -7074,7 +7075,7 @@ perft 4 397355 perft 5 9581695 perft 6 304103516 -id 1 +id 786 epd 1rqknrnb/2pp1ppp/p3p3/1p6/P2P4/5bP1/1PP1PP1P/BRQKNRNB w FBfb - 0 9 perft 1 24 perft 2 737 @@ -7083,7 +7084,7 @@ perft 4 598439 perft 5 17948681 perft 6 536330341 -id 1 +id 787 epd rbb1k1rn/p1pqpppp/6n1/1p1p4/5P2/3PP3/PPP1K1PP/RBBQ1NRN w ga - 3 9 perft 1 24 perft 2 694 @@ -7092,7 +7093,7 @@ perft 4 513782 perft 5 13094823 perft 6 419402704 -id 1 +id 788 epd rqbbknr1/1ppp2pp/p5n1/4pp2/P7/1PP5/1Q1PPPPP/R1BBKNRN w GAga - 0 9 perft 1 24 perft 2 600 @@ -7101,7 +7102,7 @@ perft 4 408207 perft 5 11029596 perft 6 308553169 -id 1 +id 789 epd rqbknbrn/2pppppp/6Q1/pp6/8/2P5/PP1PPPPP/R1BKNBRN w GAga - 2 9 perft 1 40 perft 2 949 @@ -7110,7 +7111,7 @@ perft 4 889887 perft 5 31296485 perft 6 881529007 -id 1 +id 790 epd rqbknr1b/pp1ppp2/2p2n1p/6p1/8/3P1PPP/PPP1P3/RQBKNRNB w FAfa - 0 9 perft 1 20 perft 2 560 @@ -7119,7 +7120,7 @@ perft 4 373921 perft 5 8687544 perft 6 277906201 -id 1 +id 791 epd rbqkbnrn/p3pppp/1p6/3p4/P1p3P1/1P6/1QPPPP1P/RB1KBNRN w GAga - 0 9 perft 1 30 perft 2 1155 @@ -7128,7 +7129,7 @@ perft 4 1351455 perft 5 43092716 perft 6 1614019629 -id 1 +id 792 epd rqkbb1rn/p1p1pppn/1p1p4/7p/4PP2/7P/PPPPB1P1/RQK1BNRN w GAga - 1 9 perft 1 30 perft 2 701 @@ -7137,7 +7138,7 @@ perft 4 515942 perft 5 15450970 perft 6 401499189 -id 1 +id 793 epd rqknbbrn/1p2pp1p/3p2p1/p1p5/P2P4/1P6/1KP1PPPP/RQ1NBBRN w ga - 0 9 perft 1 28 perft 2 756 @@ -7146,7 +7147,7 @@ perft 4 610320 perft 5 17989811 perft 6 525585996 -id 1 +id 794 epd rqknbrnb/1pp3pp/5p2/p2pp3/P7/3PPN2/1PP2PPP/RQKNBR1B w FAfa - 0 9 perft 1 26 perft 2 731 @@ -7155,7 +7156,7 @@ perft 4 550395 perft 5 15209404 perft 6 439767476 -id 1 +id 795 epd rbqkr1bn/p1pppp1p/1p1n4/6p1/7P/3P1PP1/PPP1P3/RBQKNRBN w FAa - 0 9 perft 1 27 perft 2 586 @@ -7164,7 +7165,7 @@ perft 4 381604 perft 5 10905865 perft 6 274364342 -id 1 +id 796 epd rqk1nrb1/ppbp1ppp/4p1n1/2p5/7P/1PP5/P2PPPP1/RQKBNRBN w FAfa - 1 9 perft 1 27 perft 2 749 @@ -7173,7 +7174,7 @@ perft 4 602318 perft 5 18084787 perft 6 520547029 -id 1 +id 797 epd rqknrbbn/pp1p1ppp/4p3/2p5/3P2P1/7P/PPP1PP2/RQKNRBBN w EAa - 0 9 perft 1 20 perft 2 533 @@ -7182,7 +7183,7 @@ perft 4 336248 perft 5 8230417 perft 6 245871540 -id 1 +id 798 epd rqknrnbb/pp1ppp1p/2p3p1/8/8/1P2P1NP/P1PP1PP1/RQKNR1BB w EAea - 0 9 perft 1 22 perft 2 633 @@ -7191,7 +7192,7 @@ perft 4 441877 perft 5 10827868 perft 6 343525739 -id 1 +id 799 epd 1brkq1rn/2pppppp/1p2n3/p2bN3/8/7P/PPPPPPP1/BBRKQ1RN w GCgc - 2 9 perft 1 27 perft 2 748 @@ -7200,7 +7201,7 @@ perft 4 580054 perft 5 16010135 perft 6 475206624 -id 1 +id 800 epd brkbqnrn/2pp1ppp/8/1p2p3/Pp2N3/8/2PPPPPP/BRKBQNR1 w GBgb - 0 9 perft 1 30 perft 2 827 @@ -7209,7 +7210,7 @@ perft 4 757837 perft 5 23746165 perft 6 751690068 -id 1 +id 801 epd brk1nbrn/pp1ppppp/2p5/7P/5P2/q2P4/PPP1P1P1/BRKQNBRN w GBgb - 1 9 perft 1 15 perft 2 471 @@ -7218,7 +7219,7 @@ perft 4 276424 perft 5 5960901 perft 6 190316951 -id 1 +id 802 epd brkqnrnb/1p1pp1p1/p4p2/2p4p/8/P2PP3/1PP1QPPP/BRK1NRNB w FBfb - 0 9 perft 1 24 perft 2 479 @@ -7227,7 +7228,7 @@ perft 4 280081 perft 5 7830230 perft 6 190419716 -id 1 +id 803 epd rbbkqnrn/2ppp2p/pp3p2/6p1/P6P/8/RPPPPPP1/1BBKQNRN w Gga - 0 9 perft 1 21 perft 2 523 @@ -7236,7 +7237,7 @@ perft 4 328733 perft 5 8322614 perft 6 242240658 -id 1 +id 804 epd rkbbqr1n/1ppppppn/7p/p7/4P3/2P2P2/PP1PB1PP/RKB1QNRN w GAa - 3 9 perft 1 27 perft 2 563 @@ -7245,7 +7246,7 @@ perft 4 372148 perft 5 11105151 perft 6 283211800 -id 1 +id 805 epd rkbqnbrn/ppppp3/8/5ppp/2P3P1/7P/PPQPPP2/RKB1NBRN w GAga - 0 9 perft 1 28 perft 2 639 @@ -7254,7 +7255,7 @@ perft 4 469250 perft 5 14872172 perft 6 384663405 -id 1 +id 806 epd rkb1nrnb/pppp1pp1/5q1p/8/P3p3/4R1P1/1PPPPP1P/1KBQNRNB w Ffa - 0 9 perft 1 28 perft 2 873 @@ -7263,7 +7264,7 @@ perft 4 720814 perft 5 20209424 perft 6 625281937 -id 1 +id 807 epd rbkqb1rn/1p1ppppp/4n3/p1p5/8/3PBP2/PPP1P1PP/RBKQ1NRN w GAga - 0 9 perft 1 26 perft 2 798 @@ -7272,7 +7273,7 @@ perft 4 667496 perft 5 18475618 perft 6 591681956 -id 1 +id 808 epd rk1qbnrn/1p1ppppp/1b6/p1p5/P7/2P3NP/1P1PPPP1/RKQBB1RN w GAga - 0 9 perft 1 22 perft 2 506 @@ -7281,7 +7282,7 @@ perft 4 301029 perft 5 7891676 perft 6 205739580 -id 1 +id 809 epd rk1nbbrn/ppp1ppp1/8/3p3p/1P1P2q1/5PB1/P1P1P1PP/RKQN1BRN w GAga - 1 9 perft 1 31 perft 2 956 @@ -7290,7 +7291,7 @@ perft 4 903799 perft 5 27827461 perft 6 876341492 -id 1 +id 810 epd rkqnbr1b/pp1pppp1/7p/2p2n2/P2P4/7N/RPP1PPPP/1KQNBR1B w Ffa - 0 9 perft 1 31 perft 2 750 @@ -7299,7 +7300,7 @@ perft 4 646252 perft 5 21639104 perft 6 617064197 -id 1 +id 811 epd rbkq1rbn/2p1pppp/pp3n2/3p4/5P2/3N2N1/PPPPP1PP/RBKQR1B1 w Afa - 2 9 perft 1 26 perft 2 647 @@ -7308,7 +7309,7 @@ perft 4 465119 perft 5 13643783 perft 6 369702807 -id 1 +id 812 epd rkqbr1bn/p2ppppp/1pp2n2/8/5P2/3P1N2/PPP1PRPP/RKQB2BN w Aa - 3 9 perft 1 24 perft 2 574 @@ -7317,7 +7318,7 @@ perft 4 371597 perft 5 10066892 perft 6 271121237 -id 1 +id 813 epd rk1qrbbn/p1ppp1pp/1p2n3/5p2/1P6/K3N3/P1PPPPPP/R1Q1RBBN w ea - 0 9 perft 1 25 perft 2 548 @@ -7326,7 +7327,7 @@ perft 4 340734 perft 5 9043111 perft 6 235545764 -id 1 +id 814 epd rkqnrnbb/pp1pp3/2p5/5ppp/8/PP4NP/2PPPPP1/RKQNR1BB w EAea - 0 9 perft 1 23 perft 2 727 @@ -7335,7 +7336,7 @@ perft 4 566572 perft 5 15078056 perft 6 471296844 -id 1 +id 815 epd bbrknq1r/ppppppp1/8/7p/5n2/3P4/PPP1PNPP/BBKRNQR1 w c - 0 9 perft 1 21 perft 2 610 @@ -7344,7 +7345,7 @@ perft 4 394705 perft 5 9605845 perft 6 293532398 -id 1 +id 816 epd brkbnqr1/2pppnpp/pp3p2/8/4PPPP/8/PPPP4/BRKBNQRN w GBgb - 1 9 perft 1 30 perft 2 757 @@ -7353,7 +7354,7 @@ perft 4 621332 perft 5 20360394 perft 6 548380577 -id 1 +id 817 epd brk1qb1n/ppppppr1/2n3pp/8/2P3P1/2N5/PP1PPP1P/BR1KQBRN w b - 1 9 perft 1 26 perft 2 570 @@ -7362,7 +7363,7 @@ perft 4 352883 perft 5 10081351 perft 6 242864559 -id 1 +id 818 epd brknq1nb/pp2prpp/8/2pP1p2/6P1/2N5/PPPP1P1P/BRK1QRNB w FBb - 1 9 perft 1 33 perft 2 830 @@ -7371,7 +7372,7 @@ perft 4 764915 perft 5 26262884 perft 6 765831403 -id 1 +id 819 epd rbbk1qrn/ppp1p1pp/5p2/3p1n2/7N/P7/1PPPPPPP/RBB1KQRN w ga - 0 9 perft 1 21 perft 2 562 @@ -7380,7 +7381,7 @@ perft 4 378883 perft 5 9520963 perft 6 290579255 -id 1 +id 820 epd rk1b1qrn/ppp1pppp/5n2/3pN3/P6P/7b/1PPPPPP1/RKBB1QRN w GAga - 4 9 perft 1 28 perft 2 677 @@ -7389,7 +7390,7 @@ perft 4 488740 perft 5 14354779 perft 6 383207197 -id 1 +id 821 epd rkbnqbrn/pp1ppp1p/2p5/6p1/P7/4P3/KPPPQPPP/R1BN1BRN w - - 3 9 perft 1 28 perft 2 585 @@ -7398,7 +7399,7 @@ perft 4 401483 perft 5 12574541 perft 6 310495538 -id 1 +id 822 epd rk1nqrnb/pbpppp2/1p4p1/7p/P7/5NP1/1PPPPPBP/RKBNQR2 w FAfa - 2 9 perft 1 26 perft 2 774 @@ -7407,7 +7408,7 @@ perft 4 645200 perft 5 19093408 perft 6 576325868 -id 1 +id 823 epd rbknb1rn/p1pp2pp/1p6/4pp2/1q3P1B/2N5/PPPPPNPP/RBK2QR1 w GAga - 2 9 perft 1 31 perft 2 1206 @@ -7416,7 +7417,7 @@ perft 4 1374158 perft 5 42849564 perft 6 1555711209 -id 1 +id 824 epd rk1bbqrn/pp1pp1pp/3n4/5p2/3p4/1PP5/PK2PPPP/R1NBBQRN w ga - 0 9 perft 1 21 perft 2 629 @@ -7425,7 +7426,7 @@ perft 4 429667 perft 5 10587910 perft 6 332632033 -id 1 +id 825 epd rknqbbr1/p1pp1pp1/1p4n1/4p2p/4P1P1/6RB/PPPP1P1P/RKNQB2N w Aga - 0 9 perft 1 27 perft 2 753 @@ -7434,7 +7435,7 @@ perft 4 593155 perft 5 17318772 perft 6 507563675 -id 1 +id 826 epd rknqbr1b/pppp1ppp/4p2n/8/1P3P2/4P3/P1PPN1PP/RKNQBR1B w FAfa - 2 9 perft 1 26 perft 2 623 @@ -7443,7 +7444,7 @@ perft 4 460663 perft 5 13389799 perft 6 383508368 -id 1 +id 827 epd r2kqrbn/bppppppp/2n5/p4B2/5P2/2P5/PP1PP1PP/1RKNQRBN w F - 2 9 perft 1 39 perft 2 1026 @@ -7452,7 +7453,7 @@ perft 4 1011922 perft 5 35946987 perft 6 992756232 -id 1 +id 828 epd rk1bqrb1/ppppppp1/1n6/7p/2P2P1n/4P1Q1/PP1P2PP/RKNB1RBN w FAfa - 0 9 perft 1 35 perft 2 760 @@ -7461,7 +7462,7 @@ perft 4 610557 perft 5 21014787 perft 6 536852043 -id 1 +id 829 epd rkq1rb1n/ppppp1pp/1n6/5p2/PPb2P2/8/1KPPP1PP/R1NQRBBN w ea - 1 9 perft 1 27 perft 2 754 @@ -7470,7 +7471,7 @@ perft 4 568788 perft 5 16461795 perft 6 448313956 -id 1 +id 830 epd rknqr2b/pppnp1pp/3p4/3b1p2/8/1N1P2N1/PPP1PPPP/RKQ1R1BB w EAea - 1 9 perft 1 27 perft 2 803 @@ -7479,7 +7480,7 @@ perft 4 700453 perft 5 21875031 perft 6 654754840 -id 1 +id 831 epd bbrknrqn/ppppp1pB/8/2P2p1p/8/5N2/PP1PPPPP/B1RK1RQN w FCfc - 0 9 perft 1 30 perft 2 799 @@ -7488,7 +7489,7 @@ perft 4 671112 perft 5 20532790 perft 6 603059376 -id 1 +id 832 epd brkbnrq1/1pppp1p1/6np/p4p2/4P3/1PP5/P1KP1PPP/BR1BNRQN w fb - 1 9 perft 1 27 perft 2 726 @@ -7497,7 +7498,7 @@ perft 4 555622 perft 5 15156662 perft 6 457601127 -id 1 +id 833 epd brknrbq1/1p1p1ppp/p3p1n1/2p5/8/1P1BPP2/P1PP2PP/BRKNR1QN w EBeb - 0 9 perft 1 36 perft 2 786 @@ -7506,7 +7507,7 @@ perft 4 655019 perft 5 22852433 perft 6 577223409 -id 1 +id 834 epd brknrqnb/p2ppp1p/2p5/1p6/3P2p1/P1P1N3/1P2PPPP/BRK1RQNB w EBeb - 0 9 perft 1 23 perft 2 649 @@ -7515,7 +7516,7 @@ perft 4 440504 perft 5 10687843 perft 6 320881984 -id 1 +id 835 epd rbbk1rqn/1ppppppp/3n4/p7/2P5/3N4/PP1PPPPP/RBB1KRQN w fa - 1 9 perft 1 20 perft 2 478 @@ -7524,7 +7525,7 @@ perft 4 275250 perft 5 7094988 perft 6 185488058 -id 1 +id 836 epd rkbbnrqn/p2p1ppp/1p2p3/8/P1p1P3/1BP5/1P1P1PPP/RKB1NRQN w FAfa - 0 9 perft 1 22 perft 2 570 @@ -7533,7 +7534,7 @@ perft 4 346811 perft 5 8671852 perft 6 229898448 -id 1 +id 837 epd rkb1rb1n/ppppppqp/8/2n3p1/2P1P1P1/8/PP1P1P1P/RKBNRBQN w EAea - 1 9 perft 1 23 perft 2 663 @@ -7542,7 +7543,7 @@ perft 4 490748 perft 5 12900485 perft 6 404944553 -id 1 +id 838 epd rkb1rqnb/pppp3p/2n3p1/4pp2/P2P3P/2P5/1P2PPP1/RKBNRQNB w EAea - 0 9 perft 1 25 perft 2 845 @@ -7551,7 +7552,7 @@ perft 4 741972 perft 5 20276176 perft 6 683290790 -id 1 +id 839 epd rbk1brqn/ppp1pppp/8/3p4/7P/1P4P1/2PPPP2/RBKNBRQN w FAfa - 0 9 perft 1 24 perft 2 526 @@ -7560,7 +7561,7 @@ perft 4 322175 perft 5 9054028 perft 6 222704171 -id 1 +id 840 epd rknbbrqn/pp3pp1/4p3/2pp3p/2P5/8/PPBPPPPP/RKN1BRQN w FAfa - 0 9 perft 1 26 perft 2 756 @@ -7569,7 +7570,7 @@ perft 4 559186 perft 5 14697705 perft 6 433719427 -id 1 +id 841 epd 1knrbbqn/rp1p1ppp/p3p3/2p5/8/5P1P/PPPPP1P1/RKNRBBQN w DAd - 0 9 perft 1 26 perft 2 539 @@ -7578,7 +7579,7 @@ perft 4 345070 perft 5 10223443 perft 6 248715580 -id 1 +id 842 epd rknr1qnb/ppp1p1pp/3p2b1/8/4p3/1P3P1P/P1PP2P1/RKNRBQNB w DAda - 0 9 perft 1 25 perft 2 701 @@ -7587,7 +7588,7 @@ perft 4 561369 perft 5 16047041 perft 6 496340789 -id 1 +id 843 epd rbk1r1bn/ppppp1pp/4n3/5p2/1P3P2/4N2P/PqPPP1P1/RBK1RQBN w EAea - 1 9 perft 1 2 perft 2 60 @@ -7596,7 +7597,7 @@ perft 4 41765 perft 5 1017864 perft 6 33183408 -id 1 +id 844 epd r1nbrqbn/k1ppp1pp/1p6/p4p2/2P5/6PQ/PP1PPP1P/RKNBR1BN w EA - 0 9 perft 1 27 perft 2 699 @@ -7605,7 +7606,7 @@ perft 4 561765 perft 5 17192121 perft 6 499247248 -id 1 +id 845 epd rknrqbbn/1pp1pp2/p5p1/3p3p/6P1/PN5P/1PPPPP2/RK1RQBBN w DAda - 0 9 perft 1 23 perft 2 611 @@ -7614,7 +7615,7 @@ perft 4 435927 perft 5 11917036 perft 6 352885930 -id 1 +id 846 epd rknrqn1b/p1pp1ppb/8/1p2p1Qp/3P4/3N4/PPP1PPPP/RK1R1NBB w DAda - 0 9 perft 1 45 perft 2 1170 @@ -7623,7 +7624,7 @@ perft 4 1320341 perft 5 52213677 perft 6 1500007485 -id 1 +id 847 epd bbkrnrnq/p2p1ppp/2p1p3/1p6/1P2Q3/6P1/P1PPPP1P/BBKRNRN1 w - - 0 9 perft 1 41 perft 2 1035 @@ -7632,7 +7633,7 @@ perft 4 1035610 perft 5 38555608 perft 6 1037686769 -id 1 +id 848 epd brkbnr2/1ppppp1p/7n/p5N1/P2q4/8/1PPPPPPP/BRKBNRQ1 w FBfb - 1 9 perft 1 22 perft 2 869 @@ -7641,7 +7642,7 @@ perft 4 679754 perft 5 16453359 perft 6 567287944 -id 1 +id 849 epd brknrbnq/p1ppppp1/1p6/7p/2PP4/5P2/PPK1P1PP/BR1NRBNQ w eb - 1 9 perft 1 23 perft 2 641 @@ -7650,7 +7651,7 @@ perft 4 422240 perft 5 10192718 perft 6 302864305 -id 1 +id 850 epd brk1r1qb/pp1ppnpp/2p2pn1/8/6N1/2N3P1/PPPPPP1P/BRK1R1QB w EBeb - 3 9 perft 1 32 perft 2 863 @@ -7659,7 +7660,7 @@ perft 4 773191 perft 5 25848794 perft 6 720443112 -id 1 +id 851 epd rbbk1rnq/pppp1pp1/4p2p/8/3P2n1/4BN1P/PPP1PPP1/RB1K1RNQ w FAfa - 3 9 perft 1 26 perft 2 628 @@ -7668,7 +7669,7 @@ perft 4 411995 perft 5 11237919 perft 6 300314373 -id 1 +id 852 epd rkbbnr1q/p1pppppp/5n2/1p5B/PP6/4P3/2PP1PPP/RKB1NRNQ w FAfa - 0 9 perft 1 30 perft 2 692 @@ -7677,7 +7678,7 @@ perft 4 519283 perft 5 16025428 perft 6 420887328 -id 1 +id 853 epd rkb1rbnq/1pppp1pp/5p2/p7/5n1P/1PN3P1/P1PPPP2/RKB1RBNQ w EAea - 0 9 perft 1 32 perft 2 825 @@ -7686,7 +7687,7 @@ perft 4 697251 perft 5 23593363 perft 6 622249676 -id 1 +id 854 epd rkbnrnqb/1ppp1p1p/p5p1/4p3/4P3/2N2P2/PPPP2PP/RKBR1NQB w Aea - 0 9 perft 1 24 perft 2 487 @@ -7695,7 +7696,7 @@ perft 4 301989 perft 5 8782713 perft 6 215787079 -id 1 +id 855 epd rbknbr1q/pppp2pp/4p3/5p1n/1P2P2N/8/P1PP1PPP/RBKNBR1Q w FAfa - 0 9 perft 1 23 perft 2 571 @@ -7704,7 +7705,7 @@ perft 4 365272 perft 5 9224232 perft 6 257288920 -id 1 +id 856 epd rknbb1nq/pppppr2/5pp1/7p/8/1N4P1/PPPPPP1P/RK1BBRNQ w FAa - 2 9 perft 1 26 perft 2 548 @@ -7713,7 +7714,7 @@ perft 4 350173 perft 5 10587626 perft 6 253006082 -id 1 +id 857 epd rknr1bnq/p2pp1pp/1p3p2/2p4b/6PP/2P2N2/PP1PPP2/RKNRBB1Q w DAda - 1 9 perft 1 25 perft 2 502 @@ -7722,7 +7723,7 @@ perft 4 279098 perft 5 7824941 perft 6 175766730 -id 1 +id 858 epd rknrb1qb/ppp1pppp/3p4/8/4P1nP/2P5/PPKP1PP1/R1NRBNQB w da - 1 9 perft 1 23 perft 2 643 @@ -7731,7 +7732,7 @@ perft 4 426616 perft 5 10507328 perft 6 312096061 -id 1 +id 859 epd rbk1rnbq/pppp1npp/4p3/5p2/4P1P1/7P/PPPP1P1N/RBKNR1BQ w EAea - 1 9 perft 1 24 perft 2 591 @@ -7740,7 +7741,7 @@ perft 4 376988 perft 5 10251465 perft 6 263574861 -id 1 +id 860 epd rknbrnb1/p1pppp1p/1p6/3N2p1/P3q1P1/8/1PPPPP1P/RKNBR1BQ w EAea - 1 9 perft 1 28 perft 2 948 @@ -7749,7 +7750,7 @@ perft 4 864588 perft 5 26241141 perft 6 812343987 -id 1 +id 861 epd rknrn1b1/ppppppqp/8/6p1/2P5/2P1BP2/PP2P1PP/RKNRNB1Q w DAda - 1 9 perft 1 31 perft 2 807 @@ -7758,7 +7759,7 @@ perft 4 672973 perft 5 20455205 perft 6 588518645 -id 1 +id 862 epd 1k1rnqbb/npppppp1/r7/p2B3p/5P2/1N4P1/PPPPP2P/RK1RNQB1 w DAd - 0 9 perft 1 40 perft 2 1122 @@ -7767,7 +7768,7 @@ perft 4 1249989 perft 5 48711073 perft 6 1412437357 -id 1 +id 863 epd bbqr1rkn/pp1ppppp/8/2p5/1P2P1n1/7N/P1PP1P1P/BBQRKR1N w FD - 0 9 perft 1 26 perft 2 841 @@ -7776,7 +7777,7 @@ perft 4 746711 perft 5 21328001 perft 6 705170410 -id 1 +id 864 epd bqkr1rnn/1ppp1ppp/p4b2/4p3/P7/3PP2N/1PP2PPP/BQRBKR1N w FC - 3 9 perft 1 24 perft 2 500 @@ -7785,7 +7786,7 @@ perft 4 293824 perft 5 7928916 perft 6 197806842 -id 1 +id 865 epd bqrkrbnn/1pp1ppp1/8/p6p/3p4/P3P2P/QPPP1PP1/B1RKRBNN w ECec - 0 9 perft 1 31 perft 2 592 @@ -7794,7 +7795,7 @@ perft 4 396423 perft 5 12607528 perft 6 298629240 -id 1 +id 866 epd bqkrrnnb/2p1pppp/p7/1P1p4/8/2R3P1/PP1PPP1P/BQ1KRNNB w E - 0 9 perft 1 42 perft 2 1124 @@ -7803,7 +7804,7 @@ perft 4 1276664 perft 5 50052573 perft 6 1483524894 -id 1 +id 867 epd qbbrkrn1/p1pppn1p/8/1p3Pp1/2P5/8/PP1PPP1P/QBBRKRNN w FDfd - 0 9 perft 1 21 perft 2 577 @@ -7812,7 +7813,7 @@ perft 4 392131 perft 5 9683808 perft 6 300294295 -id 1 +id 868 epd qrbbkrnn/pp1p2pp/4p3/5p2/2p2P1P/2P5/PP1PP1P1/QRBBKRNN w FBfb - 0 9 perft 1 21 perft 2 571 @@ -7821,7 +7822,7 @@ perft 4 345681 perft 5 8239872 perft 6 228837930 -id 1 +id 869 epd qrbkrbn1/1pp1pppp/p2p4/8/5PPn/2P5/PP1PP3/QRBKRBNN w EBeb - 0 9 perft 1 18 perft 2 466 @@ -7830,7 +7831,7 @@ perft 4 257776 perft 5 5679073 perft 6 162883949 -id 1 +id 870 epd qrb1rnnb/pp1p1ppp/2pk4/4p3/1P2P3/1R6/P1PP1PPP/Q1BKRNNB w E - 4 9 perft 1 37 perft 2 760 @@ -7839,7 +7840,7 @@ perft 4 562201 perft 5 19486022 perft 6 421740856 -id 1 +id 871 epd qbrkbrn1/p1pppp1p/6n1/1p4p1/1P6/5P2/P1PPPBPP/QBRK1RNN w FCfc - 1 9 perft 1 33 perft 2 824 @@ -7848,7 +7849,7 @@ perft 4 750924 perft 5 25176664 perft 6 734656217 -id 1 +id 872 epd qrkbbr2/2pppppp/5nn1/pp1Q4/P7/3P4/1PP1PPPP/1RKBBRNN w FBfb - 0 9 perft 1 42 perft 2 1147 @@ -7857,7 +7858,7 @@ perft 4 1311247 perft 5 48216013 perft 6 1522548864 -id 1 +id 873 epd qrkrbbnn/pp2pp2/2pp2pp/1B6/P7/4P3/1PPP1PPP/QRKRB1NN w DBdb - 0 9 perft 1 26 perft 2 464 @@ -7866,7 +7867,7 @@ perft 4 242892 perft 5 6928220 perft 6 142507795 -id 1 +id 874 epd qrkrbnnb/p1pp1pp1/1p5p/4p3/1P6/6PN/PKPPPP1P/QR1RBN1B w db - 0 9 perft 1 29 perft 2 705 @@ -7875,7 +7876,7 @@ perft 4 529810 perft 5 15055365 perft 6 419552571 -id 1 +id 875 epd qbrkr1bn/p1p1pp1p/1p1p2n1/6p1/3P1P2/4P3/PPP3PP/QBKRRNBN w ec - 2 9 perft 1 23 perft 2 613 @@ -7884,7 +7885,7 @@ perft 4 426484 perft 5 10747407 perft 6 323905533 -id 1 +id 876 epd qrk1rnb1/p1pp1ppp/1p2Bbn1/8/4P3/6P1/PPPP1P1P/QRK1RNBN w EBeb - 1 9 perft 1 28 perft 2 927 @@ -7893,7 +7894,7 @@ perft 4 846839 perft 5 23063284 perft 6 807913585 -id 1 +id 877 epd 1qkrnbbn/1rpppppp/pp6/5N2/P4P2/8/1PPPP1PP/QRKRNBB1 w DBd - 3 9 perft 1 30 perft 2 542 @@ -7902,7 +7903,7 @@ perft 4 345172 perft 5 10976745 perft 6 251694423 -id 1 +id 878 epd qrkr2bb/pppppppp/8/1n2n3/1N5P/1P6/P1PPPPP1/QRKR1NBB w DBdb - 1 9 perft 1 28 perft 2 719 @@ -7911,7 +7912,7 @@ perft 4 562015 perft 5 17351761 perft 6 479400272 -id 1 +id 879 epd bbrqkrnn/3ppppp/8/ppp5/6P1/4P2N/PPPPKP1P/BBRQ1R1N w fc - 0 9 perft 1 21 perft 2 704 @@ -7920,7 +7921,7 @@ perft 4 546215 perft 5 13676371 perft 6 470796854 -id 1 +id 880 epd brqbkrnn/1pp2p1p/3pp1p1/p5N1/8/1P6/P1PPPPPP/BRQBK1RN w Bfb - 0 9 perft 1 34 perft 2 688 @@ -7929,7 +7930,7 @@ perft 4 505618 perft 5 16639723 perft 6 402140795 -id 1 +id 881 epd br1krb1n/2qppppp/pp3n2/8/1P4P1/8/P1PPPP1P/1RQKRBNN w EBeb - 0 9 perft 1 24 perft 2 945 @@ -7938,7 +7939,7 @@ perft 4 926427 perft 5 25019636 perft 6 959651619 -id 1 +id 882 epd brqkr1nb/2ppp1pp/1p2np2/p7/2P1PN2/8/PP1P1PPP/BRQKRN1B w EBeb - 0 9 perft 1 28 perft 2 675 @@ -7947,7 +7948,7 @@ perft 4 504128 perft 5 15516491 perft 6 417396563 -id 1 +id 883 epd rbbqkrnn/3pppp1/p7/1pp4p/2P1P2P/8/PP1P1PP1/RBBQKRNN w FAfa - 0 9 perft 1 26 perft 2 671 @@ -7956,7 +7957,7 @@ perft 4 496806 perft 5 14072641 perft 6 404960259 -id 1 +id 884 epd rqbbkr1n/pp1p1p1p/4pn2/2p3p1/4P1P1/3P3P/PPP2P2/RQBBKRNN w FAfa - 0 9 perft 1 22 perft 2 633 @@ -7965,7 +7966,7 @@ perft 4 441809 perft 5 10776416 perft 6 335689685 -id 1 +id 885 epd rqbkrbnn/p1ppp3/1p3pp1/7p/3P4/P1P5/1PQ1PPPP/R1BKRBNN w EAea - 0 9 perft 1 32 perft 2 607 @@ -7974,7 +7975,7 @@ perft 4 454319 perft 5 15586203 perft 6 383515709 -id 1 +id 886 epd rqbkrnn1/pp2ppbp/3p4/2p3p1/2P5/1P3N1P/P2PPPP1/RQBKRN1B w EAea - 1 9 perft 1 29 perft 2 943 @@ -7983,7 +7984,7 @@ perft 4 908740 perft 5 28761841 perft 6 907579129 -id 1 +id 887 epd rbqkb1nn/1ppppr1p/p5p1/5p2/1P6/2P4P/P1KPPPP1/RBQ1BRNN w a - 1 9 perft 1 22 perft 2 441 @@ -7992,7 +7993,7 @@ perft 4 231273 perft 5 5784206 perft 6 140934555 -id 1 +id 888 epd rqkb1rnn/1pp1pp1p/p5p1/1b1p4/3P4/P5P1/RPP1PP1P/1QKBBRNN w Ffa - 1 9 perft 1 21 perft 2 505 @@ -8001,7 +8002,7 @@ perft 4 290897 perft 5 7147063 perft 6 188559137 -id 1 +id 889 epd rq1rbbnn/pkp1ppp1/3p3p/1p2N1P1/8/8/PPPPPP1P/RQKRBB1N w DA - 0 9 perft 1 27 perft 2 608 @@ -8010,7 +8011,7 @@ perft 4 387751 perft 5 10808908 perft 6 268393274 -id 1 +id 890 epd rqkrb2b/p2ppppp/2p3nn/1p6/5P2/PP1P4/2P1P1PP/RQKRBNNB w DAda - 1 9 perft 1 30 perft 2 749 @@ -8019,7 +8020,7 @@ perft 4 581531 perft 5 16916813 perft 6 485406712 -id 1 +id 891 epd rbqkr1bn/pp1ppp2/2p1n2p/6p1/8/4BPNP/PPPPP1P1/RBQKRN2 w EAea - 0 9 perft 1 23 perft 2 600 @@ -8028,7 +8029,7 @@ perft 4 410057 perft 5 11041820 perft 6 314327867 -id 1 +id 892 epd rqkbrnb1/2ppp1pp/pp3pn1/8/5P2/B2P4/PPP1P1PP/RQKBRN1N w EAea - 2 9 perft 1 22 perft 2 569 @@ -8037,7 +8038,7 @@ perft 4 371471 perft 5 9395816 perft 6 269460607 -id 1 +id 893 epd rqkrnbb1/p1p1pppp/1p4n1/3p4/7P/P3P3/1PPPBPP1/RQKRN1BN w DAda - 0 9 perft 1 27 perft 2 579 @@ -8046,7 +8047,7 @@ perft 4 373079 perft 5 10238486 perft 6 266047417 -id 1 +id 894 epd rqkrn1bb/p1ppp1pp/4n3/1p6/6p1/4N3/PPPPPPPP/RQKR2BB w DAda - 0 9 perft 1 20 perft 2 462 @@ -8055,7 +8056,7 @@ perft 4 274162 perft 5 6563859 perft 6 193376359 -id 1 +id 895 epd bbrkqr2/pppp1ppp/6nn/8/2P1p3/3PP2N/PP3PPP/BBRKQR1N w FCfc - 0 9 perft 1 28 perft 2 724 @@ -8064,7 +8065,7 @@ perft 4 619064 perft 5 19318355 perft 6 593204629 -id 1 +id 896 epd brk1qrnn/1pppbppp/4p3/8/1p6/P1P4P/3PPPP1/BRKBQRNN w FBfb - 1 9 perft 1 24 perft 2 662 @@ -8073,7 +8074,7 @@ perft 4 468215 perft 5 12610387 perft 6 355969349 -id 1 +id 897 epd 1r1qrbnn/p1pkpppp/1p1p4/8/3P1PP1/P4b2/1PP1P2P/BRKQRBNN w EB - 1 9 perft 1 22 perft 2 696 @@ -8082,7 +8083,7 @@ perft 4 510247 perft 5 13697382 perft 6 401903030 -id 1 +id 898 epd 1rkqrnnb/p1p1p1pp/1p1p4/3b1p1N/4P3/5N2/PPPP1PPP/BRKQR2B w EBeb - 1 9 perft 1 29 perft 2 887 @@ -8091,7 +8092,7 @@ perft 4 816176 perft 5 26051242 perft 6 791718847 -id 1 +id 899 epd rbbkq1rn/pppppppp/7n/8/P7/3P3P/1PPKPPP1/RBB1QRNN w a - 3 9 perft 1 22 perft 2 417 @@ -8100,7 +8101,7 @@ perft 4 216855 perft 5 5505063 perft 6 134818483 -id 1 +id 900 epd rkbbqr1n/1p1pppp1/2p2n2/p4NBp/8/3P4/PPP1PPPP/RK1BQRN1 w FAfa - 0 9 perft 1 37 perft 2 832 @@ -8109,7 +8110,7 @@ perft 4 728154 perft 5 26676373 perft 6 673756141 -id 1 +id 901 epd rkbqrb1n/3pBppp/ppp2n2/8/8/P2P4/1PP1PPPP/RK1QRBNN w EAea - 0 9 perft 1 28 perft 2 685 @@ -8118,7 +8119,7 @@ perft 4 543069 perft 5 16033316 perft 6 482288814 -id 1 +id 902 epd rkb1rn1b/ppppqppp/4p3/8/1P2n1P1/5Q2/P1PP1P1P/RKB1RNNB w EAea - 2 9 perft 1 37 perft 2 1158 @@ -8127,7 +8128,7 @@ perft 4 1234768 perft 5 44672979 perft 6 1389312729 -id 1 +id 903 epd r1kqbrnn/pp1pp1p1/7p/2P2p2/5b2/3P4/P1P1P1PP/RBKQBRNN w FAfa - 0 9 perft 1 5 perft 2 161 @@ -8136,7 +8137,7 @@ perft 4 154885 perft 5 4734999 perft 6 157499039 -id 1 +id 904 epd rkqbbr1n/ppp1ppp1/8/Q2p3p/4n3/3P1P2/PPP1P1PP/RK1BBRNN w FAfa - 2 9 perft 1 38 perft 2 1144 @@ -8145,7 +8146,7 @@ perft 4 1236877 perft 5 43832975 perft 6 1366087771 -id 1 +id 905 epd rkqrbbn1/p1ppppp1/Bp5p/8/P6n/2P1P3/1P1P1PPP/RKQRB1NN w DAda - 0 9 perft 1 28 perft 2 551 @@ -8154,7 +8155,7 @@ perft 4 350861 perft 5 9944107 perft 6 251179183 -id 1 +id 906 epd rkqrb1nb/1ppp1ppp/p7/4p3/5n2/3P2N1/PPPQPPPP/RK1RB1NB w DAda - 0 9 perft 1 26 perft 2 690 @@ -8163,7 +8164,7 @@ perft 4 513628 perft 5 15965907 perft 6 418191735 -id 1 +id 907 epd rbkqrnbn/pppp1p2/4p1p1/7p/7P/P2P4/BPP1PPP1/R1KQRNBN w EAea - 0 9 perft 1 27 perft 2 515 @@ -8172,7 +8173,7 @@ perft 4 309727 perft 5 8792550 perft 6 218658292 -id 1 +id 908 epd rkqbrnbn/pp1ppp2/8/2p3p1/P1P4p/5P2/1PKPP1PP/R1QBRNBN w ea - 0 9 perft 1 27 perft 2 627 @@ -8181,7 +8182,7 @@ perft 4 431101 perft 5 11978698 perft 6 328434174 -id 1 +id 909 epd rkqrnbbn/1p2pp1p/3p2p1/p1p5/P5PP/3N4/1PPPPP2/RKQR1BBN w DAda - 0 9 perft 1 23 perft 2 624 @@ -8190,7 +8191,7 @@ perft 4 451860 perft 5 11960861 perft 6 367311176 -id 1 +id 910 epd rk2rnbb/ppqppppp/2pn4/8/1P3P2/6P1/P1PPP1NP/RKQR1NBB w DAa - 1 9 perft 1 27 perft 2 727 @@ -8199,7 +8200,7 @@ perft 4 581003 perft 5 16633696 perft 6 505212747 -id 1 +id 911 epd b1krrqnn/pp1ppp1p/2p3p1/8/P3Pb1P/1P6/2PP1PP1/BBRKRQNN w EC - 0 9 perft 1 32 perft 2 943 @@ -8208,7 +8209,7 @@ perft 4 865229 perft 5 28672582 perft 6 800922511 -id 1 +id 912 epd 1rkbrqnn/p1pp1ppp/1p6/8/P2Pp3/8/1PPKPPQP/BR1BR1NN w eb - 0 9 perft 1 28 perft 2 916 @@ -8217,7 +8218,7 @@ perft 4 817624 perft 5 22840279 perft 6 759318058 -id 1 +id 913 epd brkrqb1n/1pppp1pp/p7/3n1p2/P5P1/3PP3/1PP2P1P/BRKRQBNN w DBdb - 0 9 perft 1 27 perft 2 669 @@ -8226,7 +8227,7 @@ perft 4 484259 perft 5 13956472 perft 6 380267099 -id 1 +id 914 epd brkrqnnb/3pppp1/1p6/p1p4p/2P3P1/6N1/PP1PPP1P/BRKRQ1NB w DBdb - 0 9 perft 1 29 perft 2 699 @@ -8235,7 +8236,7 @@ perft 4 512639 perft 5 15093909 perft 6 406594531 -id 1 +id 915 epd r1bkrq1n/pp2pppp/3b1n2/2pp2B1/6P1/3P1P2/PPP1P2P/RB1KRQNN w EAea - 2 9 perft 1 27 perft 2 835 @@ -8244,7 +8245,7 @@ perft 4 713550 perft 5 19867800 perft 6 631209313 -id 1 +id 916 epd rk1brq1n/p1p1pppp/3p1n2/1p3b2/4P3/2NQ4/PPPP1PPP/RKBBR2N w EAea - 4 9 perft 1 36 perft 2 1004 @@ -8253,7 +8254,7 @@ perft 4 979608 perft 5 35143142 perft 6 966310885 -id 1 +id 917 epd rkbrqbnn/1p2ppp1/B1p5/p2p3p/4P2P/8/PPPP1PP1/RKBRQ1NN w DAda - 0 9 perft 1 27 perft 2 748 @@ -8262,7 +8263,7 @@ perft 4 597819 perft 5 17597073 perft 6 515304215 -id 1 +id 918 epd rkbrqn1b/pp1pp1pp/2p2p2/5n2/8/2P2P2/PP1PP1PP/RKBRQ1NB w DAda - 0 9 perft 1 20 perft 2 479 @@ -8271,7 +8272,7 @@ perft 4 266446 perft 5 6253775 perft 6 167767913 -id 1 +id 919 epd rbkrbnn1/ppppp1pp/5q2/5p2/5P2/P3P2N/1PPP2PP/RBKRBQ1N w DAda - 3 9 perft 1 28 perft 2 947 @@ -8280,7 +8281,7 @@ perft 4 876068 perft 5 26007841 perft 6 838704143 -id 1 +id 920 epd rkr1bqnn/1ppp1p1p/p5p1/4p3/3PP2b/2P2P2/PP4PP/RKRBBQNN w CAca - 0 9 perft 1 31 perft 2 1004 @@ -8289,7 +8290,7 @@ perft 4 1006830 perft 5 32688124 perft 6 1024529879 -id 1 +id 921 epd rkrqbbnn/pppp3p/8/4ppp1/1PP4P/8/P2PPPP1/RKRQBBNN w CAca - 0 9 perft 1 24 perft 2 717 @@ -8298,7 +8299,7 @@ perft 4 564137 perft 5 15844525 perft 6 484884485 -id 1 +id 922 epd rkrqbn1b/pppp2pp/8/4pp2/1P1P2n1/5N2/P1P1PP1P/RKRQBN1B w CAca - 0 9 perft 1 25 perft 2 718 @@ -8307,7 +8308,7 @@ perft 4 587666 perft 5 17257753 perft 6 537354146 -id 1 +id 923 epd rbkrqnbn/p1p1ppp1/1p1p4/8/3PP2p/2PB4/PP3PPP/R1KRQNBN w DAda - 0 9 perft 1 30 perft 2 754 @@ -8316,7 +8317,7 @@ perft 4 611322 perft 5 19338246 perft 6 532603566 -id 1 +id 924 epd 1krbqnbn/1p2pppp/r1pp4/p7/8/1P1P2PP/P1P1PP2/RKRBQNBN w CAc - 0 9 perft 1 21 perft 2 566 @@ -8325,7 +8326,7 @@ perft 4 375128 perft 5 9700847 perft 6 279864836 -id 1 +id 925 epd rkrq1b2/pppppppb/3n2np/2N5/4P3/7P/PPPP1PP1/RKRQ1BBN w CAca - 1 9 perft 1 33 perft 2 654 @@ -8334,7 +8335,7 @@ perft 4 479678 perft 5 15990307 perft 6 382218272 -id 1 +id 926 epd rkr1nnbb/ppp2p1p/3p1qp1/4p3/P5P1/3PN3/1PP1PP1P/RKRQN1BB w CAca - 1 9 perft 1 28 perft 2 715 @@ -8343,7 +8344,7 @@ perft 4 555328 perft 5 16303092 perft 6 468666425 -id 1 +id 927 epd bbrkrnqn/1p1ppppp/8/8/p2pP3/PP6/2P2PPP/BBRKRNQN w ECec - 0 9 perft 1 24 perft 2 757 @@ -8352,7 +8353,7 @@ perft 4 603231 perft 5 15957628 perft 6 509307623 -id 1 +id 928 epd brkbrnqn/ppp2p2/4p3/P2p2pp/6P1/5P2/1PPPP2P/BRKBRNQN w EBeb - 0 9 perft 1 25 perft 2 548 @@ -8361,7 +8362,7 @@ perft 4 348259 perft 5 9688526 perft 6 247750144 -id 1 +id 929 epd brkr1bqn/1pppppp1/3n3p/1p6/P7/4P1P1/1PPP1P1P/BRKRN1QN w DBdb - 0 9 perft 1 19 perft 2 359 @@ -8370,7 +8371,7 @@ perft 4 157099 perft 5 3521652 perft 6 81787718 -id 1 +id 930 epd brkr1qnb/pppp2pp/2B1p3/5p2/2n5/6PP/PPPPPPN1/BRKR1QN1 w DBdb - 1 9 perft 1 27 perft 2 854 @@ -8379,7 +8380,7 @@ perft 4 741626 perft 5 20558538 perft 6 667089231 -id 1 +id 931 epd rbbkrnqn/p1p1p1pp/8/1p1p4/1P1Pp3/6N1/P1P2PPP/RBBKRNQ1 w EAea - 0 9 perft 1 28 perft 2 723 @@ -8388,7 +8389,7 @@ perft 4 514440 perft 5 14621108 perft 6 397454100 -id 1 +id 932 epd rkbbrn1n/pppppp2/5q1p/6p1/3P3P/4P3/PPP2PP1/RKBBRNQN w EAea - 1 9 perft 1 25 perft 2 741 @@ -8397,7 +8398,7 @@ perft 4 585198 perft 5 15605840 perft 6 485037906 -id 1 +id 933 epd rkbr1bq1/ppnppppp/6n1/2p5/2P1N2P/8/PP1PPPP1/RKBRNBQ1 w DAda - 3 9 perft 1 24 perft 2 547 @@ -8406,7 +8407,7 @@ perft 4 339497 perft 5 9410221 perft 6 234041078 -id 1 +id 934 epd 1kbrnqnb/r1ppppp1/8/pp5p/8/1P1NP3/P1PP1PPP/RKB1RQNB w Ad - 2 9 perft 1 26 perft 2 618 @@ -8415,7 +8416,7 @@ perft 4 442643 perft 5 13112297 perft 6 357030697 -id 1 +id 935 epd rbkrb1qn/1pp1ppp1/3pn2p/pP6/8/4N1P1/P1PPPP1P/RBKRB1QN w DAda - 0 9 perft 1 21 perft 2 544 @@ -8424,7 +8425,7 @@ perft 4 338832 perft 5 8381483 perft 6 236013157 -id 1 +id 936 epd rkrbbnqn/ppppp3/5p2/6pp/5PBP/4P3/PPPP2P1/RKR1BNQN w CAca - 0 9 perft 1 30 perft 2 891 @@ -8433,7 +8434,7 @@ perft 4 764356 perft 5 21894752 perft 6 669256602 -id 1 +id 937 epd rkr1bb1n/ppppp1pp/5p2/4n3/3QP3/5P2/RPPP2PP/1KRNBB1N w Cca - 1 9 perft 1 45 perft 2 1172 @@ -8442,7 +8443,7 @@ perft 4 1332060 perft 5 57856784 perft 6 1501852662 -id 1 +id 938 epd rkr1bqnb/pp1ppppp/8/2pN4/1P6/5N2/P1PPnPPP/RKR1BQ1B w CAca - 0 9 perft 1 28 perft 2 730 @@ -8451,7 +8452,7 @@ perft 4 559167 perft 5 16323242 perft 6 463032124 -id 1 +id 939 epd rbkrnqb1/2ppppp1/p5np/1p6/8/3N4/PPPPPPPP/RBKRQNB1 w DAda - 2 9 perft 1 20 perft 2 417 @@ -8460,7 +8461,7 @@ perft 4 217390 perft 5 5180716 perft 6 133936564 -id 1 +id 940 epd rkrbnqb1/p1pppnpp/5p2/1p6/2P5/1P1P1N2/P3PPPP/RKRB1QBN w CAca - 0 9 perft 1 25 perft 2 546 @@ -8469,7 +8470,7 @@ perft 4 330316 perft 5 8813781 perft 6 222026485 -id 1 +id 941 epd rkr1qbbn/ppppppp1/4n3/7p/8/P7/KPPPPPPP/R1RNQBBN w ca - 0 9 perft 1 22 perft 2 484 @@ -8478,7 +8479,7 @@ perft 4 267495 perft 5 6633319 perft 6 163291279 -id 1 +id 942 epd rkrnqnb1/1ppppp2/p5p1/7p/8/P1bPP3/1PP1QPPP/RKRN1NBB w CAca - 0 9 perft 1 22 perft 2 636 @@ -8487,7 +8488,7 @@ perft 4 441001 perft 5 11614241 perft 6 331083405 -id 1 +id 943 epd b2krn1q/p1rppppp/1Q3n2/2p1b3/1P4P1/8/P1PPPP1P/BBRKRNN1 w ECe - 3 9 perft 1 36 perft 2 1192 @@ -8496,7 +8497,7 @@ perft 4 1406795 perft 5 50382104 perft 6 1650202838 -id 1 +id 944 epd brkbrnn1/pp1pppp1/7q/2p5/6Pp/4P1NP/PPPP1P2/BRKBR1NQ w EBeb - 2 9 perft 1 30 perft 2 978 @@ -8505,7 +8506,7 @@ perft 4 942398 perft 5 29205057 perft 6 936568065 -id 1 +id 945 epd brkrnb1q/pp1p1ppp/2p1p3/5n2/1P6/5N1N/P1PPPPPP/BRKR1B1Q w DBdb - 1 9 perft 1 31 perft 2 897 @@ -8514,7 +8515,7 @@ perft 4 810187 perft 5 25423729 perft 6 755334868 -id 1 +id 946 epd brkr1nqb/pp1p1pp1/2pn3p/P3p3/4P3/6P1/1PPP1P1P/BRKRNNQB w DBdb - 0 9 perft 1 19 perft 2 382 @@ -8523,7 +8524,7 @@ perft 4 182292 perft 5 4232274 perft 6 103537333 -id 1 +id 947 epd r1bkrn1q/ppbppppp/5n2/2p5/3P4/P6N/1PP1PPPP/RBBKRNQ1 w EAea - 3 9 perft 1 27 perft 2 822 @@ -8532,7 +8533,7 @@ perft 4 678880 perft 5 19115128 perft 6 578210135 -id 1 +id 948 epd rkbbrnnq/pp2pppp/8/2pp4/P1P5/1P3P2/3PP1PP/RKBBRNNQ w EAea - 1 9 perft 1 23 perft 2 643 @@ -8541,7 +8542,7 @@ perft 4 442070 perft 5 11170489 perft 6 329615708 -id 1 +id 949 epd rkbr1b1q/p1pppppp/1p1n4/7n/5QP1/3N4/PPPPPP1P/RKBR1BN1 w DAda - 4 9 perft 1 37 perft 2 943 @@ -8550,7 +8551,7 @@ perft 4 880474 perft 5 31568111 perft 6 842265141 -id 1 +id 950 epd rkbr1nqb/pppp2np/8/4ppp1/1P6/6N1/P1PPPPPP/RKBRN1QB w DAda - 1 9 perft 1 23 perft 2 574 @@ -8559,7 +8560,7 @@ perft 4 362306 perft 5 9020291 perft 6 261247606 -id 1 +id 951 epd rbkr1nnq/p1p1pp1p/1p4p1/3p4/b3P3/4N3/PPPPNPPP/RBKRB1Q1 w DAda - 0 9 perft 1 26 perft 2 900 @@ -8568,7 +8569,7 @@ perft 4 805006 perft 5 21653203 perft 6 745802405 -id 1 +id 952 epd rkrbb1nq/p2pppp1/1p4n1/2p4p/3N4/4P1P1/PPPP1P1P/RKRBBN1Q w CAca - 0 9 perft 1 32 perft 2 697 @@ -8577,7 +8578,7 @@ perft 4 531121 perft 5 17150175 perft 6 441578567 -id 1 +id 953 epd rkrnbb1q/pp2pp1p/6pn/2pp4/2B1P2P/8/PPPP1PP1/RKRNB1NQ w CAca - 0 9 perft 1 28 perft 2 854 @@ -8586,7 +8587,7 @@ perft 4 755990 perft 5 21823412 perft 6 712787248 -id 1 +id 954 epd rk2bnqb/pprpppp1/4n2p/2p5/P7/3P2NP/1PP1PPP1/RKRNB1QB w CAa - 1 9 perft 1 26 perft 2 596 @@ -8595,7 +8596,7 @@ perft 4 414862 perft 5 11758184 perft 6 323043654 -id 1 +id 955 epd r1krnnbq/pp1ppp1p/6p1/2p5/2P5/P3P3/Rb1P1PPP/1BKRNNBQ w Dda - 0 9 perft 1 2 perft 2 61 @@ -8604,7 +8605,7 @@ perft 4 40072 perft 5 937188 perft 6 28753562 -id 1 +id 956 epd 1krbnnbq/1pp1p1pp/r7/p2p1p2/3PP3/2P3P1/PP3P1P/RKRBNNBQ w CAc - 0 9 perft 1 30 perft 2 953 @@ -8613,7 +8614,7 @@ perft 4 860530 perft 5 25531358 perft 6 787205262 -id 1 +id 957 epd rkr1nbbq/2ppp1pp/1pn5/p4p2/P6P/3P4/1PP1PPPB/RKRNNB1Q w CAca - 1 9 perft 1 24 perft 2 645 @@ -8622,7 +8623,7 @@ perft 4 446423 perft 5 11484012 perft 6 341262639 -id 1 +id 958 epd rkrnnqbb/p1ppp2p/Qp6/4Pp2/5p2/8/PPPP2PP/RKRNN1BB w CAca - 0 9 perft 1 35 perft 2 929 @@ -8631,7 +8632,7 @@ perft 4 896130 perft 5 31272517 perft 6 915268405 -id 1 +id 959 epd bbq1nr1r/pppppk1p/2n2p2/6p1/P4P2/4P1P1/1PPP3P/BBQNNRKR w HF - 1 9 perft 1 23 perft 2 589 From bc1c55aeaf619fd61e5116283705274e701df378 Mon Sep 17 00:00:00 2001 From: Jackson Hall Date: Thu, 26 Jan 2023 12:31:56 -0500 Subject: [PATCH 1584/1831] Update cp multiplier to match Lichess implementation --- chess/engine.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index f319d09bf..ca7f876ca 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -664,7 +664,9 @@ def _sf12_wins(cp: int, *, ply: int) -> int: return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) def _lichess_raw_wins(cp: int) -> int: - return round(1000 / (1 + math.exp(-0.004 * cp))) + # https://github.com/lichess-org/lila/pull/11148 + # https://github.com/lichess-org/lila/blob/2242b0a08faa06e7be5508d338ede7bb09049777/modules/analyse/src/main/WinPercent.scala#L26-L30 + return round(1000 / (1 + math.exp(-0.00368208 * cp))) class Cp(Score): From b15d55e955d821a65d05416439e0d04c45be5d9a Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 2 Feb 2023 23:31:24 -0800 Subject: [PATCH 1585/1831] Send opponent information to Xboard engines --- chess/engine.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index ca7f876ca..cfdd58845 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1945,6 +1945,8 @@ def __init__(self) -> None: self.options = { "random": Option("random", "check", False, None, None, None), "computer": Option("computer", "check", False, None, None, None), + "name": Option("name", "string", "", None, None, None), + "rating": Option("rating", "string", "", None, None, None) } self.config: Dict[str, ConfigValue] = {} self.target_config: Dict[str, ConfigValue] = {} @@ -2055,7 +2057,7 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None # Set up starting position. root = board.root() - new_options = "random" in options or "computer" in options + new_options = any(param in options for param in ("random", "computer", "name", "rating")) new_game = self.first_game or self.game != game or new_options or root != self.board.root() self.game = game self.first_game = False @@ -2071,6 +2073,10 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None if self.config.get("random"): self.send_line("random") + if "name" in options and self.features.get("name", True): + self.send_line(f"name {options['name']}") + if "rating" in options: + self.send_line(f"rating {options['rating']}") if self.config.get("computer"): self.send_line("computer") @@ -2369,7 +2375,7 @@ def _setoption(self, name: str, value: ConfigValue) -> None: self.config[name] = value = option.parse(value) - if name in ["random", "computer"]: + if name in ["random", "computer", "name", "rating"]: # Applied in _new. pass elif name in ["memory", "cores"] or name.startswith("egtpath "): From 8a270859cab13537561998f1dbf601d9b0175e4c Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Fri, 3 Feb 2023 00:46:13 -0800 Subject: [PATCH 1586/1831] Use configure() method instead of play() --- chess/engine.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index cfdd58845..e91eaaba8 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2073,10 +2073,10 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None if self.config.get("random"): self.send_line("random") - if "name" in options and self.features.get("name", True): - self.send_line(f"name {options['name']}") - if "rating" in options: - self.send_line(f"rating {options['rating']}") + if "name" in self.config and self.features.get("name", True): + self.send_line(f"name {self.config['name']}") + if "rating" in self.config: + self.send_line(f"rating {self.config['rating']}") if self.config.get("computer"): self.send_line("computer") From 13be99744cbcb00480d08fb5582694c2a3e62469 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Fri, 3 Feb 2023 01:11:37 -0800 Subject: [PATCH 1587/1831] Fix failing tests --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index e91eaaba8..68f54123c 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2073,9 +2073,9 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None if self.config.get("random"): self.send_line("random") - if "name" in self.config and self.features.get("name", True): + if self.config.get("name") and self.features.get("name", True): self.send_line(f"name {self.config['name']}") - if "rating" in self.config: + if self.config.get("rating"): self.send_line(f"rating {self.config['rating']}") if self.config.get("computer"): self.send_line("computer") From cb70c4db7f7fb8c49c759a2489d5c82412bb7691 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 4 Feb 2023 20:21:40 -0800 Subject: [PATCH 1588/1831] Separate rating inputs --- chess/engine.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 68f54123c..8f21f74ef 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1946,7 +1946,8 @@ def __init__(self) -> None: "random": Option("random", "check", False, None, None, None), "computer": Option("computer", "check", False, None, None, None), "name": Option("name", "string", "", None, None, None), - "rating": Option("rating", "string", "", None, None, None) + "engine_rating": Option("engine_rating", "spin", "", None, None, None), + "opponent_rating": Option("opponent_rating", "spin", "", None, None, None) } self.config: Dict[str, ConfigValue] = {} self.target_config: Dict[str, ConfigValue] = {} @@ -2057,7 +2058,7 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None # Set up starting position. root = board.root() - new_options = any(param in options for param in ("random", "computer", "name", "rating")) + new_options = any(param in options for param in ("random", "computer", "name", "engine_rating", "opponent_rating")) new_game = self.first_game or self.game != game or new_options or root != self.board.root() self.game = game self.first_game = False @@ -2075,8 +2076,8 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None self.send_line("random") if self.config.get("name") and self.features.get("name", True): self.send_line(f"name {self.config['name']}") - if self.config.get("rating"): - self.send_line(f"rating {self.config['rating']}") + if self.config.get("engine_rating") or self.config.get("opponent_rating"): + self.send_line(f"rating {self.config.get('engine_rating') or 0} {self.config.get('opponent_rating') or 0}") if self.config.get("computer"): self.send_line("computer") @@ -2375,7 +2376,7 @@ def _setoption(self, name: str, value: ConfigValue) -> None: self.config[name] = value = option.parse(value) - if name in ["random", "computer", "name", "rating"]: + if name in ["random", "computer", "name", "engine_rating", "opponent_rating"]: # Applied in _new. pass elif name in ["memory", "cores"] or name.startswith("egtpath "): From 7cf7dc15221925fe13e42cd279b035afdfa1cf94 Mon Sep 17 00:00:00 2001 From: disservin <45608332+Disservin@users.noreply.github.com> Date: Wed, 15 Feb 2023 21:14:18 +0100 Subject: [PATCH 1589/1831] strip option args --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index ca7f876ca..59455d503 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1377,7 +1377,7 @@ def _option(self, engine: UciProtocol, arg: str) -> None: current_var = None var = [] - for token in arg.split(" "): + for token in arg.strip().split(" "): if token == "name" and not name: current_parameter = "name" elif token == "type" and not type: From 5859dc20f01df7f862c06811a4d8206b76107cee Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 19 Feb 2023 20:58:01 -0800 Subject: [PATCH 1590/1831] Support implicit resigning from Xboard engines An XBoard engine is allowed to resign by putting the string "resign" somewhere in the comment of a "1-0" or "0-1" command. For example, "0-1 {White resigns}". Closes #964 --- chess/engine.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index ca7f876ca..8e5075fc5 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2197,6 +2197,8 @@ def line_received(self, engine: XBoardProtocol, line: str) -> None: self.play_result.resigned = True self._ping_after_move(engine) elif line.startswith("1-0") or line.startswith("0-1") or line.startswith("1/2-1/2"): + if "resign" in line and not self.result.done(): + self.play_result.resigned = True self._ping_after_move(engine) elif line.startswith("#"): pass From 47db69c6650bbc88109b5f0841fe87cc6a27a5b7 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Fri, 24 Feb 2023 01:18:32 +0100 Subject: [PATCH 1591/1831] SVG output: add option for borders around board and diagram This is useful for printing when the margin is typically white to still give the visual clues about separation. Option defaults to off. Also slightly pad the coordinates at the top, so that "f" doesn't run into the outer border. --- chess/svg.py | 76 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 6021e2054..d7aea03d9 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -76,6 +76,8 @@ "square dark lastmove": "#aaa23b", "square light lastmove": "#cdd16a", "margin": "#212121", + "inner border": "#111", + "outer border": "#111", "coord": "#e5e5e5", "arrow green": "#15781B80", "arrow red": "#88202080", @@ -245,7 +247,8 @@ def board(board: Optional[chess.BaseBoard] = None, *, coordinates: bool = True, colors: Dict[str, str] = {}, flipped: bool = False, - style: Optional[str] = None) -> str: + style: Optional[str] = None, + borders: bool = False) -> str: """ Renders a board with pieces and/or selected squares as an SVG image. @@ -267,11 +270,14 @@ def board(board: Optional[chess.BaseBoard] = None, *, :param coordinates: Pass ``False`` to disable the coordinate margin. :param colors: A dictionary to override default colors. Possible keys are ``square light``, ``square dark``, ``square light lastmove``, - ``square dark lastmove``, ``margin``, ``coord``, ``arrow green``, - ``arrow blue``, ``arrow red``, and ``arrow yellow``. Values should look - like ``#ffce9e`` (opaque), or ``#15781B80`` (transparent). + ``square dark lastmove``, ``margin``, ``coord``, ``inner border``, + ``outer border``, ``arrow green``, ``arrow blue``, ``arrow red``, + and ``arrow yellow``. Values should look like ``#ffce9e`` (opaque), + or ``#15781B80`` (transparent). :param flipped: Pass ``True`` to flip the board. :param style: A CSS stylesheet to include in the SVG image. + :param borders: Pass ``True`` to enable a border around the board and, + (if ``coordinates`` is enabled) the coordinate margin. >>> import chess >>> import chess.svg @@ -293,8 +299,11 @@ def board(board: Optional[chess.BaseBoard] = None, *, Use *orientation* with a color instead of the *flipped* toggle. """ orientation ^= flipped + inner_border = 1 if borders and coordinates else 0 + outer_border = 1 if borders else 0 margin = 15 if coordinates else 0 - svg = _svg(8 * SQUARE_SIZE + 2 * margin, size) + full_size = 2 * outer_border + 2 * margin + 2 * inner_border + 8 * SQUARE_SIZE + svg = _svg(full_size, size) if style: ET.SubElement(svg, "style").text = style @@ -318,34 +327,59 @@ def board(board: Optional[chess.BaseBoard] = None, *, if check is not None: defs.append(ET.fromstring(CHECK_GRADIENT)) - # Render coordinates. - if coordinates: - margin_color, margin_opacity = _select_color(colors, "margin") + if outer_border: + outer_border_color, outer_border_opacity = _select_color(colors, "outer border") ET.SubElement(svg, "rect", _attrs({ "x": 0, "y": 0, - "width": 2 * margin + 8 * SQUARE_SIZE, - "height": 2 * margin + 8 * SQUARE_SIZE, + "width": full_size, + "height": full_size, + "fill": outer_border_color, + "opacity": outer_border_opacity if outer_border_opacity < 1.0 else None, + })) + + if margin: + margin_color, margin_opacity = _select_color(colors, "margin") + ET.SubElement(svg, "rect", _attrs({ + "x": outer_border, + "y": outer_border, + "width": full_size - 2 * outer_border, + "height": full_size - 2 * outer_border, "fill": margin_color, "opacity": margin_opacity if margin_opacity < 1.0 else None, })) + + if inner_border: + inner_border_color, inner_border_opacity = _select_color(colors, "inner border") + ET.SubElement(svg, "rect", _attrs({ + "x": outer_border + margin, + "y": outer_border + margin, + "width": full_size - 2 * outer_border - 2 * margin, + "height": full_size - 2 * outer_border - 2 * margin, + "fill": inner_border_color, + "opacity": inner_border_opacity if inner_border_opacity < 1.0 else None, + })) + + # Render coordinates. + if coordinates: coord_color, coord_opacity = _select_color(colors, "coord") for file_index, file_name in enumerate(chess.FILE_NAMES): - x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin - svg.append(_coord(file_name, x, 0, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) - svg.append(_coord(file_name, x, margin + 8 * SQUARE_SIZE, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + inner_border + margin + outer_border + # Keep some padding here to separate the ascender from the border + svg.append(_coord(file_name, x, 1, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) + svg.append(_coord(file_name, x, full_size - outer_border - margin, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) for rank_index, rank_name in enumerate(chess.RANK_NAMES): - y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + inner_border + margin + outer_border svg.append(_coord(rank_name, 0, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) - svg.append(_coord(rank_name, margin + 8 * SQUARE_SIZE, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) + svg.append(_coord(rank_name, full_size - outer_border - margin, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) # Render board. for square, bb in enumerate(chess.BB_SQUARES): file_index = chess.square_file(square) rank_index = chess.square_rank(square) - x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin - y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + inner_border + margin + outer_border + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + inner_border + margin + outer_border cls = ["square", "light" if chess.BB_LIGHT_SQUARES & bb else "dark"] if lastmove and square in [lastmove.from_square, lastmove.to_square]: @@ -442,10 +476,10 @@ def board(board: Optional[chess.BaseBoard] = None, *, head_file = chess.square_file(head) head_rank = chess.square_rank(head) - xtail = margin + (tail_file + 0.5 if orientation else 7.5 - tail_file) * SQUARE_SIZE - ytail = margin + (7.5 - tail_rank if orientation else tail_rank + 0.5) * SQUARE_SIZE - xhead = margin + (head_file + 0.5 if orientation else 7.5 - head_file) * SQUARE_SIZE - yhead = margin + (7.5 - head_rank if orientation else head_rank + 0.5) * SQUARE_SIZE + xtail = outer_border + margin + inner_border + (tail_file + 0.5 if orientation else 7.5 - tail_file) * SQUARE_SIZE + ytail = outer_border + margin + inner_border + (7.5 - tail_rank if orientation else tail_rank + 0.5) * SQUARE_SIZE + xhead = outer_border + margin + inner_border + (head_file + 0.5 if orientation else 7.5 - head_file) * SQUARE_SIZE + yhead = outer_border + margin + inner_border + (7.5 - head_rank if orientation else head_rank + 0.5) * SQUARE_SIZE if (head_file, head_rank) == (tail_file, tail_rank): ET.SubElement(svg, "circle", _attrs({ From 3439cb61bc632b7cb4087d512683f3abf75dfce3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 24 Feb 2023 19:26:45 +0100 Subject: [PATCH 1592/1831] Tweak chess.svg.board(..., borders) docs --- chess/svg.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index d7aea03d9..dbcbc5321 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -247,8 +247,8 @@ def board(board: Optional[chess.BaseBoard] = None, *, coordinates: bool = True, colors: Dict[str, str] = {}, flipped: bool = False, - style: Optional[str] = None, - borders: bool = False) -> str: + borders: bool = False, + style: Optional[str] = None) -> str: """ Renders a board with pieces and/or selected squares as an SVG image. @@ -275,9 +275,9 @@ def board(board: Optional[chess.BaseBoard] = None, *, and ``arrow yellow``. Values should look like ``#ffce9e`` (opaque), or ``#15781B80`` (transparent). :param flipped: Pass ``True`` to flip the board. - :param style: A CSS stylesheet to include in the SVG image. :param borders: Pass ``True`` to enable a border around the board and, - (if ``coordinates`` is enabled) the coordinate margin. + (if *coordinates* is enabled) the coordinate margin. + :param style: A CSS stylesheet to include in the SVG image. >>> import chess >>> import chess.svg From ac294570687fb38db448e010590ff7f7d3bb89ff Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 24 Feb 2023 20:23:17 +0100 Subject: [PATCH 1593/1831] Improve chess.pgn error logs (closes #961) --- chess/pgn.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 1a01b034e..8750443c5 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -872,12 +872,13 @@ def builder(cls: Type[GameT]) -> GameBuilder[GameT]: return GameBuilder(Game=cls) def __repr__(self) -> str: - return "<{} at {:#x} ({!r} vs. {!r}, {!r}{})>".format( + return "<{} at {:#x} ({!r} vs. {!r}, {!r} at {!r}{})>".format( type(self).__name__, id(self), self.headers.get("White", "?"), self.headers.get("Black", "?"), self.headers.get("Date", "????.??.??"), + self.headers.get("Site", "?"), f", {len(self.errors)} errors" if self.errors else "") @@ -1202,7 +1203,7 @@ def handle_error(self, error: Exception) -> None: >>> >>> game = chess.pgn.read_game(pgn, Visitor=MyGameBuilder) """ - LOGGER.exception("error during pgn parsing") + LOGGER.error("%s while parsing %r", error, self.game) self.game.errors.append(error) def result(self) -> GameT: From 7d0b189084a27136b2e04816fb6d70a37a2a7735 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Sat, 25 Feb 2023 00:56:15 +0100 Subject: [PATCH 1594/1831] SVG: use a stroked rect for borders and margin This avoids painting the area under the squares. This makes it easier to use opacity for the field colors. --- chess/svg.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index dbcbc5321..008b0c87c 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -330,33 +330,39 @@ def board(board: Optional[chess.BaseBoard] = None, *, if outer_border: outer_border_color, outer_border_opacity = _select_color(colors, "outer border") ET.SubElement(svg, "rect", _attrs({ - "x": 0, - "y": 0, - "width": full_size, - "height": full_size, - "fill": outer_border_color, + "x": outer_border / 2, + "y": outer_border / 2, + "width": full_size - outer_border, + "height": full_size - outer_border, + "fill": "none", + "stroke": outer_border_color, + "stroke-width": outer_border, "opacity": outer_border_opacity if outer_border_opacity < 1.0 else None, })) if margin: margin_color, margin_opacity = _select_color(colors, "margin") ET.SubElement(svg, "rect", _attrs({ - "x": outer_border, - "y": outer_border, - "width": full_size - 2 * outer_border, - "height": full_size - 2 * outer_border, - "fill": margin_color, + "x": outer_border + margin / 2, + "y": outer_border + margin / 2, + "width": full_size - 2 * outer_border - margin, + "height": full_size - 2 * outer_border - margin, + "fill": "none", + "stroke": margin_color, + "stroke-width": margin, "opacity": margin_opacity if margin_opacity < 1.0 else None, })) if inner_border: inner_border_color, inner_border_opacity = _select_color(colors, "inner border") ET.SubElement(svg, "rect", _attrs({ - "x": outer_border + margin, - "y": outer_border + margin, - "width": full_size - 2 * outer_border - 2 * margin, - "height": full_size - 2 * outer_border - 2 * margin, - "fill": inner_border_color, + "x": outer_border + margin + inner_border / 2, + "y": outer_border + margin + inner_border / 2, + "width": full_size - 2 * outer_border - 2 * margin - inner_border, + "height": full_size - 2 * outer_border - 2 * margin - inner_border, + "fill": "none", + "stroke": inner_border_color, + "stroke-width": inner_border, "opacity": inner_border_opacity if inner_border_opacity < 1.0 else None, })) From d264559502ded8b6aa0bdaabd837f9e45f5a71b3 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 28 Feb 2023 00:14:55 -0800 Subject: [PATCH 1595/1831] Fix default values for rating configuration --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 8f21f74ef..b7551598a 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1946,8 +1946,8 @@ def __init__(self) -> None: "random": Option("random", "check", False, None, None, None), "computer": Option("computer", "check", False, None, None, None), "name": Option("name", "string", "", None, None, None), - "engine_rating": Option("engine_rating", "spin", "", None, None, None), - "opponent_rating": Option("opponent_rating", "spin", "", None, None, None) + "engine_rating": Option("engine_rating", "spin", 0, None, None, None), + "opponent_rating": Option("opponent_rating", "spin", 0, None, None, None) } self.config: Dict[str, ConfigValue] = {} self.target_config: Dict[str, ConfigValue] = {} From fe199c799a01b37852ca2d3473f1af63b29b58f7 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 1 Mar 2023 02:58:23 -0800 Subject: [PATCH 1596/1831] Create unified API for sending opponent info Opponent information will be sent after "new" (for XBoard engines) or "ucinewgame" (for UCI engines). --- chess/engine.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index b7551598a..5ff66c6c0 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1121,6 +1121,19 @@ async def configure(self, options: ConfigMapping) -> None: (:func:`chess.engine.Option.is_managed()`). """ + @abc.abstractmethod + async def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[int] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[int] = None) -> None: + """ + Sends the engine information about its opponent. The information will + be sent after a new game is announced and before the first move. + + :param opponent_name: Optional. The opponent's name. + :param opponent_rating: Optional. The opponent's ELO rating. + :param opponent_title: Optional. The opponent's title, such as GM, IM, and the like. + :param opponent_is_engine: Optional. Whether or not the opponent is another engine. + :param engine_rating: Optional. This engine's own rating. Only used by XBoard engines. + """ + @abc.abstractmethod async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: """ @@ -1435,6 +1448,9 @@ def _isready(self) -> None: def _ucinewgame(self) -> None: self.send_line("ucinewgame") + opponent_info = self.config.get("UCI_Opponent") + if opponent_info: + self.send_line(f"setoption name UCI_Opponent value {opponent_info}") self.first_game = False self.ponderhit = False @@ -1481,7 +1497,8 @@ def _setoption(self, name: str, value: ConfigValue) -> None: builder.append("value") builder.append(str(value)) - self.send_line(" ".join(builder)) + if name != "UCI_Opponent": # sent after ucinewgame + self.send_line(" ".join(builder)) self.config[name] = value def _configure(self, options: ConfigMapping) -> None: @@ -1500,6 +1517,13 @@ def start(self, engine: UciProtocol) -> None: return await self.communicate(UciConfigureCommand) + async def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[int] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[int] = None) -> None: + if opponent_name and "UCI_Opponent" in self.options: + rating = opponent_rating or "none" + title = opponent_title or "none" + player_type = "computer" if opponent_is_engine else "human" + return await self.configure({"UCI_Opponent": f"{title} {rating} {player_type} {opponent_name}"}) + def _position(self, board: chess.Board) -> None: # Select UCI_Variant and UCI_Chess960. uci_variant = type(board).uci_variant @@ -2406,6 +2430,16 @@ def start(self, engine: XBoardProtocol) -> None: return await self.communicate(XBoardConfigureCommand) + async def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[str] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[str] = None) -> None: + opponent_info = {"engine_rating": engine_rating or 0, + "opponent_rating": opponent_rating or 0, + "computer": opponent_is_engine} + + if self.features.get("name", True): + opponent_info["name"] = opponent_name + + return await self.configure(opponent_info) + async def quit(self) -> None: self.send_line("quit") await asyncio.shield(self.returncode) @@ -2789,6 +2823,14 @@ def configure(self, options: ConfigMapping) -> None: future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() + def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[int] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[int] = None) -> None: + with self._not_shut_down(): + coro = asyncio.wait_for( + self.protocol.send_opponent_information(opponent_name=opponent_name, opponent_rating=opponent_rating, opponent_title=opponent_title, opponent_is_engine=opponent_is_engine, engine_rating=engine_rating), + self.timeout) + future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) + return future.result + def ping(self) -> None: with self._not_shut_down(): coro = asyncio.wait_for(self.protocol.ping(), self.timeout) From b2b6163c724241a0c1c1d1dac8d94b8a31abb63c Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 1 Mar 2023 03:18:52 -0800 Subject: [PATCH 1597/1831] Fix errors found by mypy --- chess/engine.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 5ff66c6c0..967f8148b 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2430,12 +2430,12 @@ def start(self, engine: XBoardProtocol) -> None: return await self.communicate(XBoardConfigureCommand) - async def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[str] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[str] = None) -> None: - opponent_info = {"engine_rating": engine_rating or 0, - "opponent_rating": opponent_rating or 0, - "computer": opponent_is_engine} + async def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[int] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[int] = None) -> None: + opponent_info: Dict[str, Union[int, bool, str]] = {"engine_rating": engine_rating or 0, + "opponent_rating": opponent_rating or 0, + "computer": opponent_is_engine} - if self.features.get("name", True): + if opponent_name and self.features.get("name", True): opponent_info["name"] = opponent_name return await self.configure(opponent_info) @@ -2829,7 +2829,7 @@ def send_opponent_information(self, *, opponent_name: Optional[str] = None, oppo self.protocol.send_opponent_information(opponent_name=opponent_name, opponent_rating=opponent_rating, opponent_title=opponent_title, opponent_is_engine=opponent_is_engine, engine_rating=engine_rating), self.timeout) future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) - return future.result + return future.result() def ping(self) -> None: with self._not_shut_down(): From 1a642926f3d6d36d3518b0373abfd0fe0182c8f1 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 1 Mar 2023 03:51:48 -0800 Subject: [PATCH 1598/1831] Add title to opponent's name, if available --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 967f8148b..43d9cbcb7 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2436,7 +2436,7 @@ async def send_opponent_information(self, *, opponent_name: Optional[str] = None "computer": opponent_is_engine} if opponent_name and self.features.get("name", True): - opponent_info["name"] = opponent_name + opponent_info["name"] = f"{opponent_title or ''} {opponent_name}".strip() return await self.configure(opponent_info) From 69a5e0f6be881af449e05eba4d49f5b4a7123118 Mon Sep 17 00:00:00 2001 From: James Braza Date: Sat, 4 Mar 2023 13:07:05 -0800 Subject: [PATCH 1599/1831] Added clarity on SimpleEngine, module docstrings to code examples, and removed >>> from interpreter --- docs/engine.rst | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/docs/engine.rst b/docs/engine.rst index 979d0e915..4db5014c3 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -19,6 +19,7 @@ The preferred way to use the API is with an The examples also show a synchronous wrapper :class:`~chess.engine.SimpleEngine` that automatically spawns an event loop in the background. +:class:`~chess.engine.SimpleEngine` methods block until there is a result. Playing ------- @@ -27,6 +28,8 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. .. code:: python + """Using synchronous engine.SimpleEngine.""" + import chess import chess.engine @@ -41,6 +44,8 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. .. code:: python + """Using async engine.""" + import asyncio import chess import chess.engine @@ -74,6 +79,8 @@ Example: .. code:: python + """Using synchronous engine.SimpleEngine.""" + import chess import chess.engine @@ -93,6 +100,8 @@ Example: .. code:: python + """Using async engine.""" + import asyncio import chess import chess.engine @@ -139,6 +148,8 @@ Example: Stream information from the engine and stop on an arbitrary condition. .. code:: python + """Using synchronous engine.SimpleEngine.""" + import chess import chess.engine @@ -156,6 +167,8 @@ Example: Stream information from the engine and stop on an arbitrary condition. .. code:: python + """Using async engine.""" + import asyncio import chess import chess.engine @@ -193,21 +206,27 @@ Options :func:`~chess.Protocol.analyse()` and :func:`~chess.Protocol.analysis()` accept a dictionary of options. ->>> import chess.engine ->>> ->>> engine = chess.engine.SimpleEngine.popen_uci("/usr/bin/stockfish") ->>> ->>> # Check available options. ->>> engine.options["Hash"] -Option(name='Hash', type='spin', default=16, min=1, max=131072, var=[]) ->>> ->>> # Set an option. ->>> engine.configure({"Hash": 32}) ->>> ->>> # [...] +.. code:: python + + """Using synchronous engine.SimpleEngine.""" + + import chess.engine + + engine = chess.engine.SimpleEngine.popen_uci("/usr/bin/stockfish") + + # Check available options. + engine.options["Hash"] + # Option(name='Hash', type='spin', default=16, min=1, max=131072, var=[]) + + # Set an option. + engine.configure({"Hash": 32}) + + # [...] .. code:: python + """Using async engine.""" + import asyncio import chess.engine From 0192ebda9a733b25fd4c51ca7758b194c0f2516d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 6 Mar 2023 21:11:38 +0100 Subject: [PATCH 1600/1831] Try code-block captions for #973 --- docs/engine.rst | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/docs/engine.rst b/docs/engine.rst index 4db5014c3..08f8f8f5e 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -26,9 +26,8 @@ Playing Example: Let Stockfish play against itself, 100 milliseconds per move. -.. code:: python - - """Using synchronous engine.SimpleEngine.""" +.. code-block:: python + :caption: Using synchronous :class:`~chess.engine.SimpleEngine` import chess import chess.engine @@ -42,9 +41,8 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. engine.quit() -.. code:: python - - """Using async engine.""" +.. code-block:: python + :caption: Using asyncio import asyncio import chess @@ -77,9 +75,8 @@ Analysing and evaluating a position Example: -.. code:: python - - """Using synchronous engine.SimpleEngine.""" +.. code-block:: python + :caption: Using synchronous :class:`~chess.engine.SimpleEngine` import chess import chess.engine @@ -98,9 +95,8 @@ Example: engine.quit() -.. code:: python - - """Using async engine.""" +.. code-block:: python + :caption: Using asyncio import asyncio import chess @@ -146,9 +142,8 @@ Indefinite or infinite analysis Example: Stream information from the engine and stop on an arbitrary condition. -.. code:: python - - """Using synchronous engine.SimpleEngine.""" +.. code-block:: python + :caption: Using synchronous :class:`~chess.engine.SimpleEngine` import chess import chess.engine @@ -165,9 +160,8 @@ Example: Stream information from the engine and stop on an arbitrary condition. engine.quit() -.. code:: python - - """Using async engine.""" +.. code-block:: python + :caption: Using asyncio import asyncio import chess @@ -206,9 +200,8 @@ Options :func:`~chess.Protocol.analyse()` and :func:`~chess.Protocol.analysis()` accept a dictionary of options. -.. code:: python - - """Using synchronous engine.SimpleEngine.""" +.. code-block:: python + :caption: Using synchronous :class:`~chess.engine.SimpleEngine` import chess.engine @@ -223,9 +216,8 @@ Options # [...] -.. code:: python - - """Using async engine.""" +.. code-block:: python + :caption: Using asyncio import asyncio import chess.engine From c408d7c7107efad71ec46d6cec0c39569fd8f352 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 7 Mar 2023 20:11:32 -0800 Subject: [PATCH 1601/1831] Make Opponent class to store opponent information --- chess/engine.py | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 43d9cbcb7..4ec23941f 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -438,6 +438,15 @@ class Info(enum.IntFlag): INFO_ALL = Info.ALL +@dataclasses.dataclass +class Opponent: + """Used to store information about an engine's opponent.""" + name: Optional[str] + title: Optional[str] + rating: Optional[int] + is_engine = False + + class PovScore: """A relative :class:`~chess.engine.Score` and the point of view.""" @@ -1122,15 +1131,12 @@ async def configure(self, options: ConfigMapping) -> None: """ @abc.abstractmethod - async def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[int] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[int] = None) -> None: + async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: """ Sends the engine information about its opponent. The information will be sent after a new game is announced and before the first move. - :param opponent_name: Optional. The opponent's name. - :param opponent_rating: Optional. The opponent's ELO rating. - :param opponent_title: Optional. The opponent's title, such as GM, IM, and the like. - :param opponent_is_engine: Optional. Whether or not the opponent is another engine. + :param opponent: Optional. The opponent's information. :param engine_rating: Optional. This engine's own rating. Only used by XBoard engines. """ @@ -1517,12 +1523,12 @@ def start(self, engine: UciProtocol) -> None: return await self.communicate(UciConfigureCommand) - async def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[int] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[int] = None) -> None: - if opponent_name and "UCI_Opponent" in self.options: - rating = opponent_rating or "none" - title = opponent_title or "none" - player_type = "computer" if opponent_is_engine else "human" - return await self.configure({"UCI_Opponent": f"{title} {rating} {player_type} {opponent_name}"}) + async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: + if opponent and opponent.name and "UCI_Opponent" in self.options: + rating = opponent.rating or "none" + title = opponent.title or "none" + player_type = "computer" if opponent.is_engine else "human" + return await self.configure({"UCI_Opponent": f"{title} {rating} {player_type} {opponent.name}"}) def _position(self, board: chess.Board) -> None: # Select UCI_Variant and UCI_Chess960. @@ -2430,13 +2436,16 @@ def start(self, engine: XBoardProtocol) -> None: return await self.communicate(XBoardConfigureCommand) - async def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[int] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[int] = None) -> None: + async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: + if opponent is None: + return + opponent_info: Dict[str, Union[int, bool, str]] = {"engine_rating": engine_rating or 0, - "opponent_rating": opponent_rating or 0, - "computer": opponent_is_engine} + "opponent_rating": opponent.rating or 0, + "computer": opponent.is_engine} - if opponent_name and self.features.get("name", True): - opponent_info["name"] = f"{opponent_title or ''} {opponent_name}".strip() + if opponent.name and self.features.get("name", True): + opponent_info["name"] = f"{opponent.title or ''} {opponent.name}".strip() return await self.configure(opponent_info) @@ -2823,10 +2832,10 @@ def configure(self, options: ConfigMapping) -> None: future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() - def send_opponent_information(self, *, opponent_name: Optional[str] = None, opponent_rating: Optional[int] = None, opponent_title: Optional[str] = None, opponent_is_engine: bool = False, engine_rating: Optional[int] = None) -> None: + def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: with self._not_shut_down(): coro = asyncio.wait_for( - self.protocol.send_opponent_information(opponent_name=opponent_name, opponent_rating=opponent_rating, opponent_title=opponent_title, opponent_is_engine=opponent_is_engine, engine_rating=engine_rating), + self.protocol.send_opponent_information(opponent=opponent, engine_rating=engine_rating), self.timeout) future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() From dcdd7020956316ec69e519d461713eca81ae22c0 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 7 Mar 2023 20:38:43 -0800 Subject: [PATCH 1602/1831] Fix default argument and type --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 4ec23941f..feac6fc64 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -444,7 +444,7 @@ class Opponent: name: Optional[str] title: Optional[str] rating: Optional[int] - is_engine = False + is_engine: Optional[bool] class PovScore: From 49d31322dc24786de386565cfd94152e6e25884f Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 7 Mar 2023 20:47:01 -0800 Subject: [PATCH 1603/1831] Coerce entry to bool --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index feac6fc64..ba5c6ff88 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2442,7 +2442,7 @@ async def send_opponent_information(self, *, opponent: Optional[Opponent] = None opponent_info: Dict[str, Union[int, bool, str]] = {"engine_rating": engine_rating or 0, "opponent_rating": opponent.rating or 0, - "computer": opponent.is_engine} + "computer": opponent.is_engine or False} if opponent.name and self.features.get("name", True): opponent_info["name"] = f"{opponent.title or ''} {opponent.name}".strip() From 1613a31cb74e9aeb2de140f9e5d9b096ee7a8cfa Mon Sep 17 00:00:00 2001 From: Trevor Bayless Date: Fri, 10 Mar 2023 08:40:06 -0600 Subject: [PATCH 1604/1831] Remove unused ponderhit code --- chess/engine.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 402252f83..d94bc028f 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1577,9 +1577,6 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None self.send_line(" ".join(builder)) async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: - same_game = not self.first_game and game == self.game and not options - self.last_move = board.move_stack[-1] if (same_game and ponder and board.move_stack) else chess.Move.null() - class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): def __init__(self, engine: UciProtocol): super().__init__(engine) From 1f975c4000f91b1a54f368b3830641ab7e7ec159 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Mon, 13 Mar 2023 00:11:33 -0700 Subject: [PATCH 1605/1831] Add opponent information to play() method --- chess/engine.py | 61 +++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index ba5c6ff88..2545b6ea8 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1141,7 +1141,7 @@ async def send_opponent_information(self, *, opponent: Optional[Opponent] = None """ @abc.abstractmethod - async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}, opponent: Optional[Opponent] = None) -> PlayResult: """ Plays a position. @@ -1167,6 +1167,10 @@ async def play(self, board: chess.Board, limit: Limit, *, game: object = None, i analysis. The previous configuration will be restored after the analysis is complete. You can permanently apply a configuration with :func:`~chess.engine.Protocol.configure()`. + :param opponent: Optional. Information about a new opponent. Information + about the original opponent will be restored once the move is + complete. New opponent information can be made permanent with + :func:`~chess.engine.Protocol.send_opponent_information()`. """ @typing.overload @@ -1452,9 +1456,9 @@ def _id(self, engine: UciProtocol, arg: str) -> None: def _isready(self) -> None: self.send_line("isready") - def _ucinewgame(self) -> None: + def _ucinewgame(self, *, opponent: Optional[Opponent] = None) -> None: self.send_line("ucinewgame") - opponent_info = self.config.get("UCI_Opponent") + opponent_info = self._opponent_configuration(opponent=opponent).get("UCI_Opponent") or self.config.get("UCI_Opponent") if opponent_info: self.send_line(f"setoption name UCI_Opponent value {opponent_info}") self.first_game = False @@ -1523,12 +1527,17 @@ def start(self, engine: UciProtocol) -> None: return await self.communicate(UciConfigureCommand) - async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: + def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> ConfigMapping: if opponent and opponent.name and "UCI_Opponent" in self.options: rating = opponent.rating or "none" title = opponent.title or "none" player_type = "computer" if opponent.is_engine else "human" - return await self.configure({"UCI_Opponent": f"{title} {rating} {player_type} {opponent.name}"}) + return {"UCI_Opponent": f"{title} {rating} {player_type} {opponent.name}"} + else: + return {} + + async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: + return await self.configure(self._opponent_configuration(opponent=opponent, engine_rating=engine_rating)) def _position(self, board: chess.Board) -> None: # Select UCI_Variant and UCI_Chess960. @@ -1606,7 +1615,7 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None builder.append("0000") self.send_line(" ".join(builder)) - async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}, opponent: Optional[Opponent] = None) -> PlayResult: same_game = not self.first_game and game == self.game and not options self.last_move = board.move_stack[-1] if (same_game and ponder and board.move_stack) else chess.Move.null() @@ -1639,9 +1648,9 @@ def start(self, engine: UciProtocol) -> None: engine._configure(options) - if engine.first_game or engine.game != game: + if engine.first_game or engine.game != game or opponent: engine.game = game - engine._ucinewgame() + engine._ucinewgame(opponent=opponent) self.sent_isready = True engine._isready() else: @@ -2083,13 +2092,13 @@ def _variant(self, variant: Optional[str]) -> None: self.send_line(f"variant {variant}") - def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None: + def _new(self, board: chess.Board, game: object, options: ConfigMapping, opponent: Optional[Opponent] = None) -> None: self._configure(options) # Set up starting position. root = board.root() new_options = any(param in options for param in ("random", "computer", "name", "engine_rating", "opponent_rating")) - new_game = self.first_game or self.game != game or new_options or root != self.board.root() + new_game = self.first_game or self.game != game or new_options or opponent or root != self.board.root() self.game = game self.first_game = False if new_game: @@ -2104,11 +2113,16 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping) -> None if self.config.get("random"): self.send_line("random") - if self.config.get("name") and self.features.get("name", True): + + opponent_name = (opponent.name if opponent else None) or self.config.get("name") + if opponent_name and self.features.get("name", True): self.send_line(f"name {self.config['name']}") - if self.config.get("engine_rating") or self.config.get("opponent_rating"): - self.send_line(f"rating {self.config.get('engine_rating') or 0} {self.config.get('opponent_rating') or 0}") - if self.config.get("computer"): + + opponent_rating = (opponent.rating if opponent else None) or self.config.get("opponent_rating") or 0 + if self.config.get("engine_rating") or opponent_rating: + self.send_line(f"rating {self.config.get('engine_rating') or 0} {opponent_rating}") + + if (opponent and opponent.is_engine) or self.config.get("computer"): self.send_line("computer") self.send_line("force") @@ -2162,7 +2176,7 @@ def line_received(self, engine: XBoardProtocol, line: str) -> None: return await self.communicate(XBoardPingCommand) - async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}, opponent: Optional[Opponent] = None) -> PlayResult: if root_moves is not None: raise EngineError("play with root_moves, but xboard supports 'include' only in analysis mode") @@ -2174,7 +2188,7 @@ def start(self, engine: XBoardProtocol) -> None: self.pong_after_ponder: Optional[str] = None # Set game, position and configure. - engine._new(board, game, options) + engine._new(board, game, options, opponent) # Limit or time control. clock = limit.white_clock if board.turn else limit.black_clock @@ -2436,9 +2450,9 @@ def start(self, engine: XBoardProtocol) -> None: return await self.communicate(XBoardConfigureCommand) - async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: + def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> ConfigMapping: if opponent is None: - return + return {} opponent_info: Dict[str, Union[int, bool, str]] = {"engine_rating": engine_rating or 0, "opponent_rating": opponent.rating or 0, @@ -2446,8 +2460,11 @@ async def send_opponent_information(self, *, opponent: Optional[Opponent] = None if opponent.name and self.features.get("name", True): opponent_info["name"] = f"{opponent.title or ''} {opponent.name}".strip() - - return await self.configure(opponent_info) + + return opponent_info + + async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: + return await self.configure(self._opponent_configuration(opponent=opponent, engine_rating=engine_rating)) async def quit(self) -> None: self.send_line("quit") @@ -2846,10 +2863,10 @@ def ping(self) -> None: future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() - def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> PlayResult: + def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}, opponent: Optional[Opponent] = None) -> PlayResult: with self._not_shut_down(): coro = asyncio.wait_for( - self.protocol.play(board, limit, game=game, info=info, ponder=ponder, draw_offered=draw_offered, root_moves=root_moves, options=options), + self.protocol.play(board, limit, game=game, info=info, ponder=ponder, draw_offered=draw_offered, root_moves=root_moves, options=options, opponent=opponent), self._timeout_for(limit)) future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() From f24517d23e4183ae12b373be267105335250cfad Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 15 Mar 2023 02:15:03 -0700 Subject: [PATCH 1606/1831] Add tests for play() method with opponent Requires that opponent information is always and only sent after a ucinewgame message. Specifying a new opponent in the play() method results in a new game starting. --- test.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test.py b/test.py index 29ea02749..a9dd5d89b 100755 --- a/test.py +++ b/test.py @@ -3271,13 +3271,18 @@ async def main(): mock.expect("uci", [ "option name Hash type spin default 16 min 1 max 33554432", "option name Ponder type check default false", + "option name UCI_Opponent type string", "uciok", ]) await protocol.initialize() + primary_opponent = chess.engine.Opponent("Eliza", None, 3500, True) + await protocol.send_opponent_information(opponent=primary_opponent) + # First search. mock.expect("setoption name Ponder value true") mock.expect("ucinewgame") + mock.expect("setoption name UCI_Opponent value none 3500 computer Eliza") mock.expect("isready", ["readyok"]) mock.expect("position startpos") mock.expect("go movetime 1000", ["bestmove d2d4 ponder g8f6"]) @@ -3341,6 +3346,33 @@ async def main(): mock.expect("go ponder movetime 5000") await protocol.play(board, chess.engine.Limit(time=5), ponder=True) + # Ponderhit prevented by new opponent, which starts a new game. + board.push(chess.Move.from_uci("c4d5")) + board.push(chess.Move.from_uci("e6d5")) + mock.expect("stop", ["bestmove c1g5 ponder h7h6"]) + mock.expect("ucinewgame") + mock.expect("setoption name UCI_Opponent value GM 3000 human Guy Chapman") + mock.expect("isready", ["readyok"]) + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 d7d5 c4d5 e6d5") + mock.expect("go movetime 5000", ["bestmove c1g5 ponder h7h6"]) + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 d7d5 c4d5 e6d5 c1g5 h7h6") + mock.expect("go ponder movetime 5000") + opponent = chess.engine.Opponent("Guy Chapman", "GM", 3000, False) + await protocol.play(board, chess.engine.Limit(time=5), ponder=True, opponent=opponent) + + # Ponderhit prevented by restoration of previous opponent, which again starts a new game. + board.push(chess.Move.from_uci("c1g5")) + board.push(chess.Move.from_uci("h7h6")) + mock.expect("stop", ["bestmove g5h4 ponder b8c6"]) + mock.expect("ucinewgame") + mock.expect("setoption name UCI_Opponent value none 3500 computer Eliza") + mock.expect("isready", ["readyok"]) + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 d7d5 c4d5 e6d5 c1g5 h7h6") + mock.expect("go movetime 5000", ["bestmove g5h4 ponder b8c6"]) + mock.expect("position startpos moves d2d4 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 d7d5 c4d5 e6d5 c1g5 h7h6 g5h4 b8c6") + mock.expect("go ponder movetime 5000") + await protocol.play(board, chess.engine.Limit(time=5), ponder=True) + mock.assert_done() asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) From 881160ead51d3a2e6b78b747768b7a5aa047fb9a Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 15 Mar 2023 02:17:06 -0700 Subject: [PATCH 1607/1831] Conform play() method with opponent to test If the opponent is changed through the play method, a new game is started with the current board position. This includes a blank opponent that follows an opponent specification on a previous move. --- chess/engine.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 149b3ff21..04899790b 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1369,6 +1369,8 @@ def __init__(self) -> None: self.first_game = True self.may_ponderhit: Optional[chess.Board] = None self.ponderhit = False + self.opponent: Optional[Opponent] = None + self.play_opponent: Optional[Opponent] = None async def initialize(self) -> None: class UciInitializeCommand(BaseCommand[UciProtocol, None]): @@ -1456,11 +1458,23 @@ def _id(self, engine: UciProtocol, arg: str) -> None: def _isready(self) -> None: self.send_line("isready") - def _ucinewgame(self, *, opponent: Optional[Opponent] = None) -> None: - self.send_line("ucinewgame") - opponent_info = self._opponent_configuration(opponent=opponent).get("UCI_Opponent") or self.config.get("UCI_Opponent") + def _opponent_changed(self, opponent: Optional[Opponent]) -> bool: + if self.play_opponent: + return opponent != self.play_opponent + elif opponent: + return opponent != self.opponent + + return False + + def _opponent_info(self) -> None: + opponent = self.play_opponent or self.opponent + opponent_info = self._opponent_configuration(opponent=opponent).get("UCI_Opponent") if opponent_info: self.send_line(f"setoption name UCI_Opponent value {opponent_info}") + + def _ucinewgame(self) -> None: + self.send_line("ucinewgame") + self._opponent_info() self.first_game = False self.ponderhit = False @@ -1537,6 +1551,7 @@ def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine return {} async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: + self.opponent = opponent return await self.configure(self._opponent_configuration(opponent=opponent, engine_rating=engine_rating)) def _position(self, board: chess.Board) -> None: @@ -1623,7 +1638,7 @@ def __init__(self, engine: UciProtocol): # May ponderhit only in the same game and with unchanged target # options. The managed options UCI_AnalyseMode, Ponder, and # MultiPV never change between pondering play commands. - engine.may_ponderhit = board if ponder and not engine.first_game and game == engine.game and not engine._changed_options(options) else None + engine.may_ponderhit = board if ponder and not engine.first_game and game == engine.game and not engine._changed_options(options) and not engine._opponent_changed(opponent) else None def start(self, engine: UciProtocol) -> None: self.info: InfoDict = {} @@ -1645,9 +1660,10 @@ def start(self, engine: UciProtocol) -> None: engine._configure(options) - if engine.first_game or engine.game != game or opponent: + if engine.first_game or engine.game != game or engine._opponent_changed(opponent): engine.game = game - engine._ucinewgame(opponent=opponent) + engine.play_opponent = opponent + engine._ucinewgame() self.sent_isready = True engine._isready() else: From 35beb1f226a2adc8751859275d7c2775d82840c8 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 15 Mar 2023 02:20:40 -0700 Subject: [PATCH 1608/1831] Update send_opponent_information() docstring --- chess/engine.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 04899790b..b0486bf48 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1134,7 +1134,9 @@ async def configure(self, options: ConfigMapping) -> None: async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: """ Sends the engine information about its opponent. The information will - be sent after a new game is announced and before the first move. + be sent after a new game is announced and before the first move. This + method should be called before the first move of a game--i.e., the + first call to :func:`chess.engine.Protocol.play()`. :param opponent: Optional. The opponent's information. :param engine_rating: Optional. This engine's own rating. Only used by XBoard engines. From 7a5f82ae250a953b42b78886f3e71a13c99f9f00 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 15 Mar 2023 23:08:49 -0700 Subject: [PATCH 1609/1831] Use Protocol.config to update opponent Instead of having separate members of the UciProtocol class incorporate new opponent information into the config argument to simplify code. --- chess/engine.py | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index b0486bf48..5fe95f960 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1371,8 +1371,6 @@ def __init__(self) -> None: self.first_game = True self.may_ponderhit: Optional[chess.Board] = None self.ponderhit = False - self.opponent: Optional[Opponent] = None - self.play_opponent: Optional[Opponent] = None async def initialize(self) -> None: class UciInitializeCommand(BaseCommand[UciProtocol, None]): @@ -1460,17 +1458,8 @@ def _id(self, engine: UciProtocol, arg: str) -> None: def _isready(self) -> None: self.send_line("isready") - def _opponent_changed(self, opponent: Optional[Opponent]) -> bool: - if self.play_opponent: - return opponent != self.play_opponent - elif opponent: - return opponent != self.opponent - - return False - def _opponent_info(self) -> None: - opponent = self.play_opponent or self.opponent - opponent_info = self._opponent_configuration(opponent=opponent).get("UCI_Opponent") + opponent_info = self.config.get("UCI_Opponent") or self.target_config.get("UCI_Opponent") if opponent_info: self.send_line(f"setoption name UCI_Opponent value {opponent_info}") @@ -1553,7 +1542,6 @@ def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine return {} async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: - self.opponent = opponent return await self.configure(self._opponent_configuration(opponent=opponent, engine_rating=engine_rating)) def _position(self, board: chess.Board) -> None: @@ -1633,6 +1621,11 @@ def _go(self, limit: Limit, *, root_moves: Optional[Iterable[chess.Move]] = None self.send_line(" ".join(builder)) async def play(self, board: chess.Board, limit: Limit, *, game: object = None, info: Info = INFO_NONE, ponder: bool = False, draw_offered: bool = False, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}, opponent: Optional[Opponent] = None) -> PlayResult: + new_options: Dict[str, ConfigValue] = {} + for name, value in options.items(): + new_options[name] = value + new_options.update(self._opponent_configuration(opponent=opponent)) + class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): def __init__(self, engine: UciProtocol): super().__init__(engine) @@ -1640,7 +1633,7 @@ def __init__(self, engine: UciProtocol): # May ponderhit only in the same game and with unchanged target # options. The managed options UCI_AnalyseMode, Ponder, and # MultiPV never change between pondering play commands. - engine.may_ponderhit = board if ponder and not engine.first_game and game == engine.game and not engine._changed_options(options) and not engine._opponent_changed(opponent) else None + engine.may_ponderhit = board if ponder and not engine.first_game and game == engine.game and not engine._changed_options(new_options) else None def start(self, engine: UciProtocol) -> None: self.info: InfoDict = {} @@ -1653,18 +1646,19 @@ def start(self, engine: UciProtocol) -> None: engine.send_line("ponderhit") return - if "UCI_AnalyseMode" in engine.options and "UCI_AnalyseMode" not in engine.target_config and all(name.lower() != "uci_analysemode" for name in options): + if "UCI_AnalyseMode" in engine.options and "UCI_AnalyseMode" not in engine.target_config and all(name.lower() != "uci_analysemode" for name in new_options): engine._setoption("UCI_AnalyseMode", False) if "Ponder" in engine.options: engine._setoption("Ponder", ponder) if "MultiPV" in engine.options: engine._setoption("MultiPV", engine.options["MultiPV"].default) - engine._configure(options) + new_opponent = new_options.get("UCI_Opponent") or engine.target_config.get("UCI_Opponent") + opponent_changed = new_opponent != engine.config.get("UCI_Opponent") + engine._configure(new_options) - if engine.first_game or engine.game != game or engine._opponent_changed(opponent): + if engine.first_game or engine.game != game or opponent_changed: engine.game = game - engine.play_opponent = opponent engine._ucinewgame() self.sent_isready = True engine._isready() From 28aa39a6b8fb64ce75e4024095995e754977b78b Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 16 Mar 2023 00:09:31 -0700 Subject: [PATCH 1610/1831] Remove options handled by Opponent class --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 5fe95f960..80b757858 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2106,7 +2106,7 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping, opponen # Set up starting position. root = board.root() - new_options = any(param in options for param in ("random", "computer", "name", "engine_rating", "opponent_rating")) + new_options = any(param in options for param in ("random", "computer")) new_game = self.first_game or self.game != game or new_options or opponent or root != self.board.root() self.game = game self.first_game = False From 191a1c1f8c1b41f20f35fb757148f7fafab00869 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 16 Mar 2023 00:10:06 -0700 Subject: [PATCH 1611/1831] XBoard engines don't have to support name option --- chess/engine.py | 1 - 1 file changed, 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 80b757858..4b7b4b976 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1993,7 +1993,6 @@ def __init__(self) -> None: self.options = { "random": Option("random", "check", False, None, None, None), "computer": Option("computer", "check", False, None, None, None), - "name": Option("name", "string", "", None, None, None), "engine_rating": Option("engine_rating", "spin", 0, None, None, None), "opponent_rating": Option("opponent_rating", "spin", 0, None, None, None) } From 3685db1634d545b5198438192687ee0b3ecd8539 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 16 Mar 2023 00:16:54 -0700 Subject: [PATCH 1612/1831] Protocol.target_config contains current opponent --- chess/engine.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 4b7b4b976..c99aa49a9 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2122,15 +2122,15 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping, opponen if self.config.get("random"): self.send_line("random") - opponent_name = (opponent.name if opponent else None) or self.config.get("name") + opponent_name = (opponent.name if opponent else None) or self.target_config.get("name") if opponent_name and self.features.get("name", True): - self.send_line(f"name {self.config['name']}") + self.send_line(f"name {opponent_name}") - opponent_rating = (opponent.rating if opponent else None) or self.config.get("opponent_rating") or 0 - if self.config.get("engine_rating") or opponent_rating: - self.send_line(f"rating {self.config.get('engine_rating') or 0} {opponent_rating}") + opponent_rating = (opponent.rating if opponent else None) or self.target_config.get("opponent_rating") or 0 + if self.target_config.get("engine_rating") or opponent_rating: + self.send_line(f"rating {self.target_config.get('engine_rating') or 0} {opponent_rating}") - if (opponent and opponent.is_engine) or self.config.get("computer"): + if (opponent and opponent.is_engine) or (self.target_config.get("computer") if self.config.get("computer") is None else self.config.get("computer")): self.send_line("computer") self.send_line("force") From da4106369ccf13b9399e262d5757feb219041a47 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 16 Mar 2023 00:50:56 -0700 Subject: [PATCH 1613/1831] Revert "XBoard engines don't have to support name option" This reverts commit 191a1c1f8c1b41f20f35fb757148f7fafab00869. The default is that XBoard engines accept the "name" feature. --- chess/engine.py | 1 + 1 file changed, 1 insertion(+) diff --git a/chess/engine.py b/chess/engine.py index c99aa49a9..c3b863032 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1993,6 +1993,7 @@ def __init__(self) -> None: self.options = { "random": Option("random", "check", False, None, None, None), "computer": Option("computer", "check", False, None, None, None), + "name": Option("name", "string", "", None, None, None), "engine_rating": Option("engine_rating", "spin", 0, None, None, None), "opponent_rating": Option("opponent_rating", "spin", 0, None, None, None) } From 87ec56a9473a5074a89a592e0a2e68664795bdc6 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 16 Mar 2023 00:52:29 -0700 Subject: [PATCH 1614/1831] Test sending opponent information to XBoard engine --- test.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test.py b/test.py index a9dd5d89b..42f77ea68 100755 --- a/test.py +++ b/test.py @@ -3542,8 +3542,14 @@ async def main(): board.push_san("d4") board.push_san("Nf6") board.push_san("c4") + opponent = chess.engine.Opponent("Turk", None, 2100, True) + engine_rating = 3600 + await protocol.send_opponent_information(opponent=opponent, engine_rating=engine_rating) mock.expect("new") + mock.expect("name Turk") + mock.expect("rating 3600 2100") + mock.expect("computer") mock.expect("force") mock.expect("d2d4") mock.expect("g8f6") From a904617d389e0f179f24ab8e5b4b327d7bf15cdd Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 16 Mar 2023 23:00:54 -0700 Subject: [PATCH 1615/1831] Complete opponent information --- test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index 42f77ea68..f0ba7d9dc 100755 --- a/test.py +++ b/test.py @@ -3542,12 +3542,12 @@ async def main(): board.push_san("d4") board.push_san("Nf6") board.push_san("c4") - opponent = chess.engine.Opponent("Turk", None, 2100, True) + opponent = chess.engine.Opponent("Turk", "Mechanical", 2100, True) engine_rating = 3600 await protocol.send_opponent_information(opponent=opponent, engine_rating=engine_rating) mock.expect("new") - mock.expect("name Turk") + mock.expect("name Mechanical Turk") mock.expect("rating 3600 2100") mock.expect("computer") mock.expect("force") From 06e314531a6c653c537921faf70c2dce2813a57a Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 16 Mar 2023 23:16:31 -0700 Subject: [PATCH 1616/1831] Move XBoard opponent tests to own method --- test.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/test.py b/test.py index f0ba7d9dc..56843fde1 100755 --- a/test.py +++ b/test.py @@ -3542,14 +3542,8 @@ async def main(): board.push_san("d4") board.push_san("Nf6") board.push_san("c4") - opponent = chess.engine.Opponent("Turk", "Mechanical", 2100, True) - engine_rating = 3600 - await protocol.send_opponent_information(opponent=opponent, engine_rating=engine_rating) mock.expect("new") - mock.expect("name Mechanical Turk") - mock.expect("rating 3600 2100") - mock.expect("computer") mock.expect("force") mock.expect("d2d4") mock.expect("g8f6") @@ -3595,6 +3589,55 @@ async def main(): asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) + def test_xboard_opponent(self): + async def main(): + protocol = chess.engine.XBoardProtocol() + mock = chess.engine.MockTransport(protocol) + + mock.expect("xboard") + mock.expect("protover 2", ["feature ping=1 setboard=1 name=1 done=1"]) + await protocol.initialize() + mock.assert_done() + + limit = chess.engine.Limit(time=5) + board = chess.Board() + opponent = chess.engine.Opponent("Turk", "Mechanical", 2100, True) + await protocol.send_opponent_information(opponent=opponent, engine_rating=3600) + + mock.expect("new") + mock.expect("name Mechanical Turk") + mock.expect("rating 3600 2100") + mock.expect("computer") + mock.expect("force") + mock.expect("st 5") + mock.expect("nopost") + mock.expect("easy") + mock.expect("go", ["move e2e4"]) + mock.expect_ping() + result = await protocol.play(board, limit, game="game") + self.assertEqual(result.move, board.parse_san("e4")) + mock.assert_done() + + new_opponent = chess.engine.Opponent("Turochamp", None, 800, True) + board.push(result.move) + mock.expect("new") + mock.expect("name Turochamp") + mock.expect("rating 3600 800") + mock.expect("computer") + mock.expect("force") + mock.expect("e2e4") + mock.expect("st 5") + mock.expect("nopost") + mock.expect("easy") + mock.expect("go", ["move e7e5"]) + mock.expect_ping() + result = await protocol.play(board, limit, game="game", opponent=new_opponent) + self.assertEqual(result.move, board.parse_san("e5")) + mock.assert_done() + + asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) + asyncio.run(main()) + def test_xboard_analyse(self): async def main(): protocol = chess.engine.XBoardProtocol() From 7d670a489ae0da06f4a9275f82fcfbd42979bb6e Mon Sep 17 00:00:00 2001 From: snowdrop4 <82846066+snowdrop4@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:04:14 +0100 Subject: [PATCH 1617/1831] add BaseVisitor.begin_parse_san() method --- chess/pgn.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 8750443c5..553b6ece6 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1043,6 +1043,13 @@ def end_headers(self) -> Optional[SkipType]: """Called after visiting game headers.""" pass + def begin_parse_san(self, board: chess.Board, san: str) -> Optional[SkipType]: + """ + When the visitor is used by a parser, this is called at the start of + each standard algebraic notation detailing a move. + """ + pass + def parse_san(self, board: chess.Board, san: str) -> chess.Move: """ When the visitor is used by a parser, this is called to parse a move @@ -1682,14 +1689,15 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: visitor.visit_result(token) else: # Parse SAN tokens. - try: - move = visitor.parse_san(board_stack[-1], token) - except ValueError as error: - visitor.handle_error(error) - skip_variation_depth = 1 - else: - visitor.visit_move(board_stack[-1], move) - board_stack[-1].push(move) + if visitor.begin_parse_san(board_stack[-1], token) is not SKIP: + try: + move = visitor.parse_san(board_stack[-1], token) + except ValueError as error: + visitor.handle_error(error) + skip_variation_depth = 1 + else: + visitor.visit_move(board_stack[-1], move) + board_stack[-1].push(move) visitor.visit_board(board_stack[-1]) if fresh_line: From 039239718d4137c1b37cc212238303c27829c957 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 31 Mar 2023 18:20:19 +0200 Subject: [PATCH 1618/1831] Add another insufficient material test --- test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test.py b/test.py index 56843fde1..0ca635d43 100755 --- a/test.py +++ b/test.py @@ -579,6 +579,7 @@ def _check(board, white, black): _check(chess.variant.CrazyhouseBoard("8/8/8/8/3k4/3N~4/3K4/8 w - - 0 1"), False, False) _check(chess.variant.HordeBoard("8/5k2/8/8/8/4NN2/8/8 w - - 0 1"), True, False) + _check(chess.variant.HordeBoard("8/1b5r/1P6/1Pk3q1/1PP5/r1P5/P1P5/2P5 b - - 0 52"), False, False) def test_promotion_with_check(self): board = chess.Board("8/6P1/2p5/1Pqk4/6P1/2P1RKP1/4P1P1/8 w - - 0 1") From 12c6211360a36fce4cd1f324b76a2caa54a091e1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 31 Mar 2023 18:42:59 +0200 Subject: [PATCH 1619/1831] Revert default Syzygy max_fds to 128 Python's mmap.mmap() actually (unnecessarily, with regard to our use case) duplicates the file descriptor and keeps a copy around for the lifetime of the memory map. --- chess/syzygy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 45eb963d0..2d835b200 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1483,7 +1483,7 @@ class Tablebase: """ Manages a collection of tablebase files for probing. """ - def __init__(self, *, max_fds: Optional[int] = None, VariantBoard: Type[chess.Board] = chess.Board) -> None: + def __init__(self, *, max_fds: Optional[int] = 128, VariantBoard: Type[chess.Board] = chess.Board) -> None: self.variant = VariantBoard self.max_fds = max_fds @@ -1963,7 +1963,7 @@ def __exit__(self, exc_type: Optional[Type[BaseException]], exc_value: Optional[ self.close() -def open_tablebase(directory: str, *, load_wdl: bool = True, load_dtz: bool = True, max_fds: Optional[int] = None, VariantBoard: Type[chess.Board] = chess.Board) -> Tablebase: +def open_tablebase(directory: str, *, load_wdl: bool = True, load_dtz: bool = True, max_fds: Optional[int] = 128, VariantBoard: Type[chess.Board] = chess.Board) -> Tablebase: """ Opens a collection of tables for probing. See :class:`~chess.syzygy.Tablebase`. From 363672783357ccfafb23a6917953ad4d61219047 Mon Sep 17 00:00:00 2001 From: Trevor Bayless Date: Fri, 31 Mar 2023 13:22:13 -0500 Subject: [PATCH 1620/1831] Add cli-chess --- README.rst | 5 +++++ docs/images/cli-chess.png | Bin 0 -> 3570 bytes 2 files changed, 5 insertions(+) create mode 100644 docs/images/cli-chess.png diff --git a/README.rst b/README.rst index aae81e788..cbacf299e 100644 --- a/README.rst +++ b/README.rst @@ -331,6 +331,11 @@ If you like, share interesting things you are using python-chess for, for exampl | :height: 64 | | | :target: https://pettingzoo.farama.org/environments/classic/chess/ | A multi-agent reinforcement learning environment | +------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ +| .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/cli-chess.png?raw=true | `cli-chess `_ | +| :width: 64 | | +| :height: 64 | | +| :target: https://github.com/trevorbayless/cli-chess | A highly customizable way to play chess in your terminal | ++------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ * extensions to build engines (search and evaluation) – https://github.com/Mk-Chan/python-chess-engine-extensions * a stand-alone chess computer based on DGT board – http://www.picochess.org/ diff --git a/docs/images/cli-chess.png b/docs/images/cli-chess.png new file mode 100644 index 0000000000000000000000000000000000000000..eaa7ff306749f925727ab7e958e4893309e2ca52 GIT binary patch literal 3570 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 Date: Fri, 7 Apr 2023 19:46:12 -0400 Subject: [PATCH 1621/1831] Add square_manhattan_distance and square_knight_distance --- chess/__init__.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index e205bba8e..d6ef1d153 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -218,10 +218,41 @@ def square_rank(square: Square) -> int: def square_distance(a: Square, b: Square) -> int: """ - Gets the distance (i.e., the number of king steps) from square *a* to *b*. + Gets the Chebyshev distance (i.e., the number of king steps) from square *a* to *b*. """ + if a == b: + return 0; return max(abs(square_file(a) - square_file(b)), abs(square_rank(a) - square_rank(b))) +def square_manhattan_distance(a: Square, b: Square) -> int: + """ + Gets the Manhattan/Taxicab distance (i.e., the number of orthogonal king steps) from square *a* to *b*. + """ + if a == b: + return 0; + return abs(square_file(a) - square_file(b)) + abs(square_rank(a) - square_rank(b)) + +def square_knight_distance(a: Square, b: Square) -> int: + """ + Gets the Knight distance (i.e., the number of knight moves) from square *a* to *b*. + """ + if a == b: + return 0; + + dx = abs(square_file(a) - square_file(b)) + dy = abs(square_rank(a) - square_rank(b)) + + if dx + dy == 1: + return 3 + elif dx == dy == 2: + return 4 + elif dx == dy == 1: + if 1 << a & BB_CORNERS or 1 << b & BB_CORNERS: # Special case only for corner squares + return 4 + + m = math.ceil(max(dx / 2, dy / 2, (dx + dy) / 3)) + return m + ((m + dx + dy) % 2) + def square_mirror(square: Square) -> Square: """Mirrors the square vertically.""" return square ^ 0x38 From 9cc4372dce66eb4757eb3ae9adc676e3965a152e Mon Sep 17 00:00:00 2001 From: AInnuganti <130129680+AInnuganti@users.noreply.github.com> Date: Sun, 9 Apr 2023 14:42:34 -0400 Subject: [PATCH 1622/1831] Made requested changes --- chess/__init__.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index d6ef1d153..980dc34b4 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -220,25 +220,18 @@ def square_distance(a: Square, b: Square) -> int: """ Gets the Chebyshev distance (i.e., the number of king steps) from square *a* to *b*. """ - if a == b: - return 0; return max(abs(square_file(a) - square_file(b)), abs(square_rank(a) - square_rank(b))) def square_manhattan_distance(a: Square, b: Square) -> int: """ Gets the Manhattan/Taxicab distance (i.e., the number of orthogonal king steps) from square *a* to *b*. """ - if a == b: - return 0; return abs(square_file(a) - square_file(b)) + abs(square_rank(a) - square_rank(b)) def square_knight_distance(a: Square, b: Square) -> int: """ Gets the Knight distance (i.e., the number of knight moves) from square *a* to *b*. """ - if a == b: - return 0; - dx = abs(square_file(a) - square_file(b)) dy = abs(square_rank(a) - square_rank(b)) @@ -247,7 +240,7 @@ def square_knight_distance(a: Square, b: Square) -> int: elif dx == dy == 2: return 4 elif dx == dy == 1: - if 1 << a & BB_CORNERS or 1 << b & BB_CORNERS: # Special case only for corner squares + if BB_SQUARES[a] & BB_CORNERS or BB_SQUARES[b] & BB_CORNERS: # Special case only for corner squares return 4 m = math.ceil(max(dx / 2, dy / 2, (dx + dy) / 3)) From a2f1588e20123f946b1eaf98492b35e87739e26d Mon Sep 17 00:00:00 2001 From: AInnuganti <130129680+AInnuganti@users.noreply.github.com> Date: Sat, 15 Apr 2023 23:32:50 -0400 Subject: [PATCH 1623/1831] Add tests for new distance functions --- test.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test.py b/test.py index 0ca635d43..17dec2916 100755 --- a/test.py +++ b/test.py @@ -93,6 +93,31 @@ def test_parse_square(self): with self.assertRaises(ValueError): self.assertEqual(chess.parse_square("a0")) + def test_square_distance(self): + self.assertEqual(chess.square_distance(chess.A1, chess.A1), 0) + self.assertEqual(chess.square_distance(chess.A1, chess.H8), 7) + self.assertEqual(chess.square_distance(chess.E1, chess.E8), 7) + self.assertEqual(chess.square_distance(chess.A4, chess.H4), 7) + self.assertEqual(chess.square_distance(chess.D4, chess.E5), 1) + + def test_square_manhattan_distance(self): + self.assertEqual(chess.square_manhattan_distance(chess.A1, chess.A1), 0) + self.assertEqual(chess.square_manhattan_distance(chess.A1, chess.H8), 14) + self.assertEqual(chess.square_manhattan_distance(chess.E1, chess.E8), 7) + self.assertEqual(chess.square_manhattan_distance(chess.A4, chess.H4), 7) + self.assertEqual(chess.square_manhattan_distance(chess.D4, chess.E5), 2) + + def test_square_knight_distance(self): + self.assertEqual(chess.square_knight_distance(chess.A1, chess.A1), 0) + self.assertEqual(chess.square_knight_distance(chess.A1, chess.H8), 6) + self.assertEqual(chess.square_knight_distance(chess.G1, chess.F3), 1) + self.assertEqual(chess.square_knight_distance(chess.E1, chess.E8), 5) + self.assertEqual(chess.square_knight_distance(chess.A4, chess.H4), 5) + self.assertEqual(chess.square_knight_distance(chess.A1, chess.B1), 3) + self.assertEqual(chess.square_knight_distance(chess.A1, chess.C3), 4) + self.assertEqual(chess.square_knight_distance(chess.A1, chess.B2), 4) + self.assertEqual(chess.square_knight_distance(chess.C1, chess.B2), 2) + class MoveTestCase(unittest.TestCase): From d5da1d5849fdd85f7fc19d49d57cc38729906e6a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 16 Apr 2023 09:42:15 +0200 Subject: [PATCH 1624/1831] Add new distance functions to docs (#986) --- docs/core.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/core.rst b/docs/core.rst index d5790820a..8bb045bbb 100644 --- a/docs/core.rst +++ b/docs/core.rst @@ -85,6 +85,10 @@ and so on to .. autofunction:: chess.square_distance +.. autofunction:: chess.square_manhattan_distance + +.. autofunction:: chess.square_knight_distance + .. autofunction:: chess.square_mirror Pieces From bd371f68b631499d9107c20f1f785b111c547f62 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 22 Apr 2023 20:43:01 +0200 Subject: [PATCH 1625/1831] Remove SVG version and baseProfile https://github.com/niklasf/python-chess/discussions/992 --- chess/svg.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 008b0c87c..94ae21569 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -169,8 +169,6 @@ def _svg(viewbox: int, size: Optional[int]) -> ET.Element: svg = ET.Element("svg", { "xmlns": "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", - "version": "1.2", - "baseProfile": "tiny", "viewBox": f"0 0 {viewbox:d} {viewbox:d}", }) From dc2e284e9ddf909720a2bbe32e994269d4168244 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Mon, 24 Apr 2023 20:58:29 -0700 Subject: [PATCH 1626/1831] Send the final result of a game to engines UCI engines receive the final board position. Xboard engines receive the final move of the game and a message describing the winner and reason for the game ending. --- chess/engine.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index c3b863032..afb4c9d8a 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1246,6 +1246,27 @@ async def analysis(self, board: chess.Board, limit: Optional[Limit] = None, *, m and stopping the analysis at any time. """ + @abc.abstractmethod + async def send_game_result(self, board: chess.Board, winner: Optional[Color] = None, game_ending: Optional[str] = None, game_complete: bool = True) -> None: + """ + Sends the engine the result of the game. + + UCI engines only recieve the final position of the board. XBoard engines + receive the final moves and a line of the form "result {}", + where is one of "1-0", "0-1", "1/2-1/2", or "*" to indicate white + won, black won, draw, or adjournment, respectively. + + :param board: The final state of the board. + :param winner: Optional. Specify the winner of the game. This is useful + if the result of the game is not evident from the board--e.g., time + forfeiture or draw by agreement. + :param game_ending: Optional. Text describing the reason for the game + ending. Similarly to the winner paramter, this overrides any game + result derivable from the board. + :param game_complete: Optional. Whether the game is complete or may resume + at a later time. + """ + @abc.abstractmethod async def quit(self) -> None: """Asks the engine to shut down.""" @@ -1797,6 +1818,15 @@ def engine_terminated(self, engine: UciProtocol, exc: Exception) -> None: return await self.communicate(UciAnalysisCommand) + async def send_game_result(self, board: chess.Board, winner: Optional[Color] = None, game_ending: Optional[str] = None, game_complete: bool = True) -> None: + class UciGameResultCommand(BaseCommand[UciProtocol, None]): + def start(self, engine: UciProtocol) -> None: + engine._position(board) # Send final board position + self.result.set_result(None) + self.set_finished() + + return await self.communicate(UciGameResultCommand) + async def quit(self) -> None: self.send_line("quit") await asyncio.shield(self.returncode) @@ -2477,6 +2507,38 @@ def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: return await self.configure(self._opponent_configuration(opponent=opponent, engine_rating=engine_rating)) + async def send_game_result(self, board: chess.Board, winner: Optional[Color] = None, game_ending: Optional[str] = None, game_complete: bool = True) -> None: + class XBoardGameResultCommand(BaseCommand[XBoardProtocol, None]): + def start(self, engine: XBoardProtocol) -> None: + engine._new(board, engine.game, {}) # Send final moves to engine. + + outcome = board.outcome(claim_draw=True) + + if not game_complete: + result = "*" + ending = game_ending or "Game adjourned" + elif winner is not None or game_ending: + result = "1-0" if winner == chess.WHITE else ("0-1" if winner == chess.BLACK else "1/2-1/2") + ending = game_ending or "" + elif outcome is not None and outcome.winner is not None: + result = outcome.result() + winning_color = "White" if outcome.winner == chess.WHITE else "Black" + is_checkmate = outcome.termination == chess.Termination.CHECKMATE + ending = f"{winning_color} {'mates' if is_checkmate else 'variant win'}" + elif outcome is not None: + result = outcome.result() + ending = outcome.termination.name.capitalize().replace("_", " ") + else: + result = "*" + ending = "" + + ending_text = f"{{{ending}}}" if ending else "" + engine.send_line(f"result {result} {ending_text}".strip()) + self.result.set_result(None) + self.set_finished() + + return await self.communicate(XBoardGameResultCommand) + async def quit(self) -> None: self.send_line("quit") await asyncio.shield(self.returncode) @@ -2904,6 +2966,12 @@ def analysis(self, board: chess.Board, limit: Optional[Limit] = None, *, multipv future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return SimpleAnalysisResult(self, future.result()) + def send_game_result(self, board: chess.Board, winner: Optional[Color] = None, game_ending: Optional[str] = None, game_complete: bool = True) -> None: + with self._not_shut_down(): + coro = asyncio.wait_for(self.protocol.send_game_result(board, winner, game_ending, game_complete), self.timeout) + future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) + return future.result() + def quit(self) -> None: with self._not_shut_down(): coro = asyncio.wait_for(self.protocol.quit(), self.timeout) From 91996e2d9043a8eab3885e1fa30cd93ec5da80b2 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 25 Apr 2023 21:14:26 -0700 Subject: [PATCH 1627/1831] Do nothing for UCI engines UCI engines do not expect to get a message once a game ends. --- chess/engine.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index afb4c9d8a..75dd3633b 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1819,13 +1819,7 @@ def engine_terminated(self, engine: UciProtocol, exc: Exception) -> None: return await self.communicate(UciAnalysisCommand) async def send_game_result(self, board: chess.Board, winner: Optional[Color] = None, game_ending: Optional[str] = None, game_complete: bool = True) -> None: - class UciGameResultCommand(BaseCommand[UciProtocol, None]): - def start(self, engine: UciProtocol) -> None: - engine._position(board) # Send final board position - self.result.set_result(None) - self.set_finished() - - return await self.communicate(UciGameResultCommand) + pass async def quit(self) -> None: self.send_line("quit") From ee210f4a9fbc9286863b3f495259708b95bd7846 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 25 Apr 2023 21:15:00 -0700 Subject: [PATCH 1628/1831] Make default message for incomplete game blank --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 75dd3633b..314dfc753 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2510,7 +2510,7 @@ def start(self, engine: XBoardProtocol) -> None: if not game_complete: result = "*" - ending = game_ending or "Game adjourned" + ending = game_ending or "" elif winner is not None or game_ending: result = "1-0" if winner == chess.WHITE else ("0-1" if winner == chess.BLACK else "1/2-1/2") ending = game_ending or "" From f4d73525c97d4a4aa604481b4e8a37b55fb2caf8 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 25 Apr 2023 21:45:48 -0700 Subject: [PATCH 1629/1831] Tests for sending game result --- test.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/test.py b/test.py index 17dec2916..b52f38590 100755 --- a/test.py +++ b/test.py @@ -3664,6 +3664,80 @@ async def main(): asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) + def test_xboard_result(self): + async def main(): + protocol = chess.engine.XBoardProtocol() + mock = chess.engine.MockTransport(protocol) + + mock.expect("xboard") + mock.expect("protover 2", ["feature ping=1 setboard=1 done=1"]) + await protocol.initialize() + mock.assert_done() + + limit = chess.engine.Limit(time=5) + checkmate_board = chess.Board("k7/7R/6R1/8/8/8/8/K7 w - - 0 1") + + mock.expect("new") + mock.expect("force") + mock.expect("setboard k7/7R/6R1/8/8/8/8/K7 w - - 0 1") + mock.expect("st 5") + mock.expect("nopost") + mock.expect("easy") + mock.expect("go", ["move g6g8"]) + mock.expect_ping() + mock.expect("force") + mock.expect("result 1-0 {White mates}") + result = await protocol.play(checkmate_board, limit, game="checkmate") + self.assertEqual(result.move, checkmate_board.parse_uci("g6g8")) + checkmate_board.push(result.move) + self.assertTrue(checkmate_board.is_checkmate()) + await protocol.send_game_result(checkmate_board) + mock.assert_done() + + unfinished_board = chess.Board() + mock.expect("new") + mock.expect("force") + mock.expect("st 5") + mock.expect("nopost") + mock.expect("easy") + mock.expect("go", ["move e2e4"]) + mock.expect_ping() + mock.expect("force") + mock.expect("result *") + result = await protocol.play(unfinished_board, limit, game="unfinished") + self.assertEqual(result.move, unfinished_board.parse_uci("e2e4")) + unfinished_board.push(result.move) + await protocol.send_game_result(unfinished_board, game_complete=False) + mock.assert_done() + + timeout_board = chess.Board() + mock.expect("new") + mock.expect("force") + mock.expect("st 5") + mock.expect("nopost") + mock.expect("easy") + mock.expect("go", ["move e2e4"]) + mock.expect_ping() + mock.expect("force") + mock.expect("result 0-1 {Time forfeiture}") + result = await protocol.play(timeout_board, limit, game="timeout") + self.assertEqual(result.move, timeout_board.parse_uci("e2e4")) + timeout_board.push(result.move) + await protocol.send_game_result(timeout_board, chess.BLACK, "Time forfeiture") + mock.assert_done() + + material_board = chess.Board("k7/8/8/8/8/8/8/K7 b - - 0 1") + self.assertTrue(material_board.is_insufficient_material()) + mock.expect("new") + mock.expect("force") + mock.expect("setboard k7/8/8/8/8/8/8/K7 b - - 0 1") + mock.expect("result 1/2-1/2 {Insufficient material}") + await protocol.send_game_result(material_board) + mock.assert_done() + + asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) + asyncio.run(main()) + def test_xboard_analyse(self): async def main(): protocol = chess.engine.XBoardProtocol() From e5d8c6d9232037e616ee8a540ea73b3247560049 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 25 Apr 2023 21:48:34 -0700 Subject: [PATCH 1630/1831] Edit parameter comment --- chess/engine.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 314dfc753..0f91bca3f 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1263,8 +1263,7 @@ async def send_game_result(self, board: chess.Board, winner: Optional[Color] = N :param game_ending: Optional. Text describing the reason for the game ending. Similarly to the winner paramter, this overrides any game result derivable from the board. - :param game_complete: Optional. Whether the game is complete or may resume - at a later time. + :param game_complete: Optional. Whether the game reached completion. """ @abc.abstractmethod From 0512fe01c32cef2bdcbb46d9afe15ecae98eadd4 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 25 Apr 2023 22:42:56 -0700 Subject: [PATCH 1631/1831] Add test for do-nothing UCI send_game_result() --- test.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test.py b/test.py index b52f38590..fd3b93ed8 100755 --- a/test.py +++ b/test.py @@ -3465,6 +3465,32 @@ def test_uci_info(self): info = chess.engine._parse_uci_info("depth 1 seldepth 2 time 16 nodes 1 score cp 72 wdl 249 747 4 hashfull 0 nps 400 tbhits 0 multipv 1", board) self.assertEqual(info["wdl"], (249, 747, 4)) + def test_uci_result(self): + async def main(): + protocol = chess.engine.UciProtocol() + mock = chess.engine.MockTransport(protocol) + + mock.expect("uci", ["uciok"]) + await protocol.initialize() + mock.assert_done() + + limit = chess.engine.Limit(time=5) + checkmate_board = chess.Board("k7/7R/6R1/8/8/8/8/K7 w - - 0 1") + + mock.expect("ucinewgame") + mock.expect("isready", ["readyok"]) + mock.expect("position fen k7/7R/6R1/8/8/8/8/K7 w - - 0 1") + mock.expect("go movetime 5000", ["bestmove g6g8"]) + result = await protocol.play(checkmate_board, limit, game="checkmate") + self.assertEqual(result.move, checkmate_board.parse_uci("g6g8")) + checkmate_board.push(result.move) + self.assertTrue(checkmate_board.is_checkmate()) + await protocol.send_game_result(checkmate_board) + mock.assert_done() + + asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) + asyncio.run(main()) + def test_hiarcs_bestmove(self): async def main(): protocol = chess.engine.UciProtocol() From 885d59f708423fd3a1f18ae1fb9a35532dc51293 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 25 Apr 2023 22:48:10 -0700 Subject: [PATCH 1632/1831] Delete unneeded parentheses --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 0f91bca3f..ae33db688 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2511,7 +2511,7 @@ def start(self, engine: XBoardProtocol) -> None: result = "*" ending = game_ending or "" elif winner is not None or game_ending: - result = "1-0" if winner == chess.WHITE else ("0-1" if winner == chess.BLACK else "1/2-1/2") + result = "1-0" if winner == chess.WHITE else "0-1" if winner == chess.BLACK else "1/2-1/2" ending = game_ending or "" elif outcome is not None and outcome.winner is not None: result = outcome.result() From 622f3a0b8cbf7098082dca20f86d98a2a5e5f171 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 29 Apr 2023 23:42:00 +0200 Subject: [PATCH 1633/1831] Add perft with impossible castling rights --- examples/perft/tricky.perft | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/examples/perft/tricky.perft b/examples/perft/tricky.perft index b3cca9fd2..6a572a330 100644 --- a/examples/perft/tricky.perft +++ b/examples/perft/tricky.perft @@ -129,3 +129,15 @@ epd rnbqk1nr/bb3p1p/1q2r3/2pPp3/3P4/7P/1PP1NpPP/R1BQKBNR w KQkq c6 perft 1 2 perft 2 92 perft 3 2528 + +# +# Impossible castling rights +# + +id asymmetrical-and-king-on-h +epd r2r3k/p7/3p4/8/8/P6P/8/R3K2R b KQq - +perft 1 14 +perft 2 206 +perft 3 3672 +perft 4 64639 +perft 5 1320962 From 4889834dc0f1a2eb7f56440c87d4d1490c5f3f4b Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 29 Apr 2023 21:47:08 -0700 Subject: [PATCH 1634/1831] Add optional identifier to Limit instances This new field in the Limit class is used to signal when the time control for a game has changed. XBoard engines expect to receive a `level` or `st` command to indicate the time control at the start of the game, and then only `time` and `otim` commands before each subsequent move to update the engine's internal clocks. The `level` and `st` commands should only be resent when the time control changes--like in FIDE tournament time controls. During a single time control, the same `clock_id` should be used for every Limit instance. This field has a similar function to the `game` parameter of the `play()` method. --- chess/engine.py | 25 +++++++++++++++++++------ test.py | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index c3b863032..722d2be36 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -332,6 +332,14 @@ class Limit: *white_clock* and *black_clock* are, then it is sudden death. """ + clock_id: object = None + """ + An identifier to use with XBoard engines to signal that the time + control has changed. When this field changes, Xboard engines are + send level or st commands as appropriate. Otherwise, only time + and otim commands are sent to update the engine's clock. + """ + def __repr__(self) -> str: # Like default __repr__, but without None values. return "{}({})".format( @@ -2001,6 +2009,7 @@ def __init__(self) -> None: self.target_config: Dict[str, ConfigValue] = {} self.board = chess.Board() self.game: object = None + self.clock_id: object = None self.first_game = True async def initialize(self) -> None: @@ -2202,10 +2211,9 @@ def start(self, engine: XBoardProtocol) -> None: # Limit or time control. clock = limit.white_clock if board.turn else limit.black_clock increment = limit.white_inc if board.turn else limit.black_inc - if limit.remaining_moves or clock is not None or increment is not None: - base_mins, base_secs = divmod(int(clock or 0), 60) - engine.send_line(f"level {limit.remaining_moves or 0} {base_mins}:{base_secs:02d} {increment or 0}") - + if limit.clock_id is None or limit.clock_id != engine.clock_id: + self._send_time_control(engine, clock, increment) + engine.clock_id = limit.clock_id if limit.nodes is not None: if limit.time is not None or limit.white_clock is not None or limit.black_clock is not None or increment is not None: raise EngineError("xboard does not support mixing node limits with time limits") @@ -2217,8 +2225,6 @@ def start(self, engine: XBoardProtocol) -> None: engine.send_line("nps 1") engine.send_line(f"st {max(1, int(limit.nodes))}") - if limit.time is not None: - engine.send_line(f"st {max(0.01, limit.time)}") if limit.depth is not None: engine.send_line(f"sd {max(1, int(limit.depth))}") if limit.white_clock is not None: @@ -2270,6 +2276,13 @@ def line_received(self, engine: XBoardProtocol, line: str) -> None: else: LOGGER.warning("%s: Unexpected engine output: %r", engine, line) + def _send_time_control(self, engine: XBoardProtocol, clock: Optional[float], increment: Optional[float]) -> None: + if limit.remaining_moves or clock is not None or increment is not None: + base_mins, base_secs = divmod(int(clock or 0), 60) + engine.send_line(f"level {limit.remaining_moves or 0} {base_mins}:{base_secs:02d} {increment or 0}") + if limit.time is not None: + engine.send_line(f"st {max(0.01, limit.time)}") + def _post(self, engine: XBoardProtocol, line: str) -> None: if not self.result.done(): self.play_result.info = _parse_xboard_post(line, engine.board, info) diff --git a/test.py b/test.py index 17dec2916..d6d0b3926 100755 --- a/test.py +++ b/test.py @@ -3713,7 +3713,9 @@ async def main(): mock.assert_done() limit = chess.engine.Limit(black_clock=65, white_clock=100, - black_inc=4, white_inc=8) + black_inc=4, white_inc=8, + clock_id="xboard level") + board = chess.Board() mock.expect("new") mock.expect("force") mock.expect("level 0 1:40 8") @@ -3723,10 +3725,25 @@ async def main(): mock.expect("easy") mock.expect("go", ["move e2e4"]) mock.expect_ping() - result = await protocol.play(chess.Board(), limit) + result = await protocol.play(board, limit) self.assertEqual(result.move, chess.Move.from_uci("e2e4")) mock.assert_done() + board.push(result.move) + board.push_uci("e7e5") + + mock.expect("force") + mock.expect("e7e5") + mock.expect("time 10000") + mock.expect("otim 6500") + mock.expect("nopost") + mock.expect("easy") + mock.expect("go", ["move d2d4"]) + mock.expect_ping() + result = await protocol.play(board, limit) + self.assertEqual(result.move, chess.Move.from_uci("d2d4")) + mock.assert_done() + asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) From 13ef9447ae2a6063b06200965f923fc34a872ba5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 30 Apr 2023 11:59:51 +0200 Subject: [PATCH 1635/1831] Try Sphinx 7.0.0 --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 8f65fe1fd..526215aee 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -Sphinx==6.1.2 +Sphinx==7.0.0 From e73121a0caea542bc493ad72b59d7fbc17e02633 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 30 Apr 2023 13:37:13 +0200 Subject: [PATCH 1636/1831] Revert "Try Sphinx 7.0.0" This reverts commit 13ef9447ae2a6063b06200965f923fc34a872ba5. --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 526215aee..8f65fe1fd 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -Sphinx==7.0.0 +Sphinx==6.1.2 From 29bf03e1b030f761589ace9fe75da5152853f6c4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 May 2023 13:09:36 +0200 Subject: [PATCH 1637/1831] Add perft with pinned ep capturer and impossible check --- examples/perft/tricky.perft | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/perft/tricky.perft b/examples/perft/tricky.perft index 6a572a330..2510a9aea 100644 --- a/examples/perft/tricky.perft +++ b/examples/perft/tricky.perft @@ -124,6 +124,12 @@ perft 1 6 perft 2 121 perft 3 711 +id align-ep-pinned +epd 1b1k4/8/8/1rPpK3/8/8/8/8 w - d6 +perft 1 5 +perft 2 100 +perft 3 555 + id ep-unrelated-check epd rnbqk1nr/bb3p1p/1q2r3/2pPp3/3P4/7P/1PP1NpPP/R1BQKBNR w KQkq c6 perft 1 2 From 736478a1c7cd798cd7a603b92a5ac7dff692349b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 2 May 2023 20:58:22 +0200 Subject: [PATCH 1638/1831] Work around jQuery removed from Sphinx (fixes #1006) --- docs/conf.py | 7 ++++++- docs/requirements.txt | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index bde54010b..ede90b63b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,7 +15,12 @@ } # Autodoc. -extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.intersphinx"] +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.viewcode", + "sphinx.ext.intersphinx", + "sphinxcontrib.jquery" +] autodoc_member_order = "bysource" intersphinx_mapping = { "python": ("https://docs.python.org/3", None), diff --git a/docs/requirements.txt b/docs/requirements.txt index 8f65fe1fd..d99b8c473 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,2 @@ Sphinx==6.1.2 +sphinxcontrib-jquery==4.1 From 40e633bab5145945536c45fd178e8dd9a265ae1f Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 3 May 2023 03:04:37 -0700 Subject: [PATCH 1639/1831] Correct grammar --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 722d2be36..5b921de70 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -336,7 +336,7 @@ class Limit: """ An identifier to use with XBoard engines to signal that the time control has changed. When this field changes, Xboard engines are - send level or st commands as appropriate. Otherwise, only time + sent level or st commands as appropriate. Otherwise, only time and otim commands are sent to update the engine's clock. """ From c3bc113bcc765dd51f998dc2be83b32c1345091f Mon Sep 17 00:00:00 2001 From: johndoknjas Date: Sun, 4 Jun 2023 18:39:59 -0700 Subject: [PATCH 1640/1831] Small cleanups. --- chess/engine.py | 8 ++++---- chess/pgn.py | 5 +---- chess/polyglot.py | 5 +---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index c3b863032..65fc8f6c2 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1532,7 +1532,7 @@ def start(self, engine: UciProtocol) -> None: return await self.communicate(UciConfigureCommand) - def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> ConfigMapping: + def _opponent_configuration(self, *, opponent: Optional[Opponent] = None) -> ConfigMapping: if opponent and opponent.name and "UCI_Opponent" in self.options: rating = opponent.rating or "none" title = opponent.title or "none" @@ -1542,7 +1542,7 @@ def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine return {} async def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engine_rating: Optional[int] = None) -> None: - return await self.configure(self._opponent_configuration(opponent=opponent, engine_rating=engine_rating)) + return await self.configure(self._opponent_configuration(opponent=opponent)) def _position(self, board: chess.Board) -> None: # Select UCI_Variant and UCI_Chess960. @@ -1932,7 +1932,7 @@ def _chain_config(a: ConfigMapping, b: ConfigMapping) -> Iterator[Tuple[str, Con class UciOptionMap(MutableMapping[str, T]): """Dictionary with case-insensitive keys.""" - def __init__(self, data: Optional[Union[Iterable[Tuple[str, T]]]] = None, **kwargs: T) -> None: + def __init__(self, data: Optional[Iterable[Tuple[str, T]]] = None, **kwargs: T) -> None: self._store: Dict[str, Tuple[str, T]] = {} if data is None: data = {} @@ -1948,7 +1948,7 @@ def __delitem__(self, key: str) -> None: del self._store[key.lower()] def __iter__(self) -> Iterator[str]: - return (casedkey for casedkey, mappedvalue in self._store.values()) + return (casedkey for casedkey, _ in self._store.values()) def __len__(self) -> int: return len(self._store) diff --git a/chess/pgn.py b/chess/pgn.py index 553b6ece6..1f99f6506 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -942,10 +942,7 @@ def __setitem__(self, key: str, value: str) -> None: self._others[key] = value def __getitem__(self, key: str) -> str: - if key in TAG_ROSTER: - return self._tag_roster[key] - else: - return self._others[key] + return self._tag_roster[key] if key in TAG_ROSTER else self._others[key] def __delitem__(self, key: str) -> None: if key in TAG_ROSTER: diff --git a/chess/polyglot.py b/chess/polyglot.py index c56c5ecfb..39270c129 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -391,11 +391,8 @@ def __getitem__(self, index: int) -> Entry: return Entry(key, raw_move, weight, learn, move) def __iter__(self) -> Iterator[Entry]: - i = 0 - size = len(self) - while i < size: + for i in range(len(self)): yield self[i] - i += 1 def bisect_key_left(self, key: int) -> int: lo = 0 From 67aa18e3bb78d245d6762e514c0037f519c7a30f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 7 Jul 2023 22:49:38 +0200 Subject: [PATCH 1641/1831] Fix typo in docs: INFO_BASE -> INFO_BASIC --- chess/engine.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index c3b863032..22de2b440 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1155,7 +1155,7 @@ async def play(self, board: chess.Board, limit: Limit, *, game: object = None, i Will automatically inform the engine if the object is not equal to the previous game (e.g., ``ucinewgame``, ``new``). :param info: Selects which additional information to retrieve from the - engine. ``INFO_NONE``, ``INFO_BASE`` (basic information that is + engine. ``INFO_NONE``, ``INFO_BASIC`` (basic information that is trivial to obtain), ``INFO_SCORE``, ``INFO_PV``, ``INFO_REFUTATION``, ``INFO_CURRLINE``, ``INFO_ALL`` or any bitwise combination. Some overhead is associated with parsing @@ -1197,7 +1197,7 @@ async def analyse(self, board: chess.Board, limit: Limit, *, multipv: Optional[i Will automatically inform the engine if the object is not equal to the previous game (e.g., ``ucinewgame``, ``new``). :param info: Selects which information to retrieve from the - engine. ``INFO_NONE``, ``INFO_BASE`` (basic information that is + engine. ``INFO_NONE``, ``INFO_BASIC`` (basic information that is trivial to obtain), ``INFO_SCORE``, ``INFO_PV``, ``INFO_REFUTATION``, ``INFO_CURRLINE``, ``INFO_ALL`` or any bitwise combination. Some overhead is associated with parsing @@ -1230,7 +1230,7 @@ async def analysis(self, board: chess.Board, limit: Optional[Limit] = None, *, m Will automatically inform the engine if the object is not equal to the previous game (e.g., ``ucinewgame``, ``new``). :param info: Selects which information to retrieve from the - engine. ``INFO_NONE``, ``INFO_BASE`` (basic information that is + engine. ``INFO_NONE``, ``INFO_BASIC`` (basic information that is trivial to obtain), ``INFO_SCORE``, ``INFO_PV``, ``INFO_REFUTATION``, ``INFO_CURRLINE``, ``INFO_ALL`` or any bitwise combination. Some overhead is associated with parsing From c4611185b060635bf6b4aef30f7daf75e9737b22 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 8 Jul 2023 17:26:00 +0200 Subject: [PATCH 1642/1831] Add sf16 WDL model --- chess/engine.py | 18 +++++++++++++++--- test.py | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 22de2b440..55c5bc9b0 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -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 @@ -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 @@ -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) diff --git a/test.py b/test.py index 17dec2916..50b45cf5c 100755 --- a/test.py +++ b/test.py @@ -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): From a1f16f828c9d101abb8c7789ee418b06c74d919f Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 8 Jul 2023 17:03:38 -0700 Subject: [PATCH 1643/1831] Correct documentation of send_game_result method --- chess/engine.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index ae33db688..2b0285aca 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1251,10 +1251,15 @@ async def send_game_result(self, board: chess.Board, winner: Optional[Color] = N """ Sends the engine the result of the game. - UCI engines only recieve the final position of the board. XBoard engines - receive the final moves and a line of the form "result {}", - where is one of "1-0", "0-1", "1/2-1/2", or "*" to indicate white - won, black won, draw, or adjournment, respectively. + XBoard engines receive the final moves and a line of the form + "result {}". The field is one of "1-0", + "0-1", "1/2-1/2", or "*" to indicate white won, black won, draw, + or adjournment, respectively. The field is a description + of the specific reason for the end of the game: "White mates", + "Time forfeiture", "Stalemate", etc. + + UCI engines do not expect end-of-game information and so are not + sent anything. :param board: The final state of the board. :param winner: Optional. Specify the winner of the game. This is useful From 65bf3d09bd0707ac257305f4151eace2cf8db8f0 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 8 Jul 2023 18:44:33 -0700 Subject: [PATCH 1644/1831] Error on dubious characters in ending messages Curly braces and newlines can allow arbitrary messages to be sent to an engine. Do not allow these characters to be sent in end-of-game messages. Add tests to make sure an exception is raised for invalid characters. --- chess/engine.py | 3 +++ test.py | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/chess/engine.py b/chess/engine.py index 2b0285aca..41b12033e 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2508,6 +2508,9 @@ async def send_opponent_information(self, *, opponent: Optional[Opponent] = None async def send_game_result(self, board: chess.Board, winner: Optional[Color] = None, game_ending: Optional[str] = None, game_complete: bool = True) -> None: class XBoardGameResultCommand(BaseCommand[XBoardProtocol, None]): def start(self, engine: XBoardProtocol) -> None: + if game_ending and any(c in game_ending for c in "{}\n\r"): + raise EngineError(f"invalid line break or curly braces in game ending message: {game_ending!r}") + engine._new(board, engine.game, {}) # Send final moves to engine. outcome = board.outcome(claim_draw=True) diff --git a/test.py b/test.py index fd3b93ed8..4c1bd15c9 100755 --- a/test.py +++ b/test.py @@ -3752,6 +3752,22 @@ async def main(): await protocol.send_game_result(timeout_board, chess.BLACK, "Time forfeiture") mock.assert_done() + error_board = chess.Board() + mock.expect("new") + mock.expect("force") + mock.expect("st 5") + mock.expect("nopost") + mock.expect("easy") + mock.expect("go", ["move e2e4"]) + mock.expect_ping() + result = await protocol.play(error_board, limit, game="error") + self.assertEqual(result.move, error_board.parse_uci("e2e4")) + error_board.push(result.move) + for c in "\n\r{}": + with self.assertRaises(chess.engine.EngineError): + await protocol.send_game_result(error_board, chess.BLACK, f"Time{c}forfeiture") + mock.assert_done() + material_board = chess.Board("k7/8/8/8/8/8/8/K7 b - - 0 1") self.assertTrue(material_board.is_insufficient_material()) mock.expect("new") From ee11a56c96c2105a50111eef9a8a7eb1e5e5e29a Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 13 Jul 2023 01:25:12 -0700 Subject: [PATCH 1645/1831] Error when XBoard opponent has newline in name Use the configuration machinery to send the opponent's information to the engine instead of using the Opponent class directly. This will make sure that an exception is raised if the opponent's name has newlines in it before send_line() is called. This prevents opponents from injecting commands into the engine. For example, if an opponent sets their name as "Cheat\neasy", then the following commands will be sent to the local engine name Cheat easy which would cause the engine to turn off pondering. Also, add tests to show the change works as expected. --- chess/engine.py | 14 ++++++++------ test.py | 9 +++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 4c24681ee..efcc0f134 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2152,6 +2152,7 @@ def _variant(self, variant: Optional[str]) -> None: def _new(self, board: chess.Board, game: object, options: ConfigMapping, opponent: Optional[Opponent] = None) -> None: self._configure(options) + self._configure(self._opponent_configuration(opponent=opponent)) # Set up starting position. root = board.root() @@ -2172,15 +2173,16 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping, opponen if self.config.get("random"): self.send_line("random") - opponent_name = (opponent.name if opponent else None) or self.target_config.get("name") + opponent_name = self.config.get("name") if opponent_name and self.features.get("name", True): self.send_line(f"name {opponent_name}") - opponent_rating = (opponent.rating if opponent else None) or self.target_config.get("opponent_rating") or 0 - if self.target_config.get("engine_rating") or opponent_rating: - self.send_line(f"rating {self.target_config.get('engine_rating') or 0} {opponent_rating}") + opponent_rating = self.config.get("opponent_rating") + engine_rating = self.config.get("engine_rating") + if engine_rating or opponent_rating: + self.send_line(f"rating {engine_rating or 0} {opponent_rating or 0}") - if (opponent and opponent.is_engine) or (self.target_config.get("computer") if self.config.get("computer") is None else self.config.get("computer")): + if self.config.get("computer"): self.send_line("computer") self.send_line("force") @@ -2518,7 +2520,7 @@ def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine if opponent is None: return {} - opponent_info: Dict[str, Union[int, bool, str]] = {"engine_rating": engine_rating or 0, + opponent_info: Dict[str, Union[int, bool, str]] = {"engine_rating": engine_rating or self.target_config.get("engine_rating") or 0, "opponent_rating": opponent.rating or 0, "computer": opponent.is_engine or False} diff --git a/test.py b/test.py index 8cd599474..b109fabf8 100755 --- a/test.py +++ b/test.py @@ -3688,6 +3688,15 @@ async def main(): self.assertEqual(result.move, board.parse_san("e5")) mock.assert_done() + bad_opponent = chess.engine.Opponent("New\nLine", "GM", 1, False) + with self.assertRaises(chess.engine.EngineError): + await protocol.send_opponent_information(opponent=bad_opponent) + mock.assert_done() + + with self.assertRaises(chess.engine.EngineError): + result = await protocol.play(board, limit, game="bad game", opponent=bad_opponent) + mock.assert_done() + asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) From 0dae9d773f18ab10086896969c5842c7caa78f9c Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 15 Jul 2023 05:56:56 -0700 Subject: [PATCH 1646/1831] Add send_opponent_information() documentation --- chess/engine.py | 10 +++++++++- docs/engine.rst | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index efcc0f134..d60179635 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -449,10 +449,18 @@ class Info(enum.IntFlag): @dataclasses.dataclass class Opponent: """Used to store information about an engine's opponent.""" + name: Optional[str] + """The name of the opponent.""" + title: Optional[str] + """The opponent's title--for example, GM, IM, or BOT.""" + rating: Optional[int] + """The opponent's ELO rating.""" + is_engine: Optional[bool] + """Whether the opponent is a chess engine/computer program.""" class PovScore: @@ -1158,7 +1166,7 @@ async def send_opponent_information(self, *, opponent: Optional[Opponent] = None method should be called before the first move of a game--i.e., the first call to :func:`chess.engine.Protocol.play()`. - :param opponent: Optional. The opponent's information. + :param opponent: Optional. An instance of :class:`chess.engine.Opponent` that has the opponent's information. :param engine_rating: Optional. This engine's own rating. Only used by XBoard engines. """ diff --git a/docs/engine.rst b/docs/engine.rst index 08f8f8f5e..556d64793 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -70,6 +70,12 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. .. autoclass:: chess.engine.PlayResult :members: +.. autoclass:: chess.engine.Protocol + :members: send_opponent_information + +.. autoclass:: chess.engine.Opponent + :members: + Analysing and evaluating a position ----------------------------------- From 0fcee3568956feaba9f96cb1a906b4a68c83c9ab Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 15 Jul 2023 05:58:49 -0700 Subject: [PATCH 1647/1831] Add send_game_result() documentation Also, correct formatting and spelling. --- chess/engine.py | 11 ++++++----- docs/engine.rst | 3 +++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index d60179635..30618d829 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1280,9 +1280,9 @@ async def send_game_result(self, board: chess.Board, winner: Optional[Color] = N Sends the engine the result of the game. XBoard engines receive the final moves and a line of the form - "result {}". The field is one of "1-0", - "0-1", "1/2-1/2", or "*" to indicate white won, black won, draw, - or adjournment, respectively. The field is a description + ``result {}``. The ```` field is one of ``1-0``, + ``0-1``, ``1/2-1/2``, or ``*`` to indicate white won, black won, draw, + or adjournment, respectively. The ```` field is a description of the specific reason for the end of the game: "White mates", "Time forfeiture", "Stalemate", etc. @@ -1292,9 +1292,10 @@ async def send_game_result(self, board: chess.Board, winner: Optional[Color] = N :param board: The final state of the board. :param winner: Optional. Specify the winner of the game. This is useful if the result of the game is not evident from the board--e.g., time - forfeiture or draw by agreement. + forfeiture or draw by agreement. If not ``None``, this parameter + overrides any winner derivable from the board. :param game_ending: Optional. Text describing the reason for the game - ending. Similarly to the winner paramter, this overrides any game + ending. Similarly to the winner parameter, this overrides any game result derivable from the board. :param game_complete: Optional. Whether the game reached completion. """ diff --git a/docs/engine.rst b/docs/engine.rst index 556d64793..02dd4548f 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -76,6 +76,9 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. .. autoclass:: chess.engine.Opponent :members: +.. autoclass:: chess.engine.Protocol + :members: send_game_result + Analysing and evaluating a position ----------------------------------- From 53e92b445b9340368b1791843e24a8975fb602d5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 25 Jul 2023 21:16:14 +0200 Subject: [PATCH 1648/1831] Document potentially surprising time complexities (closes #1000) --- chess/pgn.py | 50 +++++++++++++++++++++++++++++++++++++++++++++----- docs/pgn.rst | 4 ++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 1f99f6506..f6783585c 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -215,6 +215,8 @@ def board(self) -> chess.Board: ``Variant``) unless the ``FEN`` header tag is set. It's a copy, so modifying the board will not alter the game. + + Complexity is `O(n)`. """ @abc.abstractmethod @@ -226,11 +228,15 @@ def ply(self) -> int: Usually this is equal to the number of parent nodes, but it may be more if the game was started from a custom position. + + Complexity is `O(n)`. """ def turn(self) -> Color: """ Gets the color to move at this node. See :data:`chess.Board.turn`. + + Complexity is `O(n)`. """ return self.ply() % 2 == 0 @@ -241,13 +247,21 @@ def root(self) -> GameNode: return node def game(self) -> Game: - """Gets the root node, i.e., the game.""" + """ + Gets the root node, i.e., the game. + + Complexity is `O(n)`. + """ root = self.root() assert isinstance(root, Game), "GameNode not rooted in Game" return root def end(self) -> GameNode: - """Follows the main variation to the end and returns the last node.""" + """ + Follows the main variation to the end and returns the last node. + + Complexity is `O(n)`. + """ node = self while node.variations: @@ -256,7 +270,11 @@ def end(self) -> GameNode: return node def is_end(self) -> bool: - """Checks if this node is the last node in the current variation.""" + """ + Checks if this node is the last node in the current variation. + + Complexity is `O(1)`. + """ return not self.variations def starts_variation(self) -> bool: @@ -267,6 +285,8 @@ def starts_variation(self) -> bool: For example, in ``1. e4 e5 (1... c5 2. Nf3) 2. Nf3``, the node holding 1... c5 starts a variation. + + Complexity is `O(1)`. """ if not self.parent or not self.parent.variations: return False @@ -274,7 +294,11 @@ def starts_variation(self) -> bool: return self.parent.variations[0] != self def is_mainline(self) -> bool: - """Checks if the node is in the mainline of the game.""" + """ + Checks if the node is in the mainline of the game. + + Complexity is `O(n)`. + """ node = self while node.parent: @@ -291,6 +315,8 @@ def is_main_variation(self) -> bool: """ Checks if this node is the first variation from the point of view of its parent. The root node is also in the main variation. + + Complexity is `O(1)`. """ if not self.parent: return True @@ -367,6 +393,8 @@ def next(self) -> Optional[ChildNode]: """ Returns the first node of the mainline after this node, or ``None`` if this node does not have any children. + + Complexity is `O(1)`. """ return self.variations[0] if self.variations else None @@ -404,6 +432,8 @@ def eval(self) -> Optional[chess.engine.PovScore]: """ Parses the first valid ``[%eval ...]`` annotation in the comment of this node, if any. + + Complexity is `O(n)`. """ match = EVAL_REGEX.search(self.comment) if not match: @@ -428,6 +458,8 @@ def eval_depth(self) -> Optional[int]: """ Parses the first valid ``[%eval ...]`` annotation in the comment of this node and returns the corresponding depth, if any. + + Complexity is `O(1)`. """ match = EVAL_REGEX.search(self.comment) return int(match.group("depth")) if match and match.group("depth") else None @@ -670,6 +702,8 @@ def san(self) -> str: See :func:`chess.Board.san()`. Do not call this on the root node. + + Complexity is `O(n)`. """ return self.parent.board().san(self.move) @@ -679,11 +713,17 @@ def uci(self, *, chess960: Optional[bool] = None) -> str: See :func:`chess.Board.uci()`. Do not call this on the root node. + + Complexity is `O(n)`. """ return self.parent.board().uci(self.move, chess960=chess960) def end(self) -> ChildNode: - """Follows the main variation to the end and returns the last node.""" + """ + Follows the main variation to the end and returns the last node. + + Complexity is `O(n)`. + """ return typing.cast(ChildNode, super().end()) def _accept_node(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT]) -> None: diff --git a/docs/pgn.rst b/docs/pgn.rst index 9ebe96594..dd5a6fa47 100644 --- a/docs/pgn.rst +++ b/docs/pgn.rst @@ -48,6 +48,10 @@ position of the game. The tree consists of one root node nodes (:class:`~chess.pgn.ChildNode`). Both extend :class:`~chess.pgn.GameNode`. +.. note:: Some basic methods have complexity `O(n)` for a game with n moves. + When following a variation, it is often more efficient to use visitors + or incrementally update state (like board, ply counter, or turn). + .. autoclass:: chess.pgn.GameNode :members: From 59a5233da0f601e18df04a3b4532d54fd252e8e9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 25 Jul 2023 21:22:54 +0200 Subject: [PATCH 1649/1831] Update Stockfish 11 download URLs (fixes #1019) --- .github/workflows/setup-ubuntu-latest.sh | 2 +- .github/workflows/setup-windows-latest.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/setup-ubuntu-latest.sh b/.github/workflows/setup-ubuntu-latest.sh index de1d567fd..8954c8f0c 100755 --- a/.github/workflows/setup-ubuntu-latest.sh +++ b/.github/workflows/setup-ubuntu-latest.sh @@ -1,7 +1,7 @@ #!/bin/sh -e # Stockfish -wget https://stockfish.s3.amazonaws.com/stockfish-11-linux.zip +wget https://files.stockfishchess.org/archive/Stockfish%2011/stockfish-11-linux.zip unzip stockfish-11-linux.zip mkdir -p bin cp stockfish-11-linux/Linux/stockfish_20011801_x64_bmi2 bin/stockfish diff --git a/.github/workflows/setup-windows-latest.sh b/.github/workflows/setup-windows-latest.sh index 3ae917a5c..685ead65a 100755 --- a/.github/workflows/setup-windows-latest.sh +++ b/.github/workflows/setup-windows-latest.sh @@ -2,7 +2,7 @@ echo Download ... choco install wget -wget https://stockfishchess.org/files/stockfish-11-win.zip +wget https://files.stockfishchess.org/archive/Stockfish%2011/stockfish-11-win.zip echo Unzip .. 7z e stockfish-11-win.zip stockfish-11-win/Windows/*.exe From 34de67dfd285e36f152a6e4eca0ce9f32ab82328 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 25 Jul 2023 22:29:10 +0200 Subject: [PATCH 1650/1831] Prepare changelog for next release --- CHANGELOG.rst | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2580c841c..0e5872ed4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,38 @@ Changelog for python-chess ========================== +Upcoming in the next release +---------------------------- + +New features: + +* Use ``chess.engine.Opponent`` to send opponent information to engines. +* Inform engines about the game result using + ``chess.engine.Protocol.send_game_result()``. +* Add ``chess.engine.Limit.clock_id``. +* Add ``chess.svg.board(..., borders=True)``. +* Avoid rendering background behind SVG boards to better support transparency. +* Add ``chess.pgn.BaseVisitor.begin_parse_san()``. +* Introduce new distance metrics ``chess.square_manhattan_distance()`` and + ``chess.square_knight_distance()``. + +Bugfixes: + +* Fix ``chess.pgn.GameNode.eval()`` sometimes off by one centipawn. +* Fix handling of additional spaces between UCI option tokens. +* Handle implicit XBoard engine resignation via output like + ``0-1 {White resigns}``. + +Changes: + +* Add model ``sf16`` for ``chess.engine.Score.wdl()``, the new default. +* Update ``lichess`` WDL model. +* Keep PGN headers that do not belong to the Seven Tag Roster in insertion + order. +* Halve the number of open file descriptors maintained by tablebases + and opening books. +* Reduce verbosity of logged ``chess.pgn`` errors. + New in v1.9.4 (22nd Dec 2022) ----------------------------- From 41b27bb099169c6b36590e1bc9b690a2de8f9a2a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 18:30:59 +0200 Subject: [PATCH 1651/1831] Bump 1.10.0 --- CHANGELOG.rst | 4 ++-- chess/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0e5872ed4..a44b2b070 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,8 @@ Changelog for python-chess ========================== -Upcoming in the next release ----------------------------- +New in v1.10.0 (27th Jul 2023) +------------------------------ New features: diff --git a/chess/__init__.py b/chess/__init__.py index 980dc34b4..6c0cf9c94 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -27,7 +27,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.9.4" +__version__ = "1.10.0" import collections import copy From cfda9c0f70697e6c17f71ffa1d1381c5067dae62 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 18:32:48 +0200 Subject: [PATCH 1652/1831] Test Python 3.11 using tox --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 3eeb764ba..1b103fd6c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37,py38,py39,py310 +envlist = py37,py38,py39,py310,py311 [testenv] passenv = LD_LIBRARY_PATH From 23e43177cc979660907814540e210ce0ea45c43b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 19:29:50 +0200 Subject: [PATCH 1653/1831] Make flake8 happy --- chess/__init__.py | 2 +- chess/engine.py | 8 ++++---- chess/variant.py | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 6c0cf9c94..b87e3cbec 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -240,7 +240,7 @@ def square_knight_distance(a: Square, b: Square) -> int: elif dx == dy == 2: return 4 elif dx == dy == 1: - if BB_SQUARES[a] & BB_CORNERS or BB_SQUARES[b] & BB_CORNERS: # Special case only for corner squares + if BB_SQUARES[a] & BB_CORNERS or BB_SQUARES[b] & BB_CORNERS: # Special case only for corner squares return 4 m = math.ceil(max(dx / 2, dy / 2, (dx + dy) / 3)) diff --git a/chess/engine.py b/chess/engine.py index 30618d829..cab9d5d2c 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2181,7 +2181,7 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping, opponen if self.config.get("random"): self.send_line("random") - + opponent_name = self.config.get("name") if opponent_name and self.features.get("name", True): self.send_line(f"name {opponent_name}") @@ -2532,7 +2532,7 @@ def _opponent_configuration(self, *, opponent: Optional[Opponent] = None, engine opponent_info: Dict[str, Union[int, bool, str]] = {"engine_rating": engine_rating or self.target_config.get("engine_rating") or 0, "opponent_rating": opponent.rating or 0, "computer": opponent.is_engine or False} - + if opponent.name and self.features.get("name", True): opponent_info["name"] = f"{opponent.title or ''} {opponent.name}".strip() @@ -2548,7 +2548,7 @@ def start(self, engine: XBoardProtocol) -> None: raise EngineError(f"invalid line break or curly braces in game ending message: {game_ending!r}") engine._new(board, engine.game, {}) # Send final moves to engine. - + outcome = board.outcome(claim_draw=True) if not game_complete: @@ -2966,7 +2966,7 @@ def send_opponent_information(self, *, opponent: Optional[Opponent] = None, engi self.timeout) future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() - + def ping(self) -> None: with self._not_shut_down(): coro = asyncio.wait_for(self.protocol.ping(), self.timeout) diff --git a/chess/variant.py b/chess/variant.py index cd1670480..31cdea287 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -17,7 +17,6 @@ from __future__ import annotations import chess -import copy import itertools from typing import Dict, Generic, Hashable, Iterable, Iterator, List, Optional, Type, TypeVar, Union From 8ede90039228a78e0d74c3b07fb3cbaacea752f6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 19:34:26 +0200 Subject: [PATCH 1654/1831] PyPI has removed GPG signatures --- release.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.py b/release.py index 099dd4a98..d27ddf04e 100755 --- a/release.py +++ b/release.py @@ -99,7 +99,7 @@ def pypi(): system("rm -rf build") system("python3 setup.py sdist bdist_wheel") system("twine check dist/*") - system("twine upload --skip-existing --sign dist/*") + system("twine upload --skip-existing") def github_release(tagname): From 1cca86ff8fcf6ee587d9a138fd774d1b762ed0e6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 19:39:46 +0200 Subject: [PATCH 1655/1831] Remove redundant license headers --- chess/__init__.py | 16 ---------------- chess/engine.py | 16 ---------------- chess/gaviota.py | 17 ----------------- chess/pgn.py | 16 ---------------- chess/polyglot.py | 16 ---------------- chess/svg.py | 20 -------------------- chess/syzygy.py | 16 ---------------- chess/variant.py | 16 ---------------- setup.py | 16 ---------------- test.py | 16 ---------------- 10 files changed, 165 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index b87e3cbec..a41f38501 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1,19 +1,3 @@ -# This file is part of the python-chess library. -# Copyright (C) 2012-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - """ A chess library with move generation and validation, Polyglot opening book probing, PGN reading and writing, diff --git a/chess/engine.py b/chess/engine.py index cab9d5d2c..37b7715fd 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1,19 +1,3 @@ -# This file is part of the python-chess library. -# Copyright (C) 2012-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - from __future__ import annotations import abc diff --git a/chess/gaviota.py b/chess/gaviota.py index 454949795..c2439728f 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1,20 +1,3 @@ -# This file is part of the python-chess library. -# Copyright (C) 2015 Jean-Noël Avila -# Copyright (C) 2015-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - from __future__ import annotations import ctypes diff --git a/chess/pgn.py b/chess/pgn.py index f6783585c..edeab84a3 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1,19 +1,3 @@ -# This file is part of the python-chess library. -# Copyright (C) 2012-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - from __future__ import annotations import abc diff --git a/chess/polyglot.py b/chess/polyglot.py index 39270c129..7d9e425ea 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -1,19 +1,3 @@ -# This file is part of the python-chess library. -# Copyright (C) 2012-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - from __future__ import annotations import chess diff --git a/chess/svg.py b/chess/svg.py index 94ae21569..3e034ce30 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -1,23 +1,3 @@ -# This file is part of the python-chess library. -# Copyright (C) 2016-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Piece vector graphics are copyright (C) Colin M.L. Burnett -# and also licensed under the -# GNU General Public License. - from __future__ import annotations import math diff --git a/chess/syzygy.py b/chess/syzygy.py index 2d835b200..fd9d80890 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1,19 +1,3 @@ -# This file is part of the python-chess library. -# Copyright (C) 2012-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - from __future__ import annotations import collections diff --git a/chess/variant.py b/chess/variant.py index 31cdea287..e81d0aa72 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -1,19 +1,3 @@ -# This file is part of the python-chess library. -# Copyright (C) 2016-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - from __future__ import annotations import chess diff --git a/setup.py b/setup.py index bc6a8af51..09675868e 100755 --- a/setup.py +++ b/setup.py @@ -1,21 +1,5 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# -# This file is part of the python-chess library. -# Copyright (C) 2012-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . import os import platform diff --git a/test.py b/test.py index b109fabf8..d25dd75ad 100755 --- a/test.py +++ b/test.py @@ -1,20 +1,4 @@ #!/usr/bin/env python3 -# -# This file is part of the python-chess library. -# Copyright (C) 2012-2021 Niklas Fiekas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . import asyncio import copy From ff1a974408abf6da882b633a19e9a340fd21b3e2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 19:42:27 +0200 Subject: [PATCH 1656/1831] Test WDL consistency under all models --- test.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test.py b/test.py index d25dd75ad..6419eb89f 100755 --- a/test.py +++ b/test.py @@ -2948,9 +2948,10 @@ def test_score_ordering(self): self.assertEqual(i >= j, a >= b) self.assertEqual(i < j, a.score(mate_score=100000) < b.score(mate_score=100000)) - self.assertTrue(not (i < j) or a.wdl().expectation() <= b.wdl().expectation()) - self.assertTrue(not (i < j) or a.wdl().winning_chance() <= b.wdl().winning_chance()) - self.assertTrue(not (i < j) or a.wdl().losing_chance() >= b.wdl().losing_chance()) + for model in ["sf12", "sf14", "sf15", "sf15.1", "sf16"]: + self.assertTrue(not (i < j) or a.wdl(model=model).expectation() <= b.wdl(model=model).expectation()) + self.assertTrue(not (i < j) or a.wdl(model=model).winning_chance() <= b.wdl(model=model).winning_chance()) + self.assertTrue(not (i < j) or a.wdl(model=model).losing_chance() >= b.wdl(model=model).losing_chance()) def test_score(self): # Negation. From 9ba8b68d789a6fb7f96c3640cbc7c1c3667cb119 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 19:51:35 +0200 Subject: [PATCH 1657/1831] Drop support for Python 3.7 (#463) --- .github/workflows/test.yml | 2 +- chess/polyglot.py | 4 ++-- chess/syzygy.py | 2 +- setup.py | 3 +-- tox.ini | 4 ++-- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 95e9a3728..e06db4221 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8", "3.9", "3.10", "3.11"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 diff --git a/chess/polyglot.py b/chess/polyglot.py index 7d9e425ea..92704e6a4 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -333,8 +333,8 @@ def __init__(self, filename: PathLike) -> None: raise IOError(f"invalid file size: ensure {filename!r} is a valid polyglot opening book") try: - # Python 3.8 - self.mmap.madvise(mmap.MADV_RANDOM) # type: ignore + # Linux + self.mmap.madvise(mmap.MADV_RANDOM) except AttributeError: pass diff --git a/chess/syzygy.py b/chess/syzygy.py index fd9d80890..af375b5da 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -596,7 +596,7 @@ def init_mmap(self) -> None: raise IOError(f"invalid file size: ensure {self.path!r} is a valid syzygy tablebase file") try: - # Python 3.8 + # Linux data.madvise(mmap.MADV_RANDOM) except AttributeError: pass diff --git a/setup.py b/setup.py index 09675868e..ed3d8b0bf 100755 --- a/setup.py +++ b/setup.py @@ -65,7 +65,7 @@ def read_description(): package_data={ "chess": ["py.typed"], }, - python_requires=">=3.7", + python_requires=">=3.8", classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", @@ -73,7 +73,6 @@ def read_description(): "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Operating System :: OS Independent", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/tox.ini b/tox.ini index 1b103fd6c..665e9f38b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37,py38,py39,py310,py311 +envlist = py38,py39,py310,py311 [testenv] passenv = LD_LIBRARY_PATH @@ -10,7 +10,7 @@ commands = python test.py --verbose python -m doctest README.rst --verbose -[testenv:{py37,py38,py39}] +[testenv:{py38,py39}] passenv = LD_LIBRARY_PATH whitelist_externals = stockfish From 85816125b4936ebfd0fd90a2cbddda747c7eeafd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 19:52:02 +0200 Subject: [PATCH 1658/1831] Try mypy also under Python 3.10 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e06db4221..184092752 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,7 +39,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.9", "3.11"] + python-version: ["3.9", "3.10", "3.11"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From 8b9e1481568e35802c733140ef2303361976e764 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 20:05:07 +0200 Subject: [PATCH 1659/1831] fixup! Drop support for Python 3.7 (#463) --- chess/polyglot.py | 5 ++++- chess/syzygy.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/chess/polyglot.py b/chess/polyglot.py index 92704e6a4..ac339902c 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -312,6 +312,9 @@ def size(self) -> int: def close(self) -> None: pass + def madvise(self, option: int, start: int = ..., length: int = ...) -> None: + pass + def _randint(rng: Optional[random.Random], a: int, b: int) -> int: return random.randint(a, b) if rng is None else rng.randint(a, b) @@ -333,7 +336,7 @@ def __init__(self, filename: PathLike) -> None: raise IOError(f"invalid file size: ensure {filename!r} is a valid polyglot opening book") try: - # Linux + # Unix self.mmap.madvise(mmap.MADV_RANDOM) except AttributeError: pass diff --git a/chess/syzygy.py b/chess/syzygy.py index af375b5da..96a17e921 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -596,7 +596,7 @@ def init_mmap(self) -> None: raise IOError(f"invalid file size: ensure {self.path!r} is a valid syzygy tablebase file") try: - # Linux + # Unix data.madvise(mmap.MADV_RANDOM) except AttributeError: pass From 6fbb309554e7aaaa450432972a66a1879fcbfe86 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 20:05:31 +0200 Subject: [PATCH 1660/1831] Unconditionally use typing.Literal --- chess/__init__.py | 15 +++++---------- chess/engine.py | 19 +++++++------------ chess/pgn.py | 13 +++---------- chess/variant.py | 4 ++-- 4 files changed, 17 insertions(+), 34 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index a41f38501..0604cec54 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -22,14 +22,9 @@ import itertools import typing -from typing import ClassVar, Callable, Counter, Dict, Generic, Hashable, Iterable, Iterator, List, Mapping, Optional, SupportsInt, Tuple, Type, TypeVar, Union +from typing import ClassVar, Callable, Counter, Dict, Generic, Hashable, Iterable, Iterator, List, Literal, Mapping, Optional, SupportsInt, Tuple, Type, TypeVar, Union -try: - from typing import Literal - _EnPassantSpec = Literal["legal", "fen", "xfen"] -except ImportError: - # Before Python 3.8. - _EnPassantSpec = str # type: ignore +EnPassantSpec = Literal["legal", "fen", "xfen"] Color = bool @@ -2394,7 +2389,7 @@ def has_legal_en_passant(self) -> bool: """Checks if there is a legal en passant capture.""" return self.ep_square is not None and any(self.generate_legal_ep()) - def fen(self, *, shredder: bool = False, en_passant: _EnPassantSpec = "legal", promoted: Optional[bool] = None) -> str: + def fen(self, *, shredder: bool = False, en_passant: EnPassantSpec = "legal", promoted: Optional[bool] = None) -> str: """ Gets a FEN representation of the position. @@ -2426,7 +2421,7 @@ def fen(self, *, shredder: bool = False, en_passant: _EnPassantSpec = "legal", p str(self.fullmove_number) ]) - def shredder_fen(self, *, en_passant: _EnPassantSpec = "legal", promoted: Optional[bool] = None) -> str: + def shredder_fen(self, *, en_passant: EnPassantSpec = "legal", promoted: Optional[bool] = None) -> str: return " ".join([ self.epd(shredder=True, en_passant=en_passant, promoted=promoted), str(self.halfmove_clock), @@ -2662,7 +2657,7 @@ def _epd_operations(self, operations: Mapping[str, Union[None, str, int, float, return "".join(epd) - def epd(self, *, shredder: bool = False, en_passant: _EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, Move, Iterable[Move]]) -> str: + def epd(self, *, shredder: bool = False, en_passant: EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, Move, Iterable[Move]]) -> str: """ Gets an EPD representation of the current position. diff --git a/chess/engine.py b/chess/engine.py index 37b7715fd..144fbb649 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -24,14 +24,9 @@ from chess import Color from types import TracebackType -from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Mapping, MutableMapping, Optional, Tuple, Type, TypeVar, Union +from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Optional, Tuple, Type, TypeVar, Union -try: - from typing import Literal - _WdlModel = Literal["sf", "sf16", "sf15.1", "sf15", "sf14", "sf12", "lichess"] -except ImportError: - # Before Python 3.8. - _WdlModel = str # type: ignore +WdlModel = Literal["sf", "sf16", "sf15.1", "sf15", "sf14", "sf12", "lichess"] T = TypeVar("T") @@ -476,7 +471,7 @@ def is_mate(self) -> bool: """Tests if this is a mate score.""" return self.relative.is_mate() - def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> PovWdl: + def wdl(self, *, model: WdlModel = "sf", ply: int = 30) -> PovWdl: """See :func:`~chess.engine.Score.wdl()`.""" return PovWdl(self.relative.wdl(model=model, ply=ply), self.turn) @@ -553,7 +548,7 @@ def is_mate(self) -> bool: return self.mate() is not None @abc.abstractmethod - def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: + def wdl(self, *, model: WdlModel = "sf", ply: int = 30) -> Wdl: """ Returns statistics for the expected outcome of this game, based on a *model*, given that this score is reached at *ply*. @@ -699,7 +694,7 @@ def mate(self) -> None: def score(self, *, mate_score: Optional[int] = None) -> int: return self.cp - def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: + def wdl(self, *, model: WdlModel = "sf", ply: int = 30) -> Wdl: if model == "lichess": wins = _lichess_raw_wins(max(-1000, min(self.cp, 1000))) losses = 1000 - wins @@ -758,7 +753,7 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: else: return -mate_score - self.moves - def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: + def wdl(self, *, model: WdlModel = "sf", ply: int = 30) -> Wdl: if model == "lichess": cp = (21 - min(10, abs(self.moves))) * 100 wins = _lichess_raw_wins(cp) @@ -795,7 +790,7 @@ def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: ... def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: return mate_score - def wdl(self, *, model: _WdlModel = "sf", ply: int = 30) -> Wdl: + def wdl(self, *, model: WdlModel = "sf", ply: int = 30) -> Wdl: return Wdl(1000, 0, 0) def __neg__(self) -> Mate: diff --git a/chess/pgn.py b/chess/pgn.py index edeab84a3..ae22afaf6 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -11,16 +11,9 @@ import chess.engine import chess.svg -from typing import Any, Callable, Dict, Generic, Iterable, Iterator, List, Mapping, MutableMapping, Set, TextIO, Tuple, Type, TypeVar, Optional, Union +from typing import Any, Callable, Dict, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Set, TextIO, Tuple, Type, TypeVar, Optional, Union from chess import Color, Square -try: - from typing import Literal - _TrueLiteral = Literal[True] -except ImportError: - # Before Python 3.8. - _TrueLiteral = bool # type: ignore - LOGGER = logging.getLogger(__name__) @@ -1289,7 +1282,7 @@ def result(self) -> chess.Board: return self.board -class SkipVisitor(BaseVisitor[_TrueLiteral]): +class SkipVisitor(BaseVisitor[Literal[True]]): """Skips a game.""" def begin_game(self) -> SkipType: @@ -1301,7 +1294,7 @@ def end_headers(self) -> SkipType: def begin_variation(self) -> SkipType: return SKIP - def result(self) -> _TrueLiteral: + def result(self) -> Literal[True]: return True diff --git a/chess/variant.py b/chess/variant.py index e81d0aa72..6160696a2 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -762,7 +762,7 @@ def set_fen(self, fen: str) -> None: self.remaining_checks[chess.WHITE] = wc self.remaining_checks[chess.BLACK] = bc - def epd(self, shredder: bool = False, en_passant: chess._EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: + def epd(self, shredder: bool = False, en_passant: chess.EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: epd = [super().epd(shredder=shredder, en_passant=en_passant, promoted=promoted), "{:d}+{:d}".format(max(self.remaining_checks[chess.WHITE], 0), max(self.remaining_checks[chess.BLACK], 0))] @@ -1019,7 +1019,7 @@ def board_fen(self, promoted: Optional[bool] = None) -> str: promoted = True return super().board_fen(promoted=promoted) - def epd(self, shredder: bool = False, en_passant: chess._EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: + def epd(self, shredder: bool = False, en_passant: chess.EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: epd = super().epd(shredder=shredder, en_passant=en_passant, promoted=promoted) board_part, info_part = epd.split(" ", 1) return f"{board_part}[{str(self.pockets[chess.WHITE]).upper()}{self.pockets[chess.BLACK]}] {info_part}" From 6dcc975d7ca599a8288c1b9435e1a161221aea49 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 20:06:55 +0200 Subject: [PATCH 1661/1831] Unconditionally use TypedDict --- chess/engine.py | 62 +++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 144fbb649..75ee9de58 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -328,41 +328,37 @@ def __repr__(self) -> str: if getattr(self, attr) is not None)) -try: - class InfoDict(typing.TypedDict, total=False): - """ - Dictionary of aggregated information sent by the engine. +class InfoDict(typing.TypedDict, total=False): + """ + Dictionary of aggregated information sent by the engine. - Commonly used keys are: ``score`` (a :class:`~chess.engine.PovScore`), - ``pv`` (a list of :class:`~chess.Move` objects), ``depth``, - ``seldepth``, ``time`` (in seconds), ``nodes``, ``nps``, ``multipv`` - (``1`` for the mainline). + Commonly used keys are: ``score`` (a :class:`~chess.engine.PovScore`), + ``pv`` (a list of :class:`~chess.Move` objects), ``depth``, + ``seldepth``, ``time`` (in seconds), ``nodes``, ``nps``, ``multipv`` + (``1`` for the mainline). - Others: ``tbhits``, ``currmove``, ``currmovenumber``, ``hashfull``, - ``cpuload``, ``refutation``, ``currline``, ``ebf`` (effective branching factor), - ``wdl`` (a :class:`~chess.engine.PovWdl`), and ``string``. - """ - score: PovScore - pv: List[chess.Move] - depth: int - seldepth: int - time: float - nodes: int - nps: int - tbhits: int - multipv: int - currmove: chess.Move - currmovenumber: int - hashfull: int - cpuload: int - refutation: Dict[chess.Move, List[chess.Move]] - currline: Dict[int, List[chess.Move]] - ebf: float - wdl: PovWdl - string: str -except AttributeError: - # Before Python 3.8. - InfoDict = dict # type: ignore + Others: ``tbhits``, ``currmove``, ``currmovenumber``, ``hashfull``, + ``cpuload``, ``refutation``, ``currline``, ``ebf`` (effective branching factor), + ``wdl`` (a :class:`~chess.engine.PovWdl`), and ``string``. + """ + score: PovScore + pv: List[chess.Move] + depth: int + seldepth: int + time: float + nodes: int + nps: int + tbhits: int + multipv: int + currmove: chess.Move + currmovenumber: int + hashfull: int + cpuload: int + refutation: Dict[chess.Move, List[chess.Move]] + currline: Dict[int, List[chess.Move]] + ebf: float + wdl: PovWdl + string: str class PlayResult: From 8214d9757da593c71ad13a1bcb933393125d5937 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 20:23:14 +0200 Subject: [PATCH 1662/1831] Remove PollingChildWatcher --- chess/engine.py | 45 +++++---------------------------------------- 1 file changed, 5 insertions(+), 40 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 75ee9de58..6fac0c602 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -108,46 +108,11 @@ def _init_watcher(self) -> asyncio.AbstractChildWatcher: pass if threading.current_thread() is threading.main_thread(): - try: - watcher = asyncio.ThreadedChildWatcher() - LOGGER.debug("Using ThreadedChildWatcher") - return watcher - except AttributeError: - # Before Python 3.8. - LOGGER.debug("Using SafeChildWatcher") - return asyncio.SafeChildWatcher() - - class PollingChildWatcher(asyncio.SafeChildWatcher): - _loop: Optional[asyncio.AbstractEventLoop] - _callbacks: Dict[int, Any] - - def __init__(self) -> None: - super().__init__() - self._poll_handle: Optional[asyncio.Handle] = None - self._poll_delay = 0.001 - - def attach_loop(self, loop: Optional[asyncio.AbstractEventLoop]) -> None: - assert loop is None or isinstance(loop, asyncio.AbstractEventLoop) - - if self._loop is not None and loop is None and self._callbacks: - warnings.warn("A loop is being detached from a child watcher with pending handlers", RuntimeWarning) - - if self._poll_handle is not None: - self._poll_handle.cancel() - - self._loop = loop - if self._loop is not None: - self._poll_handle = self._loop.call_soon(self._poll) - self._do_waitpid_all() # type: ignore - - def _poll(self) -> None: - if self._loop: - self._do_waitpid_all() # type: ignore - self._poll_delay = min(self._poll_delay * 2, 1.0) - self._poll_handle = self._loop.call_later(self._poll_delay, self._poll) - - LOGGER.debug("Using PollingChildWatcher") - return PollingChildWatcher() + LOGGER.debug("Using SafeChildWatcher") + return asyncio.SafeChildWatcher() + else: + LOGGER.debug("Using ThreadedChildWatcher") + return asyncio.ThreadedChildWatcher() def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Coroutine[Any, Any, None]], *, name: Optional[str] = None, debug: bool = False, _policy_lock: threading.Lock = threading.Lock()) -> T: From 7acc7cf603dee1e129957a68b1584e7cc9a9536a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 20:33:46 +0200 Subject: [PATCH 1663/1831] Stop using chess.engine.EventLoopPolicy --- chess/engine.py | 80 +-------------------------- docs/engine.rst | 6 -- examples/bratko_kopec/bratko_kopec.py | 1 - fuzz/engine.py | 1 - test.py | 17 ------ 5 files changed, 2 insertions(+), 103 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 6fac0c602..6958479f9 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -42,77 +42,8 @@ MANAGED_OPTIONS = ["uci_chess960", "uci_variant", "multipv", "ponder"] -class EventLoopPolicy(asyncio.AbstractEventLoopPolicy): - """ - An event loop policy for thread-local event loops and child watchers. - Ensures each event loop is capable of spawning and watching subprocesses, - even when not running on the main thread. - - Windows: Uses :class:`~asyncio.ProactorEventLoop`. - - Unix: Uses :class:`~asyncio.SelectorEventLoop`. If available, - :class:`~asyncio.PidfdChildWatcher` is used to detect subprocess - termination (Python 3.9+ on Linux 5.3+). Otherwise, the default child - watcher is used on the main thread and relatively slow eager polling - is used on all other threads. - """ - class _Local(threading.local): - loop: Optional[asyncio.AbstractEventLoop] = None - set_called = False - watcher: Optional[asyncio.AbstractChildWatcher] = None - - def __init__(self) -> None: - self._local = self._Local() - - def get_event_loop(self) -> asyncio.AbstractEventLoop: - if self._local.loop is None and not self._local.set_called and threading.current_thread() is threading.main_thread(): - self.set_event_loop(self.new_event_loop()) - if self._local.loop is None: - raise RuntimeError(f"no current event loop in thread {threading.current_thread().name!r}") - return self._local.loop - - def set_event_loop(self, loop: Optional[asyncio.AbstractEventLoop]) -> None: - assert loop is None or isinstance(loop, asyncio.AbstractEventLoop) - self._local.set_called = True - self._local.loop = loop - if self._local.watcher is not None: - self._local.watcher.attach_loop(loop) - - def new_event_loop(self) -> asyncio.AbstractEventLoop: - return asyncio.ProactorEventLoop() if sys.platform == "win32" else asyncio.SelectorEventLoop() # type: ignore - - def get_child_watcher(self) -> asyncio.AbstractChildWatcher: - if self._local.watcher is None: - self._local.watcher = self._init_watcher() - self._local.watcher.attach_loop(self._local.loop) - return self._local.watcher - - def set_child_watcher(self, watcher: Optional[asyncio.AbstractChildWatcher]) -> None: - assert watcher is None or isinstance(watcher, asyncio.AbstractChildWatcher) - if self._local.watcher is not None: - self._local.watcher.close() - self._local.watcher = watcher - - def _init_watcher(self) -> asyncio.AbstractChildWatcher: - if sys.platform == "win32": - raise NotImplementedError - - try: - os.close(os.pidfd_open(os.getpid())) - watcher: asyncio.AbstractChildWatcher = asyncio.PidfdChildWatcher() - LOGGER.debug("Using PidfdChildWatcher") - return watcher - except (AttributeError, OSError): - # Before Python 3.9 or before Linux 5.3 or the syscall is not - # permitted. - pass - - if threading.current_thread() is threading.main_thread(): - LOGGER.debug("Using SafeChildWatcher") - return asyncio.SafeChildWatcher() - else: - LOGGER.debug("Using ThreadedChildWatcher") - return asyncio.ThreadedChildWatcher() +# No longer needed, but alias kept around for compatibility. +EventLoopPolicy = asyncio.DefaultEventLoopPolicy def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Coroutine[Any, Any, None]], *, name: Optional[str] = None, debug: bool = False, _policy_lock: threading.Lock = threading.Lock()) -> T: @@ -122,16 +53,9 @@ def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Corout Blocks on *future* and returns the result as soon as it is resolved. The coroutine and all remaining tasks continue running in the background until complete. - - Note: This installs a :class:`chess.engine.EventLoopPolicy` for the entire - process. """ assert asyncio.iscoroutinefunction(coroutine) - with _policy_lock: - if not isinstance(asyncio.get_event_loop_policy(), EventLoopPolicy): - asyncio.set_event_loop_policy(EventLoopPolicy()) - future: concurrent.futures.Future[T] = concurrent.futures.Future() def background() -> None: diff --git a/docs/engine.rst b/docs/engine.rst index 02dd4548f..a326430e0 100644 --- a/docs/engine.rst +++ b/docs/engine.rst @@ -58,7 +58,6 @@ Example: Let Stockfish play against itself, 100 milliseconds per move. await engine.quit() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) .. autoclass:: chess.engine.Protocol @@ -126,7 +125,6 @@ Example: await engine.quit() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) .. autoclass:: chess.engine.Protocol @@ -189,7 +187,6 @@ Example: Stream information from the engine and stop on an arbitrary condition. await engine.quit() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) .. autoclass:: chess.engine.Protocol @@ -243,7 +240,6 @@ Options # [...] - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) .. autoclass:: chess.engine.Protocol @@ -315,5 +311,3 @@ Reference .. autoclass:: chess.engine.SimpleAnalysisResult :members: - -.. autofunction:: chess.engine.EventLoopPolicy diff --git a/examples/bratko_kopec/bratko_kopec.py b/examples/bratko_kopec/bratko_kopec.py index 62e3655a6..2553f4399 100755 --- a/examples/bratko_kopec/bratko_kopec.py +++ b/examples/bratko_kopec/bratko_kopec.py @@ -152,5 +152,4 @@ async def main() -> None: if __name__ == "__main__": - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) diff --git a/fuzz/engine.py b/fuzz/engine.py index a08d08bf3..ad0cb9fe9 100644 --- a/fuzz/engine.py +++ b/fuzz/engine.py @@ -7,7 +7,6 @@ logging.getLogger("chess.engine").setLevel(logging.CRITICAL) -asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) @PythonFuzz diff --git a/test.py b/test.py index 6419eb89f..73b96f71c 100755 --- a/test.py +++ b/test.py @@ -3114,7 +3114,6 @@ async def main(): await protocol.ping() mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_uci_debug(self): @@ -3130,7 +3129,6 @@ async def main(): protocol.debug(False) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_uci_go(self): @@ -3173,7 +3171,6 @@ async def main(): self.assertEqual(result.ponder, None) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_iota_log(self): @@ -3196,7 +3193,6 @@ async def main(): await protocol.play(board, chess.engine.Limit(time=5.0)) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_uci_analyse_mode(self): @@ -3243,7 +3239,6 @@ async def main(): self.assertEqual(best.ponder, chess.Move.from_uci("e7e5")) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_uci_play_after_analyse(self): @@ -3271,7 +3266,6 @@ async def main(): mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_uci_ponderhit(self): @@ -3387,7 +3381,6 @@ async def main(): mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_uci_info(self): @@ -3474,7 +3467,6 @@ async def main(): await protocol.send_game_result(checkmate_board) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_hiarcs_bestmove(self): @@ -3499,7 +3491,6 @@ async def main(): self.assertEqual(result.info["string"], "keep double space") mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_xboard_options(self): @@ -3562,7 +3553,6 @@ async def main(): await protocol.configure({"buttonvar": None}) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_xboard_replay(self): @@ -3624,7 +3614,6 @@ async def main(): self.assertEqual(result.move, board.parse_san("d4")) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_xboard_opponent(self): @@ -3682,7 +3671,6 @@ async def main(): result = await protocol.play(board, limit, game="bad game", opponent=bad_opponent) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_xboard_result(self): @@ -3772,7 +3760,6 @@ async def main(): await protocol.send_game_result(material_board) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_xboard_analyse(self): @@ -3810,7 +3797,6 @@ async def main(): self.assertEqual(info["pv"], [chess.Move.from_uci(move) for move in ["f7f6", "e2e4", "e7e6"]]) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_xboard_level(self): @@ -3855,7 +3841,6 @@ async def main(): self.assertEqual(result.move, chess.Move.from_uci("d2d4")) mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) def test_xboard_error(self): @@ -3874,7 +3859,6 @@ async def main(): mock.assert_done() - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) @catchAndSkip(FileNotFoundError, "need /bin/bash") @@ -3886,7 +3870,6 @@ async def main(): self.assertNotEqual(results[0], None) self.assertNotEqual(results[1], None) - asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy()) asyncio.run(main()) @catchAndSkip(FileNotFoundError, "need /bin/bash") From 61a660f5d94b5be60f5d488f04145cecdb27cf29 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 20:43:43 +0200 Subject: [PATCH 1664/1831] Rename acknowledgements section --- README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index cbacf299e..d8089b146 100644 --- a/README.rst +++ b/README.rst @@ -352,8 +352,8 @@ If you like, share interesting things you are using python-chess for, for exampl * an accessible chessboard that allows blind and visually impaired players to play chess against Stockfish – https://github.com/blindpandas/chessmart -Acknowledgements ----------------- +Prior art +--------- Thanks to the Stockfish authors and thanks to Sam Tannous for publishing his approach to `avoid rotated bitboards with direct lookup (PDF) `_ @@ -371,4 +371,4 @@ License ------- python-chess is licensed under the GPL 3 (or any later version at your option). -Check out LICENSE.txt for the full text. +Check out `LICENSE.txt` for the full text. From 773888594fe44c35b5d070a9b6b04464c07958ef Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 20:47:27 +0200 Subject: [PATCH 1665/1831] Fix outdated WDL model docs --- chess/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 6958479f9..4e18a3cf7 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -453,7 +453,8 @@ def wdl(self, *, model: WdlModel = "sf", ply: int = 30) -> Wdl: :param model: * ``sf``, the WDL model used by the latest Stockfish - (currently ``sf15.1``). + (currently ``sf16``). + * ``sf16``, the WDL model used by Stockfish 16. * ``sf15.1``, the WDL model used by Stockfish 15.1. * ``sf15``, the WDL model used by Stockfish 15. * ``sf14``, the WDL model used by Stockfish 14. From dc026b9b5a931faa6f47e79cb7da5c61a19bb53b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 20:57:31 +0200 Subject: [PATCH 1666/1831] Bump copyright year in docs --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index ede90b63b..22f960575 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -34,7 +34,7 @@ # General information about the project. project = "python-chess" -copyright = "2014–2022, Niklas Fiekas" +copyright = "2014–2023, Niklas Fiekas" # The version. version = chess.__version__ From 179b6f3032008a500f5c12ab760a7f4037b2b142 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 21:02:50 +0200 Subject: [PATCH 1667/1831] Remove experimental interactive PGN viewer (closes #753) --- chess/_interactive.py | 190 ------------------------------------------ chess/pgn.py | 5 -- 2 files changed, 195 deletions(-) delete mode 100644 chess/_interactive.py diff --git a/chess/_interactive.py b/chess/_interactive.py deleted file mode 100644 index edeef3df0..000000000 --- a/chess/_interactive.py +++ /dev/null @@ -1,190 +0,0 @@ -# TODO: Fix typing in this file. -# mypy: ignore-errors - -import chess.svg - - -class WidgetError(Exception): - """ - raised when ipywidgets is not installed - """ - - -class NotJupyter(Exception): - """ - raised when InteractiveViewer is instantiated from a non jupyter shell - """ - - -try: - from ipywidgets import Button, GridBox, Layout, HTML, Output, HBox, Select - from IPython.display import display, clear_output -except ModuleNotFoundError: - raise WidgetError("You need to have ipywidgets installed and running from Jupyter") - - -class InteractiveViewer: - def __new__(cls, game): - jupyter = True - try: - if get_ipython().__class__.__name__ != "ZMQInteractiveShell": - jupyter = False - except NameError: - jupyter = False - - if not jupyter: - raise NotJupyter("The interactive viewer only runs in Jupyter shell") - - return object.__new__(cls) - - def __init__(self, game): - self.game = game - self.__board = game.board() - self.__moves = list(game.mainline_moves()) - self.__white_moves = [str(move) for (i, move) in enumerate(self.__moves) if i % 2 == 0] - self.__black_moves = [str(move) for (i, move) in enumerate(self.__moves) if i % 2 == 1] - self.__move_list_len = len(self.__white_moves) - self.__num_moves = len(self.__moves) - self.__next_move = 0 if self.__moves else None - self.__out = Output() - - def __next_click(self, _): - move = self.__moves[self.__next_move] - self.__next_move += 1 - self.__board.push(move) - self.show() - - def __prev_click(self, _): - self.__board.pop() - self.__next_move -= 1 - self.show() - - def __reset_click(self, _): - self.__board.reset() - self.__next_move = 0 - self.show() - - def __white_select_change(self, change): - new = change["new"] - if (isinstance(new, dict)) and ("index" in new): - target = new["index"] * 2 - self.__seek(target) - self.show() - - def __black_select_change(self, change): - new = change["new"] - if (isinstance(new, dict)) and ("index" in new): - target = new["index"] * 2 + 1 - self.__seek(target) - self.show() - - def __seek(self, target): - while self.__next_move <= target: - move = self.__moves[self.__next_move] - self.__next_move += 1 - self.__board.push(move) - - while self.__next_move > target + 1: - self.__board.pop() - self.__next_move -= 1 - - def show(self): - display(self.__out) - next_move = Button( - icon="step-forward", - layout=Layout(width="60px", grid_area="right"), - disabled=self.__next_move >= self.__num_moves, - ) - - prev_move = Button( - icon="step-backward", - layout=Layout(width="60px", grid_area="left"), - disabled=self.__next_move == 0, - ) - - reset = Button( - icon="stop", - layout=Layout(width="60px", grid_area="middle"), - disabled=self.__next_move == 0, - ) - - if self.__next_move == 0: - white_move = None - black_move = None - else: - white_move = ( - self.__white_moves[self.__next_move // 2] - if (self.__next_move % 2) == 1 - else None - ) - black_move = ( - self.__black_moves[self.__next_move // 2 - 1] - if (self.__next_move % 2) == 0 - else None - ) - - white_move_list = Select( - options=self.__white_moves, - value=white_move, - rows=max(self.__move_list_len, 24), - disabled=False, - layout=Layout(width="80px"), - ) - - black_move_list = Select( - options=self.__black_moves, - value=black_move, - rows=max(self.__move_list_len, 24), - disabled=False, - layout=Layout(width="80px"), - ) - - white_move_list.observe(self.__white_select_change) - black_move_list.observe(self.__black_select_change) - - move_number_width = 3 + len(str(self.__move_list_len)) * 10 - - move_number = Select( - options=range(1, self.__move_list_len + 1), - value=None, - disabled=True, - rows=max(self.__move_list_len, 24), - layout=Layout(width=f"{move_number_width}px"), - ) - - move_list = HBox( - [move_number, white_move_list, black_move_list], - layout=Layout(height="407px", grid_area="moves"), - ) - - next_move.on_click(self.__next_click) - prev_move.on_click(self.__prev_click) - reset.on_click(self.__reset_click) - - with self.__out: - grid_box = GridBox( - children=[next_move, prev_move, reset, self.svg, move_list], - layout=Layout( - width=f"{390+move_number_width+160}px", - grid_template_rows="90% 10%", - grid_template_areas=""" - "top top top top top moves" - ". left middle right . moves" - """, - ), - ) - clear_output(wait=True) - display(grid_box) - - @property - def svg(self) -> HTML: - svg = chess.svg.board( - board=self.__board, - size=390, - lastmove=self.__board.peek() if self.__board.move_stack else None, - check=self.__board.king(self.__board.turn) - if self.__board.is_check() - else None, - ) - svg_widget = HTML(value=svg, layout=Layout(grid_area="top")) - return svg_widget diff --git a/chess/pgn.py b/chess/pgn.py index ae22afaf6..9ff218ead 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -804,11 +804,6 @@ def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str def board(self) -> chess.Board: return self.headers.board() - # TODO: Consider naming. - def _interactive_viewer(self) -> Any: - from chess._interactive import InteractiveViewer - return InteractiveViewer(self) # type: ignore - def ply(self) -> int: # Optimization: Parse FEN only for custom starting positions. return self.board().ply() if "FEN" in self.headers else 0 From bab76653b11e447f7431106025ddd4ebaefc407e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 21:30:46 +0200 Subject: [PATCH 1668/1831] Let setup.py show better error on Python 3.7 --- setup.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index ed3d8b0bf..8c397e456 100755 --- a/setup.py +++ b/setup.py @@ -18,8 +18,13 @@ end of 2018. Consider upgrading to Python 3. """)) -if sys.version_info < (3, 7): - raise ImportError("Since version 1.0.0, python-chess requires Python 3.7 or later.") +if sys.version_info < (3, 8): + raise ImportError(textwrap.dedent("""\ + You are trying to install python-chess. + + Since version 1.11.0, python-chess requires Python 3.8 or later. + Since version 1.0.0, python-chess requires Python 3.7 or later. + """)) import chess From 86da00e86f458537bc1a0a6929149a9d2730dd9a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 27 Jul 2023 21:32:46 +0200 Subject: [PATCH 1669/1831] Fix rst syntax --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index d8089b146..8ab138666 100644 --- a/README.rst +++ b/README.rst @@ -371,4 +371,4 @@ License ------- python-chess is licensed under the GPL 3 (or any later version at your option). -Check out `LICENSE.txt` for the full text. +Check out ``LICENSE.txt`` for the full text. From 60d38d5abea8ef1dc2a4787bd8a8981741324a78 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 30 Jul 2023 18:51:45 +0200 Subject: [PATCH 1670/1831] Start changelog for next release --- CHANGELOG.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a44b2b070..0fa76effa 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,15 @@ Changelog for python-chess ========================== +Upcoming in the next release +---------------------------- + +Changes: + +* Dropped support for Python 3.7, which had reached its end of life. +* `chess.engine.EventLoopPolicy` is no longer needed and now merely an alias + for the default event loop policy. + New in v1.10.0 (27th Jul 2023) ------------------------------ From 7857668ed939d346200ac624bcb7e6cecbebf19e Mon Sep 17 00:00:00 2001 From: mauricesvp Date: Wed, 2 Aug 2023 16:00:19 +0200 Subject: [PATCH 1671/1831] Add PGN TimeControl Header Parser --- chess/pgn.py | 100 ++++++++++++++++++++++++ data/pgn/nepomniachtchi-liren-game1.pgn | 22 ++++++ test.py | 47 +++++++++++ 3 files changed, 169 insertions(+) create mode 100644 data/pgn/nepomniachtchi-liren-game1.pgn diff --git a/chess/pgn.py b/chess/pgn.py index 9ff218ead..72c613dd4 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1,6 +1,7 @@ from __future__ import annotations import abc +import dataclasses import enum import itertools import logging @@ -141,6 +142,39 @@ class SkipType(enum.Enum): ResultT = TypeVar("ResultT", covariant=True) +class TimeControlType(enum.Enum): + UNKNOW = 0 + UNLIMITED = 1 + STANDARD = 2 + RAPID = 3 + BLITZ = 4 + BULLET = 5 + + +@dataclasses.dataclass +class TimeControlPart: + moves: int = 0 + time: int = 0 + increment: float = 0 + delay: float = 0 + + +@dataclasses.dataclass +class TimeControl: + """ + PGN TimeControl Parser + Spec: http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm#c9.6 + + Not Yet Implemented: + - Hourglass/Sandclock ('*' prefix) + - Differentiating between Bronstein and Simple Delay (Not part of the PGN Spec) + - More Info: https://en.wikipedia.org/wiki/Chess_clock#Timing_methods + """ + + parts: list[TimeControlPart] = dataclasses.field(default_factory=list) + type: TimeControlType = TimeControlType.UNKNOW + + class _AcceptFrame: def __init__(self, node: ChildNode, *, is_variation: bool = False, sidelines: bool = True): self.state = "pre" @@ -859,6 +893,14 @@ def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: visitor.end_game() return visitor.result() + def time_control(self) -> TimeControl: + """ + Returns the time control of the game. If the game has no time control + information, the default time control ('UNKNOWN') is returned. + """ + time_control_header = self.headers.get("TimeControl", "") + return parse_time_control(time_control_header) + @classmethod def from_board(cls: Type[GameT], board: chess.Board) -> GameT: """Creates a game from the move stack of a :class:`~chess.Board()`.""" @@ -1763,3 +1805,61 @@ def skip_game(handle: TextIO) -> bool: Skips a game. Returns ``True`` if a game was found and skipped. """ return bool(read_game(handle, Visitor=SkipVisitor)) + + +def parse_time_control(time_control: str) -> TimeControl: + tc = TimeControl() + + if not time_control: + return tc + + if time_control.startswith("?"): + return tc + + if time_control.startswith("-"): + tc.type = TimeControlType.UNLIMITED + return tc + + def _parse_part(part: str) -> TimeControlPart: + tcp = TimeControlPart() + + moves_time, *bonus = part.split("+") + + if bonus: + bonus = bonus[0] + if bonus.lower().endswith("d"): + tcp.delay = float(bonus[:-1]) + else: + tcp.increment = float(bonus) + + moves, *time = moves_time.split("/") + if time: + tcp.moves = int(moves) + tcp.time = int(time[0]) + else: + tcp.moves = 0 + tcp.time = int(moves) + + return tcp + + tc.parts = [_parse_part(part) for part in time_control.split(":")] + + if len(tc.parts) > 1: + for part in tc.parts[:-1]: + if part.moves == 0: + raise ValueError("Only last part can be 'sudden death'.") + + # Classification according to https://www.fide.com/FIDE/handbook/LawsOfChess.pdf + # (Bullet added) + base_time = tc.parts[0].time + increment = tc.parts[0].increment + if (base_time + 60 * increment) < 3 * 60: + tc.type = TimeControlType.BULLET + elif (base_time + 60 * increment) < 15 * 60: + tc.type = TimeControlType.BLITZ + elif (base_time + 60 * increment) < 60 * 60: + tc.type = TimeControlType.RAPID + else: + tc.type = TimeControlType.STANDARD + + return tc diff --git a/data/pgn/nepomniachtchi-liren-game1.pgn b/data/pgn/nepomniachtchi-liren-game1.pgn new file mode 100644 index 000000000..ea3234154 --- /dev/null +++ b/data/pgn/nepomniachtchi-liren-game1.pgn @@ -0,0 +1,22 @@ +[Event "FIDE World Championship 2023"] +[Site "Astana KAZ"] +[Date "2023.04.09"] +[Round "1"] +[White "Nepomniachtchi, Ian"] +[Black "Liren, Ding"] +[Result "1/2-1/2"] +[TimeControl "40/7200:20/3600:900+30"] +[WhiteFideId "4168119"] +[BlackFideId "8603677"] +[WhiteElo "2795"] +[BlackElo "2788"] + +1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Bxc6 dxc6 +7. Re1 Nd7 8. d4 exd4 9. Qxd4 O-O 10. Bf4 Nc5 11. Qe3 Bg4 12. Nd4 +Qd7 13. Nc3 Rad8 14. Nf5 Ne6 15. Nxe7+ Qxe7 16. Bg3 Bh5 17. f3 f6 +18. h3 h6 19. Kh2 Bf7 20. Rad1 b6 21. a3 a5 22. Ne2 Rxd1 23. Rxd1 +Rd8 24. Rd3 c5 25. Qd2 c6 26. Rxd8+ Nxd8 27. Qf4 b5 28. Qb8 Kh7 +29. Bd6 Qd7 30. Ng3 Ne6 31. f4 h5 32. c3 c4 33. h4 Qd8 34. Qb7 +Be8 35. Nf5 Qd7 36. Qb8 Qd8 37. Qxd8 Nxd8 38. Nd4 Nb7 39. e5 Kg8 +40. Kg3 Bd7 41. Bc7 Nc5 42. Bxa5 Kf7 43. Bb4 Nd3 44. e6+ Bxe6 +45. Nxc6 Bd7 46. Nd4 Nxb2 47. Kf3 Nd3 48. g3 Nc1 49. Ke3 1/2-1/2 diff --git a/test.py b/test.py index 73b96f71c..e1d0d50c5 100755 --- a/test.py +++ b/test.py @@ -2493,6 +2493,53 @@ def test_read_headers(self): self.assertEqual(first_drawn_game.headers["Site"], "03") self.assertEqual(first_drawn_game[0].move, chess.Move.from_uci("d2d3")) + def test_parse_time_control(self): + with open("data/pgn/nepomniachtchi-liren-game1.pgn") as pgn: + game = chess.pgn.read_game(pgn) + tc = game.time_control() + + self.assertEqual(tc, chess.pgn.parse_time_control(game.headers["TimeControl"])) + + self.assertEqual(tc.type, chess.pgn.TimeControlType.STANDARD) + self.assertEqual(len(tc.parts), 3) + + tcp1, tcp2, tcp3 = tc.parts + + self.assertEqual(tcp1, chess.pgn.TimeControlPart(40, 7200)) + self.assertEqual(tcp2, chess.pgn.TimeControlPart(20, 3600)) + self.assertEqual(tcp3, chess.pgn.TimeControlPart(0, 900, 30)) + + self.assertEqual(chess.pgn.TimeControlType.BULLET, chess.pgn.parse_time_control("60").type) + self.assertEqual(chess.pgn.TimeControlType.BULLET, chess.pgn.parse_time_control("60+1").type) + + self.assertEqual(chess.pgn.TimeControlType.BLITZ, chess.pgn.parse_time_control("60+2").type) + self.assertEqual(chess.pgn.TimeControlType.BLITZ, chess.pgn.parse_time_control("300").type) + self.assertEqual(chess.pgn.TimeControlType.BLITZ, chess.pgn.parse_time_control("300+3").type) + + self.assertEqual(chess.pgn.TimeControlType.RAPID, chess.pgn.parse_time_control("300+10").type) + self.assertEqual(chess.pgn.TimeControlType.RAPID, chess.pgn.parse_time_control("1800").type) + self.assertEqual(chess.pgn.TimeControlType.RAPID, chess.pgn.parse_time_control("1800+10").type) + + self.assertEqual(chess.pgn.TimeControlType.STANDARD, chess.pgn.parse_time_control("1800+30").type) + self.assertEqual(chess.pgn.TimeControlType.STANDARD, chess.pgn.parse_time_control("5400").type) + self.assertEqual(chess.pgn.TimeControlType.STANDARD, chess.pgn.parse_time_control("5400+30").type) + + with self.assertRaises(ValueError): + chess.pgn.parse_time_control("300+a") + + with self.assertRaises(ValueError): + chess.pgn.parse_time_control("300+ad") + + with self.assertRaises(ValueError): + chess.pgn.parse_time_control("600:20/180") + + with self.assertRaises(ValueError): + chess.pgn.parse_time_control("abc") + + with self.assertRaises(ValueError): + chess.pgn.parse_time_control("40/abc") + + def test_visit_board(self): class TraceVisitor(chess.pgn.BaseVisitor): def __init__(self): From acc85c2c4ede81ccd79183cb05c2754663bcc658 Mon Sep 17 00:00:00 2001 From: mauricesvp Date: Wed, 2 Aug 2023 20:53:52 +0200 Subject: [PATCH 1672/1831] Fix mypy --- chess/pgn.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 72c613dd4..55eddbc29 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1826,11 +1826,11 @@ def _parse_part(part: str) -> TimeControlPart: moves_time, *bonus = part.split("+") if bonus: - bonus = bonus[0] - if bonus.lower().endswith("d"): - tcp.delay = float(bonus[:-1]) + _bonus = bonus[0] + if _bonus.lower().endswith("d"): + tcp.delay = float(_bonus[:-1]) else: - tcp.increment = float(bonus) + tcp.increment = float(_bonus) moves, *time = moves_time.split("/") if time: From 48bd065b14c5b61cc94227ed5532a97db8ac5a45 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 2 Aug 2023 21:25:18 +0200 Subject: [PATCH 1673/1831] Add ColorName literal type --- chess/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 0604cec54..65719fd5c 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -29,7 +29,8 @@ Color = bool COLORS = [WHITE, BLACK] = [True, False] -COLOR_NAMES = ["black", "white"] +ColorName = Literal["white", "black"] +COLOR_NAMES: List[ColorName] = ["black", "white"] PieceType = int PIECE_TYPES = [PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING] = range(1, 7) From 552d6b8060a4960c765eb591c37a1252f857adbc Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 2 Aug 2023 21:48:32 +0200 Subject: [PATCH 1674/1831] Import TypedDict directly --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 4e18a3cf7..ed01e353a 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -24,7 +24,7 @@ from chess import Color from types import TracebackType -from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Optional, Tuple, Type, TypeVar, Union +from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Optional, Tuple, Type, TypedDict, TypeVar, Union WdlModel = Literal["sf", "sf16", "sf15.1", "sf15", "sf14", "sf12", "lichess"] @@ -217,7 +217,7 @@ def __repr__(self) -> str: if getattr(self, attr) is not None)) -class InfoDict(typing.TypedDict, total=False): +class InfoDict(TypedDict, total=False): """ Dictionary of aggregated information sent by the engine. From e1732436dcd590ea02cd51810c05d9e0ea030cab Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 2 Aug 2023 22:50:44 +0200 Subject: [PATCH 1675/1831] Remove _policy_lock --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index ed01e353a..fcd92563d 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -46,7 +46,7 @@ EventLoopPolicy = asyncio.DefaultEventLoopPolicy -def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Coroutine[Any, Any, None]], *, name: Optional[str] = None, debug: bool = False, _policy_lock: threading.Lock = threading.Lock()) -> T: +def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Coroutine[Any, Any, None]], *, name: Optional[str] = None, debug: bool = False) -> T: """ Runs ``coroutine(future)`` in a new event loop on a background thread. From 90eeeb0f9047197bcdfb26879061545cc34bbc94 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 2 Aug 2023 22:53:43 +0200 Subject: [PATCH 1676/1831] Fix unused debug in chess.engine.run_in_background() --- chess/engine.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index fcd92563d..5f50a1414 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -46,7 +46,7 @@ EventLoopPolicy = asyncio.DefaultEventLoopPolicy -def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Coroutine[Any, Any, None]], *, name: Optional[str] = None, debug: bool = False) -> T: +def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Coroutine[Any, Any, None]], *, name: Optional[str] = None, debug: Optional[bool] = None) -> T: """ Runs ``coroutine(future)`` in a new event loop on a background thread. @@ -60,7 +60,7 @@ def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Corout def background() -> None: try: - asyncio.run(coroutine(future)) + asyncio.run(coroutine(future), debug=debug) future.cancel() except Exception as exc: future.set_exception(exc) @@ -2894,7 +2894,7 @@ def _shutdown() -> None: self.protocol.loop.call_soon_threadsafe(_shutdown) @classmethod - def popen(cls, Protocol: Type[Protocol], command: Union[str, List[str]], *, timeout: Optional[float] = 10.0, debug: bool = False, setpgrp: bool = False, **popen_args: Any) -> SimpleEngine: + def popen(cls, Protocol: Type[Protocol], command: Union[str, List[str]], *, timeout: Optional[float] = 10.0, debug: Optional[bool] = None, setpgrp: bool = False, **popen_args: Any) -> SimpleEngine: async def background(future: concurrent.futures.Future[SimpleEngine]) -> None: transport, protocol = await Protocol.popen(command, setpgrp=setpgrp, **popen_args) threading.current_thread().name = f"{cls.__name__} (pid={transport.get_pid()})" @@ -2911,7 +2911,7 @@ async def background(future: concurrent.futures.Future[SimpleEngine]) -> None: return run_in_background(background, name=f"{cls.__name__} (command={command!r})", debug=debug) @classmethod - def popen_uci(cls, command: Union[str, List[str]], *, timeout: Optional[float] = 10.0, debug: bool = False, setpgrp: bool = False, **popen_args: Any) -> SimpleEngine: + def popen_uci(cls, command: Union[str, List[str]], *, timeout: Optional[float] = 10.0, debug: Optional[bool] = None, setpgrp: bool = False, **popen_args: Any) -> SimpleEngine: """ Spawns and initializes a UCI engine. Returns a :class:`~chess.engine.SimpleEngine` instance. @@ -2919,7 +2919,7 @@ def popen_uci(cls, command: Union[str, List[str]], *, timeout: Optional[float] = return cls.popen(UciProtocol, command, timeout=timeout, debug=debug, setpgrp=setpgrp, **popen_args) @classmethod - def popen_xboard(cls, command: Union[str, List[str]], *, timeout: Optional[float] = 10.0, debug: bool = False, setpgrp: bool = False, **popen_args: Any) -> SimpleEngine: + def popen_xboard(cls, command: Union[str, List[str]], *, timeout: Optional[float] = 10.0, debug: Optional[bool] = None, setpgrp: bool = False, **popen_args: Any) -> SimpleEngine: """ Spawns and initializes an XBoard engine. Returns a :class:`~chess.engine.SimpleEngine` instance. From 35b961c17b7a6dcbad98f4f3bfb9df115a28db29 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 6 Aug 2023 10:47:25 +0200 Subject: [PATCH 1677/1831] Avoid start_new_session if possible --- chess/engine.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 5f50a1414..01ee08b3e 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1180,7 +1180,11 @@ async def popen(cls: Type[ProtocolT], command: Union[str, List[str]], *, setpgrp popen_args["creationflags"] = popen_args.get("creationflags", 0) | subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore except AttributeError: # Unix. - popen_args["start_new_session"] = True + if sys.version_info >= (3, 11): + popen_args["process_group"] = 0 + else: + # Before Python 3.11 + popen_args["start_new_session"] = True return await asyncio.get_running_loop().subprocess_exec(cls, *command, **popen_args) From b6a04e8db55b6fca08250ba883aba50c60a3c589 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 3 Sep 2023 21:37:44 -0700 Subject: [PATCH 1678/1831] Delete unused imports --- chess/engine.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 01ee08b3e..0b0f061dc 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -10,14 +10,12 @@ import enum import logging import math -import warnings import shlex import subprocess import sys import threading import time import typing -import os import re import chess From e9997d52c8c06b773a797029ee7ba8630c0829bd Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 5 Sep 2023 22:56:14 -0700 Subject: [PATCH 1679/1831] Create new function for parsing engine output The function next_token() extracts the next word from a string and removes the leading and trailing whitespace around that word. It also returns the remainder of the string unchanged. Using this function instead of split() gets rid of extraneous whitespace when searching for keywords and preserves whitespace in strings generated by users and their engines. --- chess/engine.py | 169 +++++++++++++++++++++++++++++++----------------- 1 file changed, 110 insertions(+), 59 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 0b0f061dc..22b6125dd 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1303,14 +1303,15 @@ def start(self, engine: UciProtocol) -> None: engine.send_line("uci") def line_received(self, engine: UciProtocol, line: str) -> None: - if line == "uciok" and not self.result.done(): + token, remaining = _next_token(line) + if line.strip() == "uciok" and not self.result.done(): engine.initialized = True self.result.set_result(None) self.set_finished() - elif line.startswith("option "): - self._option(engine, line.split(" ", 1)[1]) - elif line.startswith("id "): - self._id(engine, line.split(" ", 1)[1]) + elif token == "option": + self._option(engine, remaining) + elif token == "id": + self._id(engine, remaining) def _option(self, engine: UciProtocol, arg: str) -> None: current_parameter = None @@ -1371,8 +1372,8 @@ def _option(self, engine: UciProtocol, arg: str) -> None: engine.target_config[option.name] = option.default def _id(self, engine: UciProtocol, arg: str) -> None: - key, value = arg.split(" ", 1) - engine.id[key] = value + key, value = _next_token(arg) + engine.id[key] = value.strip() return await self.communicate(UciInitializeCommand) @@ -1587,11 +1588,12 @@ def start(self, engine: UciProtocol) -> None: self._readyok(engine) def line_received(self, engine: UciProtocol, line: str) -> None: - if line.startswith("info "): - self._info(engine, line.split(" ", 1)[1]) - elif line.startswith("bestmove "): - self._bestmove(engine, line.split(" ", 1)[1]) - elif line == "readyok" and self.sent_isready: + token, remaining = _next_token(line) + if token == "info": + self._info(engine, remaining) + elif token == "bestmove": + self._bestmove(engine, remaining) + elif line.strip() == "readyok" and self.sent_isready: self._readyok(engine) else: LOGGER.warning("%s: Unexpected engine output: %r", engine, line) @@ -1679,11 +1681,12 @@ def start(self, engine: UciProtocol) -> None: self._readyok(engine) def line_received(self, engine: UciProtocol, line: str) -> None: - if line.startswith("info "): - self._info(engine, line.split(" ", 1)[1]) - elif line.startswith("bestmove "): - self._bestmove(engine, line.split(" ", 1)[1]) - elif line == "readyok" and self.sent_isready: + token, remaining = _next_token(line) + if token == "info": + self._info(engine, remaining) + elif token == "bestmove": + self._bestmove(engine, remaining) + elif line.strip() == "readyok" and self.sent_isready: self._readyok(engine) else: LOGGER.warning("%s: Unexpected engine output: %r", engine, line) @@ -1733,34 +1736,39 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL if not selector: return info - tokens = arg.split(" ") - while tokens: - parameter = tokens.pop(0) + remaining_line = arg + while remaining_line: + parameter, remaining_line = _next_token(remaining_line) if parameter == "string": - info["string"] = " ".join(tokens) + info["string"] = remaining_line break elif parameter in ["depth", "seldepth", "nodes", "multipv", "currmovenumber", "hashfull", "nps", "tbhits", "cpuload"]: try: - info[parameter] = int(tokens.pop(0)) # type: ignore + number, remaining_line = _next_token(remaining_line) + info[parameter] = int(number) # type: ignore except (ValueError, IndexError): LOGGER.error("Exception parsing %s from info: %r", parameter, arg) elif parameter == "time": try: - info["time"] = int(tokens.pop(0)) / 1000.0 + time_ms, remaining_line = _next_token(remaining_line) + info["time"] = int(time_ms) / 1000.0 except (ValueError, IndexError): LOGGER.error("Exception parsing %s from info: %r", parameter, arg) elif parameter == "ebf": try: - info["ebf"] = float(tokens.pop(0)) + number, remaining_line = _next_token(remaining_line) + info["ebf"] = float(number) except (ValueError, IndexError): LOGGER.error("Exception parsing %s from info: %r", parameter, arg) elif parameter == "score" and selector & INFO_SCORE: try: - kind = tokens.pop(0) - value = tokens.pop(0) - if tokens and tokens[0] in ["lowerbound", "upperbound"]: - info[tokens.pop(0)] = True # type: ignore + kind, remaining_line = _next_token(remaining_line) + value, remaining_line = _next_token(remaining_line) + token, remaining_after_token = _next_token(remaining_line) + if token in ["lowerbound", "upperbound"]: + info[token] = True # type: ignore + remaining_line = remaining_after_token if kind == "cp": info["score"] = PovScore(Cp(int(value)), root_board.turn) elif kind == "mate": @@ -1771,7 +1779,8 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL LOGGER.error("Exception parsing score from info: %r", arg) elif parameter == "currmove": try: - info["currmove"] = chess.Move.from_uci(tokens.pop(0)) + current_move, remaining_line = _next_token(remaining_line) + info["currmove"] = chess.Move.from_uci(current_move) except (ValueError, IndexError): LOGGER.error("Exception parsing currmove from info: %r", arg) elif parameter == "currline" and selector & INFO_CURRLINE: @@ -1779,13 +1788,19 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL if "currline" not in info: info["currline"] = {} - cpunr = int(tokens.pop(0)) + cpunr_text, remaining_line = _next_token(remaining_line) + cpunr = int(cpunr_text) currline: List[chess.Move] = [] info["currline"][cpunr] = currline board = root_board.copy(stack=False) - while tokens and UCI_REGEX.match(tokens[0]): - currline.append(board.push_uci(tokens.pop(0))) + while True: + next_move, remaining_line_after_move = _next_token(remaining_line) + if UCI_REGEX.match(next_move): + currline.append(board.push_uci(next_move)) + remaining_line = remaining_line_after_move + else: + break except (ValueError, IndexError): LOGGER.error("Exception parsing currline from info: %r, position at root: %s", arg, root_board.fen()) elif parameter == "refutation" and selector & INFO_REFUTATION: @@ -1794,13 +1809,19 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL info["refutation"] = {} board = root_board.copy(stack=False) - refuted = board.push_uci(tokens.pop(0)) + refuted_text, remaining_line = _next_token(remaining_line) + refuted = board.push_uci(refuted_text) refuted_by: List[chess.Move] = [] info["refutation"][refuted] = refuted_by - while tokens and UCI_REGEX.match(tokens[0]): - refuted_by.append(board.push_uci(tokens.pop(0))) + while True: + token, remaining_line_after_move = _next_token(remaining_line) + if UCI_REGEX.match(token): + refuted_by.append(board.push_uci(token)) + remaining_line = remaining_line_after_move + else: + break except (ValueError, IndexError): LOGGER.error("Exception parsing refutation from info: %r, position at root: %s", arg, root_board.fen()) elif parameter == "pv" and selector & INFO_PV: @@ -1808,13 +1829,21 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL pv: List[chess.Move] = [] info["pv"] = pv board = root_board.copy(stack=False) - while tokens and UCI_REGEX.match(tokens[0]): - pv.append(board.push_uci(tokens.pop(0))) + while True: + token, remaining_line_after_pv = _next_token(remaining_line) + if UCI_REGEX.match(token): + pv.append(board.push_uci(token)) + remaining_line = remaining_line_after_pv + else: + break except (ValueError, IndexError): LOGGER.error("Exception parsing pv from info: %r, position at root: %s", arg, root_board.fen()) elif parameter == "wdl": try: - info["wdl"] = PovWdl(Wdl(int(tokens.pop(0)), int(tokens.pop(0)), int(tokens.pop(0))), root_board.turn) + wins, remaining_line = _next_token(remaining_line) + draws, remaining_line = _next_token(remaining_line) + losses, remaining_line = _next_token(remaining_line) + info["wdl"] = PovWdl(Wdl(int(wins), int(draws), int(losses)), root_board.turn) except (ValueError, IndexError): LOGGER.error("Exception parsing wdl from info: %r", arg) @@ -1944,10 +1973,11 @@ def timeout(self, engine: XBoardProtocol) -> None: self.end(engine) def line_received(self, engine: XBoardProtocol, line: str) -> None: - if line.startswith("#"): + token, remaining = _next_token(line) + if token.startswith("#"): pass - elif line.startswith("feature "): - self._feature(engine, line.split(" ", 1)[1]) + elif token == "feature": + self._feature(engine, remaining) elif XBOARD_ERROR_REGEX.match(line): raise EngineError(line) @@ -2159,32 +2189,35 @@ def start(self, engine: XBoardProtocol) -> None: engine.send_line("go") def line_received(self, engine: XBoardProtocol, line: str) -> None: - if line.startswith("move "): - self._move(engine, line.split(" ", 1)[1]) - elif line.startswith("Hint: "): - self._hint(engine, line.split(" ", 1)[1]) - elif line == self.pong_after_move: - if not self.result.done(): - self.result.set_result(self.play_result) - if not ponder: + token, remaining = _next_token(line) + if token == "move": + self._move(engine, remaining.strip()) + elif token == "Hint:": + self._hint(engine, remaining.strip()) + elif token == "pong": + pong_line = f"{token} {remaining.strip()}" + if pong_line == self.pong_after_move: + if not self.result.done(): + self.result.set_result(self.play_result) + if not ponder: + self.set_finished() + elif pong_line == self.pong_after_ponder: + if not self.result.done(): + self.result.set_result(self.play_result) self.set_finished() - elif line == self.pong_after_ponder: - if not self.result.done(): - self.result.set_result(self.play_result) - self.set_finished() - elif line == "offer draw": + elif f"{token} {remaining.strip()}" == "offer draw": if not self.result.done(): self.play_result.draw_offered = True self._ping_after_move(engine) - elif line == "resign": + elif line.strip() == "resign": if not self.result.done(): self.play_result.resigned = True self._ping_after_move(engine) - elif line.startswith("1-0") or line.startswith("0-1") or line.startswith("1/2-1/2"): + elif token in ["1-0", "0-1", "1/2-1/2"]: if "resign" in line and not self.result.done(): self.play_result.resigned = True self._ping_after_move(engine) - elif line.startswith("#"): + elif token.startswith("#"): pass elif XBOARD_ERROR_REGEX.match(line): engine.first_game = True # Board state might no longer be in sync @@ -2291,11 +2324,12 @@ def start(self, engine: XBoardProtocol) -> None: self.time_limit_handle = None def line_received(self, engine: XBoardProtocol, line: str) -> None: - if line.startswith("#"): + token, remaining = _next_token(line) + if token.startswith("#"): pass elif len(line.split()) >= 4 and line.lstrip()[0].isdigit(): self._post(engine, line) - elif line == self.final_pong: + elif f"{token} {remaining.strip()}" == self.final_pong: self.end(engine) elif XBOARD_ERROR_REGEX.match(line): engine.first_game = True # Board state might no longer be in sync @@ -2551,6 +2585,23 @@ def _parse_xboard_post(line: str, root_board: chess.Board, selector: Info = INFO return info +def _next_token(line: str) -> tuple[str, str]: + """Get the next token in a whitespace-delimited line of text. + + The result is returned as a 2-part tuple of strings. + + If the input line is empty or all whitespace, then the result is two + empty strings. + + If the input line is not empty and not completely whitespace, then + the first element of the returned tuple is a single word with + leading and trailing whitespace removed. The second element is the + unchanged rest of the line.""" + + parts = line.split(maxsplit=1) + return (parts[0] if parts else "", parts[1] if len(parts) == 2 else "") + + class BestMove: """Returned by :func:`chess.engine.AnalysisResult.wait()`.""" From a68636e7a82841e4389b1d53390b6b33ff7a43e5 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 10 Sep 2023 01:34:03 -0700 Subject: [PATCH 1680/1831] Split on all whitespace --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 22b6125dd..c8ed5cd4d 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1324,7 +1324,7 @@ def _option(self, engine: UciProtocol, arg: str) -> None: current_var = None var = [] - for token in arg.strip().split(" "): + for token in arg.split(): if token == "name" and not name: current_parameter = "name" elif token == "type" and not type: From dbc278f7cedb33409fc60186df20e1ac55ab39b3 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 10 Sep 2023 01:34:40 -0700 Subject: [PATCH 1681/1831] Gather repeated code in option parsing --- chess/engine.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index c8ed5cd4d..1ec7c2c8e 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1323,6 +1323,13 @@ def _option(self, engine: UciProtocol, arg: str) -> None: max = None current_var = None var = [] + + def parse_min_max_value(token: str, which: Literal["min", "max"]): + try: + return int(token) + except ValueError: + LOGGER.exception(f"Exception parsing option {which}") + return None for token in arg.split(): if token == "name" and not name: @@ -1349,15 +1356,9 @@ def _option(self, engine: UciProtocol, arg: str) -> None: elif current_parameter == "var": current_var.append(token) elif current_parameter == "min": - try: - min = int(token) - except ValueError: - LOGGER.exception("Exception parsing option min") + min = parse_min_max_value(token, "min") elif current_parameter == "max": - try: - max = int(token) - except ValueError: - LOGGER.exception("Exception parsing option max") + max = parse_min_max_value(token, "max") if current_var is not None: var.append(" ".join(current_var)) From 2e6ff83ace87d54da0cea6c679ae1b642afe8331 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 10 Sep 2023 02:09:09 -0700 Subject: [PATCH 1682/1831] Create function for repeated code --- chess/engine.py | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 1ec7c2c8e..72681a627 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1732,6 +1732,18 @@ async def quit(self) -> None: UCI_REGEX = re.compile(r"^[a-h][1-8][a-h][1-8][pnbrqk]?|[PNBRQK]@[a-h][1-8]|0000\Z") +def _create_variation_line(root_board: chess.Board, line: str) -> tuple[list[chess.Move], str]: + board = root_board.copy(stack=False) + currline: list[chess.Move] = [] + while True: + next_move, remaining_line_after_move = _next_token(line) + if UCI_REGEX.match(next_move): + currline.append(board.push_uci(next_move)) + line = remaining_line_after_move + else: + return currline, line + + def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL) -> InfoDict: info: InfoDict = {} if not selector: @@ -1791,17 +1803,8 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL cpunr_text, remaining_line = _next_token(remaining_line) cpunr = int(cpunr_text) - currline: List[chess.Move] = [] + currline, remaining_line = _create_variation_line(root_board, remaining_line) info["currline"][cpunr] = currline - - board = root_board.copy(stack=False) - while True: - next_move, remaining_line_after_move = _next_token(remaining_line) - if UCI_REGEX.match(next_move): - currline.append(board.push_uci(next_move)) - remaining_line = remaining_line_after_move - else: - break except (ValueError, IndexError): LOGGER.error("Exception parsing currline from info: %r, position at root: %s", arg, root_board.fen()) elif parameter == "refutation" and selector & INFO_REFUTATION: @@ -1813,30 +1816,14 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL refuted_text, remaining_line = _next_token(remaining_line) refuted = board.push_uci(refuted_text) - refuted_by: List[chess.Move] = [] + refuted_by, remaining_line = _create_variation_line(board, remaining_line) info["refutation"][refuted] = refuted_by - - while True: - token, remaining_line_after_move = _next_token(remaining_line) - if UCI_REGEX.match(token): - refuted_by.append(board.push_uci(token)) - remaining_line = remaining_line_after_move - else: - break except (ValueError, IndexError): LOGGER.error("Exception parsing refutation from info: %r, position at root: %s", arg, root_board.fen()) elif parameter == "pv" and selector & INFO_PV: try: - pv: List[chess.Move] = [] + pv, remaining_line = _create_variation_line(root_board, remaining_line) info["pv"] = pv - board = root_board.copy(stack=False) - while True: - token, remaining_line_after_pv = _next_token(remaining_line) - if UCI_REGEX.match(token): - pv.append(board.push_uci(token)) - remaining_line = remaining_line_after_pv - else: - break except (ValueError, IndexError): LOGGER.error("Exception parsing pv from info: %r, position at root: %s", arg, root_board.fen()) elif parameter == "wdl": From 7aaf9d324f28e9b6a3abc82e284b7e5224b8438f Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 10 Sep 2023 02:20:11 -0700 Subject: [PATCH 1683/1831] Fix tox.ini comments Latest version of flake8 no longer allows inline comments in config file. --- tox.ini | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tox.ini b/tox.ini index 665e9f38b..f629723cd 100644 --- a/tox.ini +++ b/tox.ini @@ -20,11 +20,18 @@ commands = [flake8] ignore = - E126 E131 # Allow over-indent and unaligned indent - E241 # Allow indenting array elements - E302 E305 # Allow grouping functions - E741 # Allow "ambiguous" variable names - W504 # Allow binary operators before EOL (end of line) - E704 E301 # Allow "def overloaded(): ..." - E722 # Bare except (with or without reraise) + # Allow over-indent and unaligned indent + E126 E131 + # Allow indenting array elements + E241 + # Allow grouping functions + E302 E305 + # Allow "ambiguous" variable names + E741 + # Allow binary operators before EOL (end of line) + W504 + # Allow "def overloaded(): ..." + E704 E301 + # Bare except (with or without reraise) + E722 max-line-length = 160 From 3cb886c7a0bae1c1163db6340da8c989d4625a66 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 10 Sep 2023 02:22:53 -0700 Subject: [PATCH 1684/1831] Add return value annotation --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 72681a627..74aeb9980 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1324,7 +1324,7 @@ def _option(self, engine: UciProtocol, arg: str) -> None: current_var = None var = [] - def parse_min_max_value(token: str, which: Literal["min", "max"]): + def parse_min_max_value(token: str, which: Literal["min", "max"]) -> Optional[int]: try: return int(token) except ValueError: From 69041525dd05b496ab01d839880f437093f66536 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 10 Sep 2023 16:22:58 -0700 Subject: [PATCH 1685/1831] Delete trailing whitespace --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 74aeb9980..7a8bbc845 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1323,7 +1323,7 @@ def _option(self, engine: UciProtocol, arg: str) -> None: max = None current_var = None var = [] - + def parse_min_max_value(token: str, which: Literal["min", "max"]) -> Optional[int]: try: return int(token) @@ -1742,7 +1742,7 @@ def _create_variation_line(root_board: chess.Board, line: str) -> tuple[list[che line = remaining_line_after_move else: return currline, line - + def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL) -> InfoDict: info: InfoDict = {} From 55060d497b2c56d96ff5935329645c5d2f3dc818 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 10 Sep 2023 16:24:24 -0700 Subject: [PATCH 1686/1831] Simplify UCI option parsing with regex --- chess/engine.py | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 7a8bbc845..80312fa19 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1274,6 +1274,8 @@ def __repr__(self) -> str: return "<{} at {:#x} (state={}, result={}, finished={}>".format(type(self).__name__, id(self), self.state, self.result, self.finished) +UCI_OPTION_REGEX = re.compile(r"\s*(name|type|default|min|max|var)\s*") + class UciProtocol(Protocol): """ An implementation of the @@ -1314,14 +1316,11 @@ def line_received(self, engine: UciProtocol, line: str) -> None: self._id(engine, remaining) def _option(self, engine: UciProtocol, arg: str) -> None: - current_parameter = None - - name: List[str] = [] - type: List[str] = [] - default: List[str] = [] + name = "" + type = "" + default = "" min = None max = None - current_var = None var = [] def parse_min_max_value(token: str, which: Literal["min", "max"]) -> Optional[int]: @@ -1331,7 +1330,8 @@ def parse_min_max_value(token: str, which: Literal["min", "max"]) -> Optional[in LOGGER.exception(f"Exception parsing option {which}") return None - for token in arg.split(): + current_parameter = None + for token in UCI_OPTION_REGEX.split(arg): if token == "name" and not name: current_parameter = "name" elif token == "type" and not type: @@ -1344,27 +1344,21 @@ def parse_min_max_value(token: str, which: Literal["min", "max"]) -> Optional[in current_parameter = "max" elif token == "var": current_parameter = "var" - if current_var is not None: - var.append(" ".join(current_var)) - current_var = [] elif current_parameter == "name": - name.append(token) + name = token elif current_parameter == "type": - type.append(token) + type = token elif current_parameter == "default": - default.append(token) + default = token elif current_parameter == "var": - current_var.append(token) + var.append(token) elif current_parameter == "min": min = parse_min_max_value(token, "min") elif current_parameter == "max": max = parse_min_max_value(token, "max") - if current_var is not None: - var.append(" ".join(current_var)) - - without_default = Option(" ".join(name), " ".join(type), None, min, max, var) - option = Option(without_default.name, without_default.type, without_default.parse(" ".join(default)), min, max, var) + without_default = Option(name, type, None, min, max, var) + option = Option(without_default.name, without_default.type, without_default.parse(default), min, max, var) engine.options[option.name] = option if option.default is not None: From 4cb2b9a85f682091500ccb947dda73e305361e94 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 12 Sep 2023 23:06:30 -0700 Subject: [PATCH 1687/1831] Simplify UCI option parsing Replace repeated code with a dictionary. --- chess/engine.py | 52 ++++++++++++++++++------------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 80312fa19..33c2a3e8c 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1276,6 +1276,7 @@ def __repr__(self) -> str: UCI_OPTION_REGEX = re.compile(r"\s*(name|type|default|min|max|var)\s*") + class UciProtocol(Protocol): """ An implementation of the @@ -1316,46 +1317,31 @@ def line_received(self, engine: UciProtocol, line: str) -> None: self._id(engine, remaining) def _option(self, engine: UciProtocol, arg: str) -> None: - name = "" - type = "" - default = "" - min = None - max = None + current_parameter = None + option_parts: dict[str, str] = {k: "" for k in ["name", "type", "default", "min", "max"]} var = [] - def parse_min_max_value(token: str, which: Literal["min", "max"]) -> Optional[int]: + for token in UCI_OPTION_REGEX.split(arg): + if token == "var" or (token in option_parts and not option_parts[token]): + current_parameter = token + elif current_parameter == "var": + var.append(token) + elif current_parameter: + option_parts[current_parameter] = token + + def parse_min_max_value(option_parts: dict[str, str], which: Literal["min", "max"]) -> Optional[int]: try: - return int(token) + number = option_parts[which] + return int(number) if number else None except ValueError: LOGGER.exception(f"Exception parsing option {which}") return None - current_parameter = None - for token in UCI_OPTION_REGEX.split(arg): - if token == "name" and not name: - current_parameter = "name" - elif token == "type" and not type: - current_parameter = "type" - elif token == "default" and not default: - current_parameter = "default" - elif token == "min" and min is None: - current_parameter = "min" - elif token == "max" and max is None: - current_parameter = "max" - elif token == "var": - current_parameter = "var" - elif current_parameter == "name": - name = token - elif current_parameter == "type": - type = token - elif current_parameter == "default": - default = token - elif current_parameter == "var": - var.append(token) - elif current_parameter == "min": - min = parse_min_max_value(token, "min") - elif current_parameter == "max": - max = parse_min_max_value(token, "max") + name = option_parts["name"] + type = option_parts["type"] + default = option_parts["default"] + min = parse_min_max_value(option_parts, "min") + max = parse_min_max_value(option_parts, "max") without_default = Option(name, type, None, min, max, var) option = Option(without_default.name, without_default.type, without_default.parse(default), min, max, var) From fb991b817718770fdd0291ae4aa962df2ce9cf61 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Tue, 12 Sep 2023 23:28:50 -0700 Subject: [PATCH 1688/1831] Consolidate UCI option parameter list --- chess/engine.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 33c2a3e8c..126668c7d 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1274,9 +1274,6 @@ def __repr__(self) -> str: return "<{} at {:#x} (state={}, result={}, finished={}>".format(type(self).__name__, id(self), self.state, self.result, self.finished) -UCI_OPTION_REGEX = re.compile(r"\s*(name|type|default|min|max|var)\s*") - - class UciProtocol(Protocol): """ An implementation of the @@ -1321,7 +1318,9 @@ def _option(self, engine: UciProtocol, arg: str) -> None: option_parts: dict[str, str] = {k: "" for k in ["name", "type", "default", "min", "max"]} var = [] - for token in UCI_OPTION_REGEX.split(arg): + parameters = list(option_parts.keys()) + ['var'] + option_regex = fr"\s*({'|'.join(parameters)})\s*" + for token in re.split(option_regex, arg): if token == "var" or (token in option_parts and not option_parts[token]): current_parameter = token elif current_parameter == "var": From f22e3282b69abe37204589829d1eb09267174261 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 13 Sep 2023 00:12:22 -0700 Subject: [PATCH 1689/1831] Trim whitespace from option line --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 126668c7d..45fe56372 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1320,7 +1320,7 @@ def _option(self, engine: UciProtocol, arg: str) -> None: parameters = list(option_parts.keys()) + ['var'] option_regex = fr"\s*({'|'.join(parameters)})\s*" - for token in re.split(option_regex, arg): + for token in re.split(option_regex, arg.strip()): if token == "var" or (token in option_parts and not option_parts[token]): current_parameter = token elif current_parameter == "var": From f2fd4d3257e7f0cf8078cafa44a25a9d6e4e40c9 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 13 Sep 2023 00:26:11 -0700 Subject: [PATCH 1690/1831] Strip whitespace when receiving "readyok" --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 45fe56372..9a7a0aa8a 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1387,7 +1387,7 @@ def start(self, engine: UciProtocol) -> None: engine._isready() def line_received(self, engine: UciProtocol, line: str) -> None: - if line == "readyok": + if line.strip() == "readyok": self.result.set_result(None) self.set_finished() else: From 312e477ad24905941d3adbaf8e4b4aaa002e2ba3 Mon Sep 17 00:00:00 2001 From: Josh Giesbrecht Date: Fri, 22 Sep 2023 20:52:21 -0700 Subject: [PATCH 1691/1831] Update README.rst PicoChess URL seems to have changed - .org domain goes to a domain-for-sale page. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 8ab138666..f4cfd955c 100644 --- a/README.rst +++ b/README.rst @@ -338,7 +338,7 @@ If you like, share interesting things you are using python-chess for, for exampl +------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ * extensions to build engines (search and evaluation) – https://github.com/Mk-Chan/python-chess-engine-extensions -* a stand-alone chess computer based on DGT board – http://www.picochess.org/ +* a stand-alone chess computer based on DGT board – http://picochess.com/ * a bridge between Lichess API and chess engines – https://github.com/careless25/lichess-bot * a command-line PGN annotator – https://github.com/rpdelaney/python-chess-annotator * an HTTP microservice to render board images – https://github.com/niklasf/web-boardimage From c0bb57204f7f24c8640ba81a819b41ee3e17f253 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Fri, 22 Sep 2023 21:04:30 -0700 Subject: [PATCH 1692/1831] Update lichess-bot URL in README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 8ab138666..cf249e466 100644 --- a/README.rst +++ b/README.rst @@ -339,7 +339,7 @@ If you like, share interesting things you are using python-chess for, for exampl * extensions to build engines (search and evaluation) – https://github.com/Mk-Chan/python-chess-engine-extensions * a stand-alone chess computer based on DGT board – http://www.picochess.org/ -* a bridge between Lichess API and chess engines – https://github.com/careless25/lichess-bot +* a bridge between Lichess API and chess engines – https://github.com/lichess-bot-devs/lichess-bot * a command-line PGN annotator – https://github.com/rpdelaney/python-chess-annotator * an HTTP microservice to render board images – https://github.com/niklasf/web-boardimage * building a toy chess engine with alpha-beta pruning, piece-square tables, and move ordering – https://healeycodes.com/building-my-own-chess-engine/ From e773cd4eb93519397fe3eea0a8f92cc4662c718c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 23 Sep 2023 12:45:55 +0200 Subject: [PATCH 1693/1831] Try explicitly installing and using sphinx-rtd-theme (#1044) --- docs/conf.py | 2 +- docs/requirements.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 22f960575..a6e8a79d9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -49,4 +49,4 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of built-in themes. -html_theme = "default" +html_theme = "sphinx_rtd_theme" diff --git a/docs/requirements.txt b/docs/requirements.txt index d99b8c473..a63c6a7ca 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,3 @@ Sphinx==6.1.2 sphinxcontrib-jquery==4.1 +sphinx-rtd-theme==1.3.0 From 97b887ac723d748cbdfe5597971cfd75b520911d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 30 Sep 2023 18:40:04 +0200 Subject: [PATCH 1694/1831] Simplify _EmptyMmap.madvise signature --- chess/polyglot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/polyglot.py b/chess/polyglot.py index ac339902c..cdf9b0c2f 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -312,7 +312,7 @@ def size(self) -> int: def close(self) -> None: pass - def madvise(self, option: int, start: int = ..., length: int = ...) -> None: + def madvise(self, option: int) -> None: pass From 2093a7348edf709d1128ad3aed4707c22e6ee739 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 30 Sep 2023 18:49:47 +0200 Subject: [PATCH 1695/1831] Fix local chess.engine.InfoDict in type hint --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 9a7a0aa8a..b1d3896ab 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2597,7 +2597,7 @@ class AnalysisResult: Automatically stops the analysis when used as a context manager. """ - multipv: List[chess.engine.InfoDict] + multipv: List[InfoDict] """ A list of dictionaries with aggregated information sent by the engine. One item for each root move. From 6f4d35a0bb0f88cbe9f1fccb46a4babc22d098cf Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 30 Sep 2023 19:29:50 +0200 Subject: [PATCH 1696/1831] Remove some unused loop variables --- chess/gaviota.py | 12 ++++++------ chess/syzygy.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index c2439728f..15371eb19 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -147,7 +147,7 @@ def init_pp48_idx() -> Tuple[List[List[int]], List[int], List[int]]: MAX_I = 48 MAX_J = 48 idx = 0 - pp48_idx = [[-1] * MAX_J for i in range(MAX_I)] + pp48_idx = [[-1] * MAX_J for _ in range(MAX_I)] pp48_sq_x = [NOSQUARE] * MAX_PP48_INDEX pp48_sq_y = [NOSQUARE] * MAX_PP48_INDEX @@ -173,7 +173,7 @@ def init_ppp48_idx() -> Tuple[List[List[List[int]]], List[int], List[int], List[ MAX_I = 48 MAX_J = 48 MAX_K = 48 - ppp48_idx = [[[-1] * MAX_I for j in range(MAX_J)] for k in range(MAX_K)] + ppp48_idx = [[[-1] * MAX_I for _ in range(MAX_J)] for _ in range(MAX_K)] ppp48_sq_x = [NOSQUARE] * MAX_PPP48_INDEX ppp48_sq_y = [NOSQUARE] * MAX_PPP48_INDEX ppp48_sq_z = [NOSQUARE] * MAX_PPP48_INDEX @@ -210,7 +210,7 @@ def init_ppp48_idx() -> Tuple[List[List[List[int]]], List[int], List[int], List[ def init_aaidx() -> Tuple[List[int], List[List[int]]]: - aaidx = [[-1] * 64 for y in range(64)] + aaidx = [[-1] * 64 for _ in range(64)] aabase = [0] * MAX_AAINDEX idx = 0 @@ -240,7 +240,7 @@ def init_aaa() -> Tuple[List[int], List[List[int]]]: aaa_base[a + 1] = accum # Get aaa_xyz. - aaa_xyz = [[-1] * 3 for idx in range(MAX_AAAINDEX)] + aaa_xyz = [[-1] * 3 for _ in range(MAX_AAAINDEX)] idx = 0 for z in range(64): @@ -319,7 +319,7 @@ def wsq_to_pidx48(pawn: int) -> int: return idx48 def init_ppidx() -> Tuple[List[List[int]], List[int], List[int]]: - ppidx = [[-1] * 48 for i in range(24)] + ppidx = [[-1] * 48 for _ in range(24)] pp_hi24 = [-1] * MAX_PPINDEX pp_lo48 = [-1] * MAX_PPINDEX @@ -379,7 +379,7 @@ def norm_kkindex(x: chess.Square, y: chess.Square) -> Tuple[int, int]: return x, y def init_kkidx() -> Tuple[List[List[int]], List[int], List[int]]: - kkidx = [[-1] * 64 for x in range(64)] + kkidx = [[-1] * 64 for _ in range(64)] bksq = [-1] * MAX_KKINDEX wksq = [-1] * MAX_KKINDEX idx = 0 diff --git a/chess/syzygy.py b/chess/syzygy.py index 96a17e921..8953b8e6b 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1257,7 +1257,7 @@ def init_table_dtz(self) -> None: self.norm = [0 for _ in range(self.num)] self.tb_size = [0, 0, 0, 0] self.size = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - self.files = [PawnFileDataDtz() for f in range(4)] + self.files = [PawnFileDataDtz() for _ in range(4)] files = 4 if self.data[4] & 0x02 else 1 From 15e3584ff65c46c6b1cecaf14b6fc25868587a93 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 30 Sep 2023 19:44:41 +0200 Subject: [PATCH 1697/1831] Provide type hints for empty lists --- chess/__init__.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 65719fd5c..a9328a04b 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -412,8 +412,8 @@ def _carry_rippler(mask: Bitboard) -> Iterator[Bitboard]: break def _attack_table(deltas: List[int]) -> Tuple[List[Bitboard], List[Dict[Bitboard, Bitboard]]]: - mask_table = [] - attack_table = [] + mask_table: List[Bitboard] = [] + attack_table: List[Dict[Bitboard, Bitboard]] = [] for square in SQUARES: attacks = {} @@ -433,9 +433,9 @@ def _attack_table(deltas: List[int]) -> Tuple[List[Bitboard], List[Dict[Bitboard def _rays() -> List[List[Bitboard]]: - rays = [] + rays: List[List[Bitboard]] = [] for a, bb_a in enumerate(BB_SQUARES): - rays_row = [] + rays_row: List[Bitboard] = [] for b, bb_b in enumerate(BB_SQUARES): if BB_DIAG_ATTACKS[a][0] & bb_b: rays_row.append((BB_DIAG_ATTACKS[a][0] & BB_DIAG_ATTACKS[b][0]) | bb_a | bb_b) @@ -961,7 +961,7 @@ def board_fen(self, *, promoted: Optional[bool] = False) -> str: Gets the board FEN (e.g., ``rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR``). """ - builder = [] + builder: List[str] = [] empty = 0 for square in SQUARES_180: @@ -1056,7 +1056,7 @@ def piece_map(self, *, mask: Bitboard = BB_ALL) -> Dict[Square, Piece]: """ Gets a dictionary of :class:`pieces ` by square index. """ - result = {} + result: Dict[Square, Piece] = {} for square in scan_reversed(self.occupied & mask): result[square] = typing.cast(Piece, self.piece_at(square)) return result @@ -1225,7 +1225,7 @@ def __repr__(self) -> str: return f"{type(self).__name__}({self.board_fen()!r})" def __str__(self) -> str: - builder = [] + builder: List[str] = [] for square in SQUARES_180: piece = self.piece_at(square) @@ -1251,7 +1251,7 @@ def unicode(self, *, invert_color: bool = False, borders: bool = False, empty_sq :param invert_color: Invert color of the Unicode pieces. :param borders: Show borders and a coordinate margin. """ - builder = [] + builder: List[str] = [] for rank_index in (range(7, -1, -1) if orientation else range(8)): if borders: builder.append(" ") @@ -2094,7 +2094,7 @@ def can_claim_threefold_repetition(self) -> bool: transpositions.update((transposition_key, )) # Count positions. - switchyard = [] + switchyard: List[Move] = [] while self.move_stack: move = self.pop() switchyard.append(move) @@ -2147,7 +2147,7 @@ def is_repetition(self, count: int = 3) -> bool: # Check full replay. transposition_key = self._transposition_key() - switchyard = [] + switchyard: List[Move] = [] try: while True: @@ -2343,7 +2343,7 @@ def castling_shredder_fen(self) -> str: if not castling_rights: return "-" - builder = [] + builder: List[str] = [] for square in scan_reversed(castling_rights & BB_RANK_1): builder.append(FILE_NAMES[square_file(square)].upper()) @@ -2354,7 +2354,7 @@ def castling_shredder_fen(self) -> str: return "".join(builder) def castling_xfen(self) -> str: - builder = [] + builder: List[str] = [] for color in COLORS: king = self.king(color) @@ -2615,7 +2615,7 @@ def chess960_pos(self, *, ignore_turn: bool = False, ignore_castling: bool = Fal return super().chess960_pos() def _epd_operations(self, operations: Mapping[str, Union[None, str, int, float, Move, Iterable[Move]]]) -> str: - epd = [] + epd: List[str] = [] first_op = True for opcode, operand in operations.items(): @@ -2786,7 +2786,7 @@ def _parse_epd_ops(self: BoardT, operation_part: str, make_board: Callable[[], B if opcode == "pv": # A variation. - variation = [] + variation: List[Move] = [] for token in operand.split(): move = position.parse_xboard(token) variation.append(move) @@ -2963,7 +2963,7 @@ def variation_san(self, variation: Iterable[Move]) -> str: :raises: :exc:`IllegalMoveError` if any moves in the sequence are illegal. """ board = self.copy(stack=False) - san = [] + san: List[str] = [] for move in variation: if not board.is_legal(move): @@ -3781,7 +3781,7 @@ def __contains__(self, move: Move) -> bool: return self.board.is_pseudo_legal(move) def __repr__(self) -> str: - builder = [] + builder: List[str] = [] for move in self: if self.board.is_legal(move): @@ -3898,7 +3898,7 @@ class SquareSet: def __init__(self, squares: IntoSquareSet = BB_EMPTY) -> None: try: - self.mask = squares.__int__() & BB_ALL # type: ignore + self.mask: Bitboard = squares.__int__() & BB_ALL # type: ignore return except AttributeError: self.mask = 0 @@ -4095,7 +4095,7 @@ def __repr__(self) -> str: return f"SquareSet({self.mask:#021_x})" def __str__(self) -> str: - builder = [] + builder: List[str] = [] for square in SQUARES_180: mask = BB_SQUARES[square] From e57312294bdce09d08714e83f74e274b94f18597 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 1 Oct 2023 22:04:14 +0200 Subject: [PATCH 1698/1831] Bump actions/checkout to v4 --- .github/workflows/codeql.yml | 2 +- .github/workflows/test.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a37e82933..cd5d5a2d8 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -11,7 +11,7 @@ jobs: contents: read security-events: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: github/codeql-action/init@v2 with: languages: python diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 184092752..637880b51 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -21,7 +21,7 @@ jobs: perft: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.11" @@ -42,7 +42,7 @@ jobs: python-version: ["3.9", "3.10", "3.11"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -53,7 +53,7 @@ jobs: readme: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.11" From 86f5f55846caaec1c22bc40a2b53d42b06916617 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 1 Oct 2023 22:10:32 +0200 Subject: [PATCH 1699/1831] Fix map_idx type --- chess/syzygy.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 8953b8e6b..6a0efdef5 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -12,7 +12,7 @@ import chess from types import TracebackType -from typing import Deque, Dict, Iterable, Iterator, List, Optional, Tuple, Type, TypeVar, Union +from typing import Deque, Dict, Iterable, Iterator, List, Optional, Set, Tuple, Type, TypeVar, Union UINT64_BE = struct.Struct(">Q") @@ -368,7 +368,7 @@ def is_tablename(name: str, *, one_king: bool = True, piece_count: Optional[int] def tablenames(*, one_king: bool = True, piece_count: int = 6) -> Iterator[str]: first = "K" if one_king else "P" - targets = [] + targets: List[str] = [] white_pieces = piece_count - 2 black_pieces = 0 @@ -411,7 +411,7 @@ def _dependencies(target: str, *, one_king: bool = True) -> Iterator[str]: def dependencies(target: str, *, one_king: bool = True) -> Iterator[str]: - closed = set() + closed: Set[str] = set() if one_king: closed.add("KvK") @@ -422,7 +422,7 @@ def dependencies(target: str, *, one_king: bool = True) -> Iterator[str]: def all_dependencies(targets: Iterable[str], *, one_king: bool = True) -> Iterator[str]: - closed = set() + closed: Set[str] = set() if one_king: closed.add("KvK") @@ -684,10 +684,7 @@ def set_norm_piece(self, norm: List[int], pieces: List[int]) -> None: i += norm[i] def calc_factors_piece(self, factor: List[int], order: int, norm: List[int]) -> int: - if not self.variant.connected_kings: - PIVFAC = [31332, 28056, 462] - else: - PIVFAC = [31332, 0, 518, 278] + PIVFAC = [31332, 0, 518, 278] if self.variant.connected_kings else [31332, 28056, 462] n = 64 - norm[0] @@ -1310,7 +1307,7 @@ def init_table_dtz(self) -> None: p_data = self._next self.flags.append(self._flags) - self.map_idx = [] + self.map_idx: List[List[int]] = [] self.p_map = p_data for f in range(files): self.map_idx.append([]) From 1dd3e1e11e637113f42ad29ace841876029d7a81 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 1 Oct 2023 22:19:54 +0200 Subject: [PATCH 1700/1831] Make also mypy happy --- chess/svg.py | 2 +- chess/syzygy.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 3e034ce30..d3d19e89e 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -434,7 +434,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, }) # Render selected squares. - if squares is not None and square in squares: + if square in squares: ET.SubElement(svg, "use", _attrs({ "href": "#xx", "xlink:href": "#xx", diff --git a/chess/syzygy.py b/chess/syzygy.py index 6a0efdef5..e1fe07eb7 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1261,7 +1261,7 @@ def init_table_dtz(self) -> None: p_data = 5 if not self.has_pawns: - self.map_idx = [[0, 0, 0, 0]] + self.map_idx: List[List[int]] = [[0, 0, 0, 0]] self.setup_pieces_piece_dtz(p_data, 0) p_data += self.num + 1 @@ -1307,7 +1307,7 @@ def init_table_dtz(self) -> None: p_data = self._next self.flags.append(self._flags) - self.map_idx: List[List[int]] = [] + self.map_idx = [] self.p_map = p_data for f in range(files): self.map_idx.append([]) From 3a99f1bfc76185c81632b00c5a700b3b2a62fd4b Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 8 Oct 2023 17:39:43 +0200 Subject: [PATCH 1701/1831] Declare chess.popcount in pyright compatible way --- chess/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index a9328a04b..49ec73d9c 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -297,8 +297,12 @@ def scan_reversed(bb: Bitboard) -> Iterator[Square]: yield r bb ^= BB_SQUARES[r] -# Python 3.10 or fallback. -popcount: Callable[[Bitboard], int] = getattr(int, "bit_count", lambda bb: bin(bb).count("1")) +try: + # Python 3.10 + popcount = Bitboard.bit_count +except AttributeError: + def popcount(self: Bitboard) -> int: + return bin(self).count("1") def flip_vertical(bb: Bitboard) -> Bitboard: # https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating#FlipVertically From 99eeeae4d2eed95939f6c52eae9d3418fd1c8a8e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 8 Oct 2023 19:08:01 +0200 Subject: [PATCH 1702/1831] Revert "Declare chess.popcount in pyright compatible way" This reverts commit 3a99f1bfc76185c81632b00c5a700b3b2a62fd4b. --- chess/__init__.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 49ec73d9c..a9328a04b 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -297,12 +297,8 @@ def scan_reversed(bb: Bitboard) -> Iterator[Square]: yield r bb ^= BB_SQUARES[r] -try: - # Python 3.10 - popcount = Bitboard.bit_count -except AttributeError: - def popcount(self: Bitboard) -> int: - return bin(self).count("1") +# Python 3.10 or fallback. +popcount: Callable[[Bitboard], int] = getattr(int, "bit_count", lambda bb: bin(bb).count("1")) def flip_vertical(bb: Bitboard) -> Bitboard: # https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating#FlipVertically From 4a6dd9a89b7810312ab4ea1cf255d1a501ae09ca Mon Sep 17 00:00:00 2001 From: Rahul Saini <137695929+ProgramR4732@users.noreply.github.com> Date: Fri, 13 Oct 2023 21:24:56 +0530 Subject: [PATCH 1703/1831] Removed unnecessary indentation blocks and updated conditional statements. --- release.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/release.py b/release.py index d27ddf04e..f2f7d81fa 100755 --- a/release.py +++ b/release.py @@ -10,7 +10,7 @@ def system(command): print(command) exit_code = os.system(command) - if exit_code != 0: + if exit_code: sys.exit(exit_code) @@ -21,7 +21,7 @@ def check_git(): system("git fetch origin") behind = int(subprocess.check_output(["git", "rev-list", "--count", "master..origin/master"])) - if behind > 0: + if behind: print(f"master is {behind} commit(s) behind origin/master") sys.exit(1) @@ -65,15 +65,14 @@ def tag_and_push(): release_txt.write(headline + os.linesep) for line in changelog_file: - if not first_section: - if line.startswith("-------"): - first_section = True + if line.startswith("-------") and not first_section: + first_section = True else: if line.startswith("-------"): break - else: - if not prev_line.startswith("------"): - release_txt.write(prev_line) + + if not prev_line.startswith("------"): + release_txt.write(prev_line) prev_line = line From 615a21b4ca7679c51388159324f2a9545868f6f1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 15 Oct 2023 19:02:54 +0200 Subject: [PATCH 1704/1831] Link chess-playground --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index ee3b315e7..07e0e3251 100644 --- a/README.rst +++ b/README.rst @@ -350,6 +350,7 @@ If you like, share interesting things you are using python-chess for, for exampl * Django Rest Framework API for multiplayer chess – https://github.com/WorkShoft/capablanca-api * a `browser based PGN viewer `_ written in PyScript – https://github.com/nmstoker/ChessMatchViewer * an accessible chessboard that allows blind and visually impaired players to play chess against Stockfish – https://github.com/blindpandas/chessmart +* analyse games to extract various statistics – https://github.com/mvrozanti/chess-playground Prior art From 2b754a25854b41c68a847c5c36439f2eb1cdffb2 Mon Sep 17 00:00:00 2001 From: anonymousdouble <112695649+anonymousdouble@users.noreply.github.com> Date: Mon, 1 Jan 2024 21:15:29 +1100 Subject: [PATCH 1705/1831] Update gaviota.py refactor with chain constant value assignment to make code more Pythonic, concise and efficient. --- chess/gaviota.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index 15371eb19..39173b593 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -144,8 +144,7 @@ def init_flipt() -> List[List[int]]: def init_pp48_idx() -> Tuple[List[List[int]], List[int], List[int]]: - MAX_I = 48 - MAX_J = 48 + MAX_I = MAX_J = 48 idx = 0 pp48_idx = [[-1] * MAX_J for _ in range(MAX_I)] pp48_sq_x = [NOSQUARE] * MAX_PP48_INDEX @@ -170,9 +169,7 @@ def init_pp48_idx() -> Tuple[List[List[int]], List[int], List[int]]: def init_ppp48_idx() -> Tuple[List[List[List[int]]], List[int], List[int], List[int]]: - MAX_I = 48 - MAX_J = 48 - MAX_K = 48 + MAX_I = MAX_J = MAX_K = 48 ppp48_idx = [[[-1] * MAX_I for _ in range(MAX_J)] for _ in range(MAX_K)] ppp48_sq_x = [NOSQUARE] * MAX_PPP48_INDEX ppp48_sq_y = [NOSQUARE] * MAX_PPP48_INDEX From a64f78eb42b48a7a1f79a4fb2134c649d4dea4c2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Jan 2024 12:07:17 +0100 Subject: [PATCH 1706/1831] Try to test with Ubuntu engine packages in CI --- .github/workflows/setup-ubuntu-latest.sh | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/workflows/setup-ubuntu-latest.sh b/.github/workflows/setup-ubuntu-latest.sh index 8954c8f0c..fae35b61a 100755 --- a/.github/workflows/setup-ubuntu-latest.sh +++ b/.github/workflows/setup-ubuntu-latest.sh @@ -1,19 +1,10 @@ #!/bin/sh -e # Stockfish -wget https://files.stockfishchess.org/archive/Stockfish%2011/stockfish-11-linux.zip -unzip stockfish-11-linux.zip -mkdir -p bin -cp stockfish-11-linux/Linux/stockfish_20011801_x64_bmi2 bin/stockfish -chmod +x bin/stockfish -echo "`pwd`/bin" >> $GITHUB_PATH +sudo apt-get install -y stockfish # Crafty -git clone https://github.com/lazydroid/crafty-chess --depth 1 -cd crafty-chess -make unix-gcc -pwd >> $GITHUB_PATH -cd .. +sudo apt-get install -y crafty # Gaviota libgtb git clone https://github.com/michiguel/Gaviota-Tablebases.git --depth 1 From 0082833d30ac98cae1b272e220f56e0797f1187c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Jan 2024 12:17:41 +0100 Subject: [PATCH 1707/1831] Try to download Stockfish release in Windows CI --- .github/workflows/setup-windows-latest.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/setup-windows-latest.sh b/.github/workflows/setup-windows-latest.sh index 685ead65a..f92bd9059 100755 --- a/.github/workflows/setup-windows-latest.sh +++ b/.github/workflows/setup-windows-latest.sh @@ -2,11 +2,11 @@ echo Download ... choco install wget -wget https://files.stockfishchess.org/archive/Stockfish%2011/stockfish-11-win.zip +wget https://github.com/official-stockfish/Stockfish/releases/download/sf_16/stockfish-windows-x86-64-avx2.zip echo Unzip .. -7z e stockfish-11-win.zip stockfish-11-win/Windows/*.exe +7z e stockfish-windows-x86-64-avx2.zip /stockfish/stockfish-windows-x86-64-avx2.exe echo Setup path ... -mv stockfish_20011801_x64_bmi2.exe stockfish.exe +mv stockfish-windows-x86-64-avx2.exe stockfish.exe pwd >> $GITHUB_PATH From 8a70a2c90f228826f34f9bf2629de86e750ab796 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Jan 2024 12:21:40 +0100 Subject: [PATCH 1708/1831] Try to fix Stockfish zip extract --- .github/workflows/setup-windows-latest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/setup-windows-latest.sh b/.github/workflows/setup-windows-latest.sh index f92bd9059..815eb0db2 100755 --- a/.github/workflows/setup-windows-latest.sh +++ b/.github/workflows/setup-windows-latest.sh @@ -5,7 +5,7 @@ choco install wget wget https://github.com/official-stockfish/Stockfish/releases/download/sf_16/stockfish-windows-x86-64-avx2.zip echo Unzip .. -7z e stockfish-windows-x86-64-avx2.zip /stockfish/stockfish-windows-x86-64-avx2.exe +7z e stockfish-windows-x86-64-avx2.zip stockfish/stockfish-windows-x86-64-avx2.exe echo Setup path ... mv stockfish-windows-x86-64-avx2.exe stockfish.exe From 2477ae8f4f36ce4ff872383a47ec2cf2e2eb6cf7 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Jan 2024 12:28:48 +0100 Subject: [PATCH 1709/1831] Fix typing involving PathLike --- chess/polyglot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/polyglot.py b/chess/polyglot.py index cdf9b0c2f..bf4fa0cd1 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -11,7 +11,7 @@ from typing import Callable, Container, Iterator, List, NamedTuple, Optional, Type, Union -PathLike = Union[str, bytes, os.PathLike] +StrOrBytesPath = Union[str, bytes, os.PathLike[str], os.PathLike[bytes]] ENTRY_STRUCT = struct.Struct(">QHHI") @@ -323,7 +323,7 @@ def _randint(rng: Optional[random.Random], a: int, b: int) -> int: class MemoryMappedReader: """Maps a Polyglot opening book to memory.""" - def __init__(self, filename: PathLike) -> None: + def __init__(self, filename: StrOrBytesPath) -> None: fd = os.open(filename, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) try: self.mmap: Union[mmap.mmap, _EmptyMmap] = mmap.mmap(fd, 0, access=mmap.ACCESS_READ) @@ -500,7 +500,7 @@ def close(self) -> None: self.mmap.close() -def open_reader(path: PathLike) -> MemoryMappedReader: +def open_reader(path: StrOrBytesPath) -> MemoryMappedReader: """ Creates a reader for the file at the given path. From 62148665fd966c6047e2560bc289763ddca556af Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Jan 2024 12:33:05 +0100 Subject: [PATCH 1710/1831] Test also with Python 3.12 --- .github/workflows/test.yml | 8 ++++---- setup.py | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 637880b51..576d8b491 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.12" - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - run: python examples/perft/perft.py -t 1 examples/perft/chess960.perft --max-nodes 100000 @@ -39,7 +39,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11", "3.12"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -56,7 +56,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.12" - run: sudo apt-get update && sudo apt-get install -y docutils-common - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null - run: pip install -e . diff --git a/setup.py b/setup.py index 8c397e456..b825adb44 100755 --- a/setup.py +++ b/setup.py @@ -82,6 +82,7 @@ def read_description(): "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Games/Entertainment :: Board Games", "Topic :: Games/Entertainment :: Turn Based Strategy", "Topic :: Software Development :: Libraries :: Python Modules", From 0946d784bfead47bfba88ca185b2ed626fd31bbd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Jan 2024 12:34:51 +0100 Subject: [PATCH 1711/1831] Work around PathLike not subscriptable on Python 3.8 --- chess/polyglot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/polyglot.py b/chess/polyglot.py index bf4fa0cd1..44a68caa5 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -11,7 +11,7 @@ from typing import Callable, Container, Iterator, List, NamedTuple, Optional, Type, Union -StrOrBytesPath = Union[str, bytes, os.PathLike[str], os.PathLike[bytes]] +StrOrBytesPath = Union[str, bytes, "os.PathLike[str]", "os.PathLike[bytes]"] ENTRY_STRUCT = struct.Struct(">QHHI") From c5c388292c7986405ebbe4813b1691299bf3e900 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Jan 2024 12:37:49 +0100 Subject: [PATCH 1712/1831] Bump version requirement and copyright year --- README.rst | 2 +- docs/conf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 07e0e3251..7a677a451 100644 --- a/README.rst +++ b/README.rst @@ -59,7 +59,7 @@ python-chess: Installing ---------- -Requires Python 3.7+. Download and install the latest release: +Requires Python 3.8+. Download and install the latest release: :: diff --git a/docs/conf.py b/docs/conf.py index a6e8a79d9..98e926efa 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -34,7 +34,7 @@ # General information about the project. project = "python-chess" -copyright = "2014–2023, Niklas Fiekas" +copyright = "2014–2024, Niklas Fiekas" # The version. version = chess.__version__ From cd7f5958289dd08156436a1f84b9ea03cb1f75a1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 1 Jan 2024 14:48:01 +0100 Subject: [PATCH 1713/1831] Update to CodeQL 3 --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index cd5d5a2d8..bc991c885 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,7 +12,7 @@ jobs: security-events: write steps: - uses: actions/checkout@v4 - - uses: github/codeql-action/init@v2 + - uses: github/codeql-action/init@v3 with: languages: python - - uses: github/codeql-action/analyze@v2 + - uses: github/codeql-action/analyze@v3 From 65f6d7d7a2229be1c6c9051182d299404b0186d5 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 21 Feb 2024 03:23:07 -0800 Subject: [PATCH 1714/1831] Add support for multiple comments per move --- chess/pgn.py | 108 +++++++++++++++++++++++++++++---------------------- test.py | 58 +++++++++++++-------------- 2 files changed, 91 insertions(+), 75 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 55eddbc29..65ef0e6d5 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -197,24 +197,24 @@ class GameNode(abc.ABC): variations: List[ChildNode] """A list of child nodes.""" - comment: str + comments: list[str] """ - A comment that goes behind the move leading to this node. Comments + Comments that go behind the move leading to this node. Comments that occur before any moves are assigned to the root node. """ - starting_comment: str + starting_comments: list[str] nags: Set[int] - def __init__(self, *, comment: str = "") -> None: + def __init__(self, *, comment: Union[str, list[str]] = "") -> None: self.parent = None self.move = None self.variations = [] - self.comment = comment + self.comment = comment if isinstance(comment, list) else [comment] if comment else [] # Deprecated: These should be properties of ChildNode, but need to # remain here for backwards compatibility. - self.starting_comment = "" + self.starting_comment: list[str] = [] self.nags = set() @abc.abstractmethod @@ -386,7 +386,7 @@ def remove_variation(self, move: Union[int, chess.Move, GameNode]) -> None: """Removes a variation.""" self.variations.remove(self.variation(move)) - def add_variation(self, move: chess.Move, *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> ChildNode: + def add_variation(self, move: chess.Move, *, comment: Union[str, list[str]] = "", starting_comment: Union[str, list[str]] = "", nags: Iterable[int] = []) -> ChildNode: """Creates a child node with the given attributes.""" # Instanciate ChildNode only in this method. return ChildNode(self, move, comment=comment, starting_comment=starting_comment, nags=nags) @@ -417,7 +417,7 @@ def mainline_moves(self) -> Mainline[chess.Move]: """Returns an iterable over the main moves after this node.""" return Mainline(self, lambda node: node.move) - def add_line(self, moves: Iterable[chess.Move], *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> GameNode: + def add_line(self, moves: Iterable[chess.Move], *, comment: Union[str, list[str]] = "", starting_comment: Union[str, list[str]] = "", nags: Iterable[int] = []) -> GameNode: """ Creates a sequence of child nodes for the given list of moves. Adds *comment* and *nags* to the last node of the line and returns it. @@ -431,9 +431,12 @@ def add_line(self, moves: Iterable[chess.Move], *, comment: str = "", starting_c # Merge comment and NAGs. if node.comment: - node.comment += " " + comment + if isinstance(comment, str): + node.comment.append(comment) + else: + node.comment.extend(comment) else: - node.comment = comment + node.comment = comment if isinstance(comment, list) else [comment] if comment else [] node.nags.update(nags) @@ -446,7 +449,7 @@ def eval(self) -> Optional[chess.engine.PovScore]: Complexity is `O(n)`. """ - match = EVAL_REGEX.search(self.comment) + match = EVAL_REGEX.search(" ".join(self.comment)) if not match: return None @@ -472,7 +475,7 @@ def eval_depth(self) -> Optional[int]: Complexity is `O(1)`. """ - match = EVAL_REGEX.search(self.comment) + match = EVAL_REGEX.search(" ".join(self.comment)) return int(match.group("depth")) if match and match.group("depth") else None def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] = None) -> None: @@ -489,12 +492,16 @@ def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] elif score.white().mate(): eval = f"[%eval #{score.white().mate()}{depth_suffix}]" - self.comment, found = EVAL_REGEX.subn(_condense_affix(eval), self.comment, count=1) + found = 0 + for index in range(len(self.comment)): + self.comment[index], found = EVAL_REGEX.subn(_condense_affix(eval), self.comment[index], count=1) + if found: + break + + self.comment = list(filter(None, self.comment)) if not found and eval: - if self.comment and not self.comment.endswith(" "): - self.comment += " " - self.comment += eval + self.comment.append(eval) def arrows(self) -> List[chess.svg.Arrow]: """ @@ -504,7 +511,7 @@ def arrows(self) -> List[chess.svg.Arrow]: Returns a list of :class:`arrows `. """ arrows = [] - for match in ARROWS_REGEX.finditer(self.comment): + for match in ARROWS_REGEX.finditer(" ".join(self.comment)): for group in match.group("arrows").split(","): arrows.append(chess.svg.Arrow.from_pgn(group)) @@ -526,7 +533,10 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar pass (csl if arrow.tail == arrow.head else cal).append(arrow.pgn()) # type: ignore - self.comment = ARROWS_REGEX.sub(_condense_affix(""), self.comment) + for index in range(len(self.comment)): + self.comment[index] = ARROWS_REGEX.sub(_condense_affix(""), self.comment[index]) + + self.comment = list(filter(None, self.comment)) prefix = "" if csl: @@ -534,10 +544,8 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar if cal: prefix += f"[%cal {','.join(cal)}]" - if prefix and self.comment and not self.comment.startswith(" ") and not self.comment.startswith("\n"): - self.comment = prefix + " " + self.comment - else: - self.comment = prefix + self.comment + if prefix: + self.comment.insert(0, prefix) def clock(self) -> Optional[float]: """ @@ -547,7 +555,7 @@ def clock(self) -> Optional[float]: Returns the player's remaining time to the next time control after this move, in seconds. """ - match = CLOCK_REGEX.search(self.comment) + match = CLOCK_REGEX.search(" ".join(self.comment)) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -566,12 +574,16 @@ def set_clock(self, seconds: Optional[float]) -> None: seconds_part = f"{seconds:06.3f}".rstrip("0").rstrip(".") clk = f"[%clk {hours:d}:{minutes:02d}:{seconds_part}]" - self.comment, found = CLOCK_REGEX.subn(_condense_affix(clk), self.comment, count=1) + found = 0 + for index in range(len(self.comment)): + self.comment[index], found = CLOCK_REGEX.subn(_condense_affix(clk), self.comment[index], count=1) + if found: + break + + self.comment = list(filter(None, self.comment)) if not found and clk: - if self.comment and not self.comment.endswith(" ") and not self.comment.endswith("\n"): - self.comment += " " - self.comment += clk + self.comment.append(clk) def emt(self) -> Optional[float]: """ @@ -581,7 +593,7 @@ def emt(self) -> Optional[float]: Returns the player's elapsed move time use for the comment of this move, in seconds. """ - match = EMT_REGEX.search(self.comment) + match = EMT_REGEX.search(" ".join(self.comment)) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -600,12 +612,16 @@ def set_emt(self, seconds: Optional[float]) -> None: seconds_part = f"{seconds:06.3f}".rstrip("0").rstrip(".") emt = f"[%emt {hours:d}:{minutes:02d}:{seconds_part}]" - self.comment, found = EMT_REGEX.subn(_condense_affix(emt), self.comment, count=1) + found = 0 + for index in range(len(self.comment)): + self.comment[index], found = EMT_REGEX.subn(_condense_affix(emt), self.comment[index], count=1) + if found: + break + + self.comment = list(filter(None, self.comment)) if not found and emt: - if self.comment and not self.comment.endswith(" ") and not self.comment.endswith("\n"): - self.comment += " " - self.comment += emt + self.comment.append(emt) @abc.abstractmethod def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: @@ -661,7 +677,7 @@ class ChildNode(GameNode): move: chess.Move """The move leading to this node.""" - starting_comment: str + starting_comment: list[str] """ A comment for the start of a variation. Only nodes that actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` @@ -675,14 +691,14 @@ class ChildNode(GameNode): node of the game will never have NAGs. """ - def __init__(self, parent: GameNode, move: chess.Move, *, comment: str = "", starting_comment: str = "", nags: Iterable[int] = []) -> None: + def __init__(self, parent: GameNode, move: chess.Move, *, comment: Union[str, list[str]] = "", starting_comment: Union[str, list[str]] = "", nags: Iterable[int] = []) -> None: super().__init__(comment=comment) self.parent = parent self.move = move self.parent.variations.append(self) self.nags.update(nags) - self.starting_comment = starting_comment + self.starting_comment = starting_comment if isinstance(starting_comment, list) else [starting_comment] if starting_comment else [] def board(self) -> chess.Board: stack: List[chess.Move] = [] @@ -1134,7 +1150,7 @@ def visit_board(self, board: chess.Board) -> None: """ pass - def visit_comment(self, comment: str) -> None: + def visit_comment(self, comment: list[str]) -> None: """Called for each comment.""" pass @@ -1188,7 +1204,7 @@ def begin_game(self) -> None: self.game: GameT = self.Game() self.variation_stack: List[GameNode] = [self.game] - self.starting_comment = "" + self.starting_comment: list[str] = [] self.in_variation = False def begin_headers(self) -> Headers: @@ -1213,22 +1229,22 @@ def visit_result(self, result: str) -> None: if self.game.headers.get("Result", "*") == "*": self.game.headers["Result"] = result - def visit_comment(self, comment: str) -> None: + def visit_comment(self, comment: list[str]) -> None: if self.in_variation or (self.variation_stack[-1].parent is None and self.variation_stack[-1].is_end()): # Add as a comment for the current node if in the middle of # a variation. Add as a comment for the game if the comment # starts before any move. - new_comment = [self.variation_stack[-1].comment, comment] - self.variation_stack[-1].comment = " ".join(filter(None, new_comment)) + new_comment = self.variation_stack[-1].comment + comment + self.variation_stack[-1].comment = list(filter(None, new_comment)) else: # Otherwise, it is a starting comment. - new_comment = [self.starting_comment, comment] - self.starting_comment = " ".join(filter(None, new_comment)) + new_comment = self.starting_comment + comment + self.starting_comment = list(filter(None, new_comment)) def visit_move(self, board: chess.Board, move: chess.Move) -> None: self.variation_stack[-1] = self.variation_stack[-1].add_variation(move) self.variation_stack[-1].starting_comment = self.starting_comment - self.starting_comment = "" + self.starting_comment = [] self.in_variation = True def handle_error(self, error: Exception) -> None: @@ -1396,9 +1412,9 @@ def end_variation(self) -> None: self.write_token(") ") self.force_movenumber = True - def visit_comment(self, comment: str) -> None: + def visit_comment(self, comment: list[str]) -> None: if self.comments and (self.variations or not self.variation_depth): - self.write_token("{ " + comment.replace("}", "").strip() + " } ") + self.write_token(" ".join("{ " + single_comment.replace("}", "").strip() + " }" for single_comment in comment) + " ") self.force_movenumber = True def visit_nag(self, nag: int) -> None: @@ -1693,7 +1709,7 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: line = line[close_index + 1:] if not skip_variation_depth: - visitor.visit_comment("".join(comment_lines)) + visitor.visit_comment(["".join(comment_lines)]) # Continue with the current line. fresh_line = False diff --git a/test.py b/test.py index e1d0d50c5..d3961cc6b 100755 --- a/test.py +++ b/test.py @@ -2078,29 +2078,29 @@ class PgnTestCase(unittest.TestCase): def test_exporter(self): game = chess.pgn.Game() - game.comment = "Test game:" + game.comment = ["Test game:"] game.headers["Result"] = "*" game.headers["VeryLongHeader"] = "This is a very long header, much wider than the 80 columns that PGNs are formatted with by default" e4 = game.add_variation(game.board().parse_san("e4")) - e4.comment = "Scandinavian Defense:" + e4.comment = ["Scandinavian Defense:"] e4_d5 = e4.add_variation(e4.board().parse_san("d5")) e4_h5 = e4.add_variation(e4.board().parse_san("h5")) e4_h5.nags.add(chess.pgn.NAG_MISTAKE) - e4_h5.starting_comment = "This" - e4_h5.comment = "is nonsense" + e4_h5.starting_comment = ["This"] + e4_h5.comment = ["is nonsense"] e4_e5 = e4.add_variation(e4.board().parse_san("e5")) e4_e5_Qf3 = e4_e5.add_variation(e4_e5.board().parse_san("Qf3")) e4_e5_Qf3.nags.add(chess.pgn.NAG_MISTAKE) e4_c5 = e4.add_variation(e4.board().parse_san("c5")) - e4_c5.comment = "Sicilian" + e4_c5.comment = ["Sicilian"] e4_d5_exd5 = e4_d5.add_main_variation(e4_d5.board().parse_san("exd5")) - e4_d5_exd5.comment = "Best" + e4_d5_exd5.comment = ["Best"] # Test string exporter with various options. exporter = chess.pgn.StringExporter(headers=False, comments=False, variations=False) @@ -2229,7 +2229,7 @@ def test_comment_at_eol(self): # Make sure the comment for the second variation is there. self.assertIn(5, node[1].nags) - self.assertEqual(node[1].comment, "\n/\\ Ne7, c6") + self.assertEqual(node[1].comment, ["\n/\\ Ne7, c6"]) def test_promotion_without_equals(self): # Example game from https://github.com/rozim/ChessData as originally @@ -2317,12 +2317,12 @@ def test_variation_stack(self): def test_game_starting_comment(self): pgn = io.StringIO("{ Game starting comment } 1. d3") game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, "Game starting comment") + self.assertEqual(game.comment, ["Game starting comment"]) self.assertEqual(game[0].san(), "d3") pgn = io.StringIO("{ Empty game, but has a comment }") game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, "Empty game, but has a comment") + self.assertEqual(game.comment, ["Empty game, but has a comment"]) def test_game_starting_variation(self): pgn = io.StringIO(textwrap.dedent("""\ @@ -2330,7 +2330,7 @@ def test_game_starting_variation(self): """)) game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, "Start of game") + self.assertEqual(game.comment, ["Start of game"]) node = game[0] self.assertEqual(node.move, chess.Move.from_uci("e2e4")) @@ -2340,7 +2340,7 @@ def test_game_starting_variation(self): node = game[1] self.assertEqual(node.move, chess.Move.from_uci("d2d4")) self.assertFalse(node.comment) - self.assertEqual(node.starting_comment, "Start of variation") + self.assertEqual(node.starting_comment, ["Start of variation"]) def test_annotation_symbols(self): pgn = io.StringIO("1. b4?! g6 2. Bb2 Nc6? 3. Bxh8!!") @@ -2685,12 +2685,12 @@ def test_add_line(self): tail = game.add_line(moves, starting_comment="start", comment="end", nags=(17, 42)) self.assertEqual(tail.parent.move, chess.Move.from_uci("g1f3")) - self.assertEqual(tail.parent.starting_comment, "start") - self.assertEqual(tail.parent.comment, "") + self.assertEqual(tail.parent.starting_comment, ["start"]) + self.assertEqual(tail.parent.comment, []) self.assertEqual(len(tail.parent.nags), 0) self.assertEqual(tail.move, chess.Move.from_uci("d7d5")) - self.assertEqual(tail.comment, "end") + self.assertEqual(tail.comment, ["end"]) self.assertIn(42, tail.nags) def test_mainline(self): @@ -2820,27 +2820,27 @@ def test_recursion(self): def test_annotations(self): game = chess.pgn.Game() - game.comment = "foo [%bar] baz" + game.comment = ["foo [%bar] baz"] self.assertTrue(game.clock() is None) clock = 12345 game.set_clock(clock) - self.assertEqual(game.comment, "foo [%bar] baz [%clk 3:25:45]") + self.assertEqual(game.comment, ["foo [%bar] baz", "[%clk 3:25:45]"]) self.assertEqual(game.clock(), clock) self.assertTrue(game.eval() is None) game.set_eval(chess.engine.PovScore(chess.engine.Cp(-80), chess.WHITE)) - self.assertEqual(game.comment, "foo [%bar] baz [%clk 3:25:45] [%eval -0.80]") + self.assertEqual(game.comment, ["foo [%bar] baz", "[%clk 3:25:45]", "[%eval -0.80]"]) self.assertEqual(game.eval().white().score(), -80) self.assertEqual(game.eval_depth(), None) game.set_eval(chess.engine.PovScore(chess.engine.Mate(1), chess.WHITE), 5) - self.assertEqual(game.comment, "foo [%bar] baz [%clk 3:25:45] [%eval #1,5]") + self.assertEqual(game.comment, ["foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]"]) self.assertEqual(game.eval().white().mate(), 1) self.assertEqual(game.eval_depth(), 5) self.assertEqual(game.arrows(), []) game.set_arrows([(chess.A1, chess.A1), chess.svg.Arrow(chess.A1, chess.H1, color="red"), chess.svg.Arrow(chess.B1, chess.B8)]) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5]") + self.assertEqual(game.comment, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]"]) arrows = game.arrows() self.assertEqual(len(arrows), 3) self.assertEqual(arrows[0].color, "green") @@ -2850,18 +2850,18 @@ def test_annotations(self): self.assertTrue(game.emt() is None) emt = 321 game.set_emt(emt) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5] [%emt 0:05:21]") + self.assertEqual(game.comment, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]", "[%emt 0:05:21]"]) self.assertEqual(game.emt(), emt) game.set_eval(None) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%emt 0:05:21]") + self.assertEqual(game.comment, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%emt 0:05:21]"]) game.set_emt(None) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45]") + self.assertEqual(game.comment, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]"]) game.set_clock(None) game.set_arrows([]) - self.assertEqual(game.comment, "foo [%bar] baz") + self.assertEqual(game.comment, ["foo [%bar] baz"]) def test_eval(self): game = chess.pgn.Game() @@ -2871,28 +2871,28 @@ def test_eval(self): def test_float_emt(self): game = chess.pgn.Game() - game.comment = "[%emt 0:00:01.234]" + game.comment = ["[%emt 0:00:01.234]"] self.assertEqual(game.emt(), 1.234) game.set_emt(6.54321) - self.assertEqual(game.comment, "[%emt 0:00:06.543]") + self.assertEqual(game.comment, ["[%emt 0:00:06.543]"]) self.assertEqual(game.emt(), 6.543) game.set_emt(-70) - self.assertEqual(game.comment, "[%emt 0:00:00]") # Clamped + self.assertEqual(game.comment, ["[%emt 0:00:00]"]) # Clamped self.assertEqual(game.emt(), 0) def test_float_clk(self): game = chess.pgn.Game() - game.comment = "[%clk 0:00:01.234]" + game.comment = ["[%clk 0:00:01.234]"] self.assertEqual(game.clock(), 1.234) game.set_clock(6.54321) - self.assertEqual(game.comment, "[%clk 0:00:06.543]") + self.assertEqual(game.comment, ["[%clk 0:00:06.543]"]) self.assertEqual(game.clock(), 6.543) game.set_clock(-70) - self.assertEqual(game.comment, "[%clk 0:00:00]") # Clamped + self.assertEqual(game.comment, ["[%clk 0:00:00]"]) # Clamped self.assertEqual(game.clock(), 0) def test_node_turn(self): From 2269d6a05e137dfe42043474fdaca58c2c6b84a3 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 21 Feb 2024 03:25:33 -0800 Subject: [PATCH 1715/1831] Add test for exporting a move with multiple comments --- test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index d3961cc6b..2008ef49d 100755 --- a/test.py +++ b/test.py @@ -2100,7 +2100,7 @@ def test_exporter(self): e4_c5.comment = ["Sicilian"] e4_d5_exd5 = e4_d5.add_main_variation(e4_d5.board().parse_san("exd5")) - e4_d5_exd5.comment = ["Best"] + e4_d5_exd5.comment = ["Best", "and the end of this example"] # Test string exporter with various options. exporter = chess.pgn.StringExporter(headers=False, comments=False, variations=False) @@ -2125,7 +2125,7 @@ def test_exporter(self): { Test game: } 1. e4 { Scandinavian Defense: } 1... d5 ( { This } 1... h5 $2 { is nonsense } ) ( 1... e5 2. Qf3 $2 ) ( 1... c5 { Sicilian } ) 2. exd5 - { Best } *""") + { Best } { and the end of this example } *""") self.assertEqual(str(exporter), pgn) # Test file exporter. From 05da5981c5494b1c87b214a0fd46dfc4b0f6ac5a Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 21 Feb 2024 03:48:21 -0800 Subject: [PATCH 1716/1831] Undo member renaming --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 65ef0e6d5..f13812bae 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -197,13 +197,13 @@ class GameNode(abc.ABC): variations: List[ChildNode] """A list of child nodes.""" - comments: list[str] + comment: list[str] """ Comments that go behind the move leading to this node. Comments that occur before any moves are assigned to the root node. """ - starting_comments: list[str] + starting_comment: list[str] nags: Set[int] def __init__(self, *, comment: Union[str, list[str]] = "") -> None: From c06030895cbcf49251279724bd19669c6f580349 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 21 Feb 2024 03:48:45 -0800 Subject: [PATCH 1717/1831] Add test for reading game with mulit-comment moves --- test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test.py b/test.py index 2008ef49d..c912948c4 100755 --- a/test.py +++ b/test.py @@ -2215,6 +2215,14 @@ def test_read_game(self): self.assertEqual(sixth_game.headers["White"], "Deep Blue (Computer)") self.assertEqual(sixth_game.headers["Result"], "1-0") + def test_read_game_with_multicomment_move(self): + pgn = io.StringIO("1. e4 {A common opening} 1... e5 {A common response} {An uncommon comment}") + game = chess.pgn.read_game(pgn) + first_move = game.variation(0) + self.assertEqual(first_move.comment, ["A common opening"]) + second_move = first_move.variation(0) + self.assertEqual(second_move.comment, ["A common response", "An uncommon comment"]) + def test_comment_at_eol(self): pgn = io.StringIO(textwrap.dedent("""\ 1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d3 d6 6. Nbd2 a6 $6 (6... Bb6 $5 { From 8d076cb77600d84f692e19f70abfdf9d04b93498 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 03:43:33 -0800 Subject: [PATCH 1718/1831] Undo comment change --- chess/pgn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index f13812bae..513698dff 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -199,7 +199,7 @@ class GameNode(abc.ABC): comment: list[str] """ - Comments that go behind the move leading to this node. Comments + A comment that goes behind the move leading to this node. Comments that occur before any moves are assigned to the root node. """ From 1df1b76fb064765b7e7510fbe6b35c1b27c3dde0 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 03:55:05 -0800 Subject: [PATCH 1719/1831] Create class to hold multiple comments --- chess/pgn.py | 116 ++++++++++++++++++++++++++++++++++++++++----------- test.py | 18 ++++---- 2 files changed, 100 insertions(+), 34 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 513698dff..763b90f02 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -184,6 +184,70 @@ def __init__(self, node: ChildNode, *, is_variation: bool = False, sidelines: bo self.in_variation = False +class GameNodeComment: + """ + PGN Comment Storage + + A class that can hold one or more comments for a GameNode. + """ + def __init__(self, comment: Union[str, list[str]] = ""): + self.set(comment) + + def set(self, new_comment: Union[str, list[str]]): + """Replace the comment with a new comment or a list of comments.""" + self._comments = new_comment if isinstance(new_comment, list) else [new_comment] if new_comment else [] + + def pgn_format(self) -> str: + """Create a string representation of the comments in PGN format.""" + comments = list(map(lambda s: s.replace("{", ""), self._comments)) + comments = list(map(lambda s: s.replace("}", "").strip(), comments)) + output_comments = GameNodeComment(comments) + output_comments.remove_empty() + return "{ " + output_comments.join(" } { ") + " }" + + def remove_empty(self) -> None: + """Remove empty comments from the comment list.""" + self._comments = list(filter(None, self._comments)) + + def append(self, new_comment: str) -> None: + """Append a new comment to the end of the comment list.""" + self._comments.append(new_comment) + + def extend(self, new_comments: list[str]) -> None: + """Append several new comments to the end of the comment list.""" + self._comments.extend(new_comments) + + def insert(self, index: int, new_comment: str) -> None: + """Insert a new comment before the specified index.""" + self._comments.insert(index, new_comment) + + def join(self, joiner: str) -> str: + """Join all of the comments together with a joiner string between each.""" + return joiner.join(self._comments) + + def __len__(self) -> int: + return len(self._comments) + + def __getitem__(self, index: int) -> str: + return self._comments[index] + + def __setitem__(self, index: int, new_comment: str) -> None: + self._comments[index] = new_comment + + def __add__(self, other: GameNodeComment) -> GameNodeComment: + return GameNodeComment(self._comments + other._comments) + + def __eq__(self, other: object) -> bool: + if isinstance(other, str): + return len(self) == 1 and self[0] == other + elif isinstance(other, list): + return self._comments == other + elif isinstance(other, GameNodeComment): + return self._comments == other._comments + else: + return False + + class GameNode(abc.ABC): parent: Optional[GameNode] """The parent node or ``None`` if this is the root node of the game.""" @@ -197,24 +261,24 @@ class GameNode(abc.ABC): variations: List[ChildNode] """A list of child nodes.""" - comment: list[str] + comment: GameNodeComment """ A comment that goes behind the move leading to this node. Comments that occur before any moves are assigned to the root node. """ - starting_comment: list[str] + starting_comment: GameNodeComment nags: Set[int] def __init__(self, *, comment: Union[str, list[str]] = "") -> None: self.parent = None self.move = None self.variations = [] - self.comment = comment if isinstance(comment, list) else [comment] if comment else [] + self.comment = GameNodeComment(comment) # Deprecated: These should be properties of ChildNode, but need to # remain here for backwards compatibility. - self.starting_comment: list[str] = [] + self.starting_comment = GameNodeComment() self.nags = set() @abc.abstractmethod @@ -436,7 +500,7 @@ def add_line(self, moves: Iterable[chess.Move], *, comment: Union[str, list[str] else: node.comment.extend(comment) else: - node.comment = comment if isinstance(comment, list) else [comment] if comment else [] + node.comment.set(comment) node.nags.update(nags) @@ -449,7 +513,7 @@ def eval(self) -> Optional[chess.engine.PovScore]: Complexity is `O(n)`. """ - match = EVAL_REGEX.search(" ".join(self.comment)) + match = EVAL_REGEX.search(self.comment.join(" ")) if not match: return None @@ -475,7 +539,7 @@ def eval_depth(self) -> Optional[int]: Complexity is `O(1)`. """ - match = EVAL_REGEX.search(" ".join(self.comment)) + match = EVAL_REGEX.search(self.comment.join(" ")) return int(match.group("depth")) if match and match.group("depth") else None def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] = None) -> None: @@ -498,7 +562,7 @@ def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] if found: break - self.comment = list(filter(None, self.comment)) + self.comment.remove_empty() if not found and eval: self.comment.append(eval) @@ -511,7 +575,7 @@ def arrows(self) -> List[chess.svg.Arrow]: Returns a list of :class:`arrows `. """ arrows = [] - for match in ARROWS_REGEX.finditer(" ".join(self.comment)): + for match in ARROWS_REGEX.finditer(self.comment.join(" ")): for group in match.group("arrows").split(","): arrows.append(chess.svg.Arrow.from_pgn(group)) @@ -536,7 +600,7 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar for index in range(len(self.comment)): self.comment[index] = ARROWS_REGEX.sub(_condense_affix(""), self.comment[index]) - self.comment = list(filter(None, self.comment)) + self.comment.remove_empty() prefix = "" if csl: @@ -555,7 +619,7 @@ def clock(self) -> Optional[float]: Returns the player's remaining time to the next time control after this move, in seconds. """ - match = CLOCK_REGEX.search(" ".join(self.comment)) + match = CLOCK_REGEX.search(self.comment.join(" ")) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -580,7 +644,7 @@ def set_clock(self, seconds: Optional[float]) -> None: if found: break - self.comment = list(filter(None, self.comment)) + self.comment.remove_empty() if not found and clk: self.comment.append(clk) @@ -593,7 +657,7 @@ def emt(self) -> Optional[float]: Returns the player's elapsed move time use for the comment of this move, in seconds. """ - match = EMT_REGEX.search(" ".join(self.comment)) + match = EMT_REGEX.search(self.comment.join(" ")) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -618,7 +682,7 @@ def set_emt(self, seconds: Optional[float]) -> None: if found: break - self.comment = list(filter(None, self.comment)) + self.comment.remove_empty() if not found and emt: self.comment.append(emt) @@ -677,7 +741,7 @@ class ChildNode(GameNode): move: chess.Move """The move leading to this node.""" - starting_comment: list[str] + starting_comment: GameNodeComment """ A comment for the start of a variation. Only nodes that actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` @@ -698,7 +762,7 @@ def __init__(self, parent: GameNode, move: chess.Move, *, comment: Union[str, li self.parent.variations.append(self) self.nags.update(nags) - self.starting_comment = starting_comment if isinstance(starting_comment, list) else [starting_comment] if starting_comment else [] + self.starting_comment = GameNodeComment(starting_comment) def board(self) -> chess.Board: stack: List[chess.Move] = [] @@ -1150,7 +1214,7 @@ def visit_board(self, board: chess.Board) -> None: """ pass - def visit_comment(self, comment: list[str]) -> None: + def visit_comment(self, comment: GameNodeComment) -> None: """Called for each comment.""" pass @@ -1204,7 +1268,7 @@ def begin_game(self) -> None: self.game: GameT = self.Game() self.variation_stack: List[GameNode] = [self.game] - self.starting_comment: list[str] = [] + self.starting_comment = GameNodeComment() self.in_variation = False def begin_headers(self) -> Headers: @@ -1229,22 +1293,24 @@ def visit_result(self, result: str) -> None: if self.game.headers.get("Result", "*") == "*": self.game.headers["Result"] = result - def visit_comment(self, comment: list[str]) -> None: + def visit_comment(self, comment: GameNodeComment) -> None: if self.in_variation or (self.variation_stack[-1].parent is None and self.variation_stack[-1].is_end()): # Add as a comment for the current node if in the middle of # a variation. Add as a comment for the game if the comment # starts before any move. new_comment = self.variation_stack[-1].comment + comment - self.variation_stack[-1].comment = list(filter(None, new_comment)) + new_comment.remove_empty() + self.variation_stack[-1].comment = new_comment else: # Otherwise, it is a starting comment. new_comment = self.starting_comment + comment - self.starting_comment = list(filter(None, new_comment)) + new_comment.remove_empty() + self.starting_comment = new_comment def visit_move(self, board: chess.Board, move: chess.Move) -> None: self.variation_stack[-1] = self.variation_stack[-1].add_variation(move) self.variation_stack[-1].starting_comment = self.starting_comment - self.starting_comment = [] + self.starting_comment = GameNodeComment() self.in_variation = True def handle_error(self, error: Exception) -> None: @@ -1412,9 +1478,9 @@ def end_variation(self) -> None: self.write_token(") ") self.force_movenumber = True - def visit_comment(self, comment: list[str]) -> None: + def visit_comment(self, comment: GameNodeComment) -> None: if self.comments and (self.variations or not self.variation_depth): - self.write_token(" ".join("{ " + single_comment.replace("}", "").strip() + " }" for single_comment in comment) + " ") + self.write_token(comment.pgn_format() + " ") self.force_movenumber = True def visit_nag(self, nag: int) -> None: @@ -1709,7 +1775,7 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: line = line[close_index + 1:] if not skip_variation_depth: - visitor.visit_comment(["".join(comment_lines)]) + visitor.visit_comment(GameNodeComment("".join(comment_lines))) # Continue with the current line. fresh_line = False diff --git a/test.py b/test.py index c912948c4..8750031ca 100755 --- a/test.py +++ b/test.py @@ -2078,29 +2078,29 @@ class PgnTestCase(unittest.TestCase): def test_exporter(self): game = chess.pgn.Game() - game.comment = ["Test game:"] + game.comment.set("Test game:") game.headers["Result"] = "*" game.headers["VeryLongHeader"] = "This is a very long header, much wider than the 80 columns that PGNs are formatted with by default" e4 = game.add_variation(game.board().parse_san("e4")) - e4.comment = ["Scandinavian Defense:"] + e4.comment.set("Scandinavian Defense:") e4_d5 = e4.add_variation(e4.board().parse_san("d5")) e4_h5 = e4.add_variation(e4.board().parse_san("h5")) e4_h5.nags.add(chess.pgn.NAG_MISTAKE) - e4_h5.starting_comment = ["This"] - e4_h5.comment = ["is nonsense"] + e4_h5.starting_comment.set("This") + e4_h5.comment.set("is nonsense") e4_e5 = e4.add_variation(e4.board().parse_san("e5")) e4_e5_Qf3 = e4_e5.add_variation(e4_e5.board().parse_san("Qf3")) e4_e5_Qf3.nags.add(chess.pgn.NAG_MISTAKE) e4_c5 = e4.add_variation(e4.board().parse_san("c5")) - e4_c5.comment = ["Sicilian"] + e4_c5.comment.set("Sicilian") e4_d5_exd5 = e4_d5.add_main_variation(e4_d5.board().parse_san("exd5")) - e4_d5_exd5.comment = ["Best", "and the end of this example"] + e4_d5_exd5.comment.set(["Best", "and the end of this example"]) # Test string exporter with various options. exporter = chess.pgn.StringExporter(headers=False, comments=False, variations=False) @@ -2828,7 +2828,7 @@ def test_recursion(self): def test_annotations(self): game = chess.pgn.Game() - game.comment = ["foo [%bar] baz"] + game.comment = chess.pgn.GameNodeComment("foo [%bar] baz") self.assertTrue(game.clock() is None) clock = 12345 @@ -2879,7 +2879,7 @@ def test_eval(self): def test_float_emt(self): game = chess.pgn.Game() - game.comment = ["[%emt 0:00:01.234]"] + game.comment = chess.pgn.GameNodeComment("[%emt 0:00:01.234]") self.assertEqual(game.emt(), 1.234) game.set_emt(6.54321) @@ -2892,7 +2892,7 @@ def test_float_emt(self): def test_float_clk(self): game = chess.pgn.Game() - game.comment = ["[%clk 0:00:01.234]"] + game.comment.set("[%clk 0:00:01.234]") self.assertEqual(game.clock(), 1.234) game.set_clock(6.54321) From 829a3bf6ded7f8d738655ee924df90812b8af0c2 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 04:01:57 -0800 Subject: [PATCH 1720/1831] Empty GameNodeComments equal empty strings --- chess/pgn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 763b90f02..058c932a8 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -239,7 +239,7 @@ def __add__(self, other: GameNodeComment) -> GameNodeComment: def __eq__(self, other: object) -> bool: if isinstance(other, str): - return len(self) == 1 and self[0] == other + return (len(self) == 1 and self[0] == other) or (not self and not other) elif isinstance(other, list): return self._comments == other elif isinstance(other, GameNodeComment): From 7e0081e6d5b5f1188224a02ab9d78f0fe6b5b80d Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 04:02:15 -0800 Subject: [PATCH 1721/1831] Revert unnecessary test changes --- test.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test.py b/test.py index 8750031ca..f6d30a4d1 100755 --- a/test.py +++ b/test.py @@ -2219,7 +2219,7 @@ def test_read_game_with_multicomment_move(self): pgn = io.StringIO("1. e4 {A common opening} 1... e5 {A common response} {An uncommon comment}") game = chess.pgn.read_game(pgn) first_move = game.variation(0) - self.assertEqual(first_move.comment, ["A common opening"]) + self.assertEqual(first_move.comment, "A common opening") second_move = first_move.variation(0) self.assertEqual(second_move.comment, ["A common response", "An uncommon comment"]) @@ -2237,7 +2237,7 @@ def test_comment_at_eol(self): # Make sure the comment for the second variation is there. self.assertIn(5, node[1].nags) - self.assertEqual(node[1].comment, ["\n/\\ Ne7, c6"]) + self.assertEqual(node[1].comment, "\n/\\ Ne7, c6") def test_promotion_without_equals(self): # Example game from https://github.com/rozim/ChessData as originally @@ -2325,12 +2325,12 @@ def test_variation_stack(self): def test_game_starting_comment(self): pgn = io.StringIO("{ Game starting comment } 1. d3") game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, ["Game starting comment"]) + self.assertEqual(game.comment, "Game starting comment") self.assertEqual(game[0].san(), "d3") pgn = io.StringIO("{ Empty game, but has a comment }") game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, ["Empty game, but has a comment"]) + self.assertEqual(game.comment, "Empty game, but has a comment") def test_game_starting_variation(self): pgn = io.StringIO(textwrap.dedent("""\ @@ -2338,7 +2338,7 @@ def test_game_starting_variation(self): """)) game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, ["Start of game"]) + self.assertEqual(game.comment, "Start of game") node = game[0] self.assertEqual(node.move, chess.Move.from_uci("e2e4")) @@ -2348,7 +2348,7 @@ def test_game_starting_variation(self): node = game[1] self.assertEqual(node.move, chess.Move.from_uci("d2d4")) self.assertFalse(node.comment) - self.assertEqual(node.starting_comment, ["Start of variation"]) + self.assertEqual(node.starting_comment, "Start of variation") def test_annotation_symbols(self): pgn = io.StringIO("1. b4?! g6 2. Bb2 Nc6? 3. Bxh8!!") @@ -2693,12 +2693,12 @@ def test_add_line(self): tail = game.add_line(moves, starting_comment="start", comment="end", nags=(17, 42)) self.assertEqual(tail.parent.move, chess.Move.from_uci("g1f3")) - self.assertEqual(tail.parent.starting_comment, ["start"]) - self.assertEqual(tail.parent.comment, []) + self.assertEqual(tail.parent.starting_comment, "start") + self.assertEqual(tail.parent.comment, "") self.assertEqual(len(tail.parent.nags), 0) self.assertEqual(tail.move, chess.Move.from_uci("d7d5")) - self.assertEqual(tail.comment, ["end"]) + self.assertEqual(tail.comment, "end") self.assertIn(42, tail.nags) def test_mainline(self): @@ -2828,7 +2828,7 @@ def test_recursion(self): def test_annotations(self): game = chess.pgn.Game() - game.comment = chess.pgn.GameNodeComment("foo [%bar] baz") + game.comment.set("foo [%bar] baz") self.assertTrue(game.clock() is None) clock = 12345 @@ -2869,7 +2869,7 @@ def test_annotations(self): game.set_clock(None) game.set_arrows([]) - self.assertEqual(game.comment, ["foo [%bar] baz"]) + self.assertEqual(game.comment, "foo [%bar] baz") def test_eval(self): game = chess.pgn.Game() @@ -2879,15 +2879,15 @@ def test_eval(self): def test_float_emt(self): game = chess.pgn.Game() - game.comment = chess.pgn.GameNodeComment("[%emt 0:00:01.234]") + game.comment.set("[%emt 0:00:01.234]") self.assertEqual(game.emt(), 1.234) game.set_emt(6.54321) - self.assertEqual(game.comment, ["[%emt 0:00:06.543]"]) + self.assertEqual(game.comment, "[%emt 0:00:06.543]") self.assertEqual(game.emt(), 6.543) game.set_emt(-70) - self.assertEqual(game.comment, ["[%emt 0:00:00]"]) # Clamped + self.assertEqual(game.comment, "[%emt 0:00:00]") # Clamped self.assertEqual(game.emt(), 0) def test_float_clk(self): @@ -2896,11 +2896,11 @@ def test_float_clk(self): self.assertEqual(game.clock(), 1.234) game.set_clock(6.54321) - self.assertEqual(game.comment, ["[%clk 0:00:06.543]"]) + self.assertEqual(game.comment, "[%clk 0:00:06.543]") self.assertEqual(game.clock(), 6.543) game.set_clock(-70) - self.assertEqual(game.comment, ["[%clk 0:00:00]"]) # Clamped + self.assertEqual(game.comment, "[%clk 0:00:00]") # Clamped self.assertEqual(game.clock(), 0) def test_node_turn(self): From b524c3a130c8a535b060af7e73e82339c97617eb Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 04:24:26 -0800 Subject: [PATCH 1722/1831] Combine append() and extend() methods --- chess/pgn.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 058c932a8..a44aea6fb 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -209,13 +209,13 @@ def remove_empty(self) -> None: """Remove empty comments from the comment list.""" self._comments = list(filter(None, self._comments)) - def append(self, new_comment: str) -> None: - """Append a new comment to the end of the comment list.""" - self._comments.append(new_comment) - - def extend(self, new_comments: list[str]) -> None: - """Append several new comments to the end of the comment list.""" - self._comments.extend(new_comments) + def append(self, new_comment: Union[str, list[str]]) -> None: + """Append one or more new comments to the end of the comment list.""" + if new_comment: + if isinstance(new_comment, str): + self._comments.append(new_comment) + else: + self._comments.extend(new_comment) def insert(self, index: int, new_comment: str) -> None: """Insert a new comment before the specified index.""" @@ -494,14 +494,7 @@ def add_line(self, moves: Iterable[chess.Move], *, comment: Union[str, list[str] starting_comment = "" # Merge comment and NAGs. - if node.comment: - if isinstance(comment, str): - node.comment.append(comment) - else: - node.comment.extend(comment) - else: - node.comment.set(comment) - + node.comment.append(comment) node.nags.update(nags) return node From 9123ebd98765ccda2b81b21118d0a7e007937d10 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 04:30:00 -0800 Subject: [PATCH 1723/1831] Add missing return type annotation --- chess/pgn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index a44aea6fb..6fc34133c 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -193,7 +193,7 @@ class GameNodeComment: def __init__(self, comment: Union[str, list[str]] = ""): self.set(comment) - def set(self, new_comment: Union[str, list[str]]): + def set(self, new_comment: Union[str, list[str]]) -> None: """Replace the comment with a new comment or a list of comments.""" self._comments = new_comment if isinstance(new_comment, list) else [new_comment] if new_comment else [] From 4e084cc1d652fcf4070dd8eee0a5c561534631d5 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 20:56:04 -0800 Subject: [PATCH 1724/1831] Remove unneeded GameNodeComment instance --- chess/pgn.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 6fc34133c..78c238287 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -201,9 +201,8 @@ def pgn_format(self) -> str: """Create a string representation of the comments in PGN format.""" comments = list(map(lambda s: s.replace("{", ""), self._comments)) comments = list(map(lambda s: s.replace("}", "").strip(), comments)) - output_comments = GameNodeComment(comments) - output_comments.remove_empty() - return "{ " + output_comments.join(" } { ") + " }" + comments = list(filter(None, comments)) + return "{ " + " } { ".join(comments) + " }" def remove_empty(self) -> None: """Remove empty comments from the comment list.""" From 91801c873b58d20a48d533027d4f940907a4a3ac Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 21:37:36 -0800 Subject: [PATCH 1725/1831] Use @property to make changes backwards compatible --- chess/pgn.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++------ test.py | 18 +++++++++--------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 78c238287..5cc70747a 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -233,8 +233,13 @@ def __getitem__(self, index: int) -> str: def __setitem__(self, index: int, new_comment: str) -> None: self._comments[index] = new_comment - def __add__(self, other: GameNodeComment) -> GameNodeComment: - return GameNodeComment(self._comments + other._comments) + def __add__(self, other: Union[str, list[str], GameNodeComment]) -> GameNodeComment: + if not isinstance(other, GameNodeComment): + new_node_comment = GameNodeComment(self._comments) + new_node_comment.append(other) + return new_node_comment + else: + return GameNodeComment(self._comments + other._comments) def __eq__(self, other: object) -> bool: if isinstance(other, str): @@ -260,13 +265,37 @@ class GameNode(abc.ABC): variations: List[ChildNode] """A list of child nodes.""" - comment: GameNodeComment + _comment: GameNodeComment """ A comment that goes behind the move leading to this node. Comments that occur before any moves are assigned to the root node. """ - starting_comment: GameNodeComment + @property + def comment(self) -> GameNodeComment: + return self._comment + + @comment.setter + def comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: + if isinstance(new_comment, GameNodeComment): + self._comment = new_comment + else: + self._comment = GameNodeComment(new_comment) + + + _starting_comment: GameNodeComment + + @property + def starting_comment(self) -> GameNodeComment: + return self._starting_comment + + @starting_comment.setter + def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: + if isinstance(new_comment, GameNodeComment): + self._starting_comment = new_comment + else: + self._starting_comment = GameNodeComment(new_comment) + nags: Set[int] def __init__(self, *, comment: Union[str, list[str]] = "") -> None: @@ -733,7 +762,7 @@ class ChildNode(GameNode): move: chess.Move """The move leading to this node.""" - starting_comment: GameNodeComment + _starting_comment: GameNodeComment """ A comment for the start of a variation. Only nodes that actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` @@ -741,6 +770,17 @@ class ChildNode(GameNode): a starting comment. """ + @property + def starting_comment(self) -> GameNodeComment: + return self._starting_comment + + @starting_comment.setter + def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: + if isinstance(new_comment, GameNodeComment): + self._starting_comment = new_comment + else: + self._starting_comment = GameNodeComment(new_comment) + nags: Set[int] """ A set of NAGs as integers. NAGs always go behind a move, so the root @@ -1767,7 +1807,7 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: line = line[close_index + 1:] if not skip_variation_depth: - visitor.visit_comment(GameNodeComment("".join(comment_lines))) + visitor.visit_comment("".join(comment_lines)) # Continue with the current line. fresh_line = False diff --git a/test.py b/test.py index f6d30a4d1..91e54e5d5 100755 --- a/test.py +++ b/test.py @@ -2078,29 +2078,29 @@ class PgnTestCase(unittest.TestCase): def test_exporter(self): game = chess.pgn.Game() - game.comment.set("Test game:") + game.comment = "Test game:" game.headers["Result"] = "*" game.headers["VeryLongHeader"] = "This is a very long header, much wider than the 80 columns that PGNs are formatted with by default" e4 = game.add_variation(game.board().parse_san("e4")) - e4.comment.set("Scandinavian Defense:") + e4.comment = "Scandinavian Defense:" e4_d5 = e4.add_variation(e4.board().parse_san("d5")) e4_h5 = e4.add_variation(e4.board().parse_san("h5")) e4_h5.nags.add(chess.pgn.NAG_MISTAKE) - e4_h5.starting_comment.set("This") - e4_h5.comment.set("is nonsense") + e4_h5.starting_comment = "This" + e4_h5.comment = "is nonsense" e4_e5 = e4.add_variation(e4.board().parse_san("e5")) e4_e5_Qf3 = e4_e5.add_variation(e4_e5.board().parse_san("Qf3")) e4_e5_Qf3.nags.add(chess.pgn.NAG_MISTAKE) e4_c5 = e4.add_variation(e4.board().parse_san("c5")) - e4_c5.comment.set("Sicilian") + e4_c5.comment = "Sicilian" e4_d5_exd5 = e4_d5.add_main_variation(e4_d5.board().parse_san("exd5")) - e4_d5_exd5.comment.set(["Best", "and the end of this example"]) + e4_d5_exd5.comment = ["Best", "and the end of this example"] # Test string exporter with various options. exporter = chess.pgn.StringExporter(headers=False, comments=False, variations=False) @@ -2828,7 +2828,7 @@ def test_recursion(self): def test_annotations(self): game = chess.pgn.Game() - game.comment.set("foo [%bar] baz") + game.comment = "foo [%bar] baz" self.assertTrue(game.clock() is None) clock = 12345 @@ -2879,7 +2879,7 @@ def test_eval(self): def test_float_emt(self): game = chess.pgn.Game() - game.comment.set("[%emt 0:00:01.234]") + game.comment = "[%emt 0:00:01.234]" self.assertEqual(game.emt(), 1.234) game.set_emt(6.54321) @@ -2892,7 +2892,7 @@ def test_float_emt(self): def test_float_clk(self): game = chess.pgn.Game() - game.comment.set("[%clk 0:00:01.234]") + game.comment = "[%clk 0:00:01.234]" self.assertEqual(game.clock(), 1.234) game.set_clock(6.54321) From 54e044ac6fc2e9288453a72b3a8db435d3380f2b Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 21:50:47 -0800 Subject: [PATCH 1726/1831] Positive branch first --- chess/pgn.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 5cc70747a..a9910f45b 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -234,12 +234,12 @@ def __setitem__(self, index: int, new_comment: str) -> None: self._comments[index] = new_comment def __add__(self, other: Union[str, list[str], GameNodeComment]) -> GameNodeComment: - if not isinstance(other, GameNodeComment): - new_node_comment = GameNodeComment(self._comments) + if isinstance(other, GameNodeComment): + return GameNodeComment(self._comments + other._comments) + else: + new_node_comment = GameNodeComment(self._comments.copy()) new_node_comment.append(other) return new_node_comment - else: - return GameNodeComment(self._comments + other._comments) def __eq__(self, other: object) -> bool: if isinstance(other, str): From aa47f1e7de3a36ff117b6b2ac9c3ef0b23bef3b8 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 22:11:05 -0800 Subject: [PATCH 1727/1831] Add display methods to GameNodeComment --- chess/pgn.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chess/pgn.py b/chess/pgn.py index a9910f45b..7695a1c68 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -251,6 +251,12 @@ def __eq__(self, other: object) -> bool: else: return False + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self._comments})" + + def __str__(self) -> str: + return self.pgn_format() + class GameNode(abc.ABC): parent: Optional[GameNode] From f1a56125104ca3c80a9c615c949d18401b465948 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Thu, 22 Feb 2024 22:57:05 -0800 Subject: [PATCH 1728/1831] Create method for deleting individual comments --- chess/pgn.py | 4 ++++ test.py | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/chess/pgn.py b/chess/pgn.py index 7695a1c68..fd3096013 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -220,6 +220,10 @@ def insert(self, index: int, new_comment: str) -> None: """Insert a new comment before the specified index.""" self._comments.insert(index, new_comment) + def pop(self, index: int = -1) -> None: + """Delete comment at the given index (default is the last comment).""" + self._comments.pop(index) + def join(self, joiner: str) -> str: """Join all of the comments together with a joiner string between each.""" return joiner.join(self._comments) diff --git a/test.py b/test.py index 91e54e5d5..cbc41d6dd 100755 --- a/test.py +++ b/test.py @@ -2222,6 +2222,14 @@ def test_read_game_with_multicomment_move(self): self.assertEqual(first_move.comment, "A common opening") second_move = first_move.variation(0) self.assertEqual(second_move.comment, ["A common response", "An uncommon comment"]) + second_move.comment.pop() + self.assertEqual(second_move.comment, ["A common response"]) + self.assertEqual(second_move.comment, "A common response") + second_move.comment.append("A replaced comment") + self.assertEqual(second_move.comment, ["A common response", "A replaced comment"]) + second_move.comment.pop(0) + self.assertEqual(second_move.comment, ["A replaced comment"]) + self.assertEqual(second_move.comment, "A replaced comment") def test_comment_at_eol(self): pgn = io.StringIO(textwrap.dedent("""\ From 8e91525e47593932911951919a6855f2ea2aa170 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 24 Feb 2024 20:20:38 +0100 Subject: [PATCH 1729/1831] Add sf16.1 WDL model --- chess/engine.py | 17 +++++++++++++++-- test.py | 3 ++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index b1d3896ab..b72bf5907 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -24,7 +24,7 @@ from types import TracebackType from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Optional, Tuple, Type, TypedDict, TypeVar, Union -WdlModel = Literal["sf", "sf16", "sf15.1", "sf15", "sf14", "sf12", "lichess"] +WdlModel = Literal["sf", "sf16.1", "sf16", "sf15.1", "sf15", "sf14", "sf12", "lichess"] T = TypeVar("T") @@ -516,6 +516,16 @@ def __ge__(self, other: object) -> bool: else: return NotImplemented +def _sf16_1_wins(cp: int, *, ply=int) -> int: + # https://github.com/official-stockfish/Stockfish/blob/sf_16.1/src/uci.cpp#L48 + NormalizeToPawnValue = 356 + # https://github.com/official-stockfish/Stockfish/blob/sf_16.1/src/uci.cpp#L383-L384 + m = min(120, max(8, ply / 2 + 1)) / 32 + a = (((-1.06249702 * m + 7.42016937) * m + 0.89425629) * m) + 348.60356174 + b = (((-5.33122190 * m + 39.57831533) * m + -90.84473771) * m) + 123.40620748 + x = min(4000, max(cp * NormalizeToPawnValue / 100, -4000)) + return int(0.5 + 1000 / (1 + math.exp((a - x) / b))) + def _sf16_wins(cp: int, *, ply: int) -> int: # https://github.com/official-stockfish/Stockfish/blob/sf_16/src/uci.h#L38 NormalizeToPawnValue = 328 @@ -594,9 +604,12 @@ def wdl(self, *, model: WdlModel = "sf", ply: int = 30) -> Wdl: elif model == "sf15.1": wins = _sf15_1_wins(self.cp, ply=ply) losses = _sf15_1_wins(-self.cp, ply=ply) - else: + elif model == "sf16": wins = _sf16_wins(self.cp, ply=ply) losses = _sf16_wins(-self.cp, ply=ply) + else: + wins = _sf16_1_wins(self.cp, ply=ply) + losses = _sf16_1_wins(-self.cp, ply=ply) draws = 1000 - wins - losses return Wdl(wins, draws, losses) diff --git a/test.py b/test.py index e1d0d50c5..8dbc95a25 100755 --- a/test.py +++ b/test.py @@ -2995,7 +2995,7 @@ def test_score_ordering(self): self.assertEqual(i >= j, a >= b) self.assertEqual(i < j, a.score(mate_score=100000) < b.score(mate_score=100000)) - for model in ["sf12", "sf14", "sf15", "sf15.1", "sf16"]: + for model in ["sf12", "sf14", "sf15", "sf15.1", "sf16", "sf16.1"]: self.assertTrue(not (i < j) or a.wdl(model=model).expectation() <= b.wdl(model=model).expectation()) self.assertTrue(not (i < j) or a.wdl(model=model).winning_chance() <= b.wdl(model=model).winning_chance()) self.assertTrue(not (i < j) or a.wdl(model=model).losing_chance() >= b.wdl(model=model).losing_chance()) @@ -3035,6 +3035,7 @@ def test_wdl_model(self): 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)) + self.assertEqual(chess.engine.Cp(51).wdl(model="sf16.1", ply=158), chess.engine.Wdl(36, 964, 0)) @catchAndSkip(FileNotFoundError, "need stockfish") def test_sf_forced_mates(self): From 315052c0105ea1e0d0b4e1cbee70577fd9349f2d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 24 Feb 2024 20:25:56 +0100 Subject: [PATCH 1730/1831] Fix argument syntax --- chess/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index b72bf5907..c2b470dd5 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -516,7 +516,7 @@ def __ge__(self, other: object) -> bool: else: return NotImplemented -def _sf16_1_wins(cp: int, *, ply=int) -> int: +def _sf16_1_wins(cp: int, *, ply: int) -> int: # https://github.com/official-stockfish/Stockfish/blob/sf_16.1/src/uci.cpp#L48 NormalizeToPawnValue = 356 # https://github.com/official-stockfish/Stockfish/blob/sf_16.1/src/uci.cpp#L383-L384 From 8756e7878b2076fe9a7fe574086e43be58d4e7a2 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 28 Feb 2024 01:05:43 -0800 Subject: [PATCH 1731/1831] Test that GameNodeComment is iterable --- test.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index cbc41d6dd..ee770de0f 100755 --- a/test.py +++ b/test.py @@ -2226,7 +2226,11 @@ def test_read_game_with_multicomment_move(self): self.assertEqual(second_move.comment, ["A common response"]) self.assertEqual(second_move.comment, "A common response") second_move.comment.append("A replaced comment") - self.assertEqual(second_move.comment, ["A common response", "A replaced comment"]) + multiple_comments = ["A common response", "A replaced comment"] + self.assertEqual(second_move.comment, multiple_comments) + for move_comment, test_comment in zip(second_move.comment, multiple_comments): + self.assertEqual(move_comment, test_comment) + self.assertEqual(list(second_move.comment), multiple_comments) second_move.comment.pop(0) self.assertEqual(second_move.comment, ["A replaced comment"]) self.assertEqual(second_move.comment, "A replaced comment") From 603c9755e23093ddf985a603fa19f6b24878cad0 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 28 Feb 2024 01:20:01 -0800 Subject: [PATCH 1732/1831] Make pgn_format() code easier to read --- chess/pgn.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index fd3096013..2d7f31096 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -199,10 +199,9 @@ def set(self, new_comment: Union[str, list[str]]) -> None: def pgn_format(self) -> str: """Create a string representation of the comments in PGN format.""" - comments = list(map(lambda s: s.replace("{", ""), self._comments)) - comments = list(map(lambda s: s.replace("}", "").strip(), comments)) - comments = list(filter(None, comments)) - return "{ " + " } { ".join(comments) + " }" + comments = map(lambda s: s.replace("{", ""), self._comments) + comments = map(lambda s: s.replace("}", "").strip(), comments) + return " ".join(f"{{ {comment} }}" for comment in comments if comment) def remove_empty(self) -> None: """Remove empty comments from the comment list.""" From cce50dcacd0774d6a6595de1ce65b5f0dd7b5101 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 28 Feb 2024 01:54:19 -0800 Subject: [PATCH 1733/1831] Use built-in join() --- chess/pgn.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 2d7f31096..0e0345a92 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -223,10 +223,6 @@ def pop(self, index: int = -1) -> None: """Delete comment at the given index (default is the last comment).""" self._comments.pop(index) - def join(self, joiner: str) -> str: - """Join all of the comments together with a joiner string between each.""" - return joiner.join(self._comments) - def __len__(self) -> int: return len(self._comments) @@ -236,6 +232,9 @@ def __getitem__(self, index: int) -> str: def __setitem__(self, index: int, new_comment: str) -> None: self._comments[index] = new_comment + def __iter__(self) -> Iterator[str]: + return iter(self._comments) + def __add__(self, other: Union[str, list[str], GameNodeComment]) -> GameNodeComment: if isinstance(other, GameNodeComment): return GameNodeComment(self._comments + other._comments) @@ -543,7 +542,7 @@ def eval(self) -> Optional[chess.engine.PovScore]: Complexity is `O(n)`. """ - match = EVAL_REGEX.search(self.comment.join(" ")) + match = EVAL_REGEX.search(" ".join(self.comment)) if not match: return None @@ -569,7 +568,7 @@ def eval_depth(self) -> Optional[int]: Complexity is `O(1)`. """ - match = EVAL_REGEX.search(self.comment.join(" ")) + match = EVAL_REGEX.search(" ".join(self.comment)) return int(match.group("depth")) if match and match.group("depth") else None def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] = None) -> None: @@ -605,7 +604,7 @@ def arrows(self) -> List[chess.svg.Arrow]: Returns a list of :class:`arrows `. """ arrows = [] - for match in ARROWS_REGEX.finditer(self.comment.join(" ")): + for match in ARROWS_REGEX.finditer(" ".join(self.comment)): for group in match.group("arrows").split(","): arrows.append(chess.svg.Arrow.from_pgn(group)) @@ -649,7 +648,7 @@ def clock(self) -> Optional[float]: Returns the player's remaining time to the next time control after this move, in seconds. """ - match = CLOCK_REGEX.search(self.comment.join(" ")) + match = CLOCK_REGEX.search(" ".join(self.comment)) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -687,7 +686,7 @@ def emt(self) -> Optional[float]: Returns the player's elapsed move time use for the comment of this move, in seconds. """ - match = EMT_REGEX.search(self.comment.join(" ")) + match = EMT_REGEX.search(" ".join(self.comment)) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) From 4e695e2bc7c50066c0f84abd4206e61c917b2d03 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 28 Feb 2024 02:04:08 -0800 Subject: [PATCH 1734/1831] Add docstrings for methods Also, fix spacing. --- chess/pgn.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 0e0345a92..36cac2c59 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -190,7 +190,9 @@ class GameNodeComment: A class that can hold one or more comments for a GameNode. """ + def __init__(self, comment: Union[str, list[str]] = ""): + """Create a new comment.""" self.set(comment) def set(self, new_comment: Union[str, list[str]]) -> None: @@ -224,18 +226,23 @@ def pop(self, index: int = -1) -> None: self._comments.pop(index) def __len__(self) -> int: + """Get the number of comments in this node.""" return len(self._comments) def __getitem__(self, index: int) -> str: + """Get the comment at the given index.""" return self._comments[index] def __setitem__(self, index: int, new_comment: str) -> None: + """Change the comment at the given index.""" self._comments[index] = new_comment def __iter__(self) -> Iterator[str]: + """Return an iterator over all comments.""" return iter(self._comments) def __add__(self, other: Union[str, list[str], GameNodeComment]) -> GameNodeComment: + """Create a new comment set by adding two comment sets with +.""" if isinstance(other, GameNodeComment): return GameNodeComment(self._comments + other._comments) else: @@ -244,6 +251,7 @@ def __add__(self, other: Union[str, list[str], GameNodeComment]) -> GameNodeComm return new_node_comment def __eq__(self, other: object) -> bool: + """Check for equality between two comment sets.""" if isinstance(other, str): return (len(self) == 1 and self[0] == other) or (not self and not other) elif isinstance(other, list): @@ -254,9 +262,11 @@ def __eq__(self, other: object) -> bool: return False def __repr__(self) -> str: + """Return a code-like representation of the class.""" return f"{self.__class__.__name__}({self._comments})" def __str__(self) -> str: + """Return a string representation of the comments in PGN format.""" return self.pgn_format() @@ -290,7 +300,6 @@ def comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: else: self._comment = GameNodeComment(new_comment) - _starting_comment: GameNodeComment @property From d1dce61a45ed3784ce867ec0218d6fb3ca47e735 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 18 Apr 2024 15:53:08 +0200 Subject: [PATCH 1735/1831] Bump Sphinx to 7.3.6 --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index a63c6a7ca..7516f64de 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -Sphinx==6.1.2 +Sphinx==7.3.6 sphinxcontrib-jquery==4.1 sphinx-rtd-theme==1.3.0 From 4c7a9025e3442fb75a14eae367fd88200e210042 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 18 Apr 2024 17:40:45 +0200 Subject: [PATCH 1736/1831] Use typing_extensions.TypeAlias (#564) --- chess/__init__.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index a9328a04b..9eeb2c5e2 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -24,15 +24,19 @@ from typing import ClassVar, Callable, Counter, Dict, Generic, Hashable, Iterable, Iterator, List, Literal, Mapping, Optional, SupportsInt, Tuple, Type, TypeVar, Union +if typing.TYPE_CHECKING: + from typing_extensions import TypeAlias + + EnPassantSpec = Literal["legal", "fen", "xfen"] -Color = bool +Color: TypeAlias = bool COLORS = [WHITE, BLACK] = [True, False] ColorName = Literal["white", "black"] COLOR_NAMES: List[ColorName] = ["black", "white"] -PieceType = int +PieceType: TypeAlias = int PIECE_TYPES = [PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING] = range(1, 7) PIECE_SYMBOLS = [None, "p", "n", "b", "r", "q", "k"] PIECE_NAMES = [None, "pawn", "knight", "bishop", "rook", "queen", "king"] @@ -157,7 +161,7 @@ class AmbiguousMoveError(ValueError): """Raised when the attempted move is ambiguous in the current position""" -Square = int +Square: TypeAlias = int SQUARES = [ A1, B1, C1, D1, E1, F1, G1, H1, A2, B2, C2, D2, E2, F2, G2, H2, @@ -233,7 +237,7 @@ def square_mirror(square: Square) -> Square: SQUARES_180 = [square_mirror(sq) for sq in SQUARES] -Bitboard = int +Bitboard: TypeAlias = int BB_EMPTY = 0 BB_ALL = 0xffff_ffff_ffff_ffff @@ -3816,7 +3820,7 @@ def __repr__(self) -> str: return f"" -IntoSquareSet = Union[SupportsInt, Iterable[Square]] +IntoSquareSet: TypeAlias = Union[SupportsInt, Iterable[Square]] class SquareSet: """ From 6af0ff4c8947486e3e3fa8e83ca88815301aaa37 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 18 Apr 2024 17:59:10 +0200 Subject: [PATCH 1737/1831] Expand core constant definitions More verbose, but better IDE support --- chess/__init__.py | 234 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 175 insertions(+), 59 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 9eeb2c5e2..f9a9ab7f5 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -32,12 +32,20 @@ Color: TypeAlias = bool -COLORS = [WHITE, BLACK] = [True, False] +WHITE: Color = True +BLACK: Color = False +COLORS: List[Color] = [WHITE, BLACK] ColorName = Literal["white", "black"] COLOR_NAMES: List[ColorName] = ["black", "white"] PieceType: TypeAlias = int -PIECE_TYPES = [PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING] = range(1, 7) +PAWN: PieceType = 1 +KNIGHT: PieceType = 2 +BISHOP: PieceType = 3 +ROOK: PieceType = 4 +QUEEN: PieceType = 5 +KING: PieceType = 6 +PIECE_TYPES: List[PieceType] = [PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING] PIECE_SYMBOLS = [None, "p", "n", "b", "r", "q", "k"] PIECE_NAMES = [None, "pawn", "knight", "bishop", "rook", "queen", "king"] @@ -162,16 +170,71 @@ class AmbiguousMoveError(ValueError): Square: TypeAlias = int -SQUARES = [ - A1, B1, C1, D1, E1, F1, G1, H1, - A2, B2, C2, D2, E2, F2, G2, H2, - A3, B3, C3, D3, E3, F3, G3, H3, - A4, B4, C4, D4, E4, F4, G4, H4, - A5, B5, C5, D5, E5, F5, G5, H5, - A6, B6, C6, D6, E6, F6, G6, H6, - A7, B7, C7, D7, E7, F7, G7, H7, - A8, B8, C8, D8, E8, F8, G8, H8, -] = range(64) +A1: Square = 0 +B1: Square = 1 +C1: Square = 2 +D1: Square = 3 +E1: Square = 4 +F1: Square = 5 +G1: Square = 6 +H1: Square = 7 +A2: Square = 8 +B2: Square = 9 +C2: Square = 10 +D2: Square = 11 +E2: Square = 12 +F2: Square = 13 +G2: Square = 14 +H2: Square = 15 +A3: Square = 16 +B3: Square = 17 +C3: Square = 18 +D3: Square = 19 +E3: Square = 20 +F3: Square = 21 +G3: Square = 22 +H3: Square = 23 +A4: Square = 24 +B4: Square = 25 +C4: Square = 26 +D4: Square = 27 +E4: Square = 28 +F4: Square = 29 +G4: Square = 30 +H4: Square = 31 +A5: Square = 32 +B5: Square = 33 +C5: Square = 34 +D5: Square = 35 +E5: Square = 36 +F5: Square = 37 +G5: Square = 38 +H5: Square = 39 +A6: Square = 40 +B6: Square = 41 +C6: Square = 42 +D6: Square = 43 +E6: Square = 44 +F6: Square = 45 +G6: Square = 46 +H6: Square = 47 +A7: Square = 48 +B7: Square = 49 +C7: Square = 50 +D7: Square = 51 +E7: Square = 52 +F7: Square = 53 +G7: Square = 54 +H7: Square = 55 +A8: Square = 56 +B8: Square = 57 +C8: Square = 58 +D8: Square = 59 +E8: Square = 60 +F8: Square = 61 +G8: Square = 62 +H8: Square = 63 +SQUARES: List[Square] = list(range(64)) SQUARE_NAMES = [f + r for r in RANK_NAMES for f in FILE_NAMES] @@ -234,53 +297,106 @@ def square_mirror(square: Square) -> Square: """Mirrors the square vertically.""" return square ^ 0x38 -SQUARES_180 = [square_mirror(sq) for sq in SQUARES] +SQUARES_180: List[Square] = [square_mirror(sq) for sq in SQUARES] Bitboard: TypeAlias = int -BB_EMPTY = 0 -BB_ALL = 0xffff_ffff_ffff_ffff - -BB_SQUARES = [ - BB_A1, BB_B1, BB_C1, BB_D1, BB_E1, BB_F1, BB_G1, BB_H1, - BB_A2, BB_B2, BB_C2, BB_D2, BB_E2, BB_F2, BB_G2, BB_H2, - BB_A3, BB_B3, BB_C3, BB_D3, BB_E3, BB_F3, BB_G3, BB_H3, - BB_A4, BB_B4, BB_C4, BB_D4, BB_E4, BB_F4, BB_G4, BB_H4, - BB_A5, BB_B5, BB_C5, BB_D5, BB_E5, BB_F5, BB_G5, BB_H5, - BB_A6, BB_B6, BB_C6, BB_D6, BB_E6, BB_F6, BB_G6, BB_H6, - BB_A7, BB_B7, BB_C7, BB_D7, BB_E7, BB_F7, BB_G7, BB_H7, - BB_A8, BB_B8, BB_C8, BB_D8, BB_E8, BB_F8, BB_G8, BB_H8, -] = [1 << sq for sq in SQUARES] - -BB_CORNERS = BB_A1 | BB_H1 | BB_A8 | BB_H8 -BB_CENTER = BB_D4 | BB_E4 | BB_D5 | BB_E5 - -BB_LIGHT_SQUARES = 0x55aa_55aa_55aa_55aa -BB_DARK_SQUARES = 0xaa55_aa55_aa55_aa55 - -BB_FILES = [ - BB_FILE_A, - BB_FILE_B, - BB_FILE_C, - BB_FILE_D, - BB_FILE_E, - BB_FILE_F, - BB_FILE_G, - BB_FILE_H, -] = [0x0101_0101_0101_0101 << i for i in range(8)] - -BB_RANKS = [ - BB_RANK_1, - BB_RANK_2, - BB_RANK_3, - BB_RANK_4, - BB_RANK_5, - BB_RANK_6, - BB_RANK_7, - BB_RANK_8, -] = [0xff << (8 * i) for i in range(8)] - -BB_BACKRANKS = BB_RANK_1 | BB_RANK_8 +BB_EMPTY: Bitboard = 0 +BB_ALL: Bitboard = 0xffff_ffff_ffff_ffff + +BB_A1: Bitboard = 1 << A1 +BB_B1: Bitboard = 1 << B1 +BB_C1: Bitboard = 1 << C1 +BB_D1: Bitboard = 1 << D1 +BB_E1: Bitboard = 1 << E1 +BB_F1: Bitboard = 1 << F1 +BB_G1: Bitboard = 1 << G1 +BB_H1: Bitboard = 1 << H1 +BB_A2: Bitboard = 1 << A2 +BB_B2: Bitboard = 1 << B2 +BB_C2: Bitboard = 1 << C2 +BB_D2: Bitboard = 1 << D2 +BB_E2: Bitboard = 1 << E2 +BB_F2: Bitboard = 1 << F2 +BB_G2: Bitboard = 1 << G2 +BB_H2: Bitboard = 1 << H2 +BB_A3: Bitboard = 1 << A3 +BB_B3: Bitboard = 1 << B3 +BB_C3: Bitboard = 1 << C3 +BB_D3: Bitboard = 1 << D3 +BB_E3: Bitboard = 1 << E3 +BB_F3: Bitboard = 1 << F3 +BB_G3: Bitboard = 1 << G3 +BB_H3: Bitboard = 1 << H3 +BB_A4: Bitboard = 1 << A4 +BB_B4: Bitboard = 1 << B4 +BB_C4: Bitboard = 1 << C4 +BB_D4: Bitboard = 1 << D4 +BB_E4: Bitboard = 1 << E4 +BB_F4: Bitboard = 1 << F4 +BB_G4: Bitboard = 1 << G4 +BB_H4: Bitboard = 1 << H4 +BB_A5: Bitboard = 1 << A5 +BB_B5: Bitboard = 1 << B5 +BB_C5: Bitboard = 1 << C5 +BB_D5: Bitboard = 1 << D5 +BB_E5: Bitboard = 1 << E5 +BB_F5: Bitboard = 1 << F5 +BB_G5: Bitboard = 1 << G5 +BB_H5: Bitboard = 1 << H5 +BB_A6: Bitboard = 1 << A6 +BB_B6: Bitboard = 1 << B6 +BB_C6: Bitboard = 1 << C6 +BB_D6: Bitboard = 1 << D6 +BB_E6: Bitboard = 1 << E6 +BB_F6: Bitboard = 1 << F6 +BB_G6: Bitboard = 1 << G6 +BB_H6: Bitboard = 1 << H6 +BB_A7: Bitboard = 1 << A7 +BB_B7: Bitboard = 1 << B7 +BB_C7: Bitboard = 1 << C7 +BB_D7: Bitboard = 1 << D7 +BB_E7: Bitboard = 1 << E7 +BB_F7: Bitboard = 1 << F7 +BB_G7: Bitboard = 1 << G7 +BB_H7: Bitboard = 1 << H7 +BB_A8: Bitboard = 1 << A8 +BB_B8: Bitboard = 1 << B8 +BB_C8: Bitboard = 1 << C8 +BB_D8: Bitboard = 1 << D8 +BB_E8: Bitboard = 1 << E8 +BB_F8: Bitboard = 1 << F8 +BB_G8: Bitboard = 1 << G8 +BB_H8: Bitboard = 1 << H8 +BB_SQUARES: List[Bitboard] = [1 << sq for sq in SQUARES] + +BB_CORNERS: Bitboard = BB_A1 | BB_H1 | BB_A8 | BB_H8 +BB_CENTER: Bitboard = BB_D4 | BB_E4 | BB_D5 | BB_E5 + +BB_LIGHT_SQUARES: Bitboard = 0x55aa_55aa_55aa_55aa +BB_DARK_SQUARES: Bitboard = 0xaa55_aa55_aa55_aa55 + +BB_FILE_A: Bitboard = 0x0101_0101_0101_0101 << 0 +BB_FILE_B: Bitboard = 0x0101_0101_0101_0101 << 1 +BB_FILE_C: Bitboard = 0x0101_0101_0101_0101 << 2 +BB_FILE_D: Bitboard = 0x0101_0101_0101_0101 << 3 +BB_FILE_E: Bitboard = 0x0101_0101_0101_0101 << 4 +BB_FILE_F: Bitboard = 0x0101_0101_0101_0101 << 5 +BB_FILE_G: Bitboard = 0x0101_0101_0101_0101 << 6 +BB_FILE_H: Bitboard = 0x0101_0101_0101_0101 << 7 +BB_FILES: List[Bitboard] = [BB_FILE_A, BB_FILE_B, BB_FILE_C, BB_FILE_D, BB_FILE_E, BB_FILE_F, BB_FILE_G, BB_FILE_H] + +BB_RANK_1: Bitboard = 0xff << (8 * 0) +BB_RANK_2: Bitboard = 0xff << (8 * 1) +BB_RANK_3: Bitboard = 0xff << (8 * 2) +BB_RANK_4: Bitboard = 0xff << (8 * 3) +BB_RANK_5: Bitboard = 0xff << (8 * 4) +BB_RANK_6: Bitboard = 0xff << (8 * 5) +BB_RANK_7: Bitboard = 0xff << (8 * 6) +BB_RANK_8: Bitboard = 0xff << (8 * 7) +BB_RANKS: List[Bitboard] = [BB_RANK_1, BB_RANK_2, BB_RANK_3, BB_RANK_4, BB_RANK_5, BB_RANK_6, BB_RANK_7, BB_RANK_8] + +BB_BACKRANKS: Bitboard = BB_RANK_1 | BB_RANK_8 def lsb(bb: Bitboard) -> int: @@ -397,9 +513,9 @@ def _sliding_attacks(square: Square, occupied: Bitboard, deltas: Iterable[int]) def _step_attacks(square: Square, deltas: Iterable[int]) -> Bitboard: return _sliding_attacks(square, BB_ALL, deltas) -BB_KNIGHT_ATTACKS = [_step_attacks(sq, [17, 15, 10, 6, -17, -15, -10, -6]) for sq in SQUARES] -BB_KING_ATTACKS = [_step_attacks(sq, [9, 8, 7, 1, -9, -8, -7, -1]) for sq in SQUARES] -BB_PAWN_ATTACKS = [[_step_attacks(sq, deltas) for sq in SQUARES] for deltas in [[-7, -9], [7, 9]]] +BB_KNIGHT_ATTACKS: List[Bitboard] = [_step_attacks(sq, [17, 15, 10, 6, -17, -15, -10, -6]) for sq in SQUARES] +BB_KING_ATTACKS: List[Bitboard] = [_step_attacks(sq, [9, 8, 7, 1, -9, -8, -7, -1]) for sq in SQUARES] +BB_PAWN_ATTACKS: List[List[Bitboard]] = [[_step_attacks(sq, deltas) for sq in SQUARES] for deltas in [[-7, -9], [7, 9]]] def _edges(square: Square) -> Bitboard: From 90d81da2416bf8e3f4ffdbdd70e6105fea8607b4 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 20 Apr 2024 21:04:40 -0700 Subject: [PATCH 1738/1831] Restore previous behavior of GameNode.comment GameNode.comment now returns all comments as a single string with single spaces separating the comments. GameNode.comments (plural) returns all comments as a list of strings. --- chess/pgn.py | 90 +++++++++++++++++++++++++++++++--------------------- test.py | 43 +++++++++++++++---------- 2 files changed, 80 insertions(+), 53 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 36cac2c59..50984a64d 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -290,8 +290,8 @@ class GameNode(abc.ABC): """ @property - def comment(self) -> GameNodeComment: - return self._comment + def comment(self) -> str: + return " ".join(self._comment) @comment.setter def comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: @@ -300,11 +300,19 @@ def comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: else: self._comment = GameNodeComment(new_comment) + @property + def comments(self) -> GameNodeComment: + return self._comment + + @comments.setter + def comments(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: + self.comment = new_comment + _starting_comment: GameNodeComment @property - def starting_comment(self) -> GameNodeComment: - return self._starting_comment + def starting_comment(self) -> str: + return " ".join(self._starting_comment) @starting_comment.setter def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: @@ -313,6 +321,14 @@ def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) else: self._starting_comment = GameNodeComment(new_comment) + @property + def starting_comments(self) -> GameNodeComment: + return self._starting_comment + + @starting_comments.setter + def starting_comments(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: + self._starting_comment = new_comment + nags: Set[int] def __init__(self, *, comment: Union[str, list[str]] = "") -> None: @@ -539,7 +555,7 @@ def add_line(self, moves: Iterable[chess.Move], *, comment: Union[str, list[str] starting_comment = "" # Merge comment and NAGs. - node.comment.append(comment) + node.comments.append(comment) node.nags.update(nags) return node @@ -551,7 +567,7 @@ def eval(self) -> Optional[chess.engine.PovScore]: Complexity is `O(n)`. """ - match = EVAL_REGEX.search(" ".join(self.comment)) + match = EVAL_REGEX.search(self.comment) if not match: return None @@ -577,7 +593,7 @@ def eval_depth(self) -> Optional[int]: Complexity is `O(1)`. """ - match = EVAL_REGEX.search(" ".join(self.comment)) + match = EVAL_REGEX.search(self.comment) return int(match.group("depth")) if match and match.group("depth") else None def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] = None) -> None: @@ -595,15 +611,15 @@ def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] eval = f"[%eval #{score.white().mate()}{depth_suffix}]" found = 0 - for index in range(len(self.comment)): - self.comment[index], found = EVAL_REGEX.subn(_condense_affix(eval), self.comment[index], count=1) + for index in range(len(self.comments)): + self.comments[index], found = EVAL_REGEX.subn(_condense_affix(eval), self.comments[index], count=1) if found: break - self.comment.remove_empty() + self.comments.remove_empty() if not found and eval: - self.comment.append(eval) + self.comments.append(eval) def arrows(self) -> List[chess.svg.Arrow]: """ @@ -613,7 +629,7 @@ def arrows(self) -> List[chess.svg.Arrow]: Returns a list of :class:`arrows `. """ arrows = [] - for match in ARROWS_REGEX.finditer(" ".join(self.comment)): + for match in ARROWS_REGEX.finditer(self.comment): for group in match.group("arrows").split(","): arrows.append(chess.svg.Arrow.from_pgn(group)) @@ -635,10 +651,10 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar pass (csl if arrow.tail == arrow.head else cal).append(arrow.pgn()) # type: ignore - for index in range(len(self.comment)): - self.comment[index] = ARROWS_REGEX.sub(_condense_affix(""), self.comment[index]) + for index in range(len(self.comments)): + self.comments[index] = ARROWS_REGEX.sub(_condense_affix(""), self.comments[index]) - self.comment.remove_empty() + self.comments.remove_empty() prefix = "" if csl: @@ -647,7 +663,7 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar prefix += f"[%cal {','.join(cal)}]" if prefix: - self.comment.insert(0, prefix) + self.comments.insert(0, prefix) def clock(self) -> Optional[float]: """ @@ -657,7 +673,7 @@ def clock(self) -> Optional[float]: Returns the player's remaining time to the next time control after this move, in seconds. """ - match = CLOCK_REGEX.search(" ".join(self.comment)) + match = CLOCK_REGEX.search(self.comment) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -677,15 +693,15 @@ def set_clock(self, seconds: Optional[float]) -> None: clk = f"[%clk {hours:d}:{minutes:02d}:{seconds_part}]" found = 0 - for index in range(len(self.comment)): - self.comment[index], found = CLOCK_REGEX.subn(_condense_affix(clk), self.comment[index], count=1) + for index in range(len(self.comments)): + self.comments[index], found = CLOCK_REGEX.subn(_condense_affix(clk), self.comments[index], count=1) if found: break - self.comment.remove_empty() + self.comments.remove_empty() if not found and clk: - self.comment.append(clk) + self.comments.append(clk) def emt(self) -> Optional[float]: """ @@ -695,7 +711,7 @@ def emt(self) -> Optional[float]: Returns the player's elapsed move time use for the comment of this move, in seconds. """ - match = EMT_REGEX.search(" ".join(self.comment)) + match = EMT_REGEX.search(" ".join(self.comments)) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -715,15 +731,15 @@ def set_emt(self, seconds: Optional[float]) -> None: emt = f"[%emt {hours:d}:{minutes:02d}:{seconds_part}]" found = 0 - for index in range(len(self.comment)): - self.comment[index], found = EMT_REGEX.subn(_condense_affix(emt), self.comment[index], count=1) + for index in range(len(self.comments)): + self.comments[index], found = EMT_REGEX.subn(_condense_affix(emt), self.comments[index], count=1) if found: break - self.comment.remove_empty() + self.comments.remove_empty() if not found and emt: - self.comment.append(emt) + self.comments.append(emt) @abc.abstractmethod def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: @@ -868,7 +884,7 @@ def end(self) -> ChildNode: def _accept_node(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT]) -> None: if self.starting_comment: - visitor.visit_comment(self.starting_comment) + visitor.visit_comment(self.starting_comments) visitor.visit_move(parent_board, self.move) @@ -879,8 +895,8 @@ def _accept_node(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT]) for nag in sorted(self.nags): visitor.visit_nag(nag) - if self.comment: - visitor.visit_comment(self.comment) + if self.comments: + visitor.visit_comment(self.comments) def _accept(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT], *, sidelines: bool = True) -> None: stack = [_AcceptFrame(self, sidelines=sidelines)] @@ -1011,8 +1027,8 @@ def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: board = self.board() visitor.visit_board(board) - if self.comment: - visitor.visit_comment(self.comment) + if self.comments: + visitor.visit_comment(self.comments) if self.variations: self.variations[0]._accept(board, visitor) @@ -1347,14 +1363,14 @@ def visit_comment(self, comment: GameNodeComment) -> None: # Add as a comment for the current node if in the middle of # a variation. Add as a comment for the game if the comment # starts before any move. - new_comment = self.variation_stack[-1].comment + comment - new_comment.remove_empty() - self.variation_stack[-1].comment = new_comment + new_comments = self.variation_stack[-1].comments + comment + new_comments.remove_empty() + self.variation_stack[-1].comments = new_comments else: # Otherwise, it is a starting comment. - new_comment = self.starting_comment + comment - new_comment.remove_empty() - self.starting_comment = new_comment + new_comments = self.starting_comment + comment + new_comments.remove_empty() + self.starting_comment = new_comments def visit_move(self, board: chess.Board, move: chess.Move) -> None: self.variation_stack[-1] = self.variation_stack[-1].add_variation(move) diff --git a/test.py b/test.py index ee770de0f..aa89cd2c5 100755 --- a/test.py +++ b/test.py @@ -2220,19 +2220,24 @@ def test_read_game_with_multicomment_move(self): game = chess.pgn.read_game(pgn) first_move = game.variation(0) self.assertEqual(first_move.comment, "A common opening") + self.assertEqual(first_move.comments, "A common opening") + self.assertEqual(first_move.comments, ["A common opening"]) second_move = first_move.variation(0) - self.assertEqual(second_move.comment, ["A common response", "An uncommon comment"]) - second_move.comment.pop() - self.assertEqual(second_move.comment, ["A common response"]) + self.assertEqual(second_move.comments, ["A common response", "An uncommon comment"]) + second_move.comments.pop() + self.assertEqual(second_move.comments, ["A common response"]) + self.assertEqual(second_move.comments, "A common response") self.assertEqual(second_move.comment, "A common response") - second_move.comment.append("A replaced comment") + second_move.comments.append("A replaced comment") multiple_comments = ["A common response", "A replaced comment"] - self.assertEqual(second_move.comment, multiple_comments) - for move_comment, test_comment in zip(second_move.comment, multiple_comments): + self.assertEqual(second_move.comments, multiple_comments) + for move_comment, test_comment in zip(second_move.comments, multiple_comments): self.assertEqual(move_comment, test_comment) - self.assertEqual(list(second_move.comment), multiple_comments) - second_move.comment.pop(0) - self.assertEqual(second_move.comment, ["A replaced comment"]) + self.assertEqual(list(second_move.comments), multiple_comments) + self.assertEqual(second_move.comment, " ".join(multiple_comments)) + second_move.comments.pop(0) + self.assertEqual(second_move.comments, ["A replaced comment"]) + self.assertEqual(second_move.comments, "A replaced comment") self.assertEqual(second_move.comment, "A replaced comment") def test_comment_at_eol(self): @@ -2845,22 +2850,24 @@ def test_annotations(self): self.assertTrue(game.clock() is None) clock = 12345 game.set_clock(clock) - self.assertEqual(game.comment, ["foo [%bar] baz", "[%clk 3:25:45]"]) + self.assertEqual(game.comment, "foo [%bar] baz [%clk 3:25:45]") + self.assertEqual(game.comments, ["foo [%bar] baz", "[%clk 3:25:45]"]) self.assertEqual(game.clock(), clock) self.assertTrue(game.eval() is None) game.set_eval(chess.engine.PovScore(chess.engine.Cp(-80), chess.WHITE)) - self.assertEqual(game.comment, ["foo [%bar] baz", "[%clk 3:25:45]", "[%eval -0.80]"]) + self.assertEqual(game.comments, ["foo [%bar] baz", "[%clk 3:25:45]", "[%eval -0.80]"]) self.assertEqual(game.eval().white().score(), -80) self.assertEqual(game.eval_depth(), None) game.set_eval(chess.engine.PovScore(chess.engine.Mate(1), chess.WHITE), 5) - self.assertEqual(game.comment, ["foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]"]) + self.assertEqual(game.comments, ["foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]"]) self.assertEqual(game.eval().white().mate(), 1) self.assertEqual(game.eval_depth(), 5) self.assertEqual(game.arrows(), []) game.set_arrows([(chess.A1, chess.A1), chess.svg.Arrow(chess.A1, chess.H1, color="red"), chess.svg.Arrow(chess.B1, chess.B8)]) - self.assertEqual(game.comment, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]"]) + self.assertEqual(game.comments, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]"]) + self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5]") arrows = game.arrows() self.assertEqual(len(arrows), 3) self.assertEqual(arrows[0].color, "green") @@ -2870,17 +2877,21 @@ def test_annotations(self): self.assertTrue(game.emt() is None) emt = 321 game.set_emt(emt) - self.assertEqual(game.comment, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]", "[%emt 0:05:21]"]) + self.assertEqual(game.comments, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]", "[%emt 0:05:21]"]) + self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5] [%emt 0:05:21]") self.assertEqual(game.emt(), emt) game.set_eval(None) - self.assertEqual(game.comment, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%emt 0:05:21]"]) + self.assertEqual(game.comments, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%emt 0:05:21]"]) + self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%emt 0:05:21]") game.set_emt(None) - self.assertEqual(game.comment, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]"]) + self.assertEqual(game.comments, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]"]) + self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45]") game.set_clock(None) game.set_arrows([]) + self.assertEqual(game.comments, "foo [%bar] baz") self.assertEqual(game.comment, "foo [%bar] baz") def test_eval(self): From 2761d7c2b129bb5c88b3ff59c2dbbc792863b172 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 20 Apr 2024 21:16:52 -0700 Subject: [PATCH 1739/1831] Fix typing errors --- chess/pgn.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 50984a64d..c70c47bc2 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -306,7 +306,10 @@ def comments(self) -> GameNodeComment: @comments.setter def comments(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - self.comment = new_comment + if isinstance(new_comment, GameNodeComment): + self._comment = new_comment + else: + self._comment = GameNodeComment(new_comment) _starting_comment: GameNodeComment @@ -327,7 +330,10 @@ def starting_comments(self) -> GameNodeComment: @starting_comments.setter def starting_comments(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - self._starting_comment = new_comment + if isinstance(new_comment, GameNodeComment): + self._starting_comment = new_comment + else: + self._starting_comment = GameNodeComment(new_comment) nags: Set[int] @@ -335,11 +341,11 @@ def __init__(self, *, comment: Union[str, list[str]] = "") -> None: self.parent = None self.move = None self.variations = [] - self.comment = GameNodeComment(comment) + self.comments = GameNodeComment(comment) # Deprecated: These should be properties of ChildNode, but need to # remain here for backwards compatibility. - self.starting_comment = GameNodeComment() + self.starting_comments = GameNodeComment() self.nags = set() @abc.abstractmethod @@ -804,8 +810,8 @@ class ChildNode(GameNode): """ @property - def starting_comment(self) -> GameNodeComment: - return self._starting_comment + def starting_comment(self) -> str: + return " ".join(self._starting_comment) @starting_comment.setter def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: @@ -827,7 +833,7 @@ def __init__(self, parent: GameNode, move: chess.Move, *, comment: Union[str, li self.parent.variations.append(self) self.nags.update(nags) - self.starting_comment = GameNodeComment(starting_comment) + self.starting_comments = GameNodeComment(starting_comment) def board(self) -> chess.Board: stack: List[chess.Move] = [] @@ -1374,7 +1380,7 @@ def visit_comment(self, comment: GameNodeComment) -> None: def visit_move(self, board: chess.Board, move: chess.Move) -> None: self.variation_stack[-1] = self.variation_stack[-1].add_variation(move) - self.variation_stack[-1].starting_comment = self.starting_comment + self.variation_stack[-1].starting_comments = self.starting_comment self.starting_comment = GameNodeComment() self.in_variation = True From f0baba73ba034d48cb734bf4c0848417396a633f Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sat, 20 Apr 2024 21:22:56 -0700 Subject: [PATCH 1740/1831] Consolidate repeated logic --- chess/pgn.py | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index c70c47bc2..6ff13fd7e 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -191,9 +191,9 @@ class GameNodeComment: A class that can hold one or more comments for a GameNode. """ - def __init__(self, comment: Union[str, list[str]] = ""): + def __init__(self, comment: Union[str, list[str], GameNodeComment] = ""): """Create a new comment.""" - self.set(comment) + self.set(comment._comments if isinstance(comment,GameNodeComment) else comment) def set(self, new_comment: Union[str, list[str]]) -> None: """Replace the comment with a new comment or a list of comments.""" @@ -295,10 +295,7 @@ def comment(self) -> str: @comment.setter def comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - if isinstance(new_comment, GameNodeComment): - self._comment = new_comment - else: - self._comment = GameNodeComment(new_comment) + self._comment = GameNodeComment(new_comment) @property def comments(self) -> GameNodeComment: @@ -306,10 +303,7 @@ def comments(self) -> GameNodeComment: @comments.setter def comments(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - if isinstance(new_comment, GameNodeComment): - self._comment = new_comment - else: - self._comment = GameNodeComment(new_comment) + self._comment = GameNodeComment(new_comment) _starting_comment: GameNodeComment @@ -319,10 +313,7 @@ def starting_comment(self) -> str: @starting_comment.setter def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - if isinstance(new_comment, GameNodeComment): - self._starting_comment = new_comment - else: - self._starting_comment = GameNodeComment(new_comment) + self._starting_comment = GameNodeComment(new_comment) @property def starting_comments(self) -> GameNodeComment: @@ -330,10 +321,7 @@ def starting_comments(self) -> GameNodeComment: @starting_comments.setter def starting_comments(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - if isinstance(new_comment, GameNodeComment): - self._starting_comment = new_comment - else: - self._starting_comment = GameNodeComment(new_comment) + self._starting_comment = GameNodeComment(new_comment) nags: Set[int] @@ -815,10 +803,7 @@ def starting_comment(self) -> str: @starting_comment.setter def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - if isinstance(new_comment, GameNodeComment): - self._starting_comment = new_comment - else: - self._starting_comment = GameNodeComment(new_comment) + self._starting_comment = GameNodeComment(new_comment) nags: Set[int] """ From f840f8e58e635d89ba810ffa08cb0f81d4925f79 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 21 Apr 2024 19:27:56 -0700 Subject: [PATCH 1741/1831] Revert unneeded code change --- chess/pgn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index 6ff13fd7e..e462a0750 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -705,7 +705,7 @@ def emt(self) -> Optional[float]: Returns the player's elapsed move time use for the comment of this move, in seconds. """ - match = EMT_REGEX.search(" ".join(self.comments)) + match = EMT_REGEX.search(self.comment) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) From 716a0b9459480b852b5169a0f1b0b3dbecd3be31 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 4 May 2024 17:44:20 +0200 Subject: [PATCH 1742/1831] Require that EPD opcodes start with letter (fixes #1080) --- chess/__init__.py | 16 +++++++++++++--- test.py | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index f9a9ab7f5..bed9eec5d 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -2739,9 +2739,7 @@ def _epd_operations(self, operations: Mapping[str, Union[None, str, int, float, first_op = True for opcode, operand in operations.items(): - assert opcode != "-", "dash (-) is not a valid epd opcode" - for blacklisted in [" ", "\n", "\t", "\r"]: - assert blacklisted not in opcode, f"invalid character {blacklisted!r} in epd opcode: {opcode!r}" + self._validate_epd_opcode(opcode) if not first_op: epd.append(" ") @@ -2819,6 +2817,17 @@ def epd(self, *, shredder: bool = False, en_passant: EnPassantSpec = "legal", pr return " ".join(epd) + def _validate_epd_opcode(self, opcode: str) -> None: + if not opcode: + raise ValueError("empty string is not a valid epd opcode") + if opcode == "-": + raise ValueError("dash (-) is not a valid epd opcode") + if not opcode[0].isalpha(): + raise ValueError(f"expected epd opcode to start with a letter, got: {opcode!r}") + for blacklisted in [" ", "\n", "\t", "\r"]: + if blacklisted in opcode: + raise ValueError(f"invalid character {blacklisted!r} in epd opcode: {opcode!r}") + def _parse_epd_ops(self: BoardT, operation_part: str, make_board: Callable[[], BoardT]) -> Dict[str, Union[None, str, int, float, Move, List[Move]]]: operations: Dict[str, Union[None, str, int, float, Move, List[Move]]] = {} state = "opcode" @@ -2832,6 +2841,7 @@ def _parse_epd_ops(self: BoardT, operation_part: str, make_board: Callable[[], B if opcode == "-": opcode = "" elif opcode: + self._validate_epd_opcode(opcode) state = "after_opcode" elif ch is None or ch == ";": if opcode == "-": diff --git a/test.py b/test.py index 8dbc95a25..4ca3be6c2 100755 --- a/test.py +++ b/test.py @@ -1143,6 +1143,11 @@ def test_eret_epd(self): self.assertEqual(ops["id"], "ERET 001 - Entlastung") self.assertEqual(ops["bm"], [chess.Move.from_uci("f1f4")]) + def test_set_fen_as_epd(self): + board = chess.Board() + with self.assertRaises(ValueError): + board.set_epd(board.fen()) # Move numbers are not valid opcodes + def test_null_moves(self): self.assertEqual(str(chess.Move.null()), "0000") self.assertEqual(chess.Move.null().uci(), "0000") From df714e39a559135c51228cca6a7cb5c716756ee3 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 4 May 2024 17:59:31 +0200 Subject: [PATCH 1743/1831] Fixup invalid EPDs in chess960.perft file --- examples/perft/chess960.perft | 1920 ++++++++++++++++----------------- 1 file changed, 960 insertions(+), 960 deletions(-) diff --git a/examples/perft/chess960.perft b/examples/perft/chess960.perft index 76be26eed..12276f256 100644 --- a/examples/perft/chess960.perft +++ b/examples/perft/chess960.perft @@ -2,7 +2,7 @@ # https://github.com/AndyGrant/Ethereal/blob/master/src/perft/fischer.epd id 0 -epd bqnb1rkr/pp3ppp/3ppn2/2p5/5P2/P2P4/NPP1P1PP/BQ1BNRKR w HFhf - 2 9 +epd bqnb1rkr/pp3ppp/3ppn2/2p5/5P2/P2P4/NPP1P1PP/BQ1BNRKR w HFhf - perft 1 21 perft 2 528 perft 3 12189 @@ -11,7 +11,7 @@ perft 5 8146062 perft 6 227689589 id 1 -epd 2nnrbkr/p1qppppp/8/1ppb4/6PP/3PP3/PPP2P2/BQNNRBKR w HEhe - 1 9 +epd 2nnrbkr/p1qppppp/8/1ppb4/6PP/3PP3/PPP2P2/BQNNRBKR w HEhe - perft 1 21 perft 2 807 perft 3 18002 @@ -20,7 +20,7 @@ perft 5 16253601 perft 6 590751109 id 2 -epd b1q1rrkb/pppppppp/3nn3/8/P7/1PPP4/4PPPP/BQNNRKRB w GE - 1 9 +epd b1q1rrkb/pppppppp/3nn3/8/P7/1PPP4/4PPPP/BQNNRKRB w GE - perft 1 20 perft 2 479 perft 3 10471 @@ -29,7 +29,7 @@ perft 5 6417013 perft 6 177654692 id 3 -epd qbbnnrkr/2pp2pp/p7/1p2pp2/8/P3PP2/1PPP1KPP/QBBNNR1R w hf - 0 9 +epd qbbnnrkr/2pp2pp/p7/1p2pp2/8/P3PP2/1PPP1KPP/QBBNNR1R w hf - perft 1 22 perft 2 593 perft 3 13440 @@ -38,7 +38,7 @@ perft 5 9183776 perft 6 274103539 id 4 -epd 1nbbnrkr/p1p1ppp1/3p4/1p3P1p/3Pq2P/8/PPP1P1P1/QNBBNRKR w HFhf - 0 9 +epd 1nbbnrkr/p1p1ppp1/3p4/1p3P1p/3Pq2P/8/PPP1P1P1/QNBBNRKR w HFhf - perft 1 28 perft 2 1120 perft 3 31058 @@ -47,7 +47,7 @@ perft 5 34030312 perft 6 1250970898 id 5 -epd qnbnr1kr/ppp1b1pp/4p3/3p1p2/8/2NPP3/PPP1BPPP/QNB1R1KR w HEhe - 1 9 +epd qnbnr1kr/ppp1b1pp/4p3/3p1p2/8/2NPP3/PPP1BPPP/QNB1R1KR w HEhe - perft 1 29 perft 2 899 perft 3 26578 @@ -56,7 +56,7 @@ perft 5 24851983 perft 6 775718317 id 6 -epd q1bnrkr1/ppppp2p/2n2p2/4b1p1/2NP4/8/PPP1PPPP/QNB1RRKB w ge - 1 9 +epd q1bnrkr1/ppppp2p/2n2p2/4b1p1/2NP4/8/PPP1PPPP/QNB1RRKB w ge - perft 1 30 perft 2 860 perft 3 24566 @@ -65,7 +65,7 @@ perft 5 21093346 perft 6 649209803 id 7 -epd qbn1brkr/ppp1p1p1/2n4p/3p1p2/P7/6PP/QPPPPP2/1BNNBRKR w HFhf - 0 9 +epd qbn1brkr/ppp1p1p1/2n4p/3p1p2/P7/6PP/QPPPPP2/1BNNBRKR w HFhf - perft 1 25 perft 2 635 perft 3 17054 @@ -74,7 +74,7 @@ perft 5 13203304 perft 6 377184252 id 8 -epd qnnbbrkr/1p2ppp1/2pp3p/p7/1P5P/2NP4/P1P1PPP1/Q1NBBRKR w HFhf - 0 9 +epd qnnbbrkr/1p2ppp1/2pp3p/p7/1P5P/2NP4/P1P1PPP1/Q1NBBRKR w HFhf - perft 1 24 perft 2 572 perft 3 15243 @@ -83,7 +83,7 @@ perft 5 11110203 perft 6 293989890 id 9 -epd qn1rbbkr/ppp2p1p/1n1pp1p1/8/3P4/P6P/1PP1PPPK/QNNRBB1R w hd - 2 9 +epd qn1rbbkr/ppp2p1p/1n1pp1p1/8/3P4/P6P/1PP1PPPK/QNNRBB1R w hd - perft 1 28 perft 2 811 perft 3 23175 @@ -92,7 +92,7 @@ perft 5 19836606 perft 6 594527992 id 10 -epd qnr1bkrb/pppp2pp/3np3/5p2/8/P2P2P1/NPP1PP1P/QN1RBKRB w GDg - 3 9 +epd qnr1bkrb/pppp2pp/3np3/5p2/8/P2P2P1/NPP1PP1P/QN1RBKRB w GDg - perft 1 33 perft 2 823 perft 3 26895 @@ -101,7 +101,7 @@ perft 5 23114629 perft 6 646390782 id 11 -epd qb1nrkbr/1pppp1p1/1n3p2/p1B4p/8/3P1P1P/PPP1P1P1/QBNNRK1R w HEhe - 0 9 +epd qb1nrkbr/1pppp1p1/1n3p2/p1B4p/8/3P1P1P/PPP1P1P1/QBNNRK1R w HEhe - perft 1 31 perft 2 855 perft 3 25620 @@ -110,7 +110,7 @@ perft 5 21796206 perft 6 651054626 id 12 -epd qnnbrk1r/1p1ppbpp/2p5/p4p2/2NP3P/8/PPP1PPP1/Q1NBRKBR w HEhe - 0 9 +epd qnnbrk1r/1p1ppbpp/2p5/p4p2/2NP3P/8/PPP1PPP1/Q1NBRKBR w HEhe - perft 1 26 perft 2 790 perft 3 21238 @@ -119,7 +119,7 @@ perft 5 17819770 perft 6 544866674 id 13 -epd 1qnrkbbr/1pppppp1/p1n4p/8/P7/1P1N1P2/2PPP1PP/QN1RKBBR w HDhd - 0 9 +epd 1qnrkbbr/1pppppp1/p1n4p/8/P7/1P1N1P2/2PPP1PP/QN1RKBBR w HDhd - perft 1 37 perft 2 883 perft 3 32187 @@ -128,7 +128,7 @@ perft 5 29370838 perft 6 783201510 id 14 -epd qn1rkrbb/pp1p1ppp/2p1p3/3n4/4P2P/2NP4/PPP2PP1/Q1NRKRBB w FDfd - 1 9 +epd qn1rkrbb/pp1p1ppp/2p1p3/3n4/4P2P/2NP4/PPP2PP1/Q1NRKRBB w FDfd - perft 1 24 perft 2 585 perft 3 14769 @@ -137,7 +137,7 @@ perft 5 9482310 perft 6 233468620 id 15 -epd bb1qnrkr/pp1p1pp1/1np1p3/4N2p/8/1P4P1/P1PPPP1P/BBNQ1RKR w HFhf - 0 9 +epd bb1qnrkr/pp1p1pp1/1np1p3/4N2p/8/1P4P1/P1PPPP1P/BBNQ1RKR w HFhf - perft 1 29 perft 2 864 perft 3 25747 @@ -146,7 +146,7 @@ perft 5 24219627 perft 6 776836316 id 16 -epd bnqbnr1r/p1p1ppkp/3p4/1p4p1/P7/3NP2P/1PPP1PP1/BNQB1RKR w HF - 0 9 +epd bnqbnr1r/p1p1ppkp/3p4/1p4p1/P7/3NP2P/1PPP1PP1/BNQB1RKR w HF - perft 1 26 perft 2 889 perft 3 24353 @@ -155,7 +155,7 @@ perft 5 23701014 perft 6 809194268 id 17 -epd bnqnrbkr/1pp2pp1/p7/3pP2p/4P1P1/8/PPPP3P/BNQNRBKR w HEhe d6 0 9 +epd bnqnrbkr/1pp2pp1/p7/3pP2p/4P1P1/8/PPPP3P/BNQNRBKR w HEhe d6 perft 1 31 perft 2 984 perft 3 28677 @@ -164,7 +164,7 @@ perft 5 29032175 perft 6 1008880643 id 18 -epd b1qnrrkb/ppp1pp1p/n2p1Pp1/8/8/P7/1PPPP1PP/BNQNRKRB w GE - 0 9 +epd b1qnrrkb/ppp1pp1p/n2p1Pp1/8/8/P7/1PPPP1PP/BNQNRKRB w GE - perft 1 20 perft 2 484 perft 3 10532 @@ -173,7 +173,7 @@ perft 5 6718715 perft 6 193594729 id 19 -epd n1bqnrkr/pp1ppp1p/2p5/6p1/2P2b2/PN6/1PNPPPPP/1BBQ1RKR w HFhf - 2 9 +epd n1bqnrkr/pp1ppp1p/2p5/6p1/2P2b2/PN6/1PNPPPPP/1BBQ1RKR w HFhf - perft 1 23 perft 2 732 perft 3 17746 @@ -182,7 +182,7 @@ perft 5 14481581 perft 6 457140569 id 20 -epd n1bb1rkr/qpnppppp/2p5/p7/P1P5/5P2/1P1PPRPP/NQBBN1KR w Hhf - 1 9 +epd n1bb1rkr/qpnppppp/2p5/p7/P1P5/5P2/1P1PPRPP/NQBBN1KR w Hhf - perft 1 27 perft 2 697 perft 3 18724 @@ -191,7 +191,7 @@ perft 5 14226907 perft 6 400942568 id 21 -epd nqb1rbkr/pppppp1p/4n3/6p1/4P3/1NP4P/PP1P1PP1/1QBNRBKR w HEhe - 1 9 +epd nqb1rbkr/pppppp1p/4n3/6p1/4P3/1NP4P/PP1P1PP1/1QBNRBKR w HEhe - perft 1 28 perft 2 641 perft 3 18811 @@ -200,7 +200,7 @@ perft 5 13780398 perft 6 354122358 id 22 -epd n1bnrrkb/pp1pp2p/2p2p2/6p1/5B2/3P4/PPP1PPPP/NQ1NRKRB w GE - 2 9 +epd n1bnrrkb/pp1pp2p/2p2p2/6p1/5B2/3P4/PPP1PPPP/NQ1NRKRB w GE - perft 1 28 perft 2 606 perft 3 16883 @@ -209,7 +209,7 @@ perft 5 10815324 perft 6 254026570 id 23 -epd nbqnbrkr/2ppp1p1/pp3p1p/8/4N2P/1N6/PPPPPPP1/1BQ1BRKR w HFhf - 0 9 +epd nbqnbrkr/2ppp1p1/pp3p1p/8/4N2P/1N6/PPPPPPP1/1BQ1BRKR w HFhf - perft 1 26 perft 2 626 perft 3 17268 @@ -218,7 +218,7 @@ perft 5 12719546 perft 6 339132046 id 24 -epd nq1bbrkr/pp2nppp/2pp4/4p3/1PP1P3/1B6/P2P1PPP/NQN1BRKR w HFhf - 2 9 +epd nq1bbrkr/pp2nppp/2pp4/4p3/1PP1P3/1B6/P2P1PPP/NQN1BRKR w HFhf - perft 1 21 perft 2 504 perft 3 11812 @@ -227,7 +227,7 @@ perft 5 7697880 perft 6 207028745 id 25 -epd nqnrb1kr/2pp1ppp/1p1bp3/p1B5/5P2/3N4/PPPPP1PP/NQ1R1BKR w HDhd - 0 9 +epd nqnrb1kr/2pp1ppp/1p1bp3/p1B5/5P2/3N4/PPPPP1PP/NQ1R1BKR w HDhd - perft 1 30 perft 2 672 perft 3 19307 @@ -236,7 +236,7 @@ perft 5 13454573 perft 6 345445468 id 26 -epd nqn2krb/p1prpppp/1pbp4/7P/5P2/8/PPPPPKP1/NQNRB1RB w g - 3 9 +epd nqn2krb/p1prpppp/1pbp4/7P/5P2/8/PPPPPKP1/NQNRB1RB w g - perft 1 21 perft 2 461 perft 3 10608 @@ -245,7 +245,7 @@ perft 5 6194124 perft 6 152861936 id 27 -epd nb1n1kbr/ppp1rppp/3pq3/P3p3/8/4P3/1PPPRPPP/NBQN1KBR w Hh - 1 9 +epd nb1n1kbr/ppp1rppp/3pq3/P3p3/8/4P3/1PPPRPPP/NBQN1KBR w Hh - perft 1 19 perft 2 566 perft 3 11786 @@ -254,7 +254,7 @@ perft 5 8047916 perft 6 249171636 id 28 -epd nqnbrkbr/1ppppp1p/p7/6p1/6P1/P6P/1PPPPP2/NQNBRKBR w HEhe - 1 9 +epd nqnbrkbr/1ppppp1p/p7/6p1/6P1/P6P/1PPPPP2/NQNBRKBR w HEhe - perft 1 20 perft 2 382 perft 3 8694 @@ -263,7 +263,7 @@ perft 5 4708975 perft 6 112278808 id 29 -epd nq1rkb1r/pp1pp1pp/1n2bp1B/2p5/8/5P1P/PPPPP1P1/NQNRKB1R w HDhd - 2 9 +epd nq1rkb1r/pp1pp1pp/1n2bp1B/2p5/8/5P1P/PPPPP1P1/NQNRKB1R w HDhd - perft 1 24 perft 2 809 perft 3 20090 @@ -272,7 +272,7 @@ perft 5 17647882 perft 6 593457788 id 30 -epd nqnrkrb1/pppppp2/7p/4b1p1/8/PN1NP3/1PPP1PPP/1Q1RKRBB w FDfd - 1 9 +epd nqnrkrb1/pppppp2/7p/4b1p1/8/PN1NP3/1PPP1PPP/1Q1RKRBB w FDfd - perft 1 26 perft 2 683 perft 3 18102 @@ -281,7 +281,7 @@ perft 5 13055173 perft 6 352398011 id 31 -epd bb1nqrkr/1pp1ppp1/pn5p/3p4/8/P2NNP2/1PPPP1PP/BB2QRKR w HFhf - 0 9 +epd bb1nqrkr/1pp1ppp1/pn5p/3p4/8/P2NNP2/1PPPP1PP/BB2QRKR w HFhf - perft 1 29 perft 2 695 perft 3 21193 @@ -290,7 +290,7 @@ perft 5 17454857 perft 6 483785639 id 32 -epd bnn1qrkr/pp1ppp1p/2p5/b3Q1p1/8/5P1P/PPPPP1P1/BNNB1RKR w HFhf - 2 9 +epd bnn1qrkr/pp1ppp1p/2p5/b3Q1p1/8/5P1P/PPPPP1P1/BNNB1RKR w HFhf - perft 1 44 perft 2 920 perft 3 35830 @@ -299,7 +299,7 @@ perft 5 29742670 perft 6 702867204 id 33 -epd bnnqrbkr/pp1p2p1/2p1p2p/5p2/1P5P/1R6/P1PPPPP1/BNNQRBK1 w Ehe - 0 9 +epd bnnqrbkr/pp1p2p1/2p1p2p/5p2/1P5P/1R6/P1PPPPP1/BNNQRBK1 w Ehe - perft 1 33 perft 2 1022 perft 3 32724 @@ -308,7 +308,7 @@ perft 5 32898113 perft 6 1047360456 id 34 -epd b1nqrkrb/2pppppp/p7/1P6/1n6/P4P2/1P1PP1PP/BNNQRKRB w GEge - 0 9 +epd b1nqrkrb/2pppppp/p7/1P6/1n6/P4P2/1P1PP1PP/BNNQRKRB w GEge - perft 1 23 perft 2 638 perft 3 15744 @@ -317,7 +317,7 @@ perft 5 11735969 perft 6 344211589 id 35 -epd n1bnqrkr/3ppppp/1p6/pNp1b3/2P3P1/8/PP1PPP1P/NBB1QRKR w HFhf - 1 9 +epd n1bnqrkr/3ppppp/1p6/pNp1b3/2P3P1/8/PP1PPP1P/NBB1QRKR w HFhf - perft 1 29 perft 2 728 perft 3 20768 @@ -326,7 +326,7 @@ perft 5 15621236 perft 6 415766465 id 36 -epd n2bqrkr/p1p1pppp/1pn5/3p1b2/P6P/1NP5/1P1PPPP1/1NBBQRKR w HFhf - 3 9 +epd n2bqrkr/p1p1pppp/1pn5/3p1b2/P6P/1NP5/1P1PPPP1/1NBBQRKR w HFhf - perft 1 20 perft 2 533 perft 3 12152 @@ -335,7 +335,7 @@ perft 5 8088751 perft 6 223068417 id 37 -epd nnbqrbkr/1pp1p1p1/p2p4/5p1p/2P1P3/N7/PPQP1PPP/N1B1RBKR w HEhe - 0 9 +epd nnbqrbkr/1pp1p1p1/p2p4/5p1p/2P1P3/N7/PPQP1PPP/N1B1RBKR w HEhe - perft 1 27 perft 2 619 perft 3 18098 @@ -344,7 +344,7 @@ perft 5 13755384 perft 6 357222394 id 38 -epd nnbqrkr1/pp1pp2p/2p2b2/5pp1/1P5P/4P1P1/P1PP1P2/NNBQRKRB w GEge - 1 9 +epd nnbqrkr1/pp1pp2p/2p2b2/5pp1/1P5P/4P1P1/P1PP1P2/NNBQRKRB w GEge - perft 1 32 perft 2 1046 perft 3 33721 @@ -353,7 +353,7 @@ perft 5 36218182 perft 6 1202830851 id 39 -epd nb1qbrkr/p1pppp2/1p1n2pp/8/1P6/2PN3P/P2PPPP1/NB1QBRKR w HFhf - 0 9 +epd nb1qbrkr/p1pppp2/1p1n2pp/8/1P6/2PN3P/P2PPPP1/NB1QBRKR w HFhf - perft 1 25 perft 2 521 perft 3 14021 @@ -362,7 +362,7 @@ perft 5 8697700 perft 6 201455191 id 40 -epd nnq1brkr/pp1pppp1/8/2p4P/8/5K2/PPPbPP1P/NNQBBR1R w hf - 0 9 +epd nnq1brkr/pp1pppp1/8/2p4P/8/5K2/PPPbPP1P/NNQBBR1R w hf - perft 1 23 perft 2 724 perft 3 18263 @@ -371,7 +371,7 @@ perft 5 15338230 perft 6 484638597 id 41 -epd nnqrbb1r/pppppk2/5pp1/7p/1P6/3P2PP/P1P1PP2/NNQRBBKR w HD - 0 9 +epd nnqrbb1r/pppppk2/5pp1/7p/1P6/3P2PP/P1P1PP2/NNQRBBKR w HD - perft 1 30 perft 2 717 perft 3 21945 @@ -380,7 +380,7 @@ perft 5 17166700 perft 6 450069742 id 42 -epd nnqr1krb/p1p1pppp/2bp4/8/1p1P4/4P3/PPP2PPP/NNQRBKRB w GDgd - 0 9 +epd nnqr1krb/p1p1pppp/2bp4/8/1p1P4/4P3/PPP2PPP/NNQRBKRB w GDgd - perft 1 25 perft 2 873 perft 3 20796 @@ -389,7 +389,7 @@ perft 5 18162741 perft 6 641708630 id 43 -epd nbnqrkbr/p2ppp2/1p4p1/2p4p/3P3P/3N4/PPP1PPPR/NB1QRKB1 w Ehe - 0 9 +epd nbnqrkbr/p2ppp2/1p4p1/2p4p/3P3P/3N4/PPP1PPPR/NB1QRKB1 w Ehe - perft 1 24 perft 2 589 perft 3 15190 @@ -398,7 +398,7 @@ perft 5 10630667 perft 6 279474189 id 44 -epd n1qbrkbr/p1ppp2p/2n2pp1/1p6/1P6/2P3P1/P2PPP1P/NNQBRKBR w HEhe - 0 9 +epd n1qbrkbr/p1ppp2p/2n2pp1/1p6/1P6/2P3P1/P2PPP1P/NNQBRKBR w HEhe - perft 1 22 perft 2 592 perft 3 14269 @@ -407,7 +407,7 @@ perft 5 10356818 perft 6 301583306 id 45 -epd 2qrkbbr/ppn1pppp/n1p5/3p4/5P2/P1PP4/1P2P1PP/NNQRKBBR w HDhd - 1 9 +epd 2qrkbbr/ppn1pppp/n1p5/3p4/5P2/P1PP4/1P2P1PP/NNQRKBBR w HDhd - perft 1 27 perft 2 750 perft 3 20584 @@ -416,7 +416,7 @@ perft 5 16819085 perft 6 516796736 id 46 -epd 1nqr1rbb/pppkp1pp/1n3p2/3p4/1P6/5P1P/P1PPPKP1/NNQR1RBB w - - 1 9 +epd 1nqr1rbb/pppkp1pp/1n3p2/3p4/1P6/5P1P/P1PPPKP1/NNQR1RBB w - - perft 1 24 perft 2 623 perft 3 15921 @@ -425,7 +425,7 @@ perft 5 11594634 perft 6 322745925 id 47 -epd bbn1rqkr/pp1pp2p/4npp1/2p5/1P6/2BPP3/P1P2PPP/1BNNRQKR w HEhe - 0 9 +epd bbn1rqkr/pp1pp2p/4npp1/2p5/1P6/2BPP3/P1P2PPP/1BNNRQKR w HEhe - perft 1 23 perft 2 730 perft 3 17743 @@ -434,7 +434,7 @@ perft 5 14496370 perft 6 468608864 id 48 -epd bn1brqkr/pppp2p1/3npp2/7p/PPP5/8/3PPPPP/BNNBRQKR w HEhe - 0 9 +epd bn1brqkr/pppp2p1/3npp2/7p/PPP5/8/3PPPPP/BNNBRQKR w HEhe - perft 1 25 perft 2 673 perft 3 17835 @@ -443,7 +443,7 @@ perft 5 14284338 perft 6 434008567 id 49 -epd bn1rqbkr/ppp1ppp1/1n6/2p4p/7P/3P4/PPP1PPP1/BN1RQBKR w HDhd - 0 9 +epd bn1rqbkr/ppp1ppp1/1n6/2p4p/7P/3P4/PPP1PPP1/BN1RQBKR w HDhd - perft 1 25 perft 2 776 perft 3 20562 @@ -452,7 +452,7 @@ perft 5 18486027 perft 6 616653869 id 50 -epd bnnr1krb/ppp2ppp/3p4/3Bp3/q1P3PP/8/PP1PPP2/BNNRQKR1 w GDgd - 0 9 +epd bnnr1krb/ppp2ppp/3p4/3Bp3/q1P3PP/8/PP1PPP2/BNNRQKR1 w GDgd - perft 1 29 perft 2 1040 perft 3 30772 @@ -461,7 +461,7 @@ perft 5 31801525 perft 6 1075147725 id 51 -epd 1bbnrqkr/pp1ppppp/8/2p5/n7/3PNPP1/PPP1P2P/NBB1RQKR w HEhe - 1 9 +epd 1bbnrqkr/pp1ppppp/8/2p5/n7/3PNPP1/PPP1P2P/NBB1RQKR w HEhe - perft 1 24 perft 2 598 perft 3 15673 @@ -470,7 +470,7 @@ perft 5 11394778 perft 6 310589129 id 52 -epd nnbbrqkr/p2ppp1p/1pp5/8/6p1/N1P5/PPBPPPPP/N1B1RQKR w HEhe - 0 9 +epd nnbbrqkr/p2ppp1p/1pp5/8/6p1/N1P5/PPBPPPPP/N1B1RQKR w HEhe - perft 1 26 perft 2 530 perft 3 14031 @@ -479,7 +479,7 @@ perft 5 8846766 perft 6 229270702 id 53 -epd nnbrqbkr/2p1p1pp/p4p2/1p1p4/8/NP6/P1PPPPPP/N1BRQBKR w HDhd - 0 9 +epd nnbrqbkr/2p1p1pp/p4p2/1p1p4/8/NP6/P1PPPPPP/N1BRQBKR w HDhd - perft 1 17 perft 2 496 perft 3 10220 @@ -488,7 +488,7 @@ perft 5 7103549 perft 6 217108001 id 54 -epd nnbrqk1b/pp2pprp/2pp2p1/8/3PP1P1/8/PPP2P1P/NNBRQRKB w d - 1 9 +epd nnbrqk1b/pp2pprp/2pp2p1/8/3PP1P1/8/PPP2P1P/NNBRQRKB w d - perft 1 33 perft 2 820 perft 3 27856 @@ -497,7 +497,7 @@ perft 5 24714401 perft 6 645835197 id 55 -epd 1bnrbqkr/ppnpp1p1/2p2p1p/8/1P6/4PPP1/P1PP3P/NBNRBQKR w HDhd - 0 9 +epd 1bnrbqkr/ppnpp1p1/2p2p1p/8/1P6/4PPP1/P1PP3P/NBNRBQKR w HDhd - perft 1 27 perft 2 705 perft 3 19760 @@ -506,7 +506,7 @@ perft 5 15964771 perft 6 464662032 id 56 -epd n1rbbqkr/pp1pppp1/7p/P1p5/1n6/2PP4/1P2PPPP/NNRBBQKR w HChc - 0 9 +epd n1rbbqkr/pp1pppp1/7p/P1p5/1n6/2PP4/1P2PPPP/NNRBBQKR w HChc - perft 1 22 perft 2 631 perft 3 14978 @@ -515,7 +515,7 @@ perft 5 10911545 perft 6 320838556 id 57 -epd n1rqb1kr/p1pppp1p/1pn4b/3P2p1/P7/1P6/2P1PPPP/NNRQBBKR w HChc - 0 9 +epd n1rqb1kr/p1pppp1p/1pn4b/3P2p1/P7/1P6/2P1PPPP/NNRQBBKR w HChc - perft 1 24 perft 2 477 perft 3 12506 @@ -524,7 +524,7 @@ perft 5 7419372 perft 6 165945904 id 58 -epd nnrqbkrb/pppp1pp1/7p/4p3/6P1/2N2B2/PPPPPP1P/NR1QBKR1 w Ggc - 2 9 +epd nnrqbkrb/pppp1pp1/7p/4p3/6P1/2N2B2/PPPPPP1P/NR1QBKR1 w Ggc - perft 1 29 perft 2 658 perft 3 19364 @@ -533,7 +533,7 @@ perft 5 14233587 perft 6 373744834 id 59 -epd n1nrqkbr/ppb2ppp/3pp3/2p5/2P3P1/5P2/PP1PPB1P/NBNRQK1R w HDhd - 1 9 +epd n1nrqkbr/ppb2ppp/3pp3/2p5/2P3P1/5P2/PP1PPB1P/NBNRQK1R w HDhd - perft 1 32 perft 2 801 perft 3 25861 @@ -542,7 +542,7 @@ perft 5 22318948 perft 6 619857455 id 60 -epd 2rbqkbr/p1pppppp/1nn5/1p6/7P/P4P2/1PPPP1PB/NNRBQK1R w HChc - 2 9 +epd 2rbqkbr/p1pppppp/1nn5/1p6/7P/P4P2/1PPPP1PB/NNRBQK1R w HChc - perft 1 27 perft 2 647 perft 3 18030 @@ -551,7 +551,7 @@ perft 5 13189156 perft 6 354689323 id 61 -epd nn1qkbbr/pp2ppp1/2rp4/2p4p/P2P4/1N5P/1PP1PPP1/1NRQKBBR w HCh - 1 9 +epd nn1qkbbr/pp2ppp1/2rp4/2p4p/P2P4/1N5P/1PP1PPP1/1NRQKBBR w HCh - perft 1 24 perft 2 738 perft 3 18916 @@ -560,7 +560,7 @@ perft 5 16420659 perft 6 519075930 id 62 -epd nnrqk1bb/p1ppp2p/5rp1/1p3p2/1P4P1/5P1P/P1PPP3/NNRQKRBB w FCc - 1 9 +epd nnrqk1bb/p1ppp2p/5rp1/1p3p2/1P4P1/5P1P/P1PPP3/NNRQKRBB w FCc - perft 1 25 perft 2 795 perft 3 20510 @@ -569,7 +569,7 @@ perft 5 17342527 perft 6 556144017 id 63 -epd bb1nrkqr/ppppn2p/4ppp1/8/1P4P1/4P3/P1PPKP1P/BBNNR1QR w he - 0 9 +epd bb1nrkqr/ppppn2p/4ppp1/8/1P4P1/4P3/P1PPKP1P/BBNNR1QR w he - perft 1 29 perft 2 664 perft 3 20024 @@ -578,7 +578,7 @@ perft 5 15373803 perft 6 406016364 id 64 -epd bnnbrkqr/1p1ppp2/8/p1p3pp/1P6/N4P2/PBPPP1PP/2NBRKQR w HEhe - 0 9 +epd bnnbrkqr/1p1ppp2/8/p1p3pp/1P6/N4P2/PBPPP1PP/2NBRKQR w HEhe - perft 1 31 perft 2 770 perft 3 24850 @@ -587,7 +587,7 @@ perft 5 22562080 perft 6 662029574 id 65 -epd 1nnrkbqr/p1pp1ppp/4p3/1p6/1Pb1P3/6PB/P1PP1P1P/BNNRK1QR w HDhd - 0 9 +epd 1nnrkbqr/p1pp1ppp/4p3/1p6/1Pb1P3/6PB/P1PP1P1P/BNNRK1QR w HDhd - perft 1 27 perft 2 776 perft 3 22133 @@ -596,7 +596,7 @@ perft 5 19153245 perft 6 562738257 id 66 -epd bnr1kqrb/pppp1pp1/1n5p/4p3/P3P3/3P2P1/1PP2P1P/BNNRKQRB w GDg - 0 9 +epd bnr1kqrb/pppp1pp1/1n5p/4p3/P3P3/3P2P1/1PP2P1P/BNNRKQRB w GDg - perft 1 26 perft 2 624 perft 3 16411 @@ -605,7 +605,7 @@ perft 5 11906515 perft 6 338092952 id 67 -epd nbbnrkqr/p1ppp1pp/1p3p2/8/2P5/4P3/PP1P1PPP/NBBNRKQR w HEhe - 1 9 +epd nbbnrkqr/p1ppp1pp/1p3p2/8/2P5/4P3/PP1P1PPP/NBBNRKQR w HEhe - perft 1 25 perft 2 624 perft 3 15561 @@ -614,7 +614,7 @@ perft 5 10817378 perft 6 311138112 id 68 -epd nn1brkqr/pp1bpppp/8/2pp4/P4P2/1PN5/2PPP1PP/N1BBRKQR w HEhe - 1 9 +epd nn1brkqr/pp1bpppp/8/2pp4/P4P2/1PN5/2PPP1PP/N1BBRKQR w HEhe - perft 1 23 perft 2 659 perft 3 16958 @@ -623,7 +623,7 @@ perft 5 13242252 perft 6 373557073 id 69 -epd n1brkbqr/ppp1pp1p/6pB/3p4/2Pn4/8/PP2PPPP/NN1RKBQR w HDhd - 0 9 +epd n1brkbqr/ppp1pp1p/6pB/3p4/2Pn4/8/PP2PPPP/NN1RKBQR w HDhd - perft 1 32 perft 2 1026 perft 3 30360 @@ -632,7 +632,7 @@ perft 5 29436320 perft 6 957904151 id 70 -epd nnbrkqrb/p2ppp2/Q5pp/1pp5/4PP2/2N5/PPPP2PP/N1BRK1RB w GDgd - 0 9 +epd nnbrkqrb/p2ppp2/Q5pp/1pp5/4PP2/2N5/PPPP2PP/N1BRK1RB w GDgd - perft 1 36 perft 2 843 perft 3 29017 @@ -641,7 +641,7 @@ perft 5 24321197 perft 6 630396940 id 71 -epd nbnrbk1r/pppppppq/8/7p/8/1N2QPP1/PPPPP2P/NB1RBK1R w HDhd - 2 9 +epd nbnrbk1r/pppppppq/8/7p/8/1N2QPP1/PPPPP2P/NB1RBK1R w HDhd - perft 1 36 perft 2 973 perft 3 35403 @@ -650,7 +650,7 @@ perft 5 37143354 perft 6 1124883780 id 72 -epd nnrbbkqr/2pppp1p/p7/6p1/1p2P3/4QPP1/PPPP3P/NNRBBK1R w HChc - 0 9 +epd nnrbbkqr/2pppp1p/p7/6p1/1p2P3/4QPP1/PPPP3P/NNRBBK1R w HChc - perft 1 36 perft 2 649 perft 3 22524 @@ -659,7 +659,7 @@ perft 5 16836636 perft 6 416139320 id 73 -epd nnrkbbqr/1p2pppp/p2p4/2p5/8/1N2P1P1/PPPP1P1P/1NKRBBQR w hc - 0 9 +epd nnrkbbqr/1p2pppp/p2p4/2p5/8/1N2P1P1/PPPP1P1P/1NKRBBQR w hc - perft 1 26 perft 2 672 perft 3 18136 @@ -668,7 +668,7 @@ perft 5 13342771 perft 6 363074681 id 74 -epd n1rkbqrb/pp1ppp2/2n3p1/2p4p/P5PP/1P6/2PPPP2/NNRKBQRB w GCgc - 0 9 +epd n1rkbqrb/pp1ppp2/2n3p1/2p4p/P5PP/1P6/2PPPP2/NNRKBQRB w GCgc - perft 1 24 perft 2 804 perft 3 20712 @@ -677,7 +677,7 @@ perft 5 18761475 perft 6 617932151 id 75 -epd nbkr1qbr/1pp1pppp/pn1p4/8/3P2P1/5R2/PPP1PP1P/NBN1KQBR w H - 2 9 +epd nbkr1qbr/1pp1pppp/pn1p4/8/3P2P1/5R2/PPP1PP1P/NBN1KQBR w H - perft 1 30 perft 2 627 perft 3 18669 @@ -686,7 +686,7 @@ perft 5 12815016 perft 6 312798696 id 76 -epd nnr1kqbr/pp1pp1p1/2p5/b4p1p/P7/1PNP4/2P1PPPP/N1RBKQBR w HChc - 1 9 +epd nnr1kqbr/pp1pp1p1/2p5/b4p1p/P7/1PNP4/2P1PPPP/N1RBKQBR w HChc - perft 1 12 perft 2 421 perft 3 6530 @@ -695,7 +695,7 @@ perft 5 4266410 perft 6 149176979 id 77 -epd n1rkqbbr/p1pp1pp1/np2p2p/8/8/N4PP1/PPPPP1BP/N1RKQ1BR w HChc - 0 9 +epd n1rkqbbr/p1pp1pp1/np2p2p/8/8/N4PP1/PPPPP1BP/N1RKQ1BR w HChc - perft 1 27 perft 2 670 perft 3 19119 @@ -704,7 +704,7 @@ perft 5 14708490 perft 6 397268628 id 78 -epd nnr1qrbb/p2kpppp/1p1p4/2p5/6P1/PP1P4/2P1PP1P/NNRKQRBB w FC - 0 9 +epd nnr1qrbb/p2kpppp/1p1p4/2p5/6P1/PP1P4/2P1PP1P/NNRKQRBB w FC - perft 1 27 perft 2 604 perft 3 17043 @@ -713,7 +713,7 @@ perft 5 11993332 perft 6 308518181 id 79 -epd bbnnrkrq/ppp1pp2/6p1/3p4/7p/7P/PPPPPPP1/BBNNRRKQ w ge - 0 9 +epd bbnnrkrq/ppp1pp2/6p1/3p4/7p/7P/PPPPPPP1/BBNNRRKQ w ge - perft 1 20 perft 2 559 perft 3 12242 @@ -722,7 +722,7 @@ perft 5 8427161 perft 6 252274233 id 80 -epd bnnbrkr1/ppp2p1p/5q2/3pp1p1/4P3/1N4P1/PPPPRP1P/BN1B1KRQ w Gge - 0 9 +epd bnnbrkr1/ppp2p1p/5q2/3pp1p1/4P3/1N4P1/PPPPRP1P/BN1B1KRQ w Gge - perft 1 26 perft 2 1036 perft 3 27228 @@ -731,7 +731,7 @@ perft 5 28286576 perft 6 1042120495 id 81 -epd bn1rkbrq/1pppppp1/p6p/1n6/3P4/6PP/PPPRPP2/BNN1KBRQ w Ggd - 2 9 +epd bn1rkbrq/1pppppp1/p6p/1n6/3P4/6PP/PPPRPP2/BNN1KBRQ w Ggd - perft 1 29 perft 2 633 perft 3 19278 @@ -740,7 +740,7 @@ perft 5 14333034 perft 6 361900466 id 82 -epd b1nrkrqb/1p1npppp/p2p4/2p5/5P2/4P2P/PPPP1RP1/BNNRK1QB w Dfd - 1 9 +epd b1nrkrqb/1p1npppp/p2p4/2p5/5P2/4P2P/PPPP1RP1/BNNRK1QB w Dfd - perft 1 25 perft 2 475 perft 3 12603 @@ -749,7 +749,7 @@ perft 5 7545536 perft 6 179579818 id 83 -epd 1bbnrkrq/ppppppp1/8/7p/1n4P1/1PN5/P1PPPP1P/NBBR1KRQ w Gge - 0 9 +epd 1bbnrkrq/ppppppp1/8/7p/1n4P1/1PN5/P1PPPP1P/NBBR1KRQ w Gge - perft 1 30 perft 2 803 perft 3 25473 @@ -758,7 +758,7 @@ perft 5 23443854 perft 6 686365049 id 84 -epd nnbbrkrq/2pp1pp1/1p5p/pP2p3/7P/N7/P1PPPPP1/N1BBRKRQ w GEge - 0 9 +epd nnbbrkrq/2pp1pp1/1p5p/pP2p3/7P/N7/P1PPPPP1/N1BBRKRQ w GEge - perft 1 18 perft 2 432 perft 3 9638 @@ -767,7 +767,7 @@ perft 5 6131124 perft 6 160393505 id 85 -epd nnbrkbrq/1pppp1p1/p7/7p/1P2Pp2/BN6/P1PP1PPP/1N1RKBRQ w GDgd - 0 9 +epd nnbrkbrq/1pppp1p1/p7/7p/1P2Pp2/BN6/P1PP1PPP/1N1RKBRQ w GDgd - perft 1 27 perft 2 482 perft 3 13441 @@ -776,7 +776,7 @@ perft 5 8084701 perft 6 193484216 id 86 -epd n1brkrqb/pppp3p/n3pp2/6p1/3P1P2/N1P5/PP2P1PP/N1BRKRQB w FDfd - 0 9 +epd n1brkrqb/pppp3p/n3pp2/6p1/3P1P2/N1P5/PP2P1PP/N1BRKRQB w FDfd - perft 1 28 perft 2 642 perft 3 19005 @@ -785,7 +785,7 @@ perft 5 14529434 perft 6 384837696 id 87 -epd nbnrbk2/p1pppp1p/1p3qr1/6p1/1B1P4/1N6/PPP1PPPP/1BNR1RKQ w d - 2 9 +epd nbnrbk2/p1pppp1p/1p3qr1/6p1/1B1P4/1N6/PPP1PPPP/1BNR1RKQ w d - perft 1 30 perft 2 796 perft 3 22780 @@ -794,7 +794,7 @@ perft 5 20120565 perft 6 641832725 id 88 -epd nnrbbrkq/1pp2ppp/3p4/p3p3/3P1P2/1P2P3/P1P3PP/NNRBBKRQ w GC - 1 9 +epd nnrbbrkq/1pp2ppp/3p4/p3p3/3P1P2/1P2P3/P1P3PP/NNRBBKRQ w GC - perft 1 31 perft 2 827 perft 3 24538 @@ -803,7 +803,7 @@ perft 5 19979594 perft 6 549437308 id 89 -epd nnrkbbrq/1pp2p1p/p2pp1p1/2P5/8/8/PP1PPPPP/NNRKBBRQ w Ggc - 0 9 +epd nnrkbbrq/1pp2p1p/p2pp1p1/2P5/8/8/PP1PPPPP/NNRKBBRQ w Ggc - perft 1 24 perft 2 762 perft 3 19283 @@ -812,7 +812,7 @@ perft 5 16838099 perft 6 555230555 id 90 -epd nnr1brqb/1ppkp1pp/8/p2p1p2/1P1P4/N1P5/P3PPPP/N1RKBRQB w FC - 1 9 +epd nnr1brqb/1ppkp1pp/8/p2p1p2/1P1P4/N1P5/P3PPPP/N1RKBRQB w FC - perft 1 23 perft 2 640 perft 3 15471 @@ -821,7 +821,7 @@ perft 5 11343507 perft 6 334123513 id 91 -epd nbnrkrbq/2ppp2p/p4p2/1P4p1/4PP2/8/1PPP2PP/NBNRKRBQ w FDfd - 0 9 +epd nbnrkrbq/2ppp2p/p4p2/1P4p1/4PP2/8/1PPP2PP/NBNRKRBQ w FDfd - perft 1 31 perft 2 826 perft 3 26137 @@ -830,7 +830,7 @@ perft 5 23555139 perft 6 686250413 id 92 -epd 1nrbkr1q/1pppp1pp/1n6/p4p2/N1b4P/8/PPPPPPPB/N1RBKR1Q w FCfc - 2 9 +epd 1nrbkr1q/1pppp1pp/1n6/p4p2/N1b4P/8/PPPPPPPB/N1RBKR1Q w FCfc - perft 1 27 perft 2 862 perft 3 24141 @@ -839,7 +839,7 @@ perft 5 22027695 perft 6 696353497 id 93 -epd nnrkrbbq/pppp2pp/8/4pp2/4P3/P7/1PPPBPPP/NNKRR1BQ w c - 0 9 +epd nnrkrbbq/pppp2pp/8/4pp2/4P3/P7/1PPPBPPP/NNKRR1BQ w c - perft 1 25 perft 2 792 perft 3 19883 @@ -848,7 +848,7 @@ perft 5 16473376 perft 6 532214177 id 94 -epd n1rk1qbb/pppprpp1/2n4p/4p3/2PP3P/8/PP2PPP1/NNRKRQBB w ECc - 1 9 +epd n1rk1qbb/pppprpp1/2n4p/4p3/2PP3P/8/PP2PPP1/NNRKRQBB w ECc - perft 1 25 perft 2 622 perft 3 16031 @@ -857,7 +857,7 @@ perft 5 11420973 perft 6 321855685 id 95 -epd bbq1rnkr/pnp1pp1p/1p1p4/6p1/2P5/2Q1P2P/PP1P1PP1/BB1NRNKR w HEhe - 2 9 +epd bbq1rnkr/pnp1pp1p/1p1p4/6p1/2P5/2Q1P2P/PP1P1PP1/BB1NRNKR w HEhe - perft 1 36 perft 2 870 perft 3 30516 @@ -866,7 +866,7 @@ perft 5 28127620 perft 6 799738334 id 96 -epd bq1brnkr/1p1ppp1p/1np5/p5p1/8/1N5P/PPPPPPP1/BQ1BRNKR w HEhe - 0 9 +epd bq1brnkr/1p1ppp1p/1np5/p5p1/8/1N5P/PPPPPPP1/BQ1BRNKR w HEhe - perft 1 22 perft 2 588 perft 3 13524 @@ -875,7 +875,7 @@ perft 5 9359618 perft 6 273795898 id 97 -epd bq1rn1kr/1pppppbp/Nn4p1/8/8/P7/1PPPPPPP/BQ1RNBKR w HDhd - 1 9 +epd bq1rn1kr/1pppppbp/Nn4p1/8/8/P7/1PPPPPPP/BQ1RNBKR w HDhd - perft 1 24 perft 2 711 perft 3 18197 @@ -884,7 +884,7 @@ perft 5 14692779 perft 6 445827351 id 98 -epd bqnr1kr1/pppppp1p/6p1/5n2/4B3/3N2PP/PbPPPP2/BQNR1KR1 w GDgd - 2 9 +epd bqnr1kr1/pppppp1p/6p1/5n2/4B3/3N2PP/PbPPPP2/BQNR1KR1 w GDgd - perft 1 31 perft 2 1132 perft 3 36559 @@ -893,7 +893,7 @@ perft 5 43256823 perft 6 1456721391 id 99 -epd qbb1rnkr/ppp3pp/4n3/3ppp2/1P3PP1/8/P1PPPN1P/QBB1RNKR w HEhe - 0 9 +epd qbb1rnkr/ppp3pp/4n3/3ppp2/1P3PP1/8/P1PPPN1P/QBB1RNKR w HEhe - perft 1 28 perft 2 696 perft 3 20502 @@ -902,7 +902,7 @@ perft 5 16492398 perft 6 456983120 id 100 -epd qnbbr1kr/pp1ppp1p/4n3/6p1/2p3P1/2PP1P2/PP2P2P/QNBBRNKR w HEhe - 0 9 +epd qnbbr1kr/pp1ppp1p/4n3/6p1/2p3P1/2PP1P2/PP2P2P/QNBBRNKR w HEhe - perft 1 25 perft 2 655 perft 3 16520 @@ -911,7 +911,7 @@ perft 5 11767038 perft 6 335414976 id 101 -epd 1nbrnbkr/p1ppp1pp/1p6/5p2/4q1PP/3P4/PPP1PP2/QNBRNBKR w HDhd - 1 9 +epd 1nbrnbkr/p1ppp1pp/1p6/5p2/4q1PP/3P4/PPP1PP2/QNBRNBKR w HDhd - perft 1 30 perft 2 1162 perft 3 33199 @@ -920,7 +920,7 @@ perft 5 36048727 perft 6 1290346802 id 102 -epd q1brnkrb/p1pppppp/n7/1p6/P7/3P1P2/QPP1P1PP/1NBRNKRB w GDgd - 0 9 +epd q1brnkrb/p1pppppp/n7/1p6/P7/3P1P2/QPP1P1PP/1NBRNKRB w GDgd - perft 1 32 perft 2 827 perft 3 26106 @@ -929,7 +929,7 @@ perft 5 23143989 perft 6 673147648 id 103 -epd qbnrb1kr/ppp1pp1p/3p4/2n3p1/1P6/6N1/P1PPPPPP/QBNRB1KR w HDhd - 2 9 +epd qbnrb1kr/ppp1pp1p/3p4/2n3p1/1P6/6N1/P1PPPPPP/QBNRB1KR w HDhd - perft 1 29 perft 2 751 perft 3 23132 @@ -938,7 +938,7 @@ perft 5 19555214 perft 6 530475036 id 104 -epd q1rbbnkr/pppp1p2/2n3pp/2P1p3/3P4/8/PP1NPPPP/Q1RBBNKR w HChc - 2 9 +epd q1rbbnkr/pppp1p2/2n3pp/2P1p3/3P4/8/PP1NPPPP/Q1RBBNKR w HChc - perft 1 29 perft 2 806 perft 3 24540 @@ -947,7 +947,7 @@ perft 5 21694330 perft 6 619907316 id 105 -epd q1r1bbkr/pnpp1ppp/2n1p3/1p6/2P2P2/2N1N3/PP1PP1PP/Q1R1BBKR w HChc - 2 9 +epd q1r1bbkr/pnpp1ppp/2n1p3/1p6/2P2P2/2N1N3/PP1PP1PP/Q1R1BBKR w HChc - perft 1 32 perft 2 1017 perft 3 32098 @@ -956,7 +956,7 @@ perft 5 31204371 perft 6 958455898 id 106 -epd 2rnbkrb/pqppppp1/1pn5/7p/2P5/P1R5/QP1PPPPP/1N1NBKRB w Ggc - 4 9 +epd 2rnbkrb/pqppppp1/1pn5/7p/2P5/P1R5/QP1PPPPP/1N1NBKRB w Ggc - perft 1 26 perft 2 625 perft 3 16506 @@ -965,7 +965,7 @@ perft 5 11856964 perft 6 336672890 id 107 -epd qbnr1kbr/p2ppppp/2p5/1p6/4n2P/P4N2/1PPP1PP1/QBNR1KBR w HDhd - 0 9 +epd qbnr1kbr/p2ppppp/2p5/1p6/4n2P/P4N2/1PPP1PP1/QBNR1KBR w HDhd - perft 1 27 perft 2 885 perft 3 23828 @@ -974,7 +974,7 @@ perft 5 21855658 perft 6 706272554 id 108 -epd qnrbnk1r/pp1pp2p/5p2/2pbP1p1/3P4/1P6/P1P2PPP/QNRBNKBR w HChc - 0 9 +epd qnrbnk1r/pp1pp2p/5p2/2pbP1p1/3P4/1P6/P1P2PPP/QNRBNKBR w HChc - perft 1 26 perft 2 954 perft 3 24832 @@ -983,7 +983,7 @@ perft 5 24415089 perft 6 866744329 id 109 -epd qnrnk1br/p1p2ppp/8/1pbpp3/8/PP2N3/1QPPPPPP/1NR1KBBR w HChc - 0 9 +epd qnrnk1br/p1p2ppp/8/1pbpp3/8/PP2N3/1QPPPPPP/1NR1KBBR w HChc - perft 1 26 perft 2 783 perft 3 20828 @@ -992,7 +992,7 @@ perft 5 17477825 perft 6 539674275 id 110 -epd qnrnkrbb/Bpppp2p/6p1/5p2/5P2/3PP3/PPP3PP/QNRNKR1B w FCfc - 1 9 +epd qnrnkrbb/Bpppp2p/6p1/5p2/5P2/3PP3/PPP3PP/QNRNKR1B w FCfc - perft 1 28 perft 2 908 perft 3 25730 @@ -1001,7 +1001,7 @@ perft 5 25251641 perft 6 869525254 id 111 -epd bbnqrn1r/ppppp2k/5p2/6pp/7P/1QP5/PP1PPPP1/B1N1RNKR w HE - 0 9 +epd bbnqrn1r/ppppp2k/5p2/6pp/7P/1QP5/PP1PPPP1/B1N1RNKR w HE - perft 1 33 perft 2 643 perft 3 21790 @@ -1010,7 +1010,7 @@ perft 5 16693640 perft 6 410115900 id 112 -epd b1qbrnkr/ppp1pp2/2np4/6pp/4P3/2N4P/PPPP1PP1/BQ1BRNKR w HEhe - 0 9 +epd b1qbrnkr/ppp1pp2/2np4/6pp/4P3/2N4P/PPPP1PP1/BQ1BRNKR w HEhe - perft 1 28 perft 2 837 perft 3 24253 @@ -1019,7 +1019,7 @@ perft 5 22197063 perft 6 696399065 id 113 -epd bnqr1bkr/pp1ppppp/2p5/4N3/5P2/P7/1PPPPnPP/BNQR1BKR w HDhd - 3 9 +epd bnqr1bkr/pp1ppppp/2p5/4N3/5P2/P7/1PPPPnPP/BNQR1BKR w HDhd - perft 1 25 perft 2 579 perft 3 13909 @@ -1028,7 +1028,7 @@ perft 5 8601011 perft 6 225530258 id 114 -epd b1qr1krb/pp1ppppp/n2n4/8/2p5/2P3P1/PP1PPP1P/BNQRNKRB w GDgd - 0 9 +epd b1qr1krb/pp1ppppp/n2n4/8/2p5/2P3P1/PP1PPP1P/BNQRNKRB w GDgd - perft 1 28 perft 2 707 perft 3 19721 @@ -1037,7 +1037,7 @@ perft 5 15583376 perft 6 468399900 id 115 -epd nbbqr1kr/1pppp1pp/8/p1n2p2/4P3/PN6/1PPPQPPP/1BB1RNKR w HEhe - 0 9 +epd nbbqr1kr/1pppp1pp/8/p1n2p2/4P3/PN6/1PPPQPPP/1BB1RNKR w HEhe - perft 1 30 perft 2 745 perft 3 23416 @@ -1046,7 +1046,7 @@ perft 5 19478789 perft 6 515473678 id 116 -epd nqbbrn1r/p1pppp1k/1p4p1/7p/4P3/1R3B2/PPPP1PPP/NQB2NKR w H - 0 9 +epd nqbbrn1r/p1pppp1k/1p4p1/7p/4P3/1R3B2/PPPP1PPP/NQB2NKR w H - perft 1 24 perft 2 504 perft 3 13512 @@ -1055,7 +1055,7 @@ perft 5 9002073 perft 6 228726497 id 117 -epd nqbr1bkr/p1p1ppp1/1p1n4/3pN2p/1P6/8/P1PPPPPP/NQBR1BKR w HDhd - 0 9 +epd nqbr1bkr/p1p1ppp1/1p1n4/3pN2p/1P6/8/P1PPPPPP/NQBR1BKR w HDhd - perft 1 29 perft 2 898 perft 3 26532 @@ -1064,7 +1064,7 @@ perft 5 24703467 perft 6 757166494 id 118 -epd nqbrn1rb/pppp1kp1/5p1p/4p3/P4B2/3P2P1/1PP1PP1P/NQ1RNKRB w GD - 0 9 +epd nqbrn1rb/pppp1kp1/5p1p/4p3/P4B2/3P2P1/1PP1PP1P/NQ1RNKRB w GD - perft 1 34 perft 2 671 perft 3 22332 @@ -1073,7 +1073,7 @@ perft 5 15556806 perft 6 353235120 id 119 -epd nb1r1nkr/ppp1ppp1/2bp4/7p/3P2qP/P6R/1PP1PPP1/NBQRBNK1 w Dhd - 1 9 +epd nb1r1nkr/ppp1ppp1/2bp4/7p/3P2qP/P6R/1PP1PPP1/NBQRBNK1 w Dhd - perft 1 38 perft 2 1691 perft 3 60060 @@ -1082,7 +1082,7 @@ perft 5 88557078 perft 6 3589649998 id 120 -epd n1rbbnkr/1p1pp1pp/p7/2p1qp2/1B3P2/3P4/PPP1P1PP/NQRB1NKR w HChc - 0 9 +epd n1rbbnkr/1p1pp1pp/p7/2p1qp2/1B3P2/3P4/PPP1P1PP/NQRB1NKR w HChc - perft 1 24 perft 2 913 perft 3 21595 @@ -1091,7 +1091,7 @@ perft 5 19866918 perft 6 737239330 id 121 -epd nqrnbbkr/p2p1p1p/1pp5/1B2p1p1/1P3P2/4P3/P1PP2PP/NQRNB1KR w HChc - 0 9 +epd nqrnbbkr/p2p1p1p/1pp5/1B2p1p1/1P3P2/4P3/P1PP2PP/NQRNB1KR w HChc - perft 1 33 perft 2 913 perft 3 30159 @@ -1100,7 +1100,7 @@ perft 5 28053260 perft 6 804687975 id 122 -epd nqr1bkrb/ppp1pp2/2np2p1/P6p/8/2P4P/1P1PPPP1/NQRNBKRB w GCgc - 0 9 +epd nqr1bkrb/ppp1pp2/2np2p1/P6p/8/2P4P/1P1PPPP1/NQRNBKRB w GCgc - perft 1 24 perft 2 623 perft 3 16569 @@ -1109,7 +1109,7 @@ perft 5 12681936 perft 6 351623879 id 123 -epd nb1rnkbr/pqppppp1/1p5p/8/1PP4P/8/P2PPPP1/NBQRNKBR w HDhd - 1 9 +epd nb1rnkbr/pqppppp1/1p5p/8/1PP4P/8/P2PPPP1/NBQRNKBR w HDhd - perft 1 31 perft 2 798 perft 3 24862 @@ -1118,7 +1118,7 @@ perft 5 22616076 perft 6 666227466 id 124 -epd nqrbnkbr/2p1p1pp/3p4/pp3p2/6PP/3P1N2/PPP1PP2/NQRB1KBR w HChc - 0 9 +epd nqrbnkbr/2p1p1pp/3p4/pp3p2/6PP/3P1N2/PPP1PP2/NQRB1KBR w HChc - perft 1 24 perft 2 590 perft 3 14409 @@ -1127,7 +1127,7 @@ perft 5 9698432 perft 6 274064911 id 125 -epd nqrnkbbr/pp1p1p1p/4p1p1/1p6/8/5P1P/P1PPP1P1/NQRNKBBR w HChc - 0 9 +epd nqrnkbbr/pp1p1p1p/4p1p1/1p6/8/5P1P/P1PPP1P1/NQRNKBBR w HChc - perft 1 30 perft 2 1032 perft 3 31481 @@ -1136,7 +1136,7 @@ perft 5 34914919 perft 6 1233362066 id 126 -epd nqrnkrbb/p2ppppp/1p6/2p5/2P3P1/5P2/PP1PPN1P/NQR1KRBB w FCfc - 1 9 +epd nqrnkrbb/p2ppppp/1p6/2p5/2P3P1/5P2/PP1PPN1P/NQR1KRBB w FCfc - perft 1 30 perft 2 775 perft 3 23958 @@ -1145,7 +1145,7 @@ perft 5 21141738 perft 6 621142773 id 127 -epd bbnrqrk1/pp2pppp/4n3/2pp4/P7/1N5P/BPPPPPP1/B2RQNKR w HD - 2 9 +epd bbnrqrk1/pp2pppp/4n3/2pp4/P7/1N5P/BPPPPPP1/B2RQNKR w HD - perft 1 23 perft 2 708 perft 3 17164 @@ -1154,7 +1154,7 @@ perft 5 14343443 perft 6 481405144 id 128 -epd bnr1qnkr/p1pp1p1p/1p4p1/4p1b1/2P1P3/1P6/PB1P1PPP/1NRBQNKR w HChc - 1 9 +epd bnr1qnkr/p1pp1p1p/1p4p1/4p1b1/2P1P3/1P6/PB1P1PPP/1NRBQNKR w HChc - perft 1 30 perft 2 931 perft 3 29249 @@ -1163,7 +1163,7 @@ perft 5 30026687 perft 6 968109774 id 129 -epd b1rqnbkr/ppp1ppp1/3p3p/2n5/P3P3/2NP4/1PP2PPP/B1RQNBKR w HChc - 0 9 +epd b1rqnbkr/ppp1ppp1/3p3p/2n5/P3P3/2NP4/1PP2PPP/B1RQNBKR w HChc - perft 1 24 perft 2 596 perft 3 15533 @@ -1172,7 +1172,7 @@ perft 5 11099382 perft 6 294180723 id 130 -epd bnrqnr1b/pp1pkppp/2p1p3/P7/2P5/7P/1P1PPPP1/BNRQNKRB w GC - 0 9 +epd bnrqnr1b/pp1pkppp/2p1p3/P7/2P5/7P/1P1PPPP1/BNRQNKRB w GC - perft 1 24 perft 2 572 perft 3 15293 @@ -1181,7 +1181,7 @@ perft 5 11208688 perft 6 302955778 id 131 -epd n1brq1kr/bppppppp/p7/8/4P1Pn/8/PPPP1P2/NBBRQNKR w HDhd - 0 9 +epd n1brq1kr/bppppppp/p7/8/4P1Pn/8/PPPP1P2/NBBRQNKR w HDhd - perft 1 20 perft 2 570 perft 3 13139 @@ -1190,7 +1190,7 @@ perft 5 9919113 perft 6 284592289 id 132 -epd 1rbbqnkr/ppn1ppp1/3p3p/2p5/3P4/1N4P1/PPPBPP1P/1R1BQNKR w HBhb - 0 9 +epd 1rbbqnkr/ppn1ppp1/3p3p/2p5/3P4/1N4P1/PPPBPP1P/1R1BQNKR w HBhb - perft 1 29 perft 2 1009 perft 3 29547 @@ -1199,7 +1199,7 @@ perft 5 31059587 perft 6 1111986835 id 133 -epd nrbq2kr/ppppppb1/5n1p/5Pp1/8/P5P1/1PPPP2P/NRBQNBKR w HBhb - 1 9 +epd nrbq2kr/ppppppb1/5n1p/5Pp1/8/P5P1/1PPPP2P/NRBQNBKR w HBhb - perft 1 20 perft 2 520 perft 3 11745 @@ -1208,7 +1208,7 @@ perft 5 7809837 perft 6 216997152 id 134 -epd nrb1nkrb/pp3ppp/1qBpp3/2p5/8/P5P1/1PPPPP1P/NRBQNKR1 w GBgb - 2 9 +epd nrb1nkrb/pp3ppp/1qBpp3/2p5/8/P5P1/1PPPPP1P/NRBQNKR1 w GBgb - perft 1 32 perft 2 850 perft 3 25642 @@ -1217,7 +1217,7 @@ perft 5 21981567 perft 6 664886187 id 135 -epd 1br1bnkr/ppqppp1p/1np3p1/8/1PP4P/4N3/P2PPPP1/NBRQB1KR w HChc - 1 9 +epd 1br1bnkr/ppqppp1p/1np3p1/8/1PP4P/4N3/P2PPPP1/NBRQB1KR w HChc - perft 1 32 perft 2 798 perft 3 24765 @@ -1226,7 +1226,7 @@ perft 5 22076141 perft 6 670296871 id 136 -epd nrqbb1kr/1p1pp1pp/2p3n1/p4p2/3PP3/P5N1/1PP2PPP/NRQBB1KR w HBhb - 0 9 +epd nrqbb1kr/1p1pp1pp/2p3n1/p4p2/3PP3/P5N1/1PP2PPP/NRQBB1KR w HBhb - perft 1 32 perft 2 791 perft 3 26213 @@ -1235,7 +1235,7 @@ perft 5 23239122 perft 6 634260266 id 137 -epd nrqn1bkr/ppppp1pp/4b3/8/4P1p1/5P2/PPPP3P/NRQNBBKR w HBhb - 0 9 +epd nrqn1bkr/ppppp1pp/4b3/8/4P1p1/5P2/PPPP3P/NRQNBBKR w HBhb - perft 1 29 perft 2 687 perft 3 20223 @@ -1244,7 +1244,7 @@ perft 5 15236287 perft 6 398759980 id 138 -epd nrqnbrkb/pppp1p2/4p2p/3B2p1/8/1P4P1/PQPPPP1P/NR1NBKR1 w GB - 0 9 +epd nrqnbrkb/pppp1p2/4p2p/3B2p1/8/1P4P1/PQPPPP1P/NR1NBKR1 w GB - perft 1 37 perft 2 764 perft 3 27073 @@ -1253,7 +1253,7 @@ perft 5 21284835 perft 6 514864869 id 139 -epd nbrq1kbr/Bp3ppp/2pnp3/3p4/5P2/2P4P/PP1PP1P1/NBRQNK1R w HChc - 0 9 +epd nbrq1kbr/Bp3ppp/2pnp3/3p4/5P2/2P4P/PP1PP1P1/NBRQNK1R w HChc - perft 1 40 perft 2 1271 perft 3 48022 @@ -1262,7 +1262,7 @@ perft 5 56588117 perft 6 1850696281 id 140 -epd nrqbnkbr/1p2ppp1/p1p4p/3p4/1P6/8/PQPPPPPP/1RNBNKBR w HBhb - 0 9 +epd nrqbnkbr/1p2ppp1/p1p4p/3p4/1P6/8/PQPPPPPP/1RNBNKBR w HBhb - perft 1 28 perft 2 757 perft 3 23135 @@ -1271,7 +1271,7 @@ perft 5 21427496 perft 6 650939962 id 141 -epd nrqn1bbr/2ppkppp/4p3/pB6/8/2P1P3/PP1P1PPP/NRQNK1BR w HB - 1 9 +epd nrqn1bbr/2ppkppp/4p3/pB6/8/2P1P3/PP1P1PPP/NRQNK1BR w HB - perft 1 27 perft 2 642 perft 3 17096 @@ -1280,7 +1280,7 @@ perft 5 11872805 perft 6 327545120 id 142 -epd nrqnkrb1/p1ppp2p/1p4p1/4bp2/4PP1P/4N3/PPPP2P1/NRQ1KRBB w FBfb - 1 9 +epd nrqnkrb1/p1ppp2p/1p4p1/4bp2/4PP1P/4N3/PPPP2P1/NRQ1KRBB w FBfb - perft 1 27 perft 2 958 perft 3 27397 @@ -1289,7 +1289,7 @@ perft 5 28520172 perft 6 995356563 id 143 -epd 1bnrnqkr/pbpp2pp/8/1p2pp2/P6P/3P1N2/1PP1PPP1/BBNR1QKR w HDhd - 0 9 +epd 1bnrnqkr/pbpp2pp/8/1p2pp2/P6P/3P1N2/1PP1PPP1/BBNR1QKR w HDhd - perft 1 27 perft 2 859 perft 3 23475 @@ -1298,7 +1298,7 @@ perft 5 21581178 perft 6 732696327 id 144 -epd b1rbnqkr/1pp1ppp1/2n4p/p2p4/5P2/1PBP4/P1P1P1PP/1NRBNQKR w HChc - 0 9 +epd b1rbnqkr/1pp1ppp1/2n4p/p2p4/5P2/1PBP4/P1P1P1PP/1NRBNQKR w HChc - perft 1 26 perft 2 545 perft 3 14817 @@ -1307,7 +1307,7 @@ perft 5 9537260 perft 6 233549184 id 145 -epd 1nrnqbkr/p1pppppp/1p6/8/2b2P2/P1N5/1PP1P1PP/BNR1QBKR w HChc - 2 9 +epd 1nrnqbkr/p1pppppp/1p6/8/2b2P2/P1N5/1PP1P1PP/BNR1QBKR w HChc - perft 1 24 perft 2 668 perft 3 17716 @@ -1316,7 +1316,7 @@ perft 5 14216070 perft 6 406225409 id 146 -epd 1nrnqkrb/2ppp1pp/p7/1p3p2/5P2/N5K1/PPPPP2P/B1RNQ1RB w gc - 0 9 +epd 1nrnqkrb/2ppp1pp/p7/1p3p2/5P2/N5K1/PPPPP2P/B1RNQ1RB w gc - perft 1 33 perft 2 725 perft 3 23572 @@ -1325,7 +1325,7 @@ perft 5 18547476 perft 6 471443091 id 147 -epd nbbr1qkr/p1pppppp/8/1p1n4/3P4/1N3PP1/PPP1P2P/1BBRNQKR w HDhd - 1 9 +epd nbbr1qkr/p1pppppp/8/1p1n4/3P4/1N3PP1/PPP1P2P/1BBRNQKR w HDhd - perft 1 28 perft 2 698 perft 3 20527 @@ -1334,7 +1334,7 @@ perft 5 16555068 perft 6 458045505 id 148 -epd 1rbbnqkr/1pnppp1p/p5p1/2p5/2P4P/5P2/PP1PP1PR/NRBBNQK1 w Bhb - 1 9 +epd 1rbbnqkr/1pnppp1p/p5p1/2p5/2P4P/5P2/PP1PP1PR/NRBBNQK1 w Bhb - perft 1 24 perft 2 554 perft 3 14221 @@ -1343,7 +1343,7 @@ perft 5 9863080 perft 6 269284081 id 149 -epd nrb1qbkr/2pppppp/2n5/p7/2p5/4P3/PPNP1PPP/1RBNQBKR w HBhb - 0 9 +epd nrb1qbkr/2pppppp/2n5/p7/2p5/4P3/PPNP1PPP/1RBNQBKR w HBhb - perft 1 23 perft 2 618 perft 3 15572 @@ -1352,7 +1352,7 @@ perft 5 12044358 perft 6 360311412 id 150 -epd nrb1qkrb/2ppppp1/p3n3/1p1B3p/2P5/6P1/PP1PPPRP/NRBNQK2 w Bgb - 2 9 +epd nrb1qkrb/2ppppp1/p3n3/1p1B3p/2P5/6P1/PP1PPPRP/NRBNQK2 w Bgb - perft 1 27 perft 2 593 perft 3 16770 @@ -1361,7 +1361,7 @@ perft 5 11806808 perft 6 303338935 id 151 -epd nbrn1qkr/ppp1pp2/3p2p1/3Q3P/b7/8/PPPPPP1P/NBRNB1KR w HChc - 2 9 +epd nbrn1qkr/ppp1pp2/3p2p1/3Q3P/b7/8/PPPPPP1P/NBRNB1KR w HChc - perft 1 39 perft 2 1056 perft 3 40157 @@ -1370,7 +1370,7 @@ perft 5 42201531 perft 6 1239888683 id 152 -epd nr1bbqkr/pp1pp2p/1n3pp1/2p5/8/1P4P1/P1PPPPQP/NRNBBK1R w hb - 0 9 +epd nr1bbqkr/pp1pp2p/1n3pp1/2p5/8/1P4P1/P1PPPPQP/NRNBBK1R w hb - perft 1 25 perft 2 585 perft 3 15719 @@ -1379,7 +1379,7 @@ perft 5 11582539 perft 6 320997679 id 153 -epd nr2bbkr/ppp1pppp/1n1p4/8/6PP/1NP4q/PP1PPP2/1RNQBBKR w HBhb - 1 9 +epd nr2bbkr/ppp1pppp/1n1p4/8/6PP/1NP4q/PP1PPP2/1RNQBBKR w HBhb - perft 1 22 perft 2 742 perft 3 15984 @@ -1388,7 +1388,7 @@ perft 5 13287051 perft 6 457010195 id 154 -epd 1rnqbkrb/ppp1p1p1/1n3p2/3p3p/P6P/4P3/1PPP1PP1/NRNQBRKB w gb - 0 9 +epd 1rnqbkrb/ppp1p1p1/1n3p2/3p3p/P6P/4P3/1PPP1PP1/NRNQBRKB w gb - perft 1 22 perft 2 574 perft 3 14044 @@ -1397,7 +1397,7 @@ perft 5 9968830 perft 6 281344367 id 155 -epd nb1rqkbr/1pppp1pp/4n3/p4p2/6PP/5P2/PPPPPN2/NBR1QKBR w HCh - 0 9 +epd nb1rqkbr/1pppp1pp/4n3/p4p2/6PP/5P2/PPPPPN2/NBR1QKBR w HCh - perft 1 25 perft 2 621 perft 3 16789 @@ -1406,7 +1406,7 @@ perft 5 13378840 perft 6 396575613 id 156 -epd nrnbqkbr/2pp2pp/4pp2/pp6/8/1P3P2/P1PPPBPP/NRNBQ1KR w hb - 0 9 +epd nrnbqkbr/2pp2pp/4pp2/pp6/8/1P3P2/P1PPPBPP/NRNBQ1KR w hb - perft 1 25 perft 2 656 perft 3 16951 @@ -1415,7 +1415,7 @@ perft 5 12525939 perft 6 358763789 id 157 -epd nrnqkbbr/ppppp1p1/7p/5p2/8/P4PP1/NPPPP2P/NR1QKBBR w HBhb - 0 9 +epd nrnqkbbr/ppppp1p1/7p/5p2/8/P4PP1/NPPPP2P/NR1QKBBR w HBhb - perft 1 28 perft 2 723 perft 3 20621 @@ -1424,7 +1424,7 @@ perft 5 15952533 perft 6 439046803 id 158 -epd 1rnqkr1b/ppppp2p/1n3pp1/8/2P3P1/Pb1N4/1P1PPP1P/NR1QKRBB w FBfb - 0 9 +epd 1rnqkr1b/ppppp2p/1n3pp1/8/2P3P1/Pb1N4/1P1PPP1P/NR1QKRBB w FBfb - perft 1 26 perft 2 713 perft 3 19671 @@ -1433,7 +1433,7 @@ perft 5 15865528 perft 6 454532806 id 159 -epd bbnrnkqr/1pppp1pp/5p2/p7/7P/1P6/PBPPPPPR/1BNRNKQ1 w D - 2 9 +epd bbnrnkqr/1pppp1pp/5p2/p7/7P/1P6/PBPPPPPR/1BNRNKQ1 w D - perft 1 26 perft 2 649 perft 3 17834 @@ -1442,7 +1442,7 @@ perft 5 14375839 perft 6 435585252 id 160 -epd bnrbk1qr/1ppp1ppp/p2np3/8/P7/2N2P2/1PPPP1PP/B1RBNKQR w HC - 0 9 +epd bnrbk1qr/1ppp1ppp/p2np3/8/P7/2N2P2/1PPPP1PP/B1RBNKQR w HC - perft 1 26 perft 2 621 perft 3 17569 @@ -1451,7 +1451,7 @@ perft 5 13514201 perft 6 364421088 id 161 -epd br1nkbqr/ppppppp1/8/n6p/8/N1P2PP1/PP1PP2P/B1RNKBQR w HCh - 1 9 +epd br1nkbqr/ppppppp1/8/n6p/8/N1P2PP1/PP1PP2P/B1RNKBQR w HCh - perft 1 29 perft 2 664 perft 3 20182 @@ -1460,7 +1460,7 @@ perft 5 16125924 perft 6 442508159 id 162 -epd bnr1kqrb/pp1pppp1/2n5/2p5/1P4Pp/4N3/P1PPPP1P/BNKR1QRB w gc - 0 9 +epd bnr1kqrb/pp1pppp1/2n5/2p5/1P4Pp/4N3/P1PPPP1P/BNKR1QRB w gc - perft 1 36 perft 2 888 perft 3 31630 @@ -1469,7 +1469,7 @@ perft 5 27792175 perft 6 719015345 id 163 -epd 1bbrnkqr/pp1p1ppp/2p1p3/1n6/5P2/3Q4/PPPPP1PP/NBBRNK1R w HDhd - 2 9 +epd 1bbrnkqr/pp1p1ppp/2p1p3/1n6/5P2/3Q4/PPPPP1PP/NBBRNK1R w HDhd - perft 1 36 perft 2 891 perft 3 31075 @@ -1478,7 +1478,7 @@ perft 5 26998966 perft 6 702903862 id 164 -epd nrbbnk1r/pp2pppq/8/2pp3p/3P2P1/1N6/PPP1PP1P/1RBBNKQR w HBhb - 0 9 +epd nrbbnk1r/pp2pppq/8/2pp3p/3P2P1/1N6/PPP1PP1P/1RBBNKQR w HBhb - perft 1 29 perft 2 1036 perft 3 31344 @@ -1487,7 +1487,7 @@ perft 5 35627310 perft 6 1310683359 id 165 -epd nr1nkbqr/ppp3pp/5p2/3pp3/6b1/3PP3/PPP2PPP/NRBNKBQR w hb - 0 9 +epd nr1nkbqr/ppp3pp/5p2/3pp3/6b1/3PP3/PPP2PPP/NRBNKBQR w hb - perft 1 18 perft 2 664 perft 3 13306 @@ -1496,7 +1496,7 @@ perft 5 10658989 perft 6 386307449 id 166 -epd nrbnk1rb/ppp1pq1p/3p4/5pp1/2P1P3/1N6/PP1PKPPP/1RBN1QRB w gb - 2 9 +epd nrbnk1rb/ppp1pq1p/3p4/5pp1/2P1P3/1N6/PP1PKPPP/1RBN1QRB w gb - perft 1 25 perft 2 966 perft 3 24026 @@ -1505,7 +1505,7 @@ perft 5 23957242 perft 6 913710194 id 167 -epd 1brnbkqr/pppppp2/6p1/7p/1Pn5/P1NP4/2P1PPPP/NBR1BKQR w HChc - 0 9 +epd 1brnbkqr/pppppp2/6p1/7p/1Pn5/P1NP4/2P1PPPP/NBR1BKQR w HChc - perft 1 22 perft 2 627 perft 3 13760 @@ -1514,7 +1514,7 @@ perft 5 9627826 perft 6 285900573 id 168 -epd nrnbbk1r/p1pppppq/8/7p/1p6/P5PP/1PPPPPQ1/NRNBBK1R w HBhb - 2 9 +epd nrnbbk1r/p1pppppq/8/7p/1p6/P5PP/1PPPPPQ1/NRNBBK1R w HBhb - perft 1 29 perft 2 888 perft 3 26742 @@ -1523,7 +1523,7 @@ perft 5 27229468 perft 6 930799376 id 169 -epd n1nkb1qr/prppppbp/6p1/1p6/2P2P2/P7/1P1PP1PP/NRNKBBQR w HBh - 1 9 +epd n1nkb1qr/prppppbp/6p1/1p6/2P2P2/P7/1P1PP1PP/NRNKBBQR w HBh - perft 1 29 perft 2 804 perft 3 24701 @@ -1532,7 +1532,7 @@ perft 5 21952444 perft 6 623156747 id 170 -epd nr2bqrb/ppkpp1pp/1np5/5p1P/5P2/2P5/PP1PP1P1/NRNKBQRB w GB - 0 9 +epd nr2bqrb/ppkpp1pp/1np5/5p1P/5P2/2P5/PP1PP1P1/NRNKBQRB w GB - perft 1 22 perft 2 530 perft 3 13055 @@ -1541,7 +1541,7 @@ perft 5 9244693 perft 6 264088392 id 171 -epd nbr1kqbr/p3pppp/2ppn3/1p4P1/4P3/1P6/P1PP1P1P/NBRNKQBR w HChc - 1 9 +epd nbr1kqbr/p3pppp/2ppn3/1p4P1/4P3/1P6/P1PP1P1P/NBRNKQBR w HChc - perft 1 23 perft 2 555 perft 3 14291 @@ -1550,7 +1550,7 @@ perft 5 9692630 perft 6 247479180 id 172 -epd nr1bkqbr/1p1pp1pp/pnp2p2/8/6P1/P1PP4/1P2PP1P/NRNBKQBR w HBhb - 0 9 +epd nr1bkqbr/1p1pp1pp/pnp2p2/8/6P1/P1PP4/1P2PP1P/NRNBKQBR w HBhb - perft 1 22 perft 2 565 perft 3 13343 @@ -1559,7 +1559,7 @@ perft 5 9305533 perft 6 268612479 id 173 -epd nr1kqbbr/np2pppp/p1p5/1B1p1P2/8/4P3/PPPP2PP/NRNKQ1BR w HBhb - 0 9 +epd nr1kqbbr/np2pppp/p1p5/1B1p1P2/8/4P3/PPPP2PP/NRNKQ1BR w HBhb - perft 1 32 perft 2 730 perft 3 23391 @@ -1568,7 +1568,7 @@ perft 5 18103280 perft 6 454569900 id 174 -epd nrnk1rbb/p1p2ppp/3pq3/Qp2p3/1P1P4/8/P1P1PPPP/NRN1KRBB w fb - 2 9 +epd nrnk1rbb/p1p2ppp/3pq3/Qp2p3/1P1P4/8/P1P1PPPP/NRN1KRBB w fb - perft 1 28 perft 2 873 perft 3 25683 @@ -1577,7 +1577,7 @@ perft 5 23868737 perft 6 747991356 id 175 -epd bbnrnkrq/pp1ppp1p/6p1/2p5/6P1/P5RP/1PPPPP2/BBNRNK1Q w Dgd - 3 9 +epd bbnrnkrq/pp1ppp1p/6p1/2p5/6P1/P5RP/1PPPPP2/BBNRNK1Q w Dgd - perft 1 37 perft 2 1260 perft 3 45060 @@ -1586,7 +1586,7 @@ perft 5 54843403 perft 6 1898432768 id 176 -epd bnrb1rkq/ppnpppp1/3Q4/2p4p/7P/N7/PPPPPPP1/B1RBNKR1 w GC - 2 9 +epd bnrb1rkq/ppnpppp1/3Q4/2p4p/7P/N7/PPPPPPP1/B1RBNKR1 w GC - perft 1 38 perft 2 878 perft 3 31944 @@ -1595,7 +1595,7 @@ perft 5 28784300 perft 6 784569826 id 177 -epd bnrnkbrq/p1ppppp1/1p5p/8/P2PP3/5P2/1PP3PP/BNRNKBRQ w GCgc - 1 9 +epd bnrnkbrq/p1ppppp1/1p5p/8/P2PP3/5P2/1PP3PP/BNRNKBRQ w GCgc - perft 1 26 perft 2 617 perft 3 16992 @@ -1604,7 +1604,7 @@ perft 5 11965544 perft 6 311309576 id 178 -epd bnrnkrqb/pp2p2p/2pp1pp1/8/P7/2PP1P2/1P2P1PP/BNRNKRQB w FCfc - 0 9 +epd bnrnkrqb/pp2p2p/2pp1pp1/8/P7/2PP1P2/1P2P1PP/BNRNKRQB w FCfc - perft 1 26 perft 2 721 perft 3 19726 @@ -1613,7 +1613,7 @@ perft 5 15966934 perft 6 467132503 id 179 -epd nbbrnkr1/1pppp1p1/p6q/P4p1p/8/5P2/1PPPP1PP/NBBRNRKQ w gd - 2 9 +epd nbbrnkr1/1pppp1p1/p6q/P4p1p/8/5P2/1PPPP1PP/NBBRNRKQ w gd - perft 1 18 perft 2 556 perft 3 10484 @@ -1622,7 +1622,7 @@ perft 5 6629293 perft 6 202528241 id 180 -epd nrb1nkrq/2pp1ppp/p4b2/1p2p3/P4B2/3P4/1PP1PPPP/NR1BNRKQ w gb - 0 9 +epd nrb1nkrq/2pp1ppp/p4b2/1p2p3/P4B2/3P4/1PP1PPPP/NR1BNRKQ w gb - perft 1 24 perft 2 562 perft 3 14017 @@ -1631,7 +1631,7 @@ perft 5 9227883 perft 6 247634489 id 181 -epd nrbnkbrq/p3p1pp/1p6/2pp1P2/8/3PP3/PPP2P1P/NRBNKBRQ w GBgb - 0 9 +epd nrbnkbrq/p3p1pp/1p6/2pp1P2/8/3PP3/PPP2P1P/NRBNKBRQ w GBgb - perft 1 31 perft 2 746 perft 3 24819 @@ -1640,7 +1640,7 @@ perft 5 21019301 perft 6 542954168 id 182 -epd nrbnkrqb/pppp1p1p/4p1p1/8/7P/2P1P3/PPNP1PP1/1RBNKRQB w FBfb - 0 9 +epd nrbnkrqb/pppp1p1p/4p1p1/8/7P/2P1P3/PPNP1PP1/1RBNKRQB w FBfb - perft 1 20 perft 2 459 perft 3 9998 @@ -1649,7 +1649,7 @@ perft 5 5760165 perft 6 146614723 id 183 -epd nbrn1krq/ppp1p2p/6b1/3p1pp1/8/4N1PP/PPPPPP2/NBR1BRKQ w gc - 1 9 +epd nbrn1krq/ppp1p2p/6b1/3p1pp1/8/4N1PP/PPPPPP2/NBR1BRKQ w gc - perft 1 27 perft 2 835 perft 3 23632 @@ -1658,7 +1658,7 @@ perft 5 22667987 perft 6 760795567 id 184 -epd nrnbbkrq/p1pp2pp/5p2/1p6/2P1pP1B/1P6/P2PP1PP/NRNB1KRQ w GBgb - 0 9 +epd nrnbbkrq/p1pp2pp/5p2/1p6/2P1pP1B/1P6/P2PP1PP/NRNB1KRQ w GBgb - perft 1 24 perft 2 646 perft 3 16102 @@ -1667,7 +1667,7 @@ perft 5 11489727 perft 6 324948755 id 185 -epd nrn1bbrq/1ppkppp1/p2p3p/8/1P3N2/4P3/P1PP1PPP/NR1KBBRQ w GB - 2 9 +epd nrn1bbrq/1ppkppp1/p2p3p/8/1P3N2/4P3/P1PP1PPP/NR1KBBRQ w GB - perft 1 32 perft 2 591 perft 3 18722 @@ -1676,7 +1676,7 @@ perft 5 12069159 perft 6 269922838 id 186 -epd n1krbrqb/1ppppppp/p7/8/4n3/P4P1P/1PPPPQP1/NRNKBR1B w FB - 2 9 +epd n1krbrqb/1ppppppp/p7/8/4n3/P4P1P/1PPPPQP1/NRNKBR1B w FB - perft 1 26 perft 2 639 perft 3 16988 @@ -1685,7 +1685,7 @@ perft 5 12167153 perft 6 312633873 id 187 -epd n1rnkrbq/1p1ppp1p/8/p1p1b1p1/3PQ1P1/4N3/PPP1PP1P/NBR1KRB1 w FCfc - 0 9 +epd n1rnkrbq/1p1ppp1p/8/p1p1b1p1/3PQ1P1/4N3/PPP1PP1P/NBR1KRB1 w FCfc - perft 1 35 perft 2 1027 perft 3 35731 @@ -1694,7 +1694,7 @@ perft 5 35738410 perft 6 1060661628 id 188 -epd nrnbkrbq/2pp1pp1/pp6/4p2p/P7/5PPP/1PPPP3/NRNBKRBQ w FBfb - 0 9 +epd nrnbkrbq/2pp1pp1/pp6/4p2p/P7/5PPP/1PPPP3/NRNBKRBQ w FBfb - perft 1 26 perft 2 628 perft 3 16731 @@ -1703,7 +1703,7 @@ perft 5 11920087 perft 6 331498921 id 189 -epd 1rnkrbbq/pp1p2pp/1n3p2/1Bp1p3/1P6/1N2P3/P1PP1PPP/1RNKR1BQ w EBeb - 0 9 +epd 1rnkrbbq/pp1p2pp/1n3p2/1Bp1p3/1P6/1N2P3/P1PP1PPP/1RNKR1BQ w EBeb - perft 1 33 perft 2 992 perft 3 32244 @@ -1712,7 +1712,7 @@ perft 5 31703749 perft 6 980306735 id 190 -epd nr1krqbb/p1ppppp1/8/1p5p/1Pn5/5P2/P1PPP1PP/NRNKRQBB w EBeb - 0 9 +epd nr1krqbb/p1ppppp1/8/1p5p/1Pn5/5P2/P1PPP1PP/NRNKRQBB w EBeb - perft 1 24 perft 2 670 perft 3 15985 @@ -1721,7 +1721,7 @@ perft 5 11371067 perft 6 325556465 id 191 -epd bbq1rkr1/1ppppppp/p1n2n2/8/2P2P2/1P6/PQ1PP1PP/BB1NRKNR w HEe - 3 9 +epd bbq1rkr1/1ppppppp/p1n2n2/8/2P2P2/1P6/PQ1PP1PP/BB1NRKNR w HEe - perft 1 32 perft 2 794 perft 3 26846 @@ -1730,7 +1730,7 @@ perft 5 24085223 perft 6 645633370 id 192 -epd b1nbrknr/1qppp1pp/p4p2/1p6/6P1/P2NP3/1PPP1P1P/BQ1BRKNR w HEhe - 1 9 +epd b1nbrknr/1qppp1pp/p4p2/1p6/6P1/P2NP3/1PPP1P1P/BQ1BRKNR w HEhe - perft 1 25 perft 2 663 perft 3 17138 @@ -1739,7 +1739,7 @@ perft 5 13157826 perft 6 389603029 id 193 -epd bqnrk1nr/pp2ppbp/6p1/2pp4/2P5/5P2/PPQPP1PP/B1NRKBNR w HDhd - 0 9 +epd bqnrk1nr/pp2ppbp/6p1/2pp4/2P5/5P2/PPQPP1PP/B1NRKBNR w HDhd - perft 1 26 perft 2 850 perft 3 22876 @@ -1748,7 +1748,7 @@ perft 5 21341087 perft 6 719712622 id 194 -epd bqnrknrb/1ppp1p1p/p7/6p1/1P2p3/P1PN4/3PPPPP/BQ1RKNRB w GDgd - 0 9 +epd bqnrknrb/1ppp1p1p/p7/6p1/1P2p3/P1PN4/3PPPPP/BQ1RKNRB w GDgd - perft 1 25 perft 2 721 perft 3 19290 @@ -1757,7 +1757,7 @@ perft 5 16391601 perft 6 511725087 id 195 -epd q1b1rknr/pp1pppp1/4n2p/2p1b3/1PP5/4P3/PQ1P1PPP/1BBNRKNR w HEhe - 1 9 +epd q1b1rknr/pp1pppp1/4n2p/2p1b3/1PP5/4P3/PQ1P1PPP/1BBNRKNR w HEhe - perft 1 32 perft 2 975 perft 3 32566 @@ -1766,7 +1766,7 @@ perft 5 32649943 perft 6 962536105 id 196 -epd qnbbrknr/1p1ppppp/8/p1p5/5P2/PP1P4/2P1P1PP/QNBBRKNR w HEhe - 0 9 +epd qnbbrknr/1p1ppppp/8/p1p5/5P2/PP1P4/2P1P1PP/QNBBRKNR w HEhe - perft 1 27 perft 2 573 perft 3 16331 @@ -1775,7 +1775,7 @@ perft 5 11562434 perft 6 301166330 id 197 -epd q1brkb1r/p1pppppp/np3B2/8/6n1/1P5N/P1PPPPPP/QN1RKB1R w HDhd - 0 9 +epd q1brkb1r/p1pppppp/np3B2/8/6n1/1P5N/P1PPPPPP/QN1RKB1R w HDhd - perft 1 32 perft 2 984 perft 3 31549 @@ -1784,7 +1784,7 @@ perft 5 32597704 perft 6 1075429389 id 198 -epd qn1rk1rb/p1pppppp/1p2n3/8/2b5/4NPP1/PPPPP1RP/QNBRK2B w Dgd - 4 9 +epd qn1rk1rb/p1pppppp/1p2n3/8/2b5/4NPP1/PPPPP1RP/QNBRK2B w Dgd - perft 1 22 perft 2 802 perft 3 19156 @@ -1793,7 +1793,7 @@ perft 5 17761431 perft 6 650603534 id 199 -epd qbnrbknr/ppp2p1p/8/3pp1p1/1PP1B3/5N2/P2PPPPP/Q1NRBK1R w HDhd - 0 9 +epd qbnrbknr/ppp2p1p/8/3pp1p1/1PP1B3/5N2/P2PPPPP/Q1NRBK1R w HDhd - perft 1 34 perft 2 943 perft 3 32506 @@ -1802,7 +1802,7 @@ perft 5 32523099 perft 6 955802240 id 200 -epd qnrbb1nr/pp1p1ppp/2p2k2/4p3/4P3/5PPP/PPPP4/QNRBBKNR w HC - 0 9 +epd qnrbb1nr/pp1p1ppp/2p2k2/4p3/4P3/5PPP/PPPP4/QNRBBKNR w HC - perft 1 20 perft 2 460 perft 3 10287 @@ -1811,7 +1811,7 @@ perft 5 5846781 perft 6 140714047 id 201 -epd qnr1bbnr/ppk1p1pp/3p4/2p2p2/8/2P5/PP1PPPPP/QNKRBBNR w - - 1 9 +epd qnr1bbnr/ppk1p1pp/3p4/2p2p2/8/2P5/PP1PPPPP/QNKRBBNR w - - perft 1 19 perft 2 572 perft 3 11834 @@ -1820,7 +1820,7 @@ perft 5 7994547 perft 6 243724815 id 202 -epd qnrkbnrb/1p1p1ppp/2p5/4p3/p7/N1BP4/PPP1PPPP/Q1R1KNRB w gc - 0 9 +epd qnrkbnrb/1p1p1ppp/2p5/4p3/p7/N1BP4/PPP1PPPP/Q1R1KNRB w gc - perft 1 27 perft 2 579 perft 3 16233 @@ -1829,7 +1829,7 @@ perft 5 10845146 perft 6 268229097 id 203 -epd qbnrkn1r/1pppp1p1/p3bp2/2BN3p/8/5P2/PPPPP1PP/QBNRK2R w HDhd - 0 9 +epd qbnrkn1r/1pppp1p1/p3bp2/2BN3p/8/5P2/PPPPP1PP/QBNRK2R w HDhd - perft 1 40 perft 2 1027 perft 3 38728 @@ -1838,7 +1838,7 @@ perft 5 38511307 perft 6 1104094381 id 204 -epd qnrbknbr/1pp2ppp/4p3/p6N/2p5/8/PPPPPPPP/Q1RBK1BR w HChc - 0 9 +epd qnrbknbr/1pp2ppp/4p3/p6N/2p5/8/PPPPPPPP/Q1RBK1BR w HChc - perft 1 22 perft 2 510 perft 3 11844 @@ -1847,7 +1847,7 @@ perft 5 7403327 perft 6 200581103 id 205 -epd 1qkrnbbr/p1pppppp/2n5/1p6/8/5NP1/PPPPPP1P/QNRK1BBR w HC - 4 9 +epd 1qkrnbbr/p1pppppp/2n5/1p6/8/5NP1/PPPPPP1P/QNRK1BBR w HC - perft 1 24 perft 2 549 perft 3 13987 @@ -1856,7 +1856,7 @@ perft 5 9396521 perft 6 255676649 id 206 -epd q1rknr1b/1ppppppb/2n5/p2B3p/8/1PN3P1/P1PPPP1P/Q1RKNRB1 w FCfc - 3 9 +epd q1rknr1b/1ppppppb/2n5/p2B3p/8/1PN3P1/P1PPPP1P/Q1RKNRB1 w FCfc - perft 1 31 perft 2 924 perft 3 28520 @@ -1865,7 +1865,7 @@ perft 5 27463479 perft 6 847726572 id 207 -epd bbnqrk1r/pp1pppp1/2p4p/8/6n1/1N1P1P2/PPP1P1PP/BBQ1RKNR w HEhe - 4 9 +epd bbnqrk1r/pp1pppp1/2p4p/8/6n1/1N1P1P2/PPP1P1PP/BBQ1RKNR w HEhe - perft 1 24 perft 2 804 perft 3 20147 @@ -1874,7 +1874,7 @@ perft 5 18024195 perft 6 595947631 id 208 -epd bn1brknr/ppp1p1pp/5p2/3p4/6qQ/3P3P/PPP1PPP1/BN1BRKNR w HEhe - 4 9 +epd bn1brknr/ppp1p1pp/5p2/3p4/6qQ/3P3P/PPP1PPP1/BN1BRKNR w HEhe - perft 1 25 perft 2 854 perft 3 22991 @@ -1883,7 +1883,7 @@ perft 5 20290974 perft 6 600195008 id 209 -epd 1nqrkbnr/2pp1ppp/pp2p3/3b4/2P5/N7/PP1PPPPP/B1QRKBNR w HDhd - 0 9 +epd 1nqrkbnr/2pp1ppp/pp2p3/3b4/2P5/N7/PP1PPPPP/B1QRKBNR w HDhd - perft 1 22 perft 2 651 perft 3 16173 @@ -1892,7 +1892,7 @@ perft 5 13133439 perft 6 390886040 id 210 -epd bnqrk1rb/1pp1pppp/p2p4/4n3/2PPP3/8/PP3PPP/BNQRKNRB w GDgd - 1 9 +epd bnqrk1rb/1pp1pppp/p2p4/4n3/2PPP3/8/PP3PPP/BNQRKNRB w GDgd - perft 1 30 perft 2 950 perft 3 28169 @@ -1901,7 +1901,7 @@ perft 5 27610213 perft 6 880739164 id 211 -epd nbb1rknr/1ppq1ppp/3p4/p3p3/4P3/1N2R3/PPPP1PPP/1BBQ1KNR w Hhe - 2 9 +epd nbb1rknr/1ppq1ppp/3p4/p3p3/4P3/1N2R3/PPPP1PPP/1BBQ1KNR w Hhe - perft 1 33 perft 2 988 perft 3 31293 @@ -1910,7 +1910,7 @@ perft 5 30894863 perft 6 985384035 id 212 -epd nqbbrknr/2ppp2p/pp4p1/5p2/7P/3P1P2/PPPBP1P1/NQ1BRKNR w HEhe - 0 9 +epd nqbbrknr/2ppp2p/pp4p1/5p2/7P/3P1P2/PPPBP1P1/NQ1BRKNR w HEhe - perft 1 27 perft 2 492 perft 3 13266 @@ -1919,7 +1919,7 @@ perft 5 7583292 perft 6 175376176 id 213 -epd 1qbrkb1r/pppppppp/8/3n4/4P1n1/PN6/1PPP1P1P/1QBRKBNR w HDhd - 3 9 +epd 1qbrkb1r/pppppppp/8/3n4/4P1n1/PN6/1PPP1P1P/1QBRKBNR w HDhd - perft 1 28 perft 2 800 perft 3 21982 @@ -1928,7 +1928,7 @@ perft 5 17313279 perft 6 507140861 id 214 -epd 1qbrknrb/1p1ppppp/1np5/8/p4P1P/4P1N1/PPPP2P1/NQBRK1RB w GDgd - 0 9 +epd 1qbrknrb/1p1ppppp/1np5/8/p4P1P/4P1N1/PPPP2P1/NQBRK1RB w GDgd - perft 1 21 perft 2 482 perft 3 10581 @@ -1937,7 +1937,7 @@ perft 5 6218644 perft 6 168704845 id 215 -epd nbqrbkr1/ppp1pppp/8/3p4/6n1/2P2PPN/PP1PP2P/NBQRBK1R w HDd - 1 9 +epd nbqrbkr1/ppp1pppp/8/3p4/6n1/2P2PPN/PP1PP2P/NBQRBK1R w HDd - perft 1 29 perft 2 921 perft 3 25748 @@ -1946,7 +1946,7 @@ perft 5 24138518 perft 6 806554650 id 216 -epd nqrb1knr/1ppbpp1p/p7/3p2p1/2P3P1/5P1P/PP1PP3/NQRBBKNR w HChc - 1 9 +epd nqrb1knr/1ppbpp1p/p7/3p2p1/2P3P1/5P1P/PP1PP3/NQRBBKNR w HChc - perft 1 31 perft 2 803 perft 3 25857 @@ -1955,7 +1955,7 @@ perft 5 21998733 perft 6 583349773 id 217 -epd 1qrkbbr1/pppp1ppp/1n3n2/4p3/5P2/1N6/PPPPP1PP/1QRKBBNR w HCc - 0 9 +epd 1qrkbbr1/pppp1ppp/1n3n2/4p3/5P2/1N6/PPPPP1PP/1QRKBBNR w HCc - perft 1 25 perft 2 715 perft 3 19118 @@ -1964,7 +1964,7 @@ perft 5 15514933 perft 6 459533767 id 218 -epd nqrkb1rb/pp2pppp/2p1n3/3p4/3PP1N1/8/PPP2PPP/NQRKB1RB w GCgc - 0 9 +epd nqrkb1rb/pp2pppp/2p1n3/3p4/3PP1N1/8/PPP2PPP/NQRKB1RB w GCgc - perft 1 26 perft 2 795 perft 3 21752 @@ -1973,7 +1973,7 @@ perft 5 19185851 perft 6 616508881 id 219 -epd nb1rknbr/pp2ppp1/8/2Bp3p/6P1/2P2P1q/PP1PP2P/NBQRKN1R w HDhd - 0 9 +epd nb1rknbr/pp2ppp1/8/2Bp3p/6P1/2P2P1q/PP1PP2P/NBQRKN1R w HDhd - perft 1 35 perft 2 1391 perft 3 43025 @@ -1982,7 +1982,7 @@ perft 5 53033675 perft 6 2139267832 id 220 -epd nqrbkn1r/pp1pp1pp/8/2p2p2/5P2/P3B2P/1PbPP1P1/NQRBKN1R w HChc - 0 9 +epd nqrbkn1r/pp1pp1pp/8/2p2p2/5P2/P3B2P/1PbPP1P1/NQRBKN1R w HChc - perft 1 23 perft 2 758 perft 3 19439 @@ -1991,7 +1991,7 @@ perft 5 18296195 perft 6 628403401 id 221 -epd nqrknbbr/pp1pppp1/7p/2p5/7P/1P1N4/P1PPPPPB/NQRK1B1R w HChc - 2 9 +epd nqrknbbr/pp1pppp1/7p/2p5/7P/1P1N4/P1PPPPPB/NQRK1B1R w HChc - perft 1 29 perft 2 824 perft 3 23137 @@ -2000,7 +2000,7 @@ perft 5 19429491 perft 6 595493802 id 222 -epd 1qrknrbb/B1p1pppp/8/1p1p4/2n2P2/1P6/P1PPP1PP/NQRKNR1B w FCfc - 0 9 +epd 1qrknrbb/B1p1pppp/8/1p1p4/2n2P2/1P6/P1PPP1PP/NQRKNR1B w FCfc - perft 1 28 perft 2 771 perft 3 20237 @@ -2009,7 +2009,7 @@ perft 5 16065378 perft 6 483037840 id 223 -epd bbnrqk1r/1ppppppp/8/7n/1p6/P6P/1BPPPPP1/1BNRQKNR w HDhd - 0 9 +epd bbnrqk1r/1ppppppp/8/7n/1p6/P6P/1BPPPPP1/1BNRQKNR w HDhd - perft 1 25 perft 2 601 perft 3 15471 @@ -2018,7 +2018,7 @@ perft 5 10697065 perft 6 289472497 id 224 -epd bnrbqknr/ppp3p1/3ppp1Q/7p/3P4/1P6/P1P1PPPP/BNRB1KNR w HChc - 0 9 +epd bnrbqknr/ppp3p1/3ppp1Q/7p/3P4/1P6/P1P1PPPP/BNRB1KNR w HChc - perft 1 32 perft 2 845 perft 3 26876 @@ -2027,7 +2027,7 @@ perft 5 23717883 perft 6 682154649 id 225 -epd bn1qkb1r/pprppppp/8/2p5/2PPP1n1/8/PPR2PPP/BN1QKBNR w Hh - 1 9 +epd bn1qkb1r/pprppppp/8/2p5/2PPP1n1/8/PPR2PPP/BN1QKBNR w Hh - perft 1 32 perft 2 856 perft 3 27829 @@ -2036,7 +2036,7 @@ perft 5 25245957 perft 6 727424329 id 226 -epd 1nrqknrb/p1pp1ppp/1p2p3/3N4/5P1P/5b2/PPPPP3/B1RQKNRB w GCgc - 2 9 +epd 1nrqknrb/p1pp1ppp/1p2p3/3N4/5P1P/5b2/PPPPP3/B1RQKNRB w GCgc - perft 1 33 perft 2 873 perft 3 27685 @@ -2045,7 +2045,7 @@ perft 5 25128076 perft 6 745401024 id 227 -epd nbbrqrk1/pppppppp/8/2N1n3/P7/6P1/1PPPPP1P/1BBRQKNR w HD - 3 9 +epd nbbrqrk1/pppppppp/8/2N1n3/P7/6P1/1PPPPP1P/1BBRQKNR w HD - perft 1 25 perft 2 555 perft 3 14339 @@ -2054,7 +2054,7 @@ perft 5 9153089 perft 6 234841945 id 228 -epd 1rbbqknr/1ppp1pp1/1n2p3/p6p/4P1P1/P6N/1PPP1P1P/NRBBQK1R w HBhb - 0 9 +epd 1rbbqknr/1ppp1pp1/1n2p3/p6p/4P1P1/P6N/1PPP1P1P/NRBBQK1R w HBhb - perft 1 25 perft 2 693 perft 3 18652 @@ -2063,7 +2063,7 @@ perft 5 15133381 perft 6 439344945 id 229 -epd nrq1kbnr/p1pbpppp/3p4/1p6/6P1/1N3N2/PPPPPP1P/1RBQKB1R w HBhb - 4 9 +epd nrq1kbnr/p1pbpppp/3p4/1p6/6P1/1N3N2/PPPPPP1P/1RBQKB1R w HBhb - perft 1 24 perft 2 648 perft 3 16640 @@ -2072,7 +2072,7 @@ perft 5 12871967 perft 6 380436777 id 230 -epd nr1qknr1/p1pppp1p/b5p1/1p6/8/P4PP1/1bPPP1RP/NRBQKN1B w Bgb - 0 9 +epd nr1qknr1/p1pppp1p/b5p1/1p6/8/P4PP1/1bPPP1RP/NRBQKN1B w Bgb - perft 1 18 perft 2 533 perft 3 11215 @@ -2081,7 +2081,7 @@ perft 5 7777833 perft 6 234905172 id 231 -epd nbrqbknr/1ppp2pp/8/4pp2/p2PP1P1/7N/PPP2P1P/NBRQBK1R w HChc - 0 9 +epd nbrqbknr/1ppp2pp/8/4pp2/p2PP1P1/7N/PPP2P1P/NBRQBK1R w HChc - perft 1 29 perft 2 803 perft 3 24416 @@ -2090,7 +2090,7 @@ perft 5 22305910 perft 6 672322762 id 232 -epd nr1b1k1r/ppp1pppp/2bp1n2/6P1/2P3q1/5P2/PP1PP2P/NRQBBKNR w HBhb - 1 9 +epd nr1b1k1r/ppp1pppp/2bp1n2/6P1/2P3q1/5P2/PP1PP2P/NRQBBKNR w HBhb - perft 1 27 perft 2 1199 perft 3 30908 @@ -2099,7 +2099,7 @@ perft 5 35121759 perft 6 1418677099 id 233 -epd nrqkbbnr/2pppp1p/p7/1p6/2P1Pp2/8/PPNP2PP/1RQKBBNR w HBhb - 0 9 +epd nrqkbbnr/2pppp1p/p7/1p6/2P1Pp2/8/PPNP2PP/1RQKBBNR w HBhb - perft 1 28 perft 2 613 perft 3 17874 @@ -2108,7 +2108,7 @@ perft 5 13097064 perft 6 345294379 id 234 -epd 1rqkbnrb/pp1ppp1p/1n4p1/B1p5/3PP3/4N3/PPP2PPP/NRQK2RB w GBgb - 0 9 +epd 1rqkbnrb/pp1ppp1p/1n4p1/B1p5/3PP3/4N3/PPP2PPP/NRQK2RB w GBgb - perft 1 33 perft 2 723 perft 3 23991 @@ -2117,7 +2117,7 @@ perft 5 19715083 perft 6 535650233 id 235 -epd nbrqkn1r/1pppp2p/5pp1/p2b4/5P2/P2PN3/1PP1P1PP/NBRQK1BR w HChc - 2 9 +epd nbrqkn1r/1pppp2p/5pp1/p2b4/5P2/P2PN3/1PP1P1PP/NBRQK1BR w HChc - perft 1 23 perft 2 607 perft 3 15482 @@ -2126,7 +2126,7 @@ perft 5 11026383 perft 6 290708878 id 236 -epd nrqbknbr/pp1pppp1/8/2p4p/P3PP2/8/1PPP2PP/NRQBKNBR w HBhb - 1 9 +epd nrqbknbr/pp1pppp1/8/2p4p/P3PP2/8/1PPP2PP/NRQBKNBR w HBhb - perft 1 26 perft 2 700 perft 3 19371 @@ -2135,7 +2135,7 @@ perft 5 16058815 perft 6 485460242 id 237 -epd nrqknbbr/p2pppp1/1pp5/6Qp/3P4/1P3P2/P1P1P1PP/NR1KNBBR w HBhb - 0 9 +epd nrqknbbr/p2pppp1/1pp5/6Qp/3P4/1P3P2/P1P1P1PP/NR1KNBBR w HBhb - perft 1 40 perft 2 905 perft 3 32932 @@ -2144,7 +2144,7 @@ perft 5 29263502 perft 6 791963709 id 238 -epd nrqknrbb/1p3ppp/p2p4/2p1p3/1P6/3PP1P1/P1P2P1P/NRQKNRBB w FBfb - 0 9 +epd nrqknrbb/1p3ppp/p2p4/2p1p3/1P6/3PP1P1/P1P2P1P/NRQKNRBB w FBfb - perft 1 29 perft 2 780 perft 3 22643 @@ -2153,7 +2153,7 @@ perft 5 19532077 perft 6 593181101 id 239 -epd 1bnrkqnr/p1pppp2/7p/1p4p1/4b3/7N/PPPP1PPP/BBNRKQ1R w HDhd - 0 9 +epd 1bnrkqnr/p1pppp2/7p/1p4p1/4b3/7N/PPPP1PPP/BBNRKQ1R w HDhd - perft 1 25 perft 2 725 perft 3 19808 @@ -2162,7 +2162,7 @@ perft 5 16661676 perft 6 487354613 id 240 -epd bnrbkq1r/pp2p1pp/5n2/2pp1p2/P7/N1PP4/1P2PPPP/B1RBKQNR w HChc - 1 9 +epd bnrbkq1r/pp2p1pp/5n2/2pp1p2/P7/N1PP4/1P2PPPP/B1RBKQNR w HChc - perft 1 24 perft 2 745 perft 3 18494 @@ -2171,7 +2171,7 @@ perft 5 15079602 perft 6 488924040 id 241 -epd 2rkqbnr/p1pppppp/2b5/1pn5/1P3P1Q/2B5/P1PPP1PP/1NRK1BNR w HChc - 3 9 +epd 2rkqbnr/p1pppppp/2b5/1pn5/1P3P1Q/2B5/P1PPP1PP/1NRK1BNR w HChc - perft 1 33 perft 2 904 perft 3 30111 @@ -2180,7 +2180,7 @@ perft 5 28194726 perft 6 801757709 id 242 -epd bnrkqnrb/2pppp2/8/pp4pp/1P5P/6P1/P1PPPPB1/BNRKQNR1 w GCgc - 0 9 +epd bnrkqnrb/2pppp2/8/pp4pp/1P5P/6P1/P1PPPPB1/BNRKQNR1 w GCgc - perft 1 34 perft 2 1059 perft 3 34090 @@ -2189,7 +2189,7 @@ perft 5 33195397 perft 6 1036498304 id 243 -epd 1bbrkq1r/pppp2pp/1n2pp1n/8/2PP4/1N4P1/PP2PP1P/1BBRKQNR w HDhd - 1 9 +epd 1bbrkq1r/pppp2pp/1n2pp1n/8/2PP4/1N4P1/PP2PP1P/1BBRKQNR w HDhd - perft 1 33 perft 2 891 perft 3 28907 @@ -2198,7 +2198,7 @@ perft 5 26970098 perft 6 788040469 id 244 -epd nrbbkqnr/1p2pp1p/p1p3p1/3p4/8/1PP5/P2PPPPP/NRBBKQNR w HBhb - 0 9 +epd nrbbkqnr/1p2pp1p/p1p3p1/3p4/8/1PP5/P2PPPPP/NRBBKQNR w HBhb - perft 1 21 perft 2 567 perft 3 13212 @@ -2207,7 +2207,7 @@ perft 5 9539687 perft 6 284426039 id 245 -epd 1rbkqbr1/ppp1pppp/1n5n/3p4/3P4/1PP3P1/P3PP1P/NRBKQBNR w HBb - 1 9 +epd 1rbkqbr1/ppp1pppp/1n5n/3p4/3P4/1PP3P1/P3PP1P/NRBKQBNR w HBb - perft 1 27 perft 2 752 perft 3 20686 @@ -2216,7 +2216,7 @@ perft 5 16986290 perft 6 521817800 id 246 -epd nrbkq1rb/1ppp1pp1/4p1n1/p6p/2PP4/5P2/PPK1P1PP/NRB1QNRB w gb - 0 9 +epd nrbkq1rb/1ppp1pp1/4p1n1/p6p/2PP4/5P2/PPK1P1PP/NRB1QNRB w gb - perft 1 35 perft 2 697 perft 3 23678 @@ -2225,7 +2225,7 @@ perft 5 16906409 perft 6 390324794 id 247 -epd nbrkbqnr/p2pp1p1/5p2/1pp4p/7P/3P2P1/PPP1PP2/NBKRBQNR w hc - 0 9 +epd nbrkbqnr/p2pp1p1/5p2/1pp4p/7P/3P2P1/PPP1PP2/NBKRBQNR w hc - perft 1 25 perft 2 679 perft 3 17223 @@ -2234,7 +2234,7 @@ perft 5 12879258 perft 6 376652259 id 248 -epd nrkb1qnr/ppppp1p1/6bp/5p2/1PP1P1P1/8/P2P1P1P/NRKBBQNR w HBhb - 1 9 +epd nrkb1qnr/ppppp1p1/6bp/5p2/1PP1P1P1/8/P2P1P1P/NRKBBQNR w HBhb - perft 1 32 perft 2 761 perft 3 24586 @@ -2243,7 +2243,7 @@ perft 5 20671433 perft 6 568524724 id 249 -epd nrk1bbnr/p1q1pppp/1ppp4/8/3P3P/4K3/PPP1PPP1/NR1QBBNR w hb - 0 9 +epd nrk1bbnr/p1q1pppp/1ppp4/8/3P3P/4K3/PPP1PPP1/NR1QBBNR w hb - perft 1 30 perft 2 719 perft 3 21683 @@ -2252,7 +2252,7 @@ perft 5 16278120 perft 6 423649784 id 250 -epd nrkqbr1b/1pppp1pp/5pn1/p6N/1P3P2/8/P1PPP1PP/NRKQB1RB w GBb - 0 9 +epd nrkqbr1b/1pppp1pp/5pn1/p6N/1P3P2/8/P1PPP1PP/NRKQB1RB w GBb - perft 1 26 perft 2 494 perft 3 13815 @@ -2261,7 +2261,7 @@ perft 5 8763742 perft 6 206993496 id 251 -epd nbrkq2r/pppp1bpp/4p1n1/5p2/7P/2P3N1/PP1PPPP1/NBKRQ1BR w hc - 0 9 +epd nbrkq2r/pppp1bpp/4p1n1/5p2/7P/2P3N1/PP1PPPP1/NBKRQ1BR w hc - perft 1 27 perft 2 701 perft 3 19536 @@ -2270,7 +2270,7 @@ perft 5 15394667 perft 6 443506342 id 252 -epd nrkbqnbr/2ppp2p/pp6/5pp1/P1P5/8/1P1PPPPP/NRKBQNBR w HBhb - 0 9 +epd nrkbqnbr/2ppp2p/pp6/5pp1/P1P5/8/1P1PPPPP/NRKBQNBR w HBhb - perft 1 21 perft 2 487 perft 3 11341 @@ -2279,7 +2279,7 @@ perft 5 7218486 perft 6 193586674 id 253 -epd nr1qnbbr/pk1pppp1/1pp4p/8/3P4/5P1P/PPP1P1P1/NRKQNBBR w HB - 0 9 +epd nr1qnbbr/pk1pppp1/1pp4p/8/3P4/5P1P/PPP1P1P1/NRKQNBBR w HB - perft 1 22 perft 2 546 perft 3 13615 @@ -2288,7 +2288,7 @@ perft 5 9587439 perft 6 259830255 id 254 -epd nrkq1rbb/pp1ppp1p/2pn4/8/PP3Pp1/7P/2PPP1P1/NRKQNRBB w FBfb - 0 9 +epd nrkq1rbb/pp1ppp1p/2pn4/8/PP3Pp1/7P/2PPP1P1/NRKQNRBB w FBfb - perft 1 26 perft 2 839 perft 3 22075 @@ -2297,7 +2297,7 @@ perft 5 19867117 perft 6 658535326 id 255 -epd b2rknqr/pp1ppppp/8/2P5/n7/P7/1PPNPPPb/BBNRK1QR w HDhd - 2 9 +epd b2rknqr/pp1ppppp/8/2P5/n7/P7/1PPNPPPb/BBNRK1QR w HDhd - perft 1 24 perft 2 699 perft 3 19523 @@ -2306,7 +2306,7 @@ perft 5 17734818 perft 6 535094237 id 256 -epd bnrbknqr/pp2p2p/2p3p1/3p1p2/8/3P4/PPPNPPPP/B1RBKNQR w HChc - 0 9 +epd bnrbknqr/pp2p2p/2p3p1/3p1p2/8/3P4/PPPNPPPP/B1RBKNQR w HChc - perft 1 23 perft 2 580 perft 3 14320 @@ -2315,7 +2315,7 @@ perft 5 10133092 perft 6 288041554 id 257 -epd bnrknb1r/pppp2pp/8/4pp2/6P1/3P3P/qPP1PPQ1/BNRKNB1R w HChc - 0 9 +epd bnrknb1r/pppp2pp/8/4pp2/6P1/3P3P/qPP1PPQ1/BNRKNB1R w HChc - perft 1 28 perft 2 1100 perft 3 31813 @@ -2324,7 +2324,7 @@ perft 5 36142423 perft 6 1361341249 id 258 -epd b1rknqrb/ppp1p1p1/2np1p1p/8/4N3/6PQ/PPPPPP1P/B1RKN1RB w GCgc - 0 9 +epd b1rknqrb/ppp1p1p1/2np1p1p/8/4N3/6PQ/PPPPPP1P/B1RKN1RB w GCgc - perft 1 36 perft 2 629 perft 3 23082 @@ -2333,7 +2333,7 @@ perft 5 16897544 perft 6 367503974 id 259 -epd nb1rknqr/pbppp2p/6p1/1p3p2/5P2/3KP3/PPPP2PP/NBBR1NQR w hd - 2 9 +epd nb1rknqr/pbppp2p/6p1/1p3p2/5P2/3KP3/PPPP2PP/NBBR1NQR w hd - perft 1 18 perft 2 557 perft 3 9779 @@ -2342,7 +2342,7 @@ perft 5 5822387 perft 6 180936551 id 260 -epd nr1bknqr/1ppb1ppp/p7/3pp3/B7/2P3NP/PP1PPPP1/NRB1K1QR w HBhb - 2 9 +epd nr1bknqr/1ppb1ppp/p7/3pp3/B7/2P3NP/PP1PPPP1/NRB1K1QR w HBhb - perft 1 28 perft 2 688 perft 3 19541 @@ -2351,7 +2351,7 @@ perft 5 15153092 perft 6 425149249 id 261 -epd nrbkn2r/pppp1pqp/4p1p1/8/3P2P1/P3B3/P1P1PP1P/NR1KNBQR w HBhb - 1 9 +epd nrbkn2r/pppp1pqp/4p1p1/8/3P2P1/P3B3/P1P1PP1P/NR1KNBQR w HBhb - perft 1 32 perft 2 808 perft 3 25578 @@ -2360,7 +2360,7 @@ perft 5 22094260 perft 6 609377239 id 262 -epd nrbknqrb/2p1ppp1/1p6/p2p2Bp/1P6/3P1P2/P1P1P1PP/NR1KNQRB w GBgb - 0 9 +epd nrbknqrb/2p1ppp1/1p6/p2p2Bp/1P6/3P1P2/P1P1P1PP/NR1KNQRB w GBgb - perft 1 30 perft 2 625 perft 3 18288 @@ -2369,7 +2369,7 @@ perft 5 12225742 perft 6 301834282 id 263 -epd nbr1knqr/1pp1p1pp/3p1pb1/8/7P/5P2/PPPPPQP1/NBRKBN1R w HC - 2 9 +epd nbr1knqr/1pp1p1pp/3p1pb1/8/7P/5P2/PPPPPQP1/NBRKBN1R w HC - perft 1 29 perft 2 863 perft 3 25767 @@ -2378,7 +2378,7 @@ perft 5 24965592 perft 6 799182442 id 264 -epd n1kbbnqr/prp2ppp/1p1p4/4p3/1P2P3/3P1B2/P1P2PPP/NRK1BNQR w HBh - 2 9 +epd n1kbbnqr/prp2ppp/1p1p4/4p3/1P2P3/3P1B2/P1P2PPP/NRK1BNQR w HBh - perft 1 26 perft 2 653 perft 3 17020 @@ -2387,7 +2387,7 @@ perft 5 12187583 perft 6 336872952 id 265 -epd nrknbbqr/pp3p1p/B3p1p1/2pp4/4P3/2N3P1/PPPP1P1P/NRK1B1QR w HBhb - 0 9 +epd nrknbbqr/pp3p1p/B3p1p1/2pp4/4P3/2N3P1/PPPP1P1P/NRK1B1QR w HBhb - perft 1 29 perft 2 683 perft 3 19755 @@ -2396,7 +2396,7 @@ perft 5 14684565 perft 6 394951291 id 266 -epd n1knbqrb/pr1p1ppp/Qp6/2p1p3/4P3/6P1/PPPP1P1P/NRKNB1RB w GBg - 2 9 +epd n1knbqrb/pr1p1ppp/Qp6/2p1p3/4P3/6P1/PPPP1P1P/NRKNB1RB w GBg - perft 1 31 perft 2 552 perft 3 17197 @@ -2405,7 +2405,7 @@ perft 5 11663330 perft 6 283583340 id 267 -epd nbrknqbr/p3p1pp/1p1p1p2/2p5/2Q1PP2/8/PPPP2PP/NBRKN1BR w HChc - 0 9 +epd nbrknqbr/p3p1pp/1p1p1p2/2p5/2Q1PP2/8/PPPP2PP/NBRKN1BR w HChc - perft 1 37 perft 2 913 perft 3 32470 @@ -2414,7 +2414,7 @@ perft 5 28899548 perft 6 759875563 id 268 -epd nrkb1qbr/pp1pppp1/5n2/7p/2p5/1N1NPP2/PPPP2PP/1RKB1QBR w HBhb - 0 9 +epd nrkb1qbr/pp1pppp1/5n2/7p/2p5/1N1NPP2/PPPP2PP/1RKB1QBR w HBhb - perft 1 25 perft 2 712 perft 3 18813 @@ -2423,7 +2423,7 @@ perft 5 15045589 perft 6 445074372 id 269 -epd nrk2bbr/pppqpppp/3p4/8/1P3nP1/3P4/P1P1PP1P/NRKNQBBR w HBhb - 1 9 +epd nrk2bbr/pppqpppp/3p4/8/1P3nP1/3P4/P1P1PP1P/NRKNQBBR w HBhb - perft 1 24 perft 2 814 perft 3 19954 @@ -2432,7 +2432,7 @@ perft 5 17603960 perft 6 592121050 id 270 -epd nrknqrbb/1p2ppp1/2pp4/Q6p/P2P3P/8/1PP1PPP1/NRKN1RBB w FBfb - 0 9 +epd nrknqrbb/1p2ppp1/2pp4/Q6p/P2P3P/8/1PP1PPP1/NRKN1RBB w FBfb - perft 1 34 perft 2 513 perft 3 16111 @@ -2441,7 +2441,7 @@ perft 5 9569590 perft 6 206509331 id 271 -epd bbnrk1rq/pp2p1pp/2ppn3/5p2/8/3NNP1P/PPPPP1P1/BB1RK1RQ w GDgd - 1 9 +epd bbnrk1rq/pp2p1pp/2ppn3/5p2/8/3NNP1P/PPPPP1P1/BB1RK1RQ w GDgd - perft 1 28 perft 2 697 perft 3 20141 @@ -2450,7 +2450,7 @@ perft 5 15301879 perft 6 410843713 id 272 -epd bnrbknrq/ppppp2p/6p1/5p2/4QPP1/8/PPPPP2P/BNRBKNR1 w GCgc - 0 9 +epd bnrbknrq/ppppp2p/6p1/5p2/4QPP1/8/PPPPP2P/BNRBKNR1 w GCgc - perft 1 37 perft 2 901 perft 3 32612 @@ -2459,7 +2459,7 @@ perft 5 31385912 perft 6 903831981 id 273 -epd bnkrnbrq/ppppp1p1/B6p/5p2/8/4P3/PPPP1PPP/BNKRN1RQ w - - 0 9 +epd bnkrnbrq/ppppp1p1/B6p/5p2/8/4P3/PPPP1PPP/BNKRN1RQ w - - perft 1 26 perft 2 417 perft 3 11124 @@ -2468,7 +2468,7 @@ perft 5 5980981 perft 6 133080499 id 274 -epd bnrk1rqb/2pppp1p/3n4/pp4p1/3Q1P2/2N3P1/PPPPP2P/B1RKNR1B w FCfc - 0 9 +epd bnrk1rqb/2pppp1p/3n4/pp4p1/3Q1P2/2N3P1/PPPPP2P/B1RKNR1B w FCfc - perft 1 49 perft 2 1655 perft 3 74590 @@ -2477,7 +2477,7 @@ perft 5 107234294 perft 6 3651608327 id 275 -epd nbbrk1rq/pp2pppp/2pp4/8/2P2n2/6N1/PP1PP1PP/NBBRKR1Q w Dgd - 0 9 +epd nbbrk1rq/pp2pppp/2pp4/8/2P2n2/6N1/PP1PP1PP/NBBRKR1Q w Dgd - perft 1 28 perft 2 960 perft 3 26841 @@ -2486,7 +2486,7 @@ perft 5 26083252 perft 6 846682836 id 276 -epd nrbb2rq/pppk1ppp/4p1n1/3p4/6P1/1BP5/PP1PPPQP/NRB1KNR1 w GB - 0 9 +epd nrbb2rq/pppk1ppp/4p1n1/3p4/6P1/1BP5/PP1PPPQP/NRB1KNR1 w GB - perft 1 28 perft 2 735 perft 3 22048 @@ -2495,7 +2495,7 @@ perft 5 18588316 perft 6 512048946 id 277 -epd nrbk1brq/p1ppppp1/7p/1p6/4P1nP/P7/1PPP1PP1/NRBKNBRQ w GBgb - 0 9 +epd nrbk1brq/p1ppppp1/7p/1p6/4P1nP/P7/1PPP1PP1/NRBKNBRQ w GBgb - perft 1 22 perft 2 572 perft 3 12739 @@ -2504,7 +2504,7 @@ perft 5 8525056 perft 6 247615348 id 278 -epd nrbk1rqb/1pp2ppp/5n2/p2pp3/5B2/1N1P2P1/PPP1PP1P/1R1KNRQB w FBfb - 0 9 +epd nrbk1rqb/1pp2ppp/5n2/p2pp3/5B2/1N1P2P1/PPP1PP1P/1R1KNRQB w FBfb - perft 1 35 perft 2 927 perft 3 31559 @@ -2513,7 +2513,7 @@ perft 5 28465693 perft 6 783048748 id 279 -epd nbrkb1rq/p1pp1ppp/4n3/4p3/Pp6/6N1/1PPPPPPP/NBRKBRQ1 w Cgc - 0 9 +epd nbrkb1rq/p1pp1ppp/4n3/4p3/Pp6/6N1/1PPPPPPP/NBRKBRQ1 w Cgc - perft 1 20 perft 2 456 perft 3 10271 @@ -2522,7 +2522,7 @@ perft 5 6124625 perft 6 154766108 id 280 -epd nrkb1nrq/p2pp1pp/1pp2p2/7b/6PP/5P2/PPPPP2N/NRKBB1RQ w GBgb - 0 9 +epd nrkb1nrq/p2pp1pp/1pp2p2/7b/6PP/5P2/PPPPP2N/NRKBB1RQ w GBgb - perft 1 21 perft 2 479 perft 3 11152 @@ -2531,7 +2531,7 @@ perft 5 6696458 perft 6 165253524 id 281 -epd nr1nbbr1/pppkpp1p/6p1/3p4/P6P/1P6/1RPPPPP1/N1KNBBRQ w G - 1 9 +epd nr1nbbr1/pppkpp1p/6p1/3p4/P6P/1P6/1RPPPPP1/N1KNBBRQ w G - perft 1 20 perft 2 498 perft 3 11304 @@ -2540,7 +2540,7 @@ perft 5 7197322 perft 6 188021682 id 282 -epd nrknbrqb/3p1ppp/ppN1p3/8/6P1/8/PPPPPP1P/1RKNBRQB w FBfb - 0 9 +epd nrknbrqb/3p1ppp/ppN1p3/8/6P1/8/PPPPPP1P/1RKNBRQB w FBfb - perft 1 32 perft 2 526 perft 3 17267 @@ -2549,7 +2549,7 @@ perft 5 10755190 perft 6 220058991 id 283 -epd nbrkn1bq/p1pppr1p/1p6/5pp1/8/1N2PP2/PPPP2PP/1BKRNRBQ w c - 1 9 +epd nbrkn1bq/p1pppr1p/1p6/5pp1/8/1N2PP2/PPPP2PP/1BKRNRBQ w c - perft 1 19 perft 2 491 perft 3 10090 @@ -2558,7 +2558,7 @@ perft 5 6230616 perft 6 180748649 id 284 -epd nrkbnrbq/ppppppp1/8/8/7p/PP3P2/2PPPRPP/NRKBN1BQ w Bfb - 0 9 +epd nrkbnrbq/ppppppp1/8/8/7p/PP3P2/2PPPRPP/NRKBN1BQ w Bfb - perft 1 16 perft 2 353 perft 3 6189 @@ -2567,7 +2567,7 @@ perft 5 3008668 perft 6 82706705 id 285 -epd nrknrbbq/p4ppp/2p1p3/1p1p4/1P2P3/2P5/P1NP1PPP/1RKNRBBQ w EBeb - 0 9 +epd nrknrbbq/p4ppp/2p1p3/1p1p4/1P2P3/2P5/P1NP1PPP/1RKNRBBQ w EBeb - perft 1 29 perft 2 728 perft 3 21915 @@ -2576,7 +2576,7 @@ perft 5 18231199 perft 6 511686397 id 286 -epd nrknr1bb/pppp1p2/7p/2qPp1p1/8/1P5P/P1P1PPP1/NRKNRQBB w EBeb - 0 9 +epd nrknr1bb/pppp1p2/7p/2qPp1p1/8/1P5P/P1P1PPP1/NRKNRQBB w EBeb - perft 1 20 perft 2 714 perft 3 14336 @@ -2585,7 +2585,7 @@ perft 5 11132758 perft 6 386064577 id 287 -epd bbqnrrkn/ppp2p1p/3pp1p1/8/1PP5/2Q5/P1BPPPPP/B2NRKRN w GE - 0 9 +epd bbqnrrkn/ppp2p1p/3pp1p1/8/1PP5/2Q5/P1BPPPPP/B2NRKRN w GE - perft 1 39 perft 2 593 perft 3 23446 @@ -2594,7 +2594,7 @@ perft 5 16764576 perft 6 346185058 id 288 -epd bqn1rkrn/p1p2ppp/1p1p4/4p3/3PP2b/8/PPP2PPP/BQNBRKRN w GEge - 2 9 +epd bqn1rkrn/p1p2ppp/1p1p4/4p3/3PP2b/8/PPP2PPP/BQNBRKRN w GEge - perft 1 25 perft 2 773 perft 3 20042 @@ -2603,7 +2603,7 @@ perft 5 16632403 perft 6 515838333 id 289 -epd bqnrkb1n/p1p1pprp/3p4/1p2P1p1/2PP4/8/PP3PPP/BQNRKBRN w GDd - 1 9 +epd bqnrkb1n/p1p1pprp/3p4/1p2P1p1/2PP4/8/PP3PPP/BQNRKBRN w GDd - perft 1 31 perft 2 860 perft 3 28102 @@ -2612,7 +2612,7 @@ perft 5 27233018 perft 6 813751250 id 290 -epd bqr1krnb/ppppppp1/7p/3n4/1P4P1/P4N2/2PPPP1P/BQNRKR1B w FDf - 3 9 +epd bqr1krnb/ppppppp1/7p/3n4/1P4P1/P4N2/2PPPP1P/BQNRKR1B w FDf - perft 1 31 perft 2 709 perft 3 22936 @@ -2621,7 +2621,7 @@ perft 5 18608857 perft 6 480498340 id 291 -epd qbbn1krn/pp3ppp/4r3/2ppp3/P1P4P/8/1P1PPPP1/QBBNRKRN w GEg - 1 9 +epd qbbn1krn/pp3ppp/4r3/2ppp3/P1P4P/8/1P1PPPP1/QBBNRKRN w GEg - perft 1 26 perft 2 775 perft 3 21100 @@ -2630,7 +2630,7 @@ perft 5 18476807 perft 6 582542257 id 292 -epd qnbbrkrn/1p1pp2p/p7/2p2pp1/8/4P2P/PPPP1PPK/QNBBRR1N w ge - 0 9 +epd qnbbrkrn/1p1pp2p/p7/2p2pp1/8/4P2P/PPPP1PPK/QNBBRR1N w ge - perft 1 25 perft 2 599 perft 3 15139 @@ -2639,7 +2639,7 @@ perft 5 10260500 perft 6 279222412 id 293 -epd qnbrkbrn/1ppp2p1/p3p2p/5p2/P4P2/1P6/2PPP1PP/QNBRKBRN w GDgd - 0 9 +epd qnbrkbrn/1ppp2p1/p3p2p/5p2/P4P2/1P6/2PPP1PP/QNBRKBRN w GDgd - perft 1 27 perft 2 588 perft 3 16735 @@ -2648,7 +2648,7 @@ perft 5 11640416 perft 6 293541380 id 294 -epd 1nbrkrnb/p1pppp1p/1pq3p1/8/4P3/P1P4N/1P1P1PPP/QNBRKR1B w FDfd - 1 9 +epd 1nbrkrnb/p1pppp1p/1pq3p1/8/4P3/P1P4N/1P1P1PPP/QNBRKR1B w FDfd - perft 1 18 perft 2 609 perft 3 11789 @@ -2657,7 +2657,7 @@ perft 5 8604788 perft 6 299491047 id 295 -epd qb1r1krn/pppp2pp/1n2ppb1/4P3/7P/8/PPPP1PP1/QBNRBKRN w GDgd - 0 9 +epd qb1r1krn/pppp2pp/1n2ppb1/4P3/7P/8/PPPP1PP1/QBNRBKRN w GDgd - perft 1 20 perft 2 578 perft 3 12205 @@ -2666,7 +2666,7 @@ perft 5 7939483 perft 6 229142178 id 296 -epd qnr1bkrn/p3pppp/1bpp4/1p6/2P2PP1/8/PP1PPN1P/QNRBBKR1 w GCgc - 0 9 +epd qnr1bkrn/p3pppp/1bpp4/1p6/2P2PP1/8/PP1PPN1P/QNRBBKR1 w GCgc - perft 1 30 perft 2 865 perft 3 26617 @@ -2675,7 +2675,7 @@ perft 5 24475596 perft 6 719842237 id 297 -epd 1nkrbbrn/qppppppp/8/8/p2P4/1P5P/P1P1PPP1/QNKRBBRN w - - 0 9 +epd 1nkrbbrn/qppppppp/8/8/p2P4/1P5P/P1P1PPP1/QNKRBBRN w - - perft 1 27 perft 2 672 perft 3 18371 @@ -2684,7 +2684,7 @@ perft 5 14065717 perft 6 410130412 id 298 -epd 1qrkbrnb/ppp1p1pp/n2p4/5p2/4N3/8/PPPPPPPP/Q1RKBRNB w Ffc - 2 9 +epd 1qrkbrnb/ppp1p1pp/n2p4/5p2/4N3/8/PPPPPPPP/Q1RKBRNB w Ffc - perft 1 25 perft 2 718 perft 3 18573 @@ -2693,7 +2693,7 @@ perft 5 14404324 perft 6 424279467 id 299 -epd q1nrkrbn/pp1pppp1/2p4p/8/P7/5Pb1/BPPPPNPP/Q1NRKRB1 w FDfd - 0 9 +epd q1nrkrbn/pp1pppp1/2p4p/8/P7/5Pb1/BPPPPNPP/Q1NRKRB1 w FDfd - perft 1 22 perft 2 558 perft 3 12911 @@ -2702,7 +2702,7 @@ perft 5 8516966 perft 6 228074630 id 300 -epd qnrbkrbn/1p1p1pp1/p1p5/4p2p/8/3P1P2/PPP1P1PP/QNRBKRBN w FCfc - 0 9 +epd qnrbkrbn/1p1p1pp1/p1p5/4p2p/8/3P1P2/PPP1P1PP/QNRBKRBN w FCfc - perft 1 28 perft 2 669 perft 3 17713 @@ -2711,7 +2711,7 @@ perft 5 12055174 perft 6 313276304 id 301 -epd qnrkr1bn/p1pp1ppp/8/1p2p3/3P1P2/bP4P1/P1P1P2P/QNRKRBBN w ECec - 1 9 +epd qnrkr1bn/p1pp1ppp/8/1p2p3/3P1P2/bP4P1/P1P1P2P/QNRKRBBN w ECec - perft 1 23 perft 2 845 perft 3 20973 @@ -2720,7 +2720,7 @@ perft 5 19939053 perft 6 718075943 id 302 -epd q1krrnbb/p1p1pppp/2np4/1pB5/5P2/8/PPPPP1PP/QNRKRN1B w EC - 0 9 +epd q1krrnbb/p1p1pppp/2np4/1pB5/5P2/8/PPPPP1PP/QNRKRN1B w EC - perft 1 29 perft 2 776 perft 3 21966 @@ -2729,7 +2729,7 @@ perft 5 18110831 perft 6 549019739 id 303 -epd bbn1rkrn/pp1p1ppp/8/2p1p1q1/6P1/P7/BPPPPP1P/B1NQRKRN w GEge - 0 9 +epd bbn1rkrn/pp1p1ppp/8/2p1p1q1/6P1/P7/BPPPPP1P/B1NQRKRN w GEge - perft 1 26 perft 2 936 perft 3 25177 @@ -2738,7 +2738,7 @@ perft 5 24984621 perft 6 901444251 id 304 -epd bn1brkrn/pp1qpp1p/2p3p1/3p4/1PPP4/P7/4PPPP/BNQBRKRN w GEge - 1 9 +epd bn1brkrn/pp1qpp1p/2p3p1/3p4/1PPP4/P7/4PPPP/BNQBRKRN w GEge - perft 1 29 perft 2 755 perft 3 22858 @@ -2747,7 +2747,7 @@ perft 5 20128587 perft 6 600207069 id 305 -epd b2rkbrn/p1pppppp/qp6/8/1n6/2B2P2/P1PPP1PP/1NQRKBRN w GDgd - 0 9 +epd b2rkbrn/p1pppppp/qp6/8/1n6/2B2P2/P1PPP1PP/1NQRKBRN w GDgd - perft 1 24 perft 2 878 perft 3 21440 @@ -2756,7 +2756,7 @@ perft 5 20840078 perft 6 775795187 id 306 -epd b2rkrnb/pqp1pppp/n7/1p1p4/P7/N1P2N2/1P1PPPPP/B1QRKR1B w FDfd - 4 9 +epd b2rkrnb/pqp1pppp/n7/1p1p4/P7/N1P2N2/1P1PPPPP/B1QRKR1B w FDfd - perft 1 26 perft 2 724 perft 3 19558 @@ -2765,7 +2765,7 @@ perft 5 16109522 perft 6 492933398 id 307 -epd 1bbqrkrn/ppppp1p1/8/5p1p/P1n3P1/3P4/1PP1PP1P/NBBQRRKN w ge - 1 9 +epd 1bbqrkrn/ppppp1p1/8/5p1p/P1n3P1/3P4/1PP1PP1P/NBBQRRKN w ge - perft 1 25 perft 2 678 perft 3 17351 @@ -2774,7 +2774,7 @@ perft 5 12173245 perft 6 329661421 id 308 -epd nqb1rrkn/ppp1bppp/3pp3/8/3P4/1P6/PQP1PPPP/N1BBRRKN w - - 1 9 +epd nqb1rrkn/ppp1bppp/3pp3/8/3P4/1P6/PQP1PPPP/N1BBRRKN w - - perft 1 23 perft 2 503 perft 3 12465 @@ -2783,7 +2783,7 @@ perft 5 7626054 perft 6 188215608 id 309 -epd nqbrkbr1/p1pppppp/1p6/2N2n2/2P5/5P2/PP1PP1PP/1QBRKBRN w GDgd - 1 9 +epd nqbrkbr1/p1pppppp/1p6/2N2n2/2P5/5P2/PP1PP1PP/1QBRKBRN w GDgd - perft 1 29 perft 2 688 perft 3 20289 @@ -2792,7 +2792,7 @@ perft 5 15167248 perft 6 399015237 id 310 -epd nqbrkrn1/1ppppp2/6pp/p7/1P6/2Q5/P1PPPPPP/N1BRKRNB w FDfd - 0 9 +epd nqbrkrn1/1ppppp2/6pp/p7/1P6/2Q5/P1PPPPPP/N1BRKRNB w FDfd - perft 1 36 perft 2 602 perft 3 20985 @@ -2801,7 +2801,7 @@ perft 5 13706856 perft 6 291708797 id 311 -epd nbqrbrkn/pp1p1pp1/2p5/4p2p/2P3P1/1P3P2/P2PP2P/NBQRBKRN w GD - 0 9 +epd nbqrbrkn/pp1p1pp1/2p5/4p2p/2P3P1/1P3P2/P2PP2P/NBQRBKRN w GD - perft 1 34 perft 2 655 perft 3 22581 @@ -2810,7 +2810,7 @@ perft 5 16613630 perft 6 379344541 id 312 -epd nqrbbrkn/1p1pppp1/8/p1p4p/4P2P/1N4P1/PPPP1P2/1QRBBKRN w GC - 0 9 +epd nqrbbrkn/1p1pppp1/8/p1p4p/4P2P/1N4P1/PPPP1P2/1QRBBKRN w GC - perft 1 23 perft 2 597 perft 3 14468 @@ -2819,7 +2819,7 @@ perft 5 10096863 perft 6 294900903 id 313 -epd nqrkbbrn/2p1p1pp/pp1p1p2/8/P2N4/2P5/1P1PPPPP/1QRKBBRN w GCgc - 0 9 +epd nqrkbbrn/2p1p1pp/pp1p1p2/8/P2N4/2P5/1P1PPPPP/1QRKBBRN w GCgc - perft 1 32 perft 2 744 perft 3 23310 @@ -2828,7 +2828,7 @@ perft 5 17597164 perft 6 428786656 id 314 -epd n1krbrnb/q1pppppp/p7/1p6/3Q4/2P2P2/PP1PP1PP/N1RKBRNB w FC - 1 9 +epd n1krbrnb/q1pppppp/p7/1p6/3Q4/2P2P2/PP1PP1PP/N1RKBRNB w FC - perft 1 43 perft 2 1038 perft 3 41327 @@ -2837,7 +2837,7 @@ perft 5 40918952 perft 6 1126603824 id 315 -epd nb1rkrbn/p1pp1p1p/qp6/4p1p1/5PP1/P7/1PPPPB1P/NBQRKR1N w FDfd - 2 9 +epd nb1rkrbn/p1pp1p1p/qp6/4p1p1/5PP1/P7/1PPPPB1P/NBQRKR1N w FDfd - perft 1 26 perft 2 645 perft 3 16463 @@ -2846,7 +2846,7 @@ perft 5 11911314 perft 6 342563372 id 316 -epd nqr1krbn/pppp1ppp/8/8/3pP3/5P2/PPPb1NPP/NQRBKRB1 w FCfc - 3 9 +epd nqr1krbn/pppp1ppp/8/8/3pP3/5P2/PPPb1NPP/NQRBKRB1 w FCfc - perft 1 2 perft 2 51 perft 3 1047 @@ -2855,7 +2855,7 @@ perft 5 612305 perft 6 17040200 id 317 -epd n1rkrbbn/pqppppp1/7p/1p6/8/1NPP4/PP1KPPPP/1QR1RBBN w ec - 0 9 +epd n1rkrbbn/pqppppp1/7p/1p6/8/1NPP4/PP1KPPPP/1QR1RBBN w ec - perft 1 25 perft 2 674 perft 3 17553 @@ -2864,7 +2864,7 @@ perft 5 13421727 perft 6 403551903 id 318 -epd 1qrkrnbb/1p1p1ppp/pnp1p3/8/3PP3/P6P/1PP2PP1/NQRKRNBB w ECec - 0 9 +epd 1qrkrnbb/1p1p1ppp/pnp1p3/8/3PP3/P6P/1PP2PP1/NQRKRNBB w ECec - perft 1 24 perft 2 688 perft 3 17342 @@ -2873,7 +2873,7 @@ perft 5 13322502 perft 6 403441498 id 319 -epd 1bnrqkrn/2ppppp1/p7/1p1b3p/3PP1P1/8/PPPQ1P1P/BBNR1KRN w GDgd - 1 9 +epd 1bnrqkrn/2ppppp1/p7/1p1b3p/3PP1P1/8/PPPQ1P1P/BBNR1KRN w GDgd - perft 1 35 perft 2 925 perft 3 32238 @@ -2882,7 +2882,7 @@ perft 5 30458921 perft 6 824344087 id 320 -epd bnrbqkr1/ppp2pp1/6n1/3pp2p/1P6/2N3N1/P1PPPPPP/B1RBQRK1 w gc - 0 9 +epd bnrbqkr1/ppp2pp1/6n1/3pp2p/1P6/2N3N1/P1PPPPPP/B1RBQRK1 w gc - perft 1 23 perft 2 704 perft 3 17345 @@ -2891,7 +2891,7 @@ perft 5 14154852 perft 6 450893738 id 321 -epd 1nrqkbrn/p1pppppp/8/1p1b4/P6P/5P2/1PPPP1P1/BNRQKBRN w GCgc - 1 9 +epd 1nrqkbrn/p1pppppp/8/1p1b4/P6P/5P2/1PPPP1P1/BNRQKBRN w GCgc - perft 1 19 perft 2 505 perft 3 10619 @@ -2900,7 +2900,7 @@ perft 5 6450025 perft 6 175593967 id 322 -epd b1rqkrnb/ppppppp1/8/6p1/3n4/NP6/P1PPPP1P/B1RQKRNB w FCfc - 0 9 +epd b1rqkrnb/ppppppp1/8/6p1/3n4/NP6/P1PPPP1P/B1RQKRNB w FCfc - perft 1 25 perft 2 614 perft 3 15578 @@ -2909,7 +2909,7 @@ perft 5 10391021 perft 6 259629603 id 323 -epd nbbrqkrn/ppp3p1/3pp3/5p1p/1P2P3/P7/2PPQPPP/NBBR1KRN w GDgd - 0 9 +epd nbbrqkrn/ppp3p1/3pp3/5p1p/1P2P3/P7/2PPQPPP/NBBR1KRN w GDgd - perft 1 30 perft 2 833 perft 3 25719 @@ -2918,7 +2918,7 @@ perft 5 22873901 perft 6 649556666 id 324 -epd nr1bqrk1/ppp1pppp/6n1/3pP3/8/5PQb/PPPP2PP/NRBB1KRN w GB - 3 9 +epd nr1bqrk1/ppp1pppp/6n1/3pP3/8/5PQb/PPPP2PP/NRBB1KRN w GB - perft 1 26 perft 2 734 perft 3 20161 @@ -2927,7 +2927,7 @@ perft 5 17199594 perft 6 512134836 id 325 -epd 1rbqkbr1/ppppp1pp/1n6/4np2/3P1P2/6P1/PPPQP2P/NRB1KBRN w GBgb - 1 9 +epd 1rbqkbr1/ppppp1pp/1n6/4np2/3P1P2/6P1/PPPQP2P/NRB1KBRN w GBgb - perft 1 27 perft 2 662 perft 3 17897 @@ -2936,7 +2936,7 @@ perft 5 13038519 perft 6 338365642 id 326 -epd nr1qkr1b/ppp1pp1p/4bn2/3p2p1/4P3/1Q6/PPPP1PPP/NRB1KRNB w FBfb - 4 9 +epd nr1qkr1b/ppp1pp1p/4bn2/3p2p1/4P3/1Q6/PPPP1PPP/NRB1KRNB w FBfb - perft 1 33 perft 2 939 perft 3 30923 @@ -2945,7 +2945,7 @@ perft 5 30995969 perft 6 991509814 id 327 -epd nb1qbkrn/pprp1pp1/7p/2p1pB2/Q1PP4/8/PP2PPPP/N1R1BKRN w GCg - 2 9 +epd nb1qbkrn/pprp1pp1/7p/2p1pB2/Q1PP4/8/PP2PPPP/N1R1BKRN w GCg - perft 1 47 perft 2 1128 perft 3 50723 @@ -2954,7 +2954,7 @@ perft 5 56747878 perft 6 1560584212 id 328 -epd nrqb1rkn/pp2pppp/2bp4/2p5/6P1/2P3N1/PP1PPP1P/NRQBBRK1 w - - 3 9 +epd nrqb1rkn/pp2pppp/2bp4/2p5/6P1/2P3N1/PP1PPP1P/NRQBBRK1 w - - perft 1 24 perft 2 828 perft 3 21148 @@ -2963,7 +2963,7 @@ perft 5 19506135 perft 6 668969549 id 329 -epd nrq1bbrn/ppkpp2p/2p3p1/P4p2/8/4P1N1/1PPP1PPP/NRQKBBR1 w GB - 0 9 +epd nrq1bbrn/ppkpp2p/2p3p1/P4p2/8/4P1N1/1PPP1PPP/NRQKBBR1 w GB - perft 1 25 perft 2 525 perft 3 13533 @@ -2972,7 +2972,7 @@ perft 5 8250997 perft 6 201795680 id 330 -epd Br1kbrn1/pqpppp2/8/6pp/3b2P1/1N6/PPPPPP1P/1RQKBRN1 w FBfb - 3 9 +epd Br1kbrn1/pqpppp2/8/6pp/3b2P1/1N6/PPPPPP1P/1RQKBRN1 w FBfb - perft 1 20 perft 2 790 perft 3 18175 @@ -2981,7 +2981,7 @@ perft 5 17735648 perft 6 669854148 id 331 -epd nbrqkrbn/2p1p1pp/p7/1p1p1p2/4P1P1/5P2/PPPP3P/NBRQKRBN w FCfc - 0 9 +epd nbrqkrbn/2p1p1pp/p7/1p1p1p2/4P1P1/5P2/PPPP3P/NBRQKRBN w FCfc - perft 1 29 perft 2 771 perft 3 22489 @@ -2990,7 +2990,7 @@ perft 5 19192982 perft 6 591335970 id 332 -epd 1rqbkrbn/1ppppp1p/1n6/p1N3p1/8/2P4P/PP1PPPP1/1RQBKRBN w FBfb - 0 9 +epd 1rqbkrbn/1ppppp1p/1n6/p1N3p1/8/2P4P/PP1PPPP1/1RQBKRBN w FBfb - perft 1 29 perft 2 502 perft 3 14569 @@ -2999,7 +2999,7 @@ perft 5 8652810 perft 6 191762235 id 333 -epd 1rqkrbbn/ppnpp1pp/8/2p5/6p1/3P4/PPP1PPPP/NRK1RBBN w eb - 0 9 +epd 1rqkrbbn/ppnpp1pp/8/2p5/6p1/3P4/PPP1PPPP/NRK1RBBN w eb - perft 1 19 perft 2 531 perft 3 10812 @@ -3008,7 +3008,7 @@ perft 5 6506674 perft 6 184309316 id 334 -epd nrqkrnbb/p1pp2pp/5p2/4P3/2p5/4N3/PP1PP1PP/NRQKR1BB w EBeb - 0 9 +epd nrqkrnbb/p1pp2pp/5p2/4P3/2p5/4N3/PP1PP1PP/NRQKR1BB w EBeb - perft 1 26 perft 2 800 perft 3 23256 @@ -3017,7 +3017,7 @@ perft 5 23952941 perft 6 809841274 id 335 -epd bbnrkqrn/pp3pp1/4p2p/2pp4/4P1P1/1PB5/P1PP1P1P/1BNRKQRN w GDgd - 0 9 +epd bbnrkqrn/pp3pp1/4p2p/2pp4/4P1P1/1PB5/P1PP1P1P/1BNRKQRN w GDgd - perft 1 33 perft 2 915 perft 3 30536 @@ -3026,7 +3026,7 @@ perft 5 29602610 perft 6 881898159 id 336 -epd bnrbkqr1/1p2pppp/6n1/p1pp4/7P/P3P3/1PPPKPP1/BNRB1QRN w gc - 0 9 +epd bnrbkqr1/1p2pppp/6n1/p1pp4/7P/P3P3/1PPPKPP1/BNRB1QRN w gc - perft 1 19 perft 2 457 perft 3 9332 @@ -3035,7 +3035,7 @@ perft 5 5356253 perft 6 144653627 id 337 -epd b1rkqbrn/pp1p2pp/2n1p3/2p2p2/3P2PP/8/PPP1PP2/BNKRQBRN w gc - 0 9 +epd b1rkqbrn/pp1p2pp/2n1p3/2p2p2/3P2PP/8/PPP1PP2/BNKRQBRN w gc - perft 1 30 perft 2 985 perft 3 30831 @@ -3044,7 +3044,7 @@ perft 5 32684185 perft 6 1080607773 id 338 -epd b1rkqrnb/2ppppp1/np6/p6p/1P6/P2P3P/2P1PPP1/BNRKQRNB w FCfc - 0 9 +epd b1rkqrnb/2ppppp1/np6/p6p/1P6/P2P3P/2P1PPP1/BNRKQRNB w FCfc - perft 1 26 perft 2 692 perft 3 18732 @@ -3053,7 +3053,7 @@ perft 5 14561181 perft 6 413226841 id 339 -epd nbbrkqrn/1ppp1p2/p6p/4p1p1/5P2/1P5P/P1PPPNP1/NBBRKQR1 w GDgd - 0 9 +epd nbbrkqrn/1ppp1p2/p6p/4p1p1/5P2/1P5P/P1PPPNP1/NBBRKQR1 w GDgd - perft 1 22 perft 2 561 perft 3 13222 @@ -3062,7 +3062,7 @@ perft 5 9307003 perft 6 273928315 id 340 -epd nrbbkqrn/p1pppppp/8/1p6/4P3/7Q/PPPP1PPP/NRBBK1RN w GBgb - 0 9 +epd nrbbkqrn/p1pppppp/8/1p6/4P3/7Q/PPPP1PPP/NRBBK1RN w GBgb - perft 1 38 perft 2 769 perft 3 28418 @@ -3071,7 +3071,7 @@ perft 5 23091070 perft 6 560139600 id 341 -epd nrbkqbrn/1pppp2p/8/p4pp1/P4PQ1/8/1PPPP1PP/NRBK1BRN w GBgb - 0 9 +epd nrbkqbrn/1pppp2p/8/p4pp1/P4PQ1/8/1PPPP1PP/NRBK1BRN w GBgb - perft 1 23 perft 2 507 perft 3 13067 @@ -3080,7 +3080,7 @@ perft 5 8887567 perft 6 237475184 id 342 -epd nr1kqr1b/pp2pppp/5n2/2pp4/P5b1/5P2/1PPPPRPP/NRBK1QNB w Bfb - 2 9 +epd nr1kqr1b/pp2pppp/5n2/2pp4/P5b1/5P2/1PPPPRPP/NRBK1QNB w Bfb - perft 1 18 perft 2 626 perft 3 12386 @@ -3089,7 +3089,7 @@ perft 5 9465555 perft 6 335004239 id 343 -epd nbkrbqrn/1pppppp1/8/4P2p/pP6/P7/2PP1PPP/NBRKBQRN w GC - 0 9 +epd nbkrbqrn/1pppppp1/8/4P2p/pP6/P7/2PP1PPP/NBRKBQRN w GC - perft 1 22 perft 2 329 perft 3 8475 @@ -3098,7 +3098,7 @@ perft 5 4160034 perft 6 82875306 id 344 -epd nrkb1qrn/pp1pp1pp/8/5p1b/P1p4P/6N1/1PPPPPP1/NRKBBQR1 w GBgb - 2 9 +epd nrkb1qrn/pp1pp1pp/8/5p1b/P1p4P/6N1/1PPPPPP1/NRKBBQR1 w GBgb - perft 1 16 perft 2 479 perft 3 9037 @@ -3107,7 +3107,7 @@ perft 5 5862341 perft 6 184959796 id 345 -epd 1rkq1brn/ppppp1pp/1n6/3b1p2/3N3P/5P2/PPPPP1P1/1RKQBBRN w GBgb - 3 9 +epd 1rkq1brn/ppppp1pp/1n6/3b1p2/3N3P/5P2/PPPPP1P1/1RKQBBRN w GBgb - perft 1 23 perft 2 614 perft 3 15324 @@ -3116,7 +3116,7 @@ perft 5 11090645 perft 6 313526088 id 346 -epd nrk1brnb/pp1ppppp/2p5/3q4/5P2/PP6/1KPPP1PP/NR1QBRNB w fb - 1 9 +epd nrk1brnb/pp1ppppp/2p5/3q4/5P2/PP6/1KPPP1PP/NR1QBRNB w fb - perft 1 25 perft 2 942 perft 3 21765 @@ -3125,7 +3125,7 @@ perft 5 19318837 perft 6 685549171 id 347 -epd nbrkqr1n/1pppp2p/p4pp1/2Bb4/5P2/6P1/PPPPP2P/NBRKQ1RN w Cfc - 2 9 +epd nbrkqr1n/1pppp2p/p4pp1/2Bb4/5P2/6P1/PPPPP2P/NBRKQ1RN w Cfc - perft 1 30 perft 2 841 perft 3 24775 @@ -3134,7 +3134,7 @@ perft 5 20145765 perft 6 557578726 id 348 -epd n1kbqrbn/2p1pppp/1r6/pp1p4/P7/3P4/1PP1PPPP/NRKBQRBN w FBf - 2 9 +epd n1kbqrbn/2p1pppp/1r6/pp1p4/P7/3P4/1PP1PPPP/NRKBQRBN w FBf - perft 1 21 perft 2 591 perft 3 14101 @@ -3143,7 +3143,7 @@ perft 5 10295086 perft 6 292131422 id 349 -epd nrkqrbb1/ppp1pppp/3p4/8/4P3/2Pn1P2/PP4PP/NRKQRBBN w EBeb - 0 9 +epd nrkqrbb1/ppp1pppp/3p4/8/4P3/2Pn1P2/PP4PP/NRKQRBBN w EBeb - perft 1 4 perft 2 88 perft 3 3090 @@ -3152,7 +3152,7 @@ perft 5 2640555 perft 6 66958031 id 350 -epd nrkqrnbb/ppppp1p1/7p/1P3p2/3P4/2P5/P3PPPP/NRKQRNBB w EBeb - 0 9 +epd nrkqrnbb/ppppp1p1/7p/1P3p2/3P4/2P5/P3PPPP/NRKQRNBB w EBeb - perft 1 29 perft 2 689 perft 3 21091 @@ -3161,7 +3161,7 @@ perft 5 16226660 perft 6 408570219 id 351 -epd bbnr1rqn/pp2pkpp/2pp1p2/8/4P1P1/8/PPPP1P1P/BBNRKRQN w FD - 0 9 +epd bbnr1rqn/pp2pkpp/2pp1p2/8/4P1P1/8/PPPP1P1P/BBNRKRQN w FD - perft 1 21 perft 2 463 perft 3 11135 @@ -3170,7 +3170,7 @@ perft 5 6826249 perft 6 165025370 id 352 -epd bnrbk1qn/1pppprpp/8/p4p1P/6P1/3P4/PPP1PP2/BNRBKRQN w FCc - 0 9 +epd bnrbk1qn/1pppprpp/8/p4p1P/6P1/3P4/PPP1PP2/BNRBKRQN w FCc - perft 1 22 perft 2 459 perft 3 11447 @@ -3179,7 +3179,7 @@ perft 5 7371098 perft 6 190583454 id 353 -epd 1nrkrbqn/p1pp1ppp/4p3/1p6/1PP5/6PB/P2PPPbP/BNRKR1QN w ECec - 0 9 +epd 1nrkrbqn/p1pp1ppp/4p3/1p6/1PP5/6PB/P2PPPbP/BNRKR1QN w ECec - perft 1 30 perft 2 931 perft 3 29012 @@ -3188,7 +3188,7 @@ perft 5 28412902 perft 6 869228014 id 354 -epd b1rkr1nb/pppppqp1/n4B2/7p/8/1P4P1/P1PPPP1P/1NKRRQNB w ec - 1 9 +epd b1rkr1nb/pppppqp1/n4B2/7p/8/1P4P1/P1PPPP1P/1NKRRQNB w ec - perft 1 36 perft 2 934 perft 3 31790 @@ -3197,7 +3197,7 @@ perft 5 30392925 perft 6 952871799 id 355 -epd nbbrkrqn/p1ppp1p1/8/1p3p1p/2P3PP/8/PP1PPPQ1/NBBRKR1N w FDfd - 0 9 +epd nbbrkrqn/p1ppp1p1/8/1p3p1p/2P3PP/8/PP1PPPQ1/NBBRKR1N w FDfd - perft 1 34 perft 2 938 perft 3 31848 @@ -3206,7 +3206,7 @@ perft 5 31185844 perft 6 944483246 id 356 -epd 1rbbkrqn/ppp1pp2/1n1p2p1/7p/P3P1P1/3P4/1PP2P1P/NRBBKRQN w FBfb - 0 9 +epd 1rbbkrqn/ppp1pp2/1n1p2p1/7p/P3P1P1/3P4/1PP2P1P/NRBBKRQN w FBfb - perft 1 26 perft 2 646 perft 3 18083 @@ -3215,7 +3215,7 @@ perft 5 14006203 perft 6 384101783 id 357 -epd nrbkrbq1/Qpppp1pp/2n5/5p2/P4P2/6N1/1PPPP1PP/NRBKRB2 w EBeb - 1 9 +epd nrbkrbq1/Qpppp1pp/2n5/5p2/P4P2/6N1/1PPPP1PP/NRBKRB2 w EBeb - perft 1 27 perft 2 619 perft 3 16713 @@ -3224,7 +3224,7 @@ perft 5 11718463 perft 6 313794027 id 358 -epd 1rbkr1nb/pppp1qpp/1n6/4pp2/1PP1P3/8/PB1P1PPP/NR1KRQNB w EBeb - 1 9 +epd 1rbkr1nb/pppp1qpp/1n6/4pp2/1PP1P3/8/PB1P1PPP/NR1KRQNB w EBeb - perft 1 32 perft 2 1029 perft 3 32970 @@ -3233,7 +3233,7 @@ perft 5 35483796 perft 6 1181835398 id 359 -epd nbrk1rqn/p1ppp2p/1p6/5ppb/8/1N2P2P/PPPP1PP1/1BKRBRQN w fc - 0 9 +epd nbrk1rqn/p1ppp2p/1p6/5ppb/8/1N2P2P/PPPP1PP1/1BKRBRQN w fc - perft 1 18 perft 2 594 perft 3 12350 @@ -3242,7 +3242,7 @@ perft 5 9329122 perft 6 315021712 id 360 -epd nrkbbrqn/3pppp1/7p/ppp5/P7/1N5P/1PPPPPP1/1RKBBRQN w FBfb - 0 9 +epd nrkbbrqn/3pppp1/7p/ppp5/P7/1N5P/1PPPPPP1/1RKBBRQN w FBfb - perft 1 19 perft 2 417 perft 3 9026 @@ -3251,7 +3251,7 @@ perft 5 5236331 perft 6 137024458 id 361 -epd nrkr1bqn/ppp1pppp/3p4/1b6/7P/P7/1PPPPPP1/NRKRBBQN w DBdb - 1 9 +epd nrkr1bqn/ppp1pppp/3p4/1b6/7P/P7/1PPPPPP1/NRKRBBQN w DBdb - perft 1 17 perft 2 457 perft 3 9083 @@ -3260,7 +3260,7 @@ perft 5 5503579 perft 6 150091997 id 362 -epd nrkrbqnb/p4ppp/1p2p3/2pp4/6P1/2P2N2/PPNPPP1P/1RKRBQ1B w DBdb - 0 9 +epd nrkrbqnb/p4ppp/1p2p3/2pp4/6P1/2P2N2/PPNPPP1P/1RKRBQ1B w DBdb - perft 1 27 perft 2 755 perft 3 21012 @@ -3269,7 +3269,7 @@ perft 5 17883987 perft 6 547233320 id 363 -epd nbkrr1bn/ppB2ppp/4p3/2qp4/4P3/5P2/PPPP2PP/NBRKRQ1N w EC - 1 9 +epd nbkrr1bn/ppB2ppp/4p3/2qp4/4P3/5P2/PPPP2PP/NBRKRQ1N w EC - perft 1 37 perft 2 1473 perft 3 51939 @@ -3278,7 +3278,7 @@ perft 5 68070015 perft 6 2490912491 id 364 -epd n1kbrqbn/p1pp1pp1/4p2p/2B5/1r3P2/8/PPPPP1PP/NRKBRQ1N w EBe - 2 9 +epd n1kbrqbn/p1pp1pp1/4p2p/2B5/1r3P2/8/PPPPP1PP/NRKBRQ1N w EBe - perft 1 30 perft 2 1029 perft 3 30874 @@ -3287,7 +3287,7 @@ perft 5 32318550 perft 6 1106487743 id 365 -epd nrkrqbbn/2pppp1p/8/pp6/1P1P2p1/P5P1/2P1PP1P/NRKRQBBN w DBdb - 0 9 +epd nrkrqbbn/2pppp1p/8/pp6/1P1P2p1/P5P1/2P1PP1P/NRKRQBBN w DBdb - perft 1 22 perft 2 421 perft 3 10034 @@ -3296,7 +3296,7 @@ perft 5 5754555 perft 6 141245633 id 366 -epd nrkr1nbb/1ppp2pp/p3q3/4pp2/2P5/P3P3/1PKP1PPP/NR1RQNBB w db - 0 9 +epd nrkr1nbb/1ppp2pp/p3q3/4pp2/2P5/P3P3/1PKP1PPP/NR1RQNBB w db - perft 1 22 perft 2 619 perft 3 13953 @@ -3305,7 +3305,7 @@ perft 5 9905109 perft 6 301403003 id 367 -epd bbnrkrnq/1pp1p2p/6p1/p2p1p2/8/1P2P3/P1PP1PPP/BBNRKRNQ w FDfd - 0 9 +epd bbnrkrnq/1pp1p2p/6p1/p2p1p2/8/1P2P3/P1PP1PPP/BBNRKRNQ w FDfd - perft 1 27 perft 2 805 perft 3 21915 @@ -3314,7 +3314,7 @@ perft 5 19133881 perft 6 620749189 id 368 -epd bnrbkrn1/pp1ppp2/2p3pp/8/2Pq4/P4PP1/1P1PP2P/BNRBKRNQ w FCfc - 1 9 +epd bnrbkrn1/pp1ppp2/2p3pp/8/2Pq4/P4PP1/1P1PP2P/BNRBKRNQ w FCfc - perft 1 20 perft 2 770 perft 3 16593 @@ -3323,7 +3323,7 @@ perft 5 13581691 perft 6 456736500 id 369 -epd b1rkrbnq/1pp1pppp/2np4/p5N1/8/1P2P3/P1PP1PPP/BNRKRB1Q w ECec - 0 9 +epd b1rkrbnq/1pp1pppp/2np4/p5N1/8/1P2P3/P1PP1PPP/BNRKRB1Q w ECec - perft 1 37 perft 2 740 perft 3 27073 @@ -3332,7 +3332,7 @@ perft 5 21156664 perft 6 485803600 id 370 -epd b1krrnqb/pp1ppp1p/n1p3p1/2N5/6P1/8/PPPPPP1P/B1RKRNQB w EC - 0 9 +epd b1krrnqb/pp1ppp1p/n1p3p1/2N5/6P1/8/PPPPPP1P/B1RKRNQB w EC - perft 1 34 perft 2 850 perft 3 28494 @@ -3341,7 +3341,7 @@ perft 5 25360295 perft 6 698159474 id 371 -epd 1bbr1rnq/ppppkppp/8/3np3/4P3/3P4/PPP1KPPP/NBBRR1NQ w - - 1 9 +epd 1bbr1rnq/ppppkppp/8/3np3/4P3/3P4/PPP1KPPP/NBBRR1NQ w - - perft 1 27 perft 2 704 perft 3 18290 @@ -3350,7 +3350,7 @@ perft 5 12817011 perft 6 341026662 id 372 -epd nrbbk1nq/p1p1prpp/1p6/N2p1p2/P7/8/1PPPPPPP/R1BBKRNQ w Fb - 2 9 +epd nrbbk1nq/p1p1prpp/1p6/N2p1p2/P7/8/1PPPPPPP/R1BBKRNQ w Fb - perft 1 23 perft 2 552 perft 3 13710 @@ -3359,7 +3359,7 @@ perft 5 9236564 perft 6 248469879 id 373 -epd 1rbkrb1q/1pppp1pp/1n5n/p4p2/P3P3/1P6/2PPNPPP/NRBKRB1Q w EBeb - 1 9 +epd 1rbkrb1q/1pppp1pp/1n5n/p4p2/P3P3/1P6/2PPNPPP/NRBKRB1Q w EBeb - perft 1 22 perft 2 415 perft 3 10198 @@ -3368,7 +3368,7 @@ perft 5 5735644 perft 6 135295774 id 374 -epd nrbkr1qb/1pp1pppp/6n1/p2p4/2P1P3/1N4N1/PP1P1PPP/1RBKR1QB w EBeb - 0 9 +epd nrbkr1qb/1pp1pppp/6n1/p2p4/2P1P3/1N4N1/PP1P1PPP/1RBKR1QB w EBeb - perft 1 27 perft 2 709 perft 3 19126 @@ -3377,7 +3377,7 @@ perft 5 14192779 perft 6 380516508 id 375 -epd nbrkbrnq/p3p1pp/1pp2p2/3p4/1PP5/4P3/P1KP1PPP/NBR1BRNQ w fc - 0 9 +epd nbrkbrnq/p3p1pp/1pp2p2/3p4/1PP5/4P3/P1KP1PPP/NBR1BRNQ w fc - perft 1 24 perft 2 715 perft 3 18009 @@ -3386,7 +3386,7 @@ perft 5 14322279 perft 6 427269976 id 376 -epd nrk1brnq/pp1p1pp1/7p/b1p1p3/1P6/6P1/P1PPPPQP/NRKBBRN1 w FBfb - 2 9 +epd nrk1brnq/pp1p1pp1/7p/b1p1p3/1P6/6P1/P1PPPPQP/NRKBBRN1 w FBfb - perft 1 29 perft 2 675 perft 3 20352 @@ -3395,7 +3395,7 @@ perft 5 15316285 perft 6 389051744 id 377 -epd nrkr1bnq/1p2pppp/p2p4/1bp5/PP6/1R5N/2PPPPPP/N1KRBB1Q w Ddb - 2 9 +epd nrkr1bnq/1p2pppp/p2p4/1bp5/PP6/1R5N/2PPPPPP/N1KRBB1Q w Ddb - perft 1 27 perft 2 744 perft 3 20494 @@ -3404,7 +3404,7 @@ perft 5 16188945 perft 6 458900901 id 378 -epd nrk1b1qb/pppn1ppp/3rp3/3p4/2P3P1/3P4/PPN1PP1P/1RKRBNQB w DBb - 3 9 +epd nrk1b1qb/pppn1ppp/3rp3/3p4/2P3P1/3P4/PPN1PP1P/1RKRBNQB w DBb - perft 1 35 perft 2 941 perft 3 33203 @@ -3413,7 +3413,7 @@ perft 5 33150360 perft 6 968024386 id 379 -epd nb1rrnbq/ppkp1ppp/8/2p1p3/P7/1N2P3/1PPP1PPP/1BKRRNBQ w - - 1 9 +epd nb1rrnbq/ppkp1ppp/8/2p1p3/P7/1N2P3/1PPP1PPP/1BKRRNBQ w - - perft 1 19 perft 2 451 perft 3 9655 @@ -3422,7 +3422,7 @@ perft 5 5506897 perft 6 139436165 id 380 -epd nrkbrnbq/4pppp/1ppp4/p7/2P1P3/3P2N1/PP3PPP/NRKBR1BQ w EBeb - 0 9 +epd nrkbrnbq/4pppp/1ppp4/p7/2P1P3/3P2N1/PP3PPP/NRKBR1BQ w EBeb - perft 1 29 perft 2 591 perft 3 17132 @@ -3431,7 +3431,7 @@ perft 5 11245508 perft 6 270967202 id 381 -epd nrkrnbbq/3p1ppp/1p6/p1p1p3/3P2P1/P4Q2/1PP1PP1P/NRKRNBB1 w DBdb - 0 9 +epd nrkrnbbq/3p1ppp/1p6/p1p1p3/3P2P1/P4Q2/1PP1PP1P/NRKRNBB1 w DBdb - perft 1 38 perft 2 792 perft 3 28597 @@ -3440,7 +3440,7 @@ perft 5 22654797 perft 6 540864616 id 382 -epd nr1rnqbb/ppp1pp1p/3k2p1/3p4/1P5P/3P1N2/P1P1PPP1/NRKR1QBB w DB - 1 9 +epd nr1rnqbb/ppp1pp1p/3k2p1/3p4/1P5P/3P1N2/P1P1PPP1/NRKR1QBB w DB - perft 1 25 perft 2 758 perft 3 18547 @@ -3449,7 +3449,7 @@ perft 5 13890077 perft 6 402109399 id 383 -epd bbqrnnkr/1ppp1p1p/5p2/p5p1/P7/1P4P1/2PPPP1P/1BQRNNKR w HDhd - 0 9 +epd bbqrnnkr/1ppp1p1p/5p2/p5p1/P7/1P4P1/2PPPP1P/1BQRNNKR w HDhd - perft 1 20 perft 2 322 perft 3 7224 @@ -3458,7 +3458,7 @@ perft 5 3588435 perft 6 82754650 id 384 -epd bqrb2k1/pppppppr/5nnp/8/3P1P2/4P1N1/PPP3PP/BQRBN1KR w HCc - 1 9 +epd bqrb2k1/pppppppr/5nnp/8/3P1P2/4P1N1/PPP3PP/BQRBN1KR w HCc - perft 1 25 perft 2 597 perft 3 15872 @@ -3467,7 +3467,7 @@ perft 5 11162476 perft 6 295682250 id 385 -epd bqrnn1kr/1pppbppp/8/4p3/1p6/2P1N2P/P2PPPP1/BQR1NBKR w HChc - 1 9 +epd bqrnn1kr/1pppbppp/8/4p3/1p6/2P1N2P/P2PPPP1/BQR1NBKR w HChc - perft 1 34 perft 2 921 perft 3 31695 @@ -3476,7 +3476,7 @@ perft 5 30126510 perft 6 850296236 id 386 -epd bqr1nkr1/pppppp2/2n3p1/7p/1P1b1P2/8/PQP1P1PP/B1RNNKRB w GCgc - 0 9 +epd bqr1nkr1/pppppp2/2n3p1/7p/1P1b1P2/8/PQP1P1PP/B1RNNKRB w GCgc - perft 1 23 perft 2 788 perft 3 21539 @@ -3485,7 +3485,7 @@ perft 5 20849374 perft 6 645694580 id 387 -epd qbbrnn1r/1pppp1pk/p7/5p1p/P2P3P/3N4/1PP1PPP1/QBBR1NKR w HD - 0 9 +epd qbbrnn1r/1pppp1pk/p7/5p1p/P2P3P/3N4/1PP1PPP1/QBBR1NKR w HD - perft 1 34 perft 2 713 perft 3 24475 @@ -3494,7 +3494,7 @@ perft 5 19494094 perft 6 482645160 id 388 -epd qrbb2kr/p1pppppp/1p1n4/8/1P3n2/P7/Q1PPP1PP/1RBBNNKR w HBhb - 0 9 +epd qrbb2kr/p1pppppp/1p1n4/8/1P3n2/P7/Q1PPP1PP/1RBBNNKR w HBhb - perft 1 28 perft 2 977 perft 3 26955 @@ -3503,7 +3503,7 @@ perft 5 27802999 perft 6 992109168 id 389 -epd qrb2bkr/1pp1pppp/2np1n2/pN6/3P4/4B3/PPP1PPPP/QR2NBKR w HBhb - 0 9 +epd qrb2bkr/1pp1pppp/2np1n2/pN6/3P4/4B3/PPP1PPPP/QR2NBKR w HBhb - perft 1 27 perft 2 730 perft 3 20534 @@ -3512,7 +3512,7 @@ perft 5 17005916 perft 6 507008968 id 390 -epd qrbnnkrb/pp2pp1p/8/2pp2p1/7P/P1P5/QP1PPPP1/1RBNNKRB w GBgb - 0 9 +epd qrbnnkrb/pp2pp1p/8/2pp2p1/7P/P1P5/QP1PPPP1/1RBNNKRB w GBgb - perft 1 24 perft 2 813 perft 3 21142 @@ -3521,7 +3521,7 @@ perft 5 19615756 perft 6 655850285 id 391 -epd 1brnb1kr/p1pppppp/1p6/8/4q2n/1P2P1P1/PNPP1P1P/QBR1BNKR w HChc - 3 9 +epd 1brnb1kr/p1pppppp/1p6/8/4q2n/1P2P1P1/PNPP1P1P/QBR1BNKR w HChc - perft 1 17 perft 2 734 perft 3 13462 @@ -3530,7 +3530,7 @@ perft 5 11032633 perft 6 416356876 id 392 -epd 1rnbbnkr/1pp1pppp/1q1p4/p7/4P3/5PN1/PPPP1BPP/QRNB2KR w HBhb - 1 9 +epd 1rnbbnkr/1pp1pppp/1q1p4/p7/4P3/5PN1/PPPP1BPP/QRNB2KR w HBhb - perft 1 26 perft 2 809 perft 3 21764 @@ -3539,7 +3539,7 @@ perft 5 20292750 perft 6 675408811 id 393 -epd qrnnbb1Q/ppp1pk1p/3p2p1/5p2/PP6/5P2/2PPP1PP/1RNNBBKR w HB - 0 9 +epd qrnnbb1Q/ppp1pk1p/3p2p1/5p2/PP6/5P2/2PPP1PP/1RNNBBKR w HB - perft 1 37 perft 2 751 perft 3 27902 @@ -3548,7 +3548,7 @@ perft 5 22443036 perft 6 515122176 id 394 -epd qrnnbkrb/p3p1pp/3p1p2/1pp5/PP2P3/8/2PP1PPP/QRNNBRKB w gb - 0 9 +epd qrnnbkrb/p3p1pp/3p1p2/1pp5/PP2P3/8/2PP1PPP/QRNNBRKB w gb - perft 1 30 perft 2 906 perft 3 27955 @@ -3557,7 +3557,7 @@ perft 5 27658191 perft 6 890966633 id 395 -epd qbrnnkbr/1p2pp1p/p1p3p1/3p4/6P1/P1N4P/1PPPPP2/QBR1NKBR w HChc - 0 9 +epd qbrnnkbr/1p2pp1p/p1p3p1/3p4/6P1/P1N4P/1PPPPP2/QBR1NKBR w HChc - perft 1 26 perft 2 701 perft 3 18930 @@ -3566,7 +3566,7 @@ perft 5 14733245 perft 6 416881799 id 396 -epd qr1b1kbr/1p1ppppp/1n1n4/p1p5/4P3/5NPP/PPPP1P2/QRNB1KBR w HBhb - 1 9 +epd qr1b1kbr/1p1ppppp/1n1n4/p1p5/4P3/5NPP/PPPP1P2/QRNB1KBR w HBhb - perft 1 26 perft 2 649 perft 3 17235 @@ -3575,7 +3575,7 @@ perft 5 12367604 perft 6 342165821 id 397 -epd qrnnkb1r/1pppppp1/7p/p4b2/4P3/5P1P/PPPP2PR/QRNNKBB1 w Bhb - 1 9 +epd qrnnkb1r/1pppppp1/7p/p4b2/4P3/5P1P/PPPP2PR/QRNNKBB1 w Bhb - perft 1 34 perft 2 941 perft 3 31720 @@ -3584,7 +3584,7 @@ perft 5 30307554 perft 6 888709821 id 398 -epd qr1nkrbb/p2ppppp/1pp5/8/3Pn3/1NP3P1/PP2PP1P/QR1NKRBB w FBfb - 1 9 +epd qr1nkrbb/p2ppppp/1pp5/8/3Pn3/1NP3P1/PP2PP1P/QR1NKRBB w FBfb - perft 1 19 perft 2 505 perft 3 11107 @@ -3593,7 +3593,7 @@ perft 5 7046501 perft 6 190414579 id 399 -epd bbrqn1kr/1pppp1pp/4n3/5p2/p5P1/3P4/PPP1PPKP/BBRQNN1R w hc - 0 9 +epd bbrqn1kr/1pppp1pp/4n3/5p2/p5P1/3P4/PPP1PPKP/BBRQNN1R w hc - perft 1 24 perft 2 573 perft 3 12963 @@ -3602,7 +3602,7 @@ perft 5 8191054 perft 6 227555387 id 400 -epd brqb1nkr/pppppp1p/8/4N1pn/5P2/6P1/PPPPP2P/BRQB1NKR w HBhb - 0 9 +epd brqb1nkr/pppppp1p/8/4N1pn/5P2/6P1/PPPPP2P/BRQB1NKR w HBhb - perft 1 26 perft 2 550 perft 3 14338 @@ -3611,7 +3611,7 @@ perft 5 8903754 perft 6 223437427 id 401 -epd brqnn1kr/pp3ppp/2pbp3/3p4/8/2NPP3/PPP1BPPP/BRQ1N1KR w HBhb - 0 9 +epd brqnn1kr/pp3ppp/2pbp3/3p4/8/2NPP3/PPP1BPPP/BRQ1N1KR w HBhb - perft 1 27 perft 2 780 perft 3 20760 @@ -3620,7 +3620,7 @@ perft 5 16243731 perft 6 463883447 id 402 -epd brq1nkrb/ppp2ppp/8/n2pp2P/P7/4P3/1PPP1PP1/BRQNNKRB w GBgb - 1 9 +epd brq1nkrb/ppp2ppp/8/n2pp2P/P7/4P3/1PPP1PP1/BRQNNKRB w GBgb - perft 1 17 perft 2 426 perft 3 8295 @@ -3629,7 +3629,7 @@ perft 5 5048497 perft 6 153986034 id 403 -epd rbbqn1kr/pp2p1pp/6n1/2pp1p2/2P4P/P7/BP1PPPP1/R1BQNNKR w HAha - 0 9 +epd rbbqn1kr/pp2p1pp/6n1/2pp1p2/2P4P/P7/BP1PPPP1/R1BQNNKR w HAha - perft 1 27 perft 2 916 perft 3 25798 @@ -3638,7 +3638,7 @@ perft 5 26302461 perft 6 924181432 id 404 -epd 1qbbn1kr/1ppppppp/r3n3/8/p1P5/P7/1P1PPPPP/RQBBNNKR w HAh - 1 9 +epd 1qbbn1kr/1ppppppp/r3n3/8/p1P5/P7/1P1PPPPP/RQBBNNKR w HAh - perft 1 29 perft 2 817 perft 3 24530 @@ -3647,7 +3647,7 @@ perft 5 22147642 perft 6 670707652 id 405 -epd rqbnnbkr/ppp1ppp1/7p/3p4/PP6/7P/1NPPPPP1/RQB1NBKR w HAa - 1 9 +epd rqbnnbkr/ppp1ppp1/7p/3p4/PP6/7P/1NPPPPP1/RQB1NBKR w HAa - perft 1 23 perft 2 572 perft 3 14509 @@ -3656,7 +3656,7 @@ perft 5 10416981 perft 6 288064942 id 406 -epd r1bnnkrb/q1ppp1pp/p7/1p3pB1/2P1P3/3P4/PP3PPP/RQ1NNKRB w GAga - 2 9 +epd r1bnnkrb/q1ppp1pp/p7/1p3pB1/2P1P3/3P4/PP3PPP/RQ1NNKRB w GAga - perft 1 31 perft 2 925 perft 3 27776 @@ -3665,7 +3665,7 @@ perft 5 26316355 perft 6 843078864 id 407 -epd rbqnb1kr/ppppp1pp/5p2/5N2/7P/1n3P2/PPPPP1P1/RBQNB1KR w HAha - 1 9 +epd rbqnb1kr/ppppp1pp/5p2/5N2/7P/1n3P2/PPPPP1P1/RBQNB1KR w HAha - perft 1 32 perft 2 864 perft 3 27633 @@ -3674,7 +3674,7 @@ perft 5 24738875 perft 6 707188107 id 408 -epd rqnbbn1r/ppppppp1/6k1/8/6Pp/2PN4/PP1PPPKP/RQ1BBN1R w - - 0 9 +epd rqnbbn1r/ppppppp1/6k1/8/6Pp/2PN4/PP1PPPKP/RQ1BBN1R w - - perft 1 27 perft 2 566 perft 3 15367 @@ -3683,7 +3683,7 @@ perft 5 9714509 perft 6 234622128 id 409 -epd rqnnbbkr/p1p2pp1/1p1p3p/4p3/4NP2/6P1/PPPPP2P/RQN1BBKR w HAha - 0 9 +epd rqnnbbkr/p1p2pp1/1p1p3p/4p3/4NP2/6P1/PPPPP2P/RQN1BBKR w HAha - perft 1 27 perft 2 631 perft 3 17923 @@ -3692,7 +3692,7 @@ perft 5 13307890 perft 6 356279813 id 410 -epd 1qnnbrkb/rppp1ppp/p3p3/8/4P3/2PP1P2/PP4PP/RQNNBKRB w GA - 1 9 +epd 1qnnbrkb/rppp1ppp/p3p3/8/4P3/2PP1P2/PP4PP/RQNNBKRB w GA - perft 1 24 perft 2 479 perft 3 12135 @@ -3701,7 +3701,7 @@ perft 5 7204345 perft 6 175460841 id 411 -epd rbqnn1br/p1pppk1p/1p4p1/5p2/8/P1P2P2/1PBPP1PP/R1QNNKBR w HA - 0 9 +epd rbqnn1br/p1pppk1p/1p4p1/5p2/8/P1P2P2/1PBPP1PP/R1QNNKBR w HA - perft 1 31 perft 2 756 perft 3 23877 @@ -3710,7 +3710,7 @@ perft 5 20036784 perft 6 554292502 id 412 -epd rqnbnkbr/1ppppp2/p5p1/8/1P4p1/4PP2/P1PP3P/RQNBNKBR w HAha - 0 9 +epd rqnbnkbr/1ppppp2/p5p1/8/1P4p1/4PP2/P1PP3P/RQNBNKBR w HAha - perft 1 24 perft 2 715 perft 3 18536 @@ -3719,7 +3719,7 @@ perft 5 16013189 perft 6 515078271 id 413 -epd rq1nkbbr/1p2pppp/p2n4/2pp4/1P4P1/P2N4/2PPPP1P/RQ1NKBBR w HAha - 1 9 +epd rq1nkbbr/1p2pppp/p2n4/2pp4/1P4P1/P2N4/2PPPP1P/RQ1NKBBR w HAha - perft 1 27 perft 2 694 perft 3 19840 @@ -3728,7 +3728,7 @@ perft 5 16685687 perft 6 494574415 id 414 -epd r1nnkrbb/pp1pppp1/2p3q1/7p/8/1PPP3P/P3PPP1/RQNNKRBB w FAfa - 1 9 +epd r1nnkrbb/pp1pppp1/2p3q1/7p/8/1PPP3P/P3PPP1/RQNNKRBB w FAfa - perft 1 18 perft 2 520 perft 3 10808 @@ -3737,7 +3737,7 @@ perft 5 7508201 perft 6 235103697 id 415 -epd bbrnqk1r/pppp3p/6p1/4pp2/3P2P1/8/PPP1PP1P/BBRN1NKR w HC - 0 9 +epd bbrnqk1r/pppp3p/6p1/4pp2/3P2P1/8/PPP1PP1P/BBRN1NKR w HC - perft 1 22 perft 2 566 perft 3 12965 @@ -3746,7 +3746,7 @@ perft 5 8721079 perft 6 259069471 id 416 -epd brnb1nkr/pppqpp2/3p2pp/8/3PP3/1P6/PBP2PPP/1RNBQNKR w HBhb - 0 9 +epd brnb1nkr/pppqpp2/3p2pp/8/3PP3/1P6/PBP2PPP/1RNBQNKR w HBhb - perft 1 32 perft 2 859 perft 3 28517 @@ -3755,7 +3755,7 @@ perft 5 27734108 perft 6 829785474 id 417 -epd brnq1b1r/ppp1ppkp/3p1np1/8/8/5P1P/PPPPPKPR/BRNQNB2 w - - 0 9 +epd brnq1b1r/ppp1ppkp/3p1np1/8/8/5P1P/PPPPPKPR/BRNQNB2 w - - perft 1 21 perft 2 511 perft 3 10951 @@ -3764,7 +3764,7 @@ perft 5 6372681 perft 6 167139732 id 418 -epd brnq1rkb/1pppppp1/3n3p/p7/8/P4NP1/1PPPPPRP/BRNQ1K1B w B - 0 9 +epd brnq1rkb/1pppppp1/3n3p/p7/8/P4NP1/1PPPPPRP/BRNQ1K1B w B - perft 1 25 perft 2 548 perft 3 14049 @@ -3773,7 +3773,7 @@ perft 5 9015901 perft 6 235249649 id 419 -epd rbb1qnkr/p1ppp1pp/1p3p2/6n1/8/1PN1P2P/P1PP1PP1/RBB1QNKR w HAha - 0 9 +epd rbb1qnkr/p1ppp1pp/1p3p2/6n1/8/1PN1P2P/P1PP1PP1/RBB1QNKR w HAha - perft 1 25 perft 2 673 perft 3 16412 @@ -3782,7 +3782,7 @@ perft 5 12099119 perft 6 361714466 id 420 -epd rnbb1nkr/1ppp1ppp/4p3/p5q1/6P1/1PP5/PB1PPP1P/RN1BQNKR w HAha - 1 9 +epd rnbb1nkr/1ppp1ppp/4p3/p5q1/6P1/1PP5/PB1PPP1P/RN1BQNKR w HAha - perft 1 19 perft 2 663 perft 3 14149 @@ -3791,7 +3791,7 @@ perft 5 11491355 perft 6 399135495 id 421 -epd rnbqnbkr/1pp1p2p/3p1p2/p5p1/5PP1/2P5/PPNPP2P/RNBQ1BKR w HAha - 0 9 +epd rnbqnbkr/1pp1p2p/3p1p2/p5p1/5PP1/2P5/PPNPP2P/RNBQ1BKR w HAha - perft 1 24 perft 2 647 perft 3 16679 @@ -3800,7 +3800,7 @@ perft 5 12649636 perft 6 361157611 id 422 -epd rnb2krb/pppqppnp/8/3p2p1/1P4P1/7P/P1PPPPB1/RNBQNKR1 w GAga - 1 9 +epd rnb2krb/pppqppnp/8/3p2p1/1P4P1/7P/P1PPPPB1/RNBQNKR1 w GAga - perft 1 24 perft 2 722 perft 3 18749 @@ -3809,7 +3809,7 @@ perft 5 16609220 perft 6 563558512 id 423 -epd rbnqb1kr/pppn1pp1/3p3p/4p3/1P6/P7/R1PPPPPP/1BNQBNKR w Hha - 1 9 +epd rbnqb1kr/pppn1pp1/3p3p/4p3/1P6/P7/R1PPPPPP/1BNQBNKR w Hha - perft 1 20 perft 2 538 perft 3 12277 @@ -3818,7 +3818,7 @@ perft 5 8687621 perft 6 255304141 id 424 -epd rnqb1nkr/p1pbp1pp/8/1pPp1p2/P2P4/8/1P2PPPP/RNQBBNKR w HAha - 1 9 +epd rnqb1nkr/p1pbp1pp/8/1pPp1p2/P2P4/8/1P2PPPP/RNQBBNKR w HAha - perft 1 35 perft 2 764 perft 3 26952 @@ -3827,7 +3827,7 @@ perft 5 22592380 perft 6 564255328 id 425 -epd rnq1bbkr/1p1ppp1p/4n3/p1p3p1/P1PP4/8/RP2PPPP/1NQNBBKR w Hha - 0 9 +epd rnq1bbkr/1p1ppp1p/4n3/p1p3p1/P1PP4/8/RP2PPPP/1NQNBBKR w Hha - perft 1 29 perft 2 709 perft 3 21296 @@ -3836,7 +3836,7 @@ perft 5 17597398 perft 6 506140370 id 426 -epd 1nqnbkrb/1pppp2p/r7/p4pp1/3P4/8/PPPBPPPP/RNQNK1RB w g - 0 9 +epd 1nqnbkrb/1pppp2p/r7/p4pp1/3P4/8/PPPBPPPP/RNQNK1RB w g - perft 1 27 perft 2 1028 perft 3 28534 @@ -3845,7 +3845,7 @@ perft 5 30251988 perft 6 1096869832 id 427 -epd rbnqnkbr/p1pp1p1p/8/1p2p3/3P2pP/2P5/PP2PPP1/RBNQNKBR w HAha - 0 9 +epd rbnqnkbr/p1pp1p1p/8/1p2p3/3P2pP/2P5/PP2PPP1/RBNQNKBR w HAha - perft 1 32 perft 2 832 perft 3 27120 @@ -3854,7 +3854,7 @@ perft 5 24945574 perft 6 724171581 id 428 -epd rnq1nkbr/1p1p1ppp/2p1pb2/p7/7P/2P5/PPNPPPPB/RNQB1K1R w HAha - 2 9 +epd rnq1nkbr/1p1p1ppp/2p1pb2/p7/7P/2P5/PPNPPPPB/RNQB1K1R w HAha - perft 1 31 perft 2 779 perft 3 24010 @@ -3863,7 +3863,7 @@ perft 5 19919434 perft 6 551494771 id 429 -epd rnqnk1br/p1ppp1bp/1p3p2/6p1/4N3/P5P1/1PPPPP1P/R1QNKBBR w HAha - 2 9 +epd rnqnk1br/p1ppp1bp/1p3p2/6p1/4N3/P5P1/1PPPPP1P/R1QNKBBR w HAha - perft 1 25 perft 2 717 perft 3 19396 @@ -3872,7 +3872,7 @@ perft 5 16525239 perft 6 507175842 id 430 -epd rnq1krbb/p1p1pppp/8/1p1p4/1n5B/2N2P2/PPPPP1PP/RNQ1KR1B w FAfa - 0 9 +epd rnq1krbb/p1p1pppp/8/1p1p4/1n5B/2N2P2/PPPPP1PP/RNQ1KR1B w FAfa - perft 1 28 perft 2 867 perft 3 24029 @@ -3881,7 +3881,7 @@ perft 5 21112751 perft 6 654808184 id 431 -epd bbrnnqkr/1pp1pppp/3p4/p7/P3P3/7P/1PPP1PP1/BBRNNQKR w HChc - 0 9 +epd bbrnnqkr/1pp1pppp/3p4/p7/P3P3/7P/1PPP1PP1/BBRNNQKR w HChc - perft 1 24 perft 2 405 perft 3 11025 @@ -3890,7 +3890,7 @@ perft 5 6196438 perft 6 131401224 id 432 -epd brnbnqkr/p1ppp3/1p5p/5Pp1/5P2/3N4/PPPPP2P/BRNB1QKR w HBhb g6 0 9 +epd brnbnqkr/p1ppp3/1p5p/5Pp1/5P2/3N4/PPPPP2P/BRNB1QKR w HBhb g6 perft 1 25 perft 2 785 perft 3 21402 @@ -3899,7 +3899,7 @@ perft 5 20687969 perft 6 695850727 id 433 -epd br1nqbkr/1ppppp2/pn6/6pp/2PP4/1N4P1/PP2PP1P/BR1NQBKR w HBhb - 0 9 +epd br1nqbkr/1ppppp2/pn6/6pp/2PP4/1N4P1/PP2PP1P/BR1NQBKR w HBhb - perft 1 25 perft 2 596 perft 3 16220 @@ -3908,7 +3908,7 @@ perft 5 12185361 perft 6 337805606 id 434 -epd 1rnnqkrb/p2ppp1p/1pp5/2N3p1/8/1P6/P1PPPPKP/BR1NQ1RB w gb - 0 9 +epd 1rnnqkrb/p2ppp1p/1pp5/2N3p1/8/1P6/P1PPPPKP/BR1NQ1RB w gb - perft 1 38 perft 2 960 perft 3 34831 @@ -3917,7 +3917,7 @@ perft 5 32490040 perft 6 880403591 id 435 -epd rbbnnqkr/pp3pp1/2p1p3/3p3p/3P3P/1PP5/P3PPP1/RBBNNQKR w HAha - 0 9 +epd rbbnnqkr/pp3pp1/2p1p3/3p3p/3P3P/1PP5/P3PPP1/RBBNNQKR w HAha - perft 1 30 perft 2 785 perft 3 23079 @@ -3926,7 +3926,7 @@ perft 5 19885037 perft 6 599219582 id 436 -epd rn1bnqkr/p1ppppp1/8/1p5p/P4P1P/3N4/1PPPP1b1/RNBB1QKR w HAha - 0 9 +epd rn1bnqkr/p1ppppp1/8/1p5p/P4P1P/3N4/1PPPP1b1/RNBB1QKR w HAha - perft 1 27 perft 2 752 perft 3 21735 @@ -3935,7 +3935,7 @@ perft 5 18862234 perft 6 547415271 id 437 -epd 1nbnqbkr/1p1p1ppp/r3p3/p1p5/P3P3/3Q4/1PPP1PPP/RNBN1BKR w HAh - 2 9 +epd 1nbnqbkr/1p1p1ppp/r3p3/p1p5/P3P3/3Q4/1PPP1PPP/RNBN1BKR w HAh - perft 1 33 perft 2 721 perft 3 24278 @@ -3944,7 +3944,7 @@ perft 5 19648535 perft 6 496023732 id 438 -epd rnbnqkrb/2pppppp/1p6/p7/1PP5/4N2P/P2PPPP1/RNB1QKRB w GAg - 0 9 +epd rnbnqkrb/2pppppp/1p6/p7/1PP5/4N2P/P2PPPP1/RNB1QKRB w GAg - perft 1 23 perft 2 570 perft 3 14225 @@ -3953,7 +3953,7 @@ perft 5 10022614 perft 6 279545007 id 439 -epd rbnnbq1r/ppppppkp/6p1/N7/4P3/P7/1PPP1PPP/RB1NBQKR w HA - 5 9 +epd rbnnbq1r/ppppppkp/6p1/N7/4P3/P7/1PPP1PPP/RB1NBQKR w HA - perft 1 27 perft 2 620 perft 3 18371 @@ -3962,7 +3962,7 @@ perft 5 13909432 perft 6 349478320 id 440 -epd r1nbbqkr/pppppp1p/8/8/1n3Pp1/3N1QP1/PPPPP2P/RN1BB1KR w HAha - 0 9 +epd r1nbbqkr/pppppp1p/8/8/1n3Pp1/3N1QP1/PPPPP2P/RN1BB1KR w HAha - perft 1 31 perft 2 791 perft 3 25431 @@ -3971,7 +3971,7 @@ perft 5 22408813 perft 6 636779732 id 441 -epd rnq1bbkr/pp1p1ppp/2pnp3/8/7P/1QP5/PP1PPPPR/RNN1BBK1 w Aha - 2 9 +epd rnq1bbkr/pp1p1ppp/2pnp3/8/7P/1QP5/PP1PPPPR/RNN1BBK1 w Aha - perft 1 28 perft 2 559 perft 3 16838 @@ -3980,7 +3980,7 @@ perft 5 12242780 perft 6 315431511 id 442 -epd rnnqbrkb/2ppppp1/1p1N4/p6p/4P3/8/PPPP1PPP/R1NQBKRB w GA - 0 9 +epd rnnqbrkb/2ppppp1/1p1N4/p6p/4P3/8/PPPP1PPP/R1NQBKRB w GA - perft 1 32 perft 2 638 perft 3 20591 @@ -3989,7 +3989,7 @@ perft 5 14395828 perft 6 331782223 id 443 -epd rbnnq1br/pppp1kp1/4pp2/7p/PP6/2PP4/4PPPP/RBNNQKBR w HA - 0 9 +epd rbnnq1br/pppp1kp1/4pp2/7p/PP6/2PP4/4PPPP/RBNNQKBR w HA - perft 1 21 perft 2 521 perft 3 12201 @@ -3998,7 +3998,7 @@ perft 5 8239159 perft 6 227346638 id 444 -epd rnnbqkbr/p2ppp2/7p/1pp3p1/2P2N2/8/PP1PPPPP/RN1BQKBR w HAha - 0 9 +epd rnnbqkbr/p2ppp2/7p/1pp3p1/2P2N2/8/PP1PPPPP/RN1BQKBR w HAha - perft 1 25 perft 2 528 perft 3 13896 @@ -4007,7 +4007,7 @@ perft 5 9079829 perft 6 232750602 id 445 -epd rnn1kbbr/ppppqp2/6p1/2N1p2p/P7/2P5/1P1PPPPP/RN1QKBBR w HAha - 2 9 +epd rnn1kbbr/ppppqp2/6p1/2N1p2p/P7/2P5/1P1PPPPP/RN1QKBBR w HAha - perft 1 27 perft 2 801 perft 3 22088 @@ -4016,7 +4016,7 @@ perft 5 20334071 perft 6 682580976 id 446 -epd rnnqkrbb/p1p1p1pp/1p3p2/8/3p2Q1/P1P1P3/1P1P1PPP/RNN1KRBB w FAfa - 0 9 +epd rnnqkrbb/p1p1p1pp/1p3p2/8/3p2Q1/P1P1P3/1P1P1PPP/RNN1KRBB w FAfa - perft 1 37 perft 2 1014 perft 3 34735 @@ -4025,7 +4025,7 @@ perft 5 32921537 perft 6 988770109 id 447 -epd bbrnk1qr/1pppppp1/p4n1p/8/P2P2N1/8/1PP1PPPP/BBR1NKQR w HC - 1 9 +epd bbrnk1qr/1pppppp1/p4n1p/8/P2P2N1/8/1PP1PPPP/BBR1NKQR w HC - perft 1 21 perft 2 481 perft 3 11213 @@ -4034,7 +4034,7 @@ perft 5 7015419 perft 6 187564853 id 448 -epd brnbnkqr/1pp1p1p1/p2p1p2/7p/1P4PP/8/PBPPPP2/1RNBNKQR w HBhb - 0 9 +epd brnbnkqr/1pp1p1p1/p2p1p2/7p/1P4PP/8/PBPPPP2/1RNBNKQR w HBhb - perft 1 31 perft 2 743 perft 3 24260 @@ -4043,7 +4043,7 @@ perft 5 22391185 perft 6 653721389 id 449 -epd br2kbqr/ppppp1pp/3n1p2/3P4/3n3P/3N4/PPP1PPP1/BR1NKBQR w HBhb - 3 9 +epd br2kbqr/ppppp1pp/3n1p2/3P4/3n3P/3N4/PPP1PPP1/BR1NKBQR w HBhb - perft 1 25 perft 2 872 perft 3 22039 @@ -4052,7 +4052,7 @@ perft 5 20281962 perft 6 685749952 id 450 -epd br1nkqrb/ppppppp1/8/7p/4P3/n1P2PP1/PP1P3P/BRNNKQRB w GBgb - 0 9 +epd br1nkqrb/ppppppp1/8/7p/4P3/n1P2PP1/PP1P3P/BRNNKQRB w GBgb - perft 1 28 perft 2 607 perft 3 16934 @@ -4061,7 +4061,7 @@ perft 5 11607818 perft 6 294181806 id 451 -epd rbbn1kqr/pp1pp1p1/2pn3p/5p2/5P2/1P1N4/PNPPP1PP/RBB2KQR w HAha - 1 9 +epd rbbn1kqr/pp1pp1p1/2pn3p/5p2/5P2/1P1N4/PNPPP1PP/RBB2KQR w HAha - perft 1 27 perft 2 725 perft 3 21543 @@ -4070,7 +4070,7 @@ perft 5 19239812 perft 6 581716972 id 452 -epd rnbbnk1r/pp1ppp1p/6q1/2p5/PP4p1/4P3/2PP1PPP/RNBBNKQR w HAha - 1 9 +epd rnbbnk1r/pp1ppp1p/6q1/2p5/PP4p1/4P3/2PP1PPP/RNBBNKQR w HAha - perft 1 25 perft 2 1072 perft 3 26898 @@ -4079,7 +4079,7 @@ perft 5 28469879 perft 6 1122703887 id 453 -epd rnbnkbqr/1pp3pp/3p4/p3pp2/3P2P1/2N1N3/PPP1PP1P/R1B1KBQR w HAha - 0 9 +epd rnbnkbqr/1pp3pp/3p4/p3pp2/3P2P1/2N1N3/PPP1PP1P/R1B1KBQR w HAha - perft 1 31 perft 2 1028 perft 3 32907 @@ -4088,7 +4088,7 @@ perft 5 36025223 perft 6 1211187800 id 454 -epd r1bnkqrb/1ppppppp/p3n3/8/6P1/4N3/PPPPPPRP/RNB1KQ1B w Aga - 1 9 +epd r1bnkqrb/1ppppppp/p3n3/8/6P1/4N3/PPPPPPRP/RNB1KQ1B w Aga - perft 1 23 perft 2 457 perft 3 11416 @@ -4097,7 +4097,7 @@ perft 5 6666787 perft 6 159759052 id 455 -epd rbn1bkqr/p1pp1pp1/1pn5/4p2p/7P/1PBP4/P1P1PPP1/RBNN1KQR w HAha - 0 9 +epd rbn1bkqr/p1pp1pp1/1pn5/4p2p/7P/1PBP4/P1P1PPP1/RBNN1KQR w HAha - perft 1 23 perft 2 470 perft 3 11649 @@ -4106,7 +4106,7 @@ perft 5 6963287 perft 6 172833738 id 456 -epd rnnbbkqr/3ppppp/p7/1pp5/P6P/6P1/1PPPPP2/RNNBBKQR w HAha - 0 9 +epd rnnbbkqr/3ppppp/p7/1pp5/P6P/6P1/1PPPPP2/RNNBBKQR w HAha - perft 1 26 perft 2 569 perft 3 15733 @@ -4115,7 +4115,7 @@ perft 5 11008114 perft 6 284485303 id 457 -epd r1nk1bqr/1pppp1pp/2n5/p4p1b/5P2/1N4B1/PPPPP1PP/RN1K1BQR w HAha - 2 9 +epd r1nk1bqr/1pppp1pp/2n5/p4p1b/5P2/1N4B1/PPPPP1PP/RN1K1BQR w HAha - perft 1 25 perft 2 824 perft 3 21983 @@ -4124,7 +4124,7 @@ perft 5 20904119 perft 6 716170771 id 458 -epd r1nkbqrb/p2pppp1/npp4p/8/4PP2/2N4P/PPPP2P1/R1NKBQRB w GAga - 0 9 +epd r1nkbqrb/p2pppp1/npp4p/8/4PP2/2N4P/PPPP2P1/R1NKBQRB w GAga - perft 1 31 perft 2 548 perft 3 17480 @@ -4133,7 +4133,7 @@ perft 5 11469548 perft 6 255067638 id 459 -epd rbnnkqbr/ppppp2p/5p2/6p1/2P1B3/P6P/1P1PPPP1/R1NNKQBR w HAha - 1 9 +epd rbnnkqbr/ppppp2p/5p2/6p1/2P1B3/P6P/1P1PPPP1/R1NNKQBR w HAha - perft 1 31 perft 2 809 perft 3 24956 @@ -4142,7 +4142,7 @@ perft 5 21247414 perft 6 606221516 id 460 -epd 1r1bkqbr/pppp1ppp/2nnp3/8/2P5/N4P2/PP1PP1PP/1RNBKQBR w Hh - 0 9 +epd 1r1bkqbr/pppp1ppp/2nnp3/8/2P5/N4P2/PP1PP1PP/1RNBKQBR w Hh - perft 1 28 perft 2 810 perft 3 22844 @@ -4151,7 +4151,7 @@ perft 5 20188622 perft 6 636748147 id 461 -epd rn1kqbbr/p1pppp1p/1p4p1/1n6/1P2P3/4Q2P/P1PP1PP1/RNNK1BBR w HAha - 1 9 +epd rn1kqbbr/p1pppp1p/1p4p1/1n6/1P2P3/4Q2P/P1PP1PP1/RNNK1BBR w HAha - perft 1 39 perft 2 848 perft 3 30100 @@ -4160,7 +4160,7 @@ perft 5 25594662 perft 6 659615710 id 462 -epd rn1kqrbb/pppppppp/8/8/2nP2P1/1P2P3/P1P2P1P/RNNKQRBB w FAfa - 1 9 +epd rn1kqrbb/pppppppp/8/8/2nP2P1/1P2P3/P1P2P1P/RNNKQRBB w FAfa - perft 1 29 perft 2 766 perft 3 21701 @@ -4169,7 +4169,7 @@ perft 5 16944425 perft 6 456898648 id 463 -epd b1rnnkrq/bpppppp1/7p/8/1p6/2B5/PNPPPPPP/1BR1NKRQ w GCgc - 2 9 +epd b1rnnkrq/bpppppp1/7p/8/1p6/2B5/PNPPPPPP/1BR1NKRQ w GCgc - perft 1 25 perft 2 667 perft 3 17253 @@ -4178,7 +4178,7 @@ perft 5 12865247 perft 6 365621294 id 464 -epd brnb1krq/pppppppp/8/5P2/2P1n2P/8/PP1PP1P1/BRNBNKRQ w GBgb - 1 9 +epd brnb1krq/pppppppp/8/5P2/2P1n2P/8/PP1PP1P1/BRNBNKRQ w GBgb - perft 1 23 perft 2 620 perft 3 14882 @@ -4187,7 +4187,7 @@ perft 5 10776855 perft 6 300125003 id 465 -epd b1nnkbrq/pr1pppp1/1p5p/2p5/P2N1P2/8/1PPPP1PP/BR1NKBRQ w GBg - 0 9 +epd b1nnkbrq/pr1pppp1/1p5p/2p5/P2N1P2/8/1PPPP1PP/BR1NKBRQ w GBg - perft 1 24 perft 2 472 perft 3 12181 @@ -4196,7 +4196,7 @@ perft 5 7370758 perft 6 178605165 id 466 -epd br1nkrqb/p1p1p1pp/3n4/1p1p1p2/5N1P/4P3/PPPP1PP1/BR1NKRQB w FBfb - 0 9 +epd br1nkrqb/p1p1p1pp/3n4/1p1p1p2/5N1P/4P3/PPPP1PP1/BR1NKRQB w FBfb - perft 1 24 perft 2 775 perft 3 19398 @@ -4205,7 +4205,7 @@ perft 5 16429837 perft 6 539767605 id 467 -epd rbbnnkrq/p2pp1pp/2p5/5p2/1pPP1B2/P7/1P2PPPP/RB1NNKRQ w GAga - 0 9 +epd rbbnnkrq/p2pp1pp/2p5/5p2/1pPP1B2/P7/1P2PPPP/RB1NNKRQ w GAga - perft 1 34 perft 2 921 perft 3 30474 @@ -4214,7 +4214,7 @@ perft 5 28095833 perft 6 806446436 id 468 -epd rnbbnkr1/1p1ppp1p/2p3p1/p7/2Pq4/1P1P4/P2BPPPP/RN1BNKRQ w GAga - 2 9 +epd rnbbnkr1/1p1ppp1p/2p3p1/p7/2Pq4/1P1P4/P2BPPPP/RN1BNKRQ w GAga - perft 1 26 perft 2 1139 perft 3 29847 @@ -4223,7 +4223,7 @@ perft 5 32825932 perft 6 1281760240 id 469 -epd 1rbnkbrq/pppppp2/n5pp/2P5/P7/4N3/1P1PPPPP/RNB1KBRQ w GAg - 2 9 +epd 1rbnkbrq/pppppp2/n5pp/2P5/P7/4N3/1P1PPPPP/RNB1KBRQ w GAg - perft 1 23 perft 2 574 perft 3 14146 @@ -4232,7 +4232,7 @@ perft 5 10203438 perft 6 301874034 id 470 -epd 1nbnkr1b/rppppppq/p7/7p/1P5P/3P2P1/P1P1PP2/RNBNKRQB w FAf - 1 9 +epd 1nbnkr1b/rppppppq/p7/7p/1P5P/3P2P1/P1P1PP2/RNBNKRQB w FAf - perft 1 33 perft 2 823 perft 3 26696 @@ -4241,7 +4241,7 @@ perft 5 23266182 perft 6 672294132 id 471 -epd rbn1bkrq/ppppp3/4n2p/5pp1/1PN5/2P5/P2PPPPP/RBN1BKRQ w GAga - 0 9 +epd rbn1bkrq/ppppp3/4n2p/5pp1/1PN5/2P5/P2PPPPP/RBN1BKRQ w GAga - perft 1 27 perft 2 859 perft 3 24090 @@ -4250,7 +4250,7 @@ perft 5 23075785 perft 6 789152120 id 472 -epd r1nbbkrq/1ppp2pp/2n2p2/p3p3/5P2/1N4BP/PPPPP1P1/RN1B1KRQ w GAga - 0 9 +epd r1nbbkrq/1ppp2pp/2n2p2/p3p3/5P2/1N4BP/PPPPP1P1/RN1B1KRQ w GAga - perft 1 25 perft 2 774 perft 3 20141 @@ -4259,7 +4259,7 @@ perft 5 16718577 perft 6 515864053 id 473 -epd rnnkbbrq/1pppp1p1/5p2/7p/p6P/3N1P2/PPPPP1PQ/RN1KBBR1 w GAga - 0 9 +epd rnnkbbrq/1pppp1p1/5p2/7p/p6P/3N1P2/PPPPP1PQ/RN1KBBR1 w GAga - perft 1 29 perft 2 673 perft 3 20098 @@ -4268,7 +4268,7 @@ perft 5 15545590 perft 6 416359581 id 474 -epd r1nkbrqb/pppp1p2/n3p1p1/7p/2P2P2/1P6/P2PPQPP/RNNKBR1B w FAfa - 0 9 +epd r1nkbrqb/pppp1p2/n3p1p1/7p/2P2P2/1P6/P2PPQPP/RNNKBR1B w FAfa - perft 1 27 perft 2 722 perft 3 21397 @@ -4277,7 +4277,7 @@ perft 5 18742426 perft 6 537750982 id 475 -epd rbnnkr1q/1ppp2pp/p4p2/P2bp3/4P2P/8/1PPP1PP1/RBNNKRBQ w FAfa - 1 9 +epd rbnnkr1q/1ppp2pp/p4p2/P2bp3/4P2P/8/1PPP1PP1/RBNNKRBQ w FAfa - perft 1 26 perft 2 848 perft 3 23387 @@ -4286,7 +4286,7 @@ perft 5 21591790 perft 6 675163653 id 476 -epd rn1bkrb1/1ppppp1p/pn4p1/8/P2q3P/3P4/NPP1PPP1/RN1BKRBQ w FAfa - 1 9 +epd rn1bkrb1/1ppppp1p/pn4p1/8/P2q3P/3P4/NPP1PPP1/RN1BKRBQ w FAfa - perft 1 22 perft 2 803 perft 3 18322 @@ -4295,7 +4295,7 @@ perft 5 15847763 perft 6 536419559 id 477 -epd rn1krbbq/pppp1npp/4pp2/8/4P2P/3P2P1/PPP2P2/RNNKRBBQ w EAea - 1 9 +epd rn1krbbq/pppp1npp/4pp2/8/4P2P/3P2P1/PPP2P2/RNNKRBBQ w EAea - perft 1 29 perft 2 810 perft 3 23968 @@ -4304,7 +4304,7 @@ perft 5 20361517 perft 6 575069358 id 478 -epd rnn1rqbb/ppkp1pp1/2p1p2p/2P5/8/3P1P2/PP2P1PP/RNNKRQBB w EA - 0 9 +epd rnn1rqbb/ppkp1pp1/2p1p2p/2P5/8/3P1P2/PP2P1PP/RNNKRQBB w EA - perft 1 22 perft 2 506 perft 3 11973 @@ -4313,7 +4313,7 @@ perft 5 7287368 perft 6 189865944 id 479 -epd bbqr1knr/pppppp1p/8/4n1p1/2P1P3/6P1/PPQP1P1P/BB1RNKNR w HDhd - 0 9 +epd bbqr1knr/pppppp1p/8/4n1p1/2P1P3/6P1/PPQP1P1P/BB1RNKNR w HDhd - perft 1 26 perft 2 650 perft 3 18253 @@ -4322,7 +4322,7 @@ perft 5 14301029 perft 6 394943978 id 480 -epd bq1bnknr/pprppp1p/8/2p3p1/4PPP1/8/PPPP3P/BQRBNKNR w HCh - 0 9 +epd bq1bnknr/pprppp1p/8/2p3p1/4PPP1/8/PPPP3P/BQRBNKNR w HCh - perft 1 24 perft 2 548 perft 3 14021 @@ -4331,7 +4331,7 @@ perft 5 9374021 perft 6 250988458 id 481 -epd bqrnkb1r/1p2pppp/p1pp3n/5Q2/2P4P/5N2/PP1PPPP1/B1RNKB1R w HChc - 0 9 +epd bqrnkb1r/1p2pppp/p1pp3n/5Q2/2P4P/5N2/PP1PPPP1/B1RNKB1R w HChc - perft 1 46 perft 2 823 perft 3 33347 @@ -4340,7 +4340,7 @@ perft 5 26130444 perft 6 582880996 id 482 -epd bq1rknrb/pppppp1p/4n3/6p1/4P1P1/3P1P2/PPP4P/BQRNKNRB w GCg - 0 9 +epd bq1rknrb/pppppp1p/4n3/6p1/4P1P1/3P1P2/PPP4P/BQRNKNRB w GCg - perft 1 23 perft 2 618 perft 3 14815 @@ -4349,7 +4349,7 @@ perft 5 10606831 perft 6 315124518 id 483 -epd q1brnknr/pp1pp1p1/8/2p2p1p/5b2/P4N2/1PPPP1PP/QBBRK1NR w hd - 0 9 +epd q1brnknr/pp1pp1p1/8/2p2p1p/5b2/P4N2/1PPPP1PP/QBBRK1NR w hd - perft 1 22 perft 2 675 perft 3 15778 @@ -4358,7 +4358,7 @@ perft 5 12077228 perft 6 368479752 id 484 -epd qrbbnknr/1p1ppp1p/p1p5/8/1P2P1p1/3P1B2/P1P2PPP/QRB1NKNR w HBhb - 0 9 +epd qrbbnknr/1p1ppp1p/p1p5/8/1P2P1p1/3P1B2/P1P2PPP/QRB1NKNR w HBhb - perft 1 32 perft 2 722 perft 3 24049 @@ -4367,7 +4367,7 @@ perft 5 19584539 perft 6 484814878 id 485 -epd qrb1kbnr/p3pppp/2n5/1ppp4/7P/3P1P2/PPP1P1PR/QRBNKBN1 w Bhb - 0 9 +epd qrb1kbnr/p3pppp/2n5/1ppp4/7P/3P1P2/PPP1P1PR/QRBNKBN1 w Bhb - perft 1 26 perft 2 831 perft 3 22606 @@ -4376,7 +4376,7 @@ perft 5 20500804 perft 6 662608969 id 486 -epd qrbnknrb/ppp1pp2/6p1/7p/PPNp4/8/2PPPPPP/QRB1KNRB w GBgb - 0 9 +epd qrbnknrb/ppp1pp2/6p1/7p/PPNp4/8/2PPPPPP/QRB1KNRB w GBgb - perft 1 31 perft 2 840 perft 3 26762 @@ -4385,7 +4385,7 @@ perft 5 24422614 perft 6 701363800 id 487 -epd qbrnbknr/pp1pp1pp/8/2p2p2/3Q4/PP6/2PPPPPP/1BRNBKNR w HChc - 0 9 +epd qbrnbknr/pp1pp1pp/8/2p2p2/3Q4/PP6/2PPPPPP/1BRNBKNR w HChc - perft 1 38 perft 2 1121 perft 3 39472 @@ -4394,7 +4394,7 @@ perft 5 41108769 perft 6 1285503872 id 488 -epd qr1bbk1r/pppppp1p/1n6/5np1/4B3/1PP5/P2PPPPP/QRN1BKNR w HBhb - 0 9 +epd qr1bbk1r/pppppp1p/1n6/5np1/4B3/1PP5/P2PPPPP/QRN1BKNR w HBhb - perft 1 25 perft 2 694 perft 3 16938 @@ -4403,7 +4403,7 @@ perft 5 12164609 perft 6 345122090 id 489 -epd qrnkbbnr/1p1pp2p/p7/2p1Npp1/6P1/7P/PPPPPP2/QR1KBBNR w HBhb - 0 9 +epd qrnkbbnr/1p1pp2p/p7/2p1Npp1/6P1/7P/PPPPPP2/QR1KBBNR w HBhb - perft 1 27 perft 2 586 perft 3 16348 @@ -4412,7 +4412,7 @@ perft 5 11409633 perft 6 298054792 id 490 -epd qrnkbnrb/pp1p1p2/2p1p1pp/4N3/P4P2/8/1PPPP1PP/QR1KBNRB w GBgb - 0 9 +epd qrnkbnrb/pp1p1p2/2p1p1pp/4N3/P4P2/8/1PPPP1PP/QR1KBNRB w GBgb - perft 1 32 perft 2 645 perft 3 20737 @@ -4421,7 +4421,7 @@ perft 5 15037464 perft 6 358531599 id 491 -epd qbrnknbr/1pppppp1/p6p/8/1P6/3PP3/PQP2PPP/1BRNKNBR w HChc - 3 9 +epd qbrnknbr/1pppppp1/p6p/8/1P6/3PP3/PQP2PPP/1BRNKNBR w HChc - perft 1 26 perft 2 595 perft 3 16755 @@ -4430,7 +4430,7 @@ perft 5 12214768 perft 6 323518628 id 492 -epd qrnbk1br/1ppppp1p/p5p1/8/4Pn2/4K1P1/PPPP1P1P/QRNB1NBR w hb - 0 9 +epd qrnbk1br/1ppppp1p/p5p1/8/4Pn2/4K1P1/PPPP1P1P/QRNB1NBR w hb - perft 1 24 perft 2 609 perft 3 13776 @@ -4439,7 +4439,7 @@ perft 5 8538539 perft 6 230364479 id 493 -epd qrnk1bbr/1pnp1ppp/p1p1p3/8/3Q4/1P1N3P/P1PPPPP1/1RNK1BBR w HBhb - 0 9 +epd qrnk1bbr/1pnp1ppp/p1p1p3/8/3Q4/1P1N3P/P1PPPPP1/1RNK1BBR w HBhb - perft 1 43 perft 2 1106 perft 3 42898 @@ -4448,7 +4448,7 @@ perft 5 41695761 perft 6 1113836402 id 494 -epd qrnknrb1/pppppp2/8/6pp/4P2P/3P1P2/PbP3P1/QRNKNRBB w FBfb - 0 9 +epd qrnknrb1/pppppp2/8/6pp/4P2P/3P1P2/PbP3P1/QRNKNRBB w FBfb - perft 1 24 perft 2 658 perft 3 17965 @@ -4457,7 +4457,7 @@ perft 5 14457245 perft 6 400971226 id 495 -epd bbrqnrk1/ppp2ppp/7n/3pp3/8/P4N1N/1PPPPPPP/BBRQ1RK1 w - - 1 9 +epd bbrqnrk1/ppp2ppp/7n/3pp3/8/P4N1N/1PPPPPPP/BBRQ1RK1 w - - perft 1 22 perft 2 503 perft 3 12078 @@ -4466,7 +4466,7 @@ perft 5 8080951 perft 6 224960353 id 496 -epd brqbnk1r/1ppp1ppp/8/p3pn2/8/2PP1P2/PP2PKPP/BRQBN1NR w hb - 1 9 +epd brqbnk1r/1ppp1ppp/8/p3pn2/8/2PP1P2/PP2PKPP/BRQBN1NR w hb - perft 1 25 perft 2 745 perft 3 19387 @@ -4475,7 +4475,7 @@ perft 5 15520298 perft 6 460840861 id 497 -epd brqnkbnr/pp2pp1p/3p4/2p5/5p2/3P3P/PPP1PPP1/B1RNKBNR w Hhb - 0 9 +epd brqnkbnr/pp2pp1p/3p4/2p5/5p2/3P3P/PPP1PPP1/B1RNKBNR w Hhb - perft 1 19 perft 2 516 perft 3 10755 @@ -4484,7 +4484,7 @@ perft 5 6995034 perft 6 214340699 id 498 -epd brq1kn1b/1ppppprp/2n3p1/p7/P1N5/6P1/1PPPPP1P/BRQNK1RB w GBb - 2 9 +epd brq1kn1b/1ppppprp/2n3p1/p7/P1N5/6P1/1PPPPP1P/BRQNK1RB w GBb - perft 1 29 perft 2 557 perft 3 16739 @@ -4493,7 +4493,7 @@ perft 5 10840256 perft 6 249999654 id 499 -epd rbbq1k1r/ppp1pppp/7n/1n1p4/5P2/P2P4/1PPBP1PP/RB1QNKNR w HAha - 1 9 +epd rbbq1k1r/ppp1pppp/7n/1n1p4/5P2/P2P4/1PPBP1PP/RB1QNKNR w HAha - perft 1 25 perft 2 769 perft 3 20110 @@ -4502,7 +4502,7 @@ perft 5 17438715 perft 6 570893953 id 500 -epd r1bbnk1r/qpp1pppp/p6n/3p4/1P6/5N1P/P1PPPPP1/RQBBK1NR w ha - 0 9 +epd r1bbnk1r/qpp1pppp/p6n/3p4/1P6/5N1P/P1PPPPP1/RQBBK1NR w ha - perft 1 23 perft 2 728 perft 3 18209 @@ -4511,7 +4511,7 @@ perft 5 16053564 perft 6 529082811 id 501 -epd rqbnkbnr/1pp2p1p/3p4/p3p1p1/8/2P2P2/PP1PPNPP/RQBNKB1R w HAha - 0 9 +epd rqbnkbnr/1pp2p1p/3p4/p3p1p1/8/2P2P2/PP1PPNPP/RQBNKB1R w HAha - perft 1 26 perft 2 772 perft 3 21903 @@ -4520,7 +4520,7 @@ perft 5 19571559 perft 6 593915677 id 502 -epd r1bnknrb/pqppp1p1/1p5p/5p2/7P/3P2N1/PPP1PPP1/RQBNK1RB w GAga - 2 9 +epd r1bnknrb/pqppp1p1/1p5p/5p2/7P/3P2N1/PPP1PPP1/RQBNK1RB w GAga - perft 1 27 perft 2 748 perft 3 20291 @@ -4529,7 +4529,7 @@ perft 5 16324542 perft 6 506453626 id 503 -epd rbqnbknr/pp1pppp1/8/2p5/3P3p/5N1P/PPP1PPPR/RBQNBK2 w Aha - 0 9 +epd rbqnbknr/pp1pppp1/8/2p5/3P3p/5N1P/PPP1PPPR/RBQNBK2 w Aha - perft 1 30 perft 2 859 perft 3 26785 @@ -4538,7 +4538,7 @@ perft 5 26363334 perft 6 842796987 id 504 -epd rqnbbrk1/ppppppp1/8/5n1p/3P3P/2B3P1/PPP1PP2/RQNB1KNR w HA - 0 9 +epd rqnbbrk1/ppppppp1/8/5n1p/3P3P/2B3P1/PPP1PP2/RQNB1KNR w HA - perft 1 22 perft 2 505 perft 3 11452 @@ -4547,7 +4547,7 @@ perft 5 7055215 perft 6 186760784 id 505 -epd rqnkbbnr/pp2p1p1/8/2pp1p1p/3PPP2/8/PPP1N1PP/RQNKBB1R w HAha - 0 9 +epd rqnkbbnr/pp2p1p1/8/2pp1p1p/3PPP2/8/PPP1N1PP/RQNKBB1R w HAha - perft 1 28 perft 2 832 perft 3 23142 @@ -4556,7 +4556,7 @@ perft 5 20429246 perft 6 663183060 id 506 -epd rqnkbnr1/pppp2bp/6p1/4pp2/1P2P3/3NN3/P1PP1PPP/RQ1KB1RB w GAga - 0 9 +epd rqnkbnr1/pppp2bp/6p1/4pp2/1P2P3/3NN3/P1PP1PPP/RQ1KB1RB w GAga - perft 1 28 perft 2 641 perft 3 18835 @@ -4565,7 +4565,7 @@ perft 5 14038570 perft 6 364210162 id 507 -epd rbq2kbr/pppppppp/2n5/P7/3P1n2/2P5/1P2PPPP/RBQNKNBR w HA - 1 9 +epd rbq2kbr/pppppppp/2n5/P7/3P1n2/2P5/1P2PPPP/RBQNKNBR w HA - perft 1 31 perft 2 889 perft 3 27028 @@ -4574,7 +4574,7 @@ perft 5 24299415 perft 6 692180754 id 508 -epd rq1bkn1r/ppppp2p/3n4/5pp1/2b3P1/1N1P1P2/PPP1P2P/RQ1BKNBR w HAha - 1 9 +epd rq1bkn1r/ppppp2p/3n4/5pp1/2b3P1/1N1P1P2/PPP1P2P/RQ1BKNBR w HAha - perft 1 28 perft 2 810 perft 3 22667 @@ -4583,7 +4583,7 @@ perft 5 18719949 perft 6 556282676 id 509 -epd r1nknbbr/p2ppp1p/1pp3p1/8/1P6/4P3/P1PPNPPq/R1QKNBBR w HAha - 0 9 +epd r1nknbbr/p2ppp1p/1pp3p1/8/1P6/4P3/P1PPNPPq/R1QKNBBR w HAha - perft 1 24 perft 2 797 perft 3 22144 @@ -4592,7 +4592,7 @@ perft 5 21862776 perft 6 716521139 id 510 -epd rqnknrbb/ppp1p3/5ppp/2Np4/2P5/4P3/PP1P1PPP/RQNK1RBB w FAfa - 0 9 +epd rqnknrbb/ppp1p3/5ppp/2Np4/2P5/4P3/PP1P1PPP/RQNK1RBB w FAfa - perft 1 34 perft 2 686 perft 3 23277 @@ -4601,7 +4601,7 @@ perft 5 17664543 perft 6 423574794 id 511 -epd 1brnqknr/2p1pppp/p2p4/1P6/6P1/4Nb2/PP1PPP1P/BBR1QKNR w HChc - 1 9 +epd 1brnqknr/2p1pppp/p2p4/1P6/6P1/4Nb2/PP1PPP1P/BBR1QKNR w HChc - perft 1 34 perft 2 1019 perft 3 32982 @@ -4610,7 +4610,7 @@ perft 5 33322477 perft 6 1043293394 id 512 -epd brn1qknr/1p1pppp1/pb5p/Q1p5/3P3P/8/PPP1PPPR/BRNB1KN1 w Bhb - 2 9 +epd brn1qknr/1p1pppp1/pb5p/Q1p5/3P3P/8/PPP1PPPR/BRNB1KN1 w Bhb - perft 1 32 perft 2 642 perft 3 20952 @@ -4619,7 +4619,7 @@ perft 5 15454749 perft 6 371861782 id 513 -epd brnqkbnr/pppppp2/8/6pp/6P1/P2P1P2/1PP1P2P/BRNQKBNR w HBhb - 0 9 +epd brnqkbnr/pppppp2/8/6pp/6P1/P2P1P2/1PP1P2P/BRNQKBNR w HBhb - perft 1 20 perft 2 441 perft 3 9782 @@ -4628,7 +4628,7 @@ perft 5 5770284 perft 6 153051835 id 514 -epd 2nqknrb/1rpppppp/5B2/pp6/1PP1b3/3P4/P3PPPP/1RNQKNRB w GBg - 1 9 +epd 2nqknrb/1rpppppp/5B2/pp6/1PP1b3/3P4/P3PPPP/1RNQKNRB w GBg - perft 1 35 perft 2 1042 perft 3 36238 @@ -4637,7 +4637,7 @@ perft 5 38505058 perft 6 1202668717 id 515 -epd rb1nqknr/1pp1pppp/8/3p4/p2P4/6PN/PPPQPP1P/RBBN1K1R w HAha - 0 9 +epd rb1nqknr/1pp1pppp/8/3p4/p2P4/6PN/PPPQPP1P/RBBN1K1R w HAha - perft 1 29 perft 2 692 perft 3 21237 @@ -4646,7 +4646,7 @@ perft 5 17820605 perft 6 497251206 id 516 -epd rnbbqknr/pppp4/5p2/4p1pp/P7/2N2PP1/1PPPP2P/R1BBQKNR w HAha - 0 9 +epd rnbbqknr/pppp4/5p2/4p1pp/P7/2N2PP1/1PPPP2P/R1BBQKNR w HAha - perft 1 23 perft 2 595 perft 3 14651 @@ -4655,7 +4655,7 @@ perft 5 10881112 perft 6 329010121 id 517 -epd rn1qkbnr/p1p1pp1p/bp4p1/3p4/1P6/4P3/P1PP1PPP/RNBQKBNR w HAha - 0 9 +epd rn1qkbnr/p1p1pp1p/bp4p1/3p4/1P6/4P3/P1PP1PPP/RNBQKBNR w HAha - perft 1 30 perft 2 794 perft 3 24319 @@ -4664,7 +4664,7 @@ perft 5 21657601 perft 6 647745807 id 518 -epd r1bqk1rb/pppnpppp/5n2/3p4/2P3PP/2N5/PP1PPP2/R1BQKNRB w GAga - 1 9 +epd r1bqk1rb/pppnpppp/5n2/3p4/2P3PP/2N5/PP1PPP2/R1BQKNRB w GAga - perft 1 32 perft 2 821 perft 3 27121 @@ -4673,7 +4673,7 @@ perft 5 24923473 perft 6 710765657 id 519 -epd rbnqbknr/1p1ppp1p/6p1/p1p5/7P/3P4/PPP1PPP1/RBNQBKNR w HAha - 0 9 +epd rbnqbknr/1p1ppp1p/6p1/p1p5/7P/3P4/PPP1PPP1/RBNQBKNR w HAha - perft 1 24 perft 2 720 perft 3 18842 @@ -4682,7 +4682,7 @@ perft 5 15992882 perft 6 501093456 id 520 -epd r1qbbk1r/pp1ppppp/n1p5/5n2/B1P3P1/8/PP1PPP1P/RNQ1BKNR w HAha - 0 9 +epd r1qbbk1r/pp1ppppp/n1p5/5n2/B1P3P1/8/PP1PPP1P/RNQ1BKNR w HAha - perft 1 27 perft 2 831 perft 3 22293 @@ -4691,7 +4691,7 @@ perft 5 19948650 perft 6 637973209 id 521 -epd rnqkbb1r/p1pppppp/8/8/1p4n1/PP4PP/2PPPP2/RNQKBBNR w HAha - 0 9 +epd rnqkbb1r/p1pppppp/8/8/1p4n1/PP4PP/2PPPP2/RNQKBBNR w HAha - perft 1 18 perft 2 463 perft 3 9519 @@ -4700,7 +4700,7 @@ perft 5 6065231 perft 6 172734380 id 522 -epd rnqk1nrb/pppbpp2/7p/3p2p1/4B3/2N1N1P1/PPPPPP1P/R1QKB1R1 w GAga - 0 9 +epd rnqk1nrb/pppbpp2/7p/3p2p1/4B3/2N1N1P1/PPPPPP1P/R1QKB1R1 w GAga - perft 1 34 perft 2 1171 perft 3 38128 @@ -4709,7 +4709,7 @@ perft 5 42109356 perft 6 1465473753 id 523 -epd rbnqknbr/1pp1ppp1/3p4/7p/p2P2PP/2P5/PP2PP2/RBNQKNBR w HAha - 0 9 +epd rbnqknbr/1pp1ppp1/3p4/7p/p2P2PP/2P5/PP2PP2/RBNQKNBR w HAha - perft 1 32 perft 2 867 perft 3 28342 @@ -4718,7 +4718,7 @@ perft 5 26632459 perft 6 781067145 id 524 -epd rn1bknbr/pq2pppp/1p6/2pp4/P7/1P1P4/2PNPPPP/RNQBK1BR w HAha - 0 9 +epd rn1bknbr/pq2pppp/1p6/2pp4/P7/1P1P4/2PNPPPP/RNQBK1BR w HAha - perft 1 24 perft 2 627 perft 3 16652 @@ -4727,7 +4727,7 @@ perft 5 13200921 perft 6 385193532 id 525 -epd r1qk1bbr/ppp1pp1p/2np1n2/6p1/2PP4/3BP3/PP3PPP/RNQKN1BR w HAha - 2 9 +epd r1qk1bbr/ppp1pp1p/2np1n2/6p1/2PP4/3BP3/PP3PPP/RNQKN1BR w HAha - perft 1 31 perft 2 992 perft 3 30213 @@ -4736,7 +4736,7 @@ perft 5 30397368 perft 6 1011631987 id 526 -epd r1qknrbb/pppp1p2/2n3p1/4p2p/8/QPP5/P1NPPPPP/RN1K1RBB w FAfa - 2 9 +epd r1qknrbb/pppp1p2/2n3p1/4p2p/8/QPP5/P1NPPPPP/RN1K1RBB w FAfa - perft 1 30 perft 2 702 perft 3 21563 @@ -4745,7 +4745,7 @@ perft 5 16813114 perft 6 438096194 id 527 -epd bbkr1qnr/2pppppp/2n5/pp6/8/PPN5/1BPPPPPP/1BR1KQNR w HC - 2 9 +epd bbkr1qnr/2pppppp/2n5/pp6/8/PPN5/1BPPPPPP/1BR1KQNR w HC - perft 1 25 perft 2 573 perft 3 15183 @@ -4754,7 +4754,7 @@ perft 5 10554668 perft 6 283975400 id 528 -epd 1rnbkqnr/1bpppppp/1p6/7P/p2P4/5P2/PPP1P1P1/BRNBKQNR w HBhb - 0 9 +epd 1rnbkqnr/1bpppppp/1p6/7P/p2P4/5P2/PPP1P1P1/BRNBKQNR w HBhb - perft 1 21 perft 2 503 perft 3 11790 @@ -4763,7 +4763,7 @@ perft 5 7679979 perft 6 207799378 id 529 -epd brnkqbnr/2p1pppp/1p6/3p4/1pP5/P6P/3PPPP1/BRNKQBNR w HBhb - 0 9 +epd brnkqbnr/2p1pppp/1p6/3p4/1pP5/P6P/3PPPP1/BRNKQBNR w HBhb - perft 1 28 perft 2 743 perft 3 21054 @@ -4772,7 +4772,7 @@ perft 5 17354516 perft 6 507176753 id 530 -epd br1kqnrb/npp1pppp/8/3p4/p4N2/PP6/2PPPPPP/BR1KQNRB w GBgb - 0 9 +epd br1kqnrb/npp1pppp/8/3p4/p4N2/PP6/2PPPPPP/BR1KQNRB w GBgb - perft 1 31 perft 2 808 perft 3 25585 @@ -4781,7 +4781,7 @@ perft 5 22376575 perft 6 640362920 id 531 -epd rbbnkq1r/pppppp1p/7n/6p1/P5P1/2P2N2/1P1PPP1P/RBBNKQ1R w HAha - 1 9 +epd rbbnkq1r/pppppp1p/7n/6p1/P5P1/2P2N2/1P1PPP1P/RBBNKQ1R w HAha - perft 1 29 perft 2 580 perft 3 17585 @@ -4790,7 +4790,7 @@ perft 5 12730970 perft 6 325226128 id 532 -epd rnbbk1nr/pp2qppp/2ppp3/8/3P4/P1N4N/1PP1PPPP/R1BBKQ1R w HAha - 0 9 +epd rnbbk1nr/pp2qppp/2ppp3/8/3P4/P1N4N/1PP1PPPP/R1BBKQ1R w HAha - perft 1 29 perft 2 838 perft 3 24197 @@ -4799,7 +4799,7 @@ perft 5 21100580 perft 6 646624429 id 533 -epd rnbk1b1r/ppppn1pp/4pp2/7q/7P/P5PB/1PPPPP2/RNBKQ1NR w HAha - 3 9 +epd rnbk1b1r/ppppn1pp/4pp2/7q/7P/P5PB/1PPPPP2/RNBKQ1NR w HAha - perft 1 20 perft 2 729 perft 3 16633 @@ -4808,7 +4808,7 @@ perft 5 14507076 perft 6 498621813 id 534 -epd r2kqnrb/pbppppp1/np5p/8/4Q1P1/3P4/PPP1PP1P/RNBK1NRB w GAga - 2 9 +epd r2kqnrb/pbppppp1/np5p/8/4Q1P1/3P4/PPP1PP1P/RNBK1NRB w GAga - perft 1 47 perft 2 1219 perft 3 55009 @@ -4817,7 +4817,7 @@ perft 5 65239153 perft 6 1834391369 id 535 -epd rbnkbq1r/p1p2ppp/1p2pn2/3p4/P3P3/3P4/1PP1KPPP/RBN1BQNR w ha - 2 9 +epd rbnkbq1r/p1p2ppp/1p2pn2/3p4/P3P3/3P4/1PP1KPPP/RBN1BQNR w ha - perft 1 29 perft 2 923 perft 3 27179 @@ -4826,7 +4826,7 @@ perft 5 26202752 perft 6 868565895 id 536 -epd rk1bb1nr/ppppqppp/n7/1N2p3/6P1/7N/PPPPPP1P/R1KBBQ1R w HA - 6 9 +epd rk1bb1nr/ppppqppp/n7/1N2p3/6P1/7N/PPPPPP1P/R1KBBQ1R w HA - perft 1 27 perft 2 703 perft 3 19478 @@ -4835,7 +4835,7 @@ perft 5 16049807 perft 6 492966455 id 537 -epd rnkqbbnr/p1ppp2p/1p4p1/8/1B3p1P/2NP4/PPP1PPP1/R1KQ1BNR w HAha - 0 9 +epd rnkqbbnr/p1ppp2p/1p4p1/8/1B3p1P/2NP4/PPP1PPP1/R1KQ1BNR w HAha - perft 1 29 perft 2 610 perft 3 18855 @@ -4844,7 +4844,7 @@ perft 5 14020041 perft 6 355083962 id 538 -epd rnkqb1rb/pp1p1ppp/4p3/2P3n1/8/1PP5/P3PPPP/RNKQBNRB w GAga - 0 9 +epd rnkqb1rb/pp1p1ppp/4p3/2P3n1/8/1PP5/P3PPPP/RNKQBNRB w GAga - perft 1 29 perft 2 675 perft 3 20699 @@ -4853,7 +4853,7 @@ perft 5 17000613 perft 6 476598337 id 539 -epd rb1kqnbr/pp1pp1p1/1np2p2/7p/P1P3PP/8/1P1PPP2/RBNKQNBR w HAha - 0 9 +epd rb1kqnbr/pp1pp1p1/1np2p2/7p/P1P3PP/8/1P1PPP2/RBNKQNBR w HAha - perft 1 31 perft 2 1077 perft 3 33661 @@ -4862,7 +4862,7 @@ perft 5 37415304 perft 6 1328374620 id 540 -epd rnkbq1br/ppp2ppp/3p4/Q3p1n1/5P2/3P2P1/PPP1P2P/RNKB1NBR w HAha - 0 9 +epd rnkbq1br/ppp2ppp/3p4/Q3p1n1/5P2/3P2P1/PPP1P2P/RNKB1NBR w HAha - perft 1 41 perft 2 1201 perft 3 46472 @@ -4871,7 +4871,7 @@ perft 5 52991625 perft 6 1675608008 id 541 -epd rn1qnbbr/pp2pppp/2ppk3/8/2PP4/3Q1N2/PP2PPPP/RNK2BBR w HA - 1 9 +epd rn1qnbbr/pp2pppp/2ppk3/8/2PP4/3Q1N2/PP2PPPP/RNK2BBR w HA - perft 1 34 perft 2 666 perft 3 22474 @@ -4880,7 +4880,7 @@ perft 5 15860369 perft 6 353831792 id 542 -epd rnkqnr1b/ppppp1pp/5p2/8/Q1P2P2/8/PP1P2PP/RbK1NRBB w FAfa - 0 9 +epd rnkqnr1b/ppppp1pp/5p2/8/Q1P2P2/8/PP1P2PP/RbK1NRBB w FAfa - perft 1 36 perft 2 876 perft 3 31987 @@ -4889,7 +4889,7 @@ perft 5 29022529 perft 6 736717252 id 543 -epd bbrn1nqr/ppp1k1pp/5p2/3pp3/7P/3PN3/PPP1PPP1/BBRK1NQR w - - 1 9 +epd bbrn1nqr/ppp1k1pp/5p2/3pp3/7P/3PN3/PPP1PPP1/BBRK1NQR w - - perft 1 24 perft 2 583 perft 3 15063 @@ -4898,7 +4898,7 @@ perft 5 10522064 perft 6 280707118 id 544 -epd brnbkn1r/1pppp1p1/4q3/p4p1p/7P/1N3P2/PPPPP1PQ/BR1BKN1R w HBhb - 2 9 +epd brnbkn1r/1pppp1p1/4q3/p4p1p/7P/1N3P2/PPPPP1PQ/BR1BKN1R w HBhb - perft 1 27 perft 2 935 perft 3 26120 @@ -4907,7 +4907,7 @@ perft 5 26000648 perft 6 873063158 id 545 -epd br1knbqr/pp2p1pp/1n6/2pp1p2/6P1/2P4B/PP1PPPQP/BRNKN2R w HBhb - 0 9 +epd br1knbqr/pp2p1pp/1n6/2pp1p2/6P1/2P4B/PP1PPPQP/BRNKN2R w HBhb - perft 1 27 perft 2 681 perft 3 19202 @@ -4916,7 +4916,7 @@ perft 5 14954779 perft 6 415624943 id 546 -epd brnk1qrb/p1ppppp1/1p5p/8/P3n3/1N4P1/1PPPPPRP/BR1KNQ1B w Bgb - 0 9 +epd brnk1qrb/p1ppppp1/1p5p/8/P3n3/1N4P1/1PPPPPRP/BR1KNQ1B w Bgb - perft 1 22 perft 2 638 perft 3 13991 @@ -4925,7 +4925,7 @@ perft 5 9760752 perft 6 293499724 id 547 -epd rbbnknqr/pppp3p/5pp1/8/1P1pP3/7P/P1P2PP1/RBBNKNQR w HAha - 0 9 +epd rbbnknqr/pppp3p/5pp1/8/1P1pP3/7P/P1P2PP1/RBBNKNQR w HAha - perft 1 29 perft 2 756 perft 3 21616 @@ -4934,7 +4934,7 @@ perft 5 17602252 perft 6 528140595 id 548 -epd 1nbbknqr/rpp1ppp1/1Q1p3p/p7/2P2PP1/8/PP1PP2P/RNBBKN1R w HAh - 2 9 +epd 1nbbknqr/rpp1ppp1/1Q1p3p/p7/2P2PP1/8/PP1PP2P/RNBBKN1R w HAh - perft 1 37 perft 2 977 perft 3 34977 @@ -4943,7 +4943,7 @@ perft 5 33695089 perft 6 940198007 id 549 -epd rnb2bqr/ppkpppp1/3n3p/2p5/6PP/2N2P2/PPPPP3/R1BKNBQR w HA - 2 9 +epd rnb2bqr/ppkpppp1/3n3p/2p5/6PP/2N2P2/PPPPP3/R1BKNBQR w HA - perft 1 30 perft 2 647 perft 3 20365 @@ -4952,7 +4952,7 @@ perft 5 15115531 perft 6 369257622 id 550 -epd rn1k1qrb/p1pppppp/bp6/8/4n3/P4BPP/1PPPPP2/RNBKNQR1 w GAga - 2 9 +epd rn1k1qrb/p1pppppp/bp6/8/4n3/P4BPP/1PPPPP2/RNBKNQR1 w GAga - perft 1 22 perft 2 670 perft 3 14998 @@ -4961,7 +4961,7 @@ perft 5 11199653 perft 6 339919682 id 551 -epd rb2bnqr/nppkpppp/3p4/p7/1P6/P2N2P1/2PPPP1P/RB1KBNQR w HA - 3 9 +epd rb2bnqr/nppkpppp/3p4/p7/1P6/P2N2P1/2PPPP1P/RB1KBNQR w HA - perft 1 22 perft 2 479 perft 3 11475 @@ -4970,7 +4970,7 @@ perft 5 6831555 perft 6 167329117 id 552 -epd r1kbb1qr/2pppppp/np2n3/p7/2P3P1/8/PP1PPPQP/RNKBBN1R w HAha - 1 9 +epd r1kbb1qr/2pppppp/np2n3/p7/2P3P1/8/PP1PPPQP/RNKBBN1R w HAha - perft 1 32 perft 2 723 perft 3 23953 @@ -4979,7 +4979,7 @@ perft 5 19472074 perft 6 504622114 id 553 -epd rnknbb1r/p1ppp1pp/8/1p1P1p1q/8/P1P5/1P2PPPP/RNKNBBQR w HAha - 1 9 +epd rnknbb1r/p1ppp1pp/8/1p1P1p1q/8/P1P5/1P2PPPP/RNKNBBQR w HAha - perft 1 19 perft 2 607 perft 3 12733 @@ -4988,7 +4988,7 @@ perft 5 9753617 perft 6 325177085 id 554 -epd rnkn1qrb/pp1bp1pp/2p5/1N1p1p2/8/2P5/PPKPPPPP/R2NBQRB w ga - 2 9 +epd rnkn1qrb/pp1bp1pp/2p5/1N1p1p2/8/2P5/PPKPPPPP/R2NBQRB w ga - perft 1 27 perft 2 533 perft 3 14549 @@ -4997,7 +4997,7 @@ perft 5 9206957 perft 6 232664675 id 555 -epd r1nknqbr/pp2p1pp/2p2p2/3p4/6P1/PP1P4/2P1PP1b/RBNKNQBR w HAha - 0 9 +epd r1nknqbr/pp2p1pp/2p2p2/3p4/6P1/PP1P4/2P1PP1b/RBNKNQBR w HAha - perft 1 20 perft 2 582 perft 3 13777 @@ -5006,7 +5006,7 @@ perft 5 10708639 perft 6 326565393 id 556 -epd rnkb1qbr/p1pp1p1p/1p2pn2/1Q4p1/4P3/N4P2/PPPP2PP/R1KBN1BR w HAha - 0 9 +epd rnkb1qbr/p1pp1p1p/1p2pn2/1Q4p1/4P3/N4P2/PPPP2PP/R1KBN1BR w HAha - perft 1 40 perft 2 1038 perft 3 39356 @@ -5015,7 +5015,7 @@ perft 5 39145902 perft 6 1079612614 id 557 -epd rn2qbbr/1pkppp1p/p3n1p1/8/8/2P2P2/PP1PP1PP/RNKN1BBR w HA - 0 9 +epd rn2qbbr/1pkppp1p/p3n1p1/8/8/2P2P2/PP1PP1PP/RNKN1BBR w HA - perft 1 24 perft 2 605 perft 3 14888 @@ -5024,7 +5024,7 @@ perft 5 9687507 perft 6 260874068 id 558 -epd rn1nqrbb/p1kppp1p/8/1pp3p1/1P6/2N1P3/P1PP1PPP/RK1NQRBB w - - 0 9 +epd rn1nqrbb/p1kppp1p/8/1pp3p1/1P6/2N1P3/P1PP1PPP/RK1NQRBB w - - perft 1 21 perft 2 540 perft 3 12489 @@ -5033,7 +5033,7 @@ perft 5 8436136 perft 6 237525904 id 559 -epd bbrnknrq/1pp3pp/p2p1p2/4p3/P7/1P2N3/2PPPPPP/BBRN1RKQ w gc - 0 9 +epd bbrnknrq/1pp3pp/p2p1p2/4p3/P7/1P2N3/2PPPPPP/BBRN1RKQ w gc - perft 1 24 perft 2 527 perft 3 13900 @@ -5042,7 +5042,7 @@ perft 5 9139962 perft 6 226253685 id 560 -epd brnb1nrq/pppp1kpp/4p3/8/5p1P/P1P3P1/1P1PPP2/BRNBKNRQ w GB - 1 9 +epd brnb1nrq/pppp1kpp/4p3/8/5p1P/P1P3P1/1P1PPP2/BRNBKNRQ w GB - perft 1 29 perft 2 773 perft 3 23904 @@ -5051,7 +5051,7 @@ perft 5 20503775 perft 6 560338709 id 561 -epd br1k1brq/ppppp2p/1n1n1pp1/8/P1P5/3P2P1/1P2PP1P/BRNKNBRQ w GBgb - 0 9 +epd br1k1brq/ppppp2p/1n1n1pp1/8/P1P5/3P2P1/1P2PP1P/BRNKNBRQ w GBgb - perft 1 28 perft 2 811 perft 3 23550 @@ -5060,7 +5060,7 @@ perft 5 19913758 perft 6 565143976 id 562 -epd 1r1knrqb/n1pppppp/p1b5/1p6/8/3N1P2/PPPPP1PP/BRNK1RQB w fb - 3 9 +epd 1r1knrqb/n1pppppp/p1b5/1p6/8/3N1P2/PPPPP1PP/BRNK1RQB w fb - perft 1 29 perft 2 753 perft 3 23210 @@ -5069,7 +5069,7 @@ perft 5 20044474 perft 6 558383603 id 563 -epd rbbnk1rq/pppppppp/8/3Pn3/8/4P1P1/PPP2P1P/RBBNKNRQ w GAga - 1 9 +epd rbbnk1rq/pppppppp/8/3Pn3/8/4P1P1/PPP2P1P/RBBNKNRQ w GAga - perft 1 22 perft 2 551 perft 3 12619 @@ -5078,7 +5078,7 @@ perft 5 8204171 perft 6 217689974 id 564 -epd rnbbk1rq/2pppp1p/p3n1p1/1p6/P3N3/8/1PPPPPPP/RNBB1KRQ w ga - 0 9 +epd rnbbk1rq/2pppp1p/p3n1p1/1p6/P3N3/8/1PPPPPPP/RNBB1KRQ w ga - perft 1 26 perft 2 742 perft 3 20061 @@ -5087,7 +5087,7 @@ perft 5 16787080 perft 6 525678162 id 565 -epd rnbkn1rq/ppppppb1/6p1/7p/2B2P2/1P2P3/P1PP2PP/RNBKN1RQ w GAga - 1 9 +epd rnbkn1rq/ppppppb1/6p1/7p/2B2P2/1P2P3/P1PP2PP/RNBKN1RQ w GAga - perft 1 28 perft 2 799 perft 3 23210 @@ -5096,7 +5096,7 @@ perft 5 20755098 perft 6 639632905 id 566 -epd rn1knrqb/p2pppp1/b1p5/1p5p/2P2P2/1P6/P2PP1PP/RNBKNRQB w FAfa - 1 9 +epd rn1knrqb/p2pppp1/b1p5/1p5p/2P2P2/1P6/P2PP1PP/RNBKNRQB w FAfa - perft 1 30 perft 2 579 perft 3 18481 @@ -5105,7 +5105,7 @@ perft 5 13257198 perft 6 311282465 id 567 -epd rbnkbnrq/pp2p1Np/2p2p2/8/3p4/8/PPPPPPPP/RBNKBR1Q w Aga - 0 9 +epd rbnkbnrq/pp2p1Np/2p2p2/8/3p4/8/PPPPPPPP/RBNKBR1Q w Aga - perft 1 23 perft 2 670 perft 3 16435 @@ -5114,7 +5114,7 @@ perft 5 13012378 perft 6 411860744 id 568 -epd rk1bbnrq/ppp1pppp/n7/3p4/5P2/3P2NP/PPP1P1P1/RNKBB1RQ w GA - 0 9 +epd rk1bbnrq/ppp1pppp/n7/3p4/5P2/3P2NP/PPP1P1P1/RNKBB1RQ w GA - perft 1 26 perft 2 597 perft 3 16238 @@ -5123,7 +5123,7 @@ perft 5 11269462 perft 6 296701249 id 569 -epd r1knbbrq/pppp2p1/2n1p2p/5p2/4P3/P1PP4/1P3PPP/RNKNBBRQ w GAga - 1 9 +epd r1knbbrq/pppp2p1/2n1p2p/5p2/4P3/P1PP4/1P3PPP/RNKNBBRQ w GAga - perft 1 20 perft 2 596 perft 3 13091 @@ -5132,7 +5132,7 @@ perft 5 9416862 perft 6 293659781 id 570 -epd rnknbrqb/p1p1pp1p/3p4/1p1N2p1/8/N7/PPPPPPPP/1RK1BRQB w Ffa - 0 9 +epd rnknbrqb/p1p1pp1p/3p4/1p1N2p1/8/N7/PPPPPPPP/1RK1BRQB w Ffa - perft 1 26 perft 2 724 perft 3 18942 @@ -5141,7 +5141,7 @@ perft 5 15257204 perft 6 461293885 id 571 -epd rbnknrb1/1p1ppp1p/p1p3p1/8/1P3P2/1R6/PqPPP1PP/RBNKN1BQ w Afa - 0 9 +epd rbnknrb1/1p1ppp1p/p1p3p1/8/1P3P2/1R6/PqPPP1PP/RBNKN1BQ w Afa - perft 1 31 perft 2 1183 perft 3 34723 @@ -5150,7 +5150,7 @@ perft 5 38722152 perft 6 1421492227 id 572 -epd rnkbnrbq/2p1ppp1/p7/1p1p3p/3P4/1P4P1/P1P1PP1P/RNKBNRBQ w FAfa - 0 9 +epd rnkbnrbq/2p1ppp1/p7/1p1p3p/3P4/1P4P1/P1P1PP1P/RNKBNRBQ w FAfa - perft 1 24 perft 2 506 perft 3 12748 @@ -5159,7 +5159,7 @@ perft 5 8086100 perft 6 207129256 id 573 -epd r1knrbbq/pp1ppppp/2p1n3/8/2P3P1/P7/1PKPPP1P/RN1NRBBQ w ea - 0 9 +epd r1knrbbq/pp1ppppp/2p1n3/8/2P3P1/P7/1PKPPP1P/RN1NRBBQ w ea - perft 1 28 perft 2 570 perft 3 16037 @@ -5168,7 +5168,7 @@ perft 5 10278695 perft 6 242592363 id 574 -epd rnknrq1b/ppp1p1p1/4b3/3p1p1p/6P1/P4P2/1PPPPQ1P/RNKNR1BB w EAea - 2 9 +epd rnknrq1b/ppp1p1p1/4b3/3p1p1p/6P1/P4P2/1PPPPQ1P/RNKNR1BB w EAea - perft 1 30 perft 2 739 perft 3 23124 @@ -5177,7 +5177,7 @@ perft 5 19252739 perft 6 521629794 id 575 -epd bbqr1krn/pppp1p1p/5n2/4p1p1/3P4/P3QP2/1PP1P1PP/BB1RNKRN w GDgd - 0 9 +epd bbqr1krn/pppp1p1p/5n2/4p1p1/3P4/P3QP2/1PP1P1PP/BB1RNKRN w GDgd - perft 1 31 perft 2 799 perft 3 25627 @@ -5186,7 +5186,7 @@ perft 5 22172123 perft 6 609277274 id 576 -epd bq1b1krn/pp1ppppp/3n4/2r5/3p3N/6N1/PPP1PPPP/BQRB1KR1 w GCg - 2 9 +epd bq1b1krn/pp1ppppp/3n4/2r5/3p3N/6N1/PPP1PPPP/BQRB1KR1 w GCg - perft 1 21 perft 2 798 perft 3 18571 @@ -5195,7 +5195,7 @@ perft 5 17546069 perft 6 647165916 id 577 -epd bqrnkbrn/2pp1pp1/p7/1p2p2p/1P6/4N3/P1PPPPPP/BQR1KBRN w GCgc - 0 9 +epd bqrnkbrn/2pp1pp1/p7/1p2p2p/1P6/4N3/P1PPPPPP/BQR1KBRN w GCgc - perft 1 27 perft 2 783 perft 3 22327 @@ -5204,7 +5204,7 @@ perft 5 20059741 perft 6 624462073 id 578 -epd bqr1krnb/1np1pppp/8/pp1p4/8/2P2N2/PP1PPPPP/BQRNKR1B w FCfc - 0 9 +epd bqr1krnb/1np1pppp/8/pp1p4/8/2P2N2/PP1PPPPP/BQRNKR1B w FCfc - perft 1 28 perft 2 636 perft 3 18874 @@ -5213,7 +5213,7 @@ perft 5 14237097 perft 6 372181570 id 579 -epd qbb1rkrn/1ppppppp/p7/7n/8/P2P4/1PP1PPPP/QBBRNKRN w Gg - 0 9 +epd qbb1rkrn/1ppppppp/p7/7n/8/P2P4/1PP1PPPP/QBBRNKRN w Gg - perft 1 25 perft 2 547 perft 3 13837 @@ -5222,7 +5222,7 @@ perft 5 8849383 perft 6 229112926 id 580 -epd 1rbbnkrn/p1p1pp1p/2q5/1p1p2p1/8/2P3P1/PP1PPP1P/QRBBNKRN w GBgb - 2 9 +epd 1rbbnkrn/p1p1pp1p/2q5/1p1p2p1/8/2P3P1/PP1PPP1P/QRBBNKRN w GBgb - perft 1 24 perft 2 1010 perft 3 24370 @@ -5231,7 +5231,7 @@ perft 5 24328258 perft 6 961371180 id 581 -epd qrb1kbrn/ppp1p2p/4npp1/3p4/8/1PP4P/PR1PPPP1/Q1BNKBRN w Ggb - 1 9 +epd qrb1kbrn/ppp1p2p/4npp1/3p4/8/1PP4P/PR1PPPP1/Q1BNKBRN w Ggb - perft 1 18 perft 2 451 perft 3 9291 @@ -5240,7 +5240,7 @@ perft 5 5568106 perft 6 155744022 id 582 -epd qr2krnb/p1p1pppp/b1np4/1p6/3NP3/7P/PPPP1PP1/QRBNKR1B w FBfb - 2 9 +epd qr2krnb/p1p1pppp/b1np4/1p6/3NP3/7P/PPPP1PP1/QRBNKR1B w FBfb - perft 1 25 perft 2 667 perft 3 17081 @@ -5249,7 +5249,7 @@ perft 5 12458875 perft 6 361495148 id 583 -epd qbrnbkrn/ppp3pp/3p4/5p2/2P1pP2/6PP/PP1PP3/QBRNBKRN w GCgc - 0 9 +epd qbrnbkrn/ppp3pp/3p4/5p2/2P1pP2/6PP/PP1PP3/QBRNBKRN w GCgc - perft 1 24 perft 2 650 perft 3 16835 @@ -5258,7 +5258,7 @@ perft 5 12187382 perft 6 326834539 id 584 -epd qrnb1krn/ppp1p1pp/5p2/2Np4/b2P4/2P5/PP2PPPP/QR1BBKRN w GBgb - 0 9 +epd qrnb1krn/ppp1p1pp/5p2/2Np4/b2P4/2P5/PP2PPPP/QR1BBKRN w GBgb - perft 1 27 perft 2 641 perft 3 17490 @@ -5267,7 +5267,7 @@ perft 5 12103076 perft 6 310695797 id 585 -epd qrnkbbrn/pp2pp2/8/2pp2pp/6PP/3P4/PPPKPP2/QRN1BBRN w gb - 0 9 +epd qrnkbbrn/pp2pp2/8/2pp2pp/6PP/3P4/PPPKPP2/QRN1BBRN w gb - perft 1 22 perft 2 554 perft 3 13116 @@ -5276,7 +5276,7 @@ perft 5 9014737 perft 6 258925091 id 586 -epd qrnkbrnb/p1p1ppp1/1p6/3p4/3P3p/5N1P/PPP1PPP1/QRNKBR1B w FBfb - 0 9 +epd qrnkbrnb/p1p1ppp1/1p6/3p4/3P3p/5N1P/PPP1PPP1/QRNKBR1B w FBfb - perft 1 24 perft 2 529 perft 3 13205 @@ -5285,7 +5285,7 @@ perft 5 8295874 perft 6 213856651 id 587 -epd qbr1krbn/1pppp1pp/p7/5pn1/2PP4/8/PPB1PPPP/Q1RNKRBN w FCfc - 0 9 +epd qbr1krbn/1pppp1pp/p7/5pn1/2PP4/8/PPB1PPPP/Q1RNKRBN w FCfc - perft 1 26 perft 2 831 perft 3 21651 @@ -5294,7 +5294,7 @@ perft 5 18961456 perft 6 621884383 id 588 -epd 1rnbkrbn/1qp1pppp/3p4/pp6/4P3/1NP4P/PP1P1PP1/QR1BKRBN w FBfb - 0 9 +epd 1rnbkrbn/1qp1pppp/3p4/pp6/4P3/1NP4P/PP1P1PP1/QR1BKRBN w FBfb - perft 1 24 perft 2 597 perft 3 15089 @@ -5303,7 +5303,7 @@ perft 5 10832084 perft 6 307793179 id 589 -epd q1rkrbbn/ppp1pppp/8/3p4/1PnP4/P7/1RP1PPPP/Q1NKRBBN w Ee - 1 9 +epd q1rkrbbn/ppp1pppp/8/3p4/1PnP4/P7/1RP1PPPP/Q1NKRBBN w Ee - perft 1 20 perft 2 520 perft 3 10769 @@ -5312,7 +5312,7 @@ perft 5 6452205 perft 6 170268300 id 590 -epd qrnkrn1b/ppppp1pp/4b3/7P/6p1/P7/1PPPPP2/QRNKRNBB w EBeb - 0 9 +epd qrnkrn1b/ppppp1pp/4b3/7P/6p1/P7/1PPPPP2/QRNKRNBB w EBeb - perft 1 26 perft 2 566 perft 3 15623 @@ -5321,7 +5321,7 @@ perft 5 10940750 perft 6 287987207 id 591 -epd bbr1nkrn/ppp1pppp/3q4/3p4/8/P7/1PPPPPPP/BBRQNRKN w gc - 5 9 +epd bbr1nkrn/ppp1pppp/3q4/3p4/8/P7/1PPPPPPP/BBRQNRKN w gc - perft 1 19 perft 2 661 perft 3 13895 @@ -5330,7 +5330,7 @@ perft 5 10870247 perft 6 356399665 id 592 -epd brqbnkrn/pp1pp2p/5pp1/2p5/4P3/P2P1N2/1PP2PPP/BRQB1KRN w GBgb - 0 9 +epd brqbnkrn/pp1pp2p/5pp1/2p5/4P3/P2P1N2/1PP2PPP/BRQB1KRN w GBgb - perft 1 27 perft 2 679 perft 3 19916 @@ -5339,7 +5339,7 @@ perft 5 16391730 perft 6 455940859 id 593 -epd 2qnkbrn/p1pppppp/8/1r6/1p2bP2/7N/PPPPP1PP/BR1QKBRN w GBg - 4 9 +epd 2qnkbrn/p1pppppp/8/1r6/1p2bP2/7N/PPPPP1PP/BR1QKBRN w GBg - perft 1 18 perft 2 774 perft 3 15713 @@ -5348,7 +5348,7 @@ perft 5 14371755 perft 6 559579332 id 594 -epd r1qnkr1b/p1pppppp/7n/1p6/8/1P3b1N/PRPPPPPP/B1QNK1RB w f - 5 9 +epd r1qnkr1b/p1pppppp/7n/1p6/8/1P3b1N/PRPPPPPP/B1QNK1RB w f - perft 1 21 perft 2 677 perft 3 15437 @@ -5357,7 +5357,7 @@ perft 5 12463801 perft 6 410795298 id 595 -epd rbbqn1rn/pppp1pp1/3k4/4p2Q/2PPP3/8/PP3PPP/RBB1NKRN w GA - 1 9 +epd rbbqn1rn/pppp1pp1/3k4/4p2Q/2PPP3/8/PP3PPP/RBB1NKRN w GA - perft 1 40 perft 2 742 perft 3 28757 @@ -5366,7 +5366,7 @@ perft 5 21852196 perft 6 471452088 id 596 -epd rqbbnkrn/3pppp1/p1p4p/1p6/5P2/P2N4/1PPPP1PP/RQBBK1RN w ga - 0 9 +epd rqbbnkrn/3pppp1/p1p4p/1p6/5P2/P2N4/1PPPP1PP/RQBBK1RN w ga - perft 1 23 perft 2 665 perft 3 16400 @@ -5375,7 +5375,7 @@ perft 5 12794736 perft 6 396640086 id 597 -epd r2nkbrn/pp2pppp/8/2ppqb2/2P3P1/5P2/PP1PPN1P/RQB1KBRN w GAga - 3 9 +epd r2nkbrn/pp2pppp/8/2ppqb2/2P3P1/5P2/PP1PPN1P/RQB1KBRN w GAga - perft 1 28 perft 2 1108 perft 3 31164 @@ -5384,7 +5384,7 @@ perft 5 34780853 perft 6 1292405738 id 598 -epd rqbnk1nb/p1pppr1p/5p2/1p4p1/1PP1P3/8/P2P1PPP/RQBNKRNB w FAa - 1 9 +epd rqbnk1nb/p1pppr1p/5p2/1p4p1/1PP1P3/8/P2P1PPP/RQBNKRNB w FAa - perft 1 26 perft 2 650 perft 3 18208 @@ -5393,7 +5393,7 @@ perft 5 14565370 perft 6 416833400 id 599 -epd rbqnb1rn/p1pp1kpp/1p2pp2/8/4P2P/P5P1/1PPP1P2/RBQNBKRN w GA - 0 9 +epd rbqnb1rn/p1pp1kpp/1p2pp2/8/4P2P/P5P1/1PPP1P2/RBQNBKRN w GA - perft 1 20 perft 2 437 perft 3 9423 @@ -5402,7 +5402,7 @@ perft 5 5282124 perft 6 132309824 id 600 -epd rqnbbkrn/p1p1pppp/3p4/1p5B/8/1P1NP3/P1PP1PPP/RQ2BKRN w GAga - 0 9 +epd rqnbbkrn/p1p1pppp/3p4/1p5B/8/1P1NP3/P1PP1PPP/RQ2BKRN w GAga - perft 1 30 perft 2 606 perft 3 18382 @@ -5411,7 +5411,7 @@ perft 5 12989786 perft 6 326601372 id 601 -epd rqnkbbr1/ppppp1pp/5p2/7n/8/2PNP2P/PP1P1PP1/RQ1KBBRN w GAga - 1 9 +epd rqnkbbr1/ppppp1pp/5p2/7n/8/2PNP2P/PP1P1PP1/RQ1KBBRN w GAga - perft 1 23 perft 2 482 perft 3 12506 @@ -5420,7 +5420,7 @@ perft 5 8430874 perft 6 217797292 id 602 -epd r1nkbrnb/2ppppp1/1q6/pp5p/1P6/P3P3/2PPKPPP/RQN1BRNB w fa - 2 9 +epd r1nkbrnb/2ppppp1/1q6/pp5p/1P6/P3P3/2PPKPPP/RQN1BRNB w fa - perft 1 25 perft 2 827 perft 3 21518 @@ -5429,7 +5429,7 @@ perft 5 19290675 perft 6 632892337 id 603 -epd rbqnkrbn/p1ppppp1/7p/1p6/7P/2N1P3/PPPP1PPB/RBQ1KR1N w FAfa - 1 9 +epd rbqnkrbn/p1ppppp1/7p/1p6/7P/2N1P3/PPPP1PPB/RBQ1KR1N w FAfa - perft 1 30 perft 2 627 perft 3 18566 @@ -5438,7 +5438,7 @@ perft 5 12976682 perft 6 337377291 id 604 -epd r1nbkrbn/p1qp1ppp/8/1pp1p3/2P1P3/6P1/PP1PBP1P/RQN1KRBN w FAfa - 2 9 +epd r1nbkrbn/p1qp1ppp/8/1pp1p3/2P1P3/6P1/PP1PBP1P/RQN1KRBN w FAfa - perft 1 22 perft 2 616 perft 3 14503 @@ -5447,7 +5447,7 @@ perft 5 10850952 perft 6 335943324 id 605 -epd rqnkr1bn/ppp1ppb1/3p2pp/8/P7/2P2P2/1PKPP1PP/RQN1RBBN w ea - 1 9 +epd rqnkr1bn/ppp1ppb1/3p2pp/8/P7/2P2P2/1PKPP1PP/RQN1RBBN w ea - perft 1 31 perft 2 679 perft 3 21365 @@ -5456,7 +5456,7 @@ perft 5 15661072 perft 6 379844460 id 606 -epd r2krnbb/qppp1ppp/1n6/p3p3/PP6/4N3/N1PPPPPP/RQ1KR1BB w EAea - 4 9 +epd r2krnbb/qppp1ppp/1n6/p3p3/PP6/4N3/N1PPPPPP/RQ1KR1BB w EAea - perft 1 24 perft 2 645 perft 3 17054 @@ -5465,7 +5465,7 @@ perft 5 13837270 perft 6 416239106 id 607 -epd bbr1qk1n/1ppppp1p/2n5/p7/P7/1P2P3/2PP1PrP/1BRNQKRN w GCc - 0 9 +epd bbr1qk1n/1ppppp1p/2n5/p7/P7/1P2P3/2PP1PrP/1BRNQKRN w GCc - perft 1 18 perft 2 520 perft 3 10680 @@ -5474,7 +5474,7 @@ perft 5 7215306 perft 6 207612575 id 608 -epd brnbq1rn/2ppppkp/p5p1/1p6/8/1BP3P1/PP1PPP1P/BRN1QRKN w - - 0 9 +epd brnbq1rn/2ppppkp/p5p1/1p6/8/1BP3P1/PP1PPP1P/BRN1QRKN w - - perft 1 21 perft 2 625 perft 3 13989 @@ -5483,7 +5483,7 @@ perft 5 9929336 perft 6 300902534 id 609 -epd brn1kbrn/pp2p1pp/3p4/q1p2p2/2P4P/6P1/PP1PPP2/BRNQKBRN w GBgb - 1 9 +epd brn1kbrn/pp2p1pp/3p4/q1p2p2/2P4P/6P1/PP1PPP2/BRNQKBRN w GBgb - perft 1 18 perft 2 477 perft 3 10205 @@ -5492,7 +5492,7 @@ perft 5 6720181 perft 6 187205941 id 610 -epd brn1krnb/p3pppp/1qpp4/1p6/2P3P1/1P6/P2PPP1P/BRNQKRNB w FBfb - 1 9 +epd brn1krnb/p3pppp/1qpp4/1p6/2P3P1/1P6/P2PPP1P/BRNQKRNB w FBfb - perft 1 30 perft 2 835 perft 3 24761 @@ -5501,7 +5501,7 @@ perft 5 21806428 perft 6 654487872 id 611 -epd r1b1qkrn/1p1ppppp/p1p1n3/8/4P3/1PN5/P1PPQPPb/RBB2KRN w GAga - 0 9 +epd r1b1qkrn/1p1ppppp/p1p1n3/8/4P3/1PN5/P1PPQPPb/RBB2KRN w GAga - perft 1 28 perft 2 825 perft 3 24536 @@ -5510,7 +5510,7 @@ perft 5 22079005 perft 6 647939781 id 612 -epd r1bbqk1n/p1pppprp/n7/1p4p1/5P2/2N3N1/PPPPP1PP/1RBBQKR1 w Ga - 4 9 +epd r1bbqk1n/p1pppprp/n7/1p4p1/5P2/2N3N1/PPPPP1PP/1RBBQKR1 w Ga - perft 1 25 perft 2 545 perft 3 14657 @@ -5519,7 +5519,7 @@ perft 5 10271111 perft 6 273864588 id 613 -epd rnbqkbrn/p1pp1pp1/4p3/7p/2p4P/2P5/PP1PPPP1/R1BQKBRN w GAga - 0 9 +epd rnbqkbrn/p1pp1pp1/4p3/7p/2p4P/2P5/PP1PPPP1/R1BQKBRN w GAga - perft 1 17 perft 2 445 perft 3 9076 @@ -5528,7 +5528,7 @@ perft 5 5918310 perft 6 174733195 id 614 -epd rnbqkrnb/1p1pp1p1/2p4p/p4p2/3P2P1/7N/PPPBPP1P/RN1QKR1B w FAfa - 0 9 +epd rnbqkrnb/1p1pp1p1/2p4p/p4p2/3P2P1/7N/PPPBPP1P/RN1QKR1B w FAfa - perft 1 34 perft 2 746 perft 3 25319 @@ -5537,7 +5537,7 @@ perft 5 21285553 perft 6 569141201 id 615 -epd rbnqbkr1/1ppppp2/p5n1/6pp/4P3/1N6/PPPP1PPP/RBQ1BRKN w ga - 2 9 +epd rbnqbkr1/1ppppp2/p5n1/6pp/4P3/1N6/PPPP1PPP/RBQ1BRKN w ga - perft 1 18 perft 2 466 perft 3 9683 @@ -5546,7 +5546,7 @@ perft 5 6051500 perft 6 170135726 id 616 -epd rnqb1krn/ppppp1p1/7p/7b/P1P2pPP/8/1P1PPP2/RNQBBKRN w GAga - 0 9 +epd rnqb1krn/ppppp1p1/7p/7b/P1P2pPP/8/1P1PPP2/RNQBBKRN w GAga - perft 1 24 perft 2 575 perft 3 15400 @@ -5555,7 +5555,7 @@ perft 5 11039042 perft 6 291243811 id 617 -epd rnqkbbr1/p1pp1ppp/4p3/1p6/P3P2n/5P2/1PPP1NPP/RNQKBBR1 w GAga - 2 9 +epd rnqkbbr1/p1pp1ppp/4p3/1p6/P3P2n/5P2/1PPP1NPP/RNQKBBR1 w GAga - perft 1 27 perft 2 803 perft 3 22883 @@ -5564,7 +5564,7 @@ perft 5 20666099 perft 6 638696065 id 618 -epd rn1kbrnb/1qppp1pp/1p6/p4p2/1B1P4/1P5N/P1P1PPPP/RNQK1R1B w FAfa - 0 9 +epd rn1kbrnb/1qppp1pp/1p6/p4p2/1B1P4/1P5N/P1P1PPPP/RNQK1R1B w FAfa - perft 1 37 perft 2 1209 perft 3 43015 @@ -5573,7 +5573,7 @@ perft 5 49748034 perft 6 1671593862 id 619 -epd rbnqkrbn/Bppp1p2/p5pp/4p3/5P2/6PP/PPPPP3/RBNQKR1N w FAfa - 0 9 +epd rbnqkrbn/Bppp1p2/p5pp/4p3/5P2/6PP/PPPPP3/RBNQKR1N w FAfa - perft 1 29 perft 2 720 perft 3 20434 @@ -5582,7 +5582,7 @@ perft 5 15384362 perft 6 421343249 id 620 -epd rnqbkr1n/1p1ppbpp/3p1p2/p7/8/1P6/P1PPPPPP/R1QBKRBN w FAfa - 0 9 +epd rnqbkr1n/1p1ppbpp/3p1p2/p7/8/1P6/P1PPPPPP/R1QBKRBN w FAfa - perft 1 20 perft 2 657 perft 3 14424 @@ -5591,7 +5591,7 @@ perft 5 11843134 perft 6 413965054 id 621 -epd rnqkrb1n/ppppp3/6p1/5p1p/2b2P2/P1N5/1PPPP1PP/RQ1KRBBN w EAea - 1 9 +epd rnqkrb1n/ppppp3/6p1/5p1p/2b2P2/P1N5/1PPPP1PP/RQ1KRBBN w EAea - perft 1 28 perft 2 749 perft 3 20684 @@ -5600,7 +5600,7 @@ perft 5 15379233 perft 6 417191461 id 622 -epd rnqk1nbb/1pp2ppp/3pr3/p3p3/3P1P2/2N3N1/PPP1P1PP/R1QKR1BB w EAa - 1 9 +epd rnqk1nbb/1pp2ppp/3pr3/p3p3/3P1P2/2N3N1/PPP1P1PP/R1QKR1BB w EAa - perft 1 29 perft 2 883 perft 3 26412 @@ -5609,7 +5609,7 @@ perft 5 25144295 perft 6 789705382 id 623 -epd bbr1kqrn/p1p1ppp1/1p2n2p/3p4/1P1P4/2N5/P1P1PPPP/BBR1KQRN w GCgc - 0 9 +epd bbr1kqrn/p1p1ppp1/1p2n2p/3p4/1P1P4/2N5/P1P1PPPP/BBR1KQRN w GCgc - perft 1 22 perft 2 485 perft 3 11475 @@ -5618,7 +5618,7 @@ perft 5 6825123 perft 6 171793012 id 624 -epd brnbkq1n/ppp1ppr1/7p/3p2p1/2P3PP/8/PPBPPP2/BRN1KQRN w GBb - 2 9 +epd brnbkq1n/ppp1ppr1/7p/3p2p1/2P3PP/8/PPBPPP2/BRN1KQRN w GBb - perft 1 30 perft 2 634 perft 3 19017 @@ -5627,7 +5627,7 @@ perft 5 13674310 perft 6 345386924 id 625 -epd brnkqbr1/1pppp1pp/5p2/p7/P1P1P2n/8/1P1P1PP1/BRNKQBRN w GBgb - 0 9 +epd brnkqbr1/1pppp1pp/5p2/p7/P1P1P2n/8/1P1P1PP1/BRNKQBRN w GBgb - perft 1 21 perft 2 504 perft 3 11672 @@ -5636,7 +5636,7 @@ perft 5 7778289 perft 6 217596497 id 626 -epd b1rkqrnb/p1ppp1pp/1p1n4/5p2/5P2/PN5P/1PPPP1P1/BR1KQRNB w FBf - 0 9 +epd b1rkqrnb/p1ppp1pp/1p1n4/5p2/5P2/PN5P/1PPPP1P1/BR1KQRNB w FBf - perft 1 23 perft 2 688 perft 3 17259 @@ -5645,7 +5645,7 @@ perft 5 14228372 perft 6 451842354 id 627 -epd 1bbnkqrn/rppppp2/p5p1/7p/7P/P1P1P3/1P1P1PP1/RBBNKQRN w GAg - 1 9 +epd 1bbnkqrn/rppppp2/p5p1/7p/7P/P1P1P3/1P1P1PP1/RBBNKQRN w GAg - perft 1 25 perft 2 450 perft 3 12391 @@ -5654,7 +5654,7 @@ perft 5 7752404 perft 6 185393913 id 628 -epd rnbbkqr1/1pppppp1/7p/p3n3/PP5P/8/1BPPPPP1/RN1BKQRN w GAga - 0 9 +epd rnbbkqr1/1pppppp1/7p/p3n3/PP5P/8/1BPPPPP1/RN1BKQRN w GAga - perft 1 23 perft 2 543 perft 3 12224 @@ -5663,7 +5663,7 @@ perft 5 7549008 perft 6 199883770 id 629 -epd r1bkqbrn/ppppp1pp/8/5p2/3nPP2/1P4N1/P1PP2PP/RNBKQBR1 w GAga - 1 9 +epd r1bkqbrn/ppppp1pp/8/5p2/3nPP2/1P4N1/P1PP2PP/RNBKQBR1 w GAga - perft 1 27 perft 2 751 perft 3 21158 @@ -5672,7 +5672,7 @@ perft 5 17989920 perft 6 527273615 id 630 -epd rnbkqr1b/1p1pp1pp/p4p1n/2p5/1P5P/N4P2/P1PPP1P1/R1BKQRNB w FAfa - 0 9 +epd rnbkqr1b/1p1pp1pp/p4p1n/2p5/1P5P/N4P2/P1PPP1P1/R1BKQRNB w FAfa - perft 1 21 perft 2 498 perft 3 11738 @@ -5681,7 +5681,7 @@ perft 5 7808375 perft 6 216224115 id 631 -epd rbnkbqrn/p1p3pp/1p1p4/B3pp2/3P2P1/6N1/PPP1PP1P/RBNK1QR1 w GAga - 0 9 +epd rbnkbqrn/p1p3pp/1p1p4/B3pp2/3P2P1/6N1/PPP1PP1P/RBNK1QR1 w GAga - perft 1 34 perft 2 977 perft 3 33464 @@ -5690,7 +5690,7 @@ perft 5 33318567 perft 6 978991050 id 632 -epd r1kbbqrn/ppp3pp/2np1p2/1P2p3/3P1P2/8/P1P1P1PP/RNKBBQRN w GAga - 0 9 +epd r1kbbqrn/ppp3pp/2np1p2/1P2p3/3P1P2/8/P1P1P1PP/RNKBBQRN w GAga - perft 1 32 perft 2 920 perft 3 28916 @@ -5699,7 +5699,7 @@ perft 5 26763259 perft 6 797524786 id 633 -epd rk1qbbrn/p2npppp/1p6/2p4Q/8/4P3/PPPP1PPP/RNK1B1RN w GA - 2 9 +epd rk1qbbrn/p2npppp/1p6/2p4Q/8/4P3/PPPP1PPP/RNK1B1RN w GA - perft 1 35 perft 2 657 perft 3 22359 @@ -5708,7 +5708,7 @@ perft 5 16662477 perft 6 419496845 id 634 -epd rnk1brnb/pp1p1pp1/8/q1p1p2p/5P2/NP6/P1PPP1PP/R1KQBRNB w FAfa - 1 9 +epd rnk1brnb/pp1p1pp1/8/q1p1p2p/5P2/NP6/P1PPP1PP/R1KQBRNB w FAfa - perft 1 26 perft 2 774 perft 3 20215 @@ -5717,7 +5717,7 @@ perft 5 16987110 perft 6 523437649 id 635 -epd rb1kqrbn/npp1ppp1/p7/3P3p/2PP4/8/PP3PPP/RBNKQRBN w FAfa - 0 9 +epd rb1kqrbn/npp1ppp1/p7/3P3p/2PP4/8/PP3PPP/RBNKQRBN w FAfa - perft 1 35 perft 2 775 perft 3 27395 @@ -5726,7 +5726,7 @@ perft 5 23983464 perft 6 625669222 id 636 -epd rnkb1rbn/pp1p2pp/8/2p1pp1q/P6P/1PN5/2PPPPP1/R1KBQRBN w FAfa - 1 9 +epd rnkb1rbn/pp1p2pp/8/2p1pp1q/P6P/1PN5/2PPPPP1/R1KBQRBN w FAfa - perft 1 22 perft 2 899 perft 3 21188 @@ -5735,7 +5735,7 @@ perft 5 21518343 perft 6 857951339 id 637 -epd rnkqrbbn/1pppp1p1/8/p2N1p1p/2P4P/8/PP1PPPP1/R1KQRBBN w EAea - 0 9 +epd rnkqrbbn/1pppp1p1/8/p2N1p1p/2P4P/8/PP1PPPP1/R1KQRBBN w EAea - perft 1 29 perft 2 585 perft 3 17571 @@ -5744,7 +5744,7 @@ perft 5 12238776 perft 6 299752383 id 638 -epd rnk1r1bb/pp1ppppp/1q4n1/2p5/5P1P/3PP3/PPP3P1/RNKQRNBB w EAea - 1 9 +epd rnk1r1bb/pp1ppppp/1q4n1/2p5/5P1P/3PP3/PPP3P1/RNKQRNBB w EAea - perft 1 27 perft 2 884 perft 3 24613 @@ -5753,7 +5753,7 @@ perft 5 23698701 perft 6 790239502 id 639 -epd bbrnkrqn/1ppp1p2/6pp/p3p3/5PP1/2PB4/PP1PP2P/B1RNKRQN w FCfc - 0 9 +epd bbrnkrqn/1ppp1p2/6pp/p3p3/5PP1/2PB4/PP1PP2P/B1RNKRQN w FCfc - perft 1 37 perft 2 693 perft 3 25425 @@ -5762,7 +5762,7 @@ perft 5 20138432 perft 6 481498664 id 640 -epd b1rbkrqn/ppp2ppp/1n2p3/3p4/6P1/2PP4/PP2PP1P/BRNBKRQN w FBf - 1 9 +epd b1rbkrqn/ppp2ppp/1n2p3/3p4/6P1/2PP4/PP2PP1P/BRNBKRQN w FBf - perft 1 21 perft 2 463 perft 3 10610 @@ -5771,7 +5771,7 @@ perft 5 6307276 perft 6 159025909 id 641 -epd brnkrb1n/1pp1p1pp/3p4/p1Nq1p2/2P5/8/PP1PPPPP/BRK1RBQN w eb - 2 9 +epd brnkrb1n/1pp1p1pp/3p4/p1Nq1p2/2P5/8/PP1PPPPP/BRK1RBQN w eb - perft 1 27 perft 2 725 perft 3 17842 @@ -5780,7 +5780,7 @@ perft 5 12604078 perft 6 362747791 id 642 -epd brn1r1nb/ppppkppp/4p3/8/2PP1P2/8/PP1KP1PP/BRN1RQNB w - - 1 9 +epd brn1r1nb/ppppkppp/4p3/8/2PP1P2/8/PP1KP1PP/BRN1RQNB w - - perft 1 25 perft 2 623 perft 3 16874 @@ -5789,7 +5789,7 @@ perft 5 12290985 perft 6 317097424 id 643 -epd rbb1krqn/1pp1pp1p/p3n1p1/3pP3/8/1PN5/P1PP1PPP/RBB1KRQN w FAfa d6 0 9 +epd rbb1krqn/1pp1pp1p/p3n1p1/3pP3/8/1PN5/P1PP1PPP/RBB1KRQN w FAfa d6 perft 1 23 perft 2 529 perft 3 12641 @@ -5798,7 +5798,7 @@ perft 5 7861413 perft 6 202594556 id 644 -epd r1bbkrqn/p1pppppp/8/4n3/1p5P/P2P2P1/1PP1PP2/RNBBKRQN w FAfa - 0 9 +epd r1bbkrqn/p1pppppp/8/4n3/1p5P/P2P2P1/1PP1PP2/RNBBKRQN w FAfa - perft 1 23 perft 2 571 perft 3 13133 @@ -5807,7 +5807,7 @@ perft 5 8699448 perft 6 243460643 id 645 -epd rnbkrbqn/p1pp1ppp/4p3/1p6/8/BPN3P1/P1PPPP1P/R2KRBQN w EAea - 2 9 +epd rnbkrbqn/p1pp1ppp/4p3/1p6/8/BPN3P1/P1PPPP1P/R2KRBQN w EAea - perft 1 29 perft 2 692 perft 3 20014 @@ -5816,7 +5816,7 @@ perft 5 14904192 perft 6 386694739 id 646 -epd rnbkrqn1/pppppp2/8/1Q2b1pp/P3P3/5P2/1PPP2PP/RNBKR1NB w EAea - 0 9 +epd rnbkrqn1/pppppp2/8/1Q2b1pp/P3P3/5P2/1PPP2PP/RNBKR1NB w EAea - perft 1 37 perft 2 1001 perft 3 36440 @@ -5825,7 +5825,7 @@ perft 5 35626426 perft 6 993747544 id 647 -epd rbnkbrqn/p1pppp2/7p/1p4pP/3P1P2/8/PPP1P1P1/RBNKBRQN w FAfa - 0 9 +epd rbnkbrqn/p1pppp2/7p/1p4pP/3P1P2/8/PPP1P1P1/RBNKBRQN w FAfa - perft 1 30 perft 2 564 perft 3 17143 @@ -5834,7 +5834,7 @@ perft 5 11859538 perft 6 293703269 id 648 -epd 1nkbbrqn/3ppppp/r1p5/pp6/8/4PP2/PPPPN1PP/RNKBBRQ1 w FAf - 2 9 +epd 1nkbbrqn/3ppppp/r1p5/pp6/8/4PP2/PPPPN1PP/RNKBBRQ1 w FAf - perft 1 26 perft 2 546 perft 3 14641 @@ -5843,7 +5843,7 @@ perft 5 9556962 perft 6 245137199 id 649 -epd rnkrbbq1/pppppnp1/7p/8/1B1Q1p2/3P1P2/PPP1P1PP/RNKR1B1N w DAda - 2 9 +epd rnkrbbq1/pppppnp1/7p/8/1B1Q1p2/3P1P2/PPP1P1PP/RNKR1B1N w DAda - perft 1 43 perft 2 887 perft 3 36240 @@ -5852,7 +5852,7 @@ perft 5 33185346 perft 6 851927292 id 650 -epd 1rkrbqnb/pppppp2/2n3p1/7p/3P3P/P4N2/1PP1PPP1/RNKRBQ1B w DAd - 0 9 +epd 1rkrbqnb/pppppp2/2n3p1/7p/3P3P/P4N2/1PP1PPP1/RNKRBQ1B w DAd - perft 1 26 perft 2 622 perft 3 16049 @@ -5861,7 +5861,7 @@ perft 5 10786140 perft 6 285233838 id 651 -epd rbnkr1bn/pp1pqp1p/2p1p3/6p1/3P4/7P/PPP1PPP1/RBNKRQBN w EAea - 0 9 +epd rbnkr1bn/pp1pqp1p/2p1p3/6p1/3P4/7P/PPP1PPP1/RBNKRQBN w EAea - perft 1 19 perft 2 566 perft 3 12257 @@ -5870,7 +5870,7 @@ perft 5 9107175 perft 6 293397389 id 652 -epd r1kbrqb1/pppp2pp/2n1p1n1/5p1B/4PP2/P7/1PPP2PP/RNK1RQBN w EAea - 2 9 +epd r1kbrqb1/pppp2pp/2n1p1n1/5p1B/4PP2/P7/1PPP2PP/RNK1RQBN w EAea - perft 1 39 perft 2 1359 perft 3 53626 @@ -5879,7 +5879,7 @@ perft 5 73871486 perft 6 2633945690 id 653 -epd rnkrqbbn/p1p3pp/1p1ppp2/8/1P6/3P2P1/PKP1PP1P/RN1RQBBN w da - 0 9 +epd rnkrqbbn/p1p3pp/1p1ppp2/8/1P6/3P2P1/PKP1PP1P/RN1RQBBN w da - perft 1 26 perft 2 776 perft 3 20735 @@ -5888,7 +5888,7 @@ perft 5 16884013 perft 6 503561996 id 654 -epd rnkrqnbb/ppp2p1p/3p4/4p1p1/3P3P/N1Q5/PPP1PPP1/R1KR1NBB w DAda - 0 9 +epd rnkrqnbb/ppp2p1p/3p4/4p1p1/3P3P/N1Q5/PPP1PPP1/R1KR1NBB w DAda - perft 1 40 perft 2 1175 perft 3 45637 @@ -5897,7 +5897,7 @@ perft 5 52620163 perft 6 1633655838 id 655 -epd bbrnkrn1/p1pppp2/1p6/6pp/3q4/1P3QP1/P1PPPP1P/BBRNKRN1 w FCfc - 0 9 +epd bbrnkrn1/p1pppp2/1p6/6pp/3q4/1P3QP1/P1PPPP1P/BBRNKRN1 w FCfc - perft 1 34 perft 2 1398 perft 3 45749 @@ -5906,7 +5906,7 @@ perft 5 57268492 perft 6 2059942014 id 656 -epd br1bkrnq/1p2pppp/pnp5/3p4/P1P5/5P2/1P1PPKPP/BRNB1RNQ w fb - 2 9 +epd br1bkrnq/1p2pppp/pnp5/3p4/P1P5/5P2/1P1PPKPP/BRNB1RNQ w fb - perft 1 24 perft 2 501 perft 3 12237 @@ -5915,7 +5915,7 @@ perft 5 7049659 perft 6 177940764 id 657 -epd brnkrbn1/pppppp1q/B6p/6p1/8/1P2PP2/P1PP2PP/BRNKR1NQ w EBeb - 0 9 +epd brnkrbn1/pppppp1q/B6p/6p1/8/1P2PP2/P1PP2PP/BRNKR1NQ w EBeb - perft 1 34 perft 2 815 perft 3 25868 @@ -5924,7 +5924,7 @@ perft 5 22006883 perft 6 639803952 id 658 -epd br1krnqb/pppppp1p/1n4p1/8/8/P2NN3/2PPPPPP/BR1K1RQB w Beb - 2 9 +epd br1krnqb/pppppp1p/1n4p1/8/8/P2NN3/2PPPPPP/BR1K1RQB w Beb - perft 1 37 perft 2 1029 perft 3 36748 @@ -5933,7 +5933,7 @@ perft 5 36214583 perft 6 1026195877 id 659 -epd rbbnkr1q/p1p2ppp/1p1ppn2/8/1PP4P/8/P2PPPP1/RBBNKRNQ w FAfa - 0 9 +epd rbbnkr1q/p1p2ppp/1p1ppn2/8/1PP4P/8/P2PPPP1/RBBNKRNQ w FAfa - perft 1 28 perft 2 755 perft 3 22623 @@ -5942,7 +5942,7 @@ perft 5 18972778 perft 6 513486101 id 660 -epd r1b1krnq/pp2pppp/1bn5/2pp4/4N3/5P2/PPPPPRPP/R1BBK1NQ w Afa - 0 9 +epd r1b1krnq/pp2pppp/1bn5/2pp4/4N3/5P2/PPPPPRPP/R1BBK1NQ w Afa - perft 1 24 perft 2 705 perft 3 17427 @@ -5951,7 +5951,7 @@ perft 5 13532966 perft 6 426443376 id 661 -epd 1nbkrbn1/rpppppqp/p7/6p1/4P3/3P2P1/PPP1KP1P/RNB1RBNQ w e - 1 9 +epd 1nbkrbn1/rpppppqp/p7/6p1/4P3/3P2P1/PPP1KP1P/RNB1RBNQ w e - perft 1 31 perft 2 800 perft 3 24748 @@ -5960,7 +5960,7 @@ perft 5 21193292 perft 6 625757852 id 662 -epd r1bkrnqb/pp3ppp/n1ppp3/8/1P5P/P7/R1PPPPP1/1NBKRNQB w Eea - 0 9 +epd r1bkrnqb/pp3ppp/n1ppp3/8/1P5P/P7/R1PPPPP1/1NBKRNQB w Eea - perft 1 21 perft 2 482 perft 3 11417 @@ -5969,7 +5969,7 @@ perft 5 7112890 perft 6 180378139 id 663 -epd rbnkbrnq/ppp1p2p/5p2/3p2p1/1B1P4/1N4P1/PPP1PP1P/RB1K1RNQ w FAfa - 0 9 +epd rbnkbrnq/ppp1p2p/5p2/3p2p1/1B1P4/1N4P1/PPP1PP1P/RB1K1RNQ w FAfa - perft 1 33 perft 2 780 perft 3 25532 @@ -5978,7 +5978,7 @@ perft 5 20756770 perft 6 535497008 id 664 -epd rnk1brnq/pp1ppppp/2p5/b7/8/1P2P2P/P1PP1PPQ/RNKBBRN1 w FAfa - 3 9 +epd rnk1brnq/pp1ppppp/2p5/b7/8/1P2P2P/P1PP1PPQ/RNKBBRN1 w FAfa - perft 1 29 perft 2 648 perft 3 19043 @@ -5987,7 +5987,7 @@ perft 5 13722785 perft 6 341389148 id 665 -epd rnkrbbnq/p1p3pp/5p2/1p1pp3/P7/1PN2P2/2PPP1PP/R1KRBBNQ w DAda - 0 9 +epd rnkrbbnq/p1p3pp/5p2/1p1pp3/P7/1PN2P2/2PPP1PP/R1KRBBNQ w DAda - perft 1 26 perft 2 827 perft 3 21865 @@ -5996,7 +5996,7 @@ perft 5 18916370 perft 6 589161126 id 666 -epd r1krbnqb/p1pp1ppp/2n1p3/8/1p4P1/PPP5/3PPP1P/RNKRBNQB w DAda - 1 9 +epd r1krbnqb/p1pp1ppp/2n1p3/8/1p4P1/PPP5/3PPP1P/RNKRBNQB w DAda - perft 1 25 perft 2 540 perft 3 14709 @@ -6005,7 +6005,7 @@ perft 5 9491817 perft 6 225389422 id 667 -epd rbnkrnbq/ppp1pp2/3p2p1/2N5/P6p/2P5/1P1PPPPP/RB1KRNBQ w EAea - 0 9 +epd rbnkrnbq/ppp1pp2/3p2p1/2N5/P6p/2P5/1P1PPPPP/RB1KRNBQ w EAea - perft 1 32 perft 2 790 perft 3 25107 @@ -6014,7 +6014,7 @@ perft 5 20906017 perft 6 578332225 id 668 -epd rnkbrn1q/1ppppppb/8/p4N1p/8/P1N5/1PPPPPPP/R1KBR1BQ w EAea - 0 9 +epd rnkbrn1q/1ppppppb/8/p4N1p/8/P1N5/1PPPPPPP/R1KBR1BQ w EAea - perft 1 31 perft 2 691 perft 3 20813 @@ -6023,7 +6023,7 @@ perft 5 15308408 perft 6 404129987 id 669 -epd rnkrnbbq/p1p2ppp/3pp3/1p6/6P1/4PQ1B/PPPP1P1P/RNKRN1B1 w DAda - 0 9 +epd rnkrnbbq/p1p2ppp/3pp3/1p6/6P1/4PQ1B/PPPP1P1P/RNKRN1B1 w DAda - perft 1 29 perft 2 558 perft 3 16800 @@ -6032,7 +6032,7 @@ perft 5 10825379 perft 6 246965507 id 670 -epd rnkrnqbb/pp2p1p1/3p3p/2p2p2/5P2/1P1N4/P1PPPQPP/RNKR2BB w DAda - 0 9 +epd rnkrnqbb/pp2p1p1/3p3p/2p2p2/5P2/1P1N4/P1PPPQPP/RNKR2BB w DAda - perft 1 29 perft 2 762 perft 3 23210 @@ -6041,7 +6041,7 @@ perft 5 20522675 perft 6 596067005 id 671 -epd bb1rknnr/ppqppppp/8/2p5/3P1N2/1P6/P1P1PPPP/BBQRKN1R w HDhd - 1 9 +epd bb1rknnr/ppqppppp/8/2p5/3P1N2/1P6/P1P1PPPP/BBQRKN1R w HDhd - perft 1 33 perft 2 963 perft 3 32279 @@ -6050,7 +6050,7 @@ perft 5 34552118 perft 6 1124738493 id 672 -epd bqrbknnr/ppp1p2p/8/3p1p2/5p2/P3N2P/1PPPP1P1/BQRBK1NR w HChc - 0 9 +epd bqrbknnr/ppp1p2p/8/3p1p2/5p2/P3N2P/1PPPP1P1/BQRBK1NR w HChc - perft 1 20 perft 2 398 perft 3 9009 @@ -6059,7 +6059,7 @@ perft 5 4834319 perft 6 113660536 id 673 -epd b1rk1bnr/qpp1pppp/p4n2/3p4/3PPP2/7N/PPP3PP/BQRKNB1R w HChc - 1 9 +epd b1rk1bnr/qpp1pppp/p4n2/3p4/3PPP2/7N/PPP3PP/BQRKNB1R w HChc - perft 1 25 perft 2 648 perft 3 16587 @@ -6068,7 +6068,7 @@ perft 5 12200870 perft 6 351766307 id 674 -epd bqkrnnrb/pppp2p1/4pp2/4P2p/6P1/7P/PPPP1P2/BQRKNNRB w GC - 1 9 +epd bqkrnnrb/pppp2p1/4pp2/4P2p/6P1/7P/PPPP1P2/BQRKNNRB w GC - perft 1 30 perft 2 493 perft 3 15118 @@ -6077,7 +6077,7 @@ perft 5 8786998 perft 6 181492621 id 675 -epd q1brknnr/1p1ppppp/p7/2p5/8/1PPP4/P2RPPPP/QBB1KNNR w Hhd - 0 9 +epd q1brknnr/1p1ppppp/p7/2p5/8/1PPP4/P2RPPPP/QBB1KNNR w Hhd - perft 1 25 perft 2 501 perft 3 13206 @@ -6086,7 +6086,7 @@ perft 5 7982978 perft 6 192717198 id 676 -epd qrb1k1nr/ppppb1pp/6n1/4ppN1/3P4/4N3/PPP1PPPP/QRBBK2R w HBhb - 2 9 +epd qrb1k1nr/ppppb1pp/6n1/4ppN1/3P4/4N3/PPP1PPPP/QRBBK2R w HBhb - perft 1 31 perft 2 872 perft 3 26191 @@ -6095,7 +6095,7 @@ perft 5 22493014 perft 6 646855304 id 677 -epd 1rbknbnr/1ppp1pp1/q6p/p3p3/5P2/2PPB3/PP2P1PP/QR1KNBNR w HBhb - 0 9 +epd 1rbknbnr/1ppp1pp1/q6p/p3p3/5P2/2PPB3/PP2P1PP/QR1KNBNR w HBhb - perft 1 28 perft 2 1020 perft 3 28147 @@ -6104,7 +6104,7 @@ perft 5 27484692 perft 6 947786800 id 678 -epd qrbk2rb/1ppp1ppp/5nn1/p3p3/1N6/P7/1PPPPPPP/QRB1KNRB w gb - 0 9 +epd qrbk2rb/1ppp1ppp/5nn1/p3p3/1N6/P7/1PPPPPPP/QRB1KNRB w gb - perft 1 23 perft 2 592 perft 3 14398 @@ -6113,7 +6113,7 @@ perft 5 10098215 perft 6 293988585 id 679 -epd qbrk1nnr/1pp1pppp/2b5/p2p4/P2P2P1/8/1PP1PP1P/QBKRBNNR w hc - 1 9 +epd qbrk1nnr/1pp1pppp/2b5/p2p4/P2P2P1/8/1PP1PP1P/QBKRBNNR w hc - perft 1 26 perft 2 654 perft 3 18103 @@ -6122,7 +6122,7 @@ perft 5 13740891 perft 6 373081138 id 680 -epd qrkbbnnr/ppp2p1p/4p3/3p2p1/P7/2PP4/1P2PPPP/QRKBBNNR w HBhb - 0 9 +epd qrkbbnnr/ppp2p1p/4p3/3p2p1/P7/2PP4/1P2PPPP/QRKBBNNR w HBhb - perft 1 25 perft 2 626 perft 3 16616 @@ -6131,7 +6131,7 @@ perft 5 12079406 perft 6 324006164 id 681 -epd qr1kbbnr/ppp1pp1p/4n1p1/2Pp4/6P1/4N3/PP1PPP1P/QRK1BBNR w HB d6 0 9 +epd qr1kbbnr/ppp1pp1p/4n1p1/2Pp4/6P1/4N3/PP1PPP1P/QRK1BBNR w HB d6 perft 1 26 perft 2 699 perft 3 18068 @@ -6140,7 +6140,7 @@ perft 5 13353359 perft 6 375702908 id 682 -epd qrk1b1rb/p1pppppp/3nnQ2/1p6/1P3P2/3P4/P1P1P1PP/1RKNBNRB w GBgb - 3 9 +epd qrk1b1rb/p1pppppp/3nnQ2/1p6/1P3P2/3P4/P1P1P1PP/1RKNBNRB w GBgb - perft 1 43 perft 2 1369 perft 3 55463 @@ -6149,7 +6149,7 @@ perft 5 71514365 perft 6 2427477375 id 683 -epd qbrk1nbr/pppp3p/5n2/4ppp1/3P1P2/4N3/PPP1P1PP/QBKRN1BR w hc - 0 9 +epd qbrk1nbr/pppp3p/5n2/4ppp1/3P1P2/4N3/PPP1P1PP/QBKRN1BR w hc - perft 1 25 perft 2 752 perft 3 20165 @@ -6158,7 +6158,7 @@ perft 5 17493373 perft 6 543180234 id 684 -epd qrkb1nbr/1pppppQp/3n4/p7/5p2/1P1N4/P1PPP1PP/1RKB1NBR w HBhb - 0 9 +epd qrkb1nbr/1pppppQp/3n4/p7/5p2/1P1N4/P1PPP1PP/1RKB1NBR w HBhb - perft 1 45 perft 2 946 perft 3 40100 @@ -6167,7 +6167,7 @@ perft 5 39736157 perft 6 1051910977 id 685 -epd qrk1nbbr/ppp1p1p1/4n2p/3p1p2/1P5P/3P2P1/P1P1PP2/QRKNNBBR w HBhb - 1 9 +epd qrk1nbbr/ppp1p1p1/4n2p/3p1p2/1P5P/3P2P1/P1P1PP2/QRKNNBBR w HBhb - perft 1 32 perft 2 770 perft 3 25367 @@ -6176,7 +6176,7 @@ perft 5 21717615 perft 6 577979364 id 686 -epd qrkn1rbb/pp2pppp/2p5/3p4/P2Qn1P1/1P6/2PPPP1P/1RKNNRBB w FBfb - 0 9 +epd qrkn1rbb/pp2pppp/2p5/3p4/P2Qn1P1/1P6/2PPPP1P/1RKNNRBB w FBfb - perft 1 38 perft 2 943 perft 3 35335 @@ -6185,7 +6185,7 @@ perft 5 31909835 perft 6 798405123 id 687 -epd bbrqknnr/ppp4p/3pp3/5pp1/4PP2/5Q2/PPPP2PP/BBR1KNNR w HChc - 0 9 +epd bbrqknnr/ppp4p/3pp3/5pp1/4PP2/5Q2/PPPP2PP/BBR1KNNR w HChc - perft 1 36 perft 2 843 perft 3 29974 @@ -6194,7 +6194,7 @@ perft 5 26828059 perft 6 723306114 id 688 -epd 1rqbkn1r/p1p1pppp/1p5n/P2p4/3Pb1P1/8/1PP1PP1P/BRQBKNNR w HBhb - 0 9 +epd 1rqbkn1r/p1p1pppp/1p5n/P2p4/3Pb1P1/8/1PP1PP1P/BRQBKNNR w HBhb - perft 1 23 perft 2 778 perft 3 19482 @@ -6203,7 +6203,7 @@ perft 5 17337683 perft 6 579112676 id 689 -epd br1knbnr/1qp1pppp/pp1p4/8/8/PP6/2PPPPPP/BRQKNBNR w HBhb - 2 9 +epd br1knbnr/1qp1pppp/pp1p4/8/8/PP6/2PPPPPP/BRQKNBNR w HBhb - perft 1 26 perft 2 697 perft 3 18835 @@ -6212,7 +6212,7 @@ perft 5 15280079 perft 6 473071890 id 690 -epd brqk2rb/ppppp1pp/4np2/8/2n5/3P1Q2/PP2PPPP/BR1KNNRB w GBgb - 0 9 +epd brqk2rb/ppppp1pp/4np2/8/2n5/3P1Q2/PP2PPPP/BR1KNNRB w GBgb - perft 1 32 perft 2 948 perft 3 30434 @@ -6221,7 +6221,7 @@ perft 5 29821322 perft 6 874251866 id 691 -epd r1bqknnr/pp1pp1p1/5p1p/2p1b2N/2P5/8/PPQPPPPP/RBB1K1NR w HAha - 0 9 +epd r1bqknnr/pp1pp1p1/5p1p/2p1b2N/2P5/8/PPQPPPPP/RBB1K1NR w HAha - perft 1 31 perft 2 785 perft 3 25549 @@ -6230,7 +6230,7 @@ perft 5 22244193 perft 6 592797491 id 692 -epd rqbbknnr/ppppp2p/5pp1/8/8/1P3PP1/PQPPP2P/R1BBKNNR w HAha - 0 9 +epd rqbbknnr/ppppp2p/5pp1/8/8/1P3PP1/PQPPP2P/R1BBKNNR w HAha - perft 1 23 perft 2 391 perft 3 10163 @@ -6239,7 +6239,7 @@ perft 5 5576671 perft 6 121267576 id 693 -epd rqbknbnr/1pp1p2p/p7/3p1pp1/7N/1PP5/P2PPPPP/RQBK1BNR w HAha - 0 9 +epd rqbknbnr/1pp1p2p/p7/3p1pp1/7N/1PP5/P2PPPPP/RQBK1BNR w HAha - perft 1 27 perft 2 676 perft 3 19606 @@ -6248,7 +6248,7 @@ perft 5 15955388 perft 6 448477218 id 694 -epd rqb1nnrb/2ppkppp/1p2p3/p7/2PPP3/1P6/P4PPP/RQBKNNRB w GA - 1 9 +epd rqb1nnrb/2ppkppp/1p2p3/p7/2PPP3/1P6/P4PPP/RQBKNNRB w GA - perft 1 31 perft 2 727 perft 3 22895 @@ -6257,7 +6257,7 @@ perft 5 18361051 perft 6 483248153 id 695 -epd rb1kbn1r/p1ppppp1/qp5n/7p/P7/RPP5/3PPPPP/1BQKBNNR w Hha - 2 9 +epd rb1kbn1r/p1ppppp1/qp5n/7p/P7/RPP5/3PPPPP/1BQKBNNR w Hha - perft 1 29 perft 2 837 perft 3 23815 @@ -6266,7 +6266,7 @@ perft 5 21279560 perft 6 682863811 id 696 -epd rqkbb1nr/p1p2ppp/1p1p2n1/3Np3/4P3/5N2/PPPP1PPP/RQKBB2R w HAha - 0 9 +epd rqkbb1nr/p1p2ppp/1p1p2n1/3Np3/4P3/5N2/PPPP1PPP/RQKBB2R w HAha - perft 1 28 perft 2 717 perft 3 20663 @@ -6275,7 +6275,7 @@ perft 5 16347343 perft 6 453153783 id 697 -epd rqknbbr1/p1pppp1p/1p3np1/8/4P3/2P2P1P/PP1P2P1/RQKNBBNR w HAa - 0 9 +epd rqknbbr1/p1pppp1p/1p3np1/8/4P3/2P2P1P/PP1P2P1/RQKNBBNR w HAa - perft 1 27 perft 2 650 perft 3 18231 @@ -6284,7 +6284,7 @@ perft 5 13847463 perft 6 383256006 id 698 -epd r1k1bnrb/1qpppppp/1p2n3/p7/1P5P/6P1/P1PPPP2/RQKNBNR1 w GAga - 1 9 +epd r1k1bnrb/1qpppppp/1p2n3/p7/1P5P/6P1/P1PPPP2/RQKNBNR1 w GAga - perft 1 24 perft 2 806 perft 3 20693 @@ -6293,7 +6293,7 @@ perft 5 19382263 perft 6 686009788 id 699 -epd rb1knnbr/1pp1ppp1/p2p3p/5q2/3B2P1/3P1P2/PPP1P2P/RBQKNN1R w HAha - 0 9 +epd rb1knnbr/1pp1ppp1/p2p3p/5q2/3B2P1/3P1P2/PPP1P2P/RBQKNN1R w HAha - perft 1 34 perft 2 1360 perft 3 44096 @@ -6302,7 +6302,7 @@ perft 5 51973672 perft 6 1837704407 id 700 -epd rqkb1nbr/p1p1ppp1/1p3n1p/2Qp4/8/2P5/PP1PPPPP/R1KBNNBR w HAha - 2 9 +epd rqkb1nbr/p1p1ppp1/1p3n1p/2Qp4/8/2P5/PP1PPPPP/R1KBNNBR w HAha - perft 1 39 perft 2 983 perft 3 38218 @@ -6311,7 +6311,7 @@ perft 5 36347815 perft 6 918801645 id 701 -epd rqknnbbr/2pppp2/pp5p/6p1/1P1P4/4PP2/P1P3PP/RQKNNBBR w HAha - 0 9 +epd rqknnbbr/2pppp2/pp5p/6p1/1P1P4/4PP2/P1P3PP/RQKNNBBR w HAha - perft 1 26 perft 2 628 perft 3 17638 @@ -6320,7 +6320,7 @@ perft 5 13787303 perft 6 386125234 id 702 -epd rqkn1rbb/1pp1pppp/p7/3p4/3Pn3/2P1PP2/PP4PP/RQKNNRBB w FAfa - 1 9 +epd rqkn1rbb/1pp1pppp/p7/3p4/3Pn3/2P1PP2/PP4PP/RQKNNRBB w FAfa - perft 1 20 perft 2 527 perft 3 12216 @@ -6329,7 +6329,7 @@ perft 5 8082183 perft 6 219311659 id 703 -epd bbrkqn1r/1pppppp1/5n2/p7/1PP2P1p/7N/P2PP1PP/BBRKQN1R w HChc - 1 9 +epd bbrkqn1r/1pppppp1/5n2/p7/1PP2P1p/7N/P2PP1PP/BBRKQN1R w HChc - perft 1 36 perft 2 963 perft 3 35291 @@ -6338,7 +6338,7 @@ perft 5 35907489 perft 6 1034223364 id 704 -epd brkbqn1r/p2ppppp/7n/1p6/P1p3PP/8/1PPPPP1N/BRKBQ1NR w HBhb - 0 9 +epd brkbqn1r/p2ppppp/7n/1p6/P1p3PP/8/1PPPPP1N/BRKBQ1NR w HBhb - perft 1 18 perft 2 583 perft 3 11790 @@ -6347,7 +6347,7 @@ perft 5 8858385 perft 6 304339862 id 705 -epd brkq1bnr/pp1ppp1p/8/2p2np1/P7/8/1PPPPPPP/BRKQNBNR w HBhb - 0 9 +epd brkq1bnr/pp1ppp1p/8/2p2np1/P7/8/1PPPPPPP/BRKQNBNR w HBhb - perft 1 19 perft 2 552 perft 3 11811 @@ -6356,7 +6356,7 @@ perft 5 8432183 perft 6 262293169 id 706 -epd brkqnnrb/1ppppppp/8/8/p3P3/5N2/PPPP1PPP/BRKQ1NRB w GBgb - 3 9 +epd brkqnnrb/1ppppppp/8/8/p3P3/5N2/PPPP1PPP/BRKQ1NRB w GBgb - perft 1 21 perft 2 397 perft 3 9653 @@ -6365,7 +6365,7 @@ perft 5 5489836 perft 6 128389738 id 707 -epd rbbkq1nr/1p2pppp/p1p3nB/3p4/1Q1P4/6N1/PPP1PPPP/RB1K2NR w HAha - 0 9 +epd rbbkq1nr/1p2pppp/p1p3nB/3p4/1Q1P4/6N1/PPP1PPPP/RB1K2NR w HAha - perft 1 40 perft 2 1132 perft 3 43404 @@ -6374,7 +6374,7 @@ perft 5 47425783 perft 6 1415578783 id 708 -epd rkbbq1nr/1pppp1p1/4np2/p6p/8/PP3P2/1KPPP1PP/R1BBQNNR w ha - 0 9 +epd rkbbq1nr/1pppp1p1/4np2/p6p/8/PP3P2/1KPPP1PP/R1BBQNNR w ha - perft 1 24 perft 2 596 perft 3 15220 @@ -6383,7 +6383,7 @@ perft 5 10822049 perft 6 302056813 id 709 -epd r1bqn1nr/pkpppp1p/1p4pb/8/PN6/R7/1PPPPPPP/1KBQ1BNR w H - 2 9 +epd r1bqn1nr/pkpppp1p/1p4pb/8/PN6/R7/1PPPPPPP/1KBQ1BNR w H - perft 1 33 perft 2 794 perft 3 25450 @@ -6392,7 +6392,7 @@ perft 5 20919309 perft 6 561073410 id 710 -epd rkb1nnrb/1pppq1pp/p4p2/4p3/5P2/1P1PB3/P1P1P1PP/RK1QNNRB w GAga - 0 9 +epd rkb1nnrb/1pppq1pp/p4p2/4p3/5P2/1P1PB3/P1P1P1PP/RK1QNNRB w GAga - perft 1 26 perft 2 625 perft 3 17050 @@ -6401,7 +6401,7 @@ perft 5 12515042 perft 6 342967558 id 711 -epd rbkqbn1r/pppp1p1p/2n1p1p1/8/8/1P1PP1N1/P1P2PPP/RBKQB1NR w HAha - 1 9 +epd rbkqbn1r/pppp1p1p/2n1p1p1/8/8/1P1PP1N1/P1P2PPP/RBKQB1NR w HAha - perft 1 30 perft 2 660 perft 3 20308 @@ -6410,7 +6410,7 @@ perft 5 15348335 perft 6 403323883 id 712 -epd rkqbb1n1/pppppppr/8/6np/5P2/8/PPPPP1PP/RKQBBNNR w HAa - 6 9 +epd rkqbb1n1/pppppppr/8/6np/5P2/8/PPPPP1PP/RKQBBNNR w HAa - perft 1 23 perft 2 500 perft 3 12154 @@ -6419,7 +6419,7 @@ perft 5 7519117 perft 6 196524441 id 713 -epd rkqnbbnr/ppppppp1/8/7p/3N4/6PP/PPPPPP2/RKQNBB1R w HAa - 0 9 +epd rkqnbbnr/ppppppp1/8/7p/3N4/6PP/PPPPPP2/RKQNBB1R w HAa - perft 1 24 perft 2 484 perft 3 12495 @@ -6428,7 +6428,7 @@ perft 5 7775173 perft 6 193947530 id 714 -epd rkqnb1rb/p1p1pppp/1p1p4/2n5/3P4/2P1N1N1/PP2PPPP/RKQ1B1RB w GAga - 0 9 +epd rkqnb1rb/p1p1pppp/1p1p4/2n5/3P4/2P1N1N1/PP2PPPP/RKQ1B1RB w GAga - perft 1 28 perft 2 1020 perft 3 29124 @@ -6437,7 +6437,7 @@ perft 5 30515456 perft 6 1073711823 id 715 -epd rbk1nnbr/1ppq1ppp/p2p4/4p3/P3B2P/2P5/1P1PPPP1/R1KQNNBR w HAha - 2 9 +epd rbk1nnbr/1ppq1ppp/p2p4/4p3/P3B2P/2P5/1P1PPPP1/R1KQNNBR w HAha - perft 1 38 perft 2 998 perft 3 37265 @@ -6446,7 +6446,7 @@ perft 5 38552638 perft 6 1139322479 id 716 -epd r1qbn1br/k1pppppp/6n1/pp6/5P1P/P7/1PPPP1PB/RKQBNN1R w HA - 1 9 +epd r1qbn1br/k1pppppp/6n1/pp6/5P1P/P7/1PPPP1PB/RKQBNN1R w HA - perft 1 22 perft 2 549 perft 3 12867 @@ -6455,7 +6455,7 @@ perft 5 8725809 perft 6 251613569 id 717 -epd rkqnn1br/pppp3p/4p1pb/5p2/P2P4/7P/1PP1PPPB/RKQNNB1R w HAha - 1 9 +epd rkqnn1br/pppp3p/4p1pb/5p2/P2P4/7P/1PP1PPPB/RKQNNB1R w HAha - perft 1 32 perft 2 659 perft 3 21249 @@ -6464,7 +6464,7 @@ perft 5 15434721 perft 6 365761521 id 718 -epd rk1nnrbb/p1p1pppp/1p6/3p1q2/P3P3/2NN4/1PPP1PPP/RKQ2RBB w FAfa - 3 9 +epd rk1nnrbb/p1p1pppp/1p6/3p1q2/P3P3/2NN4/1PPP1PPP/RKQ2RBB w FAfa - perft 1 29 perft 2 989 perft 3 29087 @@ -6473,7 +6473,7 @@ perft 5 29643404 perft 6 998848556 id 719 -epd bbrk1q1r/ppppppp1/3n4/7p/3Pn3/6PN/PPP1PPNP/BBRK1Q1R w HChc - 2 9 +epd bbrk1q1r/ppppppp1/3n4/7p/3Pn3/6PN/PPP1PPNP/BBRK1Q1R w HChc - perft 1 23 perft 2 712 perft 3 16551 @@ -6482,7 +6482,7 @@ perft 5 12995202 perft 6 411077508 id 720 -epd brkbnq1r/p1ppp2p/5ppn/1p6/5P2/1P1P2P1/P1P1P2P/BRKBNQNR w HBhb - 0 9 +epd brkbnq1r/p1ppp2p/5ppn/1p6/5P2/1P1P2P1/P1P1P2P/BRKBNQNR w HBhb - perft 1 28 perft 2 856 perft 3 24984 @@ -6491,7 +6491,7 @@ perft 5 23529352 perft 6 754501112 id 721 -epd br1k1bnr/ppppp1pp/4np2/1B2P2q/3P4/8/PPP2PPP/BRKNQ1NR w HB - 3 9 +epd br1k1bnr/ppppp1pp/4np2/1B2P2q/3P4/8/PPP2PPP/BRKNQ1NR w HB - perft 1 36 perft 2 1214 perft 3 40615 @@ -6500,7 +6500,7 @@ perft 5 45096834 perft 6 1470987023 id 722 -epd brk1qnrb/pnppp1p1/1p6/5p1p/8/5PPP/PPPPP1R1/BRKNQN1B w Bgb - 0 9 +epd brk1qnrb/pnppp1p1/1p6/5p1p/8/5PPP/PPPPP1R1/BRKNQN1B w Bgb - perft 1 22 perft 2 551 perft 3 13111 @@ -6509,7 +6509,7 @@ perft 5 9040545 perft 6 259643605 id 723 -epd rbbkn1nr/1ppp2pp/p3p3/2q2p2/3P4/6P1/PPPBPP1P/RB1KNQNR w HAha - 0 9 +epd rbbkn1nr/1ppp2pp/p3p3/2q2p2/3P4/6P1/PPPBPP1P/RB1KNQNR w HAha - perft 1 31 perft 2 1060 perft 3 31332 @@ -6518,7 +6518,7 @@ perft 5 30314172 perft 6 976268967 id 724 -epd rkbbn1nr/ppppp1pp/8/6N1/5p2/1q6/P1PPPPPP/RKBBN1QR w HAha - 0 9 +epd rkbbn1nr/ppppp1pp/8/6N1/5p2/1q6/P1PPPPPP/RKBBN1QR w HAha - perft 1 3 perft 2 72 perft 3 1919 @@ -6527,7 +6527,7 @@ perft 5 1400832 perft 6 39654253 id 725 -epd rkb2bnr/pp2pppp/2p1n3/3p4/q2P4/5NP1/PPP1PP1P/RKBNQBR1 w Aha - 0 9 +epd rkb2bnr/pp2pppp/2p1n3/3p4/q2P4/5NP1/PPP1PP1P/RKBNQBR1 w Aha - perft 1 29 perft 2 861 perft 3 24504 @@ -6536,7 +6536,7 @@ perft 5 22763215 perft 6 731511256 id 726 -epd rkbq1nrb/ppppppp1/7p/8/1P1n4/P4P1P/2PPP1P1/RKBNQNRB w GAga - 0 9 +epd rkbq1nrb/ppppppp1/7p/8/1P1n4/P4P1P/2PPP1P1/RKBNQNRB w GAga - perft 1 25 perft 2 672 perft 3 17631 @@ -6545,7 +6545,7 @@ perft 5 12954224 perft 6 361237536 id 727 -epd rbknb1nr/ppp1qp1p/6p1/3pp3/3P3P/2B1P3/PPP2PP1/RBKN1QNR w HAha - 1 9 +epd rbknb1nr/ppp1qp1p/6p1/3pp3/3P3P/2B1P3/PPP2PP1/RBKN1QNR w HAha - perft 1 27 perft 2 857 perft 3 24688 @@ -6554,7 +6554,7 @@ perft 5 23790033 perft 6 768247869 id 728 -epd rknbbq1r/p1pppppp/1p2N3/8/3n4/2P5/PP1PPPPP/RK1BBQNR w HAha - 4 9 +epd rknbbq1r/p1pppppp/1p2N3/8/3n4/2P5/PP1PPPPP/RK1BBQNR w HAha - perft 1 29 perft 2 763 perft 3 22138 @@ -6563,7 +6563,7 @@ perft 5 16926075 perft 6 447896703 id 729 -epd r1nqbbnr/1pppp1pp/1k6/p4p2/8/4P3/PPPP1PPP/RKN1BBNR w HA - 0 9 +epd r1nqbbnr/1pppp1pp/1k6/p4p2/8/4P3/PPPP1PPP/RKN1BBNR w HA - perft 1 26 perft 2 658 perft 3 17302 @@ -6572,7 +6572,7 @@ perft 5 12380488 perft 6 349047256 id 730 -epd rkn2qrb/ppp1pppp/6n1/1b1p4/1P6/4PPB1/P1PP2PP/RKNQ1NRB w GAga - 3 9 +epd rkn2qrb/ppp1pppp/6n1/1b1p4/1P6/4PPB1/P1PP2PP/RKNQ1NRB w GAga - perft 1 23 perft 2 574 perft 3 14070 @@ -6581,7 +6581,7 @@ perft 5 9501401 perft 6 263870337 id 731 -epd rbkn2br/ppppp1p1/4np1p/1P5q/8/2P1N3/P2PPPPP/RBK1QNBR w HAha - 1 9 +epd rbkn2br/ppppp1p1/4np1p/1P5q/8/2P1N3/P2PPPPP/RBK1QNBR w HAha - perft 1 29 perft 2 992 perft 3 29506 @@ -6590,7 +6590,7 @@ perft 5 30148787 perft 6 1045942540 id 732 -epd 1knbqnbr/1ppppp1p/r5p1/p7/7P/2PN2P1/PP1PPP2/RK1BQNBR w HAh - 2 9 +epd 1knbqnbr/1ppppp1p/r5p1/p7/7P/2PN2P1/PP1PPP2/RK1BQNBR w HAh - perft 1 26 perft 2 698 perft 3 19395 @@ -6599,7 +6599,7 @@ perft 5 14848229 perft 6 402599313 id 733 -epd rk1qnbbr/pnpppp1p/6p1/1p6/3P4/1P6/P1P1PPPP/RKNQNBBR w HAha - 1 9 +epd rk1qnbbr/pnpppp1p/6p1/1p6/3P4/1P6/P1P1PPPP/RKNQNBBR w HAha - perft 1 20 perft 2 480 perft 3 11159 @@ -6608,7 +6608,7 @@ perft 5 7425917 perft 6 203194521 id 734 -epd rknqnrbb/pp1p2p1/5p1p/2p1p3/2P1P3/P2P4/1P3PPP/RKNQNRBB w FAfa - 0 9 +epd rknqnrbb/pp1p2p1/5p1p/2p1p3/2P1P3/P2P4/1P3PPP/RKNQNRBB w FAfa - perft 1 26 perft 2 679 perft 3 18116 @@ -6617,7 +6617,7 @@ perft 5 13790137 perft 6 392629571 id 735 -epd bbrk2qr/pp1p1ppp/3n2n1/2p1p3/3P1P2/6N1/PPP1P1PP/BBRKN1QR w HChc - 0 9 +epd bbrk2qr/pp1p1ppp/3n2n1/2p1p3/3P1P2/6N1/PPP1P1PP/BBRKN1QR w HChc - perft 1 26 perft 2 790 perft 3 21521 @@ -6626,7 +6626,7 @@ perft 5 19259490 perft 6 617563700 id 736 -epd b1krnnqr/1p1ppppp/p1p5/b6B/P7/4P1N1/1PPP1PPP/BRK1N1QR w HB - 2 9 +epd b1krnnqr/1p1ppppp/p1p5/b6B/P7/4P1N1/1PPP1PPP/BRK1N1QR w HB - perft 1 26 perft 2 625 perft 3 16451 @@ -6635,7 +6635,7 @@ perft 5 11490615 perft 6 304805107 id 737 -epd 1rknnbqr/3ppppp/p7/1pp5/4b2P/P4P2/1PPPP1PR/BRKNNBQ1 w Bhb - 1 9 +epd 1rknnbqr/3ppppp/p7/1pp5/4b2P/P4P2/1PPPP1PR/BRKNNBQ1 w Bhb - perft 1 24 perft 2 757 perft 3 19746 @@ -6644,7 +6644,7 @@ perft 5 17275100 perft 6 544309489 id 738 -epd br1nn1rb/pppkpqpp/3p1p2/8/PP6/4N3/1KPPPPPP/BR2NQRB w - - 3 9 +epd br1nn1rb/pppkpqpp/3p1p2/8/PP6/4N3/1KPPPPPP/BR2NQRB w - - perft 1 24 perft 2 682 perft 3 17129 @@ -6653,7 +6653,7 @@ perft 5 13057308 perft 6 375033550 id 739 -epd rbbkn1qr/pppp2p1/6np/4pp2/7N/7P/PPPPPPPR/RBBK1NQ1 w Aha - 0 9 +epd rbbkn1qr/pppp2p1/6np/4pp2/7N/7P/PPPPPPPR/RBBK1NQ1 w Aha - perft 1 22 perft 2 586 perft 3 14158 @@ -6662,7 +6662,7 @@ perft 5 10607781 perft 6 324452612 id 740 -epd rk1bn1qr/pppbpppp/4n3/4p3/4P3/5P2/PPPP2PP/RKBB1NQR w HAha - 1 9 +epd rk1bn1qr/pppbpppp/4n3/4p3/4P3/5P2/PPPP2PP/RKBB1NQR w HAha - perft 1 22 perft 2 530 perft 3 13440 @@ -6671,7 +6671,7 @@ perft 5 9514787 perft 6 259898748 id 741 -epd rkbnnbqr/1ppp1ppp/p7/4p3/8/QP3P2/P1PPP1PP/RKBNNB1R w HAha - 0 9 +epd rkbnnbqr/1ppp1ppp/p7/4p3/8/QP3P2/P1PPP1PP/RKBNNB1R w HAha - perft 1 29 perft 2 705 perft 3 21511 @@ -6680,7 +6680,7 @@ perft 5 17524731 perft 6 472356665 id 742 -epd 1kbnnqrb/1pp1p1pp/r4p2/p2p4/N4P2/3P4/PPP1P1PP/RKB1NQRB w GAg - 2 9 +epd 1kbnnqrb/1pp1p1pp/r4p2/p2p4/N4P2/3P4/PPP1P1PP/RKB1NQRB w GAg - perft 1 21 perft 2 623 perft 3 14979 @@ -6689,7 +6689,7 @@ perft 5 11601134 perft 6 343214006 id 743 -epd rbknbn1r/pppp1p1p/4p1q1/8/P1P3Pp/8/1P1PPP2/RBKNBNQR w HAha - 0 9 +epd rbknbn1r/pppp1p1p/4p1q1/8/P1P3Pp/8/1P1PPP2/RBKNBNQR w HAha - perft 1 30 perft 2 813 perft 3 24959 @@ -6698,7 +6698,7 @@ perft 5 23379040 perft 6 692576573 id 744 -epd rk1bb1qr/2pppppp/p2nn3/1p4P1/6QP/8/PPPPPP2/RKNBBN1R w HAha - 2 9 +epd rk1bb1qr/2pppppp/p2nn3/1p4P1/6QP/8/PPPPPP2/RKNBBN1R w HAha - perft 1 36 perft 2 857 perft 3 30124 @@ -6707,7 +6707,7 @@ perft 5 26485812 perft 6 696999449 id 745 -epd rkn1bbqr/p2ppppp/2p1n3/1p6/4PP2/6PP/PPPP4/RKNNBBQR w HAha - 0 9 +epd rkn1bbqr/p2ppppp/2p1n3/1p6/4PP2/6PP/PPPP4/RKNNBBQR w HAha - perft 1 33 perft 2 687 perft 3 22744 @@ -6716,7 +6716,7 @@ perft 5 17101732 perft 6 412778368 id 746 -epd rkn1bqrb/pnp1pppp/3p4/8/Pp6/1N2NP2/1PPPP1PP/RK2BQRB w GAga - 0 9 +epd rkn1bqrb/pnp1pppp/3p4/8/Pp6/1N2NP2/1PPPP1PP/RK2BQRB w GAga - perft 1 28 perft 2 591 perft 3 17174 @@ -6725,7 +6725,7 @@ perft 5 12182448 perft 6 312575205 id 747 -epd rbk1n1br/ppp1ppqp/2n5/2Np2p1/8/2P5/PPBPPPPP/R1KN1QBR w HAha - 4 9 +epd rbk1n1br/ppp1ppqp/2n5/2Np2p1/8/2P5/PPBPPPPP/R1KN1QBR w HAha - perft 1 35 perft 2 930 perft 3 30663 @@ -6734,7 +6734,7 @@ perft 5 27160490 perft 6 780616047 id 748 -epd rknbn1br/1ppp1ppp/p3p3/8/1q6/2P2N1P/P2PPPP1/RKNB1QBR w HAha - 0 9 +epd rknbn1br/1ppp1ppp/p3p3/8/1q6/2P2N1P/P2PPPP1/RKNB1QBR w HAha - perft 1 4 perft 2 157 perft 3 3697 @@ -6743,7 +6743,7 @@ perft 5 3454704 perft 6 125373395 id 749 -epd rkn1qbbr/pp3ppp/4n3/2ppp3/4P1P1/P2P4/1PP2P1P/RKNNQBBR w HAha - 0 9 +epd rkn1qbbr/pp3ppp/4n3/2ppp3/4P1P1/P2P4/1PP2P1P/RKNNQBBR w HAha - perft 1 28 perft 2 840 perft 3 24437 @@ -6752,7 +6752,7 @@ perft 5 23200961 perft 6 756489357 id 750 -epd rkn1qrbb/pp1ppp2/2p1n1p1/7p/2P2P1P/6P1/PP1PP3/RKNNQRBB w FAfa - 1 9 +epd rkn1qrbb/pp1ppp2/2p1n1p1/7p/2P2P1P/6P1/PP1PP3/RKNNQRBB w FAfa - perft 1 32 perft 2 867 perft 3 27595 @@ -6761,7 +6761,7 @@ perft 5 24485663 perft 6 688115847 id 751 -epd b1rknnrq/bpppp1p1/p6p/5p1P/6P1/4N3/PPPPPP2/BBRKN1RQ w GCgc - 1 9 +epd b1rknnrq/bpppp1p1/p6p/5p1P/6P1/4N3/PPPPPP2/BBRKN1RQ w GCgc - perft 1 33 perft 2 851 perft 3 28888 @@ -6770,7 +6770,7 @@ perft 5 26686205 perft 6 731944177 id 752 -epd brkb1nr1/pppppp2/3n2pp/3B4/1P6/4P3/PqPP1PPP/BRK1NNRQ w GBgb - 2 9 +epd brkb1nr1/pppppp2/3n2pp/3B4/1P6/4P3/PqPP1PPP/BRK1NNRQ w GBgb - perft 1 4 perft 2 98 perft 3 2965 @@ -6779,7 +6779,7 @@ perft 5 2352530 perft 6 64251468 id 753 -epd brk1nbrq/1ppppn1p/6p1/p4p2/P5P1/5R2/1PPPPP1P/BRKNNB1Q w Bgb - 0 9 +epd brk1nbrq/1ppppn1p/6p1/p4p2/P5P1/5R2/1PPPPP1P/BRKNNB1Q w Bgb - perft 1 29 perft 2 922 perft 3 27709 @@ -6788,7 +6788,7 @@ perft 5 27463717 perft 6 888881062 id 754 -epd brkn1rqb/1p1ppppp/3n4/p1p5/1P3P2/8/PNPPP1PP/BR1KNRQB w fb - 1 9 +epd brkn1rqb/1p1ppppp/3n4/p1p5/1P3P2/8/PNPPP1PP/BR1KNRQB w fb - perft 1 29 perft 2 633 perft 3 19399 @@ -6797,7 +6797,7 @@ perft 5 15076198 perft 6 396737074 id 755 -epd rb1k1nrq/pbp1pppp/1p1p1n2/8/5P2/4NN1P/PPPPP1P1/RBBK2RQ w GAga - 2 9 +epd rb1k1nrq/pbp1pppp/1p1p1n2/8/5P2/4NN1P/PPPPP1P1/RBBK2RQ w GAga - perft 1 28 perft 2 841 perft 3 24056 @@ -6806,7 +6806,7 @@ perft 5 20772996 perft 6 613798447 id 756 -epd rkbbnnrq/p1pp3p/4p1p1/1p3p2/P6P/1P6/1BPPPPP1/RK1BNNRQ w GAga - 0 9 +epd rkbbnnrq/p1pp3p/4p1p1/1p3p2/P6P/1P6/1BPPPPP1/RK1BNNRQ w GAga - perft 1 33 perft 2 957 perft 3 30668 @@ -6815,7 +6815,7 @@ perft 5 29735654 perft 6 903933626 id 757 -epd rk2nbrq/p1ppppp1/bpn5/7p/6P1/2N2P2/PPPPP1QP/RKB1NBR1 w GAga - 2 9 +epd rk2nbrq/p1ppppp1/bpn5/7p/6P1/2N2P2/PPPPP1QP/RKB1NBR1 w GAga - perft 1 24 perft 2 687 perft 3 18206 @@ -6824,7 +6824,7 @@ perft 5 15518417 perft 6 484217179 id 758 -epd rkbn1r1b/pp1pppnp/6q1/2p3p1/5P1P/4N3/PPPPP1P1/RKB1NRQB w FAfa - 1 9 +epd rkbn1r1b/pp1pppnp/6q1/2p3p1/5P1P/4N3/PPPPP1P1/RKB1NRQB w FAfa - perft 1 23 perft 2 831 perft 3 21254 @@ -6833,7 +6833,7 @@ perft 5 21126103 perft 6 744755212 id 759 -epd rbknb1rq/ppp1p1p1/3pnp1p/8/6PP/2PP4/PP2PP2/RBKNBNRQ w GAga - 0 9 +epd rbknb1rq/ppp1p1p1/3pnp1p/8/6PP/2PP4/PP2PP2/RBKNBNRQ w GAga - perft 1 31 perft 2 838 perft 3 26800 @@ -6842,7 +6842,7 @@ perft 5 24008129 perft 6 677776408 id 760 -epd rknbb1rq/p1pn1ppp/4p3/1p1p4/2P5/1P2N1P1/P2PPP1P/RKNBB1RQ w GAga - 1 9 +epd rknbb1rq/p1pn1ppp/4p3/1p1p4/2P5/1P2N1P1/P2PPP1P/RKNBB1RQ w GAga - perft 1 29 perft 2 830 perft 3 24798 @@ -6851,7 +6851,7 @@ perft 5 22243832 perft 6 660040360 id 761 -epd rk1nbbrq/pp1p1ppp/3n4/P3p3/2p4P/8/1PPPPPP1/RKNNBBRQ w GAga - 1 9 +epd rk1nbbrq/pp1p1ppp/3n4/P3p3/2p4P/8/1PPPPPP1/RKNNBBRQ w GAga - perft 1 24 perft 2 484 perft 3 12776 @@ -6860,7 +6860,7 @@ perft 5 8379748 perft 6 214004367 id 762 -epd rknnbr1b/ppp2pqp/3p4/4p1p1/7P/3P1P2/PPP1P1P1/RKNNBRQB w FAfa - 0 9 +epd rknnbr1b/ppp2pqp/3p4/4p1p1/7P/3P1P2/PPP1P1P1/RKNNBRQB w FAfa - perft 1 32 perft 2 838 perft 3 26408 @@ -6869,7 +6869,7 @@ perft 5 23472124 perft 6 699211365 id 763 -epd rb1k1rbq/ppppN1pp/2nn4/5p2/7P/8/PPPPPPP1/RBK1NRBQ w FA - 1 9 +epd rb1k1rbq/ppppN1pp/2nn4/5p2/7P/8/PPPPPPP1/RBK1NRBQ w FA - perft 1 27 perft 2 800 perft 3 22785 @@ -6878,7 +6878,7 @@ perft 5 20804424 perft 6 660917073 id 764 -epd r1nbnrbq/kppppp1p/6p1/8/p1PP1P2/4P3/PP4PP/RKNBNRBQ w FA - 1 9 +epd r1nbnrbq/kppppp1p/6p1/8/p1PP1P2/4P3/PP4PP/RKNBNRBQ w FA - perft 1 28 perft 2 757 perft 3 21198 @@ -6887,7 +6887,7 @@ perft 5 17180857 perft 6 507618340 id 765 -epd rkn1rbbq/p1pppppp/2n5/1pP5/8/1N2P3/PP1P1PPP/RK1NRBBQ w EAea - 1 9 +epd rkn1rbbq/p1pppppp/2n5/1pP5/8/1N2P3/PP1P1PPP/RK1NRBBQ w EAea - perft 1 22 perft 2 483 perft 3 11890 @@ -6896,7 +6896,7 @@ perft 5 7497674 perft 6 191130942 id 766 -epd rknnrqbb/2pppppp/8/p7/Np3P2/3P4/PPP1P1PP/RKN1RQBB w EAea - 0 9 +epd rknnrqbb/2pppppp/8/p7/Np3P2/3P4/PPP1P1PP/RKN1RQBB w EAea - perft 1 25 perft 2 536 perft 3 14456 @@ -6905,7 +6905,7 @@ perft 5 9694947 perft 6 245669668 id 767 -epd bb1rknrn/1qppppp1/1p4B1/p6N/8/2P5/PP1PPPPP/B1QRK1RN w GDgd - 1 9 +epd bb1rknrn/1qppppp1/1p4B1/p6N/8/2P5/PP1PPPPP/B1QRK1RN w GDgd - perft 1 32 perft 2 715 perft 3 22421 @@ -6914,7 +6914,7 @@ perft 5 17860156 perft 6 502410909 id 768 -epd b1rbknrn/qpp1ppp1/p6p/3p4/2P5/1P1P1P2/P3P1PP/BQRBKNRN w GCgc - 0 9 +epd b1rbknrn/qpp1ppp1/p6p/3p4/2P5/1P1P1P2/P3P1PP/BQRBKNRN w GCgc - perft 1 30 perft 2 818 perft 3 24421 @@ -6923,7 +6923,7 @@ perft 5 20981488 perft 6 611986786 id 769 -epd bqkrnbrn/1pp1pp1p/p7/1B1p2p1/4P3/7P/PPPP1PP1/BQKRN1RN w - - 0 9 +epd bqkrnbrn/1pp1pp1p/p7/1B1p2p1/4P3/7P/PPPP1PP1/BQKRN1RN w - - perft 1 28 perft 2 676 perft 3 18366 @@ -6932,7 +6932,7 @@ perft 5 13126287 perft 6 363765666 id 770 -epd bqrknrnb/1p2ppp1/p1pp3p/8/3P1P2/1PP5/P3P1PP/BQRKNRNB w FCfc - 0 9 +epd bqrknrnb/1p2ppp1/p1pp3p/8/3P1P2/1PP5/P3P1PP/BQRKNRNB w FCfc - perft 1 31 perft 2 646 perft 3 20686 @@ -6941,7 +6941,7 @@ perft 5 14984618 perft 6 349082278 id 771 -epd qbbrkn1r/pppppp1p/8/6p1/2P1Pn1P/6N1/PP1P1PP1/QBBRKNR1 w GDd - 3 9 +epd qbbrkn1r/pppppp1p/8/6p1/2P1Pn1P/6N1/PP1P1PP1/QBBRKNR1 w GDd - perft 1 20 perft 2 532 perft 3 11581 @@ -6950,7 +6950,7 @@ perft 5 7512432 perft 6 202967948 id 772 -epd 1rbbknr1/p1ppp1pp/1pq2pn1/8/3P4/P3P3/QPP2PPP/1RBBKNRN w GBgb - 3 9 +epd 1rbbknr1/p1ppp1pp/1pq2pn1/8/3P4/P3P3/QPP2PPP/1RBBKNRN w GBgb - perft 1 31 perft 2 1002 perft 3 30581 @@ -6959,7 +6959,7 @@ perft 5 30642468 perft 6 1009228283 id 773 -epd qrbkn1rn/pppp1ppp/8/6b1/P1P1Pp2/8/1P1P2PP/QRBKNBRN w GBgb - 0 9 +epd qrbkn1rn/pppp1ppp/8/6b1/P1P1Pp2/8/1P1P2PP/QRBKNBRN w GBgb - perft 1 22 perft 2 505 perft 3 12447 @@ -6968,7 +6968,7 @@ perft 5 8192621 perft 6 214730959 id 774 -epd qrbk1rnb/p2ppp1p/5n2/1pp3p1/8/7P/PPPPPPPN/QRBKR1NB w Bfb - 0 9 +epd qrbk1rnb/p2ppp1p/5n2/1pp3p1/8/7P/PPPPPPPN/QRBKR1NB w Bfb - perft 1 20 perft 2 619 perft 3 13448 @@ -6977,7 +6977,7 @@ perft 5 10571176 perft 6 369603424 id 775 -epd qbrkb1r1/ppp2ppp/3pn1n1/P3p3/4P3/3P4/1PP2PPP/QBRKBNRN w GCgc - 1 9 +epd qbrkb1r1/ppp2ppp/3pn1n1/P3p3/4P3/3P4/1PP2PPP/QBRKBNRN w GCgc - perft 1 26 perft 2 755 perft 3 20596 @@ -6986,7 +6986,7 @@ perft 5 17164382 perft 6 510878835 id 776 -epd qrkbb1r1/ppp1pnpp/3p2n1/5p2/1P3P2/2Q3N1/P1PPP1PP/1RKBB1RN w GBgb - 0 9 +epd qrkbb1r1/ppp1pnpp/3p2n1/5p2/1P3P2/2Q3N1/P1PPP1PP/1RKBB1RN w GBgb - perft 1 35 perft 2 918 perft 3 32244 @@ -6995,7 +6995,7 @@ perft 5 30933394 perft 6 867833733 id 777 -epd qrknbbrn/ppp1ppp1/8/7p/2Bp4/4PPP1/PPPP3P/QRKNB1RN w GBgb - 0 9 +epd qrknbbrn/ppp1ppp1/8/7p/2Bp4/4PPP1/PPPP3P/QRKNB1RN w GBgb - perft 1 27 perft 2 593 perft 3 16168 @@ -7004,7 +7004,7 @@ perft 5 10422676 perft 6 258348640 id 778 -epd qrk1brnb/ppppp3/4n2p/5pp1/2PP4/2N4P/PP2PPP1/QRK1BRNB w FBfb - 2 9 +epd qrk1brnb/ppppp3/4n2p/5pp1/2PP4/2N4P/PP2PPP1/QRK1BRNB w FBfb - perft 1 24 perft 2 672 perft 3 17447 @@ -7013,7 +7013,7 @@ perft 5 13765777 perft 6 414930519 id 779 -epd qbrknrb1/p2ppppp/2p3n1/8/p4P2/6PP/1PPPP3/QBRKNRBN w FCfc - 0 9 +epd qbrknrb1/p2ppppp/2p3n1/8/p4P2/6PP/1PPPP3/QBRKNRBN w FCfc - perft 1 29 perft 2 759 perft 3 23235 @@ -7022,7 +7022,7 @@ perft 5 20416668 perft 6 584870558 id 780 -epd 1rkb1rbn/p1pp1ppp/3np3/1p6/4qP2/3NB3/PPPPPRPP/QRKB3N w Bfb - 0 9 +epd 1rkb1rbn/p1pp1ppp/3np3/1p6/4qP2/3NB3/PPPPPRPP/QRKB3N w Bfb - perft 1 22 perft 2 923 perft 3 22585 @@ -7031,7 +7031,7 @@ perft 5 24049880 perft 6 957218571 id 781 -epd 1rknrbbn/p1pp1p1p/8/1p2p1p1/4qPP1/2P5/PP1PP1BP/QRKNR1BN w EBeb - 0 9 +epd 1rknrbbn/p1pp1p1p/8/1p2p1p1/4qPP1/2P5/PP1PP1BP/QRKNR1BN w EBeb - perft 1 28 perft 2 1309 perft 3 36355 @@ -7040,7 +7040,7 @@ perft 5 44576409 perft 6 1846382333 id 782 -epd qrk1rn1b/ppppp2p/4n3/3b1pp1/4P2P/5BP1/PPPP1P2/QRKNRNB1 w EBeb - 3 9 +epd qrk1rn1b/ppppp2p/4n3/3b1pp1/4P2P/5BP1/PPPP1P2/QRKNRNB1 w EBeb - perft 1 26 perft 2 839 perft 3 22189 @@ -7049,7 +7049,7 @@ perft 5 19978260 perft 6 661207281 id 783 -epd bbrqk1rn/pp1ppppp/8/2p5/2P1P3/5n1P/PPBP1PP1/B1RQKNRN w GCgc - 1 9 +epd bbrqk1rn/pp1ppppp/8/2p5/2P1P3/5n1P/PPBP1PP1/B1RQKNRN w GCgc - perft 1 3 perft 2 95 perft 3 2690 @@ -7058,7 +7058,7 @@ perft 5 2518864 perft 6 80775549 id 784 -epd brqbk2n/pppppprp/8/6p1/1P3n2/5P2/P1PPP1PP/R1QBKNRN w Gb - 2 9 +epd brqbk2n/pppppprp/8/6p1/1P3n2/5P2/P1PPP1PP/R1QBKNRN w Gb - perft 1 22 perft 2 593 perft 3 13255 @@ -7067,7 +7067,7 @@ perft 5 8922397 perft 6 253271592 id 785 -epd brqknbr1/pp3ppp/3p2n1/2p1p3/2P5/5P2/PPKPP1PP/BRQ1NBRN w gb - 0 9 +epd brqknbr1/pp3ppp/3p2n1/2p1p3/2P5/5P2/PPKPP1PP/BRQ1NBRN w gb - perft 1 21 perft 2 590 perft 3 13190 @@ -7076,7 +7076,7 @@ perft 5 9581695 perft 6 304103516 id 786 -epd 1rqknrnb/2pp1ppp/p3p3/1p6/P2P4/5bP1/1PP1PP1P/BRQKNRNB w FBfb - 0 9 +epd 1rqknrnb/2pp1ppp/p3p3/1p6/P2P4/5bP1/1PP1PP1P/BRQKNRNB w FBfb - perft 1 24 perft 2 737 perft 3 20052 @@ -7085,7 +7085,7 @@ perft 5 17948681 perft 6 536330341 id 787 -epd rbb1k1rn/p1pqpppp/6n1/1p1p4/5P2/3PP3/PPP1K1PP/RBBQ1NRN w ga - 3 9 +epd rbb1k1rn/p1pqpppp/6n1/1p1p4/5P2/3PP3/PPP1K1PP/RBBQ1NRN w ga - perft 1 24 perft 2 694 perft 3 16773 @@ -7094,7 +7094,7 @@ perft 5 13094823 perft 6 419402704 id 788 -epd rqbbknr1/1ppp2pp/p5n1/4pp2/P7/1PP5/1Q1PPPPP/R1BBKNRN w GAga - 0 9 +epd rqbbknr1/1ppp2pp/p5n1/4pp2/P7/1PP5/1Q1PPPPP/R1BBKNRN w GAga - perft 1 24 perft 2 600 perft 3 15347 @@ -7103,7 +7103,7 @@ perft 5 11029596 perft 6 308553169 id 789 -epd rqbknbrn/2pppppp/6Q1/pp6/8/2P5/PP1PPPPP/R1BKNBRN w GAga - 2 9 +epd rqbknbrn/2pppppp/6Q1/pp6/8/2P5/PP1PPPPP/R1BKNBRN w GAga - perft 1 40 perft 2 949 perft 3 34100 @@ -7112,7 +7112,7 @@ perft 5 31296485 perft 6 881529007 id 790 -epd rqbknr1b/pp1ppp2/2p2n1p/6p1/8/3P1PPP/PPP1P3/RQBKNRNB w FAfa - 0 9 +epd rqbknr1b/pp1ppp2/2p2n1p/6p1/8/3P1PPP/PPP1P3/RQBKNRNB w FAfa - perft 1 20 perft 2 560 perft 3 12275 @@ -7121,7 +7121,7 @@ perft 5 8687544 perft 6 277906201 id 791 -epd rbqkbnrn/p3pppp/1p6/3p4/P1p3P1/1P6/1QPPPP1P/RB1KBNRN w GAga - 0 9 +epd rbqkbnrn/p3pppp/1p6/3p4/P1p3P1/1P6/1QPPPP1P/RB1KBNRN w GAga - perft 1 30 perft 2 1155 perft 3 35865 @@ -7130,7 +7130,7 @@ perft 5 43092716 perft 6 1614019629 id 792 -epd rqkbb1rn/p1p1pppn/1p1p4/7p/4PP2/7P/PPPPB1P1/RQK1BNRN w GAga - 1 9 +epd rqkbb1rn/p1p1pppn/1p1p4/7p/4PP2/7P/PPPPB1P1/RQK1BNRN w GAga - perft 1 30 perft 2 701 perft 3 20804 @@ -7139,7 +7139,7 @@ perft 5 15450970 perft 6 401499189 id 793 -epd rqknbbrn/1p2pp1p/3p2p1/p1p5/P2P4/1P6/1KP1PPPP/RQ1NBBRN w ga - 0 9 +epd rqknbbrn/1p2pp1p/3p2p1/p1p5/P2P4/1P6/1KP1PPPP/RQ1NBBRN w ga - perft 1 28 perft 2 756 perft 3 21655 @@ -7148,7 +7148,7 @@ perft 5 17989811 perft 6 525585996 id 794 -epd rqknbrnb/1pp3pp/5p2/p2pp3/P7/3PPN2/1PP2PPP/RQKNBR1B w FAfa - 0 9 +epd rqknbrnb/1pp3pp/5p2/p2pp3/P7/3PPN2/1PP2PPP/RQKNBR1B w FAfa - perft 1 26 perft 2 731 perft 3 19509 @@ -7157,7 +7157,7 @@ perft 5 15209404 perft 6 439767476 id 795 -epd rbqkr1bn/p1pppp1p/1p1n4/6p1/7P/3P1PP1/PPP1P3/RBQKNRBN w FAa - 0 9 +epd rbqkr1bn/p1pppp1p/1p1n4/6p1/7P/3P1PP1/PPP1P3/RBQKNRBN w FAa - perft 1 27 perft 2 586 perft 3 16282 @@ -7166,7 +7166,7 @@ perft 5 10905865 perft 6 274364342 id 796 -epd rqk1nrb1/ppbp1ppp/4p1n1/2p5/7P/1PP5/P2PPPP1/RQKBNRBN w FAfa - 1 9 +epd rqk1nrb1/ppbp1ppp/4p1n1/2p5/7P/1PP5/P2PPPP1/RQKBNRBN w FAfa - perft 1 27 perft 2 749 perft 3 21480 @@ -7175,7 +7175,7 @@ perft 5 18084787 perft 6 520547029 id 797 -epd rqknrbbn/pp1p1ppp/4p3/2p5/3P2P1/7P/PPP1PP2/RQKNRBBN w EAa - 0 9 +epd rqknrbbn/pp1p1ppp/4p3/2p5/3P2P1/7P/PPP1PP2/RQKNRBBN w EAa - perft 1 20 perft 2 533 perft 3 11829 @@ -7184,7 +7184,7 @@ perft 5 8230417 perft 6 245871540 id 798 -epd rqknrnbb/pp1ppp1p/2p3p1/8/8/1P2P1NP/P1PP1PP1/RQKNR1BB w EAea - 0 9 +epd rqknrnbb/pp1ppp1p/2p3p1/8/8/1P2P1NP/P1PP1PP1/RQKNR1BB w EAea - perft 1 22 perft 2 633 perft 3 14480 @@ -7193,7 +7193,7 @@ perft 5 10827868 perft 6 343525739 id 799 -epd 1brkq1rn/2pppppp/1p2n3/p2bN3/8/7P/PPPPPPP1/BBRKQ1RN w GCgc - 2 9 +epd 1brkq1rn/2pppppp/1p2n3/p2bN3/8/7P/PPPPPPP1/BBRKQ1RN w GCgc - perft 1 27 perft 2 748 perft 3 20134 @@ -7202,7 +7202,7 @@ perft 5 16010135 perft 6 475206624 id 800 -epd brkbqnrn/2pp1ppp/8/1p2p3/Pp2N3/8/2PPPPPP/BRKBQNR1 w GBgb - 0 9 +epd brkbqnrn/2pp1ppp/8/1p2p3/Pp2N3/8/2PPPPPP/BRKBQNR1 w GBgb - perft 1 30 perft 2 827 perft 3 25308 @@ -7211,7 +7211,7 @@ perft 5 23746165 perft 6 751690068 id 801 -epd brk1nbrn/pp1ppppp/2p5/7P/5P2/q2P4/PPP1P1P1/BRKQNBRN w GBgb - 1 9 +epd brk1nbrn/pp1ppppp/2p5/7P/5P2/q2P4/PPP1P1P1/BRKQNBRN w GBgb - perft 1 15 perft 2 471 perft 3 8716 @@ -7220,7 +7220,7 @@ perft 5 5960901 perft 6 190316951 id 802 -epd brkqnrnb/1p1pp1p1/p4p2/2p4p/8/P2PP3/1PP1QPPP/BRK1NRNB w FBfb - 0 9 +epd brkqnrnb/1p1pp1p1/p4p2/2p4p/8/P2PP3/1PP1QPPP/BRK1NRNB w FBfb - perft 1 24 perft 2 479 perft 3 12584 @@ -7229,7 +7229,7 @@ perft 5 7830230 perft 6 190419716 id 803 -epd rbbkqnrn/2ppp2p/pp3p2/6p1/P6P/8/RPPPPPP1/1BBKQNRN w Gga - 0 9 +epd rbbkqnrn/2ppp2p/pp3p2/6p1/P6P/8/RPPPPPP1/1BBKQNRN w Gga - perft 1 21 perft 2 523 perft 3 12125 @@ -7238,7 +7238,7 @@ perft 5 8322614 perft 6 242240658 id 804 -epd rkbbqr1n/1ppppppn/7p/p7/4P3/2P2P2/PP1PB1PP/RKB1QNRN w GAa - 3 9 +epd rkbbqr1n/1ppppppn/7p/p7/4P3/2P2P2/PP1PB1PP/RKB1QNRN w GAa - perft 1 27 perft 2 563 perft 3 16026 @@ -7247,7 +7247,7 @@ perft 5 11105151 perft 6 283211800 id 805 -epd rkbqnbrn/ppppp3/8/5ppp/2P3P1/7P/PPQPPP2/RKB1NBRN w GAga - 0 9 +epd rkbqnbrn/ppppp3/8/5ppp/2P3P1/7P/PPQPPP2/RKB1NBRN w GAga - perft 1 28 perft 2 639 perft 3 19250 @@ -7256,7 +7256,7 @@ perft 5 14872172 perft 6 384663405 id 806 -epd rkb1nrnb/pppp1pp1/5q1p/8/P3p3/4R1P1/1PPPPP1P/1KBQNRNB w Ffa - 0 9 +epd rkb1nrnb/pppp1pp1/5q1p/8/P3p3/4R1P1/1PPPPP1P/1KBQNRNB w Ffa - perft 1 28 perft 2 873 perft 3 23690 @@ -7265,7 +7265,7 @@ perft 5 20209424 perft 6 625281937 id 807 -epd rbkqb1rn/1p1ppppp/4n3/p1p5/8/3PBP2/PPP1P1PP/RBKQ1NRN w GAga - 0 9 +epd rbkqb1rn/1p1ppppp/4n3/p1p5/8/3PBP2/PPP1P1PP/RBKQ1NRN w GAga - perft 1 26 perft 2 798 perft 3 21416 @@ -7274,7 +7274,7 @@ perft 5 18475618 perft 6 591681956 id 808 -epd rk1qbnrn/1p1ppppp/1b6/p1p5/P7/2P3NP/1P1PPPP1/RKQBB1RN w GAga - 0 9 +epd rk1qbnrn/1p1ppppp/1b6/p1p5/P7/2P3NP/1P1PPPP1/RKQBB1RN w GAga - perft 1 22 perft 2 506 perft 3 12313 @@ -7283,7 +7283,7 @@ perft 5 7891676 perft 6 205739580 id 809 -epd rk1nbbrn/ppp1ppp1/8/3p3p/1P1P2q1/5PB1/P1P1P1PP/RKQN1BRN w GAga - 1 9 +epd rk1nbbrn/ppp1ppp1/8/3p3p/1P1P2q1/5PB1/P1P1P1PP/RKQN1BRN w GAga - perft 1 31 perft 2 956 perft 3 29219 @@ -7292,7 +7292,7 @@ perft 5 27827461 perft 6 876341492 id 810 -epd rkqnbr1b/pp1pppp1/7p/2p2n2/P2P4/7N/RPP1PPPP/1KQNBR1B w Ffa - 0 9 +epd rkqnbr1b/pp1pppp1/7p/2p2n2/P2P4/7N/RPP1PPPP/1KQNBR1B w Ffa - perft 1 31 perft 2 750 perft 3 24267 @@ -7301,7 +7301,7 @@ perft 5 21639104 perft 6 617064197 id 811 -epd rbkq1rbn/2p1pppp/pp3n2/3p4/5P2/3N2N1/PPPPP1PP/RBKQR1B1 w Afa - 2 9 +epd rbkq1rbn/2p1pppp/pp3n2/3p4/5P2/3N2N1/PPPPP1PP/RBKQR1B1 w Afa - perft 1 26 perft 2 647 perft 3 18027 @@ -7310,7 +7310,7 @@ perft 5 13643783 perft 6 369702807 id 812 -epd rkqbr1bn/p2ppppp/1pp2n2/8/5P2/3P1N2/PPP1PRPP/RKQB2BN w Aa - 3 9 +epd rkqbr1bn/p2ppppp/1pp2n2/8/5P2/3P1N2/PPP1PRPP/RKQB2BN w Aa - perft 1 24 perft 2 574 perft 3 14593 @@ -7319,7 +7319,7 @@ perft 5 10066892 perft 6 271121237 id 813 -epd rk1qrbbn/p1ppp1pp/1p2n3/5p2/1P6/K3N3/P1PPPPPP/R1Q1RBBN w ea - 0 9 +epd rk1qrbbn/p1ppp1pp/1p2n3/5p2/1P6/K3N3/P1PPPPPP/R1Q1RBBN w ea - perft 1 25 perft 2 548 perft 3 14069 @@ -7328,7 +7328,7 @@ perft 5 9043111 perft 6 235545764 id 814 -epd rkqnrnbb/pp1pp3/2p5/5ppp/8/PP4NP/2PPPPP1/RKQNR1BB w EAea - 0 9 +epd rkqnrnbb/pp1pp3/2p5/5ppp/8/PP4NP/2PPPPP1/RKQNR1BB w EAea - perft 1 23 perft 2 727 perft 3 18228 @@ -7337,7 +7337,7 @@ perft 5 15078056 perft 6 471296844 id 815 -epd bbrknq1r/ppppppp1/8/7p/5n2/3P4/PPP1PNPP/BBKRNQR1 w c - 0 9 +epd bbrknq1r/ppppppp1/8/7p/5n2/3P4/PPP1PNPP/BBKRNQR1 w c - perft 1 21 perft 2 610 perft 3 13300 @@ -7346,7 +7346,7 @@ perft 5 9605845 perft 6 293532398 id 816 -epd brkbnqr1/2pppnpp/pp3p2/8/4PPPP/8/PPPP4/BRKBNQRN w GBgb - 1 9 +epd brkbnqr1/2pppnpp/pp3p2/8/4PPPP/8/PPPP4/BRKBNQRN w GBgb - perft 1 30 perft 2 757 perft 3 23908 @@ -7355,7 +7355,7 @@ perft 5 20360394 perft 6 548380577 id 817 -epd brk1qb1n/ppppppr1/2n3pp/8/2P3P1/2N5/PP1PPP1P/BR1KQBRN w b - 1 9 +epd brk1qb1n/ppppppr1/2n3pp/8/2P3P1/2N5/PP1PPP1P/BR1KQBRN w b - perft 1 26 perft 2 570 perft 3 15537 @@ -7364,7 +7364,7 @@ perft 5 10081351 perft 6 242864559 id 818 -epd brknq1nb/pp2prpp/8/2pP1p2/6P1/2N5/PPPP1P1P/BRK1QRNB w FBb - 1 9 +epd brknq1nb/pp2prpp/8/2pP1p2/6P1/2N5/PPPP1P1P/BRK1QRNB w FBb - perft 1 33 perft 2 830 perft 3 27897 @@ -7373,7 +7373,7 @@ perft 5 26262884 perft 6 765831403 id 819 -epd rbbk1qrn/ppp1p1pp/5p2/3p1n2/7N/P7/1PPPPPPP/RBB1KQRN w ga - 0 9 +epd rbbk1qrn/ppp1p1pp/5p2/3p1n2/7N/P7/1PPPPPPP/RBB1KQRN w ga - perft 1 21 perft 2 562 perft 3 13060 @@ -7382,7 +7382,7 @@ perft 5 9520963 perft 6 290579255 id 820 -epd rk1b1qrn/ppp1pppp/5n2/3pN3/P6P/7b/1PPPPPP1/RKBB1QRN w GAga - 4 9 +epd rk1b1qrn/ppp1pppp/5n2/3pN3/P6P/7b/1PPPPPP1/RKBB1QRN w GAga - perft 1 28 perft 2 677 perft 3 19235 @@ -7391,7 +7391,7 @@ perft 5 14354779 perft 6 383207197 id 821 -epd rkbnqbrn/pp1ppp1p/2p5/6p1/P7/4P3/KPPPQPPP/R1BN1BRN w - - 3 9 +epd rkbnqbrn/pp1ppp1p/2p5/6p1/P7/4P3/KPPPQPPP/R1BN1BRN w - - perft 1 28 perft 2 585 perft 3 17443 @@ -7400,7 +7400,7 @@ perft 5 12574541 perft 6 310495538 id 822 -epd rk1nqrnb/pbpppp2/1p4p1/7p/P7/5NP1/1PPPPPBP/RKBNQR2 w FAfa - 2 9 +epd rk1nqrnb/pbpppp2/1p4p1/7p/P7/5NP1/1PPPPPBP/RKBNQR2 w FAfa - perft 1 26 perft 2 774 perft 3 21626 @@ -7409,7 +7409,7 @@ perft 5 19093408 perft 6 576325868 id 823 -epd rbknb1rn/p1pp2pp/1p6/4pp2/1q3P1B/2N5/PPPPPNPP/RBK2QR1 w GAga - 2 9 +epd rbknb1rn/p1pp2pp/1p6/4pp2/1q3P1B/2N5/PPPPPNPP/RBK2QR1 w GAga - perft 1 31 perft 2 1206 perft 3 36940 @@ -7418,7 +7418,7 @@ perft 5 42849564 perft 6 1555711209 id 824 -epd rk1bbqrn/pp1pp1pp/3n4/5p2/3p4/1PP5/PK2PPPP/R1NBBQRN w ga - 0 9 +epd rk1bbqrn/pp1pp1pp/3n4/5p2/3p4/1PP5/PK2PPPP/R1NBBQRN w ga - perft 1 21 perft 2 629 perft 3 14059 @@ -7427,7 +7427,7 @@ perft 5 10587910 perft 6 332632033 id 825 -epd rknqbbr1/p1pp1pp1/1p4n1/4p2p/4P1P1/6RB/PPPP1P1P/RKNQB2N w Aga - 0 9 +epd rknqbbr1/p1pp1pp1/1p4n1/4p2p/4P1P1/6RB/PPPP1P1P/RKNQB2N w Aga - perft 1 27 perft 2 753 perft 3 20918 @@ -7436,7 +7436,7 @@ perft 5 17318772 perft 6 507563675 id 826 -epd rknqbr1b/pppp1ppp/4p2n/8/1P3P2/4P3/P1PPN1PP/RKNQBR1B w FAfa - 2 9 +epd rknqbr1b/pppp1ppp/4p2n/8/1P3P2/4P3/P1PPN1PP/RKNQBR1B w FAfa - perft 1 26 perft 2 623 perft 3 17177 @@ -7445,7 +7445,7 @@ perft 5 13389799 perft 6 383508368 id 827 -epd r2kqrbn/bppppppp/2n5/p4B2/5P2/2P5/PP1PP1PP/1RKNQRBN w F - 2 9 +epd r2kqrbn/bppppppp/2n5/p4B2/5P2/2P5/PP1PP1PP/1RKNQRBN w F - perft 1 39 perft 2 1026 perft 3 37800 @@ -7454,7 +7454,7 @@ perft 5 35946987 perft 6 992756232 id 828 -epd rk1bqrb1/ppppppp1/1n6/7p/2P2P1n/4P1Q1/PP1P2PP/RKNB1RBN w FAfa - 0 9 +epd rk1bqrb1/ppppppp1/1n6/7p/2P2P1n/4P1Q1/PP1P2PP/RKNB1RBN w FAfa - perft 1 35 perft 2 760 perft 3 25817 @@ -7463,7 +7463,7 @@ perft 5 21014787 perft 6 536852043 id 829 -epd rkq1rb1n/ppppp1pp/1n6/5p2/PPb2P2/8/1KPPP1PP/R1NQRBBN w ea - 1 9 +epd rkq1rb1n/ppppp1pp/1n6/5p2/PPb2P2/8/1KPPP1PP/R1NQRBBN w ea - perft 1 27 perft 2 754 perft 3 21009 @@ -7472,7 +7472,7 @@ perft 5 16461795 perft 6 448313956 id 830 -epd rknqr2b/pppnp1pp/3p4/3b1p2/8/1N1P2N1/PPP1PPPP/RKQ1R1BB w EAea - 1 9 +epd rknqr2b/pppnp1pp/3p4/3b1p2/8/1N1P2N1/PPP1PPPP/RKQ1R1BB w EAea - perft 1 27 perft 2 803 perft 3 23708 @@ -7481,7 +7481,7 @@ perft 5 21875031 perft 6 654754840 id 831 -epd bbrknrqn/ppppp1pB/8/2P2p1p/8/5N2/PP1PPPPP/B1RK1RQN w FCfc - 0 9 +epd bbrknrqn/ppppp1pB/8/2P2p1p/8/5N2/PP1PPPPP/B1RK1RQN w FCfc - perft 1 30 perft 2 799 perft 3 23923 @@ -7490,7 +7490,7 @@ perft 5 20532790 perft 6 603059376 id 832 -epd brkbnrq1/1pppp1p1/6np/p4p2/4P3/1PP5/P1KP1PPP/BR1BNRQN w fb - 1 9 +epd brkbnrq1/1pppp1p1/6np/p4p2/4P3/1PP5/P1KP1PPP/BR1BNRQN w fb - perft 1 27 perft 2 726 perft 3 19329 @@ -7499,7 +7499,7 @@ perft 5 15156662 perft 6 457601127 id 833 -epd brknrbq1/1p1p1ppp/p3p1n1/2p5/8/1P1BPP2/P1PP2PP/BRKNR1QN w EBeb - 0 9 +epd brknrbq1/1p1p1ppp/p3p1n1/2p5/8/1P1BPP2/P1PP2PP/BRKNR1QN w EBeb - perft 1 36 perft 2 786 perft 3 27868 @@ -7508,7 +7508,7 @@ perft 5 22852433 perft 6 577223409 id 834 -epd brknrqnb/p2ppp1p/2p5/1p6/3P2p1/P1P1N3/1P2PPPP/BRK1RQNB w EBeb - 0 9 +epd brknrqnb/p2ppp1p/2p5/1p6/3P2p1/P1P1N3/1P2PPPP/BRK1RQNB w EBeb - perft 1 23 perft 2 649 perft 3 15169 @@ -7517,7 +7517,7 @@ perft 5 10687843 perft 6 320881984 id 835 -epd rbbk1rqn/1ppppppp/3n4/p7/2P5/3N4/PP1PPPPP/RBB1KRQN w fa - 1 9 +epd rbbk1rqn/1ppppppp/3n4/p7/2P5/3N4/PP1PPPPP/RBB1KRQN w fa - perft 1 20 perft 2 478 perft 3 11094 @@ -7526,7 +7526,7 @@ perft 5 7094988 perft 6 185488058 id 836 -epd rkbbnrqn/p2p1ppp/1p2p3/8/P1p1P3/1BP5/1P1P1PPP/RKB1NRQN w FAfa - 0 9 +epd rkbbnrqn/p2p1ppp/1p2p3/8/P1p1P3/1BP5/1P1P1PPP/RKB1NRQN w FAfa - perft 1 22 perft 2 570 perft 3 13295 @@ -7535,7 +7535,7 @@ perft 5 8671852 perft 6 229898448 id 837 -epd rkb1rb1n/ppppppqp/8/2n3p1/2P1P1P1/8/PP1P1P1P/RKBNRBQN w EAea - 1 9 +epd rkb1rb1n/ppppppqp/8/2n3p1/2P1P1P1/8/PP1P1P1P/RKBNRBQN w EAea - perft 1 23 perft 2 663 perft 3 16212 @@ -7544,7 +7544,7 @@ perft 5 12900485 perft 6 404944553 id 838 -epd rkb1rqnb/pppp3p/2n3p1/4pp2/P2P3P/2P5/1P2PPP1/RKBNRQNB w EAea - 0 9 +epd rkb1rqnb/pppp3p/2n3p1/4pp2/P2P3P/2P5/1P2PPP1/RKBNRQNB w EAea - perft 1 25 perft 2 845 perft 3 22188 @@ -7553,7 +7553,7 @@ perft 5 20276176 perft 6 683290790 id 839 -epd rbk1brqn/ppp1pppp/8/3p4/7P/1P4P1/2PPPP2/RBKNBRQN w FAfa - 0 9 +epd rbk1brqn/ppp1pppp/8/3p4/7P/1P4P1/2PPPP2/RBKNBRQN w FAfa - perft 1 24 perft 2 526 perft 3 13862 @@ -7562,7 +7562,7 @@ perft 5 9054028 perft 6 222704171 id 840 -epd rknbbrqn/pp3pp1/4p3/2pp3p/2P5/8/PPBPPPPP/RKN1BRQN w FAfa - 0 9 +epd rknbbrqn/pp3pp1/4p3/2pp3p/2P5/8/PPBPPPPP/RKN1BRQN w FAfa - perft 1 26 perft 2 756 perft 3 19280 @@ -7571,7 +7571,7 @@ perft 5 14697705 perft 6 433719427 id 841 -epd 1knrbbqn/rp1p1ppp/p3p3/2p5/8/5P1P/PPPPP1P1/RKNRBBQN w DAd - 0 9 +epd 1knrbbqn/rp1p1ppp/p3p3/2p5/8/5P1P/PPPPP1P1/RKNRBBQN w DAd - perft 1 26 perft 2 539 perft 3 15194 @@ -7580,7 +7580,7 @@ perft 5 10223443 perft 6 248715580 id 842 -epd rknr1qnb/ppp1p1pp/3p2b1/8/4p3/1P3P1P/P1PP2P1/RKNRBQNB w DAda - 0 9 +epd rknr1qnb/ppp1p1pp/3p2b1/8/4p3/1P3P1P/P1PP2P1/RKNRBQNB w DAda - perft 1 25 perft 2 701 perft 3 18969 @@ -7589,7 +7589,7 @@ perft 5 16047041 perft 6 496340789 id 843 -epd rbk1r1bn/ppppp1pp/4n3/5p2/1P3P2/4N2P/PqPPP1P1/RBK1RQBN w EAea - 1 9 +epd rbk1r1bn/ppppp1pp/4n3/5p2/1P3P2/4N2P/PqPPP1P1/RBK1RQBN w EAea - perft 1 2 perft 2 60 perft 3 1319 @@ -7598,7 +7598,7 @@ perft 5 1017864 perft 6 33183408 id 844 -epd r1nbrqbn/k1ppp1pp/1p6/p4p2/2P5/6PQ/PP1PPP1P/RKNBR1BN w EA - 0 9 +epd r1nbrqbn/k1ppp1pp/1p6/p4p2/2P5/6PQ/PP1PPP1P/RKNBR1BN w EA - perft 1 27 perft 2 699 perft 3 20436 @@ -7607,7 +7607,7 @@ perft 5 17192121 perft 6 499247248 id 845 -epd rknrqbbn/1pp1pp2/p5p1/3p3p/6P1/PN5P/1PPPPP2/RK1RQBBN w DAda - 0 9 +epd rknrqbbn/1pp1pp2/p5p1/3p3p/6P1/PN5P/1PPPPP2/RK1RQBBN w DAda - perft 1 23 perft 2 611 perft 3 15515 @@ -7616,7 +7616,7 @@ perft 5 11917036 perft 6 352885930 id 846 -epd rknrqn1b/p1pp1ppb/8/1p2p1Qp/3P4/3N4/PPP1PPPP/RK1R1NBB w DAda - 0 9 +epd rknrqn1b/p1pp1ppb/8/1p2p1Qp/3P4/3N4/PPP1PPPP/RK1R1NBB w DAda - perft 1 45 perft 2 1170 perft 3 48283 @@ -7625,7 +7625,7 @@ perft 5 52213677 perft 6 1500007485 id 847 -epd bbkrnrnq/p2p1ppp/2p1p3/1p6/1P2Q3/6P1/P1PPPP1P/BBKRNRN1 w - - 0 9 +epd bbkrnrnq/p2p1ppp/2p1p3/1p6/1P2Q3/6P1/P1PPPP1P/BBKRNRN1 w - - perft 1 41 perft 2 1035 perft 3 39895 @@ -7634,7 +7634,7 @@ perft 5 38555608 perft 6 1037686769 id 848 -epd brkbnr2/1ppppp1p/7n/p5N1/P2q4/8/1PPPPPPP/BRKBNRQ1 w FBfb - 1 9 +epd brkbnr2/1ppppp1p/7n/p5N1/P2q4/8/1PPPPPPP/BRKBNRQ1 w FBfb - perft 1 22 perft 2 869 perft 3 19234 @@ -7643,7 +7643,7 @@ perft 5 16453359 perft 6 567287944 id 849 -epd brknrbnq/p1ppppp1/1p6/7p/2PP4/5P2/PPK1P1PP/BR1NRBNQ w eb - 1 9 +epd brknrbnq/p1ppppp1/1p6/7p/2PP4/5P2/PPK1P1PP/BR1NRBNQ w eb - perft 1 23 perft 2 641 perft 3 14748 @@ -7652,7 +7652,7 @@ perft 5 10192718 perft 6 302864305 id 850 -epd brk1r1qb/pp1ppnpp/2p2pn1/8/6N1/2N3P1/PPPPPP1P/BRK1R1QB w EBeb - 3 9 +epd brk1r1qb/pp1ppnpp/2p2pn1/8/6N1/2N3P1/PPPPPP1P/BRK1R1QB w EBeb - perft 1 32 perft 2 863 perft 3 28379 @@ -7661,7 +7661,7 @@ perft 5 25848794 perft 6 720443112 id 851 -epd rbbk1rnq/pppp1pp1/4p2p/8/3P2n1/4BN1P/PPP1PPP1/RB1K1RNQ w FAfa - 3 9 +epd rbbk1rnq/pppp1pp1/4p2p/8/3P2n1/4BN1P/PPP1PPP1/RB1K1RNQ w FAfa - perft 1 26 perft 2 628 perft 3 16151 @@ -7670,7 +7670,7 @@ perft 5 11237919 perft 6 300314373 id 852 -epd rkbbnr1q/p1pppppp/5n2/1p5B/PP6/4P3/2PP1PPP/RKB1NRNQ w FAfa - 0 9 +epd rkbbnr1q/p1pppppp/5n2/1p5B/PP6/4P3/2PP1PPP/RKB1NRNQ w FAfa - perft 1 30 perft 2 692 perft 3 21036 @@ -7679,7 +7679,7 @@ perft 5 16025428 perft 6 420887328 id 853 -epd rkb1rbnq/1pppp1pp/5p2/p7/5n1P/1PN3P1/P1PPPP2/RKB1RBNQ w EAea - 0 9 +epd rkb1rbnq/1pppp1pp/5p2/p7/5n1P/1PN3P1/P1PPPP2/RKB1RBNQ w EAea - perft 1 32 perft 2 825 perft 3 27130 @@ -7688,7 +7688,7 @@ perft 5 23593363 perft 6 622249676 id 854 -epd rkbnrnqb/1ppp1p1p/p5p1/4p3/4P3/2N2P2/PPPP2PP/RKBR1NQB w Aea - 0 9 +epd rkbnrnqb/1ppp1p1p/p5p1/4p3/4P3/2N2P2/PPPP2PP/RKBR1NQB w Aea - perft 1 24 perft 2 487 perft 3 13300 @@ -7697,7 +7697,7 @@ perft 5 8782713 perft 6 215787079 id 855 -epd rbknbr1q/pppp2pp/4p3/5p1n/1P2P2N/8/P1PP1PPP/RBKNBR1Q w FAfa - 0 9 +epd rbknbr1q/pppp2pp/4p3/5p1n/1P2P2N/8/P1PP1PPP/RBKNBR1Q w FAfa - perft 1 23 perft 2 571 perft 3 13799 @@ -7706,7 +7706,7 @@ perft 5 9224232 perft 6 257288920 id 856 -epd rknbb1nq/pppppr2/5pp1/7p/8/1N4P1/PPPPPP1P/RK1BBRNQ w FAa - 2 9 +epd rknbb1nq/pppppr2/5pp1/7p/8/1N4P1/PPPPPP1P/RK1BBRNQ w FAa - perft 1 26 perft 2 548 perft 3 15618 @@ -7715,7 +7715,7 @@ perft 5 10587626 perft 6 253006082 id 857 -epd rknr1bnq/p2pp1pp/1p3p2/2p4b/6PP/2P2N2/PP1PPP2/RKNRBB1Q w DAda - 1 9 +epd rknr1bnq/p2pp1pp/1p3p2/2p4b/6PP/2P2N2/PP1PPP2/RKNRBB1Q w DAda - perft 1 25 perft 2 502 perft 3 13150 @@ -7724,7 +7724,7 @@ perft 5 7824941 perft 6 175766730 id 858 -epd rknrb1qb/ppp1pppp/3p4/8/4P1nP/2P5/PPKP1PP1/R1NRBNQB w da - 1 9 +epd rknrb1qb/ppp1pppp/3p4/8/4P1nP/2P5/PPKP1PP1/R1NRBNQB w da - perft 1 23 perft 2 643 perft 3 14849 @@ -7733,7 +7733,7 @@ perft 5 10507328 perft 6 312096061 id 859 -epd rbk1rnbq/pppp1npp/4p3/5p2/4P1P1/7P/PPPP1P1N/RBKNR1BQ w EAea - 1 9 +epd rbk1rnbq/pppp1npp/4p3/5p2/4P1P1/7P/PPPP1P1N/RBKNR1BQ w EAea - perft 1 24 perft 2 591 perft 3 15178 @@ -7742,7 +7742,7 @@ perft 5 10251465 perft 6 263574861 id 860 -epd rknbrnb1/p1pppp1p/1p6/3N2p1/P3q1P1/8/1PPPPP1P/RKNBR1BQ w EAea - 1 9 +epd rknbrnb1/p1pppp1p/1p6/3N2p1/P3q1P1/8/1PPPPP1P/RKNBR1BQ w EAea - perft 1 28 perft 2 948 perft 3 27343 @@ -7751,7 +7751,7 @@ perft 5 26241141 perft 6 812343987 id 861 -epd rknrn1b1/ppppppqp/8/6p1/2P5/2P1BP2/PP2P1PP/RKNRNB1Q w DAda - 1 9 +epd rknrn1b1/ppppppqp/8/6p1/2P5/2P1BP2/PP2P1PP/RKNRNB1Q w DAda - perft 1 31 perft 2 807 perft 3 24360 @@ -7760,7 +7760,7 @@ perft 5 20455205 perft 6 588518645 id 862 -epd 1k1rnqbb/npppppp1/r7/p2B3p/5P2/1N4P1/PPPPP2P/RK1RNQB1 w DAd - 0 9 +epd 1k1rnqbb/npppppp1/r7/p2B3p/5P2/1N4P1/PPPPP2P/RK1RNQB1 w DAd - perft 1 40 perft 2 1122 perft 3 44297 @@ -7769,7 +7769,7 @@ perft 5 48711073 perft 6 1412437357 id 863 -epd bbqr1rkn/pp1ppppp/8/2p5/1P2P1n1/7N/P1PP1P1P/BBQRKR1N w FD - 0 9 +epd bbqr1rkn/pp1ppppp/8/2p5/1P2P1n1/7N/P1PP1P1P/BBQRKR1N w FD - perft 1 26 perft 2 841 perft 3 22986 @@ -7778,7 +7778,7 @@ perft 5 21328001 perft 6 705170410 id 864 -epd bqkr1rnn/1ppp1ppp/p4b2/4p3/P7/3PP2N/1PP2PPP/BQRBKR1N w FC - 3 9 +epd bqkr1rnn/1ppp1ppp/p4b2/4p3/P7/3PP2N/1PP2PPP/BQRBKR1N w FC - perft 1 24 perft 2 500 perft 3 12802 @@ -7787,7 +7787,7 @@ perft 5 7928916 perft 6 197806842 id 865 -epd bqrkrbnn/1pp1ppp1/8/p6p/3p4/P3P2P/QPPP1PP1/B1RKRBNN w ECec - 0 9 +epd bqrkrbnn/1pp1ppp1/8/p6p/3p4/P3P2P/QPPP1PP1/B1RKRBNN w ECec - perft 1 31 perft 2 592 perft 3 18585 @@ -7796,7 +7796,7 @@ perft 5 12607528 perft 6 298629240 id 866 -epd bqkrrnnb/2p1pppp/p7/1P1p4/8/2R3P1/PP1PPP1P/BQ1KRNNB w E - 0 9 +epd bqkrrnnb/2p1pppp/p7/1P1p4/8/2R3P1/PP1PPP1P/BQ1KRNNB w E - perft 1 42 perft 2 1124 perft 3 45187 @@ -7805,7 +7805,7 @@ perft 5 50052573 perft 6 1483524894 id 867 -epd qbbrkrn1/p1pppn1p/8/1p3Pp1/2P5/8/PP1PPP1P/QBBRKRNN w FDfd - 0 9 +epd qbbrkrn1/p1pppn1p/8/1p3Pp1/2P5/8/PP1PPP1P/QBBRKRNN w FDfd - perft 1 21 perft 2 577 perft 3 13244 @@ -7814,7 +7814,7 @@ perft 5 9683808 perft 6 300294295 id 868 -epd qrbbkrnn/pp1p2pp/4p3/5p2/2p2P1P/2P5/PP1PP1P1/QRBBKRNN w FBfb - 0 9 +epd qrbbkrnn/pp1p2pp/4p3/5p2/2p2P1P/2P5/PP1PP1P1/QRBBKRNN w FBfb - perft 1 21 perft 2 571 perft 3 12736 @@ -7823,7 +7823,7 @@ perft 5 8239872 perft 6 228837930 id 869 -epd qrbkrbn1/1pp1pppp/p2p4/8/5PPn/2P5/PP1PP3/QRBKRBNN w EBeb - 0 9 +epd qrbkrbn1/1pp1pppp/p2p4/8/5PPn/2P5/PP1PP3/QRBKRBNN w EBeb - perft 1 18 perft 2 466 perft 3 9443 @@ -7832,7 +7832,7 @@ perft 5 5679073 perft 6 162883949 id 870 -epd qrb1rnnb/pp1p1ppp/2pk4/4p3/1P2P3/1R6/P1PP1PPP/Q1BKRNNB w E - 4 9 +epd qrb1rnnb/pp1p1ppp/2pk4/4p3/1P2P3/1R6/P1PP1PPP/Q1BKRNNB w E - perft 1 37 perft 2 760 perft 3 26863 @@ -7841,7 +7841,7 @@ perft 5 19486022 perft 6 421740856 id 871 -epd qbrkbrn1/p1pppp1p/6n1/1p4p1/1P6/5P2/P1PPPBPP/QBRK1RNN w FCfc - 1 9 +epd qbrkbrn1/p1pppp1p/6n1/1p4p1/1P6/5P2/P1PPPBPP/QBRK1RNN w FCfc - perft 1 33 perft 2 824 perft 3 27385 @@ -7850,7 +7850,7 @@ perft 5 25176664 perft 6 734656217 id 872 -epd qrkbbr2/2pppppp/5nn1/pp1Q4/P7/3P4/1PP1PPPP/1RKBBRNN w FBfb - 0 9 +epd qrkbbr2/2pppppp/5nn1/pp1Q4/P7/3P4/1PP1PPPP/1RKBBRNN w FBfb - perft 1 42 perft 2 1147 perft 3 44012 @@ -7859,7 +7859,7 @@ perft 5 48216013 perft 6 1522548864 id 873 -epd qrkrbbnn/pp2pp2/2pp2pp/1B6/P7/4P3/1PPP1PPP/QRKRB1NN w DBdb - 0 9 +epd qrkrbbnn/pp2pp2/2pp2pp/1B6/P7/4P3/1PPP1PPP/QRKRB1NN w DBdb - perft 1 26 perft 2 464 perft 3 12653 @@ -7868,7 +7868,7 @@ perft 5 6928220 perft 6 142507795 id 874 -epd qrkrbnnb/p1pp1pp1/1p5p/4p3/1P6/6PN/PKPPPP1P/QR1RBN1B w db - 0 9 +epd qrkrbnnb/p1pp1pp1/1p5p/4p3/1P6/6PN/PKPPPP1P/QR1RBN1B w db - perft 1 29 perft 2 705 perft 3 20000 @@ -7877,7 +7877,7 @@ perft 5 15055365 perft 6 419552571 id 875 -epd qbrkr1bn/p1p1pp1p/1p1p2n1/6p1/3P1P2/4P3/PPP3PP/QBKRRNBN w ec - 2 9 +epd qbrkr1bn/p1p1pp1p/1p1p2n1/6p1/3P1P2/4P3/PPP3PP/QBKRRNBN w ec - perft 1 23 perft 2 613 perft 3 14835 @@ -7886,7 +7886,7 @@ perft 5 10747407 perft 6 323905533 id 876 -epd qrk1rnb1/p1pp1ppp/1p2Bbn1/8/4P3/6P1/PPPP1P1P/QRK1RNBN w EBeb - 1 9 +epd qrk1rnb1/p1pp1ppp/1p2Bbn1/8/4P3/6P1/PPPP1P1P/QRK1RNBN w EBeb - perft 1 28 perft 2 927 perft 3 24887 @@ -7895,7 +7895,7 @@ perft 5 23063284 perft 6 807913585 id 877 -epd 1qkrnbbn/1rpppppp/pp6/5N2/P4P2/8/1PPPP1PP/QRKRNBB1 w DBd - 3 9 +epd 1qkrnbbn/1rpppppp/pp6/5N2/P4P2/8/1PPPP1PP/QRKRNBB1 w DBd - perft 1 30 perft 2 542 perft 3 16646 @@ -7904,7 +7904,7 @@ perft 5 10976745 perft 6 251694423 id 878 -epd qrkr2bb/pppppppp/8/1n2n3/1N5P/1P6/P1PPPPP1/QRKR1NBB w DBdb - 1 9 +epd qrkr2bb/pppppppp/8/1n2n3/1N5P/1P6/P1PPPPP1/QRKR1NBB w DBdb - perft 1 28 perft 2 719 perft 3 21048 @@ -7913,7 +7913,7 @@ perft 5 17351761 perft 6 479400272 id 879 -epd bbrqkrnn/3ppppp/8/ppp5/6P1/4P2N/PPPPKP1P/BBRQ1R1N w fc - 0 9 +epd bbrqkrnn/3ppppp/8/ppp5/6P1/4P2N/PPPPKP1P/BBRQ1R1N w fc - perft 1 21 perft 2 704 perft 3 16119 @@ -7922,7 +7922,7 @@ perft 5 13676371 perft 6 470796854 id 880 -epd brqbkrnn/1pp2p1p/3pp1p1/p5N1/8/1P6/P1PPPPPP/BRQBK1RN w Bfb - 0 9 +epd brqbkrnn/1pp2p1p/3pp1p1/p5N1/8/1P6/P1PPPPPP/BRQBK1RN w Bfb - perft 1 34 perft 2 688 perft 3 22827 @@ -7931,7 +7931,7 @@ perft 5 16639723 perft 6 402140795 id 881 -epd br1krb1n/2qppppp/pp3n2/8/1P4P1/8/P1PPPP1P/1RQKRBNN w EBeb - 0 9 +epd br1krb1n/2qppppp/pp3n2/8/1P4P1/8/P1PPPP1P/1RQKRBNN w EBeb - perft 1 24 perft 2 945 perft 3 23943 @@ -7940,7 +7940,7 @@ perft 5 25019636 perft 6 959651619 id 882 -epd brqkr1nb/2ppp1pp/1p2np2/p7/2P1PN2/8/PP1P1PPP/BRQKRN1B w EBeb - 0 9 +epd brqkr1nb/2ppp1pp/1p2np2/p7/2P1PN2/8/PP1P1PPP/BRQKRN1B w EBeb - perft 1 28 perft 2 675 perft 3 19728 @@ -7949,7 +7949,7 @@ perft 5 15516491 perft 6 417396563 id 883 -epd rbbqkrnn/3pppp1/p7/1pp4p/2P1P2P/8/PP1P1PP1/RBBQKRNN w FAfa - 0 9 +epd rbbqkrnn/3pppp1/p7/1pp4p/2P1P2P/8/PP1P1PP1/RBBQKRNN w FAfa - perft 1 26 perft 2 671 perft 3 18164 @@ -7958,7 +7958,7 @@ perft 5 14072641 perft 6 404960259 id 884 -epd rqbbkr1n/pp1p1p1p/4pn2/2p3p1/4P1P1/3P3P/PPP2P2/RQBBKRNN w FAfa - 0 9 +epd rqbbkr1n/pp1p1p1p/4pn2/2p3p1/4P1P1/3P3P/PPP2P2/RQBBKRNN w FAfa - perft 1 22 perft 2 633 perft 3 14629 @@ -7967,7 +7967,7 @@ perft 5 10776416 perft 6 335689685 id 885 -epd rqbkrbnn/p1ppp3/1p3pp1/7p/3P4/P1P5/1PQ1PPPP/R1BKRBNN w EAea - 0 9 +epd rqbkrbnn/p1ppp3/1p3pp1/7p/3P4/P1P5/1PQ1PPPP/R1BKRBNN w EAea - perft 1 32 perft 2 607 perft 3 20339 @@ -7976,7 +7976,7 @@ perft 5 15586203 perft 6 383515709 id 886 -epd rqbkrnn1/pp2ppbp/3p4/2p3p1/2P5/1P3N1P/P2PPPP1/RQBKRN1B w EAea - 1 9 +epd rqbkrnn1/pp2ppbp/3p4/2p3p1/2P5/1P3N1P/P2PPPP1/RQBKRN1B w EAea - perft 1 29 perft 2 943 perft 3 28732 @@ -7985,7 +7985,7 @@ perft 5 28761841 perft 6 907579129 id 887 -epd rbqkb1nn/1ppppr1p/p5p1/5p2/1P6/2P4P/P1KPPPP1/RBQ1BRNN w a - 1 9 +epd rbqkb1nn/1ppppr1p/p5p1/5p2/1P6/2P4P/P1KPPPP1/RBQ1BRNN w a - perft 1 22 perft 2 441 perft 3 10403 @@ -7994,7 +7994,7 @@ perft 5 5784206 perft 6 140934555 id 888 -epd rqkb1rnn/1pp1pp1p/p5p1/1b1p4/3P4/P5P1/RPP1PP1P/1QKBBRNN w Ffa - 1 9 +epd rqkb1rnn/1pp1pp1p/p5p1/1b1p4/3P4/P5P1/RPP1PP1P/1QKBBRNN w Ffa - perft 1 21 perft 2 505 perft 3 11592 @@ -8003,7 +8003,7 @@ perft 5 7147063 perft 6 188559137 id 889 -epd rq1rbbnn/pkp1ppp1/3p3p/1p2N1P1/8/8/PPPPPP1P/RQKRBB1N w DA - 0 9 +epd rq1rbbnn/pkp1ppp1/3p3p/1p2N1P1/8/8/PPPPPP1P/RQKRBB1N w DA - perft 1 27 perft 2 608 perft 3 16419 @@ -8012,7 +8012,7 @@ perft 5 10808908 perft 6 268393274 id 890 -epd rqkrb2b/p2ppppp/2p3nn/1p6/5P2/PP1P4/2P1P1PP/RQKRBNNB w DAda - 1 9 +epd rqkrb2b/p2ppppp/2p3nn/1p6/5P2/PP1P4/2P1P1PP/RQKRBNNB w DAda - perft 1 30 perft 2 749 perft 3 21563 @@ -8021,7 +8021,7 @@ perft 5 16916813 perft 6 485406712 id 891 -epd rbqkr1bn/pp1ppp2/2p1n2p/6p1/8/4BPNP/PPPPP1P1/RBQKRN2 w EAea - 0 9 +epd rbqkr1bn/pp1ppp2/2p1n2p/6p1/8/4BPNP/PPPPP1P1/RBQKRN2 w EAea - perft 1 23 perft 2 600 perft 3 15082 @@ -8030,7 +8030,7 @@ perft 5 11041820 perft 6 314327867 id 892 -epd rqkbrnb1/2ppp1pp/pp3pn1/8/5P2/B2P4/PPP1P1PP/RQKBRN1N w EAea - 2 9 +epd rqkbrnb1/2ppp1pp/pp3pn1/8/5P2/B2P4/PPP1P1PP/RQKBRN1N w EAea - perft 1 22 perft 2 569 perft 3 13541 @@ -8039,7 +8039,7 @@ perft 5 9395816 perft 6 269460607 id 893 -epd rqkrnbb1/p1p1pppp/1p4n1/3p4/7P/P3P3/1PPPBPP1/RQKRN1BN w DAda - 0 9 +epd rqkrnbb1/p1p1pppp/1p4n1/3p4/7P/P3P3/1PPPBPP1/RQKRN1BN w DAda - perft 1 27 perft 2 579 perft 3 15565 @@ -8048,7 +8048,7 @@ perft 5 10238486 perft 6 266047417 id 894 -epd rqkrn1bb/p1ppp1pp/4n3/1p6/6p1/4N3/PPPPPPPP/RQKR2BB w DAda - 0 9 +epd rqkrn1bb/p1ppp1pp/4n3/1p6/6p1/4N3/PPPPPPPP/RQKR2BB w DAda - perft 1 20 perft 2 462 perft 3 10234 @@ -8057,7 +8057,7 @@ perft 5 6563859 perft 6 193376359 id 895 -epd bbrkqr2/pppp1ppp/6nn/8/2P1p3/3PP2N/PP3PPP/BBRKQR1N w FCfc - 0 9 +epd bbrkqr2/pppp1ppp/6nn/8/2P1p3/3PP2N/PP3PPP/BBRKQR1N w FCfc - perft 1 28 perft 2 724 perft 3 21688 @@ -8066,7 +8066,7 @@ perft 5 19318355 perft 6 593204629 id 896 -epd brk1qrnn/1pppbppp/4p3/8/1p6/P1P4P/3PPPP1/BRKBQRNN w FBfb - 1 9 +epd brk1qrnn/1pppbppp/4p3/8/1p6/P1P4P/3PPPP1/BRKBQRNN w FBfb - perft 1 24 perft 2 662 perft 3 16920 @@ -8075,7 +8075,7 @@ perft 5 12610387 perft 6 355969349 id 897 -epd 1r1qrbnn/p1pkpppp/1p1p4/8/3P1PP1/P4b2/1PP1P2P/BRKQRBNN w EB - 1 9 +epd 1r1qrbnn/p1pkpppp/1p1p4/8/3P1PP1/P4b2/1PP1P2P/BRKQRBNN w EB - perft 1 22 perft 2 696 perft 3 17021 @@ -8084,7 +8084,7 @@ perft 5 13697382 perft 6 401903030 id 898 -epd 1rkqrnnb/p1p1p1pp/1p1p4/3b1p1N/4P3/5N2/PPPP1PPP/BRKQR2B w EBeb - 1 9 +epd 1rkqrnnb/p1p1p1pp/1p1p4/3b1p1N/4P3/5N2/PPPP1PPP/BRKQR2B w EBeb - perft 1 29 perft 2 887 perft 3 27035 @@ -8093,7 +8093,7 @@ perft 5 26051242 perft 6 791718847 id 899 -epd rbbkq1rn/pppppppp/7n/8/P7/3P3P/1PPKPPP1/RBB1QRNN w a - 3 9 +epd rbbkq1rn/pppppppp/7n/8/P7/3P3P/1PPKPPP1/RBB1QRNN w a - perft 1 22 perft 2 417 perft 3 9900 @@ -8102,7 +8102,7 @@ perft 5 5505063 perft 6 134818483 id 900 -epd rkbbqr1n/1p1pppp1/2p2n2/p4NBp/8/3P4/PPP1PPPP/RK1BQRN1 w FAfa - 0 9 +epd rkbbqr1n/1p1pppp1/2p2n2/p4NBp/8/3P4/PPP1PPPP/RK1BQRN1 w FAfa - perft 1 37 perft 2 832 perft 3 30533 @@ -8111,7 +8111,7 @@ perft 5 26676373 perft 6 673756141 id 901 -epd rkbqrb1n/3pBppp/ppp2n2/8/8/P2P4/1PP1PPPP/RK1QRBNN w EAea - 0 9 +epd rkbqrb1n/3pBppp/ppp2n2/8/8/P2P4/1PP1PPPP/RK1QRBNN w EAea - perft 1 28 perft 2 685 perft 3 19718 @@ -8120,7 +8120,7 @@ perft 5 16033316 perft 6 482288814 id 902 -epd rkb1rn1b/ppppqppp/4p3/8/1P2n1P1/5Q2/P1PP1P1P/RKB1RNNB w EAea - 2 9 +epd rkb1rn1b/ppppqppp/4p3/8/1P2n1P1/5Q2/P1PP1P1P/RKB1RNNB w EAea - perft 1 37 perft 2 1158 perft 3 40114 @@ -8129,7 +8129,7 @@ perft 5 44672979 perft 6 1389312729 id 903 -epd r1kqbrnn/pp1pp1p1/7p/2P2p2/5b2/3P4/P1P1P1PP/RBKQBRNN w FAfa - 0 9 +epd r1kqbrnn/pp1pp1p1/7p/2P2p2/5b2/3P4/P1P1P1PP/RBKQBRNN w FAfa - perft 1 5 perft 2 161 perft 3 4745 @@ -8138,7 +8138,7 @@ perft 5 4734999 perft 6 157499039 id 904 -epd rkqbbr1n/ppp1ppp1/8/Q2p3p/4n3/3P1P2/PPP1P1PP/RK1BBRNN w FAfa - 2 9 +epd rkqbbr1n/ppp1ppp1/8/Q2p3p/4n3/3P1P2/PPP1P1PP/RK1BBRNN w FAfa - perft 1 38 perft 2 1144 perft 3 40433 @@ -8147,7 +8147,7 @@ perft 5 43832975 perft 6 1366087771 id 905 -epd rkqrbbn1/p1ppppp1/Bp5p/8/P6n/2P1P3/1P1P1PPP/RKQRB1NN w DAda - 0 9 +epd rkqrbbn1/p1ppppp1/Bp5p/8/P6n/2P1P3/1P1P1PPP/RKQRB1NN w DAda - perft 1 28 perft 2 551 perft 3 15488 @@ -8156,7 +8156,7 @@ perft 5 9944107 perft 6 251179183 id 906 -epd rkqrb1nb/1ppp1ppp/p7/4p3/5n2/3P2N1/PPPQPPPP/RK1RB1NB w DAda - 0 9 +epd rkqrb1nb/1ppp1ppp/p7/4p3/5n2/3P2N1/PPPQPPPP/RK1RB1NB w DAda - perft 1 26 perft 2 690 perft 3 19877 @@ -8165,7 +8165,7 @@ perft 5 15965907 perft 6 418191735 id 907 -epd rbkqrnbn/pppp1p2/4p1p1/7p/7P/P2P4/BPP1PPP1/R1KQRNBN w EAea - 0 9 +epd rbkqrnbn/pppp1p2/4p1p1/7p/7P/P2P4/BPP1PPP1/R1KQRNBN w EAea - perft 1 27 perft 2 515 perft 3 13992 @@ -8174,7 +8174,7 @@ perft 5 8792550 perft 6 218658292 id 908 -epd rkqbrnbn/pp1ppp2/8/2p3p1/P1P4p/5P2/1PKPP1PP/R1QBRNBN w ea - 0 9 +epd rkqbrnbn/pp1ppp2/8/2p3p1/P1P4p/5P2/1PKPP1PP/R1QBRNBN w ea - perft 1 27 perft 2 627 perft 3 16843 @@ -8183,7 +8183,7 @@ perft 5 11978698 perft 6 328434174 id 909 -epd rkqrnbbn/1p2pp1p/3p2p1/p1p5/P5PP/3N4/1PPPPP2/RKQR1BBN w DAda - 0 9 +epd rkqrnbbn/1p2pp1p/3p2p1/p1p5/P5PP/3N4/1PPPPP2/RKQR1BBN w DAda - perft 1 23 perft 2 624 perft 3 15512 @@ -8192,7 +8192,7 @@ perft 5 11960861 perft 6 367311176 id 910 -epd rk2rnbb/ppqppppp/2pn4/8/1P3P2/6P1/P1PPP1NP/RKQR1NBB w DAa - 1 9 +epd rk2rnbb/ppqppppp/2pn4/8/1P3P2/6P1/P1PPP1NP/RKQR1NBB w DAa - perft 1 27 perft 2 727 perft 3 20206 @@ -8201,7 +8201,7 @@ perft 5 16633696 perft 6 505212747 id 911 -epd b1krrqnn/pp1ppp1p/2p3p1/8/P3Pb1P/1P6/2PP1PP1/BBRKRQNN w EC - 0 9 +epd b1krrqnn/pp1ppp1p/2p3p1/8/P3Pb1P/1P6/2PP1PP1/BBRKRQNN w EC - perft 1 32 perft 2 943 perft 3 30759 @@ -8210,7 +8210,7 @@ perft 5 28672582 perft 6 800922511 id 912 -epd 1rkbrqnn/p1pp1ppp/1p6/8/P2Pp3/8/1PPKPPQP/BR1BR1NN w eb - 0 9 +epd 1rkbrqnn/p1pp1ppp/1p6/8/P2Pp3/8/1PPKPPQP/BR1BR1NN w eb - perft 1 28 perft 2 916 perft 3 24892 @@ -8219,7 +8219,7 @@ perft 5 22840279 perft 6 759318058 id 913 -epd brkrqb1n/1pppp1pp/p7/3n1p2/P5P1/3PP3/1PP2P1P/BRKRQBNN w DBdb - 0 9 +epd brkrqb1n/1pppp1pp/p7/3n1p2/P5P1/3PP3/1PP2P1P/BRKRQBNN w DBdb - perft 1 27 perft 2 669 perft 3 18682 @@ -8228,7 +8228,7 @@ perft 5 13956472 perft 6 380267099 id 914 -epd brkrqnnb/3pppp1/1p6/p1p4p/2P3P1/6N1/PP1PPP1P/BRKRQ1NB w DBdb - 0 9 +epd brkrqnnb/3pppp1/1p6/p1p4p/2P3P1/6N1/PP1PPP1P/BRKRQ1NB w DBdb - perft 1 29 perft 2 699 perft 3 20042 @@ -8237,7 +8237,7 @@ perft 5 15093909 perft 6 406594531 id 915 -epd r1bkrq1n/pp2pppp/3b1n2/2pp2B1/6P1/3P1P2/PPP1P2P/RB1KRQNN w EAea - 2 9 +epd r1bkrq1n/pp2pppp/3b1n2/2pp2B1/6P1/3P1P2/PPP1P2P/RB1KRQNN w EAea - perft 1 27 perft 2 835 perft 3 22848 @@ -8246,7 +8246,7 @@ perft 5 19867800 perft 6 631209313 id 916 -epd rk1brq1n/p1p1pppp/3p1n2/1p3b2/4P3/2NQ4/PPPP1PPP/RKBBR2N w EAea - 4 9 +epd rk1brq1n/p1p1pppp/3p1n2/1p3b2/4P3/2NQ4/PPPP1PPP/RKBBR2N w EAea - perft 1 36 perft 2 1004 perft 3 35774 @@ -8255,7 +8255,7 @@ perft 5 35143142 perft 6 966310885 id 917 -epd rkbrqbnn/1p2ppp1/B1p5/p2p3p/4P2P/8/PPPP1PP1/RKBRQ1NN w DAda - 0 9 +epd rkbrqbnn/1p2ppp1/B1p5/p2p3p/4P2P/8/PPPP1PP1/RKBRQ1NN w DAda - perft 1 27 perft 2 748 perft 3 21005 @@ -8264,7 +8264,7 @@ perft 5 17597073 perft 6 515304215 id 918 -epd rkbrqn1b/pp1pp1pp/2p2p2/5n2/8/2P2P2/PP1PP1PP/RKBRQ1NB w DAda - 0 9 +epd rkbrqn1b/pp1pp1pp/2p2p2/5n2/8/2P2P2/PP1PP1PP/RKBRQ1NB w DAda - perft 1 20 perft 2 479 perft 3 10485 @@ -8273,7 +8273,7 @@ perft 5 6253775 perft 6 167767913 id 919 -epd rbkrbnn1/ppppp1pp/5q2/5p2/5P2/P3P2N/1PPP2PP/RBKRBQ1N w DAda - 3 9 +epd rbkrbnn1/ppppp1pp/5q2/5p2/5P2/P3P2N/1PPP2PP/RBKRBQ1N w DAda - perft 1 28 perft 2 947 perft 3 26900 @@ -8282,7 +8282,7 @@ perft 5 26007841 perft 6 838704143 id 920 -epd rkr1bqnn/1ppp1p1p/p5p1/4p3/3PP2b/2P2P2/PP4PP/RKRBBQNN w CAca - 0 9 +epd rkr1bqnn/1ppp1p1p/p5p1/4p3/3PP2b/2P2P2/PP4PP/RKRBBQNN w CAca - perft 1 31 perft 2 1004 perft 3 32006 @@ -8291,7 +8291,7 @@ perft 5 32688124 perft 6 1024529879 id 921 -epd rkrqbbnn/pppp3p/8/4ppp1/1PP4P/8/P2PPPP1/RKRQBBNN w CAca - 0 9 +epd rkrqbbnn/pppp3p/8/4ppp1/1PP4P/8/P2PPPP1/RKRQBBNN w CAca - perft 1 24 perft 2 717 perft 3 18834 @@ -8300,7 +8300,7 @@ perft 5 15844525 perft 6 484884485 id 922 -epd rkrqbn1b/pppp2pp/8/4pp2/1P1P2n1/5N2/P1P1PP1P/RKRQBN1B w CAca - 0 9 +epd rkrqbn1b/pppp2pp/8/4pp2/1P1P2n1/5N2/P1P1PP1P/RKRQBN1B w CAca - perft 1 25 perft 2 718 perft 3 19654 @@ -8309,7 +8309,7 @@ perft 5 17257753 perft 6 537354146 id 923 -epd rbkrqnbn/p1p1ppp1/1p1p4/8/3PP2p/2PB4/PP3PPP/R1KRQNBN w DAda - 0 9 +epd rbkrqnbn/p1p1ppp1/1p1p4/8/3PP2p/2PB4/PP3PPP/R1KRQNBN w DAda - perft 1 30 perft 2 754 perft 3 23298 @@ -8318,7 +8318,7 @@ perft 5 19338246 perft 6 532603566 id 924 -epd 1krbqnbn/1p2pppp/r1pp4/p7/8/1P1P2PP/P1P1PP2/RKRBQNBN w CAc - 0 9 +epd 1krbqnbn/1p2pppp/r1pp4/p7/8/1P1P2PP/P1P1PP2/RKRBQNBN w CAc - perft 1 21 perft 2 566 perft 3 13519 @@ -8327,7 +8327,7 @@ perft 5 9700847 perft 6 279864836 id 925 -epd rkrq1b2/pppppppb/3n2np/2N5/4P3/7P/PPPP1PP1/RKRQ1BBN w CAca - 1 9 +epd rkrq1b2/pppppppb/3n2np/2N5/4P3/7P/PPPP1PP1/RKRQ1BBN w CAca - perft 1 33 perft 2 654 perft 3 21708 @@ -8336,7 +8336,7 @@ perft 5 15990307 perft 6 382218272 id 926 -epd rkr1nnbb/ppp2p1p/3p1qp1/4p3/P5P1/3PN3/1PP1PP1P/RKRQN1BB w CAca - 1 9 +epd rkr1nnbb/ppp2p1p/3p1qp1/4p3/P5P1/3PN3/1PP1PP1P/RKRQN1BB w CAca - perft 1 28 perft 2 715 perft 3 20361 @@ -8345,7 +8345,7 @@ perft 5 16303092 perft 6 468666425 id 927 -epd bbrkrnqn/1p1ppppp/8/8/p2pP3/PP6/2P2PPP/BBRKRNQN w ECec - 0 9 +epd bbrkrnqn/1p1ppppp/8/8/p2pP3/PP6/2P2PPP/BBRKRNQN w ECec - perft 1 24 perft 2 757 perft 3 19067 @@ -8354,7 +8354,7 @@ perft 5 15957628 perft 6 509307623 id 928 -epd brkbrnqn/ppp2p2/4p3/P2p2pp/6P1/5P2/1PPPP2P/BRKBRNQN w EBeb - 0 9 +epd brkbrnqn/ppp2p2/4p3/P2p2pp/6P1/5P2/1PPPP2P/BRKBRNQN w EBeb - perft 1 25 perft 2 548 perft 3 14563 @@ -8363,7 +8363,7 @@ perft 5 9688526 perft 6 247750144 id 929 -epd brkr1bqn/1pppppp1/3n3p/1p6/P7/4P1P1/1PPP1P1P/BRKRN1QN w DBdb - 0 9 +epd brkr1bqn/1pppppp1/3n3p/1p6/P7/4P1P1/1PPP1P1P/BRKRN1QN w DBdb - perft 1 19 perft 2 359 perft 3 7430 @@ -8372,7 +8372,7 @@ perft 5 3521652 perft 6 81787718 id 930 -epd brkr1qnb/pppp2pp/2B1p3/5p2/2n5/6PP/PPPPPPN1/BRKR1QN1 w DBdb - 1 9 +epd brkr1qnb/pppp2pp/2B1p3/5p2/2n5/6PP/PPPPPPN1/BRKR1QN1 w DBdb - perft 1 27 perft 2 854 perft 3 23303 @@ -8381,7 +8381,7 @@ perft 5 20558538 perft 6 667089231 id 931 -epd rbbkrnqn/p1p1p1pp/8/1p1p4/1P1Pp3/6N1/P1P2PPP/RBBKRNQ1 w EAea - 0 9 +epd rbbkrnqn/p1p1p1pp/8/1p1p4/1P1Pp3/6N1/P1P2PPP/RBBKRNQ1 w EAea - perft 1 28 perft 2 723 perft 3 19844 @@ -8390,7 +8390,7 @@ perft 5 14621108 perft 6 397454100 id 932 -epd rkbbrn1n/pppppp2/5q1p/6p1/3P3P/4P3/PPP2PP1/RKBBRNQN w EAea - 1 9 +epd rkbbrn1n/pppppp2/5q1p/6p1/3P3P/4P3/PPP2PP1/RKBBRNQN w EAea - perft 1 25 perft 2 741 perft 3 19224 @@ -8399,7 +8399,7 @@ perft 5 15605840 perft 6 485037906 id 933 -epd rkbr1bq1/ppnppppp/6n1/2p5/2P1N2P/8/PP1PPPP1/RKBRNBQ1 w DAda - 3 9 +epd rkbr1bq1/ppnppppp/6n1/2p5/2P1N2P/8/PP1PPPP1/RKBRNBQ1 w DAda - perft 1 24 perft 2 547 perft 3 14359 @@ -8408,7 +8408,7 @@ perft 5 9410221 perft 6 234041078 id 934 -epd 1kbrnqnb/r1ppppp1/8/pp5p/8/1P1NP3/P1PP1PPP/RKB1RQNB w Ad - 2 9 +epd 1kbrnqnb/r1ppppp1/8/pp5p/8/1P1NP3/P1PP1PPP/RKB1RQNB w Ad - perft 1 26 perft 2 618 perft 3 17305 @@ -8417,7 +8417,7 @@ perft 5 13112297 perft 6 357030697 id 935 -epd rbkrb1qn/1pp1ppp1/3pn2p/pP6/8/4N1P1/P1PPPP1P/RBKRB1QN w DAda - 0 9 +epd rbkrb1qn/1pp1ppp1/3pn2p/pP6/8/4N1P1/P1PPPP1P/RBKRB1QN w DAda - perft 1 21 perft 2 544 perft 3 12492 @@ -8426,7 +8426,7 @@ perft 5 8381483 perft 6 236013157 id 936 -epd rkrbbnqn/ppppp3/5p2/6pp/5PBP/4P3/PPPP2P1/RKR1BNQN w CAca - 0 9 +epd rkrbbnqn/ppppp3/5p2/6pp/5PBP/4P3/PPPP2P1/RKR1BNQN w CAca - perft 1 30 perft 2 891 perft 3 25435 @@ -8435,7 +8435,7 @@ perft 5 21894752 perft 6 669256602 id 937 -epd rkr1bb1n/ppppp1pp/5p2/4n3/3QP3/5P2/RPPP2PP/1KRNBB1N w Cca - 1 9 +epd rkr1bb1n/ppppp1pp/5p2/4n3/3QP3/5P2/RPPP2PP/1KRNBB1N w Cca - perft 1 45 perft 2 1172 perft 3 51766 @@ -8444,7 +8444,7 @@ perft 5 57856784 perft 6 1501852662 id 938 -epd rkr1bqnb/pp1ppppp/8/2pN4/1P6/5N2/P1PPnPPP/RKR1BQ1B w CAca - 0 9 +epd rkr1bqnb/pp1ppppp/8/2pN4/1P6/5N2/P1PPnPPP/RKR1BQ1B w CAca - perft 1 28 perft 2 730 perft 3 20511 @@ -8453,7 +8453,7 @@ perft 5 16323242 perft 6 463032124 id 939 -epd rbkrnqb1/2ppppp1/p5np/1p6/8/3N4/PPPPPPPP/RBKRQNB1 w DAda - 2 9 +epd rbkrnqb1/2ppppp1/p5np/1p6/8/3N4/PPPPPPPP/RBKRQNB1 w DAda - perft 1 20 perft 2 417 perft 3 9159 @@ -8462,7 +8462,7 @@ perft 5 5180716 perft 6 133936564 id 940 -epd rkrbnqb1/p1pppnpp/5p2/1p6/2P5/1P1P1N2/P3PPPP/RKRB1QBN w CAca - 0 9 +epd rkrbnqb1/p1pppnpp/5p2/1p6/2P5/1P1P1N2/P3PPPP/RKRB1QBN w CAca - perft 1 25 perft 2 546 perft 3 14039 @@ -8471,7 +8471,7 @@ perft 5 8813781 perft 6 222026485 id 941 -epd rkr1qbbn/ppppppp1/4n3/7p/8/P7/KPPPPPPP/R1RNQBBN w ca - 0 9 +epd rkr1qbbn/ppppppp1/4n3/7p/8/P7/KPPPPPPP/R1RNQBBN w ca - perft 1 22 perft 2 484 perft 3 11458 @@ -8480,7 +8480,7 @@ perft 5 6633319 perft 6 163291279 id 942 -epd rkrnqnb1/1ppppp2/p5p1/7p/8/P1bPP3/1PP1QPPP/RKRN1NBB w CAca - 0 9 +epd rkrnqnb1/1ppppp2/p5p1/7p/8/P1bPP3/1PP1QPPP/RKRN1NBB w CAca - perft 1 22 perft 2 636 perft 3 15526 @@ -8489,7 +8489,7 @@ perft 5 11614241 perft 6 331083405 id 943 -epd b2krn1q/p1rppppp/1Q3n2/2p1b3/1P4P1/8/P1PPPP1P/BBRKRNN1 w ECe - 3 9 +epd b2krn1q/p1rppppp/1Q3n2/2p1b3/1P4P1/8/P1PPPP1P/BBRKRNN1 w ECe - perft 1 36 perft 2 1192 perft 3 42945 @@ -8498,7 +8498,7 @@ perft 5 50382104 perft 6 1650202838 id 944 -epd brkbrnn1/pp1pppp1/7q/2p5/6Pp/4P1NP/PPPP1P2/BRKBR1NQ w EBeb - 2 9 +epd brkbrnn1/pp1pppp1/7q/2p5/6Pp/4P1NP/PPPP1P2/BRKBR1NQ w EBeb - perft 1 30 perft 2 978 perft 3 29593 @@ -8507,7 +8507,7 @@ perft 5 29205057 perft 6 936568065 id 945 -epd brkrnb1q/pp1p1ppp/2p1p3/5n2/1P6/5N1N/P1PPPPPP/BRKR1B1Q w DBdb - 1 9 +epd brkrnb1q/pp1p1ppp/2p1p3/5n2/1P6/5N1N/P1PPPPPP/BRKR1B1Q w DBdb - perft 1 31 perft 2 897 perft 3 27830 @@ -8516,7 +8516,7 @@ perft 5 25423729 perft 6 755334868 id 946 -epd brkr1nqb/pp1p1pp1/2pn3p/P3p3/4P3/6P1/1PPP1P1P/BRKRNNQB w DBdb - 0 9 +epd brkr1nqb/pp1p1pp1/2pn3p/P3p3/4P3/6P1/1PPP1P1P/BRKRNNQB w DBdb - perft 1 19 perft 2 382 perft 3 8052 @@ -8525,7 +8525,7 @@ perft 5 4232274 perft 6 103537333 id 947 -epd r1bkrn1q/ppbppppp/5n2/2p5/3P4/P6N/1PP1PPPP/RBBKRNQ1 w EAea - 3 9 +epd r1bkrn1q/ppbppppp/5n2/2p5/3P4/P6N/1PP1PPPP/RBBKRNQ1 w EAea - perft 1 27 perft 2 822 perft 3 22551 @@ -8534,7 +8534,7 @@ perft 5 19115128 perft 6 578210135 id 948 -epd rkbbrnnq/pp2pppp/8/2pp4/P1P5/1P3P2/3PP1PP/RKBBRNNQ w EAea - 1 9 +epd rkbbrnnq/pp2pppp/8/2pp4/P1P5/1P3P2/3PP1PP/RKBBRNNQ w EAea - perft 1 23 perft 2 643 perft 3 15410 @@ -8543,7 +8543,7 @@ perft 5 11170489 perft 6 329615708 id 949 -epd rkbr1b1q/p1pppppp/1p1n4/7n/5QP1/3N4/PPPPPP1P/RKBR1BN1 w DAda - 4 9 +epd rkbr1b1q/p1pppppp/1p1n4/7n/5QP1/3N4/PPPPPP1P/RKBR1BN1 w DAda - perft 1 37 perft 2 943 perft 3 34382 @@ -8552,7 +8552,7 @@ perft 5 31568111 perft 6 842265141 id 950 -epd rkbr1nqb/pppp2np/8/4ppp1/1P6/6N1/P1PPPPPP/RKBRN1QB w DAda - 1 9 +epd rkbr1nqb/pppp2np/8/4ppp1/1P6/6N1/P1PPPPPP/RKBRN1QB w DAda - perft 1 23 perft 2 574 perft 3 13260 @@ -8561,7 +8561,7 @@ perft 5 9020291 perft 6 261247606 id 951 -epd rbkr1nnq/p1p1pp1p/1p4p1/3p4/b3P3/4N3/PPPPNPPP/RBKRB1Q1 w DAda - 0 9 +epd rbkr1nnq/p1p1pp1p/1p4p1/3p4/b3P3/4N3/PPPPNPPP/RBKRB1Q1 w DAda - perft 1 26 perft 2 900 perft 3 23414 @@ -8570,7 +8570,7 @@ perft 5 21653203 perft 6 745802405 id 952 -epd rkrbb1nq/p2pppp1/1p4n1/2p4p/3N4/4P1P1/PPPP1P1P/RKRBBN1Q w CAca - 0 9 +epd rkrbb1nq/p2pppp1/1p4n1/2p4p/3N4/4P1P1/PPPP1P1P/RKRBBN1Q w CAca - perft 1 32 perft 2 697 perft 3 22231 @@ -8579,7 +8579,7 @@ perft 5 17150175 perft 6 441578567 id 953 -epd rkrnbb1q/pp2pp1p/6pn/2pp4/2B1P2P/8/PPPP1PP1/RKRNB1NQ w CAca - 0 9 +epd rkrnbb1q/pp2pp1p/6pn/2pp4/2B1P2P/8/PPPP1PP1/RKRNB1NQ w CAca - perft 1 28 perft 2 854 perft 3 23853 @@ -8588,7 +8588,7 @@ perft 5 21823412 perft 6 712787248 id 954 -epd rk2bnqb/pprpppp1/4n2p/2p5/P7/3P2NP/1PP1PPP1/RKRNB1QB w CAa - 1 9 +epd rk2bnqb/pprpppp1/4n2p/2p5/P7/3P2NP/1PP1PPP1/RKRNB1QB w CAa - perft 1 26 perft 2 596 perft 3 16251 @@ -8597,7 +8597,7 @@ perft 5 11758184 perft 6 323043654 id 955 -epd r1krnnbq/pp1ppp1p/6p1/2p5/2P5/P3P3/Rb1P1PPP/1BKRNNBQ w Dda - 0 9 +epd r1krnnbq/pp1ppp1p/6p1/2p5/2P5/P3P3/Rb1P1PPP/1BKRNNBQ w Dda - perft 1 2 perft 2 61 perft 3 1312 @@ -8606,7 +8606,7 @@ perft 5 937188 perft 6 28753562 id 956 -epd 1krbnnbq/1pp1p1pp/r7/p2p1p2/3PP3/2P3P1/PP3P1P/RKRBNNBQ w CAc - 0 9 +epd 1krbnnbq/1pp1p1pp/r7/p2p1p2/3PP3/2P3P1/PP3P1P/RKRBNNBQ w CAc - perft 1 30 perft 2 953 perft 3 28033 @@ -8615,7 +8615,7 @@ perft 5 25531358 perft 6 787205262 id 957 -epd rkr1nbbq/2ppp1pp/1pn5/p4p2/P6P/3P4/1PP1PPPB/RKRNNB1Q w CAca - 1 9 +epd rkr1nbbq/2ppp1pp/1pn5/p4p2/P6P/3P4/1PP1PPPB/RKRNNB1Q w CAca - perft 1 24 perft 2 645 perft 3 15689 @@ -8624,7 +8624,7 @@ perft 5 11484012 perft 6 341262639 id 958 -epd rkrnnqbb/p1ppp2p/Qp6/4Pp2/5p2/8/PPPP2PP/RKRNN1BB w CAca - 0 9 +epd rkrnnqbb/p1ppp2p/Qp6/4Pp2/5p2/8/PPPP2PP/RKRNN1BB w CAca - perft 1 35 perft 2 929 perft 3 32020 @@ -8633,7 +8633,7 @@ perft 5 31272517 perft 6 915268405 id 959 -epd bbq1nr1r/pppppk1p/2n2p2/6p1/P4P2/4P1P1/1PPP3P/BBQNNRKR w HF - 1 9 +epd bbq1nr1r/pppppk1p/2n2p2/6p1/P4P2/4P1P1/1PPP3P/BBQNNRKR w HF - perft 1 23 perft 2 589 perft 3 14744 From eaa6eb3b023e92441f9de810785bb1716dd4d0b5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 4 May 2024 18:03:34 +0200 Subject: [PATCH 1744/1831] Fixup invalid EPD in crazyhouse.perft file --- examples/perft/crazyhouse.perft | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/perft/crazyhouse.perft b/examples/perft/crazyhouse.perft index 42ccd68a6..ef07eac04 100644 --- a/examples/perft/crazyhouse.perft +++ b/examples/perft/crazyhouse.perft @@ -18,7 +18,7 @@ perft 3 58057 perft 4 2083382 id zh-promoted -epd 4k3/1Q~6/8/8/4b3/8/Kpp5/8/ b - - 0 1 +epd 4k3/1Q~6/8/8/4b3/8/Kpp5/8/ b - - perft 1 20 perft 2 360 perft 3 5445 From 122963b82e408417e2b4fd17643a61f42f4e9ae9 Mon Sep 17 00:00:00 2001 From: 3d12 <3d12@users.noreply.github.com> Date: Thu, 16 May 2024 20:09:41 -0500 Subject: [PATCH 1745/1831] Add rookognition --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 7a677a451..c80957a37 100644 --- a/README.rst +++ b/README.rst @@ -351,6 +351,7 @@ If you like, share interesting things you are using python-chess for, for exampl * a `browser based PGN viewer `_ written in PyScript – https://github.com/nmstoker/ChessMatchViewer * an accessible chessboard that allows blind and visually impaired players to play chess against Stockfish – https://github.com/blindpandas/chessmart * analyse games to extract various statistics – https://github.com/mvrozanti/chess-playground +* a web-based chess vision exercise – https://github.com/3d12/rookognition Prior art From 102542a3c07c74557038ced2086c0d9bbb813cf4 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 26 May 2024 03:46:30 -0700 Subject: [PATCH 1746/1831] Remove GameNodeComment class Changes PR to a simpler change that is not backwards compatible. --- chess/pgn.py | 196 +++++++++++---------------------------------------- test.py | 66 +++++++---------- 2 files changed, 65 insertions(+), 197 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index e462a0750..b40ce257c 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -130,6 +130,10 @@ def repl(match: typing.Match[str]) -> str: return repl +def _standardize_comments(comment: Union[str, list[str]]) -> list[str]: + return [] if not comment else [comment] if isinstance(comment, str) else comment + + TAG_ROSTER = ["Event", "Site", "Date", "Round", "White", "Black", "Result"] @@ -184,92 +188,6 @@ def __init__(self, node: ChildNode, *, is_variation: bool = False, sidelines: bo self.in_variation = False -class GameNodeComment: - """ - PGN Comment Storage - - A class that can hold one or more comments for a GameNode. - """ - - def __init__(self, comment: Union[str, list[str], GameNodeComment] = ""): - """Create a new comment.""" - self.set(comment._comments if isinstance(comment,GameNodeComment) else comment) - - def set(self, new_comment: Union[str, list[str]]) -> None: - """Replace the comment with a new comment or a list of comments.""" - self._comments = new_comment if isinstance(new_comment, list) else [new_comment] if new_comment else [] - - def pgn_format(self) -> str: - """Create a string representation of the comments in PGN format.""" - comments = map(lambda s: s.replace("{", ""), self._comments) - comments = map(lambda s: s.replace("}", "").strip(), comments) - return " ".join(f"{{ {comment} }}" for comment in comments if comment) - - def remove_empty(self) -> None: - """Remove empty comments from the comment list.""" - self._comments = list(filter(None, self._comments)) - - def append(self, new_comment: Union[str, list[str]]) -> None: - """Append one or more new comments to the end of the comment list.""" - if new_comment: - if isinstance(new_comment, str): - self._comments.append(new_comment) - else: - self._comments.extend(new_comment) - - def insert(self, index: int, new_comment: str) -> None: - """Insert a new comment before the specified index.""" - self._comments.insert(index, new_comment) - - def pop(self, index: int = -1) -> None: - """Delete comment at the given index (default is the last comment).""" - self._comments.pop(index) - - def __len__(self) -> int: - """Get the number of comments in this node.""" - return len(self._comments) - - def __getitem__(self, index: int) -> str: - """Get the comment at the given index.""" - return self._comments[index] - - def __setitem__(self, index: int, new_comment: str) -> None: - """Change the comment at the given index.""" - self._comments[index] = new_comment - - def __iter__(self) -> Iterator[str]: - """Return an iterator over all comments.""" - return iter(self._comments) - - def __add__(self, other: Union[str, list[str], GameNodeComment]) -> GameNodeComment: - """Create a new comment set by adding two comment sets with +.""" - if isinstance(other, GameNodeComment): - return GameNodeComment(self._comments + other._comments) - else: - new_node_comment = GameNodeComment(self._comments.copy()) - new_node_comment.append(other) - return new_node_comment - - def __eq__(self, other: object) -> bool: - """Check for equality between two comment sets.""" - if isinstance(other, str): - return (len(self) == 1 and self[0] == other) or (not self and not other) - elif isinstance(other, list): - return self._comments == other - elif isinstance(other, GameNodeComment): - return self._comments == other._comments - else: - return False - - def __repr__(self) -> str: - """Return a code-like representation of the class.""" - return f"{self.__class__.__name__}({self._comments})" - - def __str__(self) -> str: - """Return a string representation of the comments in PGN format.""" - return self.pgn_format() - - class GameNode(abc.ABC): parent: Optional[GameNode] """The parent node or ``None`` if this is the root node of the game.""" @@ -283,45 +201,13 @@ class GameNode(abc.ABC): variations: List[ChildNode] """A list of child nodes.""" - _comment: GameNodeComment + comments: list[str] """ A comment that goes behind the move leading to this node. Comments that occur before any moves are assigned to the root node. """ - @property - def comment(self) -> str: - return " ".join(self._comment) - - @comment.setter - def comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - self._comment = GameNodeComment(new_comment) - - @property - def comments(self) -> GameNodeComment: - return self._comment - - @comments.setter - def comments(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - self._comment = GameNodeComment(new_comment) - - _starting_comment: GameNodeComment - - @property - def starting_comment(self) -> str: - return " ".join(self._starting_comment) - - @starting_comment.setter - def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - self._starting_comment = GameNodeComment(new_comment) - - @property - def starting_comments(self) -> GameNodeComment: - return self._starting_comment - - @starting_comments.setter - def starting_comments(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - self._starting_comment = GameNodeComment(new_comment) + starting_comments: list[str] nags: Set[int] @@ -329,11 +215,11 @@ def __init__(self, *, comment: Union[str, list[str]] = "") -> None: self.parent = None self.move = None self.variations = [] - self.comments = GameNodeComment(comment) + self.comments = _standardize_comments(comment) # Deprecated: These should be properties of ChildNode, but need to # remain here for backwards compatibility. - self.starting_comments = GameNodeComment() + self.starting_comments = [] self.nags = set() @abc.abstractmethod @@ -549,7 +435,8 @@ def add_line(self, moves: Iterable[chess.Move], *, comment: Union[str, list[str] starting_comment = "" # Merge comment and NAGs. - node.comments.append(comment) + comments = _standardize_comments(comment) + node.comments.extend(comments) node.nags.update(nags) return node @@ -561,7 +448,7 @@ def eval(self) -> Optional[chess.engine.PovScore]: Complexity is `O(n)`. """ - match = EVAL_REGEX.search(self.comment) + match = EVAL_REGEX.search(" ".join(self.comments)) if not match: return None @@ -587,7 +474,7 @@ def eval_depth(self) -> Optional[int]: Complexity is `O(1)`. """ - match = EVAL_REGEX.search(self.comment) + match = EVAL_REGEX.search(" ".join(self.comments)) return int(match.group("depth")) if match and match.group("depth") else None def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] = None) -> None: @@ -610,7 +497,7 @@ def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] if found: break - self.comments.remove_empty() + self.comments = list(filter(None, self.comments)) if not found and eval: self.comments.append(eval) @@ -623,7 +510,7 @@ def arrows(self) -> List[chess.svg.Arrow]: Returns a list of :class:`arrows `. """ arrows = [] - for match in ARROWS_REGEX.finditer(self.comment): + for match in ARROWS_REGEX.finditer(" ".join(self.comments)): for group in match.group("arrows").split(","): arrows.append(chess.svg.Arrow.from_pgn(group)) @@ -648,7 +535,7 @@ def set_arrows(self, arrows: Iterable[Union[chess.svg.Arrow, Tuple[Square, Squar for index in range(len(self.comments)): self.comments[index] = ARROWS_REGEX.sub(_condense_affix(""), self.comments[index]) - self.comments.remove_empty() + self.comments = list(filter(None, self.comments)) prefix = "" if csl: @@ -667,7 +554,7 @@ def clock(self) -> Optional[float]: Returns the player's remaining time to the next time control after this move, in seconds. """ - match = CLOCK_REGEX.search(self.comment) + match = CLOCK_REGEX.search(" ".join(self.comments)) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -692,7 +579,7 @@ def set_clock(self, seconds: Optional[float]) -> None: if found: break - self.comments.remove_empty() + self.comments = list(filter(None, self.comments)) if not found and clk: self.comments.append(clk) @@ -705,7 +592,7 @@ def emt(self) -> Optional[float]: Returns the player's elapsed move time use for the comment of this move, in seconds. """ - match = EMT_REGEX.search(self.comment) + match = EMT_REGEX.search(" ".join(self.comments)) if match is None: return None return int(match.group("hours")) * 3600 + int(match.group("minutes")) * 60 + float(match.group("seconds")) @@ -730,7 +617,7 @@ def set_emt(self, seconds: Optional[float]) -> None: if found: break - self.comments.remove_empty() + self.comments = list(filter(None, self.comments)) if not found and emt: self.comments.append(emt) @@ -789,7 +676,7 @@ class ChildNode(GameNode): move: chess.Move """The move leading to this node.""" - _starting_comment: GameNodeComment + starting_comments: list[str] """ A comment for the start of a variation. Only nodes that actually start a variation (:func:`~chess.pgn.GameNode.starts_variation()` @@ -797,14 +684,6 @@ class ChildNode(GameNode): a starting comment. """ - @property - def starting_comment(self) -> str: - return " ".join(self._starting_comment) - - @starting_comment.setter - def starting_comment(self, new_comment: Union[str, list[str], GameNodeComment]) -> None: - self._starting_comment = GameNodeComment(new_comment) - nags: Set[int] """ A set of NAGs as integers. NAGs always go behind a move, so the root @@ -818,7 +697,7 @@ def __init__(self, parent: GameNode, move: chess.Move, *, comment: Union[str, li self.parent.variations.append(self) self.nags.update(nags) - self.starting_comments = GameNodeComment(starting_comment) + self.starting_comments = _standardize_comments(starting_comment) def board(self) -> chess.Board: stack: List[chess.Move] = [] @@ -874,7 +753,7 @@ def end(self) -> ChildNode: return typing.cast(ChildNode, super().end()) def _accept_node(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT]) -> None: - if self.starting_comment: + if self.starting_comments: visitor.visit_comment(self.starting_comments) visitor.visit_move(parent_board, self.move) @@ -1270,7 +1149,7 @@ def visit_board(self, board: chess.Board) -> None: """ pass - def visit_comment(self, comment: GameNodeComment) -> None: + def visit_comment(self, comment: list[str]) -> None: """Called for each comment.""" pass @@ -1324,7 +1203,7 @@ def begin_game(self) -> None: self.game: GameT = self.Game() self.variation_stack: List[GameNode] = [self.game] - self.starting_comment = GameNodeComment() + self.starting_comments: list[str] = [] self.in_variation = False def begin_headers(self) -> Headers: @@ -1349,24 +1228,23 @@ def visit_result(self, result: str) -> None: if self.game.headers.get("Result", "*") == "*": self.game.headers["Result"] = result - def visit_comment(self, comment: GameNodeComment) -> None: + def visit_comment(self, comment: Union[str, list[str]]) -> None: + comments = _standardize_comments(comment) if self.in_variation or (self.variation_stack[-1].parent is None and self.variation_stack[-1].is_end()): # Add as a comment for the current node if in the middle of # a variation. Add as a comment for the game if the comment # starts before any move. - new_comments = self.variation_stack[-1].comments + comment - new_comments.remove_empty() - self.variation_stack[-1].comments = new_comments + self.variation_stack[-1].comments.extend(comments) + self.variation_stack[-1].comments = list(filter(None, self.variation_stack[-1].comments)) else: # Otherwise, it is a starting comment. - new_comments = self.starting_comment + comment - new_comments.remove_empty() - self.starting_comment = new_comments + self.starting_comments.extend(comments) + self.starting_comments = list(filter(None, self.starting_comments)) def visit_move(self, board: chess.Board, move: chess.Move) -> None: self.variation_stack[-1] = self.variation_stack[-1].add_variation(move) - self.variation_stack[-1].starting_comments = self.starting_comment - self.starting_comment = GameNodeComment() + self.variation_stack[-1].starting_comments = self.starting_comments + self.starting_comments = [] self.in_variation = True def handle_error(self, error: Exception) -> None: @@ -1534,9 +1412,15 @@ def end_variation(self) -> None: self.write_token(") ") self.force_movenumber = True - def visit_comment(self, comment: GameNodeComment) -> None: + def visit_comment(self, comment: Union[str, list[str]]) -> None: if self.comments and (self.variations or not self.variation_depth): - self.write_token(comment.pgn_format() + " ") + def pgn_format(comments: list[str]) -> str: + comments = map(lambda s: s.replace("{", ""), comments) + comments = map(lambda s: s.replace("}", ""), comments) + return " ".join(f"{{ {comment} }}" for comment in comments if comment) + + comments = _standardize_comments(comment) + self.write_token(pgn_format(comments) + " ") self.force_movenumber = True def visit_nag(self, nag: int) -> None: diff --git a/test.py b/test.py index 4baf2dc58..92afd8de7 100755 --- a/test.py +++ b/test.py @@ -2083,29 +2083,29 @@ class PgnTestCase(unittest.TestCase): def test_exporter(self): game = chess.pgn.Game() - game.comment = "Test game:" + game.comments = ["Test game:"] game.headers["Result"] = "*" game.headers["VeryLongHeader"] = "This is a very long header, much wider than the 80 columns that PGNs are formatted with by default" e4 = game.add_variation(game.board().parse_san("e4")) - e4.comment = "Scandinavian Defense:" + e4.comments = ["Scandinavian Defense:"] e4_d5 = e4.add_variation(e4.board().parse_san("d5")) e4_h5 = e4.add_variation(e4.board().parse_san("h5")) e4_h5.nags.add(chess.pgn.NAG_MISTAKE) - e4_h5.starting_comment = "This" - e4_h5.comment = "is nonsense" + e4_h5.starting_comments = ["This"] + e4_h5.comments = ["is nonsense"] e4_e5 = e4.add_variation(e4.board().parse_san("e5")) e4_e5_Qf3 = e4_e5.add_variation(e4_e5.board().parse_san("Qf3")) e4_e5_Qf3.nags.add(chess.pgn.NAG_MISTAKE) e4_c5 = e4.add_variation(e4.board().parse_san("c5")) - e4_c5.comment = "Sicilian" + e4_c5.comments = ["Sicilian"] e4_d5_exd5 = e4_d5.add_main_variation(e4_d5.board().parse_san("exd5")) - e4_d5_exd5.comment = ["Best", "and the end of this example"] + e4_d5_exd5.comments = ["Best", "and the end of this example"] # Test string exporter with various options. exporter = chess.pgn.StringExporter(headers=False, comments=False, variations=False) @@ -2224,26 +2224,16 @@ def test_read_game_with_multicomment_move(self): pgn = io.StringIO("1. e4 {A common opening} 1... e5 {A common response} {An uncommon comment}") game = chess.pgn.read_game(pgn) first_move = game.variation(0) - self.assertEqual(first_move.comment, "A common opening") - self.assertEqual(first_move.comments, "A common opening") self.assertEqual(first_move.comments, ["A common opening"]) second_move = first_move.variation(0) self.assertEqual(second_move.comments, ["A common response", "An uncommon comment"]) second_move.comments.pop() self.assertEqual(second_move.comments, ["A common response"]) - self.assertEqual(second_move.comments, "A common response") - self.assertEqual(second_move.comment, "A common response") second_move.comments.append("A replaced comment") multiple_comments = ["A common response", "A replaced comment"] self.assertEqual(second_move.comments, multiple_comments) - for move_comment, test_comment in zip(second_move.comments, multiple_comments): - self.assertEqual(move_comment, test_comment) - self.assertEqual(list(second_move.comments), multiple_comments) - self.assertEqual(second_move.comment, " ".join(multiple_comments)) second_move.comments.pop(0) self.assertEqual(second_move.comments, ["A replaced comment"]) - self.assertEqual(second_move.comments, "A replaced comment") - self.assertEqual(second_move.comment, "A replaced comment") def test_comment_at_eol(self): pgn = io.StringIO(textwrap.dedent("""\ @@ -2259,7 +2249,7 @@ def test_comment_at_eol(self): # Make sure the comment for the second variation is there. self.assertIn(5, node[1].nags) - self.assertEqual(node[1].comment, "\n/\\ Ne7, c6") + self.assertEqual(node[1].comments, ["\n/\\ Ne7, c6"]) def test_promotion_without_equals(self): # Example game from https://github.com/rozim/ChessData as originally @@ -2347,12 +2337,12 @@ def test_variation_stack(self): def test_game_starting_comment(self): pgn = io.StringIO("{ Game starting comment } 1. d3") game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, "Game starting comment") + self.assertEqual(game.comments, ["Game starting comment"]) self.assertEqual(game[0].san(), "d3") pgn = io.StringIO("{ Empty game, but has a comment }") game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, "Empty game, but has a comment") + self.assertEqual(game.comments, ["Empty game, but has a comment"]) def test_game_starting_variation(self): pgn = io.StringIO(textwrap.dedent("""\ @@ -2360,17 +2350,17 @@ def test_game_starting_variation(self): """)) game = chess.pgn.read_game(pgn) - self.assertEqual(game.comment, "Start of game") + self.assertEqual(game.comments, ["Start of game"]) node = game[0] self.assertEqual(node.move, chess.Move.from_uci("e2e4")) - self.assertFalse(node.comment) - self.assertFalse(node.starting_comment) + self.assertFalse(node.comments) + self.assertFalse(node.starting_comments) node = game[1] self.assertEqual(node.move, chess.Move.from_uci("d2d4")) - self.assertFalse(node.comment) - self.assertEqual(node.starting_comment, "Start of variation") + self.assertFalse(node.comments) + self.assertEqual(node.starting_comments, ["Start of variation"]) def test_annotation_symbols(self): pgn = io.StringIO("1. b4?! g6 2. Bb2 Nc6? 3. Bxh8!!") @@ -2715,12 +2705,12 @@ def test_add_line(self): tail = game.add_line(moves, starting_comment="start", comment="end", nags=(17, 42)) self.assertEqual(tail.parent.move, chess.Move.from_uci("g1f3")) - self.assertEqual(tail.parent.starting_comment, "start") - self.assertEqual(tail.parent.comment, "") + self.assertEqual(tail.parent.starting_comments, ["start"]) + self.assertEqual(tail.parent.comments, []) self.assertEqual(len(tail.parent.nags), 0) self.assertEqual(tail.move, chess.Move.from_uci("d7d5")) - self.assertEqual(tail.comment, "end") + self.assertEqual(tail.comments, ["end"]) self.assertIn(42, tail.nags) def test_mainline(self): @@ -2850,12 +2840,11 @@ def test_recursion(self): def test_annotations(self): game = chess.pgn.Game() - game.comment = "foo [%bar] baz" + game.comments = ["foo [%bar] baz"] self.assertTrue(game.clock() is None) clock = 12345 game.set_clock(clock) - self.assertEqual(game.comment, "foo [%bar] baz [%clk 3:25:45]") self.assertEqual(game.comments, ["foo [%bar] baz", "[%clk 3:25:45]"]) self.assertEqual(game.clock(), clock) @@ -2872,7 +2861,6 @@ def test_annotations(self): self.assertEqual(game.arrows(), []) game.set_arrows([(chess.A1, chess.A1), chess.svg.Arrow(chess.A1, chess.H1, color="red"), chess.svg.Arrow(chess.B1, chess.B8)]) self.assertEqual(game.comments, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]"]) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5]") arrows = game.arrows() self.assertEqual(len(arrows), 3) self.assertEqual(arrows[0].color, "green") @@ -2883,21 +2871,17 @@ def test_annotations(self): emt = 321 game.set_emt(emt) self.assertEqual(game.comments, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%eval #1,5]", "[%emt 0:05:21]"]) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%eval #1,5] [%emt 0:05:21]") self.assertEqual(game.emt(), emt) game.set_eval(None) self.assertEqual(game.comments, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]", "[%emt 0:05:21]"]) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45] [%emt 0:05:21]") game.set_emt(None) self.assertEqual(game.comments, ["[%csl Ga1][%cal Ra1h1,Gb1b8]", "foo [%bar] baz", "[%clk 3:25:45]"]) - self.assertEqual(game.comment, "[%csl Ga1][%cal Ra1h1,Gb1b8] foo [%bar] baz [%clk 3:25:45]") game.set_clock(None) game.set_arrows([]) - self.assertEqual(game.comments, "foo [%bar] baz") - self.assertEqual(game.comment, "foo [%bar] baz") + self.assertEqual(game.comments, ["foo [%bar] baz"]) def test_eval(self): game = chess.pgn.Game() @@ -2907,28 +2891,28 @@ def test_eval(self): def test_float_emt(self): game = chess.pgn.Game() - game.comment = "[%emt 0:00:01.234]" + game.comments = ["[%emt 0:00:01.234]"] self.assertEqual(game.emt(), 1.234) game.set_emt(6.54321) - self.assertEqual(game.comment, "[%emt 0:00:06.543]") + self.assertEqual(game.comments, ["[%emt 0:00:06.543]"]) self.assertEqual(game.emt(), 6.543) game.set_emt(-70) - self.assertEqual(game.comment, "[%emt 0:00:00]") # Clamped + self.assertEqual(game.comments, ["[%emt 0:00:00]"]) # Clamped self.assertEqual(game.emt(), 0) def test_float_clk(self): game = chess.pgn.Game() - game.comment = "[%clk 0:00:01.234]" + game.comments = ["[%clk 0:00:01.234]"] self.assertEqual(game.clock(), 1.234) game.set_clock(6.54321) - self.assertEqual(game.comment, "[%clk 0:00:06.543]") + self.assertEqual(game.comments, ["[%clk 0:00:06.543]"]) self.assertEqual(game.clock(), 6.543) game.set_clock(-70) - self.assertEqual(game.comment, "[%clk 0:00:00]") # Clamped + self.assertEqual(game.comments, ["[%clk 0:00:00]"]) # Clamped self.assertEqual(game.clock(), 0) def test_node_turn(self): From 52dc00154d10c230c0aa6ce13299d7a0c825f19a Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 26 May 2024 15:04:05 -0700 Subject: [PATCH 1747/1831] Convert map return type to list --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index b40ce257c..b999d79a6 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1415,8 +1415,8 @@ def end_variation(self) -> None: def visit_comment(self, comment: Union[str, list[str]]) -> None: if self.comments and (self.variations or not self.variation_depth): def pgn_format(comments: list[str]) -> str: - comments = map(lambda s: s.replace("{", ""), comments) - comments = map(lambda s: s.replace("}", ""), comments) + comments = list(map(lambda s: s.replace("{", ""), comments)) + comments = list(map(lambda s: s.replace("}", ""), comments)) return " ".join(f"{{ {comment} }}" for comment in comments if comment) comments = _standardize_comments(comment) From 3b23452ee5728d1ec75e2cbf6f1c208e0416a9ee Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Sun, 26 May 2024 15:14:13 -0700 Subject: [PATCH 1748/1831] Remove tests of python list methods --- test.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test.py b/test.py index 92afd8de7..cf5439547 100755 --- a/test.py +++ b/test.py @@ -2227,13 +2227,6 @@ def test_read_game_with_multicomment_move(self): self.assertEqual(first_move.comments, ["A common opening"]) second_move = first_move.variation(0) self.assertEqual(second_move.comments, ["A common response", "An uncommon comment"]) - second_move.comments.pop() - self.assertEqual(second_move.comments, ["A common response"]) - second_move.comments.append("A replaced comment") - multiple_comments = ["A common response", "A replaced comment"] - self.assertEqual(second_move.comments, multiple_comments) - second_move.comments.pop(0) - self.assertEqual(second_move.comments, ["A replaced comment"]) def test_comment_at_eol(self): pgn = io.StringIO(textwrap.dedent("""\ From 3829d262c325b61b0004a314347f985008a9eb84 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 17 Jun 2024 21:18:43 +0200 Subject: [PATCH 1749/1831] Factor out Tablebase.add_file() --- chess/syzygy.py | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index e1fe07eb7..0c7d41500 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1511,27 +1511,23 @@ def add_directory(self, directory: str, *, load_wdl: bool = True, load_dtz: bool Returns the number of table files that were found. """ - num = 0 directory = os.path.abspath(directory) - - for filename in os.listdir(directory): - path = os.path.join(directory, filename) - tablename, ext = os.path.splitext(filename) - - if is_tablename(tablename, one_king=self.variant.one_king) and os.path.isfile(path): - if load_wdl: - if ext == self.variant.tbw_suffix: - num += self._open_table(self.wdl, WdlTable, path) - elif "P" not in tablename and ext == self.variant.pawnless_tbw_suffix: - num += self._open_table(self.wdl, WdlTable, path) - - if load_dtz: - if ext == self.variant.tbz_suffix: - num += self._open_table(self.dtz, DtzTable, path) - elif "P" not in tablename and ext == self.variant.pawnless_tbz_suffix: - num += self._open_table(self.dtz, DtzTable, path) - - return num + return sum(self.add_file(os.path.join(directory, filename), load_wdl=load_wdl, load_dtz=load_dtz) for filename in os.listdir(directory)) + + def add_file(self, path: str, *, load_wdl: bool = True, load_dtz: bool = True) -> int: + tablename, ext = os.path.splitext(os.path.basename(path)) + if is_tablename(tablename, one_king=self.variant.one_king) and os.path.isfile(path): + if load_wdl: + if ext == self.variant.tbw_suffix: + return self._open_table(self.wdl, WdlTable, path) + elif "P" not in tablename and ext == self.variant.pawnless_tbw_suffix: + return self._open_table(self.wdl, WdlTable, path) + if load_dtz: + if ext == self.variant.tbz_suffix: + return self._open_table(self.dtz, DtzTable, path) + elif "P" not in tablename and ext == self.variant.pawnless_tbz_suffix: + return self._open_table(self.dtz, DtzTable, path) + return 0 def probe_wdl_table(self, board: chess.Board) -> int: # Test for variant end. From a41c3c88022fd97ab0eaf7b032a3158b69628b66 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 4 Jul 2024 16:41:19 +0200 Subject: [PATCH 1750/1831] Do not eagerly check syzygy max pieces (fixes #1093) --- chess/syzygy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 0c7d41500..807b0922e 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1546,6 +1546,8 @@ def probe_wdl_table(self, board: chess.Board) -> int: try: table = typing.cast(WdlTable, self.wdl[key]) except KeyError: + if chess.popcount(board.occupied) > TBPIECES: + raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {chess.popcount(board.occupied)}: {board.fen()}") raise MissingTableError(f"did not find wdl table {key}") self._bump_lru(table) @@ -1558,8 +1560,6 @@ def probe_ab(self, board: chess.Board, alpha: int, beta: int, threats: bool = Fa raise KeyError(f"tablebase has been opened for {self.variant.uci_variant}, probed with: {board.uci_variant}") if board.castling_rights: raise KeyError(f"syzygy tables do not contain positions with castling rights: {board.fen()}") - if chess.popcount(board.occupied) > TBPIECES: - raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {chess.popcount(board.occupied)}: {board.fen()}") # Special case: Variant with compulsory captures. if self.variant.captures_compulsory: From 95803fc64a89307bfe51910f9e9349d120b81705 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 4 Jul 2024 20:58:32 +0200 Subject: [PATCH 1751/1831] Artificially limit syzygy ab search after relaxing bound --- chess/syzygy.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/chess/syzygy.py b/chess/syzygy.py index 807b0922e..8ba1cbca4 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1561,6 +1561,13 @@ def probe_ab(self, board: chess.Board, alpha: int, beta: int, threats: bool = Fa if board.castling_rights: raise KeyError(f"syzygy tables do not contain positions with castling rights: {board.fen()}") + # Probing resolves captures, so sometimes we can obtain results for + # positions that have more pieces than the maximum number of supported + # pieces. We artificially limit this to one additional level, to + # make sure search remains somewhat bounded. + if chess.popcount(board.occupied) > TBPIECES + 1: + raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {chess.popcount(board.occupied)}: {board.fen()}") + # Special case: Variant with compulsory captures. if self.variant.captures_compulsory: if board.is_variant_win(): From 474c87bfcccb8e2aa78a4a94414af3b747340f31 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 10 Jul 2024 18:02:09 +0200 Subject: [PATCH 1752/1831] Add another SAN disambiguation test (niklasf/shakmaty#77) --- test.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test.py b/test.py index 4ca3be6c2..00d766a03 100755 --- a/test.py +++ b/test.py @@ -703,6 +703,11 @@ def test_san(self): self.assertEqual(board.san(chess.Move.from_uci("h4g6")), "Nh4g6") self.assertEqual(board.fen(), fen) + # Test a bug where shakmaty used overly specific disambiguation. + fen = "8/2KN1p2/5p2/3N1B1k/5PNp/7P/7P/8 w - -" + board = chess.Board(fen) + self.assertEqual(board.san(chess.Move.from_uci("d5f6")), "N5xf6#") + # Do not disambiguate illegal alternatives. fen = "8/8/8/R2nkn2/8/8/2K5/8 b - - 0 1" board = chess.Board(fen) From ec8ecec5c0277691ec76041e82bf13140f7f719a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Thu, 11 Jul 2024 16:03:22 +0200 Subject: [PATCH 1753/1831] chess-playground discontinued --- README.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/README.rst b/README.rst index c80957a37..a6c3185c6 100644 --- a/README.rst +++ b/README.rst @@ -350,7 +350,6 @@ If you like, share interesting things you are using python-chess for, for exampl * Django Rest Framework API for multiplayer chess – https://github.com/WorkShoft/capablanca-api * a `browser based PGN viewer `_ written in PyScript – https://github.com/nmstoker/ChessMatchViewer * an accessible chessboard that allows blind and visually impaired players to play chess against Stockfish – https://github.com/blindpandas/chessmart -* analyse games to extract various statistics – https://github.com/mvrozanti/chess-playground * a web-based chess vision exercise – https://github.com/3d12/rookognition From 63aac2ec65860a64256a190220b793e80b132b50 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 19 Jul 2024 16:31:22 +0200 Subject: [PATCH 1754/1831] Expose optional occupied parameter for attackers_mask (#1090) --- chess/__init__.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index bed9eec5d..a90df9ef6 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -902,7 +902,9 @@ def attacks(self, square: Square) -> SquareSet: """ return SquareSet(self.attacks_mask(square)) - def _attackers_mask(self, color: Color, square: Square, occupied: Bitboard) -> Bitboard: + def attackers_mask(self, color: Color, square: Square, occupied: Optional[Bitboard] = None) -> Bitboard: + occupied = self.occupied if occupied is None else occupied + rank_pieces = BB_RANK_MASKS[square] & occupied file_pieces = BB_FILE_MASKS[square] & occupied diag_pieces = BB_DIAG_MASKS[square] & occupied @@ -920,27 +922,38 @@ def _attackers_mask(self, color: Color, square: Square, occupied: Bitboard) -> B return attackers & self.occupied_co[color] - def attackers_mask(self, color: Color, square: Square) -> Bitboard: - return self._attackers_mask(color, square, self.occupied) - - def is_attacked_by(self, color: Color, square: Square) -> bool: + def is_attacked_by(self, color: Color, square: Square, occupied: Optional[IntoSquareSet] = None) -> bool: """ Checks if the given side attacks the given square. Pinned pieces still count as attackers. Pawns that can be captured en passant are **not** considered attacked. + + *occupied* determines which squares are considered to block attacks. + For example, + ``board.occupied ^ board.pieces_mask(chess.KING, board.turn)`` can be + used to consider X-ray attacks through the king. + Defaults to ``board.occupied`` (all pieces including the king, + no X-ray attacks). """ - return bool(self.attackers_mask(color, square)) + return bool(self.attackers_mask(color, square, None if occupied is None else SquareSet(occupied).mask)) - def attackers(self, color: Color, square: Square) -> SquareSet: + def attackers(self, color: Color, square: Square, occupied: Optional[IntoSquareSet] = None) -> SquareSet: """ Gets the set of attackers of the given color for the given square. Pinned pieces still count as attackers. + *occupied* determines which squares are considered to block attacks. + For example, + ``board.occupied ^ board.pieces_mask(chess.KING, board.turn)`` can be + used to consider X-ray attacks through the king. + Defaults to ``board.occupied`` (all pieces including the king, + no X-ray attacks). + Returns a :class:`set of squares `. """ - return SquareSet(self.attackers_mask(color, square)) + return SquareSet(self.attackers_mask(color, square, None if occupied is None else SquareSet(occupied).mask)) def pin_mask(self, color: Color, square: Square) -> Bitboard: king = self.king(color) @@ -3723,7 +3736,7 @@ def generate_legal_captures(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboar self.generate_legal_ep(from_mask, to_mask)) def _attacked_for_king(self, path: Bitboard, occupied: Bitboard) -> bool: - return any(self._attackers_mask(not self.turn, sq, occupied) for sq in scan_reversed(path)) + return any(self.attackers_mask(not self.turn, sq, occupied) for sq in scan_reversed(path)) def generate_castling_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]: if self.is_variant_end(): From 7836d446bf0cfc3b265e038fa381a7e52a543c41 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 19 Jul 2024 16:41:25 +0200 Subject: [PATCH 1755/1831] Add chess.svg.SvgWrapper._repr_html_() (closes #1096) --- chess/svg.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chess/svg.py b/chess/svg.py index d3d19e89e..2948b0b80 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -144,6 +144,9 @@ class SvgWrapper(str): def _repr_svg_(self) -> SvgWrapper: return self + def _repr_html_(self) -> SvgWrapper: + return self + def _svg(viewbox: int, size: Optional[int]) -> ET.Element: svg = ET.Element("svg", { From 247d8a06a6b2c2dc06f9ce0b7f3e94dbd9b816bd Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 19 Jul 2024 17:27:12 +0200 Subject: [PATCH 1756/1831] Update changelog for soon to be released final 1.x --- CHANGELOG.rst | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0fa76effa..a4534badb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,9 +6,26 @@ Upcoming in the next release Changes: -* Dropped support for Python 3.7, which had reached its end of life. -* `chess.engine.EventLoopPolicy` is no longer needed and now merely an alias +* Drop support for Python 3.7, which has reached its end of life. +* ``chess.engine.EventLoopPolicy`` is no longer needed and now merely an alias for the default event loop policy. +* If available and requested via ``setpgrp``, use ``process_group`` support + from Python 3.11 for engine processes. +* No longer eagerly reject 8 piece positions in ``chess.syzygy``, so that + some 8 piece positions with decisive captures can be probed successfully. +* The string wrapper returned by ``chess.svg`` functions now also implements + ``_repr_html_``. + +New features: + +* Add ``chess.pgn.Game.time_control()`` and related data models. +* Add model ``sf16.1`` for ``chess.engine.Score.wdl()``, the new default. + +Bugfixes: + +* Fix handling of whitespace in UCI engine communication. +* For ``chess.Board.epd()`` and ``chess.Board.set_epd()``, require that EPD + opcodes start with a letter. New in v1.10.0 (27th Jul 2023) ------------------------------ From c7199a6354fe3053235c8ad88d79714afccdc0b9 Mon Sep 17 00:00:00 2001 From: Deepyaman Datta Date: Sun, 21 Jul 2024 22:42:48 -0600 Subject: [PATCH 1757/1831] Update default time control from UNKNOW to UNKNOWN --- chess/pgn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 55eddbc29..0d0879ae0 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -143,7 +143,7 @@ class SkipType(enum.Enum): class TimeControlType(enum.Enum): - UNKNOW = 0 + UNKNOWN = 0 UNLIMITED = 1 STANDARD = 2 RAPID = 3 @@ -172,7 +172,7 @@ class TimeControl: """ parts: list[TimeControlPart] = dataclasses.field(default_factory=list) - type: TimeControlType = TimeControlType.UNKNOW + type: TimeControlType = TimeControlType.UNKNOWN class _AcceptFrame: From ad6f756c4406d66a59a9cd1050f50137de84dc30 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 31 Jul 2024 00:04:57 -0700 Subject: [PATCH 1758/1831] Factor out repeated annotation editing code --- chess/pgn.py | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index b999d79a6..b8cfbe440 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -491,16 +491,7 @@ def set_eval(self, score: Optional[chess.engine.PovScore], depth: Optional[int] elif score.white().mate(): eval = f"[%eval #{score.white().mate()}{depth_suffix}]" - found = 0 - for index in range(len(self.comments)): - self.comments[index], found = EVAL_REGEX.subn(_condense_affix(eval), self.comments[index], count=1) - if found: - break - - self.comments = list(filter(None, self.comments)) - - if not found and eval: - self.comments.append(eval) + self._replace_or_add_annotation(eval, EVAL_REGEX) def arrows(self) -> List[chess.svg.Arrow]: """ @@ -573,16 +564,7 @@ def set_clock(self, seconds: Optional[float]) -> None: seconds_part = f"{seconds:06.3f}".rstrip("0").rstrip(".") clk = f"[%clk {hours:d}:{minutes:02d}:{seconds_part}]" - found = 0 - for index in range(len(self.comments)): - self.comments[index], found = CLOCK_REGEX.subn(_condense_affix(clk), self.comments[index], count=1) - if found: - break - - self.comments = list(filter(None, self.comments)) - - if not found and clk: - self.comments.append(clk) + self._replace_or_add_annotation(clk, CLOCK_REGEX) def emt(self) -> Optional[float]: """ @@ -611,16 +593,19 @@ def set_emt(self, seconds: Optional[float]) -> None: seconds_part = f"{seconds:06.3f}".rstrip("0").rstrip(".") emt = f"[%emt {hours:d}:{minutes:02d}:{seconds_part}]" + self._replace_or_add_annotation(emt, EMT_REGEX) + + def _replace_or_add_annotation(self, text: str, regex: re.Pattern[str]) -> None: found = 0 for index in range(len(self.comments)): - self.comments[index], found = EMT_REGEX.subn(_condense_affix(emt), self.comments[index], count=1) + self.comments[index], found = regex.subn(_condense_affix(text), self.comments[index], count=1) if found: break self.comments = list(filter(None, self.comments)) - if not found and emt: - self.comments.append(emt) + if not found and text: + self.comments.append(text) @abc.abstractmethod def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: From 744d2fcae0b2c9d26007648099094b05475bb5cc Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 31 Jul 2024 00:48:02 -0700 Subject: [PATCH 1759/1831] Lazily remove curly braces from comments --- chess/pgn.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index c7d4a87a3..3acf66401 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1400,9 +1400,8 @@ def end_variation(self) -> None: def visit_comment(self, comment: Union[str, list[str]]) -> None: if self.comments and (self.variations or not self.variation_depth): def pgn_format(comments: list[str]) -> str: - comments = list(map(lambda s: s.replace("{", ""), comments)) - comments = list(map(lambda s: s.replace("}", ""), comments)) - return " ".join(f"{{ {comment} }}" for comment in comments if comment) + edit = map(lambda s: s.replace("{", "").replace("}", ""), comments) + return " ".join(f"{{ {comment} }}" for comment in edit if comment) comments = _standardize_comments(comment) self.write_token(pgn_format(comments) + " ") From dce369c6388805b5ac51c8b9b765e4da33f09795 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Wed, 31 Jul 2024 00:48:28 -0700 Subject: [PATCH 1760/1831] Add test for removing curly braces from comments --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 23ecab2fc..2a4f551ea 100755 --- a/test.py +++ b/test.py @@ -2110,7 +2110,7 @@ def test_exporter(self): e4_c5.comments = ["Sicilian"] e4_d5_exd5 = e4_d5.add_main_variation(e4_d5.board().parse_san("exd5")) - e4_d5_exd5.comments = ["Best", "and the end of this example"] + e4_d5_exd5.comments = ["Best", "and the end of this {example}"] # Test string exporter with various options. exporter = chess.pgn.StringExporter(headers=False, comments=False, variations=False) From dda9e8fedc75eefb0255245abff0782ecb26f882 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 15:09:53 +0200 Subject: [PATCH 1761/1831] Refactor chess.engine.BaseCommand to pass stricter type checking --- chess/engine.py | 614 +++++++++++++++++++++++++++--------------------- 1 file changed, 344 insertions(+), 270 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index c2b470dd5..d1bbaaee1 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -24,6 +24,9 @@ from types import TracebackType from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Optional, Tuple, Type, TypedDict, TypeVar, Union +if typing.TYPE_CHECKING: + from typing_extensions import Self + WdlModel = Literal["sf", "sf16.1", "sf16", "sf15.1", "sf15", "sf14", "sf12", "lichess"] @@ -895,7 +898,7 @@ class Protocol(asyncio.SubprocessProtocol, metaclass=abc.ABCMeta): returncode: asyncio.Future[int] """Future: Exit code of the process.""" - def __init__(self: ProtocolT) -> None: + def __init__(self) -> None: self.loop = asyncio.get_running_loop() self.transport: Optional[asyncio.SubprocessTransport] = None @@ -904,8 +907,8 @@ def __init__(self: ProtocolT) -> None: 2: bytearray(), # stderr } - self.command: Optional[BaseCommand[ProtocolT, Any]] = None - self.next_command: Optional[BaseCommand[ProtocolT, Any]] = None + self.command: Optional[BaseCommand[Any]] = None + self.next_command: Optional[BaseCommand[Any]] = None self.initialized = False self.returncode: asyncio.Future[int] = asyncio.Future() @@ -915,7 +918,7 @@ def connection_made(self, transport: asyncio.BaseTransport) -> None: self.transport = transport # type: ignore LOGGER.debug("%s: Connection made", self) - def connection_lost(self: ProtocolT, exc: Optional[Exception]) -> None: + def connection_lost(self, exc: Optional[Exception]) -> None: assert self.transport is not None code = self.transport.get_returncode() assert code is not None, "connect lost, but got no returncode" @@ -923,10 +926,10 @@ def connection_lost(self: ProtocolT, exc: Optional[Exception]) -> None: # Terminate commands. if self.command is not None: - self.command._engine_terminated(self, code) + self.command._engine_terminated(code) self.command = None if self.next_command is not None: - self.next_command._engine_terminated(self, code) + self.next_command._engine_terminated(code) self.next_command = None self.returncode.set_result(code) @@ -960,18 +963,18 @@ def pipe_data_received(self, fd: int, data: Union[bytes, str]) -> None: def error_line_received(self, line: str) -> None: LOGGER.warning("%s: stderr >> %s", self, line) - def _line_received(self: ProtocolT, line: str) -> None: + def _line_received(self: Protocol, line: str) -> None: LOGGER.debug("%s: >> %s", self, line) self.line_received(line) if self.command: - self.command._line_received(self, line) + self.command._line_received(line) def line_received(self, line: str) -> None: pass - async def communicate(self: ProtocolT, command_factory: Callable[[ProtocolT], BaseCommand[ProtocolT, T]]) -> T: + async def communicate(self, command_factory: Callable[[Self], BaseCommand[T]]) -> T: command = command_factory(self) if self.returncode.done(): @@ -993,18 +996,18 @@ def previous_command_finished(_: Optional[asyncio.Future[None]]) -> None: def cancel_if_cancelled(result: asyncio.Future[T]) -> None: if result.cancelled(): - cmd._cancel(self) + cmd._cancel() cmd.result.add_done_callback(cancel_if_cancelled) cmd.finished.add_done_callback(previous_command_finished) - cmd._start(self) + cmd._start() if self.command is None: previous_command_finished(None) elif not self.command.result.done(): self.command.result.cancel() elif not self.command.result.cancelled(): - self.command._cancel(self) + self.command._cancel() return await command.result @@ -1207,32 +1210,34 @@ class CommandState(enum.Enum): DONE = enum.auto() -class BaseCommand(Generic[ProtocolT, T]): - def __init__(self, engine: ProtocolT) -> None: +class BaseCommand(Generic[T]): + def __init__(self, engine: Protocol) -> None: + self._engine = engine + self.state = CommandState.NEW self.result: asyncio.Future[T] = asyncio.Future() self.finished: asyncio.Future[None] = asyncio.Future() - def _engine_terminated(self, engine: ProtocolT, code: int) -> None: + def _engine_terminated(self, code: int) -> None: hint = ", binary not compatible with cpu?" if code in [-4, 0xc000001d] else "" exc = EngineTerminatedError(f"engine process died unexpectedly (exit code: {code}{hint})") if self.state == CommandState.ACTIVE: - self.engine_terminated(engine, exc) + self.engine_terminated(exc) elif self.state == CommandState.CANCELLING: self.finished.set_result(None) elif self.state == CommandState.NEW: - self._handle_exception(engine, exc) + self._handle_exception(exc) - def _handle_exception(self, engine: ProtocolT, exc: Exception) -> None: + def _handle_exception(self, exc: Exception) -> None: if not self.result.done(): self.result.set_exception(exc) else: - engine.loop.call_exception_handler({ + self._engine.loop.call_exception_handler({ # XXX "message": f"{type(self).__name__} failed after returning preliminary result ({self.result!r})", "exception": exc, - "protocol": engine, - "transport": engine.transport, + "protocol": self._engine, + "transport": self._engine.transport, }) if not self.finished.done(): @@ -1245,43 +1250,43 @@ def set_finished(self) -> None: self.finished.set_result(None) self.state = CommandState.DONE - def _cancel(self, engine: ProtocolT) -> None: + def _cancel(self) -> None: if self.state != CommandState.CANCELLING and self.state != CommandState.DONE: assert self.state == CommandState.ACTIVE self.state = CommandState.CANCELLING - self.cancel(engine) + self.cancel() - def _start(self, engine: ProtocolT) -> None: + def _start(self) -> None: assert self.state == CommandState.NEW self.state = CommandState.ACTIVE try: - self.check_initialized(engine) - self.start(engine) + self.check_initialized() + self.start() except EngineError as err: - self._handle_exception(engine, err) + self._handle_exception(err) - def _line_received(self, engine: ProtocolT, line: str) -> None: + def _line_received(self, line: str) -> None: assert self.state in [CommandState.ACTIVE, CommandState.CANCELLING] try: - self.line_received(engine, line) + self.line_received(line) except EngineError as err: - self._handle_exception(engine, err) + self._handle_exception(err) - def cancel(self, engine: ProtocolT) -> None: + def cancel(self) -> None: pass - def check_initialized(self, engine: ProtocolT) -> None: - if not engine.initialized: + def check_initialized(self) -> None: + if not self._engine.initialized: raise EngineError("tried to run command, but engine is not initialized") - def start(self, engine: ProtocolT) -> None: + def start(self) -> None: raise NotImplementedError - def line_received(self, engine: ProtocolT, line: str) -> None: + def line_received(self, line: str) -> None: pass - def engine_terminated(self, engine: ProtocolT, exc: Exception) -> None: - self._handle_exception(engine, exc) + def engine_terminated(self, exc: Exception) -> None: + self._handle_exception(exc) def __repr__(self) -> str: return "<{} at {:#x} (state={}, result={}, finished={}>".format(type(self).__name__, id(self), self.state, self.result, self.finished) @@ -1307,26 +1312,33 @@ def __init__(self) -> None: self.ponderhit = False async def initialize(self) -> None: - class UciInitializeCommand(BaseCommand[UciProtocol, None]): - def check_initialized(self, engine: UciProtocol) -> None: - if engine.initialized: + class UciInitializeCommand(BaseCommand[None]): + def __init__(self, engine: UciProtocol): + super().__init__(engine) + self.engine = engine + + @typing.override + def check_initialized(self) -> None: + if self.engine.initialized: raise EngineError("engine already initialized") - def start(self, engine: UciProtocol) -> None: - engine.send_line("uci") + @typing.override + def start(self) -> None: + self.engine.send_line("uci") - def line_received(self, engine: UciProtocol, line: str) -> None: + @typing.override + def line_received(self, line: str) -> None: token, remaining = _next_token(line) if line.strip() == "uciok" and not self.result.done(): - engine.initialized = True + self.engine.initialized = True self.result.set_result(None) self.set_finished() elif token == "option": - self._option(engine, remaining) + self._option(remaining) elif token == "id": - self._id(engine, remaining) + self._id(remaining) - def _option(self, engine: UciProtocol, arg: str) -> None: + def _option(self, arg: str) -> None: current_parameter = None option_parts: dict[str, str] = {k: "" for k in ["name", "type", "default", "min", "max"]} var = [] @@ -1357,16 +1369,16 @@ def parse_min_max_value(option_parts: dict[str, str], which: Literal["min", "max without_default = Option(name, type, None, min, max, var) option = Option(without_default.name, without_default.type, without_default.parse(default), min, max, var) - engine.options[option.name] = option + self.engine.options[option.name] = option if option.default is not None: - engine.config[option.name] = option.default + self.engine.config[option.name] = option.default if option.default is not None and not option.is_managed() and option.name.lower() != "uci_analysemode": - engine.target_config[option.name] = option.default + self.engine.target_config[option.name] = option.default - def _id(self, engine: UciProtocol, arg: str) -> None: + def _id(self, arg: str) -> None: key, value = _next_token(arg) - engine.id[key] = value.strip() + self.engine.id[key] = value.strip() return await self.communicate(UciInitializeCommand) @@ -1395,16 +1407,21 @@ def debug(self, on: bool = True) -> None: self.send_line("debug off") async def ping(self) -> None: - class UciPingCommand(BaseCommand[UciProtocol, None]): - def start(self, engine: UciProtocol) -> None: - engine._isready() + class UciPingCommand(BaseCommand[None]): + def __init__(self, engine: UciProtocol) -> None: + super().__init__(engine) + self.engine = engine - def line_received(self, engine: UciProtocol, line: str) -> None: + def start(self) -> None: + self.engine._isready() + + @typing.override + def line_received(self, line: str) -> None: if line.strip() == "readyok": self.result.set_result(None) self.set_finished() else: - LOGGER.warning("%s: Unexpected engine output: %r", engine, line) + LOGGER.warning("%s: Unexpected engine output: %r", self.engine, line) return await self.communicate(UciPingCommand) @@ -1438,10 +1455,14 @@ def _configure(self, options: ConfigMapping) -> None: self._setoption(name, value) async def configure(self, options: ConfigMapping) -> None: - class UciConfigureCommand(BaseCommand[UciProtocol, None]): - def start(self, engine: UciProtocol) -> None: - engine._configure(options) - engine.target_config.update({name: value for name, value in options.items() if value is not None}) + class UciConfigureCommand(BaseCommand[None]): + def __init__(self, engine: UciProtocol): + super().__init__(engine) + self.engine = engine + + def start(self) -> None: + self.engine._configure(options) + self.engine.target_config.update({name: value for name, value in options.items() if value is not None}) self.result.set_result(None) self.set_finished() @@ -1541,77 +1562,82 @@ async def play(self, board: chess.Board, limit: Limit, *, game: object = None, i new_options[name] = value new_options.update(self._opponent_configuration(opponent=opponent)) - class UciPlayCommand(BaseCommand[UciProtocol, PlayResult]): + engine = self + + class UciPlayCommand(BaseCommand[PlayResult]): def __init__(self, engine: UciProtocol): super().__init__(engine) + self.engine = engine # May ponderhit only in the same game and with unchanged target # options. The managed options UCI_AnalyseMode, Ponder, and # MultiPV never change between pondering play commands. engine.may_ponderhit = board if ponder and not engine.first_game and game == engine.game and not engine._changed_options(new_options) else None - def start(self, engine: UciProtocol) -> None: + @typing.override + def start(self) -> None: self.info: InfoDict = {} self.pondering: Optional[chess.Board] = None self.sent_isready = False self.start_time = time.perf_counter() - if engine.ponderhit: - engine.ponderhit = False - engine.send_line("ponderhit") + if self.engine.ponderhit: + self.engine.ponderhit = False + self.engine.send_line("ponderhit") return - if "UCI_AnalyseMode" in engine.options and "UCI_AnalyseMode" not in engine.target_config and all(name.lower() != "uci_analysemode" for name in new_options): - engine._setoption("UCI_AnalyseMode", False) - if "Ponder" in engine.options: - engine._setoption("Ponder", ponder) - if "MultiPV" in engine.options: - engine._setoption("MultiPV", engine.options["MultiPV"].default) + if "UCI_AnalyseMode" in self.engine.options and "UCI_AnalyseMode" not in self.engine.target_config and all(name.lower() != "uci_analysemode" for name in new_options): + self.engine._setoption("UCI_AnalyseMode", False) + if "Ponder" in self.engine.options: + self.engine._setoption("Ponder", ponder) + if "MultiPV" in self.engine.options: + self.engine._setoption("MultiPV", self.engine.options["MultiPV"].default) - new_opponent = new_options.get("UCI_Opponent") or engine.target_config.get("UCI_Opponent") - opponent_changed = new_opponent != engine.config.get("UCI_Opponent") - engine._configure(new_options) + new_opponent = new_options.get("UCI_Opponent") or self.engine.target_config.get("UCI_Opponent") + opponent_changed = new_opponent != self.engine.config.get("UCI_Opponent") + self.engine._configure(new_options) - if engine.first_game or engine.game != game or opponent_changed: - engine.game = game - engine._ucinewgame() + if self.engine.first_game or self.engine.game != game or opponent_changed: + self.engine.game = game + self.engine._ucinewgame() self.sent_isready = True - engine._isready() + self.engine._isready() else: - self._readyok(engine) + self._readyok() - def line_received(self, engine: UciProtocol, line: str) -> None: + @typing.override + def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token == "info": - self._info(engine, remaining) + self._info(remaining) elif token == "bestmove": - self._bestmove(engine, remaining) + self._bestmove(remaining) elif line.strip() == "readyok" and self.sent_isready: - self._readyok(engine) + self._readyok() else: - LOGGER.warning("%s: Unexpected engine output: %r", engine, line) + LOGGER.warning("%s: Unexpected engine output: %r", self.engine, line) - def _readyok(self, engine: UciProtocol) -> None: + def _readyok(self) -> None: self.sent_isready = False engine._position(board) engine._go(limit, root_moves=root_moves) - def _info(self, engine: UciProtocol, arg: str) -> None: + def _info(self, arg: str) -> None: if not self.pondering: - self.info.update(_parse_uci_info(arg, engine.board, info)) + self.info.update(_parse_uci_info(arg, self.engine.board, info)) - def _bestmove(self, engine: UciProtocol, arg: str) -> None: + def _bestmove(self, arg: str) -> None: if self.pondering: self.pondering = None elif not self.result.cancelled(): - best = _parse_uci_bestmove(engine.board, arg) + best = _parse_uci_bestmove(self.engine.board, arg) self.result.set_result(PlayResult(best.move, best.ponder, self.info)) if ponder and best.move and best.ponder: self.pondering = board.copy() self.pondering.push(best.move) self.pondering.push(best.ponder) - engine._position(self.pondering) + self.engine._position(self.pondering) # Adjust clocks for pondering. time_used = time.perf_counter() - self.start_time @@ -1627,89 +1653,98 @@ def _bestmove(self, engine: UciProtocol, arg: str) -> None: if ponder_limit.remaining_moves: ponder_limit.remaining_moves -= 1 - engine._go(ponder_limit, ponder=True) + self.engine._go(ponder_limit, ponder=True) if not self.pondering: - self.end(engine) + self.end() - def end(self, engine: UciProtocol) -> None: + def end(self) -> None: engine.may_ponderhit = None self.set_finished() - def cancel(self, engine: UciProtocol) -> None: - if engine.may_ponderhit and self.pondering and engine.may_ponderhit.move_stack == self.pondering.move_stack and engine.may_ponderhit == self.pondering: - engine.ponderhit = True - self.end(engine) + @typing.override + def cancel(self) -> None: + if self.engine.may_ponderhit and self.pondering and self.engine.may_ponderhit.move_stack == self.pondering.move_stack and self.engine.may_ponderhit == self.pondering: + self.engine.ponderhit = True + self.end() else: - engine.send_line("stop") + self.engine.send_line("stop") - def engine_terminated(self, engine: UciProtocol, exc: Exception) -> None: + @typing.override + def engine_terminated(self, exc: Exception) -> None: # Allow terminating engine while pondering. if not self.result.done(): - super().engine_terminated(engine, exc) + super().engine_terminated(exc) return await self.communicate(UciPlayCommand) async def analysis(self, board: chess.Board, limit: Optional[Limit] = None, *, multipv: Optional[int] = None, game: object = None, info: Info = INFO_ALL, root_moves: Optional[Iterable[chess.Move]] = None, options: ConfigMapping = {}) -> AnalysisResult: - class UciAnalysisCommand(BaseCommand[UciProtocol, AnalysisResult]): - def start(self, engine: UciProtocol) -> None: - self.analysis = AnalysisResult(stop=lambda: self.cancel(engine)) + class UciAnalysisCommand(BaseCommand[AnalysisResult]): + def __init__(self, engine: UciProtocol): + super().__init__(engine) + self.engine = engine + + def start(self) -> None: + self.analysis = AnalysisResult(stop=lambda: self.cancel()) self.sent_isready = False - if "Ponder" in engine.options: - engine._setoption("Ponder", False) - if "UCI_AnalyseMode" in engine.options and "UCI_AnalyseMode" not in engine.target_config and all(name.lower() != "uci_analysemode" for name in options): - engine._setoption("UCI_AnalyseMode", True) - if "MultiPV" in engine.options or (multipv and multipv > 1): - engine._setoption("MultiPV", 1 if multipv is None else multipv) + if "Ponder" in self.engine.options: + self.engine._setoption("Ponder", False) + if "UCI_AnalyseMode" in self.engine.options and "UCI_AnalyseMode" not in self.engine.target_config and all(name.lower() != "uci_analysemode" for name in options): + self.engine._setoption("UCI_AnalyseMode", True) + if "MultiPV" in self.engine.options or (multipv and multipv > 1): + self.engine._setoption("MultiPV", 1 if multipv is None else multipv) - engine._configure(options) + self.engine._configure(options) - if engine.first_game or engine.game != game: - engine.game = game - engine._ucinewgame() + if self.engine.first_game or self.engine.game != game: + self.engine.game = game + self.engine._ucinewgame() self.sent_isready = True - engine._isready() + self.engine._isready() else: - self._readyok(engine) + self._readyok() - def line_received(self, engine: UciProtocol, line: str) -> None: + @typing.override + def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token == "info": - self._info(engine, remaining) + self._info(remaining) elif token == "bestmove": - self._bestmove(engine, remaining) + self._bestmove(remaining) elif line.strip() == "readyok" and self.sent_isready: - self._readyok(engine) + self._readyok() else: - LOGGER.warning("%s: Unexpected engine output: %r", engine, line) + LOGGER.warning("%s: Unexpected engine output: %r", self.engine, line) - def _readyok(self, engine: UciProtocol) -> None: + def _readyok(self) -> None: self.sent_isready = False - engine._position(board) + self.engine._position(board) if limit: - engine._go(limit, root_moves=root_moves) + self.engine._go(limit, root_moves=root_moves) else: - engine._go(Limit(), root_moves=root_moves, infinite=True) + self.engine._go(Limit(), root_moves=root_moves, infinite=True) self.result.set_result(self.analysis) - def _info(self, engine: UciProtocol, arg: str) -> None: - self.analysis.post(_parse_uci_info(arg, engine.board, info)) + def _info(self, arg: str) -> None: + self.analysis.post(_parse_uci_info(arg, self.engine.board, info)) - def _bestmove(self, engine: UciProtocol, arg: str) -> None: + def _bestmove(self, arg: str) -> None: if not self.result.done(): raise EngineError("was not searching, but engine sent bestmove") - best = _parse_uci_bestmove(engine.board, arg) + best = _parse_uci_bestmove(self.engine.board, arg) self.set_finished() self.analysis.set_finished(best) - def cancel(self, engine: UciProtocol) -> None: - engine.send_line("stop") + @typing.override + def cancel(self) -> None: + self.engine.send_line("stop") - def engine_terminated(self, engine: UciProtocol, exc: Exception) -> None: - LOGGER.debug("%s: Closing analysis because engine has been terminated (error: %s)", engine, exc) + @typing.override + def engine_terminated(self, exc: Exception) -> None: + LOGGER.debug("%s: Closing analysis because engine has been terminated (error: %s)", self.engine, exc) self.analysis.set_exception(exc) return await self.communicate(UciAnalysisCommand) @@ -1938,89 +1973,96 @@ def __init__(self) -> None: self.first_game = True async def initialize(self) -> None: - class XBoardInitializeCommand(BaseCommand[XBoardProtocol, None]): - def check_initialized(self, engine: XBoardProtocol) -> None: - if engine.initialized: + class XBoardInitializeCommand(BaseCommand[None]): + def __init__(self, engine: XBoardProtocol): + super().__init__(engine) + self.engine = engine + + @typing.override + def check_initialized(self) -> None: + if self.engine.initialized: raise EngineError("engine already initialized") - def start(self, engine: XBoardProtocol) -> None: - engine.send_line("xboard") - engine.send_line("protover 2") - self.timeout_handle = engine.loop.call_later(2.0, lambda: self.timeout(engine)) + @typing.override + def start(self) -> None: + self.engine.send_line("xboard") + self.engine.send_line("protover 2") + self.timeout_handle = self.engine.loop.call_later(2.0, lambda: self.timeout()) - def timeout(self, engine: XBoardProtocol) -> None: - LOGGER.error("%s: Timeout during initialization", engine) - self.end(engine) + def timeout(self) -> None: + LOGGER.error("%s: Timeout during initialization", self.engine) + self.end() - def line_received(self, engine: XBoardProtocol, line: str) -> None: + @typing.override + def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token.startswith("#"): pass elif token == "feature": - self._feature(engine, remaining) + self._feature(remaining) elif XBOARD_ERROR_REGEX.match(line): raise EngineError(line) - def _feature(self, engine: XBoardProtocol, arg: str) -> None: + def _feature(self, arg: str) -> None: for feature in shlex.split(arg): key, value = feature.split("=", 1) if key == "option": option = _parse_xboard_option(value) if option.name not in ["random", "computer", "cores", "memory"]: - engine.options[option.name] = option + self.engine.options[option.name] = option else: try: - engine.features[key] = int(value) + self.engine.features[key] = int(value) except ValueError: - engine.features[key] = value + self.engine.features[key] = value - if "done" in engine.features: + if "done" in self.engine.features: self.timeout_handle.cancel() - if engine.features.get("done"): - self.end(engine) + if self.engine.features.get("done"): + self.end() - def end(self, engine: XBoardProtocol) -> None: - if not engine.features.get("ping", 0): + def end(self) -> None: + if not self.engine.features.get("ping", 0): self.result.set_exception(EngineError("xboard engine did not declare required feature: ping")) self.set_finished() return - if not engine.features.get("setboard", 0): + if not self.engine.features.get("setboard", 0): self.result.set_exception(EngineError("xboard engine did not declare required feature: setboard")) self.set_finished() return - if not engine.features.get("reuse", 1): - LOGGER.warning("%s: Rejecting feature reuse=0", engine) - engine.send_line("rejected reuse") - if not engine.features.get("sigterm", 1): - LOGGER.warning("%s: Rejecting feature sigterm=0", engine) - engine.send_line("rejected sigterm") - if engine.features.get("san", 0): - LOGGER.warning("%s: Rejecting feature san=1", engine) - engine.send_line("rejected san") - - if "myname" in engine.features: - engine.id["name"] = str(engine.features["myname"]) - - if engine.features.get("memory", 0): - engine.options["memory"] = Option("memory", "spin", 16, 1, None, None) - engine.send_line("accepted memory") - if engine.features.get("smp", 0): - engine.options["cores"] = Option("cores", "spin", 1, 1, None, None) - engine.send_line("accepted smp") - if engine.features.get("egt"): - for egt in str(engine.features["egt"]).split(","): + if not self.engine.features.get("reuse", 1): + LOGGER.warning("%s: Rejecting feature reuse=0", self.engine) + self.engine.send_line("rejected reuse") + if not self.engine.features.get("sigterm", 1): + LOGGER.warning("%s: Rejecting feature sigterm=0", self.engine) + self.engine.send_line("rejected sigterm") + if self.engine.features.get("san", 0): + LOGGER.warning("%s: Rejecting feature san=1", self.engine) + self.engine.send_line("rejected san") + + if "myname" in self.engine.features: + self.engine.id["name"] = str(self.engine.features["myname"]) + + if self.engine.features.get("memory", 0): + self.engine.options["memory"] = Option("memory", "spin", 16, 1, None, None) + self.engine.send_line("accepted memory") + if self.engine.features.get("smp", 0): + self.engine.options["cores"] = Option("cores", "spin", 1, 1, None, None) + self.engine.send_line("accepted smp") + if self.engine.features.get("egt"): + for egt in str(self.engine.features["egt"]).split(","): name = f"egtpath {egt}" - engine.options[name] = Option(name, "path", None, None, None, None) - engine.send_line("accepted egt") + self.engine.options[name] = Option(name, "path", None, None, None, None) + self.engine.send_line("accepted egt") - for option in engine.options.values(): + for option in self.engine.options.values(): if option.default is not None: - engine.config[option.name] = option.default + self.engine.config[option.name] = option.default if option.default is not None and not option.is_managed(): - engine.target_config[option.name] = option.default + self.engine.target_config[option.name] = option.default - engine.initialized = True + self.engine.initialized = True self.result.set_result(None) self.set_finished() @@ -2105,18 +2147,24 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping, opponen self.board.push(move) async def ping(self) -> None: - class XBoardPingCommand(BaseCommand[XBoardProtocol, None]): - def start(self, engine: XBoardProtocol) -> None: + class XBoardPingCommand(BaseCommand[None]): + def __init__(self, engine: XBoardProtocol): + super().__init__(engine) + self.engine = engine + + @typing.override + def start(self) -> None: n = id(self) & 0xffff self.pong = f"pong {n}" - engine._ping(n) + self.engine._ping(n) - def line_received(self, engine: XBoardProtocol, line: str) -> None: + @typing.override + def line_received(self, line: str) -> None: if line == self.pong: self.result.set_result(None) self.set_finished() elif not line.startswith("#"): - LOGGER.warning("%s: Unexpected engine output: %r", engine, line) + LOGGER.warning("%s: Unexpected engine output: %r", self.engine, line) elif XBOARD_ERROR_REGEX.match(line): raise EngineError(line) @@ -2126,54 +2174,60 @@ async def play(self, board: chess.Board, limit: Limit, *, game: object = None, i if root_moves is not None: raise EngineError("play with root_moves, but xboard supports 'include' only in analysis mode") - class XBoardPlayCommand(BaseCommand[XBoardProtocol, PlayResult]): - def start(self, engine: XBoardProtocol) -> None: + class XBoardPlayCommand(BaseCommand[PlayResult]): + def __init__(self, engine: XBoardProtocol): + super().__init__(engine) + self.engine = engine + + @typing.override + def start(self) -> None: self.play_result = PlayResult(None, None) self.stopped = False self.pong_after_move: Optional[str] = None self.pong_after_ponder: Optional[str] = None # Set game, position and configure. - engine._new(board, game, options, opponent) + self.engine._new(board, game, options, opponent) # Limit or time control. clock = limit.white_clock if board.turn else limit.black_clock increment = limit.white_inc if board.turn else limit.black_inc - if limit.clock_id is None or limit.clock_id != engine.clock_id: - self._send_time_control(engine, clock, increment) - engine.clock_id = limit.clock_id + if limit.clock_id is None or limit.clock_id != self.engine.clock_id: + self._send_time_control(clock, increment) + self.engine.clock_id = limit.clock_id if limit.nodes is not None: if limit.time is not None or limit.white_clock is not None or limit.black_clock is not None or increment is not None: raise EngineError("xboard does not support mixing node limits with time limits") - if "nps" not in engine.features: + if "nps" not in self.engine.features: LOGGER.warning("%s: Engine did not explicitly declare support for node limits (feature nps=?)") - elif not engine.features["nps"]: + elif not self.engine.features["nps"]: raise EngineError("xboard engine does not support node limits (feature nps=0)") - engine.send_line("nps 1") - engine.send_line(f"st {max(1, int(limit.nodes))}") + self.engine.send_line("nps 1") + self.engine.send_line(f"st {max(1, int(limit.nodes))}") if limit.depth is not None: - engine.send_line(f"sd {max(1, int(limit.depth))}") + self.engine.send_line(f"sd {max(1, int(limit.depth))}") if limit.white_clock is not None: - engine.send_line("{} {}".format("time" if board.turn else "otim", max(1, round(limit.white_clock * 100)))) + self.engine.send_line("{} {}".format("time" if board.turn else "otim", max(1, round(limit.white_clock * 100)))) if limit.black_clock is not None: - engine.send_line("{} {}".format("otim" if board.turn else "time", max(1, round(limit.black_clock * 100)))) + self.engine.send_line("{} {}".format("otim" if board.turn else "time", max(1, round(limit.black_clock * 100)))) - if draw_offered and engine.features.get("draw", 1): - engine.send_line("draw") + if draw_offered and self.engine.features.get("draw", 1): + self.engine.send_line("draw") # Start thinking. - engine.send_line("post" if info else "nopost") - engine.send_line("hard" if ponder else "easy") - engine.send_line("go") + self.engine.send_line("post" if info else "nopost") + self.engine.send_line("hard" if ponder else "easy") + self.engine.send_line("go") - def line_received(self, engine: XBoardProtocol, line: str) -> None: + @typing.override + def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token == "move": - self._move(engine, remaining.strip()) + self._move(remaining.strip()) elif token == "Hint:": - self._hint(engine, remaining.strip()) + self._hint(remaining.strip()) elif token == "pong": pong_line = f"{token} {remaining.strip()}" if pong_line == self.pong_after_move: @@ -2188,84 +2242,86 @@ def line_received(self, engine: XBoardProtocol, line: str) -> None: elif f"{token} {remaining.strip()}" == "offer draw": if not self.result.done(): self.play_result.draw_offered = True - self._ping_after_move(engine) + self._ping_after_move() elif line.strip() == "resign": if not self.result.done(): self.play_result.resigned = True - self._ping_after_move(engine) + self._ping_after_move() elif token in ["1-0", "0-1", "1/2-1/2"]: if "resign" in line and not self.result.done(): self.play_result.resigned = True - self._ping_after_move(engine) + self._ping_after_move() elif token.startswith("#"): pass elif XBOARD_ERROR_REGEX.match(line): - engine.first_game = True # Board state might no longer be in sync + self.engine.first_game = True # Board state might no longer be in sync raise EngineError(line) elif len(line.split()) >= 4 and line.lstrip()[0].isdigit(): - self._post(engine, line) + self._post(line) else: - LOGGER.warning("%s: Unexpected engine output: %r", engine, line) + LOGGER.warning("%s: Unexpected engine output: %r", self.engine, line) - def _send_time_control(self, engine: XBoardProtocol, clock: Optional[float], increment: Optional[float]) -> None: + def _send_time_control(self, clock: Optional[float], increment: Optional[float]) -> None: if limit.remaining_moves or clock is not None or increment is not None: base_mins, base_secs = divmod(int(clock or 0), 60) - engine.send_line(f"level {limit.remaining_moves or 0} {base_mins}:{base_secs:02d} {increment or 0}") + self.engine.send_line(f"level {limit.remaining_moves or 0} {base_mins}:{base_secs:02d} {increment or 0}") if limit.time is not None: - engine.send_line(f"st {max(0.01, limit.time)}") + self.engine.send_line(f"st {max(0.01, limit.time)}") - def _post(self, engine: XBoardProtocol, line: str) -> None: + def _post(self, line: str) -> None: if not self.result.done(): - self.play_result.info = _parse_xboard_post(line, engine.board, info) + self.play_result.info = _parse_xboard_post(line, self.engine.board, info) - def _move(self, engine: XBoardProtocol, arg: str) -> None: + def _move(self, arg: str) -> None: if not self.result.done() and self.play_result.move is None: try: - self.play_result.move = engine.board.push_xboard(arg) + self.play_result.move = self.engine.board.push_xboard(arg) except ValueError as err: self.result.set_exception(EngineError(err)) else: - self._ping_after_move(engine) + self._ping_after_move() else: try: - engine.board.push_xboard(arg) + self.engine.board.push_xboard(arg) except ValueError: LOGGER.exception("Exception playing unexpected move") - def _hint(self, engine: XBoardProtocol, arg: str) -> None: + def _hint(self, arg: str) -> None: if not self.result.done() and self.play_result.move is not None and self.play_result.ponder is None: try: - self.play_result.ponder = engine.board.parse_xboard(arg) + self.play_result.ponder = self.engine.board.parse_xboard(arg) except ValueError: LOGGER.exception("Exception parsing hint") else: LOGGER.warning("Unexpected hint: %r", arg) - def _ping_after_move(self, engine: XBoardProtocol) -> None: + def _ping_after_move(self) -> None: if self.pong_after_move is None: n = id(self) & 0xffff self.pong_after_move = f"pong {n}" - engine._ping(n) + self.engine._ping(n) - def cancel(self, engine: XBoardProtocol) -> None: + @typing.override + def cancel(self) -> None: if self.stopped: return self.stopped = True if self.result.cancelled(): - engine.send_line("?") + self.engine.send_line("?") if ponder: - engine.send_line("easy") + self.engine.send_line("easy") n = (id(self) + 1) & 0xffff self.pong_after_ponder = f"pong {n}" - engine._ping(n) + self.engine._ping(n) - def engine_terminated(self, engine: XBoardProtocol, exc: Exception) -> None: + @typing.override + def engine_terminated(self, exc: Exception) -> None: # Allow terminating engine while pondering. if not self.result.done(): - super().engine_terminated(engine, exc) + super().engine_terminated(exc) return await self.communicate(XBoardPlayCommand) @@ -2276,49 +2332,55 @@ async def analysis(self, board: chess.Board, limit: Optional[Limit] = None, *, m if limit is not None and (limit.white_clock is not None or limit.black_clock is not None): raise EngineError("xboard analysis does not support clock limits") - class XBoardAnalysisCommand(BaseCommand[XBoardProtocol, AnalysisResult]): - def start(self, engine: XBoardProtocol) -> None: + class XBoardAnalysisCommand(BaseCommand[AnalysisResult]): + def __init__(self, engine: XBoardProtocol): + super().__init__(engine) + self.engine = engine + + @typing.override + def start(self) -> None: self.stopped = False self.best_move: Optional[chess.Move] = None - self.analysis = AnalysisResult(stop=lambda: self.cancel(engine)) + self.analysis = AnalysisResult(stop=lambda: self.cancel()) self.final_pong: Optional[str] = None - engine._new(board, game, options) + self.engine._new(board, game, options) if root_moves is not None: - if not engine.features.get("exclude", 0): + if not self.engine.features.get("exclude", 0): raise EngineError("xboard engine does not support root_moves (feature exclude=0)") - engine.send_line("exclude all") + self.engine.send_line("exclude all") for move in root_moves: - engine.send_line(f"include {engine.board.xboard(move)}") + self.engine.send_line(f"include {self.engine.board.xboard(move)}") - engine.send_line("post") - engine.send_line("analyze") + self.engine.send_line("post") + self.engine.send_line("analyze") self.result.set_result(self.analysis) if limit is not None and limit.time is not None: - self.time_limit_handle: Optional[asyncio.Handle] = engine.loop.call_later(limit.time, lambda: self.cancel(engine)) + self.time_limit_handle: Optional[asyncio.Handle] = self.engine.loop.call_later(limit.time, lambda: self.cancel()) else: self.time_limit_handle = None - def line_received(self, engine: XBoardProtocol, line: str) -> None: + @typing.override + def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token.startswith("#"): pass elif len(line.split()) >= 4 and line.lstrip()[0].isdigit(): - self._post(engine, line) + self._post(line) elif f"{token} {remaining.strip()}" == self.final_pong: - self.end(engine) + self.end() elif XBOARD_ERROR_REGEX.match(line): - engine.first_game = True # Board state might no longer be in sync + self.engine.first_game = True # Board state might no longer be in sync raise EngineError(line) else: - LOGGER.warning("%s: Unexpected engine output: %r", engine, line) + LOGGER.warning("%s: Unexpected engine output: %r", self.engine, line) - def _post(self, engine: XBoardProtocol, line: str) -> None: - post_info = _parse_xboard_post(line, engine.board, info) + def _post(self, line: str) -> None: + post_info = _parse_xboard_post(line, self.engine.board, info) self.analysis.post(post_info) pv = post_info.get("pv") @@ -2327,36 +2389,38 @@ def _post(self, engine: XBoardProtocol, line: str) -> None: if limit is not None: if limit.time is not None and post_info.get("time", 0) >= limit.time: - self.cancel(engine) + self.cancel() elif limit.nodes is not None and post_info.get("nodes", 0) >= limit.nodes: - self.cancel(engine) + self.cancel() elif limit.depth is not None and post_info.get("depth", 0) >= limit.depth: - self.cancel(engine) + self.cancel() elif limit.mate is not None and "score" in post_info: if post_info["score"].relative >= Mate(limit.mate): - self.cancel(engine) + self.cancel() - def end(self, engine: XBoardProtocol) -> None: + def end(self) -> None: if self.time_limit_handle: self.time_limit_handle.cancel() self.set_finished() self.analysis.set_finished(BestMove(self.best_move, None)) - def cancel(self, engine: XBoardProtocol) -> None: + @typing.override + def cancel(self) -> None: if self.stopped: return self.stopped = True - engine.send_line(".") - engine.send_line("exit") + self.engine.send_line(".") + self.engine.send_line("exit") n = id(self) & 0xffff self.final_pong = f"pong {n}" - engine._ping(n) + self.engine._ping(n) - def engine_terminated(self, engine: XBoardProtocol, exc: Exception) -> None: - LOGGER.debug("%s: Closing analysis because engine has been terminated (error: %s)", engine, exc) + @typing.override + def engine_terminated(self, exc: Exception) -> None: + LOGGER.debug("%s: Closing analysis because engine has been terminated (error: %s)", self.engine, exc) if self.time_limit_handle: self.time_limit_handle.cancel() @@ -2397,10 +2461,15 @@ def _configure(self, options: ConfigMapping) -> None: self._setoption(name, value) async def configure(self, options: ConfigMapping) -> None: - class XBoardConfigureCommand(BaseCommand[XBoardProtocol, None]): - def start(self, engine: XBoardProtocol) -> None: - engine._configure(options) - engine.target_config.update({name: value for name, value in options.items() if value is not None}) + class XBoardConfigureCommand(BaseCommand[None]): + def __init__(self, engine: XBoardProtocol): + super().__init__(engine) + self.engine = engine + + @typing.override + def start(self) -> None: + self.engine._configure(options) + self.engine.target_config.update({name: value for name, value in options.items() if value is not None}) self.result.set_result(None) self.set_finished() @@ -2423,12 +2492,17 @@ async def send_opponent_information(self, *, opponent: Optional[Opponent] = None return await self.configure(self._opponent_configuration(opponent=opponent, engine_rating=engine_rating)) async def send_game_result(self, board: chess.Board, winner: Optional[Color] = None, game_ending: Optional[str] = None, game_complete: bool = True) -> None: - class XBoardGameResultCommand(BaseCommand[XBoardProtocol, None]): - def start(self, engine: XBoardProtocol) -> None: + class XBoardGameResultCommand(BaseCommand[None]): + def __init__(self, engine: XBoardProtocol): + super().__init__(engine) + self.engine = engine + + @typing.override + def start(self) -> None: if game_ending and any(c in game_ending for c in "{}\n\r"): raise EngineError(f"invalid line break or curly braces in game ending message: {game_ending!r}") - engine._new(board, engine.game, {}) # Send final moves to engine. + self.engine._new(board, self.engine.game, {}) # Send final moves to engine. outcome = board.outcome(claim_draw=True) @@ -2451,7 +2525,7 @@ def start(self, engine: XBoardProtocol) -> None: ending = "" ending_text = f"{{{ending}}}" if ending else "" - engine.send_line(f"result {result} {ending_text}".strip()) + self.engine.send_line(f"result {result} {ending_text}".strip()) self.result.set_result(None) self.set_finished() @@ -2845,7 +2919,7 @@ def id(self) -> Mapping[str, str]: future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) return future.result() - def communicate(self, command_factory: Callable[[Protocol], BaseCommand[Protocol, T]]) -> T: + def communicate(self, command_factory: Callable[[Protocol], BaseCommand[T]]) -> T: with self._not_shut_down(): coro = self.protocol.communicate(command_factory) future = asyncio.run_coroutine_threadsafe(coro, self.protocol.loop) From 5d8e82da82156f5eae2d15f07e2c24d800c87a41 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 16:05:29 +0200 Subject: [PATCH 1762/1831] Let variant boards manage their own stack --- chess/__init__.py | 9 +++---- chess/variant.py | 66 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index a90df9ef6..b82f8559f 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1542,7 +1542,7 @@ def from_chess960_pos(cls: Type[BaseBoardT], scharnagl: int) -> BaseBoardT: BoardT = TypeVar("BoardT", bound="Board") -class _BoardState(Generic[BoardT]): +class _BoardState: def __init__(self, board: BoardT) -> None: self.pawns = board.pawns @@ -1701,7 +1701,7 @@ def __init__(self: BoardT, fen: Optional[str] = STARTING_FEN, *, chess960: bool self.ep_square = None self.move_stack = [] - self._stack: List[_BoardState[BoardT]] = [] + self._stack: List[_BoardState] = [] if fen is None: self.clear() @@ -2304,9 +2304,6 @@ def is_repetition(self, count: int = 3) -> bool: return False - def _board_state(self: BoardT) -> _BoardState[BoardT]: - return _BoardState(self) - def _push_capture(self, move: Move, capture_square: Square, piece_type: PieceType, was_promoted: bool) -> None: pass @@ -2335,7 +2332,7 @@ def push(self: BoardT, move: Move) -> None: """ # Push move and remember board state. move = self._to_chess960(move) - board_state = self._board_state() + board_state = _BoardState(self) self.castling_rights = self.clean_castling_rights() # Before pushing stack self.move_stack.append(self._from_chess960(self.chess960, move.from_square, move.to_square, move.promotion, move.drop)) self._stack.append(board_state) diff --git a/chess/variant.py b/chess/variant.py index 6160696a2..119a0402c 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -673,14 +673,12 @@ def status(self) -> chess.Status: ThreeCheckBoardT = TypeVar("ThreeCheckBoardT", bound="ThreeCheckBoard") -class _ThreeCheckBoardState(Generic[ThreeCheckBoardT], chess._BoardState[ThreeCheckBoardT]): - def __init__(self, board: ThreeCheckBoardT) -> None: - super().__init__(board) +class _ThreeCheckBoardState: + def __init__(self, board: ThreeCheckBoard) -> None: self.remaining_checks_w = board.remaining_checks[chess.WHITE] self.remaining_checks_b = board.remaining_checks[chess.BLACK] - def restore(self, board: ThreeCheckBoardT) -> None: - super().restore(board) + def restore(self, board: ThreeCheckBoard) -> None: board.remaining_checks[chess.WHITE] = self.remaining_checks_w board.remaining_checks[chess.BLACK] = self.remaining_checks_b @@ -698,8 +696,13 @@ class ThreeCheckBoard(chess.Board): def __init__(self, fen: Optional[str] = starting_fen, chess960: bool = False) -> None: self.remaining_checks = [3, 3] + self._three_check_stack: List[_ThreeCheckBoardState] = [] super().__init__(fen, chess960=chess960) + def clear_stack(self) -> None: + super().clear_stack() + self._three_check_stack.clear() + def reset_board(self) -> None: super().reset_board() self.remaining_checks[chess.WHITE] = 3 @@ -710,14 +713,17 @@ def clear_board(self) -> None: self.remaining_checks[chess.WHITE] = 3 self.remaining_checks[chess.BLACK] = 3 - def _board_state(self: ThreeCheckBoardT) -> _ThreeCheckBoardState[ThreeCheckBoardT]: - return _ThreeCheckBoardState(self) - def push(self, move: chess.Move) -> None: + self._three_check_stack.append(_ThreeCheckBoardState(self)) super().push(move) if self.is_check(): self.remaining_checks[not self.turn] -= 1 + def pop(self) -> chess.Move: + move = super().pop() + self._three_check_stack.pop().restore(self) + return move + def has_insufficient_material(self, color: chess.Color) -> bool: # Any remaining piece can give check. return not (self.occupied_co[color] & ~self.kings) @@ -792,8 +798,19 @@ def _transposition_key(self) -> Hashable: def copy(self: ThreeCheckBoardT, stack: Union[bool, int] = True) -> ThreeCheckBoardT: board = super().copy(stack=stack) board.remaining_checks = self.remaining_checks.copy() + if stack: + stack = len(self.move_stack) if stack is True else stack + board._three_check_stack = self._three_check_stack[-stack:] return board + def root(self: ThreeCheckBoardT) -> ThreeCheckBoardT: + if self._three_check_stack: + board = super().root() + self._three_check_stack[0].restore(board) + return board + else: + return self.copy(stack=False) + def mirror(self: ThreeCheckBoardT) -> ThreeCheckBoardT: board = super().mirror() board.remaining_checks[chess.WHITE] = self.remaining_checks[chess.BLACK] @@ -803,14 +820,12 @@ def mirror(self: ThreeCheckBoardT) -> ThreeCheckBoardT: CrazyhouseBoardT = TypeVar("CrazyhouseBoardT", bound="CrazyhouseBoard") -class _CrazyhouseBoardState(Generic[CrazyhouseBoardT], chess._BoardState[CrazyhouseBoardT]): - def __init__(self, board: CrazyhouseBoardT) -> None: - super().__init__(board) +class _CrazyhouseBoardState: + def __init__(self, board: CrazyhouseBoard) -> None: self.pockets_w = board.pockets[chess.WHITE].copy() self.pockets_b = board.pockets[chess.BLACK].copy() - def restore(self, board: CrazyhouseBoardT) -> None: - super().restore(board) + def restore(self, board: CrazyhouseBoard) -> None: board.pockets[chess.WHITE] = self.pockets_w board.pockets[chess.BLACK] = self.pockets_b @@ -870,8 +885,13 @@ class CrazyhouseBoard(chess.Board): def __init__(self, fen: Optional[str] = starting_fen, chess960: bool = False) -> None: self.pockets = [CrazyhousePocket(), CrazyhousePocket()] + self._crazyhouse_stack: List[_CrazyhouseBoardState] = [] super().__init__(fen, chess960=chess960) + def clear_stack(self) -> None: + super().clear_stack() + self._crazyhouse_stack.clear() + def reset_board(self) -> None: super().reset_board() self.pockets[chess.WHITE].reset() @@ -882,10 +902,8 @@ def clear_board(self) -> None: self.pockets[chess.WHITE].reset() self.pockets[chess.BLACK].reset() - def _board_state(self: CrazyhouseBoardT) -> _CrazyhouseBoardState[CrazyhouseBoardT]: - return _CrazyhouseBoardState(self) - def push(self, move: chess.Move) -> None: + self._crazyhouse_stack.append(_CrazyhouseBoardState(self)) super().push(move) if move.drop: self.pockets[not self.turn].remove(move.drop) @@ -896,6 +914,11 @@ def _push_capture(self, move: chess.Move, capture_square: chess.Square, piece_ty else: self.pockets[self.turn].add(piece_type) + def pop(self) -> chess.Move: + move = super().pop() + self._crazyhouse_stack.pop().restore(self) + return move + def _is_halfmoves(self, n: int) -> bool: # No draw by 50-move rule or 75-move rule. return False @@ -1028,8 +1051,19 @@ def copy(self: CrazyhouseBoardT, stack: Union[bool, int] = True) -> CrazyhouseBo board = super().copy(stack=stack) board.pockets[chess.WHITE] = self.pockets[chess.WHITE].copy() board.pockets[chess.BLACK] = self.pockets[chess.BLACK].copy() + if stack: + stack = len(self.move_stack) if stack is True else stack + board._crazyhouse_stack = self._crazyhouse_stack[-stack:] return board + def root(self: CrazyhouseBoardT) -> CrazyhouseBoardT: + if self._crazyhouse_stack: + board = super().root() + self._crazyhouse_stack[0].restore(board) + return board + else: + return self.copy(stack=False) + def mirror(self: CrazyhouseBoardT) -> CrazyhouseBoardT: board = super().mirror() board.pockets[chess.WHITE] = self.pockets[chess.BLACK].copy() From a652aaad5d22edd4cc078dba9214fb1d81789d7a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 16:13:51 +0200 Subject: [PATCH 1763/1831] Add fallback for override decorator --- chess/engine.py | 60 ++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index d1bbaaee1..f5fdff96a 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -24,6 +24,14 @@ from types import TracebackType from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Optional, Tuple, Type, TypedDict, TypeVar, Union +try: + from typing import override +except: + # Before Python 3.12 + F = typing.TypeVar("F", bound=Callable[..., Any]) + def override(fn: F, /) -> F: + return fn + if typing.TYPE_CHECKING: from typing_extensions import Self @@ -1317,16 +1325,16 @@ def __init__(self, engine: UciProtocol): super().__init__(engine) self.engine = engine - @typing.override + @override def check_initialized(self) -> None: if self.engine.initialized: raise EngineError("engine already initialized") - @typing.override + @override def start(self) -> None: self.engine.send_line("uci") - @typing.override + @override def line_received(self, line: str) -> None: token, remaining = _next_token(line) if line.strip() == "uciok" and not self.result.done(): @@ -1415,7 +1423,7 @@ def __init__(self, engine: UciProtocol) -> None: def start(self) -> None: self.engine._isready() - @typing.override + @override def line_received(self, line: str) -> None: if line.strip() == "readyok": self.result.set_result(None) @@ -1574,7 +1582,7 @@ def __init__(self, engine: UciProtocol): # MultiPV never change between pondering play commands. engine.may_ponderhit = board if ponder and not engine.first_game and game == engine.game and not engine._changed_options(new_options) else None - @typing.override + @override def start(self) -> None: self.info: InfoDict = {} self.pondering: Optional[chess.Board] = None @@ -1605,7 +1613,7 @@ def start(self) -> None: else: self._readyok() - @typing.override + @override def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token == "info": @@ -1662,7 +1670,7 @@ def end(self) -> None: engine.may_ponderhit = None self.set_finished() - @typing.override + @override def cancel(self) -> None: if self.engine.may_ponderhit and self.pondering and self.engine.may_ponderhit.move_stack == self.pondering.move_stack and self.engine.may_ponderhit == self.pondering: self.engine.ponderhit = True @@ -1670,7 +1678,7 @@ def cancel(self) -> None: else: self.engine.send_line("stop") - @typing.override + @override def engine_terminated(self, exc: Exception) -> None: # Allow terminating engine while pondering. if not self.result.done(): @@ -1705,7 +1713,7 @@ def start(self) -> None: else: self._readyok() - @typing.override + @override def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token == "info": @@ -1738,11 +1746,11 @@ def _bestmove(self, arg: str) -> None: self.set_finished() self.analysis.set_finished(best) - @typing.override + @override def cancel(self) -> None: self.engine.send_line("stop") - @typing.override + @override def engine_terminated(self, exc: Exception) -> None: LOGGER.debug("%s: Closing analysis because engine has been terminated (error: %s)", self.engine, exc) self.analysis.set_exception(exc) @@ -1978,12 +1986,12 @@ def __init__(self, engine: XBoardProtocol): super().__init__(engine) self.engine = engine - @typing.override + @override def check_initialized(self) -> None: if self.engine.initialized: raise EngineError("engine already initialized") - @typing.override + @override def start(self) -> None: self.engine.send_line("xboard") self.engine.send_line("protover 2") @@ -1993,7 +2001,7 @@ def timeout(self) -> None: LOGGER.error("%s: Timeout during initialization", self.engine) self.end() - @typing.override + @override def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token.startswith("#"): @@ -2152,13 +2160,13 @@ def __init__(self, engine: XBoardProtocol): super().__init__(engine) self.engine = engine - @typing.override + @override def start(self) -> None: n = id(self) & 0xffff self.pong = f"pong {n}" self.engine._ping(n) - @typing.override + @override def line_received(self, line: str) -> None: if line == self.pong: self.result.set_result(None) @@ -2179,7 +2187,7 @@ def __init__(self, engine: XBoardProtocol): super().__init__(engine) self.engine = engine - @typing.override + @override def start(self) -> None: self.play_result = PlayResult(None, None) self.stopped = False @@ -2221,7 +2229,7 @@ def start(self) -> None: self.engine.send_line("hard" if ponder else "easy") self.engine.send_line("go") - @typing.override + @override def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token == "move": @@ -2301,7 +2309,7 @@ def _ping_after_move(self) -> None: self.pong_after_move = f"pong {n}" self.engine._ping(n) - @typing.override + @override def cancel(self) -> None: if self.stopped: return @@ -2317,7 +2325,7 @@ def cancel(self) -> None: self.pong_after_ponder = f"pong {n}" self.engine._ping(n) - @typing.override + @override def engine_terminated(self, exc: Exception) -> None: # Allow terminating engine while pondering. if not self.result.done(): @@ -2337,7 +2345,7 @@ def __init__(self, engine: XBoardProtocol): super().__init__(engine) self.engine = engine - @typing.override + @override def start(self) -> None: self.stopped = False self.best_move: Optional[chess.Move] = None @@ -2364,7 +2372,7 @@ def start(self) -> None: else: self.time_limit_handle = None - @typing.override + @override def line_received(self, line: str) -> None: token, remaining = _next_token(line) if token.startswith("#"): @@ -2405,7 +2413,7 @@ def end(self) -> None: self.set_finished() self.analysis.set_finished(BestMove(self.best_move, None)) - @typing.override + @override def cancel(self) -> None: if self.stopped: return @@ -2418,7 +2426,7 @@ def cancel(self) -> None: self.final_pong = f"pong {n}" self.engine._ping(n) - @typing.override + @override def engine_terminated(self, exc: Exception) -> None: LOGGER.debug("%s: Closing analysis because engine has been terminated (error: %s)", self.engine, exc) @@ -2466,7 +2474,7 @@ def __init__(self, engine: XBoardProtocol): super().__init__(engine) self.engine = engine - @typing.override + @override def start(self) -> None: self.engine._configure(options) self.engine.target_config.update({name: value for name, value in options.items() if value is not None}) @@ -2497,7 +2505,7 @@ def __init__(self, engine: XBoardProtocol): super().__init__(engine) self.engine = engine - @typing.override + @override def start(self) -> None: if game_ending and any(c in game_ending for c in "{}\n\r"): raise EngineError(f"invalid line break or curly braces in game ending message: {game_ending!r}") From 7a59a3683f33682c0c2c9b359469c8b9876ece9e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 17:02:12 +0200 Subject: [PATCH 1764/1831] Import override from typing_extensions --- chess/engine.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index f5fdff96a..347acf297 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -24,10 +24,9 @@ from types import TracebackType from typing import Any, Callable, Coroutine, Deque, Dict, Generator, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Optional, Tuple, Type, TypedDict, TypeVar, Union -try: - from typing import override -except: - # Before Python 3.12 +if typing.TYPE_CHECKING: + from typing_extensions import override +else: F = typing.TypeVar("F", bound=Callable[..., Any]) def override(fn: F, /) -> F: return fn From 571658baa358b97f3cb5104c3dfab33c6d962deb Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 17:25:03 +0200 Subject: [PATCH 1765/1831] Use typing_extensions.Self --- chess/__init__.py | 32 ++++++++++++++++---------------- chess/engine.py | 2 +- chess/pgn.py | 7 +++++-- chess/syzygy.py | 7 ++++--- chess/variant.py | 18 +++++++++++------- 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index b82f8559f..3553eee65 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -25,7 +25,7 @@ from typing import ClassVar, Callable, Counter, Dict, Generic, Hashable, Iterable, Iterator, List, Literal, Mapping, Optional, SupportsInt, Tuple, Type, TypeVar, Union if typing.TYPE_CHECKING: - from typing_extensions import TypeAlias + from typing_extensions import Self, TypeAlias EnPassantSpec = Literal["legal", "fen", "xfen"] @@ -1455,7 +1455,7 @@ def apply_transform(self, f: Callable[[Bitboard], Bitboard]) -> None: self.occupied = f(self.occupied) self.promoted = f(self.promoted) - def transform(self: BaseBoardT, f: Callable[[Bitboard], Bitboard]) -> BaseBoardT: + def transform(self, f: Callable[[Bitboard], Bitboard]) -> Self: """ Returns a transformed copy of the board (without move stack) by applying a bitboard transformation function. @@ -1473,11 +1473,11 @@ def transform(self: BaseBoardT, f: Callable[[Bitboard], Bitboard]) -> BaseBoardT board.apply_transform(f) return board - def apply_mirror(self: BaseBoardT) -> None: + def apply_mirror(self) -> None: self.apply_transform(flip_vertical) self.occupied_co[WHITE], self.occupied_co[BLACK] = self.occupied_co[BLACK], self.occupied_co[WHITE] - def mirror(self: BaseBoardT) -> BaseBoardT: + def mirror(self) -> Self: """ Returns a mirrored copy of the board (without move stack). @@ -1491,7 +1491,7 @@ def mirror(self: BaseBoardT) -> BaseBoardT: board.apply_mirror() return board - def copy(self: BaseBoardT) -> BaseBoardT: + def copy(self) -> Self: """Creates a copy of the board.""" board = type(self)(None) @@ -1509,10 +1509,10 @@ def copy(self: BaseBoardT) -> BaseBoardT: return board - def __copy__(self: BaseBoardT) -> BaseBoardT: + def __copy__(self) -> Self: return self.copy() - def __deepcopy__(self: BaseBoardT, memo: Dict[int, object]) -> BaseBoardT: + def __deepcopy__(self, memo: Dict[int, object]) -> Self: board = self.copy() memo[id(self)] = board return board @@ -1694,7 +1694,7 @@ class Board(BaseBoard): manipulation. """ - def __init__(self: BoardT, fen: Optional[str] = STARTING_FEN, *, chess960: bool = False) -> None: + def __init__(self, fen: Optional[str] = STARTING_FEN, *, chess960: bool = False) -> None: BaseBoard.__init__(self, None) self.chess960 = chess960 @@ -1786,7 +1786,7 @@ def clear_stack(self) -> None: self.move_stack.clear() self._stack.clear() - def root(self: BoardT) -> BoardT: + def root(self) -> Self: """Returns a copy of the root position.""" if self._stack: board = type(self)(None, chess960=self.chess960) @@ -2307,7 +2307,7 @@ def is_repetition(self, count: int = 3) -> bool: def _push_capture(self, move: Move, capture_square: Square, piece_type: PieceType, was_promoted: bool) -> None: pass - def push(self: BoardT, move: Move) -> None: + def push(self, move: Move) -> None: """ Updates the position with the given *move* and puts it onto the move stack. @@ -2428,7 +2428,7 @@ def push(self: BoardT, move: Move) -> None: # Swap turn. self.turn = not self.turn - def pop(self: BoardT) -> Move: + def pop(self) -> Move: """ Restores the previous position and returns the last move from the stack. @@ -2838,7 +2838,7 @@ def _validate_epd_opcode(self, opcode: str) -> None: if blacklisted in opcode: raise ValueError(f"invalid character {blacklisted!r} in epd opcode: {opcode!r}") - def _parse_epd_ops(self: BoardT, operation_part: str, make_board: Callable[[], BoardT]) -> Dict[str, Union[None, str, int, float, Move, List[Move]]]: + def _parse_epd_ops(self, operation_part: str, make_board: Callable[[], Self]) -> Dict[str, Union[None, str, int, float, Move, List[Move]]]: operations: Dict[str, Union[None, str, int, float, Move, List[Move]]] = {} state = "opcode" opcode = "" @@ -3831,16 +3831,16 @@ def apply_transform(self, f: Callable[[Bitboard], Bitboard]) -> None: self.ep_square = None if self.ep_square is None else msb(f(BB_SQUARES[self.ep_square])) self.castling_rights = f(self.castling_rights) - def transform(self: BoardT, f: Callable[[Bitboard], Bitboard]) -> BoardT: + def transform(self, f: Callable[[Bitboard], Bitboard]) -> Self: board = self.copy(stack=False) board.apply_transform(f) return board - def apply_mirror(self: BoardT) -> None: + def apply_mirror(self) -> None: super().apply_mirror() self.turn = not self.turn - def mirror(self: BoardT) -> BoardT: + def mirror(self) -> Self: """ Returns a mirrored copy of the board. @@ -3855,7 +3855,7 @@ def mirror(self: BoardT) -> BoardT: board.apply_mirror() return board - def copy(self: BoardT, *, stack: Union[bool, int] = True) -> BoardT: + def copy(self, *, stack: Union[bool, int] = True) -> Self: """ Creates a copy of the board. diff --git a/chess/engine.py b/chess/engine.py index 347acf297..59b843b8b 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -970,7 +970,7 @@ def pipe_data_received(self, fd: int, data: Union[bytes, str]) -> None: def error_line_received(self, line: str) -> None: LOGGER.warning("%s: stderr >> %s", self, line) - def _line_received(self: Protocol, line: str) -> None: + def _line_received(self, line: str) -> None: LOGGER.debug("%s: >> %s", self, line) self.line_received(line) diff --git a/chess/pgn.py b/chess/pgn.py index 0d0879ae0..83ddaf8f5 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -15,6 +15,9 @@ from typing import Any, Callable, Dict, Generic, Iterable, Iterator, List, Literal, Mapping, MutableMapping, Set, TextIO, Tuple, Type, TypeVar, Optional, Union from chess import Color, Square +if typing.TYPE_CHECKING: + from typing_extensions import Self + LOGGER = logging.getLogger(__name__) @@ -1014,10 +1017,10 @@ def __iter__(self) -> Iterator[str]: def __len__(self) -> int: return len(self._tag_roster) + len(self._others) - def copy(self: HeadersT) -> HeadersT: + def copy(self) -> Self: return type(self)(self) - def __copy__(self: HeadersT) -> HeadersT: + def __copy__(self) -> Self: return self.copy() def __repr__(self) -> str: diff --git a/chess/syzygy.py b/chess/syzygy.py index 8ba1cbca4..77a6eeded 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -14,6 +14,9 @@ from types import TracebackType from typing import Deque, Dict, Iterable, Iterator, List, Optional, Set, Tuple, Type, TypeVar, Union +if typing.TYPE_CHECKING: + from typing_extensions import Self + UINT64_BE = struct.Struct(">Q") UINT32 = struct.Struct(" None: self.data.close() self.data = None - def __enter__(self: TableT) -> TableT: + def __enter__(self) -> Self: return self def __exit__(self, exc_type: Optional[Type[BaseException]], exc_value: Optional[BaseException], traceback: Optional[TracebackType]) -> None: diff --git a/chess/variant.py b/chess/variant.py index 119a0402c..d28a6e964 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -2,9 +2,13 @@ import chess import itertools +import typing from typing import Dict, Generic, Hashable, Iterable, Iterator, List, Optional, Type, TypeVar, Union +if typing.TYPE_CHECKING: + from typing_extensions import Self + class SuicideBoard(chess.Board): @@ -795,7 +799,7 @@ def _transposition_key(self) -> Hashable: return (super()._transposition_key(), self.remaining_checks[chess.WHITE], self.remaining_checks[chess.BLACK]) - def copy(self: ThreeCheckBoardT, stack: Union[bool, int] = True) -> ThreeCheckBoardT: + def copy(self, stack: Union[bool, int] = True) -> Self: board = super().copy(stack=stack) board.remaining_checks = self.remaining_checks.copy() if stack: @@ -803,7 +807,7 @@ def copy(self: ThreeCheckBoardT, stack: Union[bool, int] = True) -> ThreeCheckBo board._three_check_stack = self._three_check_stack[-stack:] return board - def root(self: ThreeCheckBoardT) -> ThreeCheckBoardT: + def root(self) -> Self: if self._three_check_stack: board = super().root() self._three_check_stack[0].restore(board) @@ -811,7 +815,7 @@ def root(self: ThreeCheckBoardT) -> ThreeCheckBoardT: else: return self.copy(stack=False) - def mirror(self: ThreeCheckBoardT) -> ThreeCheckBoardT: + def mirror(self) -> Self: board = super().mirror() board.remaining_checks[chess.WHITE] = self.remaining_checks[chess.BLACK] board.remaining_checks[chess.BLACK] = self.remaining_checks[chess.WHITE] @@ -865,7 +869,7 @@ def __len__(self) -> int: def __repr__(self) -> str: return f"CrazyhousePocket('{self}')" - def copy(self: CrazyhousePocketT) -> CrazyhousePocketT: + def copy(self) -> Self: """Returns a copy of this pocket.""" pocket = type(self)() pocket._pieces = self._pieces[:] @@ -1047,7 +1051,7 @@ def epd(self, shredder: bool = False, en_passant: chess.EnPassantSpec = "legal", board_part, info_part = epd.split(" ", 1) return f"{board_part}[{str(self.pockets[chess.WHITE]).upper()}{self.pockets[chess.BLACK]}] {info_part}" - def copy(self: CrazyhouseBoardT, stack: Union[bool, int] = True) -> CrazyhouseBoardT: + def copy(self, stack: Union[bool, int] = True) -> Self: board = super().copy(stack=stack) board.pockets[chess.WHITE] = self.pockets[chess.WHITE].copy() board.pockets[chess.BLACK] = self.pockets[chess.BLACK].copy() @@ -1056,7 +1060,7 @@ def copy(self: CrazyhouseBoardT, stack: Union[bool, int] = True) -> CrazyhouseBo board._crazyhouse_stack = self._crazyhouse_stack[-stack:] return board - def root(self: CrazyhouseBoardT) -> CrazyhouseBoardT: + def root(self) -> Self: if self._crazyhouse_stack: board = super().root() self._crazyhouse_stack[0].restore(board) @@ -1064,7 +1068,7 @@ def root(self: CrazyhouseBoardT) -> CrazyhouseBoardT: else: return self.copy(stack=False) - def mirror(self: CrazyhouseBoardT) -> CrazyhouseBoardT: + def mirror(self) -> Self: board = super().mirror() board.pockets[chess.WHITE] = self.pockets[chess.BLACK].copy() board.pockets[chess.BLACK] = self.pockets[chess.WHITE].copy() From f286d687e496123fb46d26ce3fd06bc0db505dc4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 17:40:10 +0200 Subject: [PATCH 1766/1831] Towards pyright compatibility --- chess/__init__.py | 4 ++-- chess/engine.py | 7 +++++-- chess/variant.py | 8 ++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 3553eee65..55bd4cad2 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1544,7 +1544,7 @@ def from_chess960_pos(cls: Type[BaseBoardT], scharnagl: int) -> BaseBoardT: class _BoardState: - def __init__(self, board: BoardT) -> None: + def __init__(self, board: Board) -> None: self.pawns = board.pawns self.knights = board.knights self.bishops = board.bishops @@ -1564,7 +1564,7 @@ def __init__(self, board: BoardT) -> None: self.halfmove_clock = board.halfmove_clock self.fullmove_number = board.fullmove_number - def restore(self, board: BoardT) -> None: + def restore(self, board: Board) -> None: board.pawns = self.pawns board.knights = self.knights board.bishops = self.bishops diff --git a/chess/engine.py b/chess/engine.py index 59b843b8b..9a6a21f48 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -406,8 +406,10 @@ class Score(abc.ABC): """ @typing.overload + @abc.abstractmethod def score(self, *, mate_score: int) -> int: ... @typing.overload + @abc.abstractmethod def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: ... @abc.abstractmethod def score(self, *, mate_score: Optional[int] = None) -> Optional[int]: @@ -2120,12 +2122,13 @@ def _new(self, board: chess.Board, game: object, options: ConfigMapping, opponen if self.config.get("computer"): self.send_line("computer") - self.send_line("force") + self.send_line("force") - if new_game: fen = root.fen(shredder=board.chess960, en_passant="fen") if variant != "normal" or fen != chess.STARTING_FEN or board.chess960: self.send_line(f"setboard {fen}") + else: + self.send_line("force") # Undo moves until common position. common_stack_len = 0 diff --git a/chess/variant.py b/chess/variant.py index d28a6e964..6e9161dc8 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -133,7 +133,7 @@ def _transposition_key(self) -> Hashable: else: return super()._transposition_key() - def board_fen(self, promoted: Optional[bool] = None) -> str: + def board_fen(self, *, promoted: Optional[bool] = None) -> str: if promoted is None: promoted = self.has_chess960_castling_rights() return super().board_fen(promoted=promoted) @@ -799,7 +799,7 @@ def _transposition_key(self) -> Hashable: return (super()._transposition_key(), self.remaining_checks[chess.WHITE], self.remaining_checks[chess.BLACK]) - def copy(self, stack: Union[bool, int] = True) -> Self: + def copy(self, *, stack: Union[bool, int] = True) -> Self: board = super().copy(stack=stack) board.remaining_checks = self.remaining_checks.copy() if stack: @@ -1041,7 +1041,7 @@ def set_fen(self, fen: str) -> None: self.pockets[chess.WHITE] = white_pocket self.pockets[chess.BLACK] = black_pocket - def board_fen(self, promoted: Optional[bool] = None) -> str: + def board_fen(self, *, promoted: Optional[bool] = None) -> str: if promoted is None: promoted = True return super().board_fen(promoted=promoted) @@ -1051,7 +1051,7 @@ def epd(self, shredder: bool = False, en_passant: chess.EnPassantSpec = "legal", board_part, info_part = epd.split(" ", 1) return f"{board_part}[{str(self.pockets[chess.WHITE]).upper()}{self.pockets[chess.BLACK]}] {info_part}" - def copy(self, stack: Union[bool, int] = True) -> Self: + def copy(self, *, stack: Union[bool, int] = True) -> Self: board = super().copy(stack=stack) board.pockets[chess.WHITE] = self.pockets[chess.WHITE].copy() board.pockets[chess.BLACK] = self.pockets[chess.BLACK].copy() From 33eea7ca062ed7396590ac3408ec05121bba9483 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 18:01:47 +0200 Subject: [PATCH 1767/1831] Add changelog entries --- CHANGELOG.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a4534badb..754b5d418 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,13 @@ Changes: some 8 piece positions with decisive captures can be probed successfully. * The string wrapper returned by ``chess.svg`` functions now also implements ``_repr_html_``. +* Significant changes to ``chess.engine`` internals: + ``chess.engine.BaseCommand`` methods other than the constructor no longer + receive ``engine: Protocol``. +* Significant changes to board state internals: Subclasses of ``chess.Board`` + can no longer hook into board state recording/restoration and need to + override relevant methods instead (``clear_stack``, ``copy``, ``root``, + ``push``, ``pop``). New features: From caefd4dc6c25369750f6cc461885adfbbd52f09c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 21:11:38 +0200 Subject: [PATCH 1768/1831] chess.engine._next_token() cosmetics --- chess/engine.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 9a6a21f48..c6698bc76 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -2650,7 +2650,8 @@ def _parse_xboard_post(line: str, root_board: chess.Board, selector: Info = INFO def _next_token(line: str) -> tuple[str, str]: - """Get the next token in a whitespace-delimited line of text. + """ + Get the next token in a whitespace-delimited line of text. The result is returned as a 2-part tuple of strings. @@ -2660,10 +2661,10 @@ def _next_token(line: str) -> tuple[str, str]: If the input line is not empty and not completely whitespace, then the first element of the returned tuple is a single word with leading and trailing whitespace removed. The second element is the - unchanged rest of the line.""" - + unchanged rest of the line. + """ parts = line.split(maxsplit=1) - return (parts[0] if parts else "", parts[1] if len(parts) == 2 else "") + return parts[0] if parts else "", parts[1] if len(parts) == 2 else "" class BestMove: From 71e7c31fba31554a2b174ff7fb88a77b61674543 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 22:21:28 +0200 Subject: [PATCH 1769/1831] Show actual state in engine command state assertions (#1049, #1071) --- chess/engine.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index c6698bc76..302aa2bbd 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -989,7 +989,7 @@ async def communicate(self, command_factory: Callable[[Self], BaseCommand[T]]) - if self.returncode.done(): raise EngineTerminatedError(f"engine process dead (exit code: {self.returncode.result()})") - assert command.state == CommandState.NEW + assert command.state == CommandState.NEW, command.state if self.next_command is not None: self.next_command.result.cancel() @@ -1253,7 +1253,7 @@ def _handle_exception(self, exc: Exception) -> None: self.finished.set_result(None) def set_finished(self) -> None: - assert self.state in [CommandState.ACTIVE, CommandState.CANCELLING] + assert self.state in [CommandState.ACTIVE, CommandState.CANCELLING], self.state if not self.result.done(): self.result.set_exception(EngineError(f"engine command finished before returning result: {self!r}")) self.finished.set_result(None) @@ -1261,12 +1261,12 @@ def set_finished(self) -> None: def _cancel(self) -> None: if self.state != CommandState.CANCELLING and self.state != CommandState.DONE: - assert self.state == CommandState.ACTIVE + assert self.state == CommandState.ACTIVE, self.state self.state = CommandState.CANCELLING self.cancel() def _start(self) -> None: - assert self.state == CommandState.NEW + assert self.state == CommandState.NEW, self.state self.state = CommandState.ACTIVE try: self.check_initialized() @@ -1275,7 +1275,7 @@ def _start(self) -> None: self._handle_exception(err) def _line_received(self, line: str) -> None: - assert self.state in [CommandState.ACTIVE, CommandState.CANCELLING] + assert self.state in [CommandState.ACTIVE, CommandState.CANCELLING], self.state try: self.line_received(line) except EngineError as err: From 7299216641f5bd0434c06111608892617aa39147 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 31 Jul 2024 22:37:53 +0200 Subject: [PATCH 1770/1831] Immediately dispatch line/termination/finish (fixes #1049, fixes #1071) Avoids races between queued up lines and command finish callbacks. --- CHANGELOG.rst | 2 ++ chess/engine.py | 40 +++++++++++++++++++++++++++------------- test.py | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 754b5d418..9a0a16e6c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -30,6 +30,8 @@ New features: Bugfixes: +* Fix unsolicited engine output may cause assertion errors with regard to + command states. * Fix handling of whitespace in UCI engine communication. * For ``chess.Board.epd()`` and ``chess.Board.set_epd()``, require that EPD opcodes start with a letter. diff --git a/chess/engine.py b/chess/engine.py index 302aa2bbd..ccd6894d2 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -883,7 +883,7 @@ def write(self, data: bytes) -> None: expectation, responses = self.expectations.popleft() assert expectation == line, f"expected {expectation}, got: {line}" if responses: - self.protocol.pipe_data_received(1, "\n".join(responses + [""]).encode("utf-8")) + self.protocol.loop.call_soon(self.protocol.pipe_data_received, 1, "\n".join(responses + [""]).encode("utf-8")) def get_pid(self) -> int: return id(self) @@ -934,12 +934,12 @@ def connection_lost(self, exc: Optional[Exception]) -> None: LOGGER.debug("%s: Connection lost (exit code: %d, error: %s)", self, code, exc) # Terminate commands. - if self.command is not None: - self.command._engine_terminated(code) - self.command = None - if self.next_command is not None: - self.next_command._engine_terminated(code) - self.next_command = None + command, self.command = self.command, None + next_command, self.next_command = self.next_command, None + if command: + command._engine_terminated(code) + if next_command: + next_command._engine_terminated(code) self.returncode.set_result(code) @@ -965,9 +965,9 @@ def pipe_data_received(self, fd: int, data: Union[bytes, str]) -> None: LOGGER.warning("%s: >> %r (%s)", self, bytes(line_bytes), err) else: if fd == 1: - self.loop.call_soon(self._line_received, line) + self._line_received(line) else: - self.loop.call_soon(self.error_line_received, line) + self.error_line_received(line) def error_line_received(self, line: str) -> None: LOGGER.warning("%s: stderr >> %s", self, line) @@ -998,7 +998,7 @@ async def communicate(self, command_factory: Callable[[Self], BaseCommand[T]]) - self.next_command = command - def previous_command_finished(_: Optional[asyncio.Future[None]]) -> None: + def previous_command_finished() -> None: self.command, self.next_command = self.next_command, None if self.command is not None: cmd = self.command @@ -1008,11 +1008,11 @@ def cancel_if_cancelled(result: asyncio.Future[T]) -> None: cmd._cancel() cmd.result.add_done_callback(cancel_if_cancelled) - cmd.finished.add_done_callback(previous_command_finished) cmd._start() + cmd.add_finished_callback(previous_command_finished) if self.command is None: - previous_command_finished(None) + previous_command_finished() elif not self.command.result.done(): self.command.result.cancel() elif not self.command.result.cancelled(): @@ -1228,6 +1228,17 @@ def __init__(self, engine: Protocol) -> None: self.result: asyncio.Future[T] = asyncio.Future() self.finished: asyncio.Future[None] = asyncio.Future() + self._finished_callbacks: List[Callable[[], None]] = [] + + def add_finished_callback(self, callback: Callable[[], None]) -> None: + self._finished_callbacks.append(callback) + self._dispatch_finished() + + def _dispatch_finished(self) -> None: + if self.finished.done(): + while self._finished_callbacks: + self._finished_callbacks.pop()() + def _engine_terminated(self, code: int) -> None: hint = ", binary not compatible with cpu?" if code in [-4, 0xc000001d] else "" exc = EngineTerminatedError(f"engine process died unexpectedly (exit code: {code}{hint})") @@ -1235,6 +1246,7 @@ def _engine_terminated(self, code: int) -> None: self.engine_terminated(exc) elif self.state == CommandState.CANCELLING: self.finished.set_result(None) + self._dispatch_finished() elif self.state == CommandState.NEW: self._handle_exception(exc) @@ -1251,13 +1263,15 @@ def _handle_exception(self, exc: Exception) -> None: if not self.finished.done(): self.finished.set_result(None) + self._dispatch_finished() def set_finished(self) -> None: assert self.state in [CommandState.ACTIVE, CommandState.CANCELLING], self.state if not self.result.done(): self.result.set_exception(EngineError(f"engine command finished before returning result: {self!r}")) - self.finished.set_result(None) self.state = CommandState.DONE + self.finished.set_result(None) + self._dispatch_finished() def _cancel(self) -> None: if self.state != CommandState.CANCELLING and self.state != CommandState.DONE: diff --git a/test.py b/test.py index 00d766a03..438628b98 100755 --- a/test.py +++ b/test.py @@ -3527,6 +3527,24 @@ async def main(): asyncio.run(main()) + def test_uci_output_after_command(self): + async def main(): + protocol = chess.engine.UciProtocol() + mock = chess.engine.MockTransport(protocol) + + mock.expect("uci", [ + "Arasan v24.0.0-10-g367aa9f Copyright 1994-2023 by Jon Dart.", + "All rights reserved.", + "id name Arasan v24.0.0-10-g367aa9f", + "uciok", + "info string out of do_all_pending, list size=0" + ]) + await protocol.initialize() + + mock.assert_done() + + asyncio.run(main()) + def test_hiarcs_bestmove(self): async def main(): protocol = chess.engine.UciProtocol() From 7fa1f1825bc504ad50724e848b0e982b526c9f87 Mon Sep 17 00:00:00 2001 From: Lukas Malte Monnerjahn Date: Thu, 5 Sep 2024 11:31:03 +0200 Subject: [PATCH 1771/1831] SVG: Align pieces, check mark, selected squares and arrows correctly when rendering a border #1103 --- chess/svg.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index 2948b0b80..c665b171b 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -283,6 +283,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, inner_border = 1 if borders and coordinates else 0 outer_border = 1 if borders else 0 margin = 15 if coordinates else 0 + board_offset = inner_border + margin + outer_border full_size = 2 * outer_border + 2 * margin + 2 * inner_border + 8 * SQUARE_SIZE svg = _svg(full_size, size) @@ -351,12 +352,12 @@ def board(board: Optional[chess.BaseBoard] = None, *, if coordinates: coord_color, coord_opacity = _select_color(colors, "coord") for file_index, file_name in enumerate(chess.FILE_NAMES): - x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + inner_border + margin + outer_border + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + board_offset # Keep some padding here to separate the ascender from the border svg.append(_coord(file_name, x, 1, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) svg.append(_coord(file_name, x, full_size - outer_border - margin, SQUARE_SIZE, margin, True, margin, color=coord_color, opacity=coord_opacity)) for rank_index, rank_name in enumerate(chess.RANK_NAMES): - y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + inner_border + margin + outer_border + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + board_offset svg.append(_coord(rank_name, 0, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) svg.append(_coord(rank_name, full_size - outer_border - margin, y, margin, SQUARE_SIZE, False, margin, color=coord_color, opacity=coord_opacity)) @@ -365,8 +366,8 @@ def board(board: Optional[chess.BaseBoard] = None, *, file_index = chess.square_file(square) rank_index = chess.square_rank(square) - x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + inner_border + margin + outer_border - y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + inner_border + margin + outer_border + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + board_offset + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + board_offset cls = ["square", "light" if chess.BB_LIGHT_SQUARES & bb else "dark"] if lastmove and square in [lastmove.from_square, lastmove.to_square]: @@ -406,8 +407,8 @@ def board(board: Optional[chess.BaseBoard] = None, *, file_index = chess.square_file(check) rank_index = chess.square_rank(check) - x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin - y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + board_offset + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + board_offset ET.SubElement(svg, "rect", _attrs({ "x": x, @@ -423,8 +424,8 @@ def board(board: Optional[chess.BaseBoard] = None, *, file_index = chess.square_file(square) rank_index = chess.square_rank(square) - x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + margin - y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + margin + x = (file_index if orientation else 7 - file_index) * SQUARE_SIZE + board_offset + y = (7 - rank_index if orientation else rank_index) * SQUARE_SIZE + board_offset if board is not None: piece = board.piece_at(square) @@ -463,10 +464,10 @@ def board(board: Optional[chess.BaseBoard] = None, *, head_file = chess.square_file(head) head_rank = chess.square_rank(head) - xtail = outer_border + margin + inner_border + (tail_file + 0.5 if orientation else 7.5 - tail_file) * SQUARE_SIZE - ytail = outer_border + margin + inner_border + (7.5 - tail_rank if orientation else tail_rank + 0.5) * SQUARE_SIZE - xhead = outer_border + margin + inner_border + (head_file + 0.5 if orientation else 7.5 - head_file) * SQUARE_SIZE - yhead = outer_border + margin + inner_border + (7.5 - head_rank if orientation else head_rank + 0.5) * SQUARE_SIZE + xtail = board_offset + (tail_file + 0.5 if orientation else 7.5 - tail_file) * SQUARE_SIZE + ytail = board_offset + (7.5 - tail_rank if orientation else tail_rank + 0.5) * SQUARE_SIZE + xhead = board_offset + (head_file + 0.5 if orientation else 7.5 - head_file) * SQUARE_SIZE + yhead = board_offset + (7.5 - head_rank if orientation else head_rank + 0.5) * SQUARE_SIZE if (head_file, head_rank) == (tail_file, tail_rank): ET.SubElement(svg, "circle", _attrs({ From 0e7fabc8ae0127a994aaece31e3c69a510cef527 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 27 Sep 2024 17:37:16 +0200 Subject: [PATCH 1772/1831] Test reading PGN with UTF-8 BOM --- data/pgn/utf8-bom.pgn | 26 ++++++++++++++++++++++++++ test.py | 12 ++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 data/pgn/utf8-bom.pgn diff --git a/data/pgn/utf8-bom.pgn b/data/pgn/utf8-bom.pgn new file mode 100644 index 000000000..665e7775a --- /dev/null +++ b/data/pgn/utf8-bom.pgn @@ -0,0 +1,26 @@ +[Event "A"] +[Site "?"] +[Date "2024.04.25"] +[Round "?"] +[White "White vs 1...c5"] +[Black "?"] +[Result "*"] +[ECO "A00"] +[PlyCount "0"] +[SourceVersionDate "2024.04.25"] + + * + +[Event "B"] +[Site "?"] +[Date "2024.04.25"] +[Round "?"] +[White "White vs 1...c5"] +[Black "?"] +[Result "*"] +[ECO "A00"] +[PlyCount "0"] +[SourceVersionDate "2024.04.25"] + + * + diff --git a/test.py b/test.py index 438628b98..6102eabdb 100755 --- a/test.py +++ b/test.py @@ -2947,6 +2947,18 @@ def end_variation(self): game = chess.pgn.read_game(io.StringIO(pgn)).accept(BlackVariationsOnly()) self.assertEqual(game.accept(chess.pgn.StringExporter(headers=False)), expected_pgn) + def test_utf8_bom(self): + not_utf8_sig = "utf-8" + with open("data/pgn/utf8-bom.pgn", encoding=not_utf8_sig) as pgn: + game = chess.pgn.read_game(pgn) + self.assertEqual(game.headers["Event"], "A") + + game = chess.pgn.read_game(pgn) + self.assertEqual(game.headers["Event"], "B") + + game = chess.pgn.read_game(pgn) + self.assertEqual(game, None) + @unittest.skipIf(sys.platform == "win32" and (3, 8, 0) <= sys.version_info < (3, 8, 1), "https://bugs.python.org/issue34679") class EngineTestCase(unittest.TestCase): From c0d3c9171d22d0168a6cf7a584cdcf50909832e6 Mon Sep 17 00:00:00 2001 From: evidencebp Date: Thu, 3 Oct 2024 14:33:20 +0300 Subject: [PATCH 1773/1831] chess\__init__.py superfluous-parens There are two such alerts in this file. One has two terms and the parentheses do not contribute to readability. The other term is longer and the parenthesis help to readability and therefore are kept. --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 55bd4cad2..9d6e869fe 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -3402,7 +3402,7 @@ def clean_castling_rights(self) -> Bitboard: if white_h_side and msb(white_h_side) < msb(white_king_mask): white_h_side = 0 - black_a_side = (black_castling & -black_castling) + black_a_side = black_castling & -black_castling black_h_side = BB_SQUARES[msb(black_castling)] if black_castling else BB_EMPTY if black_a_side and msb(black_a_side) > msb(black_king_mask): From 30d991046908ce7c5a7929987c1c2081f68641b4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 4 Oct 2024 18:33:54 +0200 Subject: [PATCH 1774/1831] Prepare 1.11.0 --- CHANGELOG.rst | 4 ++-- chess/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9a0a16e6c..296079f24 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,8 @@ Changelog for python-chess ========================== -Upcoming in the next release ----------------------------- +New in v1.11.0 (4th Oct 2024) +----------------------------- Changes: diff --git a/chess/__init__.py b/chess/__init__.py index 9d6e869fe..147f24be7 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -11,7 +11,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.10.0" +__version__ = "1.11.0" import collections import copy From 46c28883f7846f87f419c5c83e7c61e3cdea5d36 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 4 Oct 2024 18:44:53 +0200 Subject: [PATCH 1775/1831] Revert "Removed unnecessary indentation blocks and updated conditional statements." This reverts commit 4a6dd9a89b7810312ab4ea1cf255d1a501ae09ca. --- release.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/release.py b/release.py index f2f7d81fa..d27ddf04e 100755 --- a/release.py +++ b/release.py @@ -10,7 +10,7 @@ def system(command): print(command) exit_code = os.system(command) - if exit_code: + if exit_code != 0: sys.exit(exit_code) @@ -21,7 +21,7 @@ def check_git(): system("git fetch origin") behind = int(subprocess.check_output(["git", "rev-list", "--count", "master..origin/master"])) - if behind: + if behind > 0: print(f"master is {behind} commit(s) behind origin/master") sys.exit(1) @@ -65,14 +65,15 @@ def tag_and_push(): release_txt.write(headline + os.linesep) for line in changelog_file: - if line.startswith("-------") and not first_section: - first_section = True + if not first_section: + if line.startswith("-------"): + first_section = True else: if line.startswith("-------"): break - - if not prev_line.startswith("------"): - release_txt.write(prev_line) + else: + if not prev_line.startswith("------"): + release_txt.write(prev_line) prev_line = line From 08697b298d87e4fa01842bd82af96d71cb972c90 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 4 Oct 2024 18:57:48 +0200 Subject: [PATCH 1776/1831] Fix twine usage, stop uploading wheels --- release.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release.py b/release.py index d27ddf04e..4057ab785 100755 --- a/release.py +++ b/release.py @@ -97,9 +97,9 @@ def tag_and_push(): def pypi(): print("--- PYPI ---------------------------------------------------------") system("rm -rf build") - system("python3 setup.py sdist bdist_wheel") + system("python3 setup.py sdist") system("twine check dist/*") - system("twine upload --skip-existing") + system("twine upload --skip-existing dist/*") def github_release(tagname): From 611221de07fa7679b5d00b712cf8472ce66e6b38 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Mon, 7 Oct 2024 20:08:23 -0700 Subject: [PATCH 1777/1831] Fix error when parsing UCI options The regex that splits a UCI option into parts did not include word boundries, so words like "mini" would be split into "min" and "i", leading to parse errors. This commit puts word boundries into the regex to fix this. Fixes #1112 --- chess/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index ccd6894d2..270e31e71 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1367,7 +1367,8 @@ def _option(self, arg: str) -> None: var = [] parameters = list(option_parts.keys()) + ['var'] - option_regex = fr"\s*({'|'.join(parameters)})\s*" + inner_regex = '|'.join([fr"\b{parameter}\b" for parameter in parameters]) + option_regex = fr"\s*({inner_regex})\s*" for token in re.split(option_regex, arg.strip()): if token == "var" or (token in option_parts and not option_parts[token]): current_parameter = token From 54b18de726e0f1d06f89f35104c66ddeb527fac7 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Mon, 7 Oct 2024 22:38:29 -0700 Subject: [PATCH 1778/1831] Add test for options fix Test uses fairy-stockfish since that engine revealed the original bug. --- test.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test.py b/test.py index 2a1df1c85..9903b208d 100755 --- a/test.py +++ b/test.py @@ -3142,6 +3142,11 @@ def test_sf_quit(self): with self.assertRaises(chess.engine.EngineTerminatedError), engine: engine.ping() + @catchAndSkip(FileNotFoundError, "need fairy-stockfish") + def test_fairy_sf_initialize(self): + with chess.engine.SimpleEngine.popen_uci("fairy-stockfish", setpgrp=True, debug=True): + pass + @catchAndSkip(FileNotFoundError, "need crafty") def test_crafty_play_to_mate(self): logging.disable(logging.WARNING) From ebb687c5dab328d91a055b1f63dabf6c28739ed2 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Mon, 7 Oct 2024 22:58:59 -0700 Subject: [PATCH 1779/1831] Make test functional by installing fairy-stockfish --- .github/workflows/setup-ubuntu-latest.sh | 3 +++ .github/workflows/setup-windows-latest.sh | 6 +++++- tox.ini | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/setup-ubuntu-latest.sh b/.github/workflows/setup-ubuntu-latest.sh index fae35b61a..10b8d1115 100755 --- a/.github/workflows/setup-ubuntu-latest.sh +++ b/.github/workflows/setup-ubuntu-latest.sh @@ -6,6 +6,9 @@ sudo apt-get install -y stockfish # Crafty sudo apt-get install -y crafty +# Fairy-stockfish +sudo apt-get install -y fairy-stockfish + # Gaviota libgtb git clone https://github.com/michiguel/Gaviota-Tablebases.git --depth 1 cd Gaviota-Tablebases diff --git a/.github/workflows/setup-windows-latest.sh b/.github/workflows/setup-windows-latest.sh index 815eb0db2..48037cbef 100755 --- a/.github/workflows/setup-windows-latest.sh +++ b/.github/workflows/setup-windows-latest.sh @@ -1,6 +1,6 @@ #!/bin/sh -e -echo Download ... +echo Download stockfish ... choco install wget wget https://github.com/official-stockfish/Stockfish/releases/download/sf_16/stockfish-windows-x86-64-avx2.zip @@ -10,3 +10,7 @@ echo Unzip .. echo Setup path ... mv stockfish-windows-x86-64-avx2.exe stockfish.exe pwd >> $GITHUB_PATH + +echo Download fairy-stockfish ... +wget https://github.com/fairy-stockfish/Fairy-Stockfish/releases/latest/download/fairy-stockfish-largeboard_x86-64.exe +mv fairy-stockfish-largeboard_x86-64.exe fairy-stockfish.exe diff --git a/tox.ini b/tox.ini index f629723cd..8d8033676 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,7 @@ passenv = LD_LIBRARY_PATH whitelist_externals = stockfish crafty + fairy-stockfish commands = python test.py --verbose python -m doctest README.rst --verbose From c0ac01b784bf1c63abb325424ea9e7bb2cb3f44e Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Mon, 7 Oct 2024 23:13:27 -0700 Subject: [PATCH 1780/1831] Add test using MockTransport --- test.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test.py b/test.py index 9903b208d..e490daa90 100755 --- a/test.py +++ b/test.py @@ -3147,6 +3147,21 @@ def test_fairy_sf_initialize(self): with chess.engine.SimpleEngine.popen_uci("fairy-stockfish", setpgrp=True, debug=True): pass + def test_uci_option_parse(self): + async def main(): + protocol = chess.engine.UciProtocol() + mock = chess.engine.MockTransport(protocol) + + mock.expect("uci", ["option name UCI_Variant type combo default chess var bughouse var chess var mini var minishogi var threekings", "uciok"]) + await protocol.initialize() + mock.assert_done() + + mock.expect("isready", ["readyok"]) + await protocol.ping() + mock.assert_done() + + asyncio.run(main()) + @catchAndSkip(FileNotFoundError, "need crafty") def test_crafty_play_to_mate(self): logging.disable(logging.WARNING) From fa4f0148f683c8e59ffa762f93045f9edfc69994 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 8 Oct 2024 22:07:21 +0200 Subject: [PATCH 1781/1831] Merge pull request #1113 from MarkZH/options-fix Fix error when parsing UCI options --- .github/workflows/setup-ubuntu-latest.sh | 3 +++ .github/workflows/setup-windows-latest.sh | 6 +++++- chess/engine.py | 3 ++- test.py | 20 ++++++++++++++++++++ tox.ini | 1 + 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/setup-ubuntu-latest.sh b/.github/workflows/setup-ubuntu-latest.sh index fae35b61a..10b8d1115 100755 --- a/.github/workflows/setup-ubuntu-latest.sh +++ b/.github/workflows/setup-ubuntu-latest.sh @@ -6,6 +6,9 @@ sudo apt-get install -y stockfish # Crafty sudo apt-get install -y crafty +# Fairy-stockfish +sudo apt-get install -y fairy-stockfish + # Gaviota libgtb git clone https://github.com/michiguel/Gaviota-Tablebases.git --depth 1 cd Gaviota-Tablebases diff --git a/.github/workflows/setup-windows-latest.sh b/.github/workflows/setup-windows-latest.sh index 815eb0db2..48037cbef 100755 --- a/.github/workflows/setup-windows-latest.sh +++ b/.github/workflows/setup-windows-latest.sh @@ -1,6 +1,6 @@ #!/bin/sh -e -echo Download ... +echo Download stockfish ... choco install wget wget https://github.com/official-stockfish/Stockfish/releases/download/sf_16/stockfish-windows-x86-64-avx2.zip @@ -10,3 +10,7 @@ echo Unzip .. echo Setup path ... mv stockfish-windows-x86-64-avx2.exe stockfish.exe pwd >> $GITHUB_PATH + +echo Download fairy-stockfish ... +wget https://github.com/fairy-stockfish/Fairy-Stockfish/releases/latest/download/fairy-stockfish-largeboard_x86-64.exe +mv fairy-stockfish-largeboard_x86-64.exe fairy-stockfish.exe diff --git a/chess/engine.py b/chess/engine.py index ccd6894d2..270e31e71 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1367,7 +1367,8 @@ def _option(self, arg: str) -> None: var = [] parameters = list(option_parts.keys()) + ['var'] - option_regex = fr"\s*({'|'.join(parameters)})\s*" + inner_regex = '|'.join([fr"\b{parameter}\b" for parameter in parameters]) + option_regex = fr"\s*({inner_regex})\s*" for token in re.split(option_regex, arg.strip()): if token == "var" or (token in option_parts and not option_parts[token]): current_parameter = token diff --git a/test.py b/test.py index 6102eabdb..9e2f9d166 100755 --- a/test.py +++ b/test.py @@ -3134,6 +3134,26 @@ def test_sf_quit(self): with self.assertRaises(chess.engine.EngineTerminatedError), engine: engine.ping() + @catchAndSkip(FileNotFoundError, "need fairy-stockfish") + def test_fairy_sf_initialize(self): + with chess.engine.SimpleEngine.popen_uci("fairy-stockfish", setpgrp=True, debug=True): + pass + + def test_uci_option_parse(self): + async def main(): + protocol = chess.engine.UciProtocol() + mock = chess.engine.MockTransport(protocol) + + mock.expect("uci", ["option name UCI_Variant type combo default chess var bughouse var chess var mini var minishogi var threekings", "uciok"]) + await protocol.initialize() + mock.assert_done() + + mock.expect("isready", ["readyok"]) + await protocol.ping() + mock.assert_done() + + asyncio.run(main()) + @catchAndSkip(FileNotFoundError, "need crafty") def test_crafty_play_to_mate(self): logging.disable(logging.WARNING) diff --git a/tox.ini b/tox.ini index f629723cd..8d8033676 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,7 @@ passenv = LD_LIBRARY_PATH whitelist_externals = stockfish crafty + fairy-stockfish commands = python test.py --verbose python -m doctest README.rst --verbose From ffc6da935642654ee13eda3bb649a8748531b960 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 9 Oct 2024 20:24:42 +0200 Subject: [PATCH 1782/1831] Prepare 1.11.1 --- CHANGELOG.rst | 8 ++++++++ chess/__init__.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 296079f24..05b899a20 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ Changelog for python-chess ========================== +New in v1.11.1 (9th Oct 2024) +----------------------------- + +Bugfixes: + +* ``chess.engine``: Fix parsing of UCI options containing containing ``name``, + ``type``, ``default``, ``min``, or ``max``, e.g., ``mini``. + New in v1.11.0 (4th Oct 2024) ----------------------------- diff --git a/chess/__init__.py b/chess/__init__.py index 147f24be7..a6a66500e 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -11,7 +11,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.11.0" +__version__ = "1.11.1" import collections import copy From 7f123cb5dd858978de4a32b7d2c8f8ea71a3552c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 9 Oct 2024 20:35:10 +0200 Subject: [PATCH 1783/1831] Remove chess.svg.board(..., flipped), use orientation (#659) --- chess/svg.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/chess/svg.py b/chess/svg.py index c665b171b..7e8facf99 100644 --- a/chess/svg.py +++ b/chess/svg.py @@ -227,7 +227,6 @@ def board(board: Optional[chess.BaseBoard] = None, *, size: Optional[int] = None, coordinates: bool = True, colors: Dict[str, str] = {}, - flipped: bool = False, borders: bool = False, style: Optional[str] = None) -> str: """ @@ -255,7 +254,6 @@ def board(board: Optional[chess.BaseBoard] = None, *, ``outer border``, ``arrow green``, ``arrow blue``, ``arrow red``, and ``arrow yellow``. Values should look like ``#ffce9e`` (opaque), or ``#15781B80`` (transparent). - :param flipped: Pass ``True`` to flip the board. :param borders: Pass ``True`` to enable a border around the board and, (if *coordinates* is enabled) the coordinate margin. :param style: A CSS stylesheet to include in the SVG image. @@ -275,11 +273,7 @@ def board(board: Optional[chess.BaseBoard] = None, *, .. image:: ../docs/Ne4.svg :alt: 8/8/8/8/4N3/8/8/8 - - .. deprecated:: 1.1 - Use *orientation* with a color instead of the *flipped* toggle. """ - orientation ^= flipped inner_border = 1 if borders and coordinates else 0 outer_border = 1 if borders else 0 margin = 15 if coordinates else 0 From f2b0452389c4272948b253ac6266eb89ac85c179 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 9 Oct 2024 20:37:08 +0200 Subject: [PATCH 1784/1831] Remove deprecated chess.pgn.BaseVisitor.parse_san() (#659) --- chess/pgn.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index bded9ae5d..eddb6bc52 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1104,22 +1104,6 @@ def begin_parse_san(self, board: chess.Board, san: str) -> Optional[SkipType]: """ pass - def parse_san(self, board: chess.Board, san: str) -> chess.Move: - """ - When the visitor is used by a parser, this is called to parse a move - in standard algebraic notation. - - You can override the default implementation to work around specific - quirks of your input format. - - .. deprecated:: 1.1 - This method is very limited, because it is only called on moves - that the parser recognizes in the first place. Instead of adding - workarounds here, please report common quirks so that - they can be handled for everyone. - """ - return board.parse_san(san) - def visit_move(self, board: chess.Board, move: chess.Move) -> None: """ Called for each move. @@ -1751,7 +1735,7 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: # Parse SAN tokens. if visitor.begin_parse_san(board_stack[-1], token) is not SKIP: try: - move = visitor.parse_san(board_stack[-1], token) + move = board_stack[-1].parse_san(token) except ValueError as error: visitor.handle_error(error) skip_variation_depth = 1 From b2657ebc4768e2815cb8ddeb8c9ed13109332e15 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 9 Oct 2024 20:41:43 +0200 Subject: [PATCH 1785/1831] Remove deprecated chess.engine.Wdl tuple behavior (#659) --- chess/engine.py | 45 +-------------------------------------------- test.py | 2 +- 2 files changed, 2 insertions(+), 45 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 270e31e71..64a3926b7 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -720,16 +720,11 @@ def __str__(self) -> str: MateGiven = MateGivenType() +@dataclasses.dataclass class PovWdl: """ Relative :class:`win/draw/loss statistics ` and the point of view. - - .. deprecated:: 1.2 - Behaves like a tuple - ``(wdl.relative.wins, wdl.relative.draws, wdl.relative.losses)`` - for backwards compatibility. But it is recommended to use the provided - fields and methods instead. """ relative: Wdl @@ -738,10 +733,6 @@ class PovWdl: turn: Color """The point of view (``chess.WHITE`` or ``chess.BLACK``).""" - def __init__(self, relative: Wdl, turn: Color) -> None: - self.relative = relative - self.turn = turn - def white(self) -> Wdl: """Gets the :class:`~chess.engine.Wdl` from White's point of view.""" return self.pov(chess.WHITE) @@ -763,30 +754,6 @@ def __bool__(self) -> bool: def __repr__(self) -> str: return "PovWdl({!r}, {})".format(self.relative, "WHITE" if self.turn else "BLACK") - # Unfortunately in python-chess v1.1.0, info["wdl"] was a simple tuple - # of the relative permille values, so we have to support __iter__, - # __len__, __getitem__, and equality comparisons with other tuples. - # Never mind the ordering, because that's not a sensible operation, anyway. - - def __iter__(self) -> Iterator[int]: - yield self.relative.wins - yield self.relative.draws - yield self.relative.losses - - def __len__(self) -> int: - return 3 - - def __getitem__(self, idx: int) -> int: - return (self.relative.wins, self.relative.draws, self.relative.losses)[idx] - - def __eq__(self, other: object) -> bool: - if isinstance(other, PovWdl): - return self.white() == other.white() - elif isinstance(other, tuple): - return (self.relative.wins, self.relative.draws, self.relative.losses) == other - else: - return NotImplemented - @dataclasses.dataclass class Wdl: @@ -830,16 +797,6 @@ def expectation(self) -> float: def __bool__(self) -> bool: return bool(self.total()) - def __iter__(self) -> Iterator[int]: - yield self.wins - yield self.draws - yield self.losses - - def __reversed__(self) -> Iterator[int]: - yield self.losses - yield self.draws - yield self.wins - def __pos__(self) -> Wdl: return self diff --git a/test.py b/test.py index e490daa90..68904a50e 100755 --- a/test.py +++ b/test.py @@ -3540,7 +3540,7 @@ def test_uci_info(self): # WDL (activated with UCI_ShowWDL). info = chess.engine._parse_uci_info("depth 1 seldepth 2 time 16 nodes 1 score cp 72 wdl 249 747 4 hashfull 0 nps 400 tbhits 0 multipv 1", board) - self.assertEqual(info["wdl"], (249, 747, 4)) + self.assertEqual(info["wdl"].white(), chess.engine.Wdl(249, 747, 4)) def test_uci_result(self): async def main(): From 6228bac55b8e680362f35e69c1c72a4d53d00cf4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 12 Oct 2024 20:50:29 +0200 Subject: [PATCH 1786/1831] Update Sphinx --- docs/requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 7516f64de..c04e3554a 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -Sphinx==7.3.6 +Sphinx==8.1.2 sphinxcontrib-jquery==4.1 -sphinx-rtd-theme==1.3.0 +sphinx-rtd-theme==3.0.1 From e2041699939d7ae08811fe7a1391e8910d5ec62a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 13 Oct 2024 11:12:49 +0200 Subject: [PATCH 1787/1831] Towards passing pyright --- chess/__init__.py | 10 +++++++--- chess/engine.py | 2 +- chess/syzygy.py | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 147f24be7..4f5791f7c 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1218,6 +1218,8 @@ def _set_chess960_pos(self, scharnagl: int) -> None: n, bb = divmod(n, 4) n, q = divmod(n, 6) + n1 = 0 + n2 = 0 for n1 in range(0, 4): n2 = n + (3 - n1) * (4 - n1) // 2 - 5 if n1 < n2 and 1 <= n2 <= 4: @@ -2394,7 +2396,7 @@ def push(self, move: Move) -> None: elif move.to_square == ep_square and abs(diff) in [7, 9] and not captured_piece_type: # Remove pawns captured en passant. down = -8 if self.turn == WHITE else 8 - capture_square = ep_square + down + capture_square = move.to_square + down captured_piece_type = self._remove_piece_at(capture_square) # Promotion. @@ -3166,6 +3168,8 @@ def parse_san(self, san: str) -> Move: # Filter by original square. from_mask = BB_ALL + from_file = None + from_rank = None if match.group(2): from_file = FILE_NAMES.index(match.group(2)) from_mask &= BB_FILES[from_file] @@ -3177,7 +3181,7 @@ def parse_san(self, san: str) -> Move: if match.group(1): piece_type = PIECE_SYMBOLS.index(match.group(1).lower()) from_mask &= self.pieces_mask(piece_type, self.turn) - elif match.group(2) and match.group(3): + elif from_file is not None and from_rank is not None: # Allow fully specified moves, even if they are not pawn moves, # including castling moves. move = self.find_move(square(from_file, from_rank), to_square, promotion) @@ -3189,7 +3193,7 @@ def parse_san(self, san: str) -> Move: from_mask &= self.pawns # Do not allow pawn captures if file is not specified. - if not match.group(2): + if from_file is None: from_mask &= BB_FILES[square_file(to_square)] # Match legal moves. diff --git a/chess/engine.py b/chess/engine.py index 64a3926b7..c961d0da1 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -826,7 +826,7 @@ def get_pipe_transport(self, fd: int) -> Optional[asyncio.BaseTransport]: assert fd == 0, f"expected 0 for stdin, got {fd}" return self - def write(self, data: bytes) -> None: + def write(self, data: bytes | bytearray | memoryview) -> None: self.stdin_buffer.extend(data) while b"\n" in self.stdin_buffer: line_bytes, self.stdin_buffer = self.stdin_buffer.split(b"\n", 1) diff --git a/chess/syzygy.py b/chess/syzygy.py index 77a6eeded..89f8c2596 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -780,6 +780,7 @@ def encode_piece(self, norm: List[int], pos: List[chess.Square], factor: List[in for i in range(n): pos[i] ^= 0x38 + i = 0 for i in range(n): if offdiag(pos[i]): break From c42749dee7e06f1215ad159d58452d571810b8db Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 13 Oct 2024 11:49:05 +0200 Subject: [PATCH 1788/1831] Make chess.engine.Protocol.options an abstract property --- chess/engine.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index c961d0da1..3f1e0e399 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -852,9 +852,6 @@ def get_returncode(self) -> Optional[int]: class Protocol(asyncio.SubprocessProtocol, metaclass=abc.ABCMeta): """Protocol for communicating with a chess engine process.""" - options: MutableMapping[str, Option] - """Dictionary of available options.""" - id: Dict[str, str] """ Dictionary of information about the engine. Common keys are ``name`` @@ -981,6 +978,11 @@ def __repr__(self) -> str: pid = self.transport.get_pid() if self.transport is not None else "?" return f"<{type(self).__name__} (pid={pid})>" + @property + @abc.abstractmethod + def options(self) -> MutableMapping[str, Option]: + """Dictionary of available options.""" + @abc.abstractmethod async def initialize(self) -> None: """Initializes the engine.""" @@ -1281,7 +1283,7 @@ class UciProtocol(Protocol): def __init__(self) -> None: super().__init__() - self.options: UciOptionMap[Option] = UciOptionMap() + self._options: UciOptionMap[Option] = UciOptionMap() self.config: UciOptionMap[ConfigValue] = UciOptionMap() self.target_config: UciOptionMap[ConfigValue] = UciOptionMap() self.id = {} @@ -1291,6 +1293,11 @@ def __init__(self) -> None: self.may_ponderhit: Optional[chess.Board] = None self.ponderhit = False + @property + @override + def options(self) -> UciOptionMap[Option]: + return self._options + async def initialize(self) -> None: class UciInitializeCommand(BaseCommand[None]): def __init__(self, engine: UciProtocol): @@ -1939,7 +1946,7 @@ def __init__(self) -> None: super().__init__() self.features: Dict[str, Union[int, str]] = {} self.id = {} - self.options = { + self._options = { "random": Option("random", "check", False, None, None, None), "computer": Option("computer", "check", False, None, None, None), "name": Option("name", "string", "", None, None, None), @@ -1953,6 +1960,11 @@ def __init__(self) -> None: self.clock_id: object = None self.first_game = True + @property + @override + def options(self) -> Dict[str, Option]: + return self._options + async def initialize(self) -> None: class XBoardInitializeCommand(BaseCommand[None]): def __init__(self, engine: XBoardProtocol): From 7553d4115f69368e2d7bf07a90773cea128d7d11 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 13 Oct 2024 12:35:01 +0200 Subject: [PATCH 1789/1831] Make chess.pgn.GameNode pass pyright subtyping check --- chess/pgn.py | 65 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index eddb6bc52..20e95de50 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -16,7 +16,11 @@ from chess import Color, Square if typing.TYPE_CHECKING: - from typing_extensions import Self + from typing_extensions import Self, override +else: + F = typing.TypeVar("F", bound=Callable[..., Any]) + def override(fn: F, /) -> F: + return fn LOGGER = logging.getLogger(__name__) @@ -192,15 +196,6 @@ def __init__(self, node: ChildNode, *, is_variation: bool = False, sidelines: bo class GameNode(abc.ABC): - parent: Optional[GameNode] - """The parent node or ``None`` if this is the root node of the game.""" - - move: Optional[chess.Move] - """ - The move leading to this node or ``None`` if this is the root node of the - game. - """ - variations: List[ChildNode] """A list of child nodes.""" @@ -215,8 +210,6 @@ class GameNode(abc.ABC): nags: Set[int] def __init__(self, *, comment: Union[str, list[str]] = "") -> None: - self.parent = None - self.move = None self.variations = [] self.comments = _standardize_comments(comment) @@ -225,6 +218,19 @@ def __init__(self, *, comment: Union[str, list[str]] = "") -> None: self.starting_comments = [] self.nags = set() + @property + @abc.abstractmethod + def parent(self) -> Optional[GameNode]: + """The parent node or ``None`` if this is the root node of the game.""" + + @property + @abc.abstractmethod + def move(self) -> Optional[chess.Move]: + """ + The move leading to this node or ``None`` if this is the root node of + the game. + """ + @abc.abstractmethod def board(self) -> chess.Board: """ @@ -658,12 +664,6 @@ class ChildNode(GameNode): Extends :class:`~chess.pgn.GameNode`. """ - parent: GameNode - """The parent node.""" - - move: chess.Move - """The move leading to this node.""" - starting_comments: list[str] """ A comment for the start of a variation. Only nodes that @@ -680,13 +680,25 @@ class ChildNode(GameNode): def __init__(self, parent: GameNode, move: chess.Move, *, comment: Union[str, list[str]] = "", starting_comment: Union[str, list[str]] = "", nags: Iterable[int] = []) -> None: super().__init__(comment=comment) - self.parent = parent - self.move = move + self._parent = parent + self._move = move self.parent.variations.append(self) self.nags.update(nags) self.starting_comments = _standardize_comments(starting_comment) + @property + @override + def parent(self) -> GameNode: + """The parent node.""" + return self._parent + + @property + @override + def move(self) -> chess.Move: + """The move leading to this node.""" + return self._move + def board(self) -> chess.Board: stack: List[chess.Move] = [] node: GameNode = self @@ -838,9 +850,21 @@ def __init__(self, headers: Optional[Union[Mapping[str, str], Iterable[Tuple[str self.headers = Headers(headers) self.errors = [] + @property + @override + def parent(self) -> None: + return None + + @property + @override + def move(self) -> None: + return None + + @override def board(self) -> chess.Board: return self.headers.board() + @override def ply(self) -> int: # Optimization: Parse FEN only for custom starting positions. return self.board().ply() if "FEN" in self.headers else 0 @@ -873,6 +897,7 @@ def setup(self, board: Union[chess.Board, str]) -> None: else: self.headers.pop("Variant", None) + @override def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: """ Traverses the game in PGN order using the given *visitor*. Returns From f7736478cbe6e99bb77a7719bfafa79e9a40eef0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 13 Oct 2024 12:35:28 +0200 Subject: [PATCH 1790/1831] Initialize board_stack even on skip_game path --- chess/pgn.py | 1 + 1 file changed, 1 insertion(+) diff --git a/chess/pgn.py b/chess/pgn.py index 20e95de50..11d7aa760 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -1575,6 +1575,7 @@ def read_game(handle: TextIO, *, Visitor: Any = GameBuilder) -> Any: skipping_game = False managed_headers: Optional[Headers] = None unmanaged_headers: Optional[Headers] = None + board_stack: List[chess.Board] = [] # Ignore leading empty lines and comments. line = handle.readline().lstrip("\ufeff") From 0c8fed280f5d0ea237dc5a667081665d65412643 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 13 Oct 2024 12:42:13 +0200 Subject: [PATCH 1791/1831] Fix builder constructor typing --- chess/pgn.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/chess/pgn.py b/chess/pgn.py index 11d7aa760..f40980d48 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -699,6 +699,7 @@ def move(self) -> chess.Move: """The move leading to this node.""" return self._move + @override def board(self) -> chess.Board: stack: List[chess.Move] = [] node: GameNode = self @@ -714,6 +715,7 @@ def board(self) -> chess.Board: return board + @override def ply(self) -> int: ply = 0 node: GameNode = self @@ -744,6 +746,7 @@ def uci(self, *, chess960: Optional[bool] = None) -> str: """ return self.parent.board().uci(self.move, chess960=chess960) + @override def end(self) -> ChildNode: """ Follows the main variation to the end and returns the last node. @@ -801,6 +804,7 @@ def _accept(self, parent_board: chess.Board, visitor: BaseVisitor[ResultT], *, s else: stack.pop() + @override def accept(self, visitor: BaseVisitor[ResultT]) -> ResultT: self._accept(self.parent.board(), visitor, sidelines=False) return visitor.result() @@ -1192,10 +1196,11 @@ class GameBuilder(BaseVisitor[GameT]): @typing.overload def __init__(self: GameBuilder[Game]) -> None: ... @typing.overload - def __init__(self: GameBuilder[GameT], *, Game: Type[GameT]) -> None: ... + def __init__(self, *, Game: Type[GameT]) -> None: ... def __init__(self, *, Game: Any = Game) -> None: self.Game = Game + @override def begin_game(self) -> None: self.game: GameT = self.Game() @@ -1203,28 +1208,35 @@ def begin_game(self) -> None: self.starting_comments: list[str] = [] self.in_variation = False + @override def begin_headers(self) -> Headers: return self.game.headers + @override def visit_header(self, tagname: str, tagvalue: str) -> None: self.game.headers[tagname] = tagvalue + @override def visit_nag(self, nag: int) -> None: self.variation_stack[-1].nags.add(nag) + @override def begin_variation(self) -> None: parent = self.variation_stack[-1].parent assert parent is not None, "begin_variation called, but root node on top of stack" self.variation_stack.append(parent) self.in_variation = False + @override def end_variation(self) -> None: self.variation_stack.pop() + @override def visit_result(self, result: str) -> None: if self.game.headers.get("Result", "*") == "*": self.game.headers["Result"] = result + @override def visit_comment(self, comment: Union[str, list[str]]) -> None: comments = _standardize_comments(comment) if self.in_variation or (self.variation_stack[-1].parent is None and self.variation_stack[-1].is_end()): @@ -1238,12 +1250,14 @@ def visit_comment(self, comment: Union[str, list[str]]) -> None: self.starting_comments.extend(comments) self.starting_comments = list(filter(None, self.starting_comments)) + @override def visit_move(self, board: chess.Board, move: chess.Move) -> None: self.variation_stack[-1] = self.variation_stack[-1].add_variation(move) self.variation_stack[-1].starting_comments = self.starting_comments self.starting_comments = [] self.in_variation = True + @override def handle_error(self, error: Exception) -> None: """ Populates :data:`chess.pgn.Game.errors` with encountered errors and @@ -1277,6 +1291,7 @@ def handle_error(self, error: Exception) -> None: LOGGER.error("%s while parsing %r", error, self.game) self.game.errors.append(error) + @override def result(self) -> GameT: """ Returns the visited :class:`~chess.pgn.Game()`. @@ -1290,20 +1305,24 @@ class HeadersBuilder(BaseVisitor[HeadersT]): @typing.overload def __init__(self: HeadersBuilder[Headers]) -> None: ... @typing.overload - def __init__(self: HeadersBuilder[HeadersT], *, Headers: Type[Headers]) -> None: ... + def __init__(self, *, Headers: Type[HeadersT]) -> None: ... def __init__(self, *, Headers: Any = Headers) -> None: self.Headers = Headers + @override def begin_headers(self) -> HeadersT: self.headers: HeadersT = self.Headers({}) return self.headers + @override def visit_header(self, tagname: str, tagvalue: str) -> None: self.headers[tagname] = tagvalue + @override def end_headers(self) -> SkipType: return SKIP + @override def result(self) -> HeadersT: return self.headers @@ -1314,20 +1333,25 @@ class BoardBuilder(BaseVisitor[chess.Board]): on the move stack. """ + @override def begin_game(self) -> None: self.skip_variation_depth = 0 + @override def begin_variation(self) -> SkipType: self.skip_variation_depth += 1 return SKIP + @override def end_variation(self) -> None: self.skip_variation_depth = max(self.skip_variation_depth - 1, 0) + @override def visit_board(self, board: chess.Board) -> None: if not self.skip_variation_depth: self.board = board + @override def result(self) -> chess.Board: return self.board @@ -1335,15 +1359,19 @@ def result(self) -> chess.Board: class SkipVisitor(BaseVisitor[Literal[True]]): """Skips a game.""" + @override def begin_game(self) -> SkipType: return SKIP + @override def end_headers(self) -> SkipType: return SKIP + @override def begin_variation(self) -> SkipType: return SKIP + @override def result(self) -> Literal[True]: return True @@ -1458,6 +1486,7 @@ class StringExporter(StringExporterMixin, BaseVisitor[str]): There will be no newline characters at the end of the string. """ + @override def result(self) -> str: if self.current_line: return "\n".join(itertools.chain(self.lines, [self.current_line.rstrip()])).rstrip() @@ -1489,6 +1518,7 @@ def __init__(self, handle: TextIO, *, columns: Optional[int] = 80, headers: bool super().__init__(columns=columns, headers=headers, comments=comments, variations=variations) self.handle = handle + @override def begin_game(self) -> None: self.written: int = 0 super().begin_game() @@ -1504,6 +1534,7 @@ def write_line(self, line: str = "") -> None: self.written += self.handle.write(line.rstrip()) self.written += self.handle.write("\n") + @override def result(self) -> int: return self.written From ef13fdbfdb03a10e520a834b32e8a6cac988323a Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 13 Oct 2024 12:44:42 +0200 Subject: [PATCH 1792/1831] Run pyright in CI --- .github/workflows/test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 576d8b491..ffe0c4bc5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,7 +35,7 @@ jobs: - run: python examples/perft/perft.py -t 1 --variant horde examples/perft/horde.perft - run: python examples/perft/perft.py -t 1 --variant crazyhouse examples/perft/crazyhouse.perft - run: python examples/perft/perft.py -t 1 --variant 3check examples/perft/3check.perft - mypy: + typing: strategy: matrix: os: [ubuntu-latest, windows-latest] @@ -50,6 +50,9 @@ jobs: - run: pip install mypy - run: python -m mypy --strict chess - run: python -m mypy --strict examples/**/*.py + - run: pip install pyright + - run: python -m pyright chess + - run: python -m pyright --strict examples/**/*.py readme: runs-on: ubuntu-latest steps: From 100b1c8b21846c0a9db2f237621368e02294da5f Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 13 Oct 2024 12:45:44 +0200 Subject: [PATCH 1793/1831] Fixup pyright usage in CI --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ffe0c4bc5..035b7f3d1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,7 +52,7 @@ jobs: - run: python -m mypy --strict examples/**/*.py - run: pip install pyright - run: python -m pyright chess - - run: python -m pyright --strict examples/**/*.py + - run: python -m pyright examples/**/*.py readme: runs-on: ubuntu-latest steps: From 4549a1dd5d58661c89ea7a0fd33ae2a3d8e308d8 Mon Sep 17 00:00:00 2001 From: Alexander Lyashuk Date: Sat, 26 Oct 2024 11:36:00 +0200 Subject: [PATCH 1794/1831] Add 'movesleft' parameter to UCI info parsing --- chess/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 3f1e0e399..b979b278f 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1771,7 +1771,8 @@ def _parse_uci_info(arg: str, root_board: chess.Board, selector: Info = INFO_ALL if parameter == "string": info["string"] = remaining_line break - elif parameter in ["depth", "seldepth", "nodes", "multipv", "currmovenumber", "hashfull", "nps", "tbhits", "cpuload"]: + elif parameter in ["depth", "seldepth", "nodes", "multipv", "currmovenumber", + "hashfull", "nps", "tbhits", "cpuload", "movesleft"]: try: number, remaining_line = _next_token(remaining_line) info[parameter] = int(number) # type: ignore From f1676d51191dbc36cc7d03b4de4da34526e99f88 Mon Sep 17 00:00:00 2001 From: Alexander Lyashuk Date: Sat, 26 Oct 2024 11:41:50 +0200 Subject: [PATCH 1795/1831] Added a test. --- test.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index 68904a50e..6db84d254 100755 --- a/test.py +++ b/test.py @@ -3508,14 +3508,15 @@ def test_uci_info(self): self.assertEqual(info["seldepth"], 8) self.assertEqual(info["score"], chess.engine.PovScore(chess.engine.Mate(+3), chess.WHITE)) - # Info: tbhits, cpuload, hashfull, time, nodes, nps. - info = chess.engine._parse_uci_info("tbhits 123 cpuload 456 hashfull 789 time 987 nodes 654 nps 321", board) + # Info: tbhits, cpuload, hashfull, time, nodes, nps, movesleft. + info = chess.engine._parse_uci_info("tbhits 123 cpuload 456 hashfull 789 movesleft 42 time 987 nodes 654 nps 321", board) self.assertEqual(info["tbhits"], 123) self.assertEqual(info["cpuload"], 456) self.assertEqual(info["hashfull"], 789) self.assertEqual(info["time"], 0.987) self.assertEqual(info["nodes"], 654) self.assertEqual(info["nps"], 321) + self.assertEqual(info["movesleft"], 42) # Hakkapeliitta double spaces. info = chess.engine._parse_uci_info("depth 10 seldepth 9 score cp 22 time 17 nodes 48299 nps 2683000 tbhits 0", board) From 518d662e5467c13630cfe98f9b99e720775d80b1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 9 Nov 2024 13:20:59 +0100 Subject: [PATCH 1796/1831] Accept a1a1 as UCI null move (used by lc0, closes #1119) --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index 4f5791f7c..fdd52ed07 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -705,7 +705,7 @@ def from_uci(cls, uci: str) -> Move: promotion = PIECE_SYMBOLS.index(uci[4]) if len(uci) == 5 else None except ValueError: raise InvalidMoveError(f"invalid uci: {uci!r}") - if from_square == to_square: + if from_square == to_square and from_square != A1: raise InvalidMoveError(f"invalid uci (use 0000 for null moves): {uci!r}") return cls(from_square, to_square, promotion=promotion) else: From 78c765b4dd1741df3a569c3cd96a079d06298823 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 20 Dec 2024 20:25:50 +0100 Subject: [PATCH 1797/1831] Simplify portable os.O_BINARY access --- chess/polyglot.py | 2 +- chess/syzygy.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/polyglot.py b/chess/polyglot.py index 44a68caa5..a7d6807c4 100644 --- a/chess/polyglot.py +++ b/chess/polyglot.py @@ -324,7 +324,7 @@ class MemoryMappedReader: """Maps a Polyglot opening book to memory.""" def __init__(self, filename: StrOrBytesPath) -> None: - fd = os.open(filename, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) + fd = os.open(filename, os.O_RDONLY | getattr(os, "O_BINARY", 0)) try: self.mmap: Union[mmap.mmap, _EmptyMmap] = mmap.mmap(fd, 0, access=mmap.ACCESS_READ) except (ValueError, OSError): diff --git a/chess/syzygy.py b/chess/syzygy.py index 89f8c2596..5ead9922c 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -587,7 +587,7 @@ def __init__(self, path: str, *, variant: Type[chess.Board] = chess.Board) -> No def init_mmap(self) -> None: if self.data is None: - fd = os.open(self.path, os.O_RDONLY | os.O_BINARY if hasattr(os, "O_BINARY") else os.O_RDONLY) + fd = os.open(self.path, os.O_RDONLY | getattr(os, "O_BINARY", 0)) try: data = mmap.mmap(fd, 0, access=mmap.ACCESS_READ) finally: From ea87e07a22e65bc3b541f2beaefd83e4477d20d1 Mon Sep 17 00:00:00 2001 From: Manan Date: Tue, 31 Dec 2024 18:09:35 +0530 Subject: [PATCH 1798/1831] Update __init__.py Removed redundant `Generic` import from `chess/__init__.py` --- chess/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index b01a2e478..8d0a68258 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -22,7 +22,7 @@ import itertools import typing -from typing import ClassVar, Callable, Counter, Dict, Generic, Hashable, Iterable, Iterator, List, Literal, Mapping, Optional, SupportsInt, Tuple, Type, TypeVar, Union +from typing import ClassVar, Callable, Counter, Dict, Hashable, Iterable, Iterator, List, Literal, Mapping, Optional, SupportsInt, Tuple, Type, TypeVar, Union if typing.TYPE_CHECKING: from typing_extensions import Self, TypeAlias From 5f76cb296a10a81672cbf60368a62e2c85adedec Mon Sep 17 00:00:00 2001 From: Adrien Barbaresi Date: Sun, 5 Jan 2025 17:42:33 +0100 Subject: [PATCH 1799/1831] gaviota.py: simplify and improve code --- chess/gaviota.py | 553 +++++++++++++++-------------------------------- 1 file changed, 179 insertions(+), 374 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index 39173b593..8cfd40d1e 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -11,11 +11,12 @@ import struct import typing -import chess - +from itertools import accumulate from types import TracebackType from typing import BinaryIO, Callable, Dict, List, Optional, Tuple, Type, Union +import chess + LOGGER = logging.getLogger(__name__) @@ -109,30 +110,19 @@ def idx_is_empty(x: int) -> int: def flip_type(x: chess.Square, y: chess.Square) -> int: ret = 0 + file_x, rank_x = chess.square_file(x), chess.square_rank(x) + file_y, rank_y = chess.square_file(y), chess.square_rank(y) - if chess.square_file(x) > 3: - x = flip_we(x) - y = flip_we(y) + if file_x > 3: + x, y = flip_we(x), flip_we(y) ret |= 1 - if chess.square_rank(x) > 3: - x = flip_ns(x) - y = flip_ns(y) + if rank_x > 3: + x, y = flip_ns(x), flip_ns(y) ret |= 2 - rowx = chess.square_rank(x) - colx = chess.square_file(x) - - if rowx > colx: - x = flip_nw_se(x) - y = flip_nw_se(y) - ret |= 4 - - rowy = chess.square_rank(y) - coly = chess.square_file(y) - if rowx == colx and rowy > coly: - x = flip_nw_se(x) - y = flip_nw_se(y) + if (rank_x, file_x) > (rank_y, file_y): + x, y = flip_nw_se(x), flip_nw_se(y) ret |= 4 return ret @@ -145,7 +135,6 @@ def init_flipt() -> List[List[int]]: def init_pp48_idx() -> Tuple[List[List[int]], List[int], List[int]]: MAX_I = MAX_J = 48 - idx = 0 pp48_idx = [[-1] * MAX_J for _ in range(MAX_I)] pp48_sq_x = [NOSQUARE] * MAX_PP48_INDEX pp48_sq_y = [NOSQUARE] * MAX_PP48_INDEX @@ -157,10 +146,8 @@ def init_pp48_idx() -> Tuple[List[List[int]], List[int], List[int]]: j = flip_we(flip_ns(b)) - 8 if idx_is_empty(pp48_idx[i][j]): - pp48_idx[i][j] = idx - pp48_idx[j][i] = idx - pp48_sq_x[idx] = i - pp48_sq_y[idx] = j + pp48_idx[i][j] = pp48_idx[j][i] = idx + pp48_sq_x[idx], pp48_sq_y[idx] = i, j idx += 1 return pp48_idx, pp48_sq_x, pp48_sq_y @@ -179,26 +166,15 @@ def init_ppp48_idx() -> Tuple[List[List[List[int]]], List[int], List[int], List[ for x in range(48): for y in range(x + 1, 48): for z in range(y + 1, 48): - a = ITOSQ[x] - b = ITOSQ[y] - c = ITOSQ[z] - if not in_queenside(b) or not in_queenside(c): + if not (in_queenside(ITOSQ[y]) and in_queenside(ITOSQ[z])): continue - i = a - 8 - j = b - 8 - k = c - 8 + i, j, k = ITOSQ[x] - 8, ITOSQ[y] - 8, ITOSQ[z] - 8 if idx_is_empty(ppp48_idx[i][j][k]): - ppp48_idx[i][j][k] = idx - ppp48_idx[i][k][j] = idx - ppp48_idx[j][i][k] = idx - ppp48_idx[j][k][i] = idx - ppp48_idx[k][i][j] = idx - ppp48_idx[k][j][i] = idx - ppp48_sq_x[idx] = i - ppp48_sq_y[idx] = j - ppp48_sq_z[idx] = k + for p in [(i, j, k), (i, k, j), (j, i, k), (j, k, i), (k, i, j), (k, j, i)]: + ppp48_idx[p[0]][p[1]][p[2]] = idx + ppp48_sq_x[idx], ppp48_sq_y[idx], ppp48_sq_z[idx] = i, j, k idx += 1 return ppp48_idx, ppp48_sq_x, ppp48_sq_y, ppp48_sq_z @@ -216,8 +192,7 @@ def init_aaidx() -> Tuple[List[int], List[List[int]]]: if idx_is_empty(aaidx[x][y]): # Still empty. - aaidx[x][y] = idx - aaidx[y][x] = idx + aaidx[x][y] = aaidx[y][x] = idx aabase[idx] = x idx += 1 @@ -229,24 +204,10 @@ def init_aaidx() -> Tuple[List[int], List[List[int]]]: def init_aaa() -> Tuple[List[int], List[List[int]]]: # Get aaa_base. comb = [a * (a - 1) // 2 for a in range(64)] - - accum = 0 - aaa_base = [0] * 64 - for a in range(64 - 1): - accum += comb[a] - aaa_base[a + 1] = accum + aaa_base = list(accumulate(comb)) # Get aaa_xyz. - aaa_xyz = [[-1] * 3 for _ in range(MAX_AAAINDEX)] - - idx = 0 - for z in range(64): - for y in range(z): - for x in range(y): - aaa_xyz[idx][0] = x - aaa_xyz[idx][1] = y - aaa_xyz[idx][2] = z - idx += 1 + aaa_xyz = [[x, y, z] for z in range(64) for y in range(z) for x in range(y)] return aaa_base, aaa_xyz @@ -351,34 +312,33 @@ def init_ppidx() -> Tuple[List[List[int]], List[int], List[int]]: def norm_kkindex(x: chess.Square, y: chess.Square) -> Tuple[int, int]: - if chess.square_file(x) > 3: - x = flip_we(x) - y = flip_we(y) + file_x, rank_x = chess.square_file(x), chess.square_rank(x) + + if file_x > 3: + x, y = flip_we(x), flip_we(y) - if chess.square_rank(x) > 3: - x = flip_ns(x) - y = flip_ns(y) + if rank_x > 3: + x, y = flip_ns(x), flip_ns(y) rowx = chess.square_rank(x) colx = chess.square_file(x) if rowx > colx: - x = flip_nw_se(x) - y = flip_nw_se(y) + x, y = flip_nw_se(x), flip_nw_se(y) rowy = chess.square_rank(y) coly = chess.square_file(y) if rowx == colx and rowy > coly: - x = flip_nw_se(x) - y = flip_nw_se(y) + x, y = flip_nw_se(x), flip_nw_se(y) return x, y + def init_kkidx() -> Tuple[List[List[int]], List[int], List[int]]: kkidx = [[-1] * 64 for _ in range(64)] - bksq = [-1] * MAX_KKINDEX - wksq = [-1] * MAX_KKINDEX + bksq, wksq = [-1] * MAX_KKINDEX, [-1] * MAX_KKINDEX + idx = 0 for x in range(64): for y in range(64): @@ -388,10 +348,8 @@ def init_kkidx() -> Tuple[List[List[int]], List[int], List[int]]: i, j = norm_kkindex(x, y) if idx_is_empty(kkidx[i][j]): - kkidx[i][j] = idx - kkidx[x][y] = idx - bksq[idx] = i - wksq[idx] = j + kkidx[i][j] = kkidx[x][y] = idx + bksq[idx], wksq[idx] = i, j idx += 1 return kkidx, wksq, bksq @@ -404,20 +362,12 @@ def kxk_pctoindex(c: Request) -> int: ft = flip_type(c.black_piece_squares[0], c.white_piece_squares[0]) - ws = c.white_piece_squares - bs = c.black_piece_squares - - if (ft & 1) != 0: - ws = [flip_we(b) for b in ws] - bs = [flip_we(b) for b in bs] - - if (ft & 2) != 0: - ws = [flip_ns(b) for b in ws] - bs = [flip_ns(b) for b in bs] + ws, bs = c.white_piece_squares, c.black_piece_squares - if (ft & 4) != 0: - ws = [flip_nw_se(b) for b in ws] - bs = [flip_nw_se(b) for b in bs] + for f, flip in [(1, flip_we), (2, flip_ns), (4, flip_nw_se)]: + if ft & f: + ws = [flip(b) for b in ws] + bs = [flip(b) for b in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] @@ -426,6 +376,14 @@ def kxk_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ws[1] + +def flip_we_col(*pieces: int) -> tuple[int, ...]: + if (pieces[0] & 7) > 3: + # Column is more than 3, i.e., e, f, g or h. + pieces = tuple(flip_we(piece) for piece in pieces) + return pieces + + def kapkb_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 * 64 BLOCK_B = 64 * 64 * 64 @@ -438,24 +396,17 @@ def kapkb_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] ba = c.black_piece_squares[1] - if not (chess.A2 <= pawn < chess.A8): + if not chess.A2 <= pawn < chess.A8: return NOINDEX - if (pawn & 7) > 3: - # Column is more than 3, i.e., e, f, g or h. - pawn = flip_we(pawn) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) - ba = flip_we(ba) + pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) - sq = pawn - sq ^= 56 # flip_ns - sq -= 8 # Down one row - pslice = (sq + (sq & 3)) >> 1 + # flip_ns, down one row + pslice = ((pawn ^ 56) - 8 + (pawn & 3)) >> 1 return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa * BLOCK_D + ba + def kabpk_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 * 64 BLOCK_B = 64 * 64 * 64 @@ -468,18 +419,13 @@ def kabpk_pctoindex(c: Request) -> int: pawn = c.white_piece_squares[3] bk = c.black_piece_squares[0] - if (pawn & 7) > 3: - # Column is more than 3, i.e., e, f, g or h. - pawn = flip_we(pawn) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) - wb = flip_we(wb) + pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) pslice = wsq_to_pidx24(pawn) return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa * BLOCK_D + wb + def kabkp_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 * 64 BLOCK_B = 64 * 64 * 64 @@ -492,23 +438,17 @@ def kabkp_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] wb = c.white_piece_squares[2] - if not (chess.A2 <= pawn < chess.A8): + if not chess.A2 <= pawn < chess.A8: return NOINDEX - if (pawn & 7) > 3: - # Column is more than 3, i.e., e, f, g or h. - pawn = flip_we(pawn) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) - wb = flip_we(wb) + pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) - sq = pawn - sq -= 8 # Down one row - pslice = (sq + (sq & 3)) >> 1 + # Down one row + pslice = ((pawn - 8) + (pawn & 3)) >> 1 return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa * BLOCK_D + wb + def kaapk_pctoindex(c: Request) -> int: BLOCK_C = MAX_AAINDEX BLOCK_B = 64 * BLOCK_C @@ -520,13 +460,7 @@ def kaapk_pctoindex(c: Request) -> int: pawn = c.white_piece_squares[3] bk = c.black_piece_squares[0] - if (pawn & 7) > 3: - # Column is more than 3, i.e., e, f, g or h. - pawn = flip_we(pawn) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) - wa2 = flip_we(wa2) + pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) pslice = wsq_to_pidx24(pawn) @@ -537,6 +471,7 @@ def kaapk_pctoindex(c: Request) -> int: return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + aa_combo + def kaakp_pctoindex(c: Request) -> int: BLOCK_C = MAX_AAINDEX BLOCK_B = 64 * BLOCK_C @@ -548,13 +483,7 @@ def kaakp_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] pawn = c.black_piece_squares[1] - if (pawn & 7) > 3: - # Column is more than 3, i.e., e, f, g or h. - pawn = flip_we(pawn) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) - wa2 = flip_we(wa2) + pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) pawn = flip_ns(pawn) pslice = wsq_to_pidx24(pawn) @@ -566,6 +495,7 @@ def kaakp_pctoindex(c: Request) -> int: return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + aa_combo + def kapkp_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 BLOCK_B = 64 * 64 @@ -573,30 +503,20 @@ def kapkp_pctoindex(c: Request) -> int: wk = c.white_piece_squares[0] wa = c.white_piece_squares[1] - pawn_a = c.white_piece_squares[2] + anchor = c.white_piece_squares[2] bk = c.black_piece_squares[0] - pawn_b = c.black_piece_squares[1] - - anchor = pawn_a - loosen = pawn_b + loosen = c.black_piece_squares[1] - if (anchor & 7) > 3: - # Column is more than 3, i.e., e, f, g or h. - anchor = flip_we(anchor) - loosen = flip_we(loosen) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) + anchor, loosen, wk, bk, wa = flip_we_col(anchor, loosen, wk, bk, wa) - m = wsq_to_pidx24(anchor) - n = loosen - 8 - pp_slice = m * 48 + n + pp_slice = wsq_to_pidx24(anchor) * 48 + loosen - 8 if idx_is_empty(pp_slice): return NOINDEX return pp_slice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa + def kappk_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 BLOCK_B = 64 * 64 @@ -610,13 +530,7 @@ def kappk_pctoindex(c: Request) -> int: anchor, loosen = pp_putanchorfirst(pawn_a, pawn_b) - if (anchor & 7) > 3: - # Column is more than 3, i.e., e, f, g or h. - anchor = flip_we(anchor) - loosen = flip_we(loosen) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) + anchor, loosen, wk, bk, wa = flip_we_col(anchor, loosen, wk, bk, wa) i = wsq_to_pidx24(anchor) j = wsq_to_pidx48(loosen) @@ -628,6 +542,7 @@ def kappk_pctoindex(c: Request) -> int: return pp_slice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa + def kppka_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 BLOCK_B = 64 * 64 @@ -641,12 +556,7 @@ def kppka_pctoindex(c: Request) -> int: anchor, loosen = pp_putanchorfirst(pawn_a, pawn_b) - if (anchor & 7) > 3: - anchor = flip_we(anchor) - loosen = flip_we(loosen) - wk = flip_we(wk) - bk = flip_we(bk) - ba = flip_we(ba) + anchor, loosen, wk, bk, wa = flip_we_col(anchor, loosen, wk, bk, wa) i = wsq_to_pidx24(anchor) j = wsq_to_pidx48(loosen) @@ -658,6 +568,7 @@ def kppka_pctoindex(c: Request) -> int: return pp_slice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + ba + def kabck_pctoindex(c: Request) -> int: N_WHITE = 4 N_BLACK = 1 @@ -689,6 +600,7 @@ def kabck_pctoindex(c: Request) -> int: return ki * BLOCK_A + ws[1] * BLOCK_B + ws[2] * BLOCK_C + ws[3] + def kabbk_pctoindex(c: Request) -> int: N_WHITE = 4 N_BLACK = 1 @@ -720,6 +632,7 @@ def kabbk_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai * BLOCK_Bx + ws[1] + def kaabk_pctoindex(c: Request) -> int: N_WHITE = 4 N_BLACK = 1 @@ -751,45 +664,23 @@ def kaabk_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai * BLOCK_Bx + ws[3] + def aaa_getsubi(x: int, y: int, z: int) -> int: - bse = AAA_BASE[z] - calc_idx = x + (y - 1) * y // 2 + bse - return calc_idx + return x + (y - 1) * y // 2 + AAA_BASE[z] + def kaaak_pctoindex(c: Request) -> int: - N_WHITE = 4 - N_BLACK = 1 BLOCK_Ax = MAX_AAAINDEX - - ws = c.white_piece_squares[:N_WHITE] - bs = c.black_piece_squares[:N_BLACK] - + ws = c.white_piece_squares[:4] + bs = c.black_piece_squares[:1] ft = FLIPT[c.black_piece_squares[0]][c.white_piece_squares[0]] - if (ft & WE_FLAG) != 0: - ws = [flip_we(i) for i in ws] - bs = [flip_we(i) for i in bs] - - if (ft & NS_FLAG) != 0: - ws = [flip_ns(i) for i in ws] - bs = [flip_ns(i) for i in bs] + for flag, flip in [(WE_FLAG, flip_we), (NS_FLAG, flip_ns), (NW_SE_FLAG, flip_nw_se)]: + if ft & flag: + ws = [flip(i) for i in ws] + bs = [flip(i) for i in bs] - if (ft & NW_SE_FLAG) != 0: - ws = [flip_nw_se(i) for i in ws] - bs = [flip_nw_se(i) for i in bs] - - if ws[2] < ws[1]: - tmp = ws[1] - ws[1] = ws[2] - ws[2] = tmp - if ws[3] < ws[2]: - tmp = ws[2] - ws[2] = ws[3] - ws[3] = tmp - if ws[2] < ws[1]: - tmp = ws[1] - ws[1] = ws[2] - ws[2] = tmp + ws[1:4] = sorted(ws[1:4]) ki = KKIDX[bs[0]][ws[0]] @@ -803,6 +694,7 @@ def kaaak_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai + def kppkp_pctoindex(c: Request) -> int: BLOCK_Ax = MAX_PP48_INDEX * 64 * 64 BLOCK_Bx = 64 * 64 @@ -814,12 +706,7 @@ def kppkp_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] pawn_c = c.black_piece_squares[1] - if (pawn_c & 7) > 3: - wk = flip_we(wk) - pawn_a = flip_we(pawn_a) - pawn_b = flip_we(pawn_b) - bk = flip_we(bk) - pawn_c = flip_we(pawn_c) + pawn_c, wk, pawn_a, pawn_b, bk = flip_we_col(pawn_c, wk, pawn_a, pawn_b, bk) i = flip_we(flip_ns(pawn_a)) - 8 j = flip_we(flip_ns(pawn_b)) - 8 @@ -834,28 +721,19 @@ def kppkp_pctoindex(c: Request) -> int: return k * BLOCK_Ax + pp48_slice * BLOCK_Bx + wk * BLOCK_Cx + bk + def kaakb_pctoindex(c: Request) -> int: - N_WHITE = 3 - N_BLACK = 2 BLOCK_Bx = 64 BLOCK_Ax = BLOCK_Bx * MAX_AAINDEX + ws = c.white_piece_squares[:3] + bs = c.black_piece_squares[:2] ft = FLIPT[c.black_piece_squares[0]][c.white_piece_squares[0]] - ws = c.white_piece_squares[:N_WHITE] - bs = c.black_piece_squares[:N_BLACK] - - if (ft & WE_FLAG) != 0: - ws = [flip_we(i) for i in ws] - bs = [flip_we(i) for i in bs] - - if (ft & NS_FLAG) != 0: - ws = [flip_ns(i) for i in ws] - bs = [flip_ns(i) for i in bs] - - if (ft & NW_SE_FLAG) != 0: - ws = [flip_nw_se(i) for i in ws] - bs = [flip_nw_se(i) for i in bs] + for flag, flip in [(WE_FLAG, flip_we), (NS_FLAG, flip_ns), (NW_SE_FLAG, flip_nw_se)]: + if ft & flag: + ws = [flip(i) for i in ws] + bs = [flip(i) for i in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] ai = AAIDX[ws[1]][ws[2]] @@ -865,6 +743,7 @@ def kaakb_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai * BLOCK_Bx + bs[1] + def kabkc_pctoindex(c: Request) -> int: N_WHITE = 3 N_BLACK = 2 @@ -878,17 +757,10 @@ def kabkc_pctoindex(c: Request) -> int: ws = c.white_piece_squares[:N_WHITE] bs = c.black_piece_squares[:N_BLACK] - if (ft & WE_FLAG) != 0: - ws = [flip_we(i) for i in ws] - bs = [flip_we(i) for i in bs] - - if (ft & NS_FLAG) != 0: - ws = [flip_ns(i) for i in ws] - bs = [flip_ns(i) for i in bs] - - if (ft & NW_SE_FLAG) != 0: - ws = [flip_nw_se(i) for i in ws] - bs = [flip_nw_se(i) for i in bs] + for flag, flip in [(WE_FLAG, flip_we), (NS_FLAG, flip_ns), (NW_SE_FLAG, flip_nw_se)]: + if ft & flag: + ws = [flip(i) for i in ws] + bs = [flip(i) for i in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX [black king] [white king] @@ -897,23 +769,17 @@ def kabkc_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ws[1] * BLOCK_Bx + ws[2] * BLOCK_Cx + bs[1] + def kpkp_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 BLOCK_Bx = 64 wk = c.white_piece_squares[0] bk = c.black_piece_squares[0] - pawn_a = c.white_piece_squares[1] - pawn_b = c.black_piece_squares[1] + anchor = c.white_piece_squares[1] + loosen = c.black_piece_squares[1] - anchor = pawn_a - loosen = pawn_b - - if (anchor & 7) > 3: - anchor = flip_we(anchor) - loosen = flip_we(loosen) - wk = flip_we(wk) - bk = flip_we(bk) + anchor, loosen, wk, bk = flip_we_col(anchor, loosen, wk, bk) m = wsq_to_pidx24(anchor) n = loosen - 8 @@ -925,6 +791,7 @@ def kpkp_pctoindex(c: Request) -> int: return pp_slice * BLOCK_Ax + wk * BLOCK_Bx + bk + def kppk_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 BLOCK_Bx = 64 @@ -935,11 +802,7 @@ def kppk_pctoindex(c: Request) -> int: anchor, loosen = pp_putanchorfirst(pawn_a, pawn_b) - if (anchor & 7) > 3: - anchor = flip_we(anchor) - loosen = flip_we(loosen) - wk = flip_we(wk) - bk = flip_we(bk) + anchor, loosen, wk, bk = flip_we_col(anchor, loosen, wk, bk) i = wsq_to_pidx24(anchor) j = wsq_to_pidx48(loosen) @@ -951,6 +814,7 @@ def kppk_pctoindex(c: Request) -> int: return pp_slice * BLOCK_Ax + wk * BLOCK_Bx + bk + def kapk_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 * 64 BLOCK_Bx = 64 * 64 @@ -961,22 +825,17 @@ def kapk_pctoindex(c: Request) -> int: wk = c.white_piece_squares[0] bk = c.black_piece_squares[0] - if not (chess.A2 <= pawn < chess.A8): + if not chess.A2 <= pawn < chess.A8: return NOINDEX - if (pawn & 7) > 3: - pawn = flip_we(pawn) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) + pawn, wk, bk, wa = flip_we_col(pawn, wk, bk, wa) - sq = pawn - sq ^= 56 # flip_ns - sq -= 8 # Down one row + sq = pawn ^ 56 - 8 # flip_ns and down one row pslice = ((sq + (sq & 3)) >> 1) return pslice * BLOCK_Ax + wk * BLOCK_Bx + bk * BLOCK_Cx + wa + def kabk_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 BLOCK_Bx = 64 @@ -986,17 +845,10 @@ def kabk_pctoindex(c: Request) -> int: ws = c.white_piece_squares bs = c.black_piece_squares - if (ft & 1) != 0: - ws = [flip_we(b) for b in ws] - bs = [flip_we(b) for b in bs] - - if (ft & 2) != 0: - ws = [flip_ns(b) for b in ws] - bs = [flip_ns(b) for b in bs] - - if (ft & 4) != 0: - ws = [flip_nw_se(b) for b in ws] - bs = [flip_nw_se(b) for b in bs] + for flag, flip in [(1, flip_we), (2, flip_ns), (4, flip_nw_se)]: + if ft & flag: + ws = [flip(b) for b in ws] + bs = [flip(b) for b in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] @@ -1005,6 +857,7 @@ def kabk_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ws[1] * BLOCK_Bx + ws[2] + def kakp_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 * 64 BLOCK_Bx = 64 * 64 @@ -1015,42 +868,29 @@ def kakp_pctoindex(c: Request) -> int: wk = c.white_piece_squares[0] bk = c.black_piece_squares[0] - if not (chess.A2 <= pawn < chess.A8): + if not chess.A2 <= pawn < chess.A8: return NOINDEX - if (pawn & 7) > 3: - pawn = flip_we(pawn) - wk = flip_we(wk) - bk = flip_we(bk) - wa = flip_we(wa) + pawn, wk, bk, wa = flip_we_col(pawn, wk, bk, wa) - sq = pawn - sq -= 8 # Down one row - pslice = (sq + (sq & 3)) >> 1 + # Down one row + pslice = ((pawn - 8) + ((pawn - 8) & 3)) >> 1 return pslice * BLOCK_Ax + wk * BLOCK_Bx + bk * BLOCK_Cx + wa + def kaak_pctoindex(c: Request) -> int: - N_WHITE = 3 - N_BLACK = 1 BLOCK_Ax = MAX_AAINDEX ft = FLIPT[c.black_piece_squares[0]][c.white_piece_squares[0]] - ws = c.white_piece_squares[:N_WHITE] - bs = c.black_piece_squares[:N_BLACK] - - if (ft & WE_FLAG) != 0: - ws = [flip_we(i) for i in ws] - bs = [flip_we(i) for i in bs] + ws = c.white_piece_squares[:3] + bs = c.black_piece_squares[:1] - if (ft & NS_FLAG) != 0: - ws = [flip_ns(i) for i in ws] - bs = [flip_ns(i) for i in bs] - - if (ft & NW_SE_FLAG) != 0: - ws = [flip_nw_se(i) for i in ws] - bs = [flip_nw_se(i) for i in bs] + for flag, flip in [(WE_FLAG, flip_we), (NS_FLAG, flip_ns), (NW_SE_FLAG, flip_nw_se)]: + if ft & flag: + ws = [flip(i) for i in ws] + bs = [flip(i) for i in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] ai = AAIDX[ws[1]][ws[2]] @@ -1060,6 +900,7 @@ def kaak_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai + def kakb_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 BLOCK_Bx = 64 @@ -1069,23 +910,9 @@ def kakb_pctoindex(c: Request) -> int: ws = c.white_piece_squares[:] bs = c.black_piece_squares[:] - if (ft & 1) != 0: - ws[0] = flip_we(ws[0]) - ws[1] = flip_we(ws[1]) - bs[0] = flip_we(bs[0]) - bs[1] = flip_we(bs[1]) - - if (ft & 2) != 0: - ws[0] = flip_ns(ws[0]) - ws[1] = flip_ns(ws[1]) - bs[0] = flip_ns(bs[0]) - bs[1] = flip_ns(bs[1]) - - if (ft & 4) != 0: - ws[0] = flip_nw_se(ws[0]) - ws[1] = flip_nw_se(ws[1]) - bs[0] = flip_nw_se(bs[0]) - bs[1] = flip_nw_se(bs[1]) + for bit, flip in [(1, flip_we), (2, flip_ns), (4, flip_nw_se)]: + if ft & bit: + ws[0], ws[1], bs[0], bs[1] = flip(ws[0]), flip(ws[1]), flip(bs[0]), flip(bs[1]) ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] @@ -1094,6 +921,7 @@ def kakb_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ws[1] * BLOCK_Bx + bs[1] + def kpk_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 BLOCK_B = 64 @@ -1102,21 +930,16 @@ def kpk_pctoindex(c: Request) -> int: wk = c.white_piece_squares[0] bk = c.black_piece_squares[0] - if not (chess.A2 <= pawn < chess.A8): + if not chess.A2 <= pawn < chess.A8: return NOINDEX - if (pawn & 7) > 3: - pawn = flip_we(pawn) - wk = flip_we(wk) - bk = flip_we(bk) + pawn, wk, bk = flip_we_col(pawn, wk, bk) - sq = pawn - sq ^= 56 # flip_ns - sq -= 8 # Down one row + sq = (pawn ^ 56) - 8 # flip_ns, down one row pslice = ((sq + (sq & 3)) >> 1) - res = pslice * BLOCK_A + wk * BLOCK_B + bk - return res + return pslice * BLOCK_A + wk * BLOCK_B + bk + def kpppk_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 @@ -1126,26 +949,16 @@ def kpppk_pctoindex(c: Request) -> int: pawn_a = c.white_piece_squares[1] pawn_b = c.white_piece_squares[2] pawn_c = c.white_piece_squares[3] - bk = c.black_piece_squares[0] - i = pawn_a - 8 - j = pawn_b - 8 - k = pawn_c - 8 - + i, j, k = [x - 8 for x in (pawn_a, pawn_b, pawn_c)] ppp48_slice = PPP48_IDX[i][j][k] if idx_is_empty(ppp48_slice): - wk = flip_we(wk) - pawn_a = flip_we(pawn_a) - pawn_b = flip_we(pawn_b) - pawn_c = flip_we(pawn_c) - bk = flip_we(bk) - - i = pawn_a - 8 - j = pawn_b - 8 - k = pawn_c - 8 + wk, pawn_a, pawn_b, pawn_c, bk = [flip_we(x) for x in (wk, pawn_a, pawn_b, pawn_c, bk)] + # removing this doesn't impact the tests? + i, j, k = [x - 8 for x in (pawn_a, pawn_b, pawn_c)] ppp48_slice = PPP48_IDX[i][j][k] if idx_is_empty(ppp48_slice): @@ -1330,13 +1143,15 @@ def __init__(self, maxindex: int, slice_n: int, pctoi: Callable[[Request], int]) def sortlists(ws: List[int], wp: List[int]) -> Tuple[List[int], List[int]]: - z = sorted(zip(wp, ws), key=lambda x: x[0], reverse=True) + z = sorted(zip(wp, ws), reverse=True) wp2, ws2 = zip(*z) return list(ws2), list(wp2) + def egtb_block_unpack(side: int, n: int, bp: bytes) -> List[int]: return [dtm_unpack(side, i) for i in bp[:n]] + def split_index(i: int) -> Tuple[int, int]: return divmod(i, ENTRIES_PER_BLOCK) @@ -1360,19 +1175,23 @@ def removepiece(ys: List[int], yp: List[int], j: int) -> None: del ys[j] del yp[j] + def opp(side: int) -> int: return 1 if side == 0 else 0 -def adjust_up(dist: int) -> int: - udist = dist - sw = udist & INFOMASK - if sw in [iWMATE, iWMATEt, iBMATE, iBMATEt]: - udist += (1 << PLYSHIFT) +def adjust_up(dist: int) -> int: + if (dist & INFOMASK) in [iWMATE, iWMATEt, iBMATE, iBMATEt]: + return dist + (1 << PLYSHIFT) + return dist - return udist def bestx(side: int, a: int, b: int) -> int: + if a == iFORBID: + return b + if b == iFORBID: + return a + # 0 = selectfirst # 1 = selectlowest # 2 = selecthighest @@ -1385,33 +1204,25 @@ def bestx(side: int, a: int, b: int) -> int: [3, 3, 3, 0], # forbid ] - xorkey = [0, 3] - - if a == iFORBID: - return b - if b == iFORBID: - return a - retu = [a, a, b, b] if b < a: - retu[1] = b - retu[2] = a + retu[1:2] = [b, a] - key = comparison[a & 3][b & 3] ^ xorkey[side] + key = comparison[a & 3][b & 3] ^ [0, 3][side] # ^ xorkey return retu[key] + def unpackdist(d: int) -> Tuple[int, int]: return d >> PLYSHIFT, d & INFOMASK -def dtm_unpack(stm: int, packed: int) -> int: - p = packed - if p in [iDRAW, iFORBID]: - return p +def dtm_unpack(stm: int, packed: int) -> int: + if packed in [iDRAW, iFORBID]: + return packed - info = p & 3 - store = p >> 2 + info = packed & 3 + store = packed >> 2 if stm == 0: if info == iWMATE: @@ -1587,28 +1398,23 @@ def probe_dtm(self, board: chess.Board) -> int: if req.realside == 1: if req.is_reversed: return ply - else: - return -ply - else: - if req.is_reversed: - return -ply - else: - return ply - elif res == iBMATE: + return -ply + if req.is_reversed: + return -ply + return ply + + if res == iBMATE: # Black mates in the stored position. if req.realside == 0: if req.is_reversed: return ply - else: - return -ply - else: - if req.is_reversed: - return -ply - else: - return ply - else: - # Draw. - return 0 + return -ply + if req.is_reversed: + return -ply + return ply + + # Draw. + return 0 def get_dtm(self, board: chess.Board, default: Optional[int] = None) -> Optional[int]: try: @@ -1644,12 +1450,12 @@ def probe_wdl(self, board: chess.Board) -> int: if dtm == 0: if board.is_checkmate(): return -1 - else: - return 0 - elif dtm > 0: + return 0 + + if dtm > 0: return 1 - else: - return -1 + + return -1 def get_wdl(self, board: chess.Board, default: Optional[int] = None) -> Optional[int]: try: @@ -1795,8 +1601,7 @@ def egtb_block_getsize(self, req: Request, idx: int) -> int: if (offset + blocksz) > maxindex: return maxindex - offset # Last block size - else: - return blocksz # Size of a normal block + return blocksz # Size of a normal block def _tb_probe(self, req: Request) -> int: stream = self._setup_tablebase(req) From 4849537943da0cf3aa839770af2fa9f4c1432424 Mon Sep 17 00:00:00 2001 From: Adrien Barbaresi Date: Sun, 5 Jan 2025 17:49:53 +0100 Subject: [PATCH 1800/1831] fix mypy errors --- chess/gaviota.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index 8cfd40d1e..9abe11bcb 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -419,7 +419,7 @@ def kabpk_pctoindex(c: Request) -> int: pawn = c.white_piece_squares[3] bk = c.black_piece_squares[0] - pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) + pawn, wk, bk, wa, wb = flip_we_col(pawn, wk, bk, wa, wb) pslice = wsq_to_pidx24(pawn) @@ -441,7 +441,7 @@ def kabkp_pctoindex(c: Request) -> int: if not chess.A2 <= pawn < chess.A8: return NOINDEX - pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) + pawn, wk, bk, wa, wb = flip_we_col(pawn, wk, bk, wa, wb) # Down one row pslice = ((pawn - 8) + (pawn & 3)) >> 1 @@ -460,7 +460,7 @@ def kaapk_pctoindex(c: Request) -> int: pawn = c.white_piece_squares[3] bk = c.black_piece_squares[0] - pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) + pawn, wk, bk, wa, wa2 = flip_we_col(pawn, wk, bk, wa, wa2) pslice = wsq_to_pidx24(pawn) @@ -483,7 +483,7 @@ def kaakp_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] pawn = c.black_piece_squares[1] - pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) + pawn, wk, bk, wa, wa2 = flip_we_col(pawn, wk, bk, wa, wa2) pawn = flip_ns(pawn) pslice = wsq_to_pidx24(pawn) @@ -556,7 +556,7 @@ def kppka_pctoindex(c: Request) -> int: anchor, loosen = pp_putanchorfirst(pawn_a, pawn_b) - anchor, loosen, wk, bk, wa = flip_we_col(anchor, loosen, wk, bk, wa) + anchor, loosen, wk, bk, ba = flip_we_col(anchor, loosen, wk, bk, ba) i = wsq_to_pidx24(anchor) j = wsq_to_pidx48(loosen) From 08b6647d6fd5b6a512bbc9e1ab50222073f697bc Mon Sep 17 00:00:00 2001 From: Adrien Barbaresi Date: Mon, 6 Jan 2025 13:59:45 +0100 Subject: [PATCH 1801/1831] add permutations --- chess/gaviota.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index 9abe11bcb..a3372f04e 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -11,7 +11,7 @@ import struct import typing -from itertools import accumulate +from itertools import accumulate, permutations from types import TracebackType from typing import BinaryIO, Callable, Dict, List, Optional, Tuple, Type, Union @@ -172,8 +172,8 @@ def init_ppp48_idx() -> Tuple[List[List[List[int]]], List[int], List[int], List[ i, j, k = ITOSQ[x] - 8, ITOSQ[y] - 8, ITOSQ[z] - 8 if idx_is_empty(ppp48_idx[i][j][k]): - for p in [(i, j, k), (i, k, j), (j, i, k), (j, k, i), (k, i, j), (k, j, i)]: - ppp48_idx[p[0]][p[1]][p[2]] = idx + for ii, jj, kk in permutations((i, j, k)): + ppp48_idx[ii][jj][kk] = idx ppp48_sq_x[idx], ppp48_sq_y[idx], ppp48_sq_z[idx] = i, j, k idx += 1 From bbf2a05e6b6e3a83651b4333584940bc652cdea2 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Wed, 8 Jan 2025 20:30:04 +0100 Subject: [PATCH 1802/1831] Update source of Gaviota tables --- data/gaviota/SOURCE.txt | 290 +++++++++++++++++------------------ data/gaviota/TEST-SOURCE.txt | 94 ++++++------ 2 files changed, 192 insertions(+), 192 deletions(-) diff --git a/data/gaviota/SOURCE.txt b/data/gaviota/SOURCE.txt index dda9c83c7..706756322 100644 --- a/data/gaviota/SOURCE.txt +++ b/data/gaviota/SOURCE.txt @@ -1,145 +1,145 @@ -https://syzygy-tables.info/gaviota/kbk.gtb.cp4 -https://syzygy-tables.info/gaviota/knk.gtb.cp4 -https://syzygy-tables.info/gaviota/kpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqk.gtb.cp4 -https://syzygy-tables.info/gaviota/krk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kbkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kbkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbpk.gtb.cp4 -https://syzygy-tables.info/gaviota/knkn.gtb.cp4 -https://syzygy-tables.info/gaviota/knkp.gtb.cp4 -https://syzygy-tables.info/gaviota/knnk.gtb.cp4 -https://syzygy-tables.info/gaviota/knpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kpkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kppk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrk.gtb.cp4 -https://syzygy-tables.info/gaviota/krbk.gtb.cp4 -https://syzygy-tables.info/gaviota/krkb.gtb.cp4 -https://syzygy-tables.info/gaviota/krkn.gtb.cp4 -https://syzygy-tables.info/gaviota/krkp.gtb.cp4 -https://syzygy-tables.info/gaviota/krkr.gtb.cp4 -https://syzygy-tables.info/gaviota/krnk.gtb.cp4 -https://syzygy-tables.info/gaviota/krpk.gtb.cp4 -https://syzygy-tables.info/gaviota/krrk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbbpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbpkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kbpkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kbpkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kbpkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kbpkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kbppk.gtb.cp4 -https://syzygy-tables.info/gaviota/knnkb.gtb.cp4 -https://syzygy-tables.info/gaviota/knnkn.gtb.cp4 -https://syzygy-tables.info/gaviota/knnkp.gtb.cp4 -https://syzygy-tables.info/gaviota/knnkq.gtb.cp4 -https://syzygy-tables.info/gaviota/knnkr.gtb.cp4 -https://syzygy-tables.info/gaviota/knnnk.gtb.cp4 -https://syzygy-tables.info/gaviota/knnpk.gtb.cp4 -https://syzygy-tables.info/gaviota/knpkb.gtb.cp4 -https://syzygy-tables.info/gaviota/knpkn.gtb.cp4 -https://syzygy-tables.info/gaviota/knpkp.gtb.cp4 -https://syzygy-tables.info/gaviota/knpkq.gtb.cp4 -https://syzygy-tables.info/gaviota/knpkr.gtb.cp4 -https://syzygy-tables.info/gaviota/knppk.gtb.cp4 -https://syzygy-tables.info/gaviota/kppkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kppkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kppkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kppkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kppkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kpppk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqpkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kqpkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kqpkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kqpkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kqpkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kqppk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqqk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqrk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrrk.gtb.cp4 -https://syzygy-tables.info/gaviota/krbbk.gtb.cp4 -https://syzygy-tables.info/gaviota/krbkb.gtb.cp4 -https://syzygy-tables.info/gaviota/krbkn.gtb.cp4 -https://syzygy-tables.info/gaviota/krbkp.gtb.cp4 -https://syzygy-tables.info/gaviota/krbkq.gtb.cp4 -https://syzygy-tables.info/gaviota/krbkr.gtb.cp4 -https://syzygy-tables.info/gaviota/krbnk.gtb.cp4 -https://syzygy-tables.info/gaviota/krbpk.gtb.cp4 -https://syzygy-tables.info/gaviota/krnkb.gtb.cp4 -https://syzygy-tables.info/gaviota/krnkn.gtb.cp4 -https://syzygy-tables.info/gaviota/krnkp.gtb.cp4 -https://syzygy-tables.info/gaviota/krnkq.gtb.cp4 -https://syzygy-tables.info/gaviota/krnkr.gtb.cp4 -https://syzygy-tables.info/gaviota/krnnk.gtb.cp4 -https://syzygy-tables.info/gaviota/krnpk.gtb.cp4 -https://syzygy-tables.info/gaviota/krpkb.gtb.cp4 -https://syzygy-tables.info/gaviota/krpkn.gtb.cp4 -https://syzygy-tables.info/gaviota/krpkp.gtb.cp4 -https://syzygy-tables.info/gaviota/krpkq.gtb.cp4 -https://syzygy-tables.info/gaviota/krpkr.gtb.cp4 -https://syzygy-tables.info/gaviota/krppk.gtb.cp4 -https://syzygy-tables.info/gaviota/krrbk.gtb.cp4 -https://syzygy-tables.info/gaviota/krrkb.gtb.cp4 -https://syzygy-tables.info/gaviota/krrkn.gtb.cp4 -https://syzygy-tables.info/gaviota/krrkp.gtb.cp4 -https://syzygy-tables.info/gaviota/krrkq.gtb.cp4 -https://syzygy-tables.info/gaviota/krrkr.gtb.cp4 -https://syzygy-tables.info/gaviota/krrnk.gtb.cp4 -https://syzygy-tables.info/gaviota/krrpk.gtb.cp4 -https://syzygy-tables.info/gaviota/krrrk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kpkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbpkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbpkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbpkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbpkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbpkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knpkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knpkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knpkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knpkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knpkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kpppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqpkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqpkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqpkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqpkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqpkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqqk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqrk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrrk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krpkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krpkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krpkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krpkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krpkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrrk.gtb.cp4 diff --git a/data/gaviota/TEST-SOURCE.txt b/data/gaviota/TEST-SOURCE.txt index f7d29a546..36c83d39a 100644 --- a/data/gaviota/TEST-SOURCE.txt +++ b/data/gaviota/TEST-SOURCE.txt @@ -1,47 +1,47 @@ -https://syzygy-tables.info/gaviota/kbbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kbkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kbkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbpk.gtb.cp4 -https://syzygy-tables.info/gaviota/knkn.gtb.cp4 -https://syzygy-tables.info/gaviota/knkp.gtb.cp4 -https://syzygy-tables.info/gaviota/knnk.gtb.cp4 -https://syzygy-tables.info/gaviota/knpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kpkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kppk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkb.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkq.gtb.cp4 -https://syzygy-tables.info/gaviota/kqkr.gtb.cp4 -https://syzygy-tables.info/gaviota/kqnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqpk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqqk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrk.gtb.cp4 -https://syzygy-tables.info/gaviota/krbk.gtb.cp4 -https://syzygy-tables.info/gaviota/krkb.gtb.cp4 -https://syzygy-tables.info/gaviota/krkn.gtb.cp4 -https://syzygy-tables.info/gaviota/krkp.gtb.cp4 -https://syzygy-tables.info/gaviota/krkr.gtb.cp4 -https://syzygy-tables.info/gaviota/krnk.gtb.cp4 -https://syzygy-tables.info/gaviota/krpk.gtb.cp4 -https://syzygy-tables.info/gaviota/krrk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqrnk.gtb.cp4 -https://syzygy-tables.info/gaviota/krpkn.gtb.cp4 -https://syzygy-tables.info/gaviota/kbpkp.gtb.cp4 -https://syzygy-tables.info/gaviota/krrpk.gtb.cp4 -https://syzygy-tables.info/gaviota/knppk.gtb.cp4 -https://syzygy-tables.info/gaviota/kbnkb.gtb.cp4 -https://syzygy-tables.info/gaviota/knnkn.gtb.cp4 -https://syzygy-tables.info/gaviota/krrnk.gtb.cp4 -https://syzygy-tables.info/gaviota/kqbbk.gtb.cp4 -https://syzygy-tables.info/gaviota/kppkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kppkq.gtb.cp4 -https://syzygy-tables.info/gaviota/krrrk.gtb.cp4 -https://syzygy-tables.info/gaviota/krnkp.gtb.cp4 -https://syzygy-tables.info/gaviota/kpppk.gtb.cp4 -https://syzygy-tables.info/gaviota/knnkp.gtb.cp4 -https://syzygy-tables.info/gaviota/krnpk.gtb.cp4 -https://syzygy-tables.info/gaviota/knpkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kpkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqqk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krkr.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqrnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krpkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbpkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kbnkb.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnkn.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrnk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kqbbk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kppkq.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krrrk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/kpppk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knnkp.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/krnpk.gtb.cp4 +https://tablebase.lichess.ovh/tables/standard/Gaviota/knpkp.gtb.cp4 From 3a974697b31e39ea8ad7e115350dc190464d7a76 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Jan 2025 15:50:27 +0100 Subject: [PATCH 1803/1831] Use import from only for types --- chess/gaviota.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index a3372f04e..0bbe41b81 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -4,6 +4,7 @@ import ctypes.util import dataclasses import fnmatch +import itertools import logging import lzma import os @@ -11,7 +12,6 @@ import struct import typing -from itertools import accumulate, permutations from types import TracebackType from typing import BinaryIO, Callable, Dict, List, Optional, Tuple, Type, Union @@ -172,7 +172,7 @@ def init_ppp48_idx() -> Tuple[List[List[List[int]]], List[int], List[int], List[ i, j, k = ITOSQ[x] - 8, ITOSQ[y] - 8, ITOSQ[z] - 8 if idx_is_empty(ppp48_idx[i][j][k]): - for ii, jj, kk in permutations((i, j, k)): + for ii, jj, kk in itertools.permutations((i, j, k)): ppp48_idx[ii][jj][kk] = idx ppp48_sq_x[idx], ppp48_sq_y[idx], ppp48_sq_z[idx] = i, j, k idx += 1 @@ -204,7 +204,7 @@ def init_aaidx() -> Tuple[List[int], List[List[int]]]: def init_aaa() -> Tuple[List[int], List[List[int]]]: # Get aaa_base. comb = [a * (a - 1) // 2 for a in range(64)] - aaa_base = list(accumulate(comb)) + aaa_base = list(itertools.accumulate(comb)) # Get aaa_xyz. aaa_xyz = [[x, y, z] for z in range(64) for y in range(z) for x in range(y)] From 57536b1a0787cecf0a725ac50e9ce98e65340f11 Mon Sep 17 00:00:00 2001 From: "Robert Nurnberg @ elitebook" Date: Mon, 20 Jan 2025 08:49:28 +0100 Subject: [PATCH 1804/1831] fix typo in comment --- chess/syzygy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/syzygy.py b/chess/syzygy.py index 5ead9922c..c61890550 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1850,7 +1850,7 @@ def probe_dtz(self, board: chess.Board) -> int: +-----+------------------+--------------------------------------------+ The return value can be off by one: a return value -n can mean a - losing zeroing move in in n + 1 plies and a return value +n can mean a + losing zeroing move in n + 1 plies and a return value +n can mean a winning zeroing move in n + 1 plies. This implies some primary tablebase lines may waste up to 1 ply. Rounding is never used for endgame phases where it would change the From 636e95fbf292f322fc4ab31b8c4add51f7534362 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 23 Feb 2025 21:05:39 +0100 Subject: [PATCH 1805/1831] Revert simplifications of chess.gaviota from #1130 The resulting code is not equivalent, that is, when the full tablebase is available ./test.py GaviotaTestCase fails with ERROR: test_dm_4 (__main__.GaviotaTestCase.test_dm_4) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/niklas/Projekte/python-chess/./test.py", line 35, in _wrapper return f(self) File "/home/niklas/Projekte/python-chess/./test.py", line 4305, in test_dm_4 dtm = self.tablebase.probe_dtm(board) File "/home/niklas/Projekte/python-chess/chess/gaviota.py", line 1393, in probe_dtm dtm = self.egtb_get_dtm(req) File "/home/niklas/Projekte/python-chess/chess/gaviota.py", line 1518, in egtb_get_dtm dtm = self._tb_probe(req) File "/home/niklas/Projekte/python-chess/chess/gaviota.py", line 1621, in _tb_probe buffer_zipped = stream.read(z) ValueError: read length must be non-negative or -1 --- chess/gaviota.py | 553 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 374 insertions(+), 179 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index 0bbe41b81..39173b593 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -4,7 +4,6 @@ import ctypes.util import dataclasses import fnmatch -import itertools import logging import lzma import os @@ -12,11 +11,11 @@ import struct import typing +import chess + from types import TracebackType from typing import BinaryIO, Callable, Dict, List, Optional, Tuple, Type, Union -import chess - LOGGER = logging.getLogger(__name__) @@ -110,19 +109,30 @@ def idx_is_empty(x: int) -> int: def flip_type(x: chess.Square, y: chess.Square) -> int: ret = 0 - file_x, rank_x = chess.square_file(x), chess.square_rank(x) - file_y, rank_y = chess.square_file(y), chess.square_rank(y) - if file_x > 3: - x, y = flip_we(x), flip_we(y) + if chess.square_file(x) > 3: + x = flip_we(x) + y = flip_we(y) ret |= 1 - if rank_x > 3: - x, y = flip_ns(x), flip_ns(y) + if chess.square_rank(x) > 3: + x = flip_ns(x) + y = flip_ns(y) ret |= 2 - if (rank_x, file_x) > (rank_y, file_y): - x, y = flip_nw_se(x), flip_nw_se(y) + rowx = chess.square_rank(x) + colx = chess.square_file(x) + + if rowx > colx: + x = flip_nw_se(x) + y = flip_nw_se(y) + ret |= 4 + + rowy = chess.square_rank(y) + coly = chess.square_file(y) + if rowx == colx and rowy > coly: + x = flip_nw_se(x) + y = flip_nw_se(y) ret |= 4 return ret @@ -135,6 +145,7 @@ def init_flipt() -> List[List[int]]: def init_pp48_idx() -> Tuple[List[List[int]], List[int], List[int]]: MAX_I = MAX_J = 48 + idx = 0 pp48_idx = [[-1] * MAX_J for _ in range(MAX_I)] pp48_sq_x = [NOSQUARE] * MAX_PP48_INDEX pp48_sq_y = [NOSQUARE] * MAX_PP48_INDEX @@ -146,8 +157,10 @@ def init_pp48_idx() -> Tuple[List[List[int]], List[int], List[int]]: j = flip_we(flip_ns(b)) - 8 if idx_is_empty(pp48_idx[i][j]): - pp48_idx[i][j] = pp48_idx[j][i] = idx - pp48_sq_x[idx], pp48_sq_y[idx] = i, j + pp48_idx[i][j] = idx + pp48_idx[j][i] = idx + pp48_sq_x[idx] = i + pp48_sq_y[idx] = j idx += 1 return pp48_idx, pp48_sq_x, pp48_sq_y @@ -166,15 +179,26 @@ def init_ppp48_idx() -> Tuple[List[List[List[int]]], List[int], List[int], List[ for x in range(48): for y in range(x + 1, 48): for z in range(y + 1, 48): - if not (in_queenside(ITOSQ[y]) and in_queenside(ITOSQ[z])): + a = ITOSQ[x] + b = ITOSQ[y] + c = ITOSQ[z] + if not in_queenside(b) or not in_queenside(c): continue - i, j, k = ITOSQ[x] - 8, ITOSQ[y] - 8, ITOSQ[z] - 8 + i = a - 8 + j = b - 8 + k = c - 8 if idx_is_empty(ppp48_idx[i][j][k]): - for ii, jj, kk in itertools.permutations((i, j, k)): - ppp48_idx[ii][jj][kk] = idx - ppp48_sq_x[idx], ppp48_sq_y[idx], ppp48_sq_z[idx] = i, j, k + ppp48_idx[i][j][k] = idx + ppp48_idx[i][k][j] = idx + ppp48_idx[j][i][k] = idx + ppp48_idx[j][k][i] = idx + ppp48_idx[k][i][j] = idx + ppp48_idx[k][j][i] = idx + ppp48_sq_x[idx] = i + ppp48_sq_y[idx] = j + ppp48_sq_z[idx] = k idx += 1 return ppp48_idx, ppp48_sq_x, ppp48_sq_y, ppp48_sq_z @@ -192,7 +216,8 @@ def init_aaidx() -> Tuple[List[int], List[List[int]]]: if idx_is_empty(aaidx[x][y]): # Still empty. - aaidx[x][y] = aaidx[y][x] = idx + aaidx[x][y] = idx + aaidx[y][x] = idx aabase[idx] = x idx += 1 @@ -204,10 +229,24 @@ def init_aaidx() -> Tuple[List[int], List[List[int]]]: def init_aaa() -> Tuple[List[int], List[List[int]]]: # Get aaa_base. comb = [a * (a - 1) // 2 for a in range(64)] - aaa_base = list(itertools.accumulate(comb)) + + accum = 0 + aaa_base = [0] * 64 + for a in range(64 - 1): + accum += comb[a] + aaa_base[a + 1] = accum # Get aaa_xyz. - aaa_xyz = [[x, y, z] for z in range(64) for y in range(z) for x in range(y)] + aaa_xyz = [[-1] * 3 for _ in range(MAX_AAAINDEX)] + + idx = 0 + for z in range(64): + for y in range(z): + for x in range(y): + aaa_xyz[idx][0] = x + aaa_xyz[idx][1] = y + aaa_xyz[idx][2] = z + idx += 1 return aaa_base, aaa_xyz @@ -312,33 +351,34 @@ def init_ppidx() -> Tuple[List[List[int]], List[int], List[int]]: def norm_kkindex(x: chess.Square, y: chess.Square) -> Tuple[int, int]: - file_x, rank_x = chess.square_file(x), chess.square_rank(x) - - if file_x > 3: - x, y = flip_we(x), flip_we(y) + if chess.square_file(x) > 3: + x = flip_we(x) + y = flip_we(y) - if rank_x > 3: - x, y = flip_ns(x), flip_ns(y) + if chess.square_rank(x) > 3: + x = flip_ns(x) + y = flip_ns(y) rowx = chess.square_rank(x) colx = chess.square_file(x) if rowx > colx: - x, y = flip_nw_se(x), flip_nw_se(y) + x = flip_nw_se(x) + y = flip_nw_se(y) rowy = chess.square_rank(y) coly = chess.square_file(y) if rowx == colx and rowy > coly: - x, y = flip_nw_se(x), flip_nw_se(y) + x = flip_nw_se(x) + y = flip_nw_se(y) return x, y - def init_kkidx() -> Tuple[List[List[int]], List[int], List[int]]: kkidx = [[-1] * 64 for _ in range(64)] - bksq, wksq = [-1] * MAX_KKINDEX, [-1] * MAX_KKINDEX - + bksq = [-1] * MAX_KKINDEX + wksq = [-1] * MAX_KKINDEX idx = 0 for x in range(64): for y in range(64): @@ -348,8 +388,10 @@ def init_kkidx() -> Tuple[List[List[int]], List[int], List[int]]: i, j = norm_kkindex(x, y) if idx_is_empty(kkidx[i][j]): - kkidx[i][j] = kkidx[x][y] = idx - bksq[idx], wksq[idx] = i, j + kkidx[i][j] = idx + kkidx[x][y] = idx + bksq[idx] = i + wksq[idx] = j idx += 1 return kkidx, wksq, bksq @@ -362,12 +404,20 @@ def kxk_pctoindex(c: Request) -> int: ft = flip_type(c.black_piece_squares[0], c.white_piece_squares[0]) - ws, bs = c.white_piece_squares, c.black_piece_squares + ws = c.white_piece_squares + bs = c.black_piece_squares + + if (ft & 1) != 0: + ws = [flip_we(b) for b in ws] + bs = [flip_we(b) for b in bs] + + if (ft & 2) != 0: + ws = [flip_ns(b) for b in ws] + bs = [flip_ns(b) for b in bs] - for f, flip in [(1, flip_we), (2, flip_ns), (4, flip_nw_se)]: - if ft & f: - ws = [flip(b) for b in ws] - bs = [flip(b) for b in bs] + if (ft & 4) != 0: + ws = [flip_nw_se(b) for b in ws] + bs = [flip_nw_se(b) for b in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] @@ -376,14 +426,6 @@ def kxk_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ws[1] - -def flip_we_col(*pieces: int) -> tuple[int, ...]: - if (pieces[0] & 7) > 3: - # Column is more than 3, i.e., e, f, g or h. - pieces = tuple(flip_we(piece) for piece in pieces) - return pieces - - def kapkb_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 * 64 BLOCK_B = 64 * 64 * 64 @@ -396,17 +438,24 @@ def kapkb_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] ba = c.black_piece_squares[1] - if not chess.A2 <= pawn < chess.A8: + if not (chess.A2 <= pawn < chess.A8): return NOINDEX - pawn, wk, bk, wa, ba = flip_we_col(pawn, wk, bk, wa, ba) + if (pawn & 7) > 3: + # Column is more than 3, i.e., e, f, g or h. + pawn = flip_we(pawn) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) + ba = flip_we(ba) - # flip_ns, down one row - pslice = ((pawn ^ 56) - 8 + (pawn & 3)) >> 1 + sq = pawn + sq ^= 56 # flip_ns + sq -= 8 # Down one row + pslice = (sq + (sq & 3)) >> 1 return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa * BLOCK_D + ba - def kabpk_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 * 64 BLOCK_B = 64 * 64 * 64 @@ -419,13 +468,18 @@ def kabpk_pctoindex(c: Request) -> int: pawn = c.white_piece_squares[3] bk = c.black_piece_squares[0] - pawn, wk, bk, wa, wb = flip_we_col(pawn, wk, bk, wa, wb) + if (pawn & 7) > 3: + # Column is more than 3, i.e., e, f, g or h. + pawn = flip_we(pawn) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) + wb = flip_we(wb) pslice = wsq_to_pidx24(pawn) return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa * BLOCK_D + wb - def kabkp_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 * 64 BLOCK_B = 64 * 64 * 64 @@ -438,17 +492,23 @@ def kabkp_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] wb = c.white_piece_squares[2] - if not chess.A2 <= pawn < chess.A8: + if not (chess.A2 <= pawn < chess.A8): return NOINDEX - pawn, wk, bk, wa, wb = flip_we_col(pawn, wk, bk, wa, wb) + if (pawn & 7) > 3: + # Column is more than 3, i.e., e, f, g or h. + pawn = flip_we(pawn) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) + wb = flip_we(wb) - # Down one row - pslice = ((pawn - 8) + (pawn & 3)) >> 1 + sq = pawn + sq -= 8 # Down one row + pslice = (sq + (sq & 3)) >> 1 return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa * BLOCK_D + wb - def kaapk_pctoindex(c: Request) -> int: BLOCK_C = MAX_AAINDEX BLOCK_B = 64 * BLOCK_C @@ -460,7 +520,13 @@ def kaapk_pctoindex(c: Request) -> int: pawn = c.white_piece_squares[3] bk = c.black_piece_squares[0] - pawn, wk, bk, wa, wa2 = flip_we_col(pawn, wk, bk, wa, wa2) + if (pawn & 7) > 3: + # Column is more than 3, i.e., e, f, g or h. + pawn = flip_we(pawn) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) + wa2 = flip_we(wa2) pslice = wsq_to_pidx24(pawn) @@ -471,7 +537,6 @@ def kaapk_pctoindex(c: Request) -> int: return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + aa_combo - def kaakp_pctoindex(c: Request) -> int: BLOCK_C = MAX_AAINDEX BLOCK_B = 64 * BLOCK_C @@ -483,7 +548,13 @@ def kaakp_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] pawn = c.black_piece_squares[1] - pawn, wk, bk, wa, wa2 = flip_we_col(pawn, wk, bk, wa, wa2) + if (pawn & 7) > 3: + # Column is more than 3, i.e., e, f, g or h. + pawn = flip_we(pawn) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) + wa2 = flip_we(wa2) pawn = flip_ns(pawn) pslice = wsq_to_pidx24(pawn) @@ -495,7 +566,6 @@ def kaakp_pctoindex(c: Request) -> int: return pslice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + aa_combo - def kapkp_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 BLOCK_B = 64 * 64 @@ -503,20 +573,30 @@ def kapkp_pctoindex(c: Request) -> int: wk = c.white_piece_squares[0] wa = c.white_piece_squares[1] - anchor = c.white_piece_squares[2] + pawn_a = c.white_piece_squares[2] bk = c.black_piece_squares[0] - loosen = c.black_piece_squares[1] + pawn_b = c.black_piece_squares[1] + + anchor = pawn_a + loosen = pawn_b - anchor, loosen, wk, bk, wa = flip_we_col(anchor, loosen, wk, bk, wa) + if (anchor & 7) > 3: + # Column is more than 3, i.e., e, f, g or h. + anchor = flip_we(anchor) + loosen = flip_we(loosen) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) - pp_slice = wsq_to_pidx24(anchor) * 48 + loosen - 8 + m = wsq_to_pidx24(anchor) + n = loosen - 8 + pp_slice = m * 48 + n if idx_is_empty(pp_slice): return NOINDEX return pp_slice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa - def kappk_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 BLOCK_B = 64 * 64 @@ -530,7 +610,13 @@ def kappk_pctoindex(c: Request) -> int: anchor, loosen = pp_putanchorfirst(pawn_a, pawn_b) - anchor, loosen, wk, bk, wa = flip_we_col(anchor, loosen, wk, bk, wa) + if (anchor & 7) > 3: + # Column is more than 3, i.e., e, f, g or h. + anchor = flip_we(anchor) + loosen = flip_we(loosen) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) i = wsq_to_pidx24(anchor) j = wsq_to_pidx48(loosen) @@ -542,7 +628,6 @@ def kappk_pctoindex(c: Request) -> int: return pp_slice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + wa - def kppka_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 * 64 BLOCK_B = 64 * 64 @@ -556,7 +641,12 @@ def kppka_pctoindex(c: Request) -> int: anchor, loosen = pp_putanchorfirst(pawn_a, pawn_b) - anchor, loosen, wk, bk, ba = flip_we_col(anchor, loosen, wk, bk, ba) + if (anchor & 7) > 3: + anchor = flip_we(anchor) + loosen = flip_we(loosen) + wk = flip_we(wk) + bk = flip_we(bk) + ba = flip_we(ba) i = wsq_to_pidx24(anchor) j = wsq_to_pidx48(loosen) @@ -568,7 +658,6 @@ def kppka_pctoindex(c: Request) -> int: return pp_slice * BLOCK_A + wk * BLOCK_B + bk * BLOCK_C + ba - def kabck_pctoindex(c: Request) -> int: N_WHITE = 4 N_BLACK = 1 @@ -600,7 +689,6 @@ def kabck_pctoindex(c: Request) -> int: return ki * BLOCK_A + ws[1] * BLOCK_B + ws[2] * BLOCK_C + ws[3] - def kabbk_pctoindex(c: Request) -> int: N_WHITE = 4 N_BLACK = 1 @@ -632,7 +720,6 @@ def kabbk_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai * BLOCK_Bx + ws[1] - def kaabk_pctoindex(c: Request) -> int: N_WHITE = 4 N_BLACK = 1 @@ -664,23 +751,45 @@ def kaabk_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai * BLOCK_Bx + ws[3] - def aaa_getsubi(x: int, y: int, z: int) -> int: - return x + (y - 1) * y // 2 + AAA_BASE[z] - + bse = AAA_BASE[z] + calc_idx = x + (y - 1) * y // 2 + bse + return calc_idx def kaaak_pctoindex(c: Request) -> int: + N_WHITE = 4 + N_BLACK = 1 BLOCK_Ax = MAX_AAAINDEX - ws = c.white_piece_squares[:4] - bs = c.black_piece_squares[:1] + + ws = c.white_piece_squares[:N_WHITE] + bs = c.black_piece_squares[:N_BLACK] + ft = FLIPT[c.black_piece_squares[0]][c.white_piece_squares[0]] - for flag, flip in [(WE_FLAG, flip_we), (NS_FLAG, flip_ns), (NW_SE_FLAG, flip_nw_se)]: - if ft & flag: - ws = [flip(i) for i in ws] - bs = [flip(i) for i in bs] + if (ft & WE_FLAG) != 0: + ws = [flip_we(i) for i in ws] + bs = [flip_we(i) for i in bs] + + if (ft & NS_FLAG) != 0: + ws = [flip_ns(i) for i in ws] + bs = [flip_ns(i) for i in bs] - ws[1:4] = sorted(ws[1:4]) + if (ft & NW_SE_FLAG) != 0: + ws = [flip_nw_se(i) for i in ws] + bs = [flip_nw_se(i) for i in bs] + + if ws[2] < ws[1]: + tmp = ws[1] + ws[1] = ws[2] + ws[2] = tmp + if ws[3] < ws[2]: + tmp = ws[2] + ws[2] = ws[3] + ws[3] = tmp + if ws[2] < ws[1]: + tmp = ws[1] + ws[1] = ws[2] + ws[2] = tmp ki = KKIDX[bs[0]][ws[0]] @@ -694,7 +803,6 @@ def kaaak_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai - def kppkp_pctoindex(c: Request) -> int: BLOCK_Ax = MAX_PP48_INDEX * 64 * 64 BLOCK_Bx = 64 * 64 @@ -706,7 +814,12 @@ def kppkp_pctoindex(c: Request) -> int: bk = c.black_piece_squares[0] pawn_c = c.black_piece_squares[1] - pawn_c, wk, pawn_a, pawn_b, bk = flip_we_col(pawn_c, wk, pawn_a, pawn_b, bk) + if (pawn_c & 7) > 3: + wk = flip_we(wk) + pawn_a = flip_we(pawn_a) + pawn_b = flip_we(pawn_b) + bk = flip_we(bk) + pawn_c = flip_we(pawn_c) i = flip_we(flip_ns(pawn_a)) - 8 j = flip_we(flip_ns(pawn_b)) - 8 @@ -721,19 +834,28 @@ def kppkp_pctoindex(c: Request) -> int: return k * BLOCK_Ax + pp48_slice * BLOCK_Bx + wk * BLOCK_Cx + bk - def kaakb_pctoindex(c: Request) -> int: + N_WHITE = 3 + N_BLACK = 2 BLOCK_Bx = 64 BLOCK_Ax = BLOCK_Bx * MAX_AAINDEX - ws = c.white_piece_squares[:3] - bs = c.black_piece_squares[:2] ft = FLIPT[c.black_piece_squares[0]][c.white_piece_squares[0]] - for flag, flip in [(WE_FLAG, flip_we), (NS_FLAG, flip_ns), (NW_SE_FLAG, flip_nw_se)]: - if ft & flag: - ws = [flip(i) for i in ws] - bs = [flip(i) for i in bs] + ws = c.white_piece_squares[:N_WHITE] + bs = c.black_piece_squares[:N_BLACK] + + if (ft & WE_FLAG) != 0: + ws = [flip_we(i) for i in ws] + bs = [flip_we(i) for i in bs] + + if (ft & NS_FLAG) != 0: + ws = [flip_ns(i) for i in ws] + bs = [flip_ns(i) for i in bs] + + if (ft & NW_SE_FLAG) != 0: + ws = [flip_nw_se(i) for i in ws] + bs = [flip_nw_se(i) for i in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] ai = AAIDX[ws[1]][ws[2]] @@ -743,7 +865,6 @@ def kaakb_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai * BLOCK_Bx + bs[1] - def kabkc_pctoindex(c: Request) -> int: N_WHITE = 3 N_BLACK = 2 @@ -757,10 +878,17 @@ def kabkc_pctoindex(c: Request) -> int: ws = c.white_piece_squares[:N_WHITE] bs = c.black_piece_squares[:N_BLACK] - for flag, flip in [(WE_FLAG, flip_we), (NS_FLAG, flip_ns), (NW_SE_FLAG, flip_nw_se)]: - if ft & flag: - ws = [flip(i) for i in ws] - bs = [flip(i) for i in bs] + if (ft & WE_FLAG) != 0: + ws = [flip_we(i) for i in ws] + bs = [flip_we(i) for i in bs] + + if (ft & NS_FLAG) != 0: + ws = [flip_ns(i) for i in ws] + bs = [flip_ns(i) for i in bs] + + if (ft & NW_SE_FLAG) != 0: + ws = [flip_nw_se(i) for i in ws] + bs = [flip_nw_se(i) for i in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX [black king] [white king] @@ -769,17 +897,23 @@ def kabkc_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ws[1] * BLOCK_Bx + ws[2] * BLOCK_Cx + bs[1] - def kpkp_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 BLOCK_Bx = 64 wk = c.white_piece_squares[0] bk = c.black_piece_squares[0] - anchor = c.white_piece_squares[1] - loosen = c.black_piece_squares[1] + pawn_a = c.white_piece_squares[1] + pawn_b = c.black_piece_squares[1] - anchor, loosen, wk, bk = flip_we_col(anchor, loosen, wk, bk) + anchor = pawn_a + loosen = pawn_b + + if (anchor & 7) > 3: + anchor = flip_we(anchor) + loosen = flip_we(loosen) + wk = flip_we(wk) + bk = flip_we(bk) m = wsq_to_pidx24(anchor) n = loosen - 8 @@ -791,7 +925,6 @@ def kpkp_pctoindex(c: Request) -> int: return pp_slice * BLOCK_Ax + wk * BLOCK_Bx + bk - def kppk_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 BLOCK_Bx = 64 @@ -802,7 +935,11 @@ def kppk_pctoindex(c: Request) -> int: anchor, loosen = pp_putanchorfirst(pawn_a, pawn_b) - anchor, loosen, wk, bk = flip_we_col(anchor, loosen, wk, bk) + if (anchor & 7) > 3: + anchor = flip_we(anchor) + loosen = flip_we(loosen) + wk = flip_we(wk) + bk = flip_we(bk) i = wsq_to_pidx24(anchor) j = wsq_to_pidx48(loosen) @@ -814,7 +951,6 @@ def kppk_pctoindex(c: Request) -> int: return pp_slice * BLOCK_Ax + wk * BLOCK_Bx + bk - def kapk_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 * 64 BLOCK_Bx = 64 * 64 @@ -825,17 +961,22 @@ def kapk_pctoindex(c: Request) -> int: wk = c.white_piece_squares[0] bk = c.black_piece_squares[0] - if not chess.A2 <= pawn < chess.A8: + if not (chess.A2 <= pawn < chess.A8): return NOINDEX - pawn, wk, bk, wa = flip_we_col(pawn, wk, bk, wa) + if (pawn & 7) > 3: + pawn = flip_we(pawn) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) - sq = pawn ^ 56 - 8 # flip_ns and down one row + sq = pawn + sq ^= 56 # flip_ns + sq -= 8 # Down one row pslice = ((sq + (sq & 3)) >> 1) return pslice * BLOCK_Ax + wk * BLOCK_Bx + bk * BLOCK_Cx + wa - def kabk_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 BLOCK_Bx = 64 @@ -845,10 +986,17 @@ def kabk_pctoindex(c: Request) -> int: ws = c.white_piece_squares bs = c.black_piece_squares - for flag, flip in [(1, flip_we), (2, flip_ns), (4, flip_nw_se)]: - if ft & flag: - ws = [flip(b) for b in ws] - bs = [flip(b) for b in bs] + if (ft & 1) != 0: + ws = [flip_we(b) for b in ws] + bs = [flip_we(b) for b in bs] + + if (ft & 2) != 0: + ws = [flip_ns(b) for b in ws] + bs = [flip_ns(b) for b in bs] + + if (ft & 4) != 0: + ws = [flip_nw_se(b) for b in ws] + bs = [flip_nw_se(b) for b in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] @@ -857,7 +1005,6 @@ def kabk_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ws[1] * BLOCK_Bx + ws[2] - def kakp_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 * 64 BLOCK_Bx = 64 * 64 @@ -868,29 +1015,42 @@ def kakp_pctoindex(c: Request) -> int: wk = c.white_piece_squares[0] bk = c.black_piece_squares[0] - if not chess.A2 <= pawn < chess.A8: + if not (chess.A2 <= pawn < chess.A8): return NOINDEX - pawn, wk, bk, wa = flip_we_col(pawn, wk, bk, wa) + if (pawn & 7) > 3: + pawn = flip_we(pawn) + wk = flip_we(wk) + bk = flip_we(bk) + wa = flip_we(wa) - # Down one row - pslice = ((pawn - 8) + ((pawn - 8) & 3)) >> 1 + sq = pawn + sq -= 8 # Down one row + pslice = (sq + (sq & 3)) >> 1 return pslice * BLOCK_Ax + wk * BLOCK_Bx + bk * BLOCK_Cx + wa - def kaak_pctoindex(c: Request) -> int: + N_WHITE = 3 + N_BLACK = 1 BLOCK_Ax = MAX_AAINDEX ft = FLIPT[c.black_piece_squares[0]][c.white_piece_squares[0]] - ws = c.white_piece_squares[:3] - bs = c.black_piece_squares[:1] + ws = c.white_piece_squares[:N_WHITE] + bs = c.black_piece_squares[:N_BLACK] + + if (ft & WE_FLAG) != 0: + ws = [flip_we(i) for i in ws] + bs = [flip_we(i) for i in bs] - for flag, flip in [(WE_FLAG, flip_we), (NS_FLAG, flip_ns), (NW_SE_FLAG, flip_nw_se)]: - if ft & flag: - ws = [flip(i) for i in ws] - bs = [flip(i) for i in bs] + if (ft & NS_FLAG) != 0: + ws = [flip_ns(i) for i in ws] + bs = [flip_ns(i) for i in bs] + + if (ft & NW_SE_FLAG) != 0: + ws = [flip_nw_se(i) for i in ws] + bs = [flip_nw_se(i) for i in bs] ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] ai = AAIDX[ws[1]][ws[2]] @@ -900,7 +1060,6 @@ def kaak_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ai - def kakb_pctoindex(c: Request) -> int: BLOCK_Ax = 64 * 64 BLOCK_Bx = 64 @@ -910,9 +1069,23 @@ def kakb_pctoindex(c: Request) -> int: ws = c.white_piece_squares[:] bs = c.black_piece_squares[:] - for bit, flip in [(1, flip_we), (2, flip_ns), (4, flip_nw_se)]: - if ft & bit: - ws[0], ws[1], bs[0], bs[1] = flip(ws[0]), flip(ws[1]), flip(bs[0]), flip(bs[1]) + if (ft & 1) != 0: + ws[0] = flip_we(ws[0]) + ws[1] = flip_we(ws[1]) + bs[0] = flip_we(bs[0]) + bs[1] = flip_we(bs[1]) + + if (ft & 2) != 0: + ws[0] = flip_ns(ws[0]) + ws[1] = flip_ns(ws[1]) + bs[0] = flip_ns(bs[0]) + bs[1] = flip_ns(bs[1]) + + if (ft & 4) != 0: + ws[0] = flip_nw_se(ws[0]) + ws[1] = flip_nw_se(ws[1]) + bs[0] = flip_nw_se(bs[0]) + bs[1] = flip_nw_se(bs[1]) ki = KKIDX[bs[0]][ws[0]] # KKIDX[black king][white king] @@ -921,7 +1094,6 @@ def kakb_pctoindex(c: Request) -> int: return ki * BLOCK_Ax + ws[1] * BLOCK_Bx + bs[1] - def kpk_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 BLOCK_B = 64 @@ -930,16 +1102,21 @@ def kpk_pctoindex(c: Request) -> int: wk = c.white_piece_squares[0] bk = c.black_piece_squares[0] - if not chess.A2 <= pawn < chess.A8: + if not (chess.A2 <= pawn < chess.A8): return NOINDEX - pawn, wk, bk = flip_we_col(pawn, wk, bk) + if (pawn & 7) > 3: + pawn = flip_we(pawn) + wk = flip_we(wk) + bk = flip_we(bk) - sq = (pawn ^ 56) - 8 # flip_ns, down one row + sq = pawn + sq ^= 56 # flip_ns + sq -= 8 # Down one row pslice = ((sq + (sq & 3)) >> 1) - return pslice * BLOCK_A + wk * BLOCK_B + bk - + res = pslice * BLOCK_A + wk * BLOCK_B + bk + return res def kpppk_pctoindex(c: Request) -> int: BLOCK_A = 64 * 64 @@ -949,16 +1126,26 @@ def kpppk_pctoindex(c: Request) -> int: pawn_a = c.white_piece_squares[1] pawn_b = c.white_piece_squares[2] pawn_c = c.white_piece_squares[3] + bk = c.black_piece_squares[0] - i, j, k = [x - 8 for x in (pawn_a, pawn_b, pawn_c)] + i = pawn_a - 8 + j = pawn_b - 8 + k = pawn_c - 8 + ppp48_slice = PPP48_IDX[i][j][k] if idx_is_empty(ppp48_slice): - wk, pawn_a, pawn_b, pawn_c, bk = [flip_we(x) for x in (wk, pawn_a, pawn_b, pawn_c, bk)] + wk = flip_we(wk) + pawn_a = flip_we(pawn_a) + pawn_b = flip_we(pawn_b) + pawn_c = flip_we(pawn_c) + bk = flip_we(bk) + + i = pawn_a - 8 + j = pawn_b - 8 + k = pawn_c - 8 - # removing this doesn't impact the tests? - i, j, k = [x - 8 for x in (pawn_a, pawn_b, pawn_c)] ppp48_slice = PPP48_IDX[i][j][k] if idx_is_empty(ppp48_slice): @@ -1143,15 +1330,13 @@ def __init__(self, maxindex: int, slice_n: int, pctoi: Callable[[Request], int]) def sortlists(ws: List[int], wp: List[int]) -> Tuple[List[int], List[int]]: - z = sorted(zip(wp, ws), reverse=True) + z = sorted(zip(wp, ws), key=lambda x: x[0], reverse=True) wp2, ws2 = zip(*z) return list(ws2), list(wp2) - def egtb_block_unpack(side: int, n: int, bp: bytes) -> List[int]: return [dtm_unpack(side, i) for i in bp[:n]] - def split_index(i: int) -> Tuple[int, int]: return divmod(i, ENTRIES_PER_BLOCK) @@ -1175,23 +1360,19 @@ def removepiece(ys: List[int], yp: List[int], j: int) -> None: del ys[j] del yp[j] - def opp(side: int) -> int: return 1 if side == 0 else 0 - def adjust_up(dist: int) -> int: - if (dist & INFOMASK) in [iWMATE, iWMATEt, iBMATE, iBMATEt]: - return dist + (1 << PLYSHIFT) - return dist + udist = dist + sw = udist & INFOMASK + if sw in [iWMATE, iWMATEt, iBMATE, iBMATEt]: + udist += (1 << PLYSHIFT) -def bestx(side: int, a: int, b: int) -> int: - if a == iFORBID: - return b - if b == iFORBID: - return a + return udist +def bestx(side: int, a: int, b: int) -> int: # 0 = selectfirst # 1 = selectlowest # 2 = selecthighest @@ -1204,25 +1385,33 @@ def bestx(side: int, a: int, b: int) -> int: [3, 3, 3, 0], # forbid ] + xorkey = [0, 3] + + if a == iFORBID: + return b + if b == iFORBID: + return a + retu = [a, a, b, b] if b < a: - retu[1:2] = [b, a] + retu[1] = b + retu[2] = a - key = comparison[a & 3][b & 3] ^ [0, 3][side] # ^ xorkey + key = comparison[a & 3][b & 3] ^ xorkey[side] return retu[key] - def unpackdist(d: int) -> Tuple[int, int]: return d >> PLYSHIFT, d & INFOMASK - def dtm_unpack(stm: int, packed: int) -> int: - if packed in [iDRAW, iFORBID]: - return packed + p = packed + + if p in [iDRAW, iFORBID]: + return p - info = packed & 3 - store = packed >> 2 + info = p & 3 + store = p >> 2 if stm == 0: if info == iWMATE: @@ -1398,23 +1587,28 @@ def probe_dtm(self, board: chess.Board) -> int: if req.realside == 1: if req.is_reversed: return ply - return -ply - if req.is_reversed: - return -ply - return ply - - if res == iBMATE: + else: + return -ply + else: + if req.is_reversed: + return -ply + else: + return ply + elif res == iBMATE: # Black mates in the stored position. if req.realside == 0: if req.is_reversed: return ply - return -ply - if req.is_reversed: - return -ply - return ply - - # Draw. - return 0 + else: + return -ply + else: + if req.is_reversed: + return -ply + else: + return ply + else: + # Draw. + return 0 def get_dtm(self, board: chess.Board, default: Optional[int] = None) -> Optional[int]: try: @@ -1450,12 +1644,12 @@ def probe_wdl(self, board: chess.Board) -> int: if dtm == 0: if board.is_checkmate(): return -1 - return 0 - - if dtm > 0: + else: + return 0 + elif dtm > 0: return 1 - - return -1 + else: + return -1 def get_wdl(self, board: chess.Board, default: Optional[int] = None) -> Optional[int]: try: @@ -1601,7 +1795,8 @@ def egtb_block_getsize(self, req: Request, idx: int) -> int: if (offset + blocksz) > maxindex: return maxindex - offset # Last block size - return blocksz # Size of a normal block + else: + return blocksz # Size of a normal block def _tb_probe(self, req: Request) -> int: stream = self._setup_tablebase(req) From dd4d9c1285d70f1aaffa276244101d9373053c1d Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 23 Feb 2025 22:55:23 +0100 Subject: [PATCH 1806/1831] Fix ep resolution in chess.gaviota.PythonTablebase (fixes #1132) --- chess/gaviota.py | 142 +++++++---------------------------------------- test.py | 5 ++ 2 files changed, 26 insertions(+), 121 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index 39173b593..83fb7bb64 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1356,51 +1356,9 @@ def split_index(i: int) -> Tuple[int, int]: iBMATEt = tb_BMATE | 4 -def removepiece(ys: List[int], yp: List[int], j: int) -> None: - del ys[j] - del yp[j] - def opp(side: int) -> int: return 1 if side == 0 else 0 -def adjust_up(dist: int) -> int: - udist = dist - sw = udist & INFOMASK - - if sw in [iWMATE, iWMATEt, iBMATE, iBMATEt]: - udist += (1 << PLYSHIFT) - - return udist - -def bestx(side: int, a: int, b: int) -> int: - # 0 = selectfirst - # 1 = selectlowest - # 2 = selecthighest - # 3 = selectsecond - comparison = [ - # draw, wmate, bmate, forbid - [0, 3, 0, 0], # draw - [0, 1, 0, 0], # wmate - [3, 3, 2, 0], # bmate - [3, 3, 3, 0], # forbid - ] - - xorkey = [0, 3] - - if a == iFORBID: - return b - if b == iFORBID: - return a - - retu = [a, a, b, b] - - if b < a: - retu[1] = b - retu[2] = a - - key = comparison[a & 3][b & 3] ^ xorkey[side] - return retu[key] - def unpackdist(d: int) -> Tuple[int, int]: return d >> PLYSHIFT, d & INFOMASK @@ -1492,12 +1450,11 @@ class Request: black_piece_types: List[int] is_reversed: bool - def __init__(self, white_squares: List[int], white_types: List[chess.PieceType], black_squares: List[int], black_types: List[chess.PieceType], side: int, epsq: int): + def __init__(self, white_squares: List[int], white_types: List[chess.PieceType], black_squares: List[int], black_types: List[chess.PieceType], side: int): self.white_squares, self.white_types = sortlists(white_squares, white_types) self.black_squares, self.black_types = sortlists(black_squares, black_types) self.realside = side self.side = side - self.epsq = epsq @dataclasses.dataclass @@ -1569,17 +1526,34 @@ def probe_dtm(self, board: chess.Board) -> int: if board.occupied == board.kings: return 0 + # Resolve en passant. + dtm = self._probe_dtm_no_ep(board) + for move in board.generate_legal_ep(): + try: + board.push(move) + + child_dtm = -self._probe_dtm_no_ep(board) + if child_dtm > 0: + child_dtm += 1 + elif child_dtm < 0: + child_dtm -= 1 + + dtm = min(dtm, child_dtm) if dtm * child_dtm > 0 else max(dtm, child_dtm) + finally: + board.pop() + return dtm + + def _probe_dtm_no_ep(self, board: chess.Board) -> int: # Prepare the tablebase request. white_squares = list(chess.SquareSet(board.occupied_co[chess.WHITE])) white_types = [typing.cast(chess.PieceType, board.piece_type_at(sq)) for sq in white_squares] black_squares = list(chess.SquareSet(board.occupied_co[chess.BLACK])) black_types = [typing.cast(chess.PieceType, board.piece_type_at(sq)) for sq in black_squares] side = 0 if (board.turn == chess.WHITE) else 1 - epsq = board.ep_square if board.ep_square else NOSQUARE - req = Request(white_squares, white_types, black_squares, black_types, side, epsq) + req = Request(white_squares, white_types, black_squares, black_types, side) # Probe. - dtm = self.egtb_get_dtm(req) + dtm = self._tb_probe(req) ply, res = unpackdist(dtm) if res == iWMATE: @@ -1675,10 +1649,7 @@ def _setup_tablebase(self, req: Request) -> BinaryIO: req.white_piece_types = req.black_types req.black_piece_squares = [flip_ns(s) for s in req.white_squares] req.black_piece_types = req.white_types - req.side = opp(req.side) - if req.epsq != NOSQUARE: - req.epsq = flip_ns(req.epsq) else: raise MissingTableError(f"no gaviota table available for: {white_letters.upper()}v{black_letters.upper()}") @@ -1708,77 +1679,6 @@ def close(self) -> None: _, stream = self.streams.popitem() stream.close() - def egtb_get_dtm(self, req: Request) -> int: - dtm = self._tb_probe(req) - - if req.epsq != NOSQUARE: - capturer_a = 0 - capturer_b = 0 - xed = 0 - - # Flip for move generation. - if req.side == 0: - xs = list(req.white_piece_squares) - xp = list(req.white_piece_types) - ys = list(req.black_piece_squares) - yp = list(req.black_piece_types) - else: - xs = list(req.black_piece_squares) - xp = list(req.black_piece_types) - ys = list(req.white_piece_squares) - yp = list(req.white_piece_types) - - # Captured pawn trick: from ep square to captured. - xed = req.epsq ^ (1 << 3) - - # Find captured index (j). - try: - j = ys.index(xed) - except ValueError: - j = -1 - - # Try first possible ep capture. - if 0 == (0x88 & (map88(xed) + 1)): - capturer_a = xed + 1 - - # Try second possible ep capture. - if 0 == (0x88 & (map88(xed) - 1)): - capturer_b = xed - 1 - - if (j > -1) and (ys[j] == xed): - # Find capturers (i). - for i in range(len(xs)): - if xp[i] == chess.PAWN and (xs[i] == capturer_a or xs[i] == capturer_b): - epscore = iFORBID - - # Copy position. - xs_after = xs[:] - ys_after = ys[:] - xp_after = xp[:] - yp_after = yp[:] - - # Execute capture. - xs_after[i] = req.epsq - removepiece(ys_after, yp_after, j) - - # Flip back. - if req.side == 1: - xs_after, ys_after = ys_after, xs_after - xp_after, yp_after = yp_after, xp_after - - # Make subrequest. - subreq = Request(xs_after, xp_after, ys_after, yp_after, opp(req.side), NOSQUARE) - try: - epscore = self._tb_probe(subreq) - epscore = adjust_up(epscore) - - # Choose to ep or not. - dtm = bestx(req.side, epscore, dtm) - except IndexError: - break - - return dtm - def egtb_block_getnumber(self, req: Request, idx: int) -> int: maxindex = EGKEY[req.egkey].maxindex diff --git a/test.py b/test.py index 6db84d254..7a3a3cdef 100755 --- a/test.py +++ b/test.py @@ -4348,6 +4348,11 @@ def test_two_ep(self): board = chess.Board("K7/8/8/6k1/5pPp/8/8/8 b - g3 0 61") self.assertEqual(self.tablebase.probe_dtm(board), 17) + @catchAndSkip(chess.gaviota.MissingTableError, "need KPvKP.gtb.cp4") + def test_ep_is_best(self): + board = chess.Board("8/8/7k/8/1pP5/7K/8/8 b - c3 0 1") + self.assertEqual(self.tablebase.probe_dtm(board), 19) + class SvgTestCase(unittest.TestCase): From 06de70e2e87969743dfa2196db1e2cbe687a08a8 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 24 Feb 2025 21:52:23 +0100 Subject: [PATCH 1807/1831] Fix checkmating ep capture in chess.gaviota.PythonTablebase --- chess/gaviota.py | 17 ++++++++++------- test.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index 83fb7bb64..281df836b 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1493,8 +1493,8 @@ def probe_dtm(self, board: chess.Board) -> int: Probes for depth to mate information. The absolute value is the number of half-moves until forced mate - (or ``0`` in drawn positions). The value is positive if the - side to move is winning, otherwise it is negative. + (or ``0`` in drawn or checkmated positions). The value is positive if + the side to move is winning, otherwise it is negative or 0. In the example position, white to move will get mated in 10 half-moves: @@ -1532,11 +1532,14 @@ def probe_dtm(self, board: chess.Board) -> int: try: board.push(move) - child_dtm = -self._probe_dtm_no_ep(board) - if child_dtm > 0: - child_dtm += 1 - elif child_dtm < 0: - child_dtm -= 1 + if board.is_checkmate(): + child_dtm = 1 + else: + child_dtm = -self._probe_dtm_no_ep(board) + if child_dtm > 0: + child_dtm += 1 + elif child_dtm < 0: + child_dtm -= 1 dtm = min(dtm, child_dtm) if dtm * child_dtm > 0 else max(dtm, child_dtm) finally: diff --git a/test.py b/test.py index 7a3a3cdef..c120c049f 100755 --- a/test.py +++ b/test.py @@ -4353,6 +4353,16 @@ def test_ep_is_best(self): board = chess.Board("8/8/7k/8/1pP5/7K/8/8 b - c3 0 1") self.assertEqual(self.tablebase.probe_dtm(board), 19) + @catchAndSkip(chess.gaviota.MissingTableError, "need KQPvKP.gtb.cp4") + def test_ep_is_mate(self): + # The resulting mate. + board = chess.Board("5Q2/7k/6P1/5K2/8/8/8/8 b - - 0 1") + self.assertEqual(self.tablebase.probe_dtm(board), 0) + + # Ep leads to the previously tested mate position. + board = chess.Board("5Q2/7k/8/5KpP/8/8/8/8 w - g6 0 1") + self.assertEqual(self.tablebase.probe_dtm(board), 1) + class SvgTestCase(unittest.TestCase): From 45f616fae51a2b08ca4b4d0c01ddddf175d81ff9 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 25 Feb 2025 20:05:16 +0100 Subject: [PATCH 1808/1831] Supprt Python 3.13 --- .github/workflows/test.yml | 8 ++++---- setup.py | 1 + tox.ini | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 035b7f3d1..22d3b278a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.12" + python-version: "3.13" - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - run: python examples/perft/perft.py -t 1 examples/perft/chess960.perft --max-nodes 100000 @@ -39,7 +39,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -59,7 +59,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.12" + python-version: "3.13" - run: sudo apt-get update && sudo apt-get install -y docutils-common - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null - run: pip install -e . diff --git a/setup.py b/setup.py index b825adb44..9d6aa8c58 100755 --- a/setup.py +++ b/setup.py @@ -83,6 +83,7 @@ def read_description(): "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Games/Entertainment :: Board Games", "Topic :: Games/Entertainment :: Turn Based Strategy", "Topic :: Software Development :: Libraries :: Python Modules", diff --git a/tox.ini b/tox.ini index 8d8033676..5970b2c79 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py38,py39,py310,py311 +envlist = py38,py39,py310,py311,py312,py313 [testenv] passenv = LD_LIBRARY_PATH From b3c1f62c82b5fc40b14fa33bc9edd31cef68a944 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Tue, 25 Feb 2025 19:20:27 +0100 Subject: [PATCH 1809/1831] Prepare 1.11.2 --- CHANGELOG.rst | 8 ++++++++ chess/__init__.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 05b899a20..03a9555d1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ Changelog for python-chess ========================== +New in v1.11.2 (25th Feb 2025) +------------------------------ + +Bugfixes: + +* Fix ``chess.gaviota.PythonTablebase`` does not properly resolve positions + where en passant captures are the best move. + New in v1.11.1 (9th Oct 2024) ----------------------------- diff --git a/chess/__init__.py b/chess/__init__.py index 8d0a68258..268f91cd5 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -11,7 +11,7 @@ __email__ = "niklas.fiekas@backscattering.de" -__version__ = "1.11.1" +__version__ = "1.11.2" import collections import copy From 2b8b0eb06accff3c4dea2e1cec108b3900a4f1d5 Mon Sep 17 00:00:00 2001 From: Mark Harrison Date: Mon, 24 Mar 2025 01:54:37 -0700 Subject: [PATCH 1810/1831] Add some missing docstrings This should cause these methods to appear in the readthedocs docs. --- chess/__init__.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index 268f91cd5..28bcad0cd 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1810,11 +1810,13 @@ def ply(self) -> int: return 2 * (self.fullmove_number - 1) + (self.turn == BLACK) def remove_piece_at(self, square: Square) -> Optional[Piece]: + """Remove a piece, if any, from the given square and return the removed piece.""" piece = super().remove_piece_at(square) self.clear_stack() return piece def set_piece_at(self, square: Square, piece: Optional[Piece], promoted: bool = False) -> None: + """Place a piece on a square.""" super().set_piece_at(square, piece, promoted=promoted) self.clear_stack() @@ -1998,6 +2000,7 @@ def is_pseudo_legal(self, move: Move) -> bool: return bool(self.attacks_mask(move.from_square) & to_mask) def is_legal(self, move: Move) -> bool: + """Check if a move is legal in the current position.""" return not self.is_variant_end() and self.is_pseudo_legal(move) and not self.is_into_check(move) def is_variant_end(self) -> bool: @@ -2034,9 +2037,27 @@ def is_variant_draw(self) -> bool: return False def is_game_over(self, *, claim_draw: bool = False) -> bool: + """ + Check if the game is over by any rule. + + The game is not considered to be over by the + :func:`fifty-move rule ` or + :func:`threefold repetition `, + unless *claim_draw* is given. Note that checking the latter can be + slow. + """ return self.outcome(claim_draw=claim_draw) is not None def result(self, *, claim_draw: bool = False) -> str: + """ + Return the result of a game: 1-0, 0-1, 1/2-1/2, or *. + + The game is not considered to be over by the + :func:`fifty-move rule ` or + :func:`threefold repetition `, + unless *claim_draw* is given. Note that checking the latter can be + slow. + """ outcome = self.outcome(claim_draw=claim_draw) return outcome.result() if outcome else "*" From b2144c2564f740ea120d037e9ec6129d8a3bea2c Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Oct 2025 23:01:01 +0200 Subject: [PATCH 1811/1831] Remove explicit CodeQL configuration --- .github/workflows/codeql.yml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index bc991c885..000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: CodeQL - -on: [push, pull_request] - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - steps: - - uses: actions/checkout@v4 - - uses: github/codeql-action/init@v3 - with: - languages: python - - uses: github/codeql-action/analyze@v3 From 760360b8ddb65129aea46f84d99b5491e6ed6435 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Oct 2025 23:04:49 +0200 Subject: [PATCH 1812/1831] Explicitly specify CI workflow permissions --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 22d3b278a..9eca0fce3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,6 +2,9 @@ name: Test on: [push, pull_request] +permissions: + contents: read + jobs: test: strategy: From 6b1cfedd442a05767ee28c7752a800ad4190f423 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Oct 2025 23:14:56 +0200 Subject: [PATCH 1813/1831] Fix chess.gaviota bytearray usage does not pass mypy 1.18 --- chess/gaviota.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index 281df836b..dc19557cd 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1716,7 +1716,7 @@ def _tb_probe(self, req: Request) -> int: z = self.egtb_block_getsize_zipped(req.egkey, block) self.egtb_block_park(req.egkey, block, stream) - buffer_zipped = stream.read(z) + buffer_zipped: bytearray | bytes = stream.read(z) if buffer_zipped[0] == 0: # If flag is zero, plain LZMA is following. From 71f5a21fe9a83770081fa9f7d2deb3835db984e4 Mon Sep 17 00:00:00 2001 From: Jackson Hall Date: Sat, 4 Oct 2025 16:52:41 -0400 Subject: [PATCH 1814/1831] Add and use rank/file constants --- chess/__init__.py | 80 +++++++++++++++++++++++++++++------------------ chess/gaviota.py | 8 ++--- chess/syzygy.py | 2 +- 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 28bcad0cd..3d3dad4f0 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -64,8 +64,28 @@ def piece_name(piece_type: PieceType) -> str: "P": "♙", "p": "♟", } +File: TypeAlias = int +FILE_A: File = 0 +FILE_B: File = 1 +FILE_C: File = 2 +FILE_D: File = 3 +FILE_E: File = 4 +FILE_F: File = 5 +FILE_G: File = 6 +FILE_H: File = 7 +FILES = [FILE_A, FILE_B, FILE_C, FILE_D, FILE_E, FILE_F, FILE_G, FILE_H] FILE_NAMES = ["a", "b", "c", "d", "e", "f", "g", "h"] +Rank: TypeAlias = int +RANK_1: Rank = 0 +RANK_2: Rank = 1 +RANK_3: Rank = 2 +RANK_4: Rank = 3 +RANK_5: Rank = 4 +RANK_6: Rank = 5 +RANK_7: Rank = 6 +RANK_8: Rank = 7 +RANKS = [RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8] RANK_NAMES = ["1", "2", "3", "4", "5", "6", "7", "8"] STARTING_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" @@ -251,15 +271,15 @@ def square_name(square: Square) -> str: """Gets the name of the square, like ``a3``.""" return SQUARE_NAMES[square] -def square(file_index: int, rank_index: int) -> Square: +def square(file_index: File, rank_index: Rank) -> Square: """Gets a square number by file and rank index.""" return rank_index * 8 + file_index -def square_file(square: Square) -> int: +def square_file(square: Square) -> File: """Gets the file index of the square where ``0`` is the a-file.""" return square & 7 -def square_rank(square: Square) -> int: +def square_rank(square: Square) -> Rank: """Gets the rank index of the square where ``0`` is the first rank.""" return square >> 3 @@ -376,24 +396,24 @@ def square_mirror(square: Square) -> Square: BB_LIGHT_SQUARES: Bitboard = 0x55aa_55aa_55aa_55aa BB_DARK_SQUARES: Bitboard = 0xaa55_aa55_aa55_aa55 -BB_FILE_A: Bitboard = 0x0101_0101_0101_0101 << 0 -BB_FILE_B: Bitboard = 0x0101_0101_0101_0101 << 1 -BB_FILE_C: Bitboard = 0x0101_0101_0101_0101 << 2 -BB_FILE_D: Bitboard = 0x0101_0101_0101_0101 << 3 -BB_FILE_E: Bitboard = 0x0101_0101_0101_0101 << 4 -BB_FILE_F: Bitboard = 0x0101_0101_0101_0101 << 5 -BB_FILE_G: Bitboard = 0x0101_0101_0101_0101 << 6 -BB_FILE_H: Bitboard = 0x0101_0101_0101_0101 << 7 +BB_FILE_A: Bitboard = 0x0101_0101_0101_0101 << FILE_A +BB_FILE_B: Bitboard = 0x0101_0101_0101_0101 << FILE_B +BB_FILE_C: Bitboard = 0x0101_0101_0101_0101 << FILE_C +BB_FILE_D: Bitboard = 0x0101_0101_0101_0101 << FILE_D +BB_FILE_E: Bitboard = 0x0101_0101_0101_0101 << FILE_E +BB_FILE_F: Bitboard = 0x0101_0101_0101_0101 << FILE_F +BB_FILE_G: Bitboard = 0x0101_0101_0101_0101 << FILE_G +BB_FILE_H: Bitboard = 0x0101_0101_0101_0101 << FILE_H BB_FILES: List[Bitboard] = [BB_FILE_A, BB_FILE_B, BB_FILE_C, BB_FILE_D, BB_FILE_E, BB_FILE_F, BB_FILE_G, BB_FILE_H] -BB_RANK_1: Bitboard = 0xff << (8 * 0) -BB_RANK_2: Bitboard = 0xff << (8 * 1) -BB_RANK_3: Bitboard = 0xff << (8 * 2) -BB_RANK_4: Bitboard = 0xff << (8 * 3) -BB_RANK_5: Bitboard = 0xff << (8 * 4) -BB_RANK_6: Bitboard = 0xff << (8 * 5) -BB_RANK_7: Bitboard = 0xff << (8 * 6) -BB_RANK_8: Bitboard = 0xff << (8 * 7) +BB_RANK_1: Bitboard = 0xff << (8 * RANK_1) +BB_RANK_2: Bitboard = 0xff << (8 * RANK_2) +BB_RANK_3: Bitboard = 0xff << (8 * RANK_3) +BB_RANK_4: Bitboard = 0xff << (8 * RANK_4) +BB_RANK_5: Bitboard = 0xff << (8 * RANK_5) +BB_RANK_6: Bitboard = 0xff << (8 * RANK_6) +BB_RANK_7: Bitboard = 0xff << (8 * RANK_7) +BB_RANK_8: Bitboard = 0xff << (8 * RANK_8) BB_RANKS: List[Bitboard] = [BB_RANK_1, BB_RANK_2, BB_RANK_3, BB_RANK_4, BB_RANK_5, BB_RANK_6, BB_RANK_7, BB_RANK_8] BB_BACKRANKS: Bitboard = BB_RANK_1 | BB_RANK_8 @@ -1847,7 +1867,7 @@ def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bit self.occupied_co[not self.turn] & to_mask) for to_square in scan_reversed(targets): - if square_rank(to_square) in [0, 7]: + if square_rank(to_square) in [RANK_1, RANK_8]: yield Move(from_square, to_square, QUEEN) yield Move(from_square, to_square, ROOK) yield Move(from_square, to_square, BISHOP) @@ -1870,7 +1890,7 @@ def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bit for to_square in scan_reversed(single_moves): from_square = to_square + (8 if self.turn == BLACK else -8) - if square_rank(to_square) in [0, 7]: + if square_rank(to_square) in [RANK_1, RANK_8]: yield Move(from_square, to_square, QUEEN) yield Move(from_square, to_square, ROOK) yield Move(from_square, to_square, BISHOP) @@ -1897,7 +1917,7 @@ def generate_pseudo_legal_ep(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboa capturers = ( self.pawns & self.occupied_co[self.turn] & from_mask & BB_PAWN_ATTACKS[not self.turn][self.ep_square] & - BB_RANKS[4 if self.turn else 3]) + BB_RANKS[RANK_5 if self.turn else RANK_4]) for capturer in scan_reversed(capturers): yield Move(capturer, self.ep_square) @@ -1977,9 +1997,9 @@ def is_pseudo_legal(self, move: Move) -> bool: if piece != PAWN: return False - if self.turn == WHITE and square_rank(move.to_square) != 7: + if self.turn == WHITE and square_rank(move.to_square) != RANK_8: return False - elif self.turn == BLACK and square_rank(move.to_square) != 0: + elif self.turn == BLACK and square_rank(move.to_square) != RANK_1: return False # Handle castling. @@ -2401,18 +2421,18 @@ def push(self, move: Move) -> None: else: self.castling_rights &= ~BB_RANK_8 elif captured_piece_type == KING and not self.promoted & to_bb: - if self.turn == WHITE and square_rank(move.to_square) == 7: + if self.turn == WHITE and square_rank(move.to_square) == RANK_8: self.castling_rights &= ~BB_RANK_8 - elif self.turn == BLACK and square_rank(move.to_square) == 0: + elif self.turn == BLACK and square_rank(move.to_square) == RANK_1: self.castling_rights &= ~BB_RANK_1 # Handle special pawn moves. if piece_type == PAWN: diff = move.to_square - move.from_square - if diff == 16 and square_rank(move.from_square) == 1: + if diff == 16 and square_rank(move.from_square) == RANK_2: self.ep_square = move.from_square + 8 - elif diff == -16 and square_rank(move.from_square) == 6: + elif diff == -16 and square_rank(move.from_square) == RANK_7: self.ep_square = move.from_square - 8 elif move.to_square == ep_square and abs(diff) in [7, 9] and not captured_piece_type: # Remove pawns captured en passant. @@ -3605,11 +3625,11 @@ def _valid_ep_square(self) -> Optional[Square]: return None if self.turn == WHITE: - ep_rank = 5 + ep_rank = RANK_6 pawn_mask = shift_down(BB_SQUARES[self.ep_square]) seventh_rank_mask = shift_up(BB_SQUARES[self.ep_square]) else: - ep_rank = 2 + ep_rank = RANK_3 pawn_mask = shift_up(BB_SQUARES[self.ep_square]) seventh_rank_mask = shift_down(BB_SQUARES[self.ep_square]) diff --git a/chess/gaviota.py b/chess/gaviota.py index dc19557cd..c352a27ca 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -110,12 +110,12 @@ def idx_is_empty(x: int) -> int: def flip_type(x: chess.Square, y: chess.Square) -> int: ret = 0 - if chess.square_file(x) > 3: + if chess.square_file(x) > chess.FILE_D: x = flip_we(x) y = flip_we(y) ret |= 1 - if chess.square_rank(x) > 3: + if chess.square_rank(x) > chess.RANK_4: x = flip_ns(x) y = flip_ns(y) ret |= 2 @@ -351,11 +351,11 @@ def init_ppidx() -> Tuple[List[List[int]], List[int], List[int]]: def norm_kkindex(x: chess.Square, y: chess.Square) -> Tuple[int, int]: - if chess.square_file(x) > 3: + if chess.square_file(x) > chess.FILE_D: x = flip_we(x) y = flip_we(y) - if chess.square_rank(x) > 3: + if chess.square_rank(x) > chess.RANK_4: x = flip_ns(x) y = flip_ns(y) diff --git a/chess/syzygy.py b/chess/syzygy.py index c61890550..0c6b7822c 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -761,7 +761,7 @@ def calc_symlen(self, d: PairsData, s: int, tmp: List[int]) -> None: d.symlen[s] = d.symlen[s1] + d.symlen[s2] + 1 tmp[s] = 1 - def pawn_file(self, pos: List[chess.Square]) -> int: + def pawn_file(self, pos: List[chess.Square]) -> chess.File: for i in range(1, self.pawns[0]): if FLAP[pos[0]] > FLAP[pos[i]]: pos[0], pos[i] = pos[i], pos[0] From bd8074d20e7aa667315b54470d0f3aae6390e69d Mon Sep 17 00:00:00 2001 From: Jackson Hall Date: Sat, 4 Oct 2025 20:47:45 -0400 Subject: [PATCH 1815/1831] Add `parse_file`/`parse_rank`, `file_name`/rank_name` --- chess/__init__.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index 3d3dad4f0..84bfa632a 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -275,6 +275,32 @@ def square(file_index: File, rank_index: Rank) -> Square: """Gets a square number by file and rank index.""" return rank_index * 8 + file_index +def parse_file(name: str) -> File: + """ + Gets the file index for the given file *name* + (e.g., ``a`` returns ``0``). + + :raises: :exc:`ValueError` if the file name is invalid. + """ + return FILE_NAMES.index(name) + +def file_name(file: File) -> str: + """Gets the name of the file, like ``a``.""" + return FILE_NAMES[file] + +def parse_rank(name: str) -> File: + """ + Gets the rank index for the given rank *name* + (e.g., ``1`` returns ``0``). + + :raises: :exc:`ValueError` if the rank name is invalid. + """ + return FILE_NAMES.index(name) + +def rank_name(rank: Rank) -> str: + """Gets the name of the rank, like ``1``.""" + return FILE_NAMES[rank] + def square_file(square: Square) -> File: """Gets the file index of the square where ``0`` is the a-file.""" return square & 7 From 376d603694913a82bcb2efa594972a5fba5804f6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Oct 2025 09:20:54 +0200 Subject: [PATCH 1816/1831] Explicitly support Python 3.14 --- .github/workflows/test.yml | 24 ++++++++++++------------ setup.py | 1 + tox.ini | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9eca0fce3..6b31bce24 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,11 +10,11 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - run: .github/workflows/setup-${{ matrix.os }}.sh @@ -24,10 +24,10 @@ jobs: perft: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: - python-version: "3.13" + python-version: "3.14" - run: pip install -e . - run: python examples/perft/perft.py -t 1 examples/perft/random.perft --max-nodes 10000 - run: python examples/perft/perft.py -t 1 examples/perft/chess960.perft --max-nodes 100000 @@ -42,11 +42,11 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - run: pip install -e . @@ -59,10 +59,10 @@ jobs: readme: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: - python-version: "3.13" + python-version: "3.14" - run: sudo apt-get update && sudo apt-get install -y docutils-common - run: python setup.py --long-description | rst2html --strict --no-raw > /dev/null - run: pip install -e . diff --git a/setup.py b/setup.py index 9d6aa8c58..5815947cd 100755 --- a/setup.py +++ b/setup.py @@ -84,6 +84,7 @@ def read_description(): "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Games/Entertainment :: Board Games", "Topic :: Games/Entertainment :: Turn Based Strategy", "Topic :: Software Development :: Libraries :: Python Modules", diff --git a/tox.ini b/tox.ini index 5970b2c79..493a46feb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py38,py39,py310,py311,py312,py313 +envlist = py38,py39,py310,py311,py312,py313,py314 [testenv] passenv = LD_LIBRARY_PATH From e4386c2f1efcb686c1d6222681cc84d1f0b06ded Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Oct 2025 15:25:33 +0200 Subject: [PATCH 1817/1831] Remove chess.engine.DefaultEventLoopPolicy (breaking change forced by Python) --- chess/engine.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index b979b278f..8482c31ba 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -50,10 +50,6 @@ def override(fn: F, /) -> F: MANAGED_OPTIONS = ["uci_chess960", "uci_variant", "multipv", "ponder"] -# No longer needed, but alias kept around for compatibility. -EventLoopPolicy = asyncio.DefaultEventLoopPolicy - - def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Coroutine[Any, Any, None]], *, name: Optional[str] = None, debug: Optional[bool] = None) -> T: """ Runs ``coroutine(future)`` in a new event loop on a background thread. From e974a37e52a59709a0988872a12c1f01244a8c15 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Oct 2025 15:30:39 +0200 Subject: [PATCH 1818/1831] Fix test_sf_forced_mates() failing due to ambiguous mate --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index c120c049f..2ebd357d0 100755 --- a/test.py +++ b/test.py @@ -3079,7 +3079,7 @@ def test_sf_forced_mates(self): for epd in epds: operations = board.set_epd(epd) - result = engine.play(board, chess.engine.Limit(mate=5), game=object()) + result = engine.play(board, chess.engine.Limit(mate=3), game=object()) self.assertIn(result.move, operations["bm"], operations["id"]) @catchAndSkip(FileNotFoundError, "need stockfish") From 8412bd56a282f7fe7071a8b1788b6b791d5e7b0e Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Oct 2025 15:33:30 +0200 Subject: [PATCH 1819/1831] asyncio.iscoroutinefunction() -> inspect.iscoroutinefunction() --- chess/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chess/engine.py b/chess/engine.py index 8482c31ba..913940190 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -8,6 +8,7 @@ import copy import dataclasses import enum +import inspect import logging import math import shlex @@ -58,7 +59,7 @@ def run_in_background(coroutine: Callable[[concurrent.futures.Future[T]], Corout The coroutine and all remaining tasks continue running in the background until complete. """ - assert asyncio.iscoroutinefunction(coroutine) + assert inspect.iscoroutinefunction(coroutine) future: concurrent.futures.Future[T] = concurrent.futures.Future() From 624d3a730c180e749ea04a473a828b9c31ff52a4 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 11 Oct 2025 15:38:19 +0200 Subject: [PATCH 1820/1831] Do not fail-fast matrix jobs that may have interesting results --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6b31bce24..9d0880bb4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,6 +11,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + fail-fast: false runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v5 @@ -43,6 +44,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + fail-fast: false runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 From 4d9b3bfd860bfa95731d4e208fd98c7c10a15533 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 27 Oct 2025 21:24:16 +0100 Subject: [PATCH 1821/1831] Fix Gaviota tables opened as writable (fixes #1166) --- chess/gaviota.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/gaviota.py b/chess/gaviota.py index c352a27ca..8beb18d4d 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1663,7 +1663,7 @@ def _open_tablebase(self, req: Request) -> BinaryIO: if stream is None: path = self.available_tables[req.egkey] - stream = open(path, "rb+") + stream = open(path, "rb") self.egtb_loadindexes(req.egkey, stream) self.streams[req.egkey] = stream From f8575f962caf3fcddcf95d935d1d75a1cceb586b Mon Sep 17 00:00:00 2001 From: Jackson Hall Date: Sun, 2 Nov 2025 18:46:03 -0500 Subject: [PATCH 1822/1831] Add `Board.gives_checkmate()` --- chess/__init__.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/chess/__init__.py b/chess/__init__.py index 84bfa632a..b51c31ca3 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -1980,6 +1980,17 @@ def gives_check(self, move: Move) -> bool: finally: self.pop() + def gives_checkmate(self, move: Move) -> bool: + """ + Probes if the given move would put the opponent in checkmate. The move + must be at least pseudo-legal. + """ + self.push(move) + try: + return self.is_checkmate() + finally: + self.pop() + def is_into_check(self, move: Move) -> bool: king = self.king(self.turn) if king is None: From d59bad55df4b8759e53b0ee8673ec8e69c5f5a82 Mon Sep 17 00:00:00 2001 From: johndoknjas Date: Fri, 2 Jan 2026 10:02:39 -0800 Subject: [PATCH 1823/1831] Ensure hash is always set after threads. --- chess/engine.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 913940190..72b579dc9 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1875,12 +1875,16 @@ def _parse_uci_bestmove(board: chess.Board, args: str) -> BestMove: return BestMove(move, ponder) -def _chain_config(a: ConfigMapping, b: ConfigMapping) -> Iterator[Tuple[str, ConfigValue]]: - for name, value in a.items(): +def _chain_config(a: ConfigMapping, b: ConfigMapping, with_hash_reordering: bool = True) -> Iterator[Tuple[str, ConfigValue]]: + merged = dict(a) + for k, v in b.items(): + merged.setdefault(k, v) + if with_hash_reordering and 'Hash' in merged and 'Threads' in merged: + hash_val = merged['Hash'] + del merged['Hash'] + merged['Hash'] = hash_val + for name, value in merged.items(): yield name, value - for name, value in b.items(): - if name not in a: - yield name, value class UciOptionMap(MutableMapping[str, T]): From a5bbe3ea49f04b6a153efd278d1d17b073a11fc0 Mon Sep 17 00:00:00 2001 From: johndoknjas Date: Fri, 2 Jan 2026 20:46:19 -0800 Subject: [PATCH 1824/1831] Remove optional parameter. --- chess/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 72b579dc9..0a9af75d9 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1875,11 +1875,11 @@ def _parse_uci_bestmove(board: chess.Board, args: str) -> BestMove: return BestMove(move, ponder) -def _chain_config(a: ConfigMapping, b: ConfigMapping, with_hash_reordering: bool = True) -> Iterator[Tuple[str, ConfigValue]]: +def _chain_config(a: ConfigMapping, b: ConfigMapping) -> Iterator[Tuple[str, ConfigValue]]: merged = dict(a) for k, v in b.items(): merged.setdefault(k, v) - if with_hash_reordering and 'Hash' in merged and 'Threads' in merged: + if 'Hash' in merged and 'Threads' in merged: hash_val = merged['Hash'] del merged['Hash'] merged['Hash'] = hash_val From a28315bbfe31410120e97aa2f2fe56a19043e242 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sat, 3 Jan 2026 12:29:26 +0100 Subject: [PATCH 1825/1831] Comment Hash after Threads --- chess/engine.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/chess/engine.py b/chess/engine.py index 0a9af75d9..c66bc0c45 100644 --- a/chess/engine.py +++ b/chess/engine.py @@ -1875,16 +1875,16 @@ def _parse_uci_bestmove(board: chess.Board, args: str) -> BestMove: return BestMove(move, ponder) -def _chain_config(a: ConfigMapping, b: ConfigMapping) -> Iterator[Tuple[str, ConfigValue]]: +def _chain_config(a: ConfigMapping, b: ConfigMapping) -> Iterable[Tuple[str, ConfigValue]]: merged = dict(a) for k, v in b.items(): merged.setdefault(k, v) - if 'Hash' in merged and 'Threads' in merged: - hash_val = merged['Hash'] - del merged['Hash'] - merged['Hash'] = hash_val - for name, value in merged.items(): - yield name, value + if "Hash" in merged and "Threads" in merged: + # Move Hash after Threads, as recommended by Stockfish. + hash_val = merged["Hash"] + del merged["Hash"] + merged["Hash"] = hash_val + return merged.items() class UciOptionMap(MutableMapping[str, T]): From 76cbe9843b7be94676cf19ea2a446e4eb3ac4291 Mon Sep 17 00:00:00 2001 From: winapiadmin <138602885+winapiadmin@users.noreply.github.com> Date: Fri, 13 Feb 2026 21:41:52 +0000 Subject: [PATCH 1826/1831] Multiple kings per color (was_into_check and more affected) (#1179) * fixed multiple kings for was_into_check * fixed king() behavior on multiple kings minus prev commit * add test cases (very little) * using the precomputed king mask * removed testcase of was_into_check() on multiple kings... ... because it would cause the function to return False (because king() didn't detect any king because of decision) --- chess/__init__.py | 2 +- test.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/chess/__init__.py b/chess/__init__.py index b51c31ca3..347f22ea1 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -916,7 +916,7 @@ def king(self, color: Color) -> Optional[Square]: considered. """ king_mask = self.occupied_co[color] & self.kings & ~self.promoted - return msb(king_mask) if king_mask else None + return msb(king_mask) if king_mask and popcount(king_mask) == 1 else None def attacks_mask(self, square: Square) -> Bitboard: bb_square = BB_SQUARES[square] diff --git a/test.py b/test.py index 2ebd357d0..4927a2b80 100755 --- a/test.py +++ b/test.py @@ -1720,6 +1720,10 @@ def test_impossible_check_due_to_en_passant(self): self.assertFalse(board.has_legal_en_passant()) self.assertEqual(len(list(board.legal_moves)), 2) + def test_multiple_kings(self): + board = chess.Board("KKKK1kkk/8/8/8/8/8/8/8 w - - 0 1") + self.assertEqual(board.king(chess.WHITE), None) + class LegalMoveGeneratorTestCase(unittest.TestCase): From 312f3bf07758628e4ee9befbd9e3df7dd5eccea6 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 13 Feb 2026 22:52:23 +0100 Subject: [PATCH 1827/1831] Introduce Board._effective_promoted() --- chess/__init__.py | 55 ++++++++++++++++++++++++++++------------------- chess/variant.py | 27 +++++++---------------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/chess/__init__.py b/chess/__init__.py index 347f22ea1..7fe4cb9cc 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -907,16 +907,19 @@ def color_at(self, square: Square) -> Optional[Color]: else: return None + def _effective_promoted(self) -> Bitboard: + return BB_EMPTY + def king(self, color: Color) -> Optional[Square]: """ - Finds the king square of the given side. Returns ``None`` if there - is no king of that color. + Finds the unique king square of the given side. Returns ``None`` if + there is no king or multiple kings of that color. In variants with king promotions, only non-promoted kings are considered. """ - king_mask = self.occupied_co[color] & self.kings & ~self.promoted - return msb(king_mask) if king_mask and popcount(king_mask) == 1 else None + king_mask = self.occupied_co[color] & self.kings & ~self._effective_promoted() + return msb(king_mask) if king_mask and not king_mask & (king_mask - 1) else None def attacks_mask(self, square: Square) -> Bitboard: bb_square = BB_SQUARES[square] @@ -1135,7 +1138,7 @@ def set_piece_at(self, square: Square, piece: Optional[Piece], promoted: bool = else: self._set_piece_at(square, piece.piece_type, piece.color, promoted) - def board_fen(self, *, promoted: Optional[bool] = False) -> str: + def board_fen(self, *, promoted: Optional[bool] = None) -> str: """ Gets the board FEN (e.g., ``rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR``). @@ -1153,7 +1156,14 @@ def board_fen(self, *, promoted: Optional[bool] = False) -> str: builder.append(str(empty)) empty = 0 builder.append(piece.symbol()) - if promoted and BB_SQUARES[square] & self.promoted: + + if promoted is None: + promoted_mask = self._effective_promoted() + elif promoted: + promoted_mask = self.promoted + else: + promoted_mask = BB_EMPTY + if BB_SQUARES[square] & promoted_mask: builder.append("~") if BB_SQUARES[square] & BB_FILE_H: @@ -1335,7 +1345,7 @@ def chess960_pos(self) -> Optional[int]: return None if self.pawns != BB_RANK_2 | BB_RANK_7: return None - if self.promoted: + if self._effective_promoted(): return None # Piece counts. @@ -2452,12 +2462,12 @@ def push(self, move: Move) -> None: # Update castling rights. self.castling_rights &= ~to_bb & ~from_bb - if piece_type == KING and not promoted: + if piece_type == KING and not self._effective_promoted() & from_bb: if self.turn == WHITE: self.castling_rights &= ~BB_RANK_1 else: self.castling_rights &= ~BB_RANK_8 - elif captured_piece_type == KING and not self.promoted & to_bb: + elif captured_piece_type == KING and not self._effective_promoted() & to_bb: if self.turn == WHITE and square_rank(move.to_square) == RANK_8: self.castling_rights &= ~BB_RANK_8 elif self.turn == BLACK and square_rank(move.to_square) == RANK_1: @@ -3404,8 +3414,8 @@ def _reduces_castling_rights(self, move: Move) -> bool: cr = self.clean_castling_rights() touched = BB_SQUARES[move.from_square] ^ BB_SQUARES[move.to_square] return bool(touched & cr or - cr & BB_RANK_1 and touched & self.kings & self.occupied_co[WHITE] & ~self.promoted or - cr & BB_RANK_8 and touched & self.kings & self.occupied_co[BLACK] & ~self.promoted) + cr & BB_RANK_1 and touched & self.kings & self.occupied_co[WHITE] & ~self._effective_promoted() or + cr & BB_RANK_8 and touched & self.kings & self.occupied_co[BLACK] & ~self._effective_promoted()) def is_irreversible(self, move: Move) -> bool: """ @@ -3459,16 +3469,16 @@ def clean_castling_rights(self) -> Bitboard: black_castling &= (BB_A8 | BB_H8) # The kings must be on e1 or e8. - if not self.occupied_co[WHITE] & self.kings & ~self.promoted & BB_E1: + if not self.occupied_co[WHITE] & self.kings & ~self._effective_promoted() & BB_E1: white_castling = 0 - if not self.occupied_co[BLACK] & self.kings & ~self.promoted & BB_E8: + if not self.occupied_co[BLACK] & self.kings & ~self._effective_promoted() & BB_E8: black_castling = 0 return white_castling | black_castling else: # The kings must be on the back rank. - white_king_mask = self.occupied_co[WHITE] & self.kings & BB_RANK_1 & ~self.promoted - black_king_mask = self.occupied_co[BLACK] & self.kings & BB_RANK_8 & ~self.promoted + white_king_mask = self.occupied_co[WHITE] & self.kings & BB_RANK_1 & ~self._effective_promoted() + black_king_mask = self.occupied_co[BLACK] & self.kings & BB_RANK_8 & ~self._effective_promoted() if not white_king_mask: white_castling = 0 if not black_king_mask: @@ -3506,7 +3516,7 @@ def has_kingside_castling_rights(self, color: Color) -> bool: castling rights. """ backrank = BB_RANK_1 if color == WHITE else BB_RANK_8 - king_mask = self.kings & self.occupied_co[color] & backrank & ~self.promoted + king_mask = self.kings & self.occupied_co[color] & backrank & ~self._effective_promoted() if not king_mask: return False @@ -3527,7 +3537,7 @@ def has_queenside_castling_rights(self, color: Color) -> bool: castling rights. """ backrank = BB_RANK_1 if color == WHITE else BB_RANK_8 - king_mask = self.kings & self.occupied_co[color] & backrank & ~self.promoted + king_mask = self.kings & self.occupied_co[color] & backrank & ~self._effective_promoted() if not king_mask: return False @@ -3600,11 +3610,11 @@ def status(self) -> Status: errors |= STATUS_EMPTY # There must be exactly one king of each color. - if not self.occupied_co[WHITE] & self.kings: + if not self.occupied_co[WHITE] & self.kings & ~self._effective_promoted(): errors |= STATUS_NO_WHITE_KING - if not self.occupied_co[BLACK] & self.kings: + if not self.occupied_co[BLACK] & self.kings & ~self._effective_promoted(): errors |= STATUS_NO_BLACK_KING - if popcount(self.occupied & self.kings) > 2: + if popcount(self.occupied & self.kings & ~self._effective_promoted()) > 2: errors |= STATUS_TOO_MANY_KINGS # There can not be more than 16 pieces of any color. @@ -3638,7 +3648,7 @@ def status(self) -> Status: # More than the maximum number of possible checkers in the variant. checkers = self.checkers_mask() - our_kings = self.kings & self.occupied_co[self.turn] & ~self.promoted + our_kings = self.kings & self.occupied_co[self.turn] & ~self._effective_promoted() if checkers: if popcount(checkers) > 2: errors |= STATUS_TOO_MANY_CHECKERS @@ -3822,7 +3832,7 @@ def generate_castling_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboar return backrank = BB_RANK_1 if self.turn == WHITE else BB_RANK_8 - king = self.occupied_co[self.turn] & self.kings & ~self.promoted & backrank & from_mask + king = self.occupied_co[self.turn] & self.kings & ~self._effective_promoted() & backrank & from_mask king &= -king if not king: return @@ -3879,6 +3889,7 @@ def _to_chess960(self, move: Move) -> Move: def _transposition_key(self) -> Hashable: return (self.pawns, self.knights, self.bishops, self.rooks, self.queens, self.kings, + self._effective_promoted(), self.occupied_co[WHITE], self.occupied_co[BLACK], self.turn, self.clean_castling_rights(), self.ep_square if self.has_legal_en_passant() else None) diff --git a/chess/variant.py b/chess/variant.py index 6e9161dc8..ba4c0f1ce 100644 --- a/chess/variant.py +++ b/chess/variant.py @@ -127,16 +127,8 @@ def is_legal(self, move: chess.Move) -> bool: else: return not any(self.generate_pseudo_legal_captures()) - def _transposition_key(self) -> Hashable: - if self.has_chess960_castling_rights(): - return (super()._transposition_key(), self.kings & self.promoted) - else: - return super()._transposition_key() - - def board_fen(self, *, promoted: Optional[bool] = None) -> str: - if promoted is None: - promoted = self.has_chess960_castling_rights() - return super().board_fen(promoted=promoted) + def _effective_promoted(self) -> chess.Bitboard: + return self.kings & self.promoted if self.castling_rights else chess.BB_EMPTY def status(self) -> chess.Status: status = super().status() @@ -261,9 +253,9 @@ def _push_capture(self, move: chess.Move, capture_square: chess.Square, piece_ty # Destroy castling rights. self.castling_rights &= ~explosion_radius - if explosion_radius & self.kings & self.occupied_co[chess.WHITE] & ~self.promoted: + if explosion_radius & self.kings & self.occupied_co[chess.WHITE] & ~self._effective_promoted(): self.castling_rights &= ~chess.BB_RANK_1 - if explosion_radius & self.kings & self.occupied_co[chess.BLACK] & ~self.promoted: + if explosion_radius & self.kings & self.occupied_co[chess.BLACK] & ~self._effective_promoted(): self.castling_rights &= ~chess.BB_RANK_8 # Explode the capturing piece. @@ -930,9 +922,11 @@ def _is_halfmoves(self, n: int) -> bool: def is_irreversible(self, move: chess.Move) -> bool: return self._reduces_castling_rights(move) + def _effective_promoted(self) -> chess.Bitboard: + return self.promoted & ~self.kings & ~self.pawns + def _transposition_key(self) -> Hashable: return (super()._transposition_key(), - self.promoted, str(self.pockets[chess.WHITE]), str(self.pockets[chess.BLACK])) def legal_drop_squares_mask(self) -> chess.Bitboard: @@ -1009,7 +1003,7 @@ def has_insufficient_material(self, color: chess.Color) -> bool: # a different color complex. return ( chess.popcount(self.occupied) + sum(len(pocket) for pocket in self.pockets) <= 3 and - not self.promoted and + not self._effective_promoted() and not self.pawns and not self.rooks and not self.queens and @@ -1041,11 +1035,6 @@ def set_fen(self, fen: str) -> None: self.pockets[chess.WHITE] = white_pocket self.pockets[chess.BLACK] = black_pocket - def board_fen(self, *, promoted: Optional[bool] = None) -> str: - if promoted is None: - promoted = True - return super().board_fen(promoted=promoted) - def epd(self, shredder: bool = False, en_passant: chess.EnPassantSpec = "legal", promoted: Optional[bool] = None, **operations: Union[None, str, int, float, chess.Move, Iterable[chess.Move]]) -> str: epd = super().epd(shredder=shredder, en_passant=en_passant, promoted=promoted) board_part, info_part = epd.split(" ", 1) From fc50a27fa3cfa07243f78eca93ea6126347ea1fa Mon Sep 17 00:00:00 2001 From: Christopher Akiki Date: Fri, 13 Mar 2026 17:49:05 +0100 Subject: [PATCH 1828/1831] [MINOR:TYPO] Update pgn.py instanciate -> instantiate --- chess/pgn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chess/pgn.py b/chess/pgn.py index f40980d48..5ae5b43b0 100644 --- a/chess/pgn.py +++ b/chess/pgn.py @@ -402,7 +402,7 @@ def remove_variation(self, move: Union[int, chess.Move, GameNode]) -> None: def add_variation(self, move: chess.Move, *, comment: Union[str, list[str]] = "", starting_comment: Union[str, list[str]] = "", nags: Iterable[int] = []) -> ChildNode: """Creates a child node with the given attributes.""" - # Instanciate ChildNode only in this method. + # Instantiate ChildNode only in this method. return ChildNode(self, move, comment=comment, starting_comment=starting_comment, nags=nags) def add_main_variation(self, move: chess.Move, *, comment: str = "", nags: Iterable[int] = []) -> ChildNode: From 5e2a2bc153b7646497f3e811f3cfd28aaca1b1ea Mon Sep 17 00:00:00 2001 From: Cady Date: Mon, 30 Mar 2026 16:21:49 -0400 Subject: [PATCH 1829/1831] Fixed typo in README.rst, issue 1183 --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index a6c3185c6..d4d51a128 100644 --- a/README.rst +++ b/README.rst @@ -314,7 +314,7 @@ If you like, share interesting things you are using python-chess for, for exampl | .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/clente-chess.png?raw=true | `clente/chess `_ | | :height: 64 | | | :width: 64 | | -| :target: https://github.com/clente/chess | Oppinionated wrapper to use python-chess from the R programming language | +| :target: https://github.com/clente/chess | Opinionated wrapper to use python-chess from the R programming language | +------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------+ | .. image:: https://github.com/niklasf/python-chess/blob/master/docs/images/crazyara.png?raw=true | https://crazyara.org/ | | :height: 64 | | From efb8b4278c85e0145b29b867de03dc715456dd86 Mon Sep 17 00:00:00 2001 From: Litschi Date: Fri, 27 Mar 2026 19:31:11 +0100 Subject: [PATCH 1830/1831] feat: added piece_count function instead of chess.popcount(board.occupied) --- CHANGELOG.rst | 9 +++++++++ chess/__init__.py | 3 +++ chess/gaviota.py | 8 ++++---- chess/syzygy.py | 10 +++++----- test.py | 2 +- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 03a9555d1..212db89b1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,15 @@ Changelog for python-chess ========================== +New in unreleased (27th Mar 2026) +--------------------------------- + +Bugfixes: +* Fixed typo in README.rst. + +Changes: +* Added ``board.piece_count`` function. + New in v1.11.2 (25th Feb 2025) ------------------------------ diff --git a/chess/__init__.py b/chess/__init__.py index 7fe4cb9cc..12b249bd5 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -841,6 +841,9 @@ def clear_board(self) -> None: :class:`~chess.Board` also clears the move stack. """ self._clear_board() + + def piece_count(self) -> int: + return popcount(self.occupied) def pieces_mask(self, piece_type: PieceType, color: Color) -> Bitboard: if piece_type == PAWN: diff --git a/chess/gaviota.py b/chess/gaviota.py index 8beb18d4d..7152a18f0 100644 --- a/chess/gaviota.py +++ b/chess/gaviota.py @@ -1519,8 +1519,8 @@ def probe_dtm(self, board: chess.Board) -> int: raise KeyError(f"gaviota tables do not contain positions with castling rights: {board.fen()}") # Supports only up to 5 pieces. - if chess.popcount(board.occupied) > 5: - raise KeyError(f"gaviota tables support up to 5 pieces, not {chess.popcount(board.occupied)}: {board.fen()}") + if board.piece_count() > 5: + raise KeyError(f"gaviota tables support up to 5 pieces, not {board.piece_count()}: {board.fen()}") # KvK is a draw. if board.occupied == board.kings: @@ -1885,8 +1885,8 @@ def _probe_hard(self, board: chess.Board, wdl_only: bool = False) -> int: if board.castling_rights: raise KeyError(f"gaviota tables do not contain positions with castling rights: {board.fen()}") - if chess.popcount(board.occupied) > 5: - raise KeyError(f"gaviota tables support up to 5 pieces, not {chess.popcount(board.occupied)}: {board.fen()}") + if board.piece_count() > 5: + raise KeyError(f"gaviota tables support up to 5 pieces, not {board.piece_count()}: {board.fen()}") stm = ctypes.c_uint(0 if board.turn == chess.WHITE else 1) ep_square = ctypes.c_uint(board.ep_square if board.ep_square else 64) diff --git a/chess/syzygy.py b/chess/syzygy.py index 0c6b7822c..2250db5b5 100644 --- a/chess/syzygy.py +++ b/chess/syzygy.py @@ -1548,8 +1548,8 @@ def probe_wdl_table(self, board: chess.Board) -> int: try: table = typing.cast(WdlTable, self.wdl[key]) except KeyError: - if chess.popcount(board.occupied) > TBPIECES: - raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {chess.popcount(board.occupied)}: {board.fen()}") + if board.piece_count() > TBPIECES: + raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {board.piece_count()}: {board.fen()}") raise MissingTableError(f"did not find wdl table {key}") self._bump_lru(table) @@ -1567,8 +1567,8 @@ def probe_ab(self, board: chess.Board, alpha: int, beta: int, threats: bool = Fa # positions that have more pieces than the maximum number of supported # pieces. We artificially limit this to one additional level, to # make sure search remains somewhat bounded. - if chess.popcount(board.occupied) > TBPIECES + 1: - raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {chess.popcount(board.occupied)}: {board.fen()}") + if board.piece_count() > TBPIECES + 1: + raise KeyError(f"syzygy tables support up to {TBPIECES} pieces, not {board.piece_count()}: {board.fen()}") # Special case: Variant with compulsory captures. if self.variant.captures_compulsory: @@ -1613,7 +1613,7 @@ def sprobe_ab(self, board: chess.Board, alpha: int, beta: int, threats: bool = F threats_found = False - if threats or chess.popcount(board.occupied) >= 6: + if threats or board.piece_count() >= 6: for threat in board.generate_legal_moves(~board.pawns): board.push(threat) try: diff --git a/test.py b/test.py index 4927a2b80..228c62f3f 100755 --- a/test.py +++ b/test.py @@ -1220,7 +1220,7 @@ def test_clear(self): self.assertFalse(board.ep_square) self.assertFalse(board.piece_at(chess.E1)) - self.assertEqual(chess.popcount(board.occupied), 0) + self.assertEqual(board.piece_count(), 0) def test_threefold_repetition(self): board = chess.Board() From a345dbd131fb5cbcbffdc9e50901d359480926c5 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 3 Apr 2026 21:24:06 +0200 Subject: [PATCH 1831/1831] Document board.piece_count() --- CHANGELOG.rst | 9 --------- chess/__init__.py | 7 ++++++- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 212db89b1..03a9555d1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,15 +1,6 @@ Changelog for python-chess ========================== -New in unreleased (27th Mar 2026) ---------------------------------- - -Bugfixes: -* Fixed typo in README.rst. - -Changes: -* Added ``board.piece_count`` function. - New in v1.11.2 (25th Feb 2025) ------------------------------ diff --git a/chess/__init__.py b/chess/__init__.py index 12b249bd5..9ea44f36e 100644 --- a/chess/__init__.py +++ b/chess/__init__.py @@ -841,8 +841,13 @@ def clear_board(self) -> None: :class:`~chess.Board` also clears the move stack. """ self._clear_board() - + def piece_count(self) -> int: + """ + Gets the number of pieces on the board. + + Does not include Crazyhouse pockets. + """ return popcount(self.occupied) def pieces_mask(self, piece_type: PieceType, color: Color) -> Bitboard: