Verified Commit 136245f4 authored by Carmen Bianca Bakker's avatar Carmen Bianca Bakker

Merge branch 'master' into remove-enum

parents 5c995229 d66497be
Pipeline #20066896 passed with stages
in 8 minutes and 5 seconds
......@@ -24,13 +24,11 @@
"""Miscellaneous utility functions and the like."""
import re
from functools import lru_cache
from typing import Any, Iterator, List
from ._core import Side, Square
@lru_cache(maxsize=2)
def opponent(side: Side) -> Side:
"""Return the opposite side.
......
......@@ -121,6 +121,12 @@ _PIECE_PATHS = { # type: Dict[Type, Set[_DirectionPath]]
_PIECE_PATHS[_QUEEN] = _PIECE_PATHS[_BISHOP].union(_PIECE_PATHS[_ROOK])
_PIECE_PATHS[_KING] = _PIECE_PATHS[_QUEEN]
_TO_CHECK = { # type: Dict[Type, Set[Type]]
_KNIGHT: frozenset({_KNIGHT}),
_BISHOP: frozenset({_BISHOP, _QUEEN, _KING}),
_ROOK: frozenset({_ROOK, _QUEEN, _KING}),
}
def attacked(position: Position, side: Side, square: Square) -> bool:
""" Is *square* in check by *side*?
......@@ -162,21 +168,17 @@ def attacked(position: Position, side: Side, square: Square) -> bool:
# Pawn
pawn_paths = _PAWN_PATHS[
opponent(side)][1] # type: Iterable[_DirectionPath]
pawn_piece = Piece(_PAWN, side)
for path in pawn_paths:
target = square.in_bounds(path)
if not target:
continue
if position.board.get(target) == Piece(_PAWN, side):
if position.board.get(target) == pawn_piece:
return True
# Pretend our square is a knight, a bishop or a rook. If an identical
# piece (or a queen or a king) is in our path, then our square is in check.
to_check = { # type: Dict[Type, Set[Type]]
_KNIGHT: {_KNIGHT},
_BISHOP: {_BISHOP, _QUEEN, _KING},
_ROOK: {_ROOK, _QUEEN, _KING},
}
for type_, targets in to_check.items():
for type_, targets in _TO_CHECK.items():
for path in _PIECE_PATHS[type_]:
first_traverse = True
current = square
......@@ -317,8 +319,9 @@ def is_check(position: Position, side: Side = None) -> bool:
"""
if side is None:
side = position.side_to_play
king_piece = Piece(_KING, side)
for square, piece in position.board.all_pieces():
if piece == Piece(_KING, side):
if piece == king_piece:
return attacked(position, opponent(side), square)
LOGGER.warning('no king in %s', position)
return False
......
......@@ -58,7 +58,7 @@ def main():
print()
# Measure performance without profiler
NUMBER = 5 # pylint: disable=invalid-name
NUMBER = 10 # pylint: disable=invalid-name
secs = timeit(board_cls, number=NUMBER)
print('Time without profiler: {:.3f} seconds'.format(secs / NUMBER))
print()
......
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