Beispiel #1
0
    def test_pawn_moves(self):
        """Test of pawn_moves() method."""

        assert sorted(PieceMoves.pawn_moves(Position(4, 4), self.game)) == [
            Move(Position(4, 4), Position(3, 5)),
            Move(Position(4, 4), Position(4, 5)),
        ]
Beispiel #2
0
    def pawn_moves(pos: Position, game: Game) -> List[Move]:
        """Return list of <game.turn> pawn moves.
        pawn moves = positions_under_threat + move forward + en_passant
        """

        # Init move list
        moves = []
        # Check if position under threat occupied with opponent pieces or en_passant possible.
        for pos_under_threat in PositionsUnderThreat.positions_under_pawn_threat(
                pos, game.turn, game.board):
            move = Move(pos, pos_under_threat)
            if PositionsUnderThreat.is_position_enemy(
                    pos_under_threat, game.turn,
                    game.board) or move in PieceMoves.en_passant_moves(
                        pos, game):
                moves.append(move)

        # Check forward move.
        shift_forward_y = 1 if game.turn == Colour.WHITE else -1
        pos_forward = Position(pos.x, pos.y + shift_forward_y)
        if game.board.is_position_empty(pos_forward):
            move = Move(pos, pos_forward)
            moves.append(move)
        # Check double move forward
        shift_forward_y = 2 if game.turn == Colour.WHITE else -2
        pos_d_forward = Position(pos.x, pos.y + shift_forward_y)
        if (game.board.is_position_empty(pos_forward)
                and game.board.is_position_empty(pos_d_forward)
                and not PieceMoves.is_piece_touched(pos, game)):
            move = Move(pos, pos_d_forward)
            moves.append(move)
        return moves
Beispiel #3
0
    def test_remove_piece(self):
        board = Board()

        board.set_piece(Position(1, 2), Pieces.BLACK_BISHOP)
        assert board.get_piece(Position(1, 2)) == Pieces.BLACK_BISHOP

        board.remove_piece(Position(1, 2))
        assert board.get_piece(Position(1, 2)) is None
Beispiel #4
0
    def test_positions_under_knight_threat(self):
        """Test of positions_under_knight_threat() method."""

        assert sorted(
            PositionsUnderThreat.positions_under_knight_threat(
                Position(7, 6), Colour.WHITE,
                self.board)) == [Position(5, 7),
                                 Position(6, 4)]
Beispiel #5
0
    def test_set_piece(self):
        board = Board()

        board.set_piece(Position(4, 4), Pieces.WHITE_ROOK)
        # TODO(amirov-m): What is the right order for actual and expected?
        assert board.get_piece(Position(4, 4)) == Pieces.WHITE_ROOK

        board.set_piece(Position(7, 7), Pieces.BLACK_PAWN)
        assert board.get_piece(Position(7, 7)) == Pieces.BLACK_PAWN
Beispiel #6
0
    def test_positions_under_threat(self):
        """Test of positions_under_threat() method."""

        assert sorted(
            PositionsUnderThreat.positions_under_threat(
                Position(4, 4), Pieces.WHITE_KING, self.board)) == [
                    Position(3, 3),
                    Position(3, 5),
                    Position(4, 5),
                    Position(5, 3)
                ]
Beispiel #7
0
    def test_positions_under_king_threat(self):
        """Test of positions_under_king_threat() method."""

        assert sorted(
            PositionsUnderThreat.positions_under_king_threat(
                Position(4, 4), Colour.WHITE, self.board)) == [
                    Position(3, 3),
                    Position(3, 5),
                    Position(4, 5),
                    Position(5, 3)
                ]
Beispiel #8
0
    def check_positions(pos: Position, colour: Colour, board: Board,
                        shifts: list) -> List[Position]:
        """Take input list of shifts and verify which of them are possible."""

        # Init position list.
        positions_under_threat = []
        # Iterate through shifts.
        for shift_x, shift_y in shifts:
            # Check if shift is possible, otherwise break the loop.
            if PositionsUnderThreat.is_position_enemy_or_empty(
                    Position(pos.x + shift_x, pos.y + shift_y), colour, board):
                # Add shift
                positions_under_threat.append(
                    Position(pos.x + shift_x, pos.y + shift_y))
        return positions_under_threat
