Example #1
0
 def test_eq_ne_for_unequal(self, loc_label1, loc_label2):
     loc1 = Location(loc_label1) if loc_label1 else None
     loc2 = Location(loc_label2) if loc_label2 else None
     eq12 = (loc1 == loc2)
     ne12 = (loc1 != loc2)
     self.assertFalse(eq12)
     self.assertTrue(ne12)
Example #2
0
 def test_get_path(self, src_label, dst_label, expected_path_labels):
     src = Location(src_label)
     dst = Location(dst_label)
     actual_path = src.get_path(dst)
     expected_path = [Location(label) for label in expected_path_labels]
     self.assertIsInstance(actual_path, list)
     self.assertEqual(actual_path, expected_path)
Example #3
0
    def test_pawn_first_move(self):
        white_pawn = self.piece_factory.create('P')
        black_pawn = self.piece_factory.create('p')

        white_first_move = Move(src=Location("b2"), dst=Location("b4"))
        black_first_move = Move(src=Location("g7"), dst=Location("g5"))

        self.assertTrue(white_pawn._first_move(white_first_move))
        self.assertFalse(white_pawn._first_move(black_first_move))

        self.assertTrue(black_pawn._first_move(black_first_move))
        self.assertFalse(black_pawn._first_move(white_first_move))
Example #4
0
 def test_setitem(self, loc_label, symbol):
     piece_factory = PieceFactory()
     loc = Location(loc_label)
     piece = piece_factory.create(symbol)
     self.board[loc] = piece
     value = self.board[loc]
     self.assertIs(value, piece)
Example #5
0
 def test_eq_ne_hash_for_equal(self, given_loc_label):
     loc1 = Location(given_loc_label)
     loc2 = Location(given_loc_label.lower())
     loc3 = Location(given_loc_label.upper())
     eq12 = (loc1 == loc2)
     eq23 = (loc2 == loc3)
     ne12 = (loc1 != loc2)
     ne23 = (loc2 != loc3)
     hash1 = hash(loc1)
     hash2 = hash(loc2)
     hash3 = hash(loc3)
     self.assertTrue(eq12)
     self.assertTrue(eq23)
     self.assertFalse(ne12)
     self.assertFalse(ne23)
     self.assertEqual(hash1, hash2)
     self.assertEqual(hash2, hash3)
Example #6
0
 def test_pop_piece(self, loc_label, expected_symbol=None):
     loc = Location(loc_label)
     value = self.board.pop_piece(loc)
     value_after = self.board[loc]
     if value is None:
         self.assertIsNone(expected_symbol)
     else:
         self.assertIsInstance(value, Piece)
         self.assertEqual(value.get_symbol(), expected_symbol)
     self.assertIsNone(value_after)
Example #7
0
    def test_queen_move(self):
        queen = self.piece_factory.create('Q')

        moves = [
            Move(src=Location("b1"), dst=Location("a1")),
            Move(src=Location("b1"), dst=Location("b8")),
            Move(src=Location("b1"), dst=Location("g6")),
        ]
        for move in moves:
            queen.get_route(move)

        move = Move(src=Location("b1"), dst=Location("h3"))
        self.assertRaises(UserActionError, queen.get_route, move)
Example #8
0
 def test_init_and_basics(self, given_loc_label):
     loc = Location(given_loc_label)
     expected_loc_label = given_loc_label.lower()
     expected_x_label = expected_loc_label[0]
     expected_y_label = expected_loc_label[1]
     expected_repr = "Location('{}')".format(expected_loc_label)
     expected_str = expected_loc_label
     self.assertEqual(loc.loc_label, expected_loc_label)
     self.assertEqual(loc.x_label, expected_x_label)
     self.assertEqual(loc.y_label, expected_y_label)
     self.assertEqual(repr(loc), expected_repr)
     self.assertEqual(str(loc), expected_str)
Example #9
0
 def test_init(self, loc_label):
     fresh_board = Board()
     loc = Location(loc_label)
     value = fresh_board[loc]
     self.assertIsNone(value)
Example #10
0
 def __init__(self, session, src_label, dst_label):
     super(NormalMove, self).__init__(session)
     self.src = Location(src_label)
     self.dst = Location(dst_label)
     self.piece = session.board[self.src]
     self._en_passant_attack_dst = None
Example #11
0
class NormalMove(Move):

    def __init__(self, session, src_label, dst_label):
        super(NormalMove, self).__init__(session)
        self.src = Location(src_label)
        self.dst = Location(dst_label)
        self.piece = session.board[self.src]
        self._en_passant_attack_dst = None

    def get_vector(self):
        return self.src.get_vector(self.dst)

    def get_path(self):
        return self.src.get_path(self.dst)

    def execute(self):
        self._validate_and_prepare()
        with critical_part():
            self._mutate_board()
            self._maintain_future_castlings()

    # non-public helpers:

    def _validate_and_prepare(self):
        self._check_src_not_empty()
        self._check_if_player_owns_src_piece()
        self._check_src_dst_are_distinct()
        route = self.piece.get_route(self)
        self._check_path(route)
        self._check_dst_field(route)

    def _mutate_board(self):
        moved_piece = self._session.board.pop_piece(self.src)
        assert moved_piece is self.piece
        self._session.board[self.dst] = moved_piece
        if self._en_passant_attack_dst:
            del self._session.board[self._en_passant_attack_dst]

    def _maintain_future_castlings(self):
        player = self._session.current_player
        if self._should_disable_queenside_castlings():
            player.queenside_castling_enabled = False
        if self._should_disable_kingside_castlings():
            player.kingside_castling_enabled = False

    def _check_src_not_empty(self):
        if self.piece is None:
            raise UserActionError('Source location does not contain any figure.')

    def _check_if_player_owns_src_piece(self):
        if self.piece.is_white != self._session.is_white_turn:
            raise UserActionError('You tried to move not your piece.')

    def _check_src_dst_are_distinct(self):
        if self.get_vector() == (0, 0):
            raise UserActionError('You tried to move to the same location.')

    def _check_path(self, route):
        for loc in route.path:
            if self._session.board[loc] is not None:
                raise UserActionError('Other piece on move path.')

    def _check_dst_field(self, route):
        dst_piece = self._session.board[self.dst]
        if route.attack_required:
            assert isinstance(self.piece, Pawn)
            if not dst_piece:
                self._check_en_passant()
            elif self.piece.is_white == dst_piece.is_white:
                raise UserActionError('This move has to be an attack.')
        if route.attack_forbidden:
            if dst_piece:
                raise UserActionError('This move can\'t be an attack.')
        if dst_piece and self.piece.is_white == dst_piece.is_white:
            raise UserActionError('You tried to attack your\'s piece.')

    def _check_en_passant(self):
        if not self._session.last_move:
            raise UserActionError('Invalid en passant attack.')
        last_move = self._session.last_move
        if not isinstance(self.piece, Pawn) or not isinstance(last_move.piece, Pawn):
            raise UserActionError('Invalid en passant attack.')
        if not self._between(
                self.dst.y_label,
                last_move.src.y_label,
                last_move.dst.y_label):
            raise UserActionError('Invalid en passant attack.')
        self._en_passant_attack_dst = last_move.dst

    def _between(self, value, first, second):
        if first < second:
            return first < value < second
        return second < value < first

    def _should_disable_queenside_castlings(self):
        is_white_turn = self._session.is_white_turn
        return isinstance(self.piece, King) or (
            isinstance(self.piece, Rook) and (
                (self.src.loc_label == 'a1' and is_white_turn) or
                (self.src.loc_label == 'a8' and not is_white_turn)))

    def _should_disable_kingside_castlings(self):
        is_white_turn = self._session.is_white_turn
        return isinstance(self.piece, King) or (
            isinstance(self.piece, Rook) and (
                (self.src.loc_label == 'h1' and is_white_turn) or
                (self.src.loc_label == 'h8' and not is_white_turn)))
Example #12
0
 def _get_king_dst(self):
     loc_label = Location.make_loc_label(
         self.king_dst_x_label,
         self._get_y_label())
     return Location(loc_label)
Example #13
0
    def test_rook_attacked_locations(self):
        rook = self.piece_factory.create('R')

        attacked_locations = rook.get_attacked_locations(Location('a1'))
        valid_attacked_locations = [
            Location('a2'),
            Location('a3'),
            Location('a4'),
            Location('a5'),
            Location('a6'),
            Location('a7'),
            Location('a8'),
            Location('b1'),
            Location('c1'),
            Location('d1'),
            Location('e1'),
            Location('f1'),
            Location('g1'),
            Location('h1'),
        ]
        self.assertItemsEqual(attacked_locations, valid_attacked_locations)

        attacked_locations = rook.get_attacked_locations(Location('g4'))
        valid_attacked_locations = [
            Location('g1'),
            Location('g2'),
            Location('g3'),
            Location('g5'),
            Location('g6'),
            Location('g7'),
            Location('g8'),
            Location('a4'),
            Location('b4'),
            Location('c4'),
            Location('d4'),
            Location('e4'),
            Location('f4'),
            Location('h4'),
        ]
        self.assertItemsEqual(attacked_locations, valid_attacked_locations)
Example #14
0
 def test_king_correct_move(self, src, dst):
     king = self.piece_factory.create('K')
     move = Move(src=Location(src), dst=Location(dst))
     king.get_route(move)
Example #15
0
 def test_rook_correct_move(self, src, dst):
     rook = self.piece_factory.create('R')
     move = Move(src=Location(src), dst=Location(dst))
     rook.get_route(move)
Example #16
0
    def test_pawn_move(self):
        white_pawn = self.piece_factory.create('P')
        black_pawn = self.piece_factory.create('p')

        move = Move(src=Location("b2"),
                    dst=Location("c2"))  # move to the right
        self.assertRaises(UserActionError, white_pawn.get_route, move)

        move = Move(src=Location("b2"), dst=Location("a2"))  # move to the left
        self.assertRaises(UserActionError, white_pawn.get_route, move)

        move = Move(src=Location("b2"), dst=Location("b1"))  # white move down
        self.assertRaises(UserActionError, white_pawn.get_route, move)

        move = Move(src=Location("g1"), dst=Location("f1"))  # black move up
        self.assertRaises(UserActionError, black_pawn.get_route, move)

        move = Move(src=Location("b2"),
                    dst=Location("b4"))  # white piece first move
        route = white_pawn.get_route(move)
        self.assertFalse(route.attack_required)
        self.assertTrue(route.attack_forbidden)

        # white piece not first two fields move
        move = Move(src=Location("b3"), dst=Location("b5"))
        self.assertRaises(UserActionError, white_pawn.get_route, move)

        # black piece first move
        move = Move(src=Location("b7"), dst=Location("b5"))
        route = black_pawn.get_route(move)
        self.assertFalse(route.attack_required)
        self.assertTrue(route.attack_forbidden)

        # black piece not first two fields move
        move = Move(src=Location("b6"), dst=Location("b4"))
        self.assertRaises(UserActionError, black_pawn.get_route, move)

        # white move attack
        move = Move(src=Location("b3"), dst=Location("a4"))
        route = white_pawn.get_route(move)
        self.assertTrue(route.attack_required)
        self.assertFalse(route.attack_forbidden)
Example #17
0
 def test_get_path_raising_error(self, src_label, dst_label):
     src = Location(src_label)
     dst = Location(dst_label)
     with self.assertRaises(UserActionError):
         src.get_path(dst)
Example #18
0
 def test_get_vector(self, src_label, dst_label, expected_vector):
     src = Location(src_label)
     dst = Location(dst_label)
     actual_vector = src.get_vector(dst)
     self.assertIsInstance(actual_vector, tuple)
     self.assertEqual(actual_vector, expected_vector)
Example #19
0
 def test_init_raising_error(self, given_loc_label):
     with self.assertRaises(UserActionError):
         Location(given_loc_label)
Example #20
0
    def test_bishop_move(self):
        bishop = self.piece_factory.create('B')

        move = Move(src=Location("b1"), dst=Location("a3"))
        self.assertRaises(UserActionError, bishop.get_route, move)

        move = Move(src=Location("b1"), dst=Location("c1"))
        self.assertRaises(UserActionError, bishop.get_route, move)

        move = Move(src=Location("b1"), dst=Location("b8"))
        self.assertRaises(UserActionError, bishop.get_route, move)

        moves = [
            Move(src=Location("b1"), dst=Location("a2")),
            Move(src=Location("a2"), dst=Location("e6")),
            Move(src=Location("e6"), dst=Location("g4")),
            Move(src=Location("g4"), dst=Location("h5")),
            Move(src=Location("h5"), dst=Location("e8"))
        ]
        for move in moves:
            bishop.get_route(move)
Example #21
0
 def test_getitem_piece(self, loc_label, expected_symbol):
     loc = Location(loc_label)
     value = self.board[loc]
     self.assertIsInstance(value, Piece)
     self.assertEqual(value.get_symbol(), expected_symbol)
Example #22
0
 def test_knight_correct_move(self, src, dst):
     knight = self.piece_factory.create('N')
     move = Move(src=Location(src), dst=Location(dst))
     knight.get_route(move)
Example #23
0
 def test_getitem_none(self, loc_label):
     loc = Location(loc_label)
     value = self.board[loc]
     self.assertIsNone(value)
Example #24
0
 def test_rook_illegal_move(self, src, dst):
     rook = self.piece_factory.create('R')
     move = Move(src=Location(src), dst=Location(dst))
     self.assertRaises(UserActionError, rook.get_route, move)
Example #25
0
 def act(self, loc_label):
     dst = Location(loc_label)
     return self._set_queen(dst)
Example #26
0
 def test_king_illegal_move(self, src, dst):
     king = self.piece_factory.create('K')
     move = Move(src=Location(src), dst=Location(dst))
     self.assertRaises(UserActionError, king.get_route, move)
Example #27
0
 def _get_rook_dst_label(self):
     return Location.make_loc_label(
         self.rook_dst_x_label,
         self._get_y_label())
Example #28
0
    def test_bishop_attacked_locations(self):
        bishop = self.piece_factory.create('B')

        attacked_locations = bishop.get_attacked_locations(Location('C2'))
        valid_attacked_locations = [
            Location('b1'),
            Location('d3'),
            Location('e4'),
            Location('f5'),
            Location('g6'),
            Location('h7'),
            Location('b3'),
            Location('a4'),
            Location('d1'),
        ]

        self.assertItemsEqual(attacked_locations, valid_attacked_locations)

        attacked_locations = bishop.get_attacked_locations(Location('a1'))
        valid_attacked_locations = [
            Location('b2'),
            Location('c3'),
            Location('d4'),
            Location('e5'),
            Location('f6'),
            Location('g7'),
            Location('h8'),
        ]

        self.assertItemsEqual(attacked_locations, valid_attacked_locations)
Example #29
0
 def test_delitem(self, loc_label):
     loc = Location(loc_label)
     del self.board[loc]
     value_after = self.board[loc]
     self.assertIsNone(value_after)