def check_for_checkmate(): if chess.get_turn() == 1: _, white_king_moves, white_king_captures = chess_rules.check_valid_move( "White King", white_king_pos, "", chess.get_chess_board()) if len(white_king_moves) == 0 and len(white_king_captures) == 0: print("WHITE CHECKMATE, No Moves") return True else: for i in white_king_moves: # if i in all_possible_moves_black or i in all_possible_captures_black: if i in all_possible_captures_black: print(f"WHITE CHECKMATE") else: return None print(f"White King moves: {white_king_moves}") # End game return True else: _, black_king_moves, black_king_captures = chess_rules.check_valid_move( "Black King", black_king_pos, "", chess.get_chess_board()) if len(black_king_moves) == 0 and len(captures) == 0: print("BLACK CHECKMATE, No Moves") return True else: for i in black_king_moves: #if i in all_possible_moves_white or i in all_possible_captures_black: if i in all_possible_captures_black: print("BLACK CHECKMATE") else: return None print(f"Black King moves: {black_king_moves}") # End game return True
def move_pawn(computer): # Check all pawns and see all possible pawn positions # Needs to return the pawn to move(pawn position) and the location that it is moving to # This returns pawn and whatever game object it will capture # Should I make it so it only returns if it can capture or should it be able to return a position to move to # I rewrote this because I hated the original code for it pawn_dict = {} # {pawn: [current_pos, [moves], [captures]]} # This will initialize pawn_dict # So this technically works with all game objects, not just pawns for key, value in computer.get_game_pieces().items(): #print(f"{key.get_name()} at pos {value[0]}") #if 9 <= value[1] <= 16: #moves, captures = chess_rules.pawn_calculate_all_possible_moves(value[0], chess.chess.get_chess_board()) _, moves, captures = chess_rules.check_valid_move(key.get_name(), value[0], None, chess.chess.get_chess_board()) pawn_dict[key] = [value[0], moves, captures] highest_value_dict = {} # {value: [(pawn, enemy_piece)]} highest_value = 0 for key, value in pawn_dict.items(): for capture in value[2]: enemy_piece = chess.chess.get_chess_board().get(capture) print(f"{key.get_name()} can capture {enemy_piece.get_name()}") value = enemy_piece.get_value() if value > highest_value: highest_value = value if value not in highest_value_dict: highest_value_dict[value] = [(key, enemy_piece)] else: highest_value_dict[value].append((key, enemy_piece)) # Return the pawn and enemy piece of there is only a len of 1 if len(highest_value_dict) > 0: if len(highest_value_dict[highest_value]) == 1: return highest_value_dict[highest_value] # Return a 'random' set, this solution is anything but elegant random_index = random.randrange(len(highest_value_dict)) index = 0 for value in highest_value_dict[highest_value]: if index == random_index: return value index += 1
def decide_piece(computer): # Get a list of all pieces that have possible moves or captures piece_list_moves = [] piece_list_captures = [] for key, value in computer.get_game_pieces().items(): print(key.get_name(), key.get_pos()) _, moves, captures = chess_rules.check_valid_move(key.get_name(), value[0], None, chess.chess.get_chess_board()) # So far this is the only place where it sets all of a pieces moves, probably not the best place to put it..idk key.set_moves(moves) key.set_captures(captures) if len(moves) > 0: piece_list_moves.append(key) if len(captures) > 0: piece_list_captures.append(key) # Check moves and see if any would check the opposite king black_king_pos = (-1, -1) white_king_pos = (-1, -1) for game_piece in chess.chess.get_chess_board(): if chess.chess.get_chess_board().get(game_piece) is not None: # Sets the positions of the kings if chess.chess.get_chess_board().get(game_piece).get_name() == "Black King": black_king_pos = (game_piece[0], game_piece[1]) elif chess.chess.get_chess_board().get(game_piece).get_name() == "White King": white_king_pos = (game_piece[0], game_piece[1]) temp_list = [] for piece in piece_list_moves: for move in piece.get_moves(): temp_chess_board = copy.deepcopy(chess.chess.get_chess_board()) print(piece.get_name(), piece.get_pos(), move) temp_chess_board[piece.get_pos()] = None temp_chess_board[move] = piece _, moves, captures = chess_rules.check_valid_move(piece.get_name(), move, None, temp_chess_board) if black_king_pos in captures or white_king_pos in captures: print(f"CHECK HERE {piece.get_name()} {move}") temp_list.append((piece.get_pos(), move)) #return piece.get_pos(), move if len(temp_list) > 0: rand_index = random.randrange(0, len(temp_list)) return temp_list[rand_index][0], temp_list[rand_index][1] piece_dict = {} # {pawn: [current_pos, [moves], [captures]]} # This will initialize pawn_dict # So this technically works with all game objects, not just pawns for key, value in computer.get_game_pieces().items(): # print(f"{key.get_name()} at pos {value[0]}") # if 9 <= value[1] <= 16: # moves, captures = chess_rules.pawn_calculate_all_possible_moves(value[0], chess.chess.get_chess_board()) _, moves, captures = chess_rules.check_valid_move(key.get_name(), value[0], None, chess.chess.get_chess_board()) piece_dict[key] = [value[0], moves, captures] highest_value_dict = {} # {value: [(pawn, enemy_piece)]} highest_value = 0 for key, value in piece_dict.items(): for capture in value[2]: enemy_piece = chess.chess.get_chess_board().get(capture) print(f"{key.get_name()} can capture {enemy_piece.get_name()}") value = enemy_piece.get_value() if value > highest_value: highest_value = value if value not in highest_value_dict: highest_value_dict[value] = [(key, enemy_piece)] else: highest_value_dict[value].append((key, enemy_piece)) # Return the pawn and enemy piece of there is only a len of 1 if len(highest_value_dict) > 0: if len(highest_value_dict[highest_value]) == 1: return highest_value_dict[highest_value][0][0].get_pos(), highest_value_dict[highest_value][0][1].get_pos() # Return a 'random' set, this solution is anything but elegant random_index = random.randrange(len(highest_value_dict)) index = 0 for value in highest_value_dict[highest_value]: if index == random_index: return value[0].get_pos(), value[1].get_pos() index += 1 return make_move(computer)
def move_king(computer): print("Move King") if computer.get_name() == "White": # Probably would be best to have a method that always know where the kings position is king_pos = (-1, -1) king_moves = [] king_captures = [] all_possible_black_moves = [] all_possible_black_captures = [] # Finds the position of the king and gets its moves and captures for game_piece in chess.chess.get_chess_board(): if chess.chess.get_chess_board().get(game_piece) is not None and \ chess.chess.get_chess_board().get(game_piece).get_player_side() == 1: if chess.chess.get_chess_board().get(game_piece).get_name() == "White King": _, moves, captures = chess_rules.check_valid_move( chess.chess.get_chess_board().get(game_piece).get_name(), game_piece, "", chess.chess.get_chess_board()) king_moves.extend(moves) king_captures.extend(captures) king_pos = game_piece break # This gets all enemy moves and captures for game_piece in chess.chess.get_chess_board(): if chess.chess.get_chess_board().get(game_piece) is not None and \ chess.chess.get_chess_board().get(game_piece).get_player_side() == 2: _, moves, captures = chess_rules.check_valid_move( chess.chess.get_chess_board().get(game_piece).get_name(), game_piece, "", chess.chess.get_chess_board()) all_possible_black_moves.extend(moves) all_possible_black_captures.extend(captures) best_possible_moves = [] # This chooses the best move to go to for x in king_captures: if x not in all_possible_black_captures and all_possible_black_moves and \ chess.chess.get_chess_board().get(x).get_name() != "Black King": best_possible_moves.append(x) for x in king_moves: if x not in all_possible_black_captures and all_possible_black_moves: best_possible_moves.append(x) if len(best_possible_moves) == 0: # BLACK WINS... i think print("BLACK WINS") #time.sleep(5) chess.end_game() return None, None random_move = best_possible_moves[random.randrange(len(best_possible_moves))] return king_pos, random_move elif computer.get_name() == "Black": king_pos = (-1, -1) king_moves = [] king_captures = [] all_possible_white_moves = [] all_possible_white_captures = [] # Finds the position of the king and gets its moves and captures for game_piece in chess.chess.get_chess_board(): if chess.chess.get_chess_board().get(game_piece) is not None and \ chess.chess.get_chess_board().get(game_piece).get_player_side() == 2: if chess.chess.get_chess_board().get(game_piece).get_name() == "Black King": _, moves, captures = chess_rules.check_valid_move( chess.chess.get_chess_board().get(game_piece).get_name(), game_piece, "", chess.chess.get_chess_board()) king_moves.extend(moves) king_captures.extend(captures) king_pos = game_piece break # This gets all enemy moves and captures for game_piece in chess.chess.get_chess_board(): if chess.chess.get_chess_board().get(game_piece) is not None and \ chess.chess.get_chess_board().get(game_piece).get_player_side() == 1: _, moves, captures = chess_rules.check_valid_move( chess.chess.get_chess_board().get(game_piece).get_name(), game_piece, "", chess.chess.get_chess_board()) all_possible_white_moves.extend(moves) all_possible_white_captures.extend(captures) best_possible_moves = [] # This chooses the best move to go to for x in king_captures: if x not in all_possible_white_captures and all_possible_white_moves and \ chess.chess.get_chess_board().get(x).get_name() != "White King": best_possible_moves.append(x) for x in king_moves: if x not in all_possible_white_captures and all_possible_white_moves: best_possible_moves.append(x) if len(best_possible_moves) == 0: # WHITE WINS... i think print("WHITE WINS") #time.sleep(5) chess.end_game() return None, None random_move = best_possible_moves[random.randrange(len(best_possible_moves))] return king_pos, random_move
def make_move(computer): if computer.get_name() == "White": game_piece_list = [] all_possible_moves_white = [] all_possible_captures_white = [] for game_piece in chess.chess.get_chess_board(): if chess.chess.get_chess_board().get(game_piece) is not None and \ chess.chess.get_chess_board().get(game_piece).get_player_side() == 1: game_piece_list.append(game_piece) valid_choice = False while not valid_choice: random_game_piece = game_piece_list[random.randrange(len(game_piece_list))] # print(random_game_piece) _, moves, captures = chess_rules.check_valid_move( chess.chess.get_chess_board().get(random_game_piece).get_name(), random_game_piece, "", chess.chess.get_chess_board()) if len(moves) > 0 or len(captures) > 0: valid_choice = True # print(f"DEBUG: {len(moves)}") if len(moves) > 0: random_move = moves[random.randrange(len(moves))] else: random_move = captures[random.randrange(len(captures))] #all_possible_moves_white.extend(moves) #all_possible_captures_white.extend(captures) # if len(all_possible_captures_white) > 0: # # choice2 = random.randrange(len(captures)) # # if random.randrange(1) == 0: # # return moves[choice1] # # else: # # return captures[choice2] # print("Returning") return random_game_piece, random_move else: game_piece_list = [] # all_possible_moves_black = [] # all_possible_captures_black = [] for game_piece in chess.chess.get_chess_board(): if chess.chess.get_chess_board().get(game_piece) is not None and \ chess.chess.get_chess_board().get(game_piece).get_player_side() == 2: # print(chess.chess.get_chess_board().get(game_piece).get_name()) game_piece_list.append(game_piece) valid_choice = False while not valid_choice: random_game_piece = game_piece_list[random.randrange(len(game_piece_list))] # print(random_game_piece) _, moves, captures = chess_rules.check_valid_move( chess.chess.get_chess_board().get(random_game_piece).get_name(), random_game_piece, "", chess.chess.get_chess_board()) if len(moves) > 0 or len(captures) > 0: valid_choice = True if len(moves) > 0: random_move = moves[random.randrange(len(moves))] else: random_move = captures[random.randrange(len(captures))] # all_possible_moves_white.extend(moves) # all_possible_captures_white.extend(captures) # choice1 = random.randrange(len(moves)) # # if len(captures) > 0: # # choice2 = random.randrange(len(captures)) # # if random.randrange(1) == 0: # # return moves[choice1] # # else: # # return captures[choice2] # print("Returning") return random_game_piece, random_move
def check_for_check(): # Check all pieces and see if king is in check, need to get all possible moves/captures for all pieces all_possible_moves_white = [] all_possible_captures_white = [] all_possible_moves_black = [] all_possible_captures_black = [] # This breaks sometimes, not sure why def get_kings_pos(): black_king_pos = (-1, -1) white_king_pos = (-1, -1) for game_piece in chess.get_chess_board(): if chess.get_chess_board().get(game_piece) is not None: # Sets the positions of the kings if chess.get_chess_board().get( game_piece).get_name() == "Black King": black_king_pos = (game_piece[0], game_piece[1]) elif chess.get_chess_board().get( game_piece).get_name() == "White King": white_king_pos = (game_piece[0], game_piece[1]) #print(black_king_pos, white_king_pos) return black_king_pos, white_king_pos black_king_pos, white_king_pos = get_kings_pos() # This checks for checkmate def check_for_checkmate(): if chess.get_turn() == 1: _, white_king_moves, white_king_captures = chess_rules.check_valid_move( "White King", white_king_pos, "", chess.get_chess_board()) if len(white_king_moves) == 0 and len(white_king_captures) == 0: print("WHITE CHECKMATE, No Moves") return True else: for i in white_king_moves: # if i in all_possible_moves_black or i in all_possible_captures_black: if i in all_possible_captures_black: print(f"WHITE CHECKMATE") else: return None print(f"White King moves: {white_king_moves}") # End game return True else: _, black_king_moves, black_king_captures = chess_rules.check_valid_move( "Black King", black_king_pos, "", chess.get_chess_board()) if len(black_king_moves) == 0 and len(captures) == 0: print("BLACK CHECKMATE, No Moves") return True else: for i in black_king_moves: #if i in all_possible_moves_white or i in all_possible_captures_black: if i in all_possible_captures_black: print("BLACK CHECKMATE") else: return None print(f"Black King moves: {black_king_moves}") # End game return True for game_piece in chess.get_chess_board(): if chess.get_chess_board().get(game_piece) is not None: #print(f"Chess Position: {game_piece} | Chess Name: {chess.get_chess_board().get(game_piece).get_name()}") is_valid_move, moves, captures = chess_rules.check_valid_move( chess.get_chess_board()[game_piece].get_name(), game_piece, "", chess.get_chess_board()) # If player is white if chess.get_chess_board().get(game_piece).get_player_side() == 1: all_possible_moves_white.extend(moves) all_possible_captures_white.extend(captures) # If player is black else: all_possible_moves_black.extend(moves) all_possible_captures_black.extend(captures) #print(captures) if black_king_pos in captures or white_king_pos in captures: # Check for checkmate at this point print("CHECK") if check_for_checkmate(): end_game() return True
def highlight_box(box_cords, player1, player2): # Need error conditioning # Will break if the user selects a pixel such as 100, 200, 300, 400... # False by default to keep a box highlighted when selecting empty boxes box_deselect = False x_pos = -1 y_pos = -1 try: x_pos = box_cords[0] * 100 y_pos = box_cords[1] * 100 except: # print("No pos found") # Breaks out of function return None # Checks if the last highlighted box is in the chess_board keys if chess.get_highlighted_box() in chess.get_chess_board().keys(): # Checks if the last highlighted box value in chess_board is not None if chess.get_chess_board()[chess.get_highlighted_box()] is not None: # print("Not none") is_valid_move, _, _ = chess_rules.check_valid_move( chess.get_chess_board()[ chess.get_highlighted_box()].get_name(), chess.get_highlighted_box(), box_cords, chess.get_chess_board()) # Checks if that game piece can make that move and that it is the correct piece turn # if is_valid_move and \ # chess.get_chess_board()[chess.get_highlighted_box()].get_player_side() == chess.get_turn(): if chess.get_chess_board()[chess.get_highlighted_box( )].get_player_side() == chess.get_turn(): # if "King" in chess.get_chess_board().get(chess.get_highlighted_box()).get_name(): # # print("Check") # temp is the game piece that is moving temp = chess.get_chess_board()[chess.get_highlighted_box()] temp.set_pos(box_cords) print( f"{temp.get_name()}({temp.get_pos()}) moving to {box_cords}" ) if temp.get_player_side() == 1: player1.update_game_piece(temp, box_cords) else: player2.update_game_piece(temp, box_cords) capture = '' if chess.get_chess_board().get(box_cords) is not None: print( f"Capturing piece {chess.get_chess_board().get(box_cords).get_name()} ({box_cords}" ) capture = chess.get_chess_board().get(box_cords).get_id() if player1.get_game_pieces().get( chess.get_chess_board().get(box_cords)): player1.remove_game_piece( chess.get_chess_board().get(box_cords)) else: player2.remove_game_piece( chess.get_chess_board().get(box_cords)) # Sets the previous box to None chess.update_game_piece(chess.get_highlighted_box(), None) # Sets the new box to whichever piece was moving(temp) chess.update_game_piece(box_cords, temp) # Do all CSV stuff here with open('chess_data.csv', 'a', newline='') as csvfile: writer = csv.writer(csvfile) writer.writerow([ temp.get_player_side(), temp.get_id(), chess.get_highlighted_box(), box_cords, capture ]) # draw_boxes() call because if highlights are left over after viewing all possible moves draw_boxes() #check_for_check() # Set to true to deselect box after making move box_deselect = True if chess.get_turn() == 1: chess.set_turn(2) else: chess.set_turn(1) else: print("Cant move there") # Else piece lands on another piece else: pass # print("Is none") # Checks if the new box cords is different from the last, if it is, sets the last box cords to normal color if chess.get_highlighted_box() != box_cords and chess.get_highlighted_box( ) != (-1, -1): #print(chess.get_highlighted_box()) print( f"Un-highlighting {chess.get_highlighted_box()} and highlighting {box_cords}" ) # This makes it so you cant draw with the boxes highlight_box(chess.get_highlighted_box(), None, None) # if box_deselect is True, it deselects the box after a user makes a move if not box_deselect: chess.set_highlighted_box(box_cords) highlight_box(box_cords, None, None) # Checks if user is selecting the highlighted box to unselect it if chess.get_highlighted_box() == box_cords: if (box_cords[1] % 2) == 0: if (box_cords[0] % 2) == 0: pygame.draw.rect(screen, chess.get_chessboard_color1(), pygame.Rect(x_pos, y_pos, 100, 100)) chess.set_highlighted_box((-1, -1)) else: pygame.draw.rect(screen, chess.get_chessboard_color2(), pygame.Rect(x_pos, y_pos, 100, 100)) chess.set_highlighted_box((-1, -1)) else: if (box_cords[0] % 2) == 0: pygame.draw.rect(screen, chess.get_chessboard_color2(), pygame.Rect(x_pos, y_pos, 100, 100)) chess.set_highlighted_box((-1, -1)) else: pygame.draw.rect(screen, chess.get_chessboard_color1(), pygame.Rect(x_pos, y_pos, 100, 100)) chess.set_highlighted_box((-1, -1)) # else the user selects a different box that is not already selected else: # Setting the box to selected pygame.draw.rect(screen, (166, 166, 166), pygame.Rect(x_pos, y_pos, 100, 100)) chess.set_highlighted_box(box_cords) chess_piece = "" return box_cords
def init_game(player1, player2): global chess chess = Chess() pygame.init() # Set up everything necessary for the computer class player1.set_game_pieces(chess.get_white_pieces_obj()) player2.set_game_pieces(chess.get_black_pieces_obj()) size = width, height = 1000, 800 global screen screen = pygame.display.set_mode(size) def init_game_pieces(): print("Running init_game_pieces") black_pieces_list = chess.get_black_game_pieces() screen.blit(black_pieces_list[0][0], (25, 25)) screen.blit(black_pieces_list[1][0], (125, 25)) screen.blit(black_pieces_list[2][0], (225, 25)) screen.blit(black_pieces_list[3][0], (325, 25)) screen.blit(black_pieces_list[4][0], (425, 25)) screen.blit(black_pieces_list[2][0], (525, 25)) screen.blit(black_pieces_list[1][0], (625, 25)) screen.blit(black_pieces_list[0][0], (725, 25)) black_pawn_x_pos = 25 for x in range(8): screen.blit(black_pieces_list[5][0], (black_pawn_x_pos, 125)) black_pawn_x_pos += 100 white_pieces_list = chess.get_white_game_pieces() screen.blit(white_pieces_list[0][0], (25, 725)) screen.blit(white_pieces_list[1][0], (125, 725)) screen.blit(white_pieces_list[2][0], (225, 725)) screen.blit(white_pieces_list[3][0], (325, 725)) screen.blit(white_pieces_list[4][0], (425, 725)) screen.blit(white_pieces_list[2][0], (525, 725)) screen.blit(white_pieces_list[1][0], (625, 725)) screen.blit(white_pieces_list[0][0], (725, 725)) white_pawn_x_pos = 25 for x in range(8): screen.blit(white_pieces_list[5][0], (white_pawn_x_pos, 625)) white_pawn_x_pos += 100 #draw_lines() draw_boxes() init_game_pieces() counter = 0 # Game loop while chess.is_running(): # Turns # White goes first, then once white makes a move, black makes a move if len(player1.get_game_pieces()) == 1 and len( player2.get_game_pieces()) == 1: if player1.get_game_pieces().get(chess.get_white_king())[1] == 7 \ and player2.get_game_pieces().get(chess.get_black_king())[1] == 7: end_game() if chess.get_turn() == 1: update_turn(screen, "White's Turn") #returns True if king in check if check_for_check(): king_pos, random_move = computer.move_king(player1) if king_pos == None and random_move == None: break highlight_box(king_pos, player1, player2) update_board(screen) highlight_box(random_move, player1, player2) update_board(screen) #pygame.time.wait(500) else: random_game_piece, random_move = computer.decide_piece(player1) highlight_box(random_game_piece, player1, player2) update_board(screen) highlight_box(random_move, player1, player2) update_board(screen) #pygame.time.wait(500) # pygame.time.wait(500) elif chess.get_turn() == 2: update_turn(screen, "Black's Turn") #returns True if king in check if check_for_check(): king_pos, random_move = computer.move_king(player2) if king_pos == None and random_move == None: break highlight_box(king_pos, player1, player2) update_board(screen) highlight_box(random_move, player1, player2) update_board(screen) # pygame.time.wait(500) else: #random_game_piece, random_move = computer.make_move(player2) game_piece, move = computer.decide_piece(player2) highlight_box(game_piece, player1, player2) update_board(screen) highlight_box(move, player1, player2) update_board(screen) # pygame.time.wait(500) # pygame.time.wait(500) # This is if there is human interaction (Left or right mouse click) for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if (1, 0, 0) == pygame.mouse.get_pressed(): mouse_pos = pygame.mouse.get_pos() board_pos = check_bounds(mouse_pos, screen) highlight_box(board_pos, player1, player2) update_board(screen) counter = 0 # This highlights all possible moves for selected game piece if (0, 0, 1) == pygame.mouse.get_pressed(): mouse_pos = pygame.mouse.get_pos() board_pos = check_bounds(mouse_pos, screen) if chess.get_chess_board().get(board_pos) is not None: _, moves, captures = chess_rules.check_valid_move( chess.get_chess_board().get(board_pos).get_name(), board_pos, "", chess.get_chess_board()) if counter % 2 == 0: highlight_all_possible_moves(moves, captures, True) else: highlight_all_possible_moves(moves, captures, False) counter += 1 if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: pygame.time.wait(5000) pygame.display.flip() # This is for after the game ends and I want to analyze to see all the shit that broke and doesnt make sense # press ESC to quit the game # x = True # # while x: # # for event in pygame.event.get(): # # if event.type == pygame.KEYDOWN: # # if event.key == pygame.K_ESCAPE: # # x = False # # if (0, 0, 1) == pygame.mouse.get_pressed(): # # print("RMB") # # mouse_pos = pygame.mouse.get_pos() # # board_pos = check_bounds(mouse_pos, screen) # # if chess.get_chess_board().get(board_pos) is not None: # # _, moves, captures = chess_rules.check_valid_move( # chess.get_chess_board().get(board_pos).get_name(), # board_pos, "", # chess.get_chess_board()) # # if counter % 2 == 0: # highlight_all_possible_moves(moves, captures, True) # else: # highlight_all_possible_moves(moves, captures, False) # # counter += 1 # # pygame.display.flip() print("GAME ENDED")