Accept a tuple of ints in Square.in_bounds

This is a slight performance increase, because the Enum sequence it
previously accepted was more expensive to hash.
parent 80753f7d
Pipeline #20082341 passed with stages
in 9 minutes and 8 seconds
......@@ -31,7 +31,7 @@ from collections import namedtuple
from enum import Enum
from functools import lru_cache
from types import MethodType
from typing import Sequence, FrozenSet, Union
from typing import FrozenSet, Sequence, Tuple, Union
SAN_END_PATTERN = re.compile(
r'[+#]?[?!]*$')
......@@ -190,7 +190,10 @@ class Square(str):
return destination
raise IndexError('Cannot traverse {!r} from {!r}'.format(path, self))
def in_bounds(self, path: Sequence[Direction]) -> Union['Square', bool]:
def in_bounds(
self,
path: Sequence[Union[Direction, Tuple[int, int]]]) -> Union[
'Square', bool]:
"""Traverse with *path*. Return the destination if it is inside the
bounds of a chess board. Else, return :const:`False`.
......@@ -199,7 +202,9 @@ class Square(str):
"""
balance = (0, 0) # Total offset from origin.
for direction in path:
offset = direction.value
offset = direction
if isinstance(direction, Direction):
offset = direction.value
balance = tuple(map(sum, zip(balance, offset)))
file_ = chr(ord(self.file) + balance[0])
rank = self.rank + balance[1]
......
......@@ -71,51 +71,51 @@ _PAWN_PATHS = { # type: Dict[Side, _TupleOfTwoTuplesOf]
_WHITE: (
# Advancing paths
(
(_UP,),
(_UP, _UP),
(_UP.value,),
(_UP.value, _UP.value),
),
# Capturing paths
(
(_UP, _RIGHT),
(_UP, _LEFT),
(_UP.value, _RIGHT.value),
(_UP.value, _LEFT.value),
),
),
_BLACK: (
# Adancing paths
(
(_DOWN,),
(_DOWN, _DOWN),
(_DOWN.value,),
(_DOWN.value, _DOWN.value),
),
# Capturing paths
(
(_DOWN, _RIGHT),
(_DOWN, _LEFT),
(_DOWN.value, _RIGHT.value),
(_DOWN.value, _LEFT.value),
),
),
}
_PIECE_PATHS = { # type: Dict[Type, Set[_DirectionPath]]
_KNIGHT: {
(_UP, _UP, _RIGHT),
(_UP, _UP, _LEFT),
(_UP, _RIGHT, _RIGHT),
(_UP, _LEFT, _LEFT),
(_DOWN, _RIGHT, _RIGHT),
(_DOWN, _LEFT, _LEFT),
(_DOWN, _DOWN, _RIGHT),
(_DOWN, _DOWN, _LEFT),
(_UP.value, _UP.value, _RIGHT.value),
(_UP.value, _UP.value, _LEFT.value),
(_UP.value, _RIGHT.value, _RIGHT.value),
(_UP.value, _LEFT.value, _LEFT.value),
(_DOWN.value, _RIGHT.value, _RIGHT.value),
(_DOWN.value, _LEFT.value, _LEFT.value),
(_DOWN.value, _DOWN.value, _RIGHT.value),
(_DOWN.value, _DOWN.value, _LEFT.value),
},
_BISHOP: {
(_UP, _RIGHT),
(_UP, _LEFT),
(_DOWN, _RIGHT),
(_DOWN, _LEFT),
(_UP.value, _RIGHT.value),
(_UP.value, _LEFT.value),
(_DOWN.value, _RIGHT.value),
(_DOWN.value, _LEFT.value),
},
_ROOK: {
(_UP,),
(_RIGHT,),
(_LEFT,),
(_DOWN,),
(_UP.value,),
(_RIGHT.value,),
(_LEFT.value,),
(_DOWN.value,),
},
}
_PIECE_PATHS[_QUEEN] = _PIECE_PATHS[_BISHOP].union(_PIECE_PATHS[_ROOK])
......@@ -719,7 +719,7 @@ def _all_moves_single(position: Position, square: Square) -> Iterator[Move]:
if piece.type == _KING:
# Kingside
if position.castling[side].kingside:
destination = square.traverse((_RIGHT, _RIGHT))
destination = square.traverse((_RIGHT.value, _RIGHT.value))
current = square
while current != destination:
current = current.right()
......@@ -731,7 +731,7 @@ def _all_moves_single(position: Position, square: Square) -> Iterator[Move]:
yield Move(square, destination, piece, flags=flags)
# Queenside
if position.castling[side].queenside:
destination = square.traverse((_LEFT, _LEFT))
destination = square.traverse((_LEFT.value, _LEFT.value))
current = square
while current != destination:
current = current.left()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment