from enum import Enum class Move: def __init__(self, from_row, from_col, to_row, to_col): self.from_row = from_row self.from_col = from_col self.to_row = to_row self.to_col = to_col def __str__(self): output = f'Move [from_row={self.from_row}, from_col={self.from_col}' output += f', to_row={self.to_row}, to_col={self.to_col}]' return output # kinda just guessing, but on prarielearn it only showed the file names included in the project and the # ones we need to create for the submission, i was gonna put all these in their own files, but now i'm # just putting it here because i dont wanna risk not being able to submit class PieceType: # piece type for each piece PAWN = 0 ROOK = 1 KING = 2 QUEEN = 3 KNIGHT = 4 BISHOP = 5 # check if something is a valid move set element ( (y, x) tuple ) def valid_move_set_element(move_set: tuple[int, int]) -> bool: # check if move set is a tuple if not isinstance(move_set, tuple): raise TypeError(f'each move set in move sets must be a tuple ({move_set})') # check if the length of the tuple is 2, because it needs to have a y and x ms_len = len(move_set) if ms_len != 2: raise ValueError(f'length of move set ({move_set}) is {ms_len}, must be 2 (y and x)') # check if each element is an int for i in range(ms_len): p = move_set[i] if not isinstance(p, int): raise TypeError(f'tuple element at index {i} ({p}) must be an int') return True # general move set list class for each piece type class MoveSets: def __init__(self, *move_sets: tuple[int, int]): # loop over indices of move_sets, checking if each element at index i is valid, exception thrown by valid_move_set if not for i in range(len(move_sets)): valid_move_set_element(move_sets[i]) # set all the stuff equal self.__move_sets = move_sets @property def move_sets(self): return self.__move_sets def is_valid_move(self, move: Move) -> bool: # is the move valid, i dunno raise NotImplementedError('u gotta implement me bruh') def valid_range(max: int) -> list[int]: return [-i if max < 0 else i for i in range(1, abs(max)+1)] # class for static move sets class StaticMoveSet(MoveSets): def is_valid_move(self, move: Move) -> bool: # get the difference between the to and from row / column from_to_row_diff = move.to_row - move.from_row from_to_col_diff = move.to_col - move.from_col # iterate over each move set, checking if it follows any of the move sets passed to the method for ms in self.move_sets: # checks if the difference in y and x is equal to any available options if from_to_col_diff == ms[0] and from_to_row_diff == ms[1]: return True return False # in these lists, the move sets are static, so the y and x are a set of combo's of ways to move """ pawn move sets are mostly static, but there will be an override for the is_valid_move method, checking to see if the pawn can move 1 up 1 left / right to take another enemy piece these values simulate these move sets, with x being the pawn, m being a possible static move, and p being possible moves (such as the case i explained) ########## # x # # pmp # # m # # # # # # m # # pmp # # x # ########## """ pawn_valid_move_sets = [(1, 0), (2, 0)] # in these lists, the move sets are dynamic, so the y and x are a range of times they can move on the x and y rook_valid_move_sets = [(0, 8), (8, 0), (0, -8), (-8, 0)] # class for dynamic move sets class DynamicMoveSet(MoveSets): def is_valid_move(self, move: Move) -> bool: from_to_row_diff = move.to_row - move.from_row from_to_col_diff = move.to_col - move.from_col # check if the to and from actually moved if from_to_row_diff == 0 and from_to_col_diff == 0: return False for ms in self.move_sets: possible_valid_row_moves, possible_valid_col_moves = [valid_range(mse) for mse in ms] # check if move in row is possible, only if there are valid moves for row movement if len(possible_valid_row_moves) > 0: if from_to_row_diff not in possible_valid_row_moves: continue else: # if theres no valid moves for rows, make sure theres no change in the from to row difference if from_to_row_diff != 0: continue # check if move in column is possible, only if there are valid moves for column movement if len(possible_valid_col_moves) > 0: if from_to_col_diff not in possible_valid_col_moves: continue else: # if theres no valid moves for columns, make sure theres no change in the from to column difference if from_to_col_diff != 0: continue return True return False # create move sets # static move sets pawn_move_sets = StaticMoveSet(*pawn_valid_move_sets) # dynamic move sets