Beispiel #9
0
    def test_positions_under_queen_threat(self):
        """Test of positions_under_queen_threat() method."""

        assert sorted(
            PositionsUnderThreat.positions_under_queen_threat(
                Position(5, 5), Colour.WHITE, self.board)) == [
                    Position(4, 5),
                    Position(4, 6),
                    Position(5, 6),
                    Position(5, 7),
                    Position(6, 4),
                    Position(6, 5),
                    Position(7, 3),
                    Position(7, 5),
                ]
Beispiel #10
0
 def test_get_positions_for_piece(self):
     board = Board()
     board.set_piece(Position(1, 0), Pieces.WHITE_KNIGHT)
     board.set_piece(Position(4, 0), Pieces.WHITE_KNIGHT)
     board.set_piece(Position(0, 7), Pieces.WHITE_KNIGHT)
     board.set_piece(Position(7, 7), Pieces.WHITE_KNIGHT)
     piece_positions = board.get_positions_for_piece(Pieces.WHITE_KNIGHT)
     assert set(piece_positions) == {
         Position(1, 0),
         Position(4, 0),
         Position(0, 7),
         Position(7, 7),
     }
Beispiel #11
0
    def test_positions_under_rook_threat(self):
        """Test of positions_under_rook_threat() method."""

        assert sorted(
            PositionsUnderThreat.positions_under_rook_threat(
                Position(3, 7), Colour.WHITE, self.board)) == [
                    Position(0, 7),
                    Position(1, 7),
                    Position(2, 7),
                    Position(3, 5),
                    Position(3, 6),
                    Position(4, 7),
                    Position(5, 7),
                ]
Beispiel #12
0
    def test_all_positions_under_threat_for_side(self):
        """Test of all_positions_under_threat_for_side() method."""

        assert sorted(
            PositionsUnderThreat.all_positions_under_threat_for_side(
                Colour.WHITE, self.board)) == [
                    Position(3, 4),
                    Position(3, 7),
                    Position(4, 7),
                    Position(5, 4),
                    Position(5, 5),
                    Position(5, 6),
                    Position(6, 7),
                    Position(7, 7),
                ]
Beispiel #13
0
    def test_is_mate(self):
        """Test of is_check() method."""

        assert not GameLogic.is_mate(self.game)
        # Create dummy board
        board = Board()
        board.set_piece(Position(0, 1), Piece(PieceType.PAWN, Colour.WHITE))
        board.set_piece(Position(1, 1), Piece(PieceType.PAWN, Colour.WHITE))
        board.set_piece(Position(0, 0), Piece(PieceType.KING, Colour.WHITE))
        board.set_piece(Position(2, 0), Piece(PieceType.ROOK, Colour.BLACK))
        history_moves = [
            Move(Position(4, 3), Position(4, 4)),
            Move(Position(3, 6), Position(3, 4)),
        ]
        game = Game(board, Colour.WHITE, history_moves)
        assert GameLogic.is_mate(game)
Beispiel #14
0
    def check_positions_with_obstacles(pos: Position, colour: Colour,
                                       board: Board,
                                       shifts: list) -> List[Position]:
        """Take input list of shifts and verify which of them are possible.
        Iterate through shifts till the first obstacle. Obstacle means own or enemy piece.
        """

        # Init position list.
        positions_under_threat = []
        # Iterates though shifts.
        for shift_x, shift_y in shifts:
            # Check if shift is possible, otherwise break the loop.
            if not PositionsUnderThreat.is_position_enemy_or_empty(
                    Position(pos.x + shift_x, pos.y + shift_y), colour, board):
                break
            # Add shift
            positions_under_threat.append(
                Position(pos.x + shift_x, pos.y + shift_y))
            # Check if position is occupied with enemy piece, otherwise break the loop.
            if PositionsUnderThreat.is_position_enemy(
                    Position(pos.x + shift_x, pos.y + shift_y), colour, board):
                break
        return positions_under_threat
Beispiel #15
0
    def make_move(move: Move, game: Game) -> Game:
        """Make move.

        Attention: no checking of check after move. Technically move can be not valid!!!
        """

        # Copy game (pass by value)
        game = copy.deepcopy(game)
        # Retrieve piece at start position
        piece = game.board.get_piece(move.start)
        # Get possible moves
        possible_moves = PieceMoves.moves(piece.type, move.start, game)
        # Check if move satisfies
        if move in possible_moves:
            # Check if castling occurs
            if move in PieceMoves.castling_moves(move.start, game):
                game.board.set_piece(
                    Position(int((move.finish.x + move.start.x) / 2),
                             move.start.y),
                    Piece(PieceType.ROOK, game.turn),
                )
                # Short castling
                if move.finish.x - move.start.x > 0:
                    game.board.remove_piece(Position(7, move.start.y))
                # Long castling
                else:
                    game.board.remove_piece(Position(0, move.start.y))
            # Check if en passant occurs
            if move in PieceMoves.en_passant_moves(move.start, game):
                game.board.remove_piece(Position(move.finish.x, move.start.y))
            # Update board
            game.board.set_piece(move.finish, piece)
            game.board.remove_piece(move.start)
            # Update history
            game.history_moves.append(move)
        return Game(game.board, Colour.change_colour(game.turn),
                    game.history_moves)
Beispiel #16
0
    def en_passant_moves(pos: Position, game: Game) -> List[Move]:
        """Return list of <game.turn> en passant moves.
        en passant:
            - opponent pawn makes the move at previous turn
            - opponent pawn jumps over 2 positions
        """

        # Init list of moves.
        en_passant = []
        # Retrieve start piece.
        piece_start = game.board.get_piece(pos)
        # Check if piece_start not empty.
        if piece_start is not None and piece_start.type == PieceType.PAWN:
            # 2 directions.
            shifts = [(-1, 0), (1, 0)]
            for shift_x, shift_y in shifts:
                # Retrieve not start piece.
                piece = game.board.get_piece(
                    Position(pos.x + shift_x, pos.y + shift_y))
                if piece is not None and piece.type == PieceType.PAWN:
                    # Retrieve last_move.
                    last_move = game.history_moves[-1]
                    # Check if pawn makes the last move and if it jumps over 2 positions.
                    if (Position(pos.x + shift_x,
                                 pos.y + shift_y) == last_move.finish and
                            abs(last_move.start.y - last_move.finish.y) == 2):
                        # Add move in dependence of colour.
                        if game.turn == Colour.WHITE:
                            move = Move(pos,
                                        Position(pos.x + shift_x, pos.y + 1))
                            en_passant.append(move)
                        else:
                            move = Move(pos,
                                        Position(pos.x + shift_x, pos.y - 1))
                            en_passant.append(move)
        return en_passant
Beispiel #17
0
    def setUp(self) -> None:
        """Create dummy game."""

        # Create dummy board
        self.board = Board()
        self.board.set_piece(Position(4, 3), Pieces.WHITE_PAWN)
        self.board.set_piece(Position(3, 4), Pieces.WHITE_PAWN)
        self.board.set_piece(Position(5, 4), Pieces.WHITE_PAWN)
        self.board.set_piece(Position(0, 6), Pieces.WHITE_PAWN)
        self.board.set_piece(Position(7, 7), Pieces.WHITE_PAWN)
        self.board.set_piece(Position(4, 4), Pieces.WHITE_KING)
        self.board.set_piece(Position(6, 6), Pieces.WHITE_BISHOP)
        self.board.set_piece(Position(3, 7), Pieces.WHITE_ROOK)
        self.board.set_piece(Position(5, 5), Pieces.WHITE_QUEEN)
        self.board.set_piece(Position(7, 6), Pieces.WHITE_KNIGHT)

        self.board.set_piece(Position(4, 5), Pieces.BLACK_PAWN)
        self.board.set_piece(Position(5, 7), Pieces.BLACK_ROOK)
Beispiel #18
0
    def test_make_move(self):
        """Test of make_move() method."""

        # Check short castling
        game = GameLogic.make_move(Move(Position(4, 0), Position(6, 0)),
                                   self.game)
        assert game.turn != self.game.turn
        assert game.history_moves[-1] == Move(Position(4, 0), Position(6, 0))
        assert game.board.get_piece(Position(4, 0)) is None
        assert game.board.get_piece(Position(5, 0)).type == PieceType.ROOK
        assert game.board.get_piece(Position(6, 0)).type == PieceType.KING
        assert game.board.get_piece(Position(7, 0)) is None
        # Check long castling
        game = GameLogic.make_move(Move(Position(4, 0), Position(2, 0)),
                                   self.game)
        assert game.turn != self.game.turn
        assert game.history_moves[-1] == Move(Position(4, 0), Position(2, 0))
        assert game.board.get_piece(Position(4, 0)) is None
        assert game.board.get_piece(Position(3, 0)).type == PieceType.ROOK
        assert game.board.get_piece(Position(2, 0)).type == PieceType.KING
        assert game.board.get_piece(Position(1, 0)) is None
        assert game.board.get_piece(Position(0, 0)) is None
        # Check en_passant
        game = GameLogic.make_move(Move(Position(4, 4), Position(3, 5)),
                                   self.game)
        assert game.turn != self.game.turn
        assert game.history_moves[-1] == Move(Position(4, 4), Position(3, 5))
        assert game.board.get_piece(Position(4, 4)) is None
        assert game.board.get_piece(Position(3, 5)).type == PieceType.PAWN
        assert game.board.get_piece(Position(3, 5)).colour == Colour.WHITE
        assert game.board.get_piece(Position(3, 4)) is None
Beispiel #19
0
 def test_remove_piece_empty_cell(self):
     board = Board()
     board.remove_piece(Position(3, 4))
     assert board.get_piece(Position(3, 4)) is None
Beispiel #20
0
    def test_king_moves(self):
        """Test of king_moves() method."""

        assert sorted(PieceMoves.king_moves(Position(4, 0), self.game)) == [
            Move(Position(4, 0), Position(3, 0)),
            Move(Position(4, 0), Position(3, 1)),
            Move(Position(4, 0), Position(4, 1)),
            Move(Position(4, 0), Position(5, 0)),
            Move(Position(4, 0), Position(5, 1)),
            Move(Position(4, 0), Position(6, 0)),
        ]
Beispiel #21
0
    def setUp(self) -> None:
        """Create dummy game."""

        # Create dummy board
        self.board = Board()
        self.board.set_piece(Position(4, 0), Pieces.WHITE_KING)
        self.board.set_piece(Position(0, 0), Pieces.WHITE_ROOK)
        self.board.set_piece(Position(7, 0), Pieces.WHITE_ROOK)
        self.board.set_piece(Position(4, 4), Pieces.WHITE_PAWN)
        self.board.set_piece(Position(4, 1), Pieces.WHITE_BISHOP)

        self.board.set_piece(Position(3, 4), Pieces.BLACK_PAWN)
        self.board.set_piece(Position(5, 4), Pieces.BLACK_PAWN)
        self.board.set_piece(Position(4, 3), Pieces.BLACK_ROOK)
        self.board.set_piece(Position(2, 2), Pieces.BLACK_PAWN)
        # Create game
        self.game = Game(self.board, Colour.WHITE,
                         [Move(Position(3, 6), Position(3, 4))])
Beispiel #22
0
    def test_is_move_possible(self):
        """Test of is_move_possible() method."""

        assert not GameLogic.is_move_possible(
            self.game, Move(Position(4, 1), Position(3, 2)))
        assert not GameLogic.is_move_possible(
            self.game, Move(Position(4, 0), Position(3, 1)))
        assert not GameLogic.is_move_possible(
            self.game, Move(Position(4, 0), Position(4, -1)))
        assert not GameLogic.is_move_possible(
            self.game, Move(Position(2, 2), Position(2, 1)))
        assert GameLogic.is_move_possible(self.game,
                                          Move(Position(4, 0), Position(5, 1)))
        assert GameLogic.is_move_possible(self.game,
                                          Move(Position(4, 0), Position(2, 0)))
        assert GameLogic.is_move_possible(self.game,
                                          Move(Position(4, 0), Position(6, 0)))
Beispiel #23
0
    def create_start_board() -> Board:
        board = Board()

        # Set white pieces.
        board.set_piece(Position(0, 0), Pieces.WHITE_ROOK)
        board.set_piece(Position(1, 0), Pieces.WHITE_KNIGHT)
        board.set_piece(Position(2, 0), Pieces.WHITE_BISHOP)
        board.set_piece(Position(3, 0), Pieces.WHITE_QUEEN)
        board.set_piece(Position(4, 0), Pieces.WHITE_KING)
        board.set_piece(Position(5, 0), Pieces.WHITE_BISHOP)
        board.set_piece(Position(6, 0), Pieces.WHITE_KNIGHT)
        board.set_piece(Position(7, 0), Pieces.WHITE_ROOK)

        board.set_piece(Position(0, 1), Pieces.WHITE_PAWN)
        board.set_piece(Position(1, 1), Pieces.WHITE_PAWN)
        board.set_piece(Position(2, 1), Pieces.WHITE_PAWN)
        board.set_piece(Position(3, 1), Pieces.WHITE_PAWN)
        board.set_piece(Position(4, 1), Pieces.WHITE_PAWN)
        board.set_piece(Position(5, 1), Pieces.WHITE_PAWN)
        board.set_piece(Position(6, 1), Pieces.WHITE_PAWN)
        board.set_piece(Position(7, 1), Pieces.WHITE_PAWN)

        # Set black pieces.
        board.set_piece(Position(0, 7), Pieces.BLACK_ROOK)
        board.set_piece(Position(1, 7), Pieces.BLACK_KNIGHT)
        board.set_piece(Position(2, 7), Pieces.BLACK_BISHOP)
        board.set_piece(Position(3, 7), Pieces.BLACK_QUEEN)
        board.set_piece(Position(4, 7), Pieces.BLACK_KING)
        board.set_piece(Position(5, 7), Pieces.BLACK_BISHOP)
        board.set_piece(Position(6, 7), Pieces.BLACK_KNIGHT)
        board.set_piece(Position(7, 7), Pieces.BLACK_ROOK)

        board.set_piece(Position(0, 6), Pieces.BLACK_PAWN)
        board.set_piece(Position(1, 6), Pieces.BLACK_PAWN)
        board.set_piece(Position(2, 6), Pieces.BLACK_PAWN)
        board.set_piece(Position(3, 6), Pieces.BLACK_PAWN)
        board.set_piece(Position(4, 6), Pieces.BLACK_PAWN)
        board.set_piece(Position(5, 6), Pieces.BLACK_PAWN)
        board.set_piece(Position(6, 6), Pieces.BLACK_PAWN)
        board.set_piece(Position(7, 6), Pieces.BLACK_PAWN)

        return board
Beispiel #24
0
 def test_all_moves(self):
     """Test of all_moves() method."""
     assert sorted(PieceMoves.all_moves(self.game)) == [
         Move(Position(0, 0), Position(1, 0)),
         Move(Position(0, 0), Position(2, 0)),
         Move(Position(0, 0), Position(3, 0)),
         Move(Position(0, 1), Position(0, 2)),
         Move(Position(0, 1), Position(0, 3)),
         *sorted(PieceMoves.king_moves(Position(4, 0), self.game)),
         Move(Position(4, 4), Position(3, 5)),
         Move(Position(4, 4), Position(4, 5)),
         Move(Position(7, 0), Position(5, 0)),
         Move(Position(7, 0), Position(6, 0)),
         Move(Position(7, 1), Position(7, 2)),
         Move(Position(7, 1), Position(7, 3)),
     ]
Beispiel #25
0
    def test_positions_under_pawn_threat(self):
        """Test of positions_under_pawn_threat() method."""

        assert not PositionsUnderThreat.positions_under_pawn_threat(
            Position(4, 3), Colour.WHITE, self.board)
        assert sorted(
            PositionsUnderThreat.positions_under_pawn_threat(
                Position(3, 4), Colour.WHITE,
                self.board)) == [Position(2, 5),
                                 Position(4, 5)]
        assert sorted(
            PositionsUnderThreat.positions_under_pawn_threat(
                Position(5, 4), Colour.WHITE,
                self.board)) == [Position(4, 5),
                                 Position(6, 5)]
        assert sorted(
            PositionsUnderThreat.positions_under_pawn_threat(
                Position(0, 6), Colour.WHITE, self.board)) == [Position(1, 7)]
        assert not PositionsUnderThreat.positions_under_pawn_threat(
            Position(7, 7), Colour.WHITE, self.board)
        assert PositionsUnderThreat.positions_under_pawn_threat(
            Position(4, 5), Colour.BLACK,
            self.board) == [Position(3, 4), Position(5, 4)]
Beispiel #26
0
    def test_en_passant_moves(self):
        """Test of en_passant_moves() method."""

        assert sorted(PieceMoves.en_passant_moves(Position(
            4, 4), self.game)) == [Move(Position(4, 4), Position(3, 5))]
Beispiel #27
0
 def test_set_piece_rewrite_piece(self):
     board = Board()
     board.set_piece(Position(1, 3), Pieces.WHITE_QUEEN)
     board.set_piece(Position(1, 3), Pieces.BLACK_KING)
     assert board.get_piece(Position(1, 3)) == Pieces.BLACK_KING
Beispiel #28
0
    def test_castling_moves(self):
        """Test of castling_moves() method."""

        assert sorted(PieceMoves.castling_moves(Position(
            4, 0), self.game)) == [Move(Position(4, 0), Position(6, 0))]
Beispiel #29
0
    def castling_moves(pos: Position, game: Game) -> List[Move]:
        """Return list of <game.turn> castling moves.
        Check is taking into account!!!
        """

        # Init catling list.
        castling = []
        # Retrieve piece at start position.
        piece_start = game.board.get_piece(pos)
        # Retrieve positions under threat (important info for castling).
        pos_under_threat = PositionsUnderThreat.all_positions_under_threat_for_side(
            game.turn, game.board)
        # Check if piece piece at start position King with no threat/check.
        if (piece_start is not None and piece_start.type == PieceType.KING
                and not PieceMoves.is_piece_touched(pos, game)
                and pos not in pos_under_threat):
            # Short castling. _1r_ means 1 pos to the right from white side.
            is_1r_pos_avail = (
                game.board.is_position_empty(Position(pos.x + 1, pos.y))
                and Position(pos.x + 1, pos.y) not in pos_under_threat)
            is_2r_pos_avail = (
                game.board.is_position_empty(Position(pos.x + 2, pos.y))
                and Position(pos.x + 2, pos.y) not in pos_under_threat)
            is_3r_pos_rook = (
                not game.board.is_position_empty(Position(pos.x + 3, pos.y))
                and game.board.get_piece(Position(
                    pos.x + 3, pos.y)).type == PieceType.ROOK)
            if (is_1r_pos_avail and is_2r_pos_avail and is_3r_pos_rook
                    and not PieceMoves.is_piece_touched(
                        Position(pos.x + 3, pos.y), game)):
                move = Move(pos, Position(pos.x + 2, pos.y))
                castling.append(move)
            # Long castling. _1l_ means 1 pos to the left from white side.
            is_1l_pos_avail = (
                game.board.is_position_empty(Position(pos.x - 1, pos.y))
                and Position(pos.x - 1, pos.y) not in pos_under_threat)
            is_2l_pos_avail = (
                game.board.is_position_empty(Position(pos.x - 2, pos.y))
                and Position(pos.x - 2, pos.y) not in pos_under_threat)
            is_4l_pos_rook = (
                not game.board.is_position_empty(Position(pos.x - 4, pos.y))
                and game.board.get_piece(Position(
                    pos.x - 4, pos.y)).type == PieceType.ROOK)
            if (is_1l_pos_avail and is_2l_pos_avail and is_4l_pos_rook
                    and game.board.is_position_empty(Position(
                        pos.x - 3, pos.y)) and not PieceMoves.is_piece_touched(
                            Position(pos.x - 4, pos.y), game)):
                move = Move(pos, Position(pos.x - 2, pos.y))
                castling.append(move)
        return castling
Beispiel #30
0
    def test_is_piece_touched(self):
        """Test of is_piece_touched() method."""

        assert PieceMoves.is_piece_touched(Position(4, 4), self.game)
        assert PieceMoves.is_piece_touched(Position(3, 4), self.game)