def knight_take_test(): print("========================================") print("Performing the knight take test") print("========================================") board = Board() white_knight = Knight(Colour.WHITE) current_location = Location('b', 1) board.__add_piece__(white_knight, current_location) white_pawn = Pawn(Colour.WHITE) black_pawn = Pawn(Colour.BLACK) board.__add_piece__(white_pawn, Location('a', 3)) board.__add_piece__(black_pawn, Location('c', 3)) print("Added a knight and 2 pawns to the board...") print(board) allowed_moves = white_knight.allowed_moves(current_location, board) print("For a {} {} starting at position {} the moves are:".format( white_knight.colour, white_knight.name, current_location)) print(allowed_moves) new_location = allowed_moves[0] board.move_piece(white_knight, current_location, new_location) current_location = new_location print("Moved the {} to position {}".format(white_knight.name, new_location)) print(board) print("For a {} {} at position {} the moves are:".format( white_knight.colour, white_knight.name, current_location)) print(white_knight.allowed_moves(current_location, board))
def bishop_take_test(): print("========================================") print("Performing the bishop take test") print("========================================") board = Board() piece = Bishop(Colour.WHITE) current_location = Location('c', 3) board.__add_piece__(piece, current_location) friend_piece = Pawn(Colour.WHITE) enemy_piece = Pawn(Colour.BLACK) board.__add_piece__(friend_piece, Location('b', 2)) board.__add_piece__(enemy_piece, Location('d', 4)) print("Added a Bishop and 2 pawns to the board...") print(board) allowed_moves = piece.allowed_moves(current_location, board) print("For a {} {} starting at position {} the moves are:".format( piece.colour, piece.name, current_location)) print(allowed_moves) new_location = allowed_moves[0] board.move_piece(piece, current_location, new_location) current_location = new_location print("Moved the {} to position {}".format(piece.name, new_location)) print(board) print("For a {} {} at position {} the moves are:".format( piece.colour, piece.name, current_location)) print(piece.allowed_moves(current_location, board))
def king_castling_check_test(): print("========================================") print("Performing the king castling check test") print("========================================") board = Board() piece = King(Colour.WHITE) current_location = Location('e', 1) board.__add_piece__(piece, current_location) board.__add_piece__(Rook(Colour.WHITE), Location('a', 1)) board.__add_piece__(Rook(Colour.WHITE), Location('h', 1)) board.__add_piece__(Rook(Colour.BLACK), Location('e', 2)) print(board) allowed_moves = piece.allowed_moves(current_location, board) print("For a {} {} starting at position {} the moves are:".format( piece.colour, piece.name, current_location)) print(allowed_moves) new_location = allowed_moves[0] board.move_piece(piece, current_location, new_location) current_location = new_location print("Moved the {} to position {}".format(piece.name, new_location)) print(board) print("For a {} {} at position {} the moves are:".format( piece.colour, piece.name, current_location)) print(piece.allowed_moves(current_location, board))
def __first_move__(self, current_location, board): moves = [] if self.moves_made == 0: if self.colour is Colour.WHITE: foward_move = Location( current_location.letter, current_location.number+2) else: foward_move = Location( current_location.letter, current_location.number-2) if self.__is_valid_square__(foward_move, board) \ and board.get_piece_at_square(foward_move) is None: moves.append(foward_move) return moves
def __move_forward__(self, current_location, board): moves = [] if self.colour is Colour.WHITE: if current_location.number == self.promotion_row_white: return moves foward_move = Location( current_location.letter, current_location.number+1) else: if current_location.number == self.promotion_row_black: return moves foward_move = Location( current_location.letter, current_location.number-1) if self.__is_valid_square__(foward_move, board) \ and board.get_piece_at_square(foward_move) is None: moves.append(foward_move) return moves
def __check_take__(self, take_location, board): if self.__is_valid_square__(take_location, board): piece_at_move = board.get_piece_at_square(take_location) if piece_at_move is not None and piece_at_move.colour is not self.colour: take_location.take = True take_location.take_piece = piece_at_move take_location.take_piece_location = Location( take_location.letter, take_location.number)
def __castling_moves__(self, current_location, enemy_moves_next_turn, board): castling_moves = [] # Quick calc the castling positions castle_row = 1 if self.colour == Colour.WHITE else 8 left_castle_letter = 'c' right_castle_letter = 'g' left_rook_castle_pos = Location('a', castle_row) right_rook_castle_pos = Location('h', castle_row) king_castle_pos = Location('e', castle_row) blank_squares_left = [ Location(letter, castle_row) for letter in ['b', 'c', 'd'] ] blank_squares_right = [ Location(letter, castle_row) for letter in ['f', 'g'] ] # King hasn't already moved and Not in check if self.moves_made < 1 and current_location == king_castle_pos \ and current_location not in enemy_moves_next_turn: # Left rook still in original position piece_at_left_rook_pos = board.get_piece_at_square( left_rook_castle_pos) if piece_at_left_rook_pos is not None and piece_at_left_rook_pos.moves_made < 1: # Empty spaces between king and rook pieces_between_king_and_rook = [ piece for piece in [ board.get_piece_at_square(location) for location in blank_squares_left ] if piece is not None ] if len(pieces_between_king_and_rook) == 0: castling_moves += [ Location(left_castle_letter, castle_row, castle=True, castle_piece=piece_at_left_rook_pos, castle_piece_location=left_rook_castle_pos) ] # Right rook still in original position piece_at_right_rook_pos = board.get_piece_at_square( right_rook_castle_pos) if piece_at_right_rook_pos is not None and piece_at_right_rook_pos.moves_made < 1: # Empty spaces between king and rook pieces_between_king_and_rook = [ piece for piece in [ board.get_piece_at_square(location) for location in blank_squares_right ] if piece is not None ] if len(pieces_between_king_and_rook) == 0: castling_moves += [ Location(right_castle_letter, castle_row, castle=True, castle_piece=piece_at_right_rook_pos, castle_piece_location=right_rook_castle_pos) ] return castling_moves
def __get_directional_move_moves__(self, current_location, board, up=True, right=True): moves = [] vertical_direction = 1 if up else -1 horizontal_direction_function = self.__get_next_letter__ if right \ else self.__get_previous_letter__ next_location = Location(horizontal_direction_function( current_location.letter), current_location.number+vertical_direction) while self.__is_valid_square__(next_location, board): piece_at_move = board.get_piece_at_square(next_location) if piece_at_move is None: moves.append(next_location) else: if piece_at_move.colour != self.colour: moves.append(next_location) break next_location = Location(horizontal_direction_function( next_location.letter), next_location.number+vertical_direction) return moves
def __calculate_rook_castle_position__(self, king_to_position): if king_to_position == Location('g', 1): return Location('f', 1) if king_to_position == Location('c', 1): return Location('d', 1) if king_to_position == Location('g', 8): return Location('f', 8) if king_to_position == Location('c', 8): return Location('d', 8) else: raise Exception('Invalid king move castle location.')
def __normal_takes__(self, current_location, board): moves = [] if self.colour is Colour.WHITE: promotion_row = self.promotion_row_white promotion_move_row = promotion_row+1 else: promotion_row = self.promotion_row_black promotion_move_row = promotion_row-1 if self.colour is Colour.WHITE: up_left_take = Location(self.__get_previous_letter__( current_location.letter), current_location.number+1) self.__check_take__(up_left_take, board) if up_left_take.take: if up_left_take.number == promotion_move_row: moves += self.__get_take_promotions__(up_left_take) else: moves.append(up_left_take) up_right_take = Location(self.__get_next_letter__( current_location.letter), current_location.number+1) self.__check_take__(up_right_take, board) if up_right_take.take: if up_right_take.number == promotion_move_row: moves += self.__get_take_promotions__(up_right_take) else: moves.append(up_right_take) else: down_left_take = Location(self.__get_previous_letter__( current_location.letter), current_location.number-1) self.__check_take__(down_left_take, board) if down_left_take.take: if down_left_take.number == promotion_move_row: moves += self.__get_take_promotions__(down_left_take) else: moves.append(down_left_take) down_right_take = Location(self.__get_next_letter__( current_location.letter), current_location.number-1) self.__check_take__(down_right_take, board) if down_right_take.take: if down_right_take.number == promotion_move_row: moves += self.__get_take_promotions__(down_right_take) else: moves.append(down_right_take) return moves
def __promotions__(self, current_location, board): moves = [] if self.colour is Colour.WHITE: promotion_row = self.promotion_row_white move_row = promotion_row+1 else: promotion_row = self.promotion_row_black move_row = promotion_row-1 if current_location.number == promotion_row: if board.get_piece_at_square(Location(current_location.letter, move_row)) is None: moves += [Location(current_location.letter, move_row, promotion=True, promotion_piece=Queen(self.colour))] moves += [Location(current_location.letter, move_row, promotion=True, promotion_piece=Rook(self.colour))] moves += [Location(current_location.letter, move_row, promotion=True, promotion_piece=Bishop(self.colour))] moves += [Location(current_location.letter, move_row, promotion=True, promotion_piece=Knight(self.colour))] return moves
def __get_take_promotions__(self, take): moves = [] moves += [Location(take.letter, take.number, promotion=True, promotion_piece=Queen(self.colour), take=take.take, take_piece=take.take_piece, take_piece_location=take.take_piece_location)] moves += [Location(take.letter, take.number, promotion=True, promotion_piece=Rook(self.colour), take=take.take, take_piece=take.take_piece, take_piece_location=take.take_piece_location)] moves += [Location(take.letter, take.number, promotion=True, promotion_piece=Bishop(self.colour), take=take.take, take_piece=take.take_piece, take_piece_location=take.take_piece_location)] moves += [Location(take.letter, take.number, promotion=True, promotion_piece=Knight(self.colour), take=take.take, take_piece=take.take_piece, take_piece_location=take.take_piece_location)] return moves
def basic_pawn_test(): print("========================================") print("Performing the basic pawn movement test") print("========================================") board = Board() pawn_colour = Colour.WHITE white_pawn_one = Pawn(pawn_colour) current_location = Location('a', 2) board.__add_piece__(white_pawn_one, current_location) print("For a {} pawn starting at position {} the moves are:".format( pawn_colour, current_location)) print(white_pawn_one.allowed_moves(current_location, board)) new_location = Location('a', 4) board.move_piece(white_pawn_one, current_location, new_location) current_location = new_location print("Moved the pawn to position {}".format(new_location)) print("For a {} pawn at position {} the moves are:".format( pawn_colour, current_location)) print(white_pawn_one.allowed_moves(current_location, board))
def __str__(self): board_string = "" for row in self.numbers.keys(): board_string = " | " + str(row) + board_string for column in self.letters.keys(): piece = self.get_piece_at_square(Location(column, row)) board_string = " |" + \ (" " + str(piece) if piece is not None else " ") + board_string board_string = "\n _______________________________________\n" + board_string board_string += "\n _______________________________________\n" board_string += " A B C D E F G H \n" return board_string
def __en_passant_takes__(self, current_location, board): # The en passant rule means that we can take double moved # pawns as if they only moved 1 square, immediately after # the move was made. moves = [] move_history = board.move_history en_passant_row = self.__get_en_passant_row_for_attacking_colour__( self.colour) if len(move_history) != 0: last_move = move_history[-1] if current_location.number == en_passant_row and \ last_move.piece.name == "Pawn" \ and last_move.piece.colour is not self.colour \ and last_move.piece.moves_made == 1 \ and last_move.to_location.number == en_passant_row: right_letter = self.__get_next_letter__( last_move.to_location.letter) left_letter = self.__get_previous_letter__( last_move.to_location.letter) if left_letter == current_location.letter \ or right_letter == current_location.letter: take_location = Location( last_move.to_location.letter, last_move.to_location.number) if self.colour is Colour.WHITE: take = Location( last_move.to_location.letter, current_location.number+1, True, last_move.piece, take_location) if board.get_piece_at_square(take) is None: moves.append(take) else: take = Location( last_move.to_location.letter, current_location.number-1, True, last_move.piece, take_location) if board.get_piece_at_square(take) is None: moves.append(take) return moves
def basic_king_test(): print("========================================") print("Performing the basic king movement test") print("========================================") board = Board() piece = King(Colour.WHITE) current_location = Location('d', 5) board.__add_piece__(piece, current_location) print(board) allowed_moves = piece.allowed_moves(current_location, board) print("For a {} {} starting at position {} the moves are:".format( piece.colour, piece.name, current_location)) print(allowed_moves) new_location = allowed_moves[0] board.move_piece(piece, current_location, new_location) current_location = new_location print("Moved the {} to position {}".format(piece.name, new_location)) print(board) print("For a {} {} at position {} the moves are:".format( piece.colour, piece.name, current_location)) print(piece.allowed_moves(current_location, board))
def __get_directional_move_moves__(self, current_location, board, up=False, down=False, left=False, right=False): directions = [up, down, left, right] direction_counts = sum(1 for direction in directions if direction) if direction_counts < 1 or direction_counts > 2 or (up and down) or ( left and right): raise Exception("Invalid directions given.") next_number = current_location.number next_letter = current_location.letter if up: next_number = current_location.number + 1 if right: next_letter = self.__get_next_letter__(current_location.letter) if down: next_number = current_location.number - 1 if left: next_letter = self.__get_previous_letter__(current_location.letter) return Location(next_letter, next_number)
def basic_knight_test(): print("========================================") print("Performing the basic knight movement test") print("========================================") board = Board() white_knight = Knight(Colour.WHITE) current_location = Location('b', 1) board.__add_piece__(white_knight, current_location) print(board) allowed_moves = white_knight.allowed_moves(current_location, board) print("For a {} {} starting at position {} the moves are:".format( white_knight.colour, white_knight.name, current_location)) print(allowed_moves) new_location = allowed_moves[0] board.move_piece(white_knight, current_location, new_location) current_location = new_location print("Moved the {} to position {}".format(white_knight.name, new_location)) print(board) print("For a {} {} at position {} the moves are:".format( white_knight.colour, white_knight.name, current_location)) print(white_knight.allowed_moves(current_location, board))
def pawn_en_passant_test(): print("========================================") print("Performing the pawn en passant test") print("========================================") board = Board() white_pawn_one = Pawn(Colour.WHITE) black_pawn_one = Pawn(Colour.BLACK) black_pawn_two = Pawn(Colour.BLACK) wp1_loc = Location('b', 2) bp1_loc = Location('a', 7) bp2_loc = Location('c', 7) board.__add_piece__(white_pawn_one, wp1_loc) board.__add_piece__(black_pawn_one, bp1_loc) board.__add_piece__(black_pawn_two, bp2_loc) print("The board was seeded with the following pieces: ") print("{} pawn at position {}".format(white_pawn_one.colour, wp1_loc)) print("{} pawn at position {}".format(black_pawn_one.colour, bp1_loc)) print("{} pawn at position {}".format(black_pawn_two.colour, bp2_loc)) print(board) # White pawn moves print("For the {} pawn starting at position {} the moves are:".format( white_pawn_one.colour, wp1_loc)) allowed_moves = white_pawn_one.allowed_moves(wp1_loc, board) print(allowed_moves) new_location = allowed_moves[1] board.move_piece(white_pawn_one, wp1_loc, new_location) wp1_loc = new_location print("Moved the pawn to position {}".format(wp1_loc)) print(board) # Black pawn moves print("For the {} pawn starting at position {} the moves are:".format( black_pawn_one.colour, bp1_loc)) allowed_moves = black_pawn_one.allowed_moves(bp1_loc, board) print(allowed_moves) new_location = allowed_moves[1] print("For the {} pawn starting at position {} the moves are:".format( black_pawn_two.colour, bp2_loc)) allowed_moves = black_pawn_two.allowed_moves(bp2_loc, board) print(allowed_moves) board.move_piece(black_pawn_one, bp1_loc, new_location) print("Moved the {} pawn at {} to position {}".format( black_pawn_one.colour, bp1_loc, new_location)) bp1_loc = new_location print(board) # White pawn moves print("For the {} pawn at position {} the moves are:".format( white_pawn_one.colour, wp1_loc)) allowed_moves = white_pawn_one.allowed_moves(wp1_loc, board) print(allowed_moves) new_location = allowed_moves[0] board.move_piece(white_pawn_one, wp1_loc, new_location) wp1_loc = new_location print("Moved the pawn to position {}".format(wp1_loc)) print(board) # Black pawn moves print("For the {} pawn starting at position {} the moves are:".format( black_pawn_one.colour, bp1_loc)) allowed_moves = black_pawn_one.allowed_moves(bp1_loc, board) print(allowed_moves) print("For the {} pawn starting at position {} the moves are:".format( black_pawn_two.colour, bp2_loc)) allowed_moves = black_pawn_two.allowed_moves(bp2_loc, board) print(allowed_moves) new_location = allowed_moves[1] board.move_piece(black_pawn_two, bp2_loc, new_location) print("Moved the {} pawn at {} to position {}".format( black_pawn_two.colour, bp2_loc, new_location)) bp2_loc = new_location print(board) # White pawn moves print("For the {} pawn at position {} the moves are:".format( white_pawn_one.colour, wp1_loc)) allowed_moves = white_pawn_one.allowed_moves(wp1_loc, board) print(allowed_moves) new_location = allowed_moves[1] board.move_piece(white_pawn_one, wp1_loc, new_location) wp1_loc = new_location print("Moved the pawn to position {}".format(wp1_loc)) print(board) print("The move history for this board is: ") [print(item) for item in board.move_history]
def __add_inital_pieces__(board, colour): first_row = 1 if colour == Colour.WHITE else 8 second_row = 2 if colour == Colour.WHITE else 7 board.__add_piece__(Rook(colour), Location('a', first_row)) board.__add_piece__(Knight(colour), Location('b', first_row)) board.__add_piece__(Bishop(colour), Location('c', first_row)) board.__add_piece__(Queen(colour), Location('d', first_row)) board.__add_piece__(King(colour), Location('e', first_row)) board.__add_piece__(Bishop(colour), Location('f', first_row)) board.__add_piece__(Knight(colour), Location('g', first_row)) board.__add_piece__(Rook(colour), Location('h', first_row)) board.__add_piece__(Pawn(colour), Location('a', second_row)) board.__add_piece__(Pawn(colour), Location('b', second_row)) board.__add_piece__(Pawn(colour), Location('c', second_row)) board.__add_piece__(Pawn(colour), Location('d', second_row)) board.__add_piece__(Pawn(colour), Location('e', second_row)) board.__add_piece__(Pawn(colour), Location('f', second_row)) board.__add_piece__(Pawn(colour), Location('g', second_row)) board.__add_piece__(Pawn(colour), Location('h', second_row))
def __rook_move_worker__(self, current_location, board): moves = [] current_number = current_location.number # Upwards moves for next_number in range(current_number + 1, list(board.numbers.keys())[-1] + 1): new_location = Location(current_location.letter, next_number) piece_at_move = board.get_piece_at_square(new_location) if piece_at_move is None: moves.append(new_location) else: if piece_at_move.colour != self.colour: moves.append(new_location) break # Downwards moves for next_number in range(current_number - 1, list(board.numbers.keys())[0] - 1, -1): new_location = Location(current_location.letter, next_number) piece_at_move = board.get_piece_at_square(new_location) if piece_at_move is None: moves.append(new_location) else: if piece_at_move.colour != self.colour: moves.append(new_location) break current_letter = current_location.letter # Rightwards moves right_location = Location(self.__get_next_letter__(current_letter), current_location.number) while self.__is_valid_square__(right_location, board): piece_at_move = board.get_piece_at_square(right_location) if piece_at_move is None: moves.append(right_location) else: if piece_at_move.colour != self.colour: moves.append(right_location) break right_location = Location( self.__get_next_letter__(right_location.letter), current_location.number) # Leftwards moves left_location = Location(self.__get_previous_letter__(current_letter), current_location.number) while self.__is_valid_square__(left_location, board): piece_at_move = board.get_piece_at_square(left_location) if piece_at_move is None: moves.append(left_location) else: if piece_at_move.colour != self.colour: moves.append(left_location) break left_location = Location( self.__get_previous_letter__(left_location.letter), current_location.number) [self.__check_take__(location, board) for location in moves] return moves