diff --git a/Chess.py b/Chess.py index 1340849..98824fe 100644 --- a/Chess.py +++ b/Chess.py @@ -4,7 +4,7 @@ Features To-Do (short-term): Play back moves Be able to click on a move in the pane to view it ---> One idea I had before was pause mode (mode between edit and play) +--> One idea I had before was replayed mode (mode between edit and play) --> I think the right thing to do would take the df_prior_moves to get the move. The tricky part is differentiating this from Undo move (through a conditional variable checking within each class for example). And coloring prior_move_color appropriately. Menu objects are still invisible yet clickable @@ -37,6 +37,7 @@ import start_objects import placed_objects import play_objects +import replayed_objects from load_images_sounds import * from menu_buttons import * import random @@ -48,7 +49,7 @@ from tkinter.colorchooser import askcolor from tkinter.filedialog import * from tkinter import ttk -from ast import * +import ast import pygame import datetime import logging @@ -106,7 +107,7 @@ def pos_load_file(reset=False): log.info("File not found") return loaded_file = open_file.read() - loaded_dict = literal_eval(loaded_file) + loaded_dict = ast.literal_eval(loaded_file) for obj_list in play_objects.Piece_Lists_Shortcut.all_pieces(): for obj in obj_list: @@ -552,18 +553,36 @@ def prior_move_color(grid_coordinate, prior_move_piece): else: grid.prior_move_color = False grid.no_highlight() - for piece_list in play_objects.Piece_Lists_Shortcut.all_pieces(): - for piece in piece_list: - if piece == prior_move_piece: - piece.prior_move_color = True - else: - piece.prior_move_color = False - piece.no_highlight() + if Switch_Modes_Controller.REPLAYED == False: + # Updating prior move sprites for play objects + for piece_list in play_objects.Piece_Lists_Shortcut.all_pieces(): + for piece in piece_list: + if piece == prior_move_piece: + piece.prior_move_color = True + else: + piece.prior_move_color = False + piece.no_highlight() + else: + # Updating prior move sprites for replayed objects + for piece_list in replayed_objects.Piece_Lists_Shortcut.all_pieces(): + for piece in piece_list: + if piece == prior_move_piece: + piece.prior_move_color = True + else: + piece.prior_move_color = False + piece.prior_move_update() + #print("Does piece have red color? " + str(prior_move_piece.prior_move_color)) def piece_on_grid(grid_coordinate): - for piece_list in play_objects.Piece_Lists_Shortcut.all_pieces(): - for piece in piece_list: - if grid_coordinate == piece.coordinate: - return piece + if Switch_Modes_Controller.REPLAYED == False: + for piece_list in play_objects.Piece_Lists_Shortcut.all_pieces(): + for piece in piece_list: + if grid_coordinate == piece.coordinate: + return piece + else: + for piece_list in replayed_objects.Piece_Lists_Shortcut.all_pieces(): + for piece in piece_list: + if grid_coordinate == piece.coordinate: + return piece def update_prior_move_color(whoseturn): if Move_Tracker.move_counter() == 0: for grid in board.Grid.grid_list: @@ -590,6 +609,7 @@ def update_prior_move_color(whoseturn): class Switch_Modes_Controller(): EDIT_MODE, PLAY_MODE = 0, 1 GAME_MODE = EDIT_MODE + REPLAYED = False def switch_mode(game_mode, PLAY_EDIT_SWITCH_BUTTON): if game_mode == Switch_Modes_Controller.EDIT_MODE: log.info("\nEditing Mode Activated\n") @@ -617,6 +637,120 @@ def placed_to_play(placed_list, class_obj, color): # Play pieces spawn where their placed piece correspondents are located for placed_obj in placed_list: class_obj(placed_obj.coordinate, color) + def play_to_replayed(play_list, class_obj, color): + # Play pieces spawn where their placed piece correspondents are located + for play_obj in play_list: + if play_obj.coordinate is not None: + class_obj(color, play_obj.coordinate_history, coord=play_obj.coordinate) + elif play_obj.coordinate is None: + class_obj(color, play_obj.coordinate_history, + captured_move_number_and_coordinate=play_obj.captured_move_number_and_coordinate, + out_of_bounds_x_y=play_obj.rect.topleft) + def rewind_moves(): + list_of_moves_backwards = Switch_Modes_Controller.list_of_moves_backwards(Move_Tracker.df_prior_moves)[:-1] + # list_of_moves_backwards list is ordered in descending order to the selected move + for move_dict in list_of_moves_backwards: + for replayed_obj_list in replayed_objects.Piece_Lists_Shortcut.all_pieces(): + for replayed_obj in replayed_obj_list: + for piece_history in replayed_obj.coordinate_history: + if piece_history in dict(move_dict): + if replayed_obj.coordinate_history[piece_history] == ast.literal_eval(move_dict[piece_history]): + replayed_obj.coordinate = ast.literal_eval(move_dict[piece_history])['before'] + Grid_Controller.prior_move_color(replayed_obj.coordinate, replayed_obj) + if ast.literal_eval(move_dict[piece_history])['move_notation'] == "O-O": + if replayed_obj.color == "white": + Grid_Controller.piece_on_grid('f1').coordinate = 'h1' + elif replayed_obj.color == "black": + Grid_Controller.piece_on_grid('f8').coordinate = 'h8' + elif ast.literal_eval(move_dict[piece_history])['move_notation'] == "O-O-O": + if replayed_obj.color == "white": + Grid_Controller.piece_on_grid('d1').coordinate = 'a1' + elif replayed_obj.color == "black": + Grid_Controller.piece_on_grid('d8').coordinate = 'a8' + if "x" in ast.literal_eval(move_dict[piece_history])['move_notation']: + if replayed_obj.color == "white": + for piece_list in replayed_objects.Piece_Lists_Shortcut.black_pieces(): + for piece in piece_list: + if piece.captured_move_number_and_coordinate: + if piece.captured_move_number_and_coordinate['move_number'] == piece_history: + if 'ep_grid_after_coord' in piece.captured_move_number_and_coordinate: + # En Passant exception + piece.coordinate = piece.captured_move_number_and_coordinate['ep_grid_after_coord'][0] + str(int(piece.captured_move_number_and_coordinate['ep_grid_after_coord'][1])-1) + else: + piece.coordinate = ast.literal_eval(move_dict[piece_history])['after'] + elif replayed_obj.color == "black": + for piece_list in replayed_objects.Piece_Lists_Shortcut.white_pieces(): + for piece in piece_list: + if piece.captured_move_number_and_coordinate: + if piece.captured_move_number_and_coordinate['move_number'] == piece_history: + if 'ep_grid_after_coord' in piece.captured_move_number_and_coordinate: + # En Passant exception + piece.coordinate = piece.captured_move_number_and_coordinate['ep_grid_after_coord'][0] + str(int(piece.captured_move_number_and_coordinate['ep_grid_after_coord'][1])+1) + else: + piece.coordinate = ast.literal_eval(move_dict[piece_history])['after'] + if "=Q" in ast.literal_eval(move_dict[piece_history])['move_notation']: + if replayed_obj.color == "white": + for piece_list in replayed_objects.Piece_Lists_Shortcut.white_pieces(): + for piece in replayed_objects.ReplayedQueen.white_queen_list: + if piece.coordinate == eval(Move_Tracker.df_prior_moves.loc[piece_history, "white_move"])['after']: + piece.kill() + replayed_objects.ReplayedQueen.white_queen_list.remove(piece) + elif replayed_obj.color == "black": + for piece_list in replayed_objects.Piece_Lists_Shortcut.black_pieces(): + for piece in replayed_objects.ReplayedQueen.black_queen_list: + if piece.coordinate == eval(Move_Tracker.df_prior_moves.loc[piece_history, "black_move"])['after']: + piece.kill() + replayed_objects.ReplayedQueen.black_queen_list.remove(piece) + # -1 in the list refers to the highlighted move in the pane + # Retrieve the grids from the piece that we are replaying, and get the grid from the previous move to that one + prior_move_grid_and_piece_highlight_dict = Switch_Modes_Controller.list_of_moves_backwards(Move_Tracker.df_prior_moves)[-1] + old_grid_coordinate_before = ast.literal_eval(list(prior_move_grid_and_piece_highlight_dict.values())[0])['before'] + old_grid_coordinate_after = ast.literal_eval(list(prior_move_grid_and_piece_highlight_dict.values())[0])['after'] + old_piece = Grid_Controller.piece_on_grid(old_grid_coordinate_after) + Grid_Controller.prior_move_color(old_grid_coordinate_before, old_piece) + def replayed_game(replayed, game_controller): + Switch_Modes_Controller.REPLAYED = replayed + if Switch_Modes_Controller.REPLAYED == True: + replayed_objects.remove_all_replayed() + Switch_Modes_Controller.play_to_replayed(play_objects.PlayPawn.white_pawn_list, replayed_objects.ReplayedPawn, "white") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayBishop.white_bishop_list, replayed_objects.ReplayedBishop, "white") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayKnight.white_knight_list, replayed_objects.ReplayedKnight, "white") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayRook.white_rook_list, replayed_objects.ReplayedRook, "white") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayQueen.white_queen_list, replayed_objects.ReplayedQueen, "white") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayKing.white_king_list, replayed_objects.ReplayedKing, "white") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayPawn.black_pawn_list, replayed_objects.ReplayedPawn, "black") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayBishop.black_bishop_list, replayed_objects.ReplayedBishop, "black") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayKnight.black_knight_list, replayed_objects.ReplayedKnight, "black") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayRook.black_rook_list, replayed_objects.ReplayedRook, "black") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayQueen.black_queen_list, replayed_objects.ReplayedQueen, "black") + Switch_Modes_Controller.play_to_replayed(play_objects.PlayKing.black_king_list, replayed_objects.ReplayedKing, "black") + Switch_Modes_Controller.rewind_moves() + else: + replayed_objects.remove_all_replayed() + Grid_Controller.update_prior_move_color(game_controller.WHOSETURN) + def list_of_moves_backwards(df_prior_moves): + moves_backwards_list = [] + limit_moves = Move_Tracker.selected_move[0] + limit_color = Move_Tracker.selected_move[1] + for move_num in range(Move_Tracker.move_counter(), limit_moves-1, -1): + moves_backwards_dict = {} + if limit_color == 'black_move' and move_num == limit_moves: + # Selected move is black, so ignore the white move on that same move number and break + moves_backwards_dict[move_num] = df_prior_moves.loc[move_num, 'black_move'] + moves_backwards_list.append(moves_backwards_dict) + break + elif df_prior_moves.loc[move_num, 'black_move'] == '': + # Current move has no black move yet, so ignore adding that to list + pass + else: + moves_backwards_dict[move_num] = df_prior_moves.loc[move_num, 'black_move'] + moves_backwards_list.append(moves_backwards_dict) + moves_backwards_dict = {} + moves_backwards_dict[move_num] = df_prior_moves.loc[move_num, 'white_move'] + moves_backwards_list.append(moves_backwards_dict) + # When select a move on pane, we take back the move right after that + return moves_backwards_list + class Move_Tracker(): df_moves = pd.DataFrame(columns=["white_move", "black_move"]) @@ -630,7 +764,8 @@ def restart(): Move_Tracker.df_moves.index = np.arange(1, len(Move_Tracker.df_moves)+1) Move_Tracker.df_prior_moves = pd.DataFrame(columns=["white_move", "black_move"]) Move_Tracker.df_prior_moves.index = np.arange(1, len(Move_Tracker.df_prior_moves)+1) - Move_Tracker.move_counter = lambda : len(Move_Tracker.df_moves) + #%% The below 1 line may need to be deleted + Move_Tracker.move_counter = lambda : len(Move_Tracker.df_moves) Move_Tracker.selected_move = (0, "") def undo_move_in_dfs(undo_color): if undo_color == "black": @@ -710,6 +845,7 @@ def __del__(self): play_objects.PlayKing.black_king_list = [] for grid in board.Grid.grid_list: grid.reset_play_interaction_vars() + Switch_Modes_Controller.replayed_game(False, self) # Reset Moves Panel MoveNumberRectangle.rectangle_list = [] PieceMoveRectangle.rectangle_list = [] @@ -889,7 +1025,7 @@ def select_piece_unselect_all_others(mousepos, game_controller): for piece_list in play_objects.Piece_Lists_Shortcut.white_pieces(): for piece in piece_list: # Selects piece - if (piece.rect.collidepoint(mousepos) and piece.select == False): + if (piece.rect.collidepoint(mousepos) and piece.select == False and Switch_Modes_Controller.REPLAYED == False): clicked_piece = piece else: # Unselects piece @@ -900,7 +1036,7 @@ def select_piece_unselect_all_others(mousepos, game_controller): elif game_controller.WHOSETURN == "black": for piece_list in play_objects.Piece_Lists_Shortcut.black_pieces(): for piece in piece_list: - if (piece.rect.collidepoint(mousepos) and piece.select == False): + if (piece.rect.collidepoint(mousepos) and piece.select == False and Switch_Modes_Controller.REPLAYED == False): clicked_piece = piece else: piece.no_highlight() @@ -912,6 +1048,7 @@ def select_piece_unselect_all_others(mousepos, game_controller): clicked_piece.spaces_available(game_controller) clicked_piece = None def undo_move(game_controller): + Switch_Modes_Controller.replayed_game(False, game_controller) pieces_to_undo = [] # Using pieces_to_undo as a list for castling if Move_Tracker.move_counter() >= 1: @@ -982,11 +1119,12 @@ def undo_move(game_controller): Move_Tracker.undo_move_in_dfs("black") game_controller.switch_turn("black") Grid_Controller.update_prior_move_color("black") + print("TESTING123") + #%% Trying to resolve issue where we undo move into check Move_Controller.game_status_check(game_controller) log.info("Back to (" + str(len(Move_Tracker.df_moves)) + ".) " + "Black undo turn " + str(piece_to_undo) + " going back to " + str(piece_to_undo.coordinate)) elif game_controller.WHOSETURN == "black": for piece_to_undo in pieces_to_undo: - #print("PIECES TO UNDO " + str(piece_to_undo) + " LIST " + str(piece_to_undo.coordinate_history)) piece_to_undo.coordinate = piece_to_undo.coordinate_history[Move_Tracker.move_counter()]['before'] piece_to_undo.rect.topleft = board.Grid.grid_dict[piece_to_undo.coordinate].rect.topleft del piece_to_undo.coordinate_history[Move_Tracker.move_counter()] @@ -1029,7 +1167,9 @@ def make_move(grid, piece, game_controller): prior_moves_dict = {} # Update df_moves dictionary with a new record for the new move (when white's turn) if piece.color == "white": - Move_Tracker.df_moves.loc[Move_Tracker.move_counter()+1] = ["", ""] + next_move = Move_Tracker.move_counter()+1 + Move_Tracker.df_moves.loc[next_move] = ["", ""] + Move_Tracker.df_prior_moves.loc[next_move] = ["", ""] # Taking a piece by checking if available grid is opposite color of piece # And iterating through all pieces to check if coordinates of that grid # are the same as any of the pieces @@ -1284,6 +1424,7 @@ def record_move(game_controller, grid, piece, prior_moves_dict, captured_abb, sp prior_moves_dict['move_notation'] = Move_Controller.move_translator(grid.occupied_piece, piece_in_funcs, captured_abb, special_abb, check_abb) Move_Tracker.selected_move = (Move_Tracker.move_counter(), "white_move") Move_Tracker.df_prior_moves.loc[Move_Tracker.move_counter(), "white_move"] = str(prior_moves_dict) + Switch_Modes_Controller.replayed_game(False, game_controller) log.info(move_text) if game_controller.result_abb != "*": log.info(game_controller.result_abb) @@ -1444,6 +1585,14 @@ def mouse_coordinate(mousepos): for piece_move_rect in PieceMoveRectangle.rectangle_list: if piece_move_rect.rect.collidepoint(MOUSEPOS) and piece_move_rect.text_is_visible: Move_Tracker.selected_move = (piece_move_rect.move_number, piece_move_rect.move_color) + if Move_Tracker.selected_move[0] == len(Move_Tracker.df_moves): + if Move_Tracker.df_moves.loc[len(Move_Tracker.df_moves), "black_move"] != "" \ + and piece_move_rect.move_color == "white_move": + Switch_Modes_Controller.replayed_game(True, game_controller) + else: + Switch_Modes_Controller.replayed_game(False, game_controller) + else: + Switch_Modes_Controller.replayed_game(True, game_controller) # Editing mode only if Switch_Modes_Controller.GAME_MODE == Switch_Modes_Controller.EDIT_MODE: #BUTTONS @@ -1537,6 +1686,7 @@ def update_pieces_and_board(): # MIDDLE MOUSE DEBUGGER if event.type == pygame.MOUSEBUTTONDOWN and pygame.mouse.get_pressed()[1]: + #%% Middle mouse debugger def test_piece(): for piece_list in play_objects.Piece_Lists_Shortcut.all_pieces(): for piece in piece_list: @@ -1582,8 +1732,12 @@ def test_grid_str(): placed_objects.PLACED_SPRITES.draw(SCREEN) elif(Switch_Modes_Controller.GAME_MODE == Switch_Modes_Controller.PLAY_MODE): #Only draw play sprites in play mode FLIP_BOARD_BUTTON.draw(SCREEN) - play_objects.PLAY_SPRITES.update() - play_objects.PLAY_SPRITES.draw(SCREEN) + if Switch_Modes_Controller.REPLAYED == False: + play_objects.PLAY_SPRITES.update() + play_objects.PLAY_SPRITES.draw(SCREEN) + else: + replayed_objects.REPLAYED_SPRITES.update() + replayed_objects.REPLAYED_SPRITES.draw(SCREEN) PGN_SAVE_FILE_BUTTON.draw(SCREEN) PLAY_PANEL_SPRITES.draw(SCREEN) @@ -1644,7 +1798,7 @@ def test_grid_str(): if debug_message == 1: log.info("Entering debug mode") debug_message = 0 - # USE BREAKPOINT HERE + #%% Testing (space) print(str(Move_Tracker.selected_move)) #print(str(Move_Tracker.df_moves)) log.info("Use breakpoint here") diff --git a/PGN_Sample_Games/list_index_out_of_range_Bc4ThenUndo.pgn b/PGN_Sample_Games/list_index_out_of_range_Bc4ThenUndo.pgn new file mode 100644 index 0000000..c1e4398 --- /dev/null +++ b/PGN_Sample_Games/list_index_out_of_range_Bc4ThenUndo.pgn @@ -0,0 +1,13 @@ +[Event ""] +[Site ""] +[Date ""] +[Round ""] +[White ""] +[Black ""] +[Result "*"] +[ECO ""] +[TimeControl "0"] +[WhiteElo ""] +[BlackElo ""] + +1. e4 e5 2. Nf3 Nf6 3. Nxe5 Nxe4 4. Qe2 Nf6 5. Nc6 Qe7 6. Nxe7 Bxe7 7. Nc3 h6 8. d4 Nh5 9. Bf4 O-O 10. h3 Nxf4 11. Qe3 Nd5 12. Nxd5 Re8 13. O-O-O Bf6 14. Qxe8 Kh7 15. Qe4 Kh8 * \ No newline at end of file diff --git a/placed_objects.py b/placed_objects.py index b027f83..beddf8b 100644 --- a/placed_objects.py +++ b/placed_objects.py @@ -42,14 +42,14 @@ def remove_all_placed(): class PlacedPawn(pygame.sprite.Sprite): white_pawn_list = [] black_pawn_list = [] - def __init__(self, coord, col): + def __init__(self, coord, color): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_PAWN"] PLACED_SPRITES.add(self) PlacedPawn.white_pawn_list.append(self) - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_PAWN"] PLACED_SPRITES.add(self) PlacedPawn.black_pawn_list.append(self) @@ -61,23 +61,23 @@ def __init__(self, coord, col): def update(self): self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft def destroy(self): - if self.col == "white": + if self.color == "white": PlacedPawn.white_pawn_list.remove(self) - elif self.col == "black": + elif self.color == "black": PlacedPawn.black_pawn_list.remove(self) self.kill() class PlacedBishop(pygame.sprite.Sprite): white_bishop_list = [] black_bishop_list = [] - def __init__(self, coord, col): + def __init__(self, coord, color): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_BISHOP"] PLACED_SPRITES.add(self) PlacedBishop.white_bishop_list.append(self) - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_BISHOP"] PLACED_SPRITES.add(self) PlacedBishop.black_bishop_list.append(self) @@ -89,23 +89,23 @@ def __init__(self, coord, col): def update(self): self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft def destroy(self): - if self.col == "white": + if self.color == "white": PlacedBishop.white_bishop_list.remove(self) - elif self.col == "black": + elif self.color == "black": PlacedBishop.black_bishop_list.remove(self) self.kill() class PlacedKnight(pygame.sprite.Sprite): white_knight_list = [] black_knight_list = [] - def __init__(self, coord, col): + def __init__(self, coord, color): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_KNIGHT"] PLACED_SPRITES.add(self) PlacedKnight.white_knight_list.append(self) - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_KNIGHT"] PLACED_SPRITES.add(self) PlacedKnight.black_knight_list.append(self) @@ -117,23 +117,23 @@ def __init__(self, coord, col): def update(self): self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft def destroy(self): - if self.col == "white": + if self.color == "white": PlacedKnight.white_knight_list.remove(self) - elif self.col == "black": + elif self.color == "black": PlacedKnight.black_knight_list.remove(self) self.kill() class PlacedRook(pygame.sprite.Sprite): white_rook_list = [] black_rook_list = [] - def __init__(self, coord, col): + def __init__(self, coord, color): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_ROOK"] PLACED_SPRITES.add(self) PlacedRook.white_rook_list.append(self) - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_ROOK"] PLACED_SPRITES.add(self) PlacedRook.black_rook_list.append(self) @@ -145,23 +145,23 @@ def __init__(self, coord, col): def update(self): self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft def destroy(self): - if self.col == "white": + if self.color == "white": PlacedRook.white_rook_list.remove(self) - elif self.col == "black": + elif self.color == "black": PlacedRook.black_rook_list.remove(self) self.kill() class PlacedQueen(pygame.sprite.Sprite): white_queen_list = [] black_queen_list = [] - def __init__(self, coord, col): + def __init__(self, coord, color): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_QUEEN"] PLACED_SPRITES.add(self) PlacedQueen.white_queen_list.append(self) - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_QUEEN"] PLACED_SPRITES.add(self) PlacedQueen.black_queen_list.append(self) @@ -173,23 +173,23 @@ def __init__(self, coord, col): def update(self): self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft def destroy(self): - if self.col == "white": + if self.color == "white": PlacedQueen.white_queen_list.remove(self) - elif self.col == "black": + elif self.color == "black": PlacedQueen.black_queen_list.remove(self) self.kill() class PlacedKing(pygame.sprite.Sprite): white_king_list = [] black_king_list = [] - def __init__(self, coord, col): + def __init__(self, coord, color): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_KING"] PLACED_SPRITES.add(self) PlacedKing.white_king_list.append(self) - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_KING"] PLACED_SPRITES.add(self) PlacedKing.black_king_list.append(self) @@ -201,8 +201,8 @@ def __init__(self, coord, col): def update(self): self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft def destroy(self): - if self.col == "white": + if self.color == "white": PlacedKing.white_king_list.remove(self) - elif self.col == "black": + elif self.color == "black": PlacedKing.black_king_list.remove(self) self.kill() \ No newline at end of file diff --git a/play_objects.py b/play_objects.py index e8754fe..1ca276a 100644 --- a/play_objects.py +++ b/play_objects.py @@ -6,20 +6,20 @@ class Piece_Lists_Shortcut(): def all_pieces(): - return [PlayPawn.white_pawn_list, PlayBishop.white_bishop_list, + return [PlayKing.black_king_list, PlayKing.white_king_list, + PlayPawn.white_pawn_list, PlayBishop.white_bishop_list, PlayKnight.white_knight_list, PlayRook.white_rook_list, - PlayQueen.white_queen_list, PlayKing.white_king_list, - PlayPawn.black_pawn_list, PlayBishop.black_bishop_list, - PlayKnight.black_knight_list, PlayRook.black_rook_list, - PlayQueen.black_queen_list, PlayKing.black_king_list] + PlayQueen.white_queen_list, PlayPawn.black_pawn_list, + PlayBishop.black_bishop_list, PlayKnight.black_knight_list, + PlayRook.black_rook_list, PlayQueen.black_queen_list] def white_pieces(): - return [PlayPawn.white_pawn_list, PlayBishop.white_bishop_list, - PlayKnight.white_knight_list, PlayRook.white_rook_list, - PlayQueen.white_queen_list, PlayKing.white_king_list] + return [PlayKing.white_king_list, PlayPawn.white_pawn_list, + PlayBishop.white_bishop_list, PlayKnight.white_knight_list, + PlayRook.white_rook_list, PlayQueen.white_queen_list] def black_pieces(): - return [PlayPawn.black_pawn_list, PlayBishop.black_bishop_list, - PlayKnight.black_knight_list, PlayRook.black_rook_list, - PlayQueen.black_queen_list, PlayKing.black_king_list] + return [PlayKing.black_king_list, PlayPawn.black_pawn_list, + PlayBishop.black_bishop_list, PlayKnight.black_knight_list, + PlayRook.black_rook_list, PlayQueen.black_queen_list] class ChessPiece: def __init__(self, coord, image, col): @@ -343,22 +343,26 @@ def bishop_direction_spaces_available(bishop, game_controller, x, y): grid.highlight(bishop.color, bishop.coordinate) # If current king is in check elif game_controller.color_in_check == bishop.color: + # Disable piece if it is pinned and checked from another enemy piece - if bishop.pinned == True: - bishop.disable = True - return - # Block path of enemy bishop, rook, or queen - # You cannot have multiple spaces in one direction when blocking so return - elif grid.coordinate in game_controller.check_attacking_coordinates[:-1] \ - and (game_controller.attacker_piece == "bishop" or game_controller.attacker_piece == "rook" \ - or game_controller.attacker_piece == "queen"): - grid.highlight(bishop.color, bishop.coordinate) - return - # The only grid available is the attacker piece when pawn or knight - elif grid.coordinate == game_controller.check_attacking_coordinates[0] \ - and (game_controller.attacker_piece == "pawn" or game_controller.attacker_piece == "knight"): - grid.highlight(bishop.color, bishop.coordinate) - return + try: + if bishop.pinned == True: + bishop.disable = True + return + # Block path of enemy bishop, rook, or queen + # You cannot have multiple spaces in one direction when blocking so return + elif grid.coordinate in game_controller.check_attacking_coordinates[:-1] \ + and (game_controller.attacker_piece == "bishop" or game_controller.attacker_piece == "rook" \ + or game_controller.attacker_piece == "queen"): + grid.highlight(bishop.color, bishop.coordinate) + return + # The only grid available is the attacker piece when pawn or knight + elif grid.coordinate == game_controller.check_attacking_coordinates[0] \ + and (game_controller.attacker_piece == "pawn" or game_controller.attacker_piece == "knight"): + grid.highlight(bishop.color, bishop.coordinate) + return + except: + print("BISHOP COORD " + str(bishop.coordinate)) # If pinned and the grid is within the attacking coordinates restraint # Includes grid.coordinate != self.coordinate so that staying at same coordinate doesn't count as move elif(bishop.pinned == True and grid.coordinate in bishop.pin_attacking_coordinates \ diff --git a/replayed_objects.py b/replayed_objects.py new file mode 100644 index 0000000..d9ca6df --- /dev/null +++ b/replayed_objects.py @@ -0,0 +1,332 @@ +import pygame +from load_images_sounds import * +import board + +REPLAYED_SPRITES = pygame.sprite.Group() + +def remove_all_replayed(): + for spr_list in [ReplayedPawn.white_pawn_list, ReplayedBishop.white_bishop_list, + ReplayedKnight.white_knight_list, ReplayedRook.white_rook_list, + ReplayedQueen.white_queen_list, ReplayedKing.white_king_list, + ReplayedPawn.black_pawn_list, ReplayedBishop.black_bishop_list, + ReplayedKnight.black_knight_list, ReplayedRook.black_rook_list, + ReplayedQueen.black_queen_list, ReplayedKing.black_king_list]: + for obj in spr_list: + obj.kill() + ReplayedPawn.white_pawn_list = [] + ReplayedBishop.white_bishop_list = [] + ReplayedKnight.white_knight_list = [] + ReplayedRook.white_rook_list = [] + ReplayedQueen.white_queen_list = [] + ReplayedKing.white_king_list = [] + ReplayedPawn.black_pawn_list = [] + ReplayedBishop.black_bishop_list = [] + ReplayedKnight.black_knight_list = [] + ReplayedRook.black_rook_list = [] + ReplayedQueen.black_queen_list = [] + ReplayedKing.black_king_list = [] + +class Piece_Lists_Shortcut(): + def all_pieces(): + return [ReplayedPawn.white_pawn_list, ReplayedBishop.white_bishop_list, + ReplayedKnight.white_knight_list, ReplayedRook.white_rook_list, + ReplayedQueen.white_queen_list, ReplayedKing.white_king_list, + ReplayedPawn.black_pawn_list, ReplayedBishop.black_bishop_list, + ReplayedKnight.black_knight_list, ReplayedRook.black_rook_list, + ReplayedQueen.black_queen_list, ReplayedKing.black_king_list] + def white_pieces(): + return [ReplayedPawn.white_pawn_list, ReplayedBishop.white_bishop_list, + ReplayedKnight.white_knight_list, ReplayedRook.white_rook_list, + ReplayedQueen.white_queen_list, ReplayedKing.white_king_list] + def black_pieces(): + return [ReplayedPawn.black_pawn_list, ReplayedBishop.black_bishop_list, + ReplayedKnight.black_knight_list, ReplayedRook.black_rook_list, + ReplayedQueen.black_queen_list, ReplayedKing.black_king_list] + +class ReplayedPawn(pygame.sprite.Sprite): + white_pawn_list = [] + black_pawn_list = [] + def __init__(self, color, coordinate_history, coord=None, captured_move_number_and_coordinate=None, out_of_bounds_x_y=None): + pygame.sprite.Sprite.__init__(self) + self.color = color + if self.color == "white": + self.image = IMAGES["SPR_WHITE_PAWN"] + REPLAYED_SPRITES.add(self) + ReplayedPawn.white_pawn_list.append(self) + elif self.color == "black": + self.image = IMAGES["SPR_BLACK_PAWN"] + REPLAYED_SPRITES.add(self) + ReplayedPawn.black_pawn_list.append(self) + self.coordinate = coord + self.coordinate_history = coordinate_history + self.rect = self.image.get_rect() + if self.coordinate is not None: + for grid in board.Grid.grid_list: + if grid.coordinate == self.coordinate: + self.rect.topleft = grid.rect.topleft + else: + self.rect.topleft = out_of_bounds_x_y + self.prior_move_color = False + self.taken_off_board = False + self.captured_move_number_and_coordinate = captured_move_number_and_coordinate + def update(self): + if self.coordinate is not None: + self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft + def destroy(self): + if self.color == "white": + ReplayedPawn.white_pawn_list.remove(self) + elif self.color == "black": + ReplayedPawn.black_pawn_list.remove(self) + self.kill() + def prior_move_update(self): + if self.taken_off_board != True: + if(self.color == "white"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_WHITE_PAWN_PRIORMOVE"] + else: + self.image = IMAGES["SPR_WHITE_PAWN"] + elif(self.color == "black"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_BLACK_PAWN_PRIORMOVE"] + else: + self.image = IMAGES["SPR_BLACK_PAWN"] + +class ReplayedBishop(pygame.sprite.Sprite): + white_bishop_list = [] + black_bishop_list = [] + def __init__(self, color, coordinate_history, coord=None, captured_move_number_and_coordinate=None, out_of_bounds_x_y=None): + pygame.sprite.Sprite.__init__(self) + self.color = color + if self.color == "white": + self.image = IMAGES["SPR_WHITE_BISHOP"] + REPLAYED_SPRITES.add(self) + ReplayedBishop.white_bishop_list.append(self) + elif self.color == "black": + self.image = IMAGES["SPR_BLACK_BISHOP"] + REPLAYED_SPRITES.add(self) + ReplayedBishop.black_bishop_list.append(self) + self.coordinate = coord + self.coordinate_history = coordinate_history + self.rect = self.image.get_rect() + if self.coordinate is not None: + for grid in board.Grid.grid_list: + if grid.coordinate == self.coordinate: + self.rect.topleft = grid.rect.topleft + else: + self.rect.topleft = out_of_bounds_x_y + self.prior_move_color = False + self.taken_off_board = False + self.captured_move_number_and_coordinate = captured_move_number_and_coordinate + def update(self): + if self.coordinate is not None: + self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft + def destroy(self): + if self.color == "white": + ReplayedBishop.white_bishop_list.remove(self) + elif self.color == "black": + ReplayedBishop.black_bishop_list.remove(self) + self.kill() + def prior_move_update(self): + if self.taken_off_board != True: + if(self.color == "white"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_WHITE_BISHOP_PRIORMOVE"] + else: + self.image = IMAGES["SPR_WHITE_BISHOP"] + elif(self.color == "black"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_BLACK_BISHOP_PRIORMOVE"] + else: + self.image = IMAGES["SPR_BLACK_BISHOP"] + +class ReplayedKnight(pygame.sprite.Sprite): + white_knight_list = [] + black_knight_list = [] + def __init__(self, color, coordinate_history, coord=None, captured_move_number_and_coordinate=None, out_of_bounds_x_y=None): + pygame.sprite.Sprite.__init__(self) + self.color = color + if self.color == "white": + self.image = IMAGES["SPR_WHITE_KNIGHT"] + REPLAYED_SPRITES.add(self) + ReplayedKnight.white_knight_list.append(self) + elif self.color == "black": + self.image = IMAGES["SPR_BLACK_KNIGHT"] + REPLAYED_SPRITES.add(self) + ReplayedKnight.black_knight_list.append(self) + self.coordinate = coord + self.coordinate_history = coordinate_history + self.rect = self.image.get_rect() + if self.coordinate is not None: + for grid in board.Grid.grid_list: + if grid.coordinate == self.coordinate: + self.rect.topleft = grid.rect.topleft + else: + self.rect.topleft = out_of_bounds_x_y + self.prior_move_color = False + self.taken_off_board = False + self.captured_move_number_and_coordinate = captured_move_number_and_coordinate + def update(self): + if self.coordinate is not None: + self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft + def destroy(self): + if self.color == "white": + ReplayedKnight.white_knight_list.remove(self) + elif self.color == "black": + ReplayedKnight.black_knight_list.remove(self) + self.kill() + def prior_move_update(self): + if self.taken_off_board != True: + if(self.color == "white"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_WHITE_KNIGHT_PRIORMOVE"] + else: + self.image = IMAGES["SPR_WHITE_KNIGHT"] + elif(self.color == "black"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_BLACK_KNIGHT_PRIORMOVE"] + else: + self.image = IMAGES["SPR_BLACK_KNIGHT"] + +class ReplayedRook(pygame.sprite.Sprite): + white_rook_list = [] + black_rook_list = [] + def __init__(self, color, coordinate_history, coord=None, captured_move_number_and_coordinate=None, out_of_bounds_x_y=None): + pygame.sprite.Sprite.__init__(self) + self.color = color + if self.color == "white": + self.image = IMAGES["SPR_WHITE_ROOK"] + REPLAYED_SPRITES.add(self) + ReplayedRook.white_rook_list.append(self) + elif self.color == "black": + self.image = IMAGES["SPR_BLACK_ROOK"] + REPLAYED_SPRITES.add(self) + ReplayedRook.black_rook_list.append(self) + self.coordinate = coord + self.coordinate_history = coordinate_history + self.rect = self.image.get_rect() + if self.coordinate is not None: + for grid in board.Grid.grid_list: + if grid.coordinate == self.coordinate: + self.rect.topleft = grid.rect.topleft + else: + self.rect.topleft = out_of_bounds_x_y + self.prior_move_color = False + self.taken_off_board = False + self.captured_move_number_and_coordinate = captured_move_number_and_coordinate + def update(self): + if self.coordinate is not None: + self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft + def destroy(self): + if self.color == "white": + ReplayedRook.white_rook_list.remove(self) + elif self.color == "black": + ReplayedRook.black_rook_list.remove(self) + self.kill() + def prior_move_update(self): + if self.taken_off_board != True: + if(self.color == "white"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_WHITE_ROOK_PRIORMOVE"] + else: + self.image = IMAGES["SPR_WHITE_ROOK"] + elif(self.color == "black"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_BLACK_ROOK_PRIORMOVE"] + else: + self.image = IMAGES["SPR_BLACK_ROOK"] + +class ReplayedQueen(pygame.sprite.Sprite): + white_queen_list = [] + black_queen_list = [] + def __init__(self, color, coordinate_history, coord=None, captured_move_number_and_coordinate=None, out_of_bounds_x_y=None): + pygame.sprite.Sprite.__init__(self) + self.color = color + if self.color == "white": + self.image = IMAGES["SPR_WHITE_QUEEN"] + REPLAYED_SPRITES.add(self) + ReplayedQueen.white_queen_list.append(self) + elif self.color == "black": + self.image = IMAGES["SPR_BLACK_QUEEN"] + REPLAYED_SPRITES.add(self) + ReplayedQueen.black_queen_list.append(self) + self.coordinate = coord + self.coordinate_history = coordinate_history + self.rect = self.image.get_rect() + if self.coordinate is not None: + for grid in board.Grid.grid_list: + if grid.coordinate == self.coordinate: + self.rect.topleft = grid.rect.topleft + else: + self.rect.topleft = out_of_bounds_x_y + self.prior_move_color = False + self.taken_off_board = False + self.captured_move_number_and_coordinate = captured_move_number_and_coordinate + def update(self): + if self.coordinate is not None: + self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft + def destroy(self): + if self.color == "white": + ReplayedQueen.white_queen_list.remove(self) + elif self.color == "black": + ReplayedQueen.black_queen_list.remove(self) + self.kill() + def prior_move_update(self): + if self.taken_off_board != True: + if(self.color == "white"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_WHITE_QUEEN_PRIORMOVE"] + else: + self.image = IMAGES["SPR_WHITE_QUEEN"] + elif(self.color == "black"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_BLACK_QUEEN_PRIORMOVE"] + else: + self.image = IMAGES["SPR_BLACK_QUEEN"] + +class ReplayedKing(pygame.sprite.Sprite): + white_king_list = [] + black_king_list = [] + def __init__(self, color, coordinate_history, coord=None, captured_move_number_and_coordinate=None, out_of_bounds_x_y=None): + pygame.sprite.Sprite.__init__(self) + self.color = color + if self.color == "white": + self.image = IMAGES["SPR_WHITE_KING"] + REPLAYED_SPRITES.add(self) + ReplayedKing.white_king_list.append(self) + elif self.color == "black": + self.image = IMAGES["SPR_BLACK_KING"] + REPLAYED_SPRITES.add(self) + ReplayedKing.black_king_list.append(self) + self.coordinate = coord + self.coordinate_history = coordinate_history + self.rect = self.image.get_rect() + if self.coordinate is not None: + for grid in board.Grid.grid_list: + if grid.coordinate == self.coordinate: + self.rect.topleft = grid.rect.topleft + else: + self.rect.topleft = out_of_bounds_x_y + self.prior_move_color = False + self.taken_off_board = False + self.captured_move_number_and_coordinate = captured_move_number_and_coordinate + def update(self): + if self.coordinate is not None: + self.rect.topleft = board.Grid.grid_dict[self.coordinate].rect.topleft + def destroy(self): + if self.color == "white": + ReplayedKing.white_king_list.remove(self) + elif self.color == "black": + ReplayedKing.black_king_list.remove(self) + self.kill() + def prior_move_update(self): + if self.taken_off_board != True: + if(self.color == "white"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_WHITE_KING_PRIORMOVE"] + else: + self.image = IMAGES["SPR_WHITE_KING"] + elif(self.color == "black"): + if(self.prior_move_color == True): + self.image = IMAGES["SPR_BLACK_KING_PRIORMOVE"] + else: + self.image = IMAGES["SPR_BLACK_KING"] \ No newline at end of file diff --git a/start_objects.py b/start_objects.py index 8635aab..3655820 100644 --- a/start_objects.py +++ b/start_objects.py @@ -32,12 +32,12 @@ def draw(self, screen): StartPiecesBehind(IMAGES["SPR_BLACK_KING"], initvar.STARTPOS['black_king']) class StartPawn(pygame.sprite.Sprite): - def __init__(self, col, pos): + def __init__(self, color, pos): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_PAWN"] - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_PAWN"] self.rect = self.image.get_rect() self.rect.topleft = pos @@ -46,12 +46,12 @@ def update(self): pass class StartBishop(pygame.sprite.Sprite): - def __init__(self, col, pos): + def __init__(self, color, pos): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_BISHOP"] - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_BISHOP"] self.rect = self.image.get_rect() self.rect.topleft = pos @@ -60,12 +60,12 @@ def update(self): pass class StartKnight(pygame.sprite.Sprite): - def __init__(self, col, pos): + def __init__(self, color, pos): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_KNIGHT"] - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_KNIGHT"] self.rect = self.image.get_rect() self.rect.topleft = pos @@ -74,12 +74,12 @@ def update(self): pass class StartRook(pygame.sprite.Sprite): - def __init__(self, col, pos): + def __init__(self, color, pos): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_ROOK"] - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_ROOK"] self.rect = self.image.get_rect() self.rect.topleft = pos @@ -88,12 +88,12 @@ def update(self): pass class StartQueen(pygame.sprite.Sprite): - def __init__(self, col, pos): + def __init__(self, color, pos): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_QUEEN"] - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_QUEEN"] self.rect = self.image.get_rect() self.rect.topleft = pos @@ -102,12 +102,12 @@ def update(self): pass class StartKing(pygame.sprite.Sprite): - def __init__(self, col, pos): + def __init__(self, color, pos): pygame.sprite.Sprite.__init__(self) - self.col = col - if self.col == "white": + self.color = color + if self.color == "white": self.image = IMAGES["SPR_WHITE_KING"] - elif self.col == "black": + elif self.color == "black": self.image = IMAGES["SPR_BLACK_KING"] self.rect = self.image.get_rect() self.rect.topleft = pos