def test_white_pawns_can_capture_diagonally(): # Arrange board = Board.empty() pawn = Pawn(Player.WHITE) pawn_square = Square.at(3, 4) board.set_piece(pawn_square, pawn) enemy1 = Pawn(Player.BLACK) enemy1_square = Square.at(4, 5) board.set_piece(enemy1_square, enemy1) enemy2 = Pawn(Player.BLACK) enemy2_square = Square.at(4, 3) board.set_piece(enemy2_square, enemy2) # Act moves = pawn.get_available_moves(board) # Assert assert enemy1_square in moves assert enemy2_square in moves
def test_black_pawn_cannot_move_at_bottom_of_board(): # Arrange board = Board.empty() pawn = Pawn(Player.BLACK) square = Square.at(0, 4) board.set_piece(square, pawn) # Act moves = pawn.get_available_moves(board) # Assert assert len(moves) == 0
def test_white_pawn_cannot_move_at_top_of_board(): # Arrange board = Board.empty() pawn = Pawn(Player.WHITE) square = Square.at(7, 4) board.set_piece(square, pawn) # Act moves = pawn.get_available_moves(board) # Assert assert len(moves) == 0
def test_black_knights_can_move_in_l_shape(): # Arrange board = Board.empty() knight = Knight(Player.BLACK) square = Square.at(3, 3) board.set_piece(square, knight) # Act moves = knight.get_available_moves(board) # Assert assert Square.at(4, 5) in moves assert Square.at(4, 1) in moves assert Square.at(5, 4) in moves assert Square.at(5, 2) in moves assert Square.at(2, 5) in moves assert Square.at(2, 1) in moves assert Square.at(1, 4) in moves assert Square.at(1, 2) in moves
def get_available_moves(self, board): location = board.find_piece(self) king_moves = [ Square.at(location.row + 1, location.col + 1), Square.at(location.row + 1, location.col), Square.at(location.row + 1, location.col - 1), Square.at(location.row, location.col + 1), Square.at(location.row, location.col - 1), Square.at(location.row - 1, location.col + 1), Square.at(location.row - 1, location.col), Square.at(location.row - 1, location.col - 1) ] return list( filter(lambda square: self.is_free(board, square), king_moves))
def get_available_moves(self, board): moves = [] list = [(-2,-1),(-1,-2),(1,-2),(2,-1),(2,1),(1,2),(-1,2),(-2,1)] current_square = board.find_piece(self) for vertical,horizontal in list: if inBounds(current_square.row+vertical) and inBounds(current_square.col+horizontal): square = Square.at(current_square.row+vertical,current_square.col+horizontal) piece = board.get_piece(square) if piece == None: moves.append(square) elif piece.player != self.player: moves.append(square) return moves
def test_king_cannot_move_off_the_left_of_board(): # Arrange board = Board.empty() king = King(Player.BLACK) square = Square.at(4,0) board.set_piece(square, king) # Act moves = king.get_available_moves(board) # Assert assert Square.at(3, 1) in moves assert Square.at(4, 1) in moves assert Square.at(5, 1) in moves assert Square.at(3, 0) in moves assert Square.at(5, 0) in moves assert Square.at(3, -1) not in moves assert Square.at(4, -1) not in moves assert Square.at(5, -1) not in moves
def test_king_cannot_move_off_the_right_of_board(): # Arrange board = Board.empty() king = King(Player.BLACK) square = Square.at(4,7) board.set_piece(square, king) # Act moves = king.get_available_moves(board) # Assert assert Square.at(3, 6) in moves assert Square.at(4, 6) in moves assert Square.at(5, 6) in moves assert Square.at(3, 7) in moves assert Square.at(5, 7) in moves assert Square.at(3, 8) not in moves assert Square.at(4, 8) not in moves assert Square.at(5, 8) not in moves
def test_white_king_can_move_up_one_square(): # Arrange board = Board.empty() king = King(Player.WHITE) square = Square.at(4, 4) board.set_piece(square, king) # Act moves = king.get_available_moves(board) # Assert assert Square.at(3, 3) in moves assert Square.at(3, 4) in moves assert Square.at(3, 5) in moves assert Square.at(4, 3) in moves assert Square.at(4, 5) in moves assert Square.at(5, 3) in moves assert Square.at(5, 4) in moves assert Square.at(5, 5) in moves
def testKnightMovementShape(): board = Board.empty() knight = Knight(Player.WHITE) square = Square.at(3, 5) board.set_piece(square, knight) moves = knight.get_available_moves(board) expected_moves = [ Square.at(4, 7), Square.at(4, 3), Square.at(5, 6), Square.at(5, 4), Square.at(2, 7), Square.at(2, 3), Square.at(1, 6), Square.at(1, 4) ] assert len(moves) == len(expected_moves) assert set(moves) == set(expected_moves)
def test_king_cannot_move_off_the_bottom_of_board(): # Arrange board = Board.empty() king = King(Player.BLACK) square = Square.at(0,4) board.set_piece(square, king) # Act moves = king.get_available_moves(board) # Assert assert Square.at(1, 3) in moves assert Square.at(1, 4) in moves assert Square.at(1, 5) in moves assert Square.at(0, 3) in moves assert Square.at(0, 5) in moves assert Square.at(-1, 3) not in moves assert Square.at(-1, 4) not in moves assert Square.at(-1, 5) not in moves
def test_kings_cannot_move_off_the_board(): # Arrange board = Board.empty() king = King(Player.WHITE) king_square = Square.at(0, 0) board.set_piece(king_square, king) friendly_1 = Pawn(Player.WHITE) friendly_1_square = Square.at(1, 0) board.set_piece(friendly_1_square, friendly_1) friendly_2 = Pawn(Player.WHITE) friendly_2_square = Square.at(0, 1) board.set_piece(friendly_2_square, friendly_2) friendly_3 = Pawn(Player.WHITE) friendly_3_square = Square.at(1, 1) board.set_piece(friendly_3_square, friendly_3) # Act moves = king.get_available_moves(board) # Assert assert len(moves) == 0
def test_queens_cannot_move_off_the_board(): # Arrange board = Board.empty() queen = Queen(Player.WHITE) queen_square = Square.at(0, 0) board.set_piece(queen_square, queen) friendly_1 = Pawn(Player.WHITE) friendly_1_square = Square.at(1, 0) board.set_piece(friendly_1_square, friendly_1) friendly_2 = Pawn(Player.WHITE) friendly_2_square = Square.at(0, 1) board.set_piece(friendly_2_square, friendly_2) friendly_3 = Pawn(Player.WHITE) friendly_3_square = Square.at(1, 1) board.set_piece(friendly_3_square, friendly_3) # Act moves = queen.get_available_moves(board) # Assert assert len(moves) == 0
def get_available_moves(self, board): moves = [] forward_step = self.steps(board, 'forward_step', limit=True)[0] if not board.has_enemy(forward_step): moves.append(forward_step) current_square = self.position(board) start_row = {Player.WHITE: 1, Player.BLACK: 6}[self.player] if current_square.row == start_row: double_step = Square.at( current_square.row + (2 * self.direction()), current_square.col) if board.square_is_empty(double_step): moves.append(double_step) moves += self.attackable_squares(board, current_square) return moves
def test_king_cannot_move_to_check_by_bishop(): # Arrange board = Board.empty() king = King(Player.WHITE) king_square = Square.at(2, 3) board.set_piece(king_square, king) enemy = Bishop(Player.BLACK) enemy_square = Square.at(1, 2) board.set_piece(enemy_square, enemy) # Act moves = king.get_available_moves(board) # Assert assert len(moves) == 7 assert Square.at(1, 2) in moves assert Square.at(2, 2) in moves assert Square.at(3, 2) in moves assert Square.at(3, 3) in moves assert Square.at(3, 4) not in moves assert Square.at(2, 4) in moves assert Square.at(1, 4) in moves assert Square.at(1, 3) in moves
def get_available_moves(self, board): current_square = self.position(board) moves = [ Square.at(current_square.row + 2, current_square.col - 1), Square.at(current_square.row + 2, current_square.col + 1), Square.at(current_square.row - 2, current_square.col - 1), Square.at(current_square.row - 2, current_square.col + 1), Square.at(current_square.row + 1, current_square.col - 2), Square.at(current_square.row - 1, current_square.col - 2), Square.at(current_square.row + 1, current_square.col + 2), Square.at(current_square.row - 1, current_square.col + 2) ] valid_moves = [] for move in moves: if board.in_board(move): valid_moves.append(move) return valid_moves
def capture_enemies(self, current_square, candidate_square, direction, board): """ Checks if the pawn can capture an enemy piece, including via en passant. """ valid_moves = [] if current_square.is_on_board() and candidate_square.is_on_board(): if not board.is_square_empty(candidate_square): if board.capture_possible(current_square, candidate_square): valid_moves.append( Square.at(candidate_square.row, candidate_square.col)) elif self.enpassant_truefalse(board, candidate_square): valid_moves.append(candidate_square) return valid_moves
def test_white_kings_can_move_to_all_neighbouring_squares(): # Arrange board = Board.empty() king = King(Player.WHITE) square = Square.at(1, 4) board.set_piece(square, king) # Act moves = king.get_available_moves(board) # Assert assert set(moves) == set([ Square.at(1, 5), Square.at(1, 3), Square.at(2, 5), Square.at(2, 3), Square.at(2, 4), Square.at(0, 5), Square.at(0, 3), Square.at(0, 4) ])
def get_available_moves(self, board): moves = [] current_square = board.find_piece(self) for vertical,horizontal in [(1,1),(1,-1),(-1,1),(-1,-1)]: for i in range(1,8): if inBounds(current_square.row+(vertical*i)) and inBounds(current_square.col+(horizontal*i)): square = Square.at(current_square.row+(vertical*i),current_square.col+(horizontal*i)) piece = board.get_piece(square) if piece == None: moves.append(square) elif piece.player != self.player: moves.append(square) break else: break return moves
def move_to(self, board, new_square): """ Move this piece to the given square on the board. """ current_square = board.find_piece(self) if current_square.row - new_square.row == 2 or -2: self.enPassant = True else: self.enPassant = False # delete piece if performing en pessant if current_square.col - new_square.col == 1 or current_square.col - new_square.col == -1: if new_square.isEmpty: board.set_piece(Square.at(current_square.row, new_square.col), None) board.move_piece(current_square, new_square)
def can_castle(self, board, current_square, distance_to_rook): if self.has_moved: return False direction = 1 if distance_to_rook < 0: direction = -1 rook_column = current_square.col + distance_to_rook rook_square = Square.at(current_square.row, rook_column) rook = board.get_piece(rook_square) if not isinstance(rook, Rook): return False castle_squares = self.get_moves_in_direction(board, current_square, 1 * direction, 0, abs(distance_to_rook)) castle_squares_are_empty = len( castle_squares) == abs(distance_to_rook) - 1 return not rook.has_moved and castle_squares_are_empty
def handle_castling(self, from_square, to_square, piece): if not isinstance(piece, King): return if abs(from_square.col - to_square.col) > 1: if to_square.col == 2: rook = self.get_piece(Square.at(to_square.row, 0)) self.set_piece(Square.at(to_square.row, 3), rook) self.set_piece(Square.at(to_square.row, 0), None) else: rook = self.get_piece(Square.at(to_square.row, 7)) self.set_piece(Square.at(to_square.row, 5), rook) self.set_piece(Square.at(to_square.row, 7), None)
def get_available_moves(self, board): moves = [] current_square = board.find_piece(self) for vertical in [-1,0,1]: for horizontal in [-1,0,1]: square = Square.at(current_square.row+vertical,current_square.col+horizontal) if square != current_square and inBounds(square.row) and inBounds(square.col): piece = board.get_piece(square) if not self.in_check(board,square): if piece is None: moves.append(square) elif piece.player != self.player: moves.append(square) return moves
def get_available_moves(self, board): loc = board.find_piece(self) row, col = loc.row, loc.col possibleMoves = [ Square.at(row + 2, col + 1), Square.at(row + 2, col - 1), Square.at(row + 1, col + 2), Square.at(row + 1, col - 2), Square.at(row - 2, col + 1), Square.at(row - 2, col - 1), Square.at(row - 1, col + 2), Square.at(row - 1, col - 2) ] validMoves = [] for move in possibleMoves: if (self.isFreeOrCapturable(board, move)): validMoves.append(move) return validMoves
def checkEnPessant(self, board, current_square): lastPieceSquare = board.find_piece(board.lastPieceMoved) lastPiece = board.lastPieceMoved if not isinstance(lastPiece, Pawn) or not isinstance( self, Pawn) or not lastPieceSquare.squareOnBoard(): return [] if not lastPiece.enPassant or lastPieceSquare.row != current_square.row: return [] direction = 1 if board.current_player == Player.BLACK: direction = -1 enPessantSquare = Square.at(lastPieceSquare.row + direction, lastPieceSquare.col) return [enPessantSquare]
def get_available_moves(self, board): bishop = [] currentP = board.find_piece(self) # Up and right motion if currentP.row >= currentP.col: for i in range(currentP.row + 1, BOARD_MAX + 1): if board.get_piece( Square.at(i, i + (currentP.col - currentP.row))) is None: bishop.append( Square.at(i, i + (currentP.col - currentP.row))) else: if board.get_piece( Square.at( i, i + (currentP.col - currentP.row))).player is not self.player: bishop.append( Square.at(i, i + (currentP.col - currentP.row))) break else: for i in range(currentP.col + 1, BOARD_MAX + 1): if board.get_piece( Square.at(i + (currentP.row - currentP.col), i)) is None: bishop.append( Square.at(i + (currentP.row - currentP.col), i)) else: if board.get_piece( Square.at(i + (currentP.row - currentP.col), i)).player is not self.player: bishop.append( Square.at(i + (currentP.row - currentP.col), i)) break return bishop
def handle_castling(self, moving_piece, from_square, to_square): if isinstance(moving_piece, King): if abs(from_square.col - to_square.col) > 1: if to_square.row == 0: if to_square.col == 2: self.set_piece(Square.at(0, 0), None) self.set_piece(Square.at(0, 3), Rook(self.current_player)) elif to_square.col == 6: self.set_piece(Square.at(0, 7), None) self.set_piece(Square.at(0, 5), Rook(self.current_player)) elif to_square.row == 7: if to_square.col == 2: self.set_piece(Square.at(7, 0), None) self.set_piece(Square.at(7, 3), Rook(self.current_player)) elif to_square.col == 6: self.set_piece(Square.at(7, 7), None) self.set_piece(Square.at(7, 5), Rook(self.current_player)) return
def get_available_moves(self, board): square = board.find_piece(self) if square.row not in [0, 7, 1, 6]: if self.player == Player.WHITE: return [Square.at(square.row + 1, square.col)] if self.player == Player.BLACK: return [Square.at(square.row - 1, square.col)] if square.row in [1, 6]: if self.player == Player.WHITE: return [Square.at(square.row + 1, square.col), Square.at(square.row + 2, square.col)] if self.player == Player.BLACK: return [Square.at(square.row - 1, square.col), Square.at(square.row - 2, square.col)] return []
def _checked_by_knight(self, board, pos) -> bool: config = [ (1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1), ] for row_offset, col_offset in config: curr_knight = board.get_piece( Square.at(pos.row + row_offset, pos.col + col_offset)) if isinstance(curr_knight, Knight) and curr_knight.player is not self.player: return True return False
def kill_opponent(self, current_square, board): direction_row = 1 if self.player == Player.WHITE else -1 directions_col = [] if current_square.col == 0: directions_col = [1] if current_square.col == 7: directions_col = [-1] if not self.edge_check_col(current_square): directions_col = [1, -1] attack_squares = [] valid_attack_squares = [] for direction_col in directions_col: attack_squares.append( Square.at(current_square.row + direction_row, current_square.col + direction_col)) for attack_square in attack_squares: if board.is_square_attackable(attack_square, self.player): valid_attack_squares.append(attack_square) elif self.en_passant_attack(board, attack_square): valid_attack_squares.append(attack_square) return valid_attack_squares