Files
cis163/chess/chess_piece.py
cutsweettea bbd55f48a0 gooo
2025-10-29 10:36:33 -04:00

67 lines
3.3 KiB
Python

from player import Player
from move import Move
from typing import TypeVar
from abc import ABC, abstractmethod
ChessPieceT = TypeVar('ChessPieceT')
class ChessPiece(ABC):
def __init__(self, piece_color: Player):
self.player = piece_color
@property
def player(self):
return self.__player
@player.setter
def player(self, new_val):
if not isinstance(new_val, Player):
raise TypeError(f'new value for player is not of type Player')
self.__player = new_val
def __str__(self):
# im not making this abstract, attributes amongst each piece are the same, str repr is also dynamic for the class name
return f'[{self.__class__.__name__} player={self.player}]'
def is_valid_move(self, move: Move, board: list[list[ChessPieceT]]) -> bool:
if not isinstance(board, list):
raise TypeError(f'board must be a list')
for arr in board:
if not isinstance(arr, list):
raise TypeError(f'each element in the board list bust be another list')
for v in arr:
if not isinstance(v, ChessPiece) and v != None:
raise TypeError(f'each element in each row of the board must be of type ChessPiece or must be None')
# create variables for the board dimensions, original spot and destination spot
board_dim = len(board)
board_orig: ChessPiece | None = board[move.from_col][move.from_row]
board_dest: ChessPiece = board[move.to_col][move.to_row]
# check if move is within bounds by checking if y and x are within the board dimensions
move_col_valid = 0 <= move.to_col <= board_dim
move_row_valid = 0 <= move.to_row <= board_dim
within_bounds = move_col_valid and move_row_valid
# check if player is still at the original position they started at
different_position = move.from_col != move.to_col or move.from_row != move.to_row
# check if the current piece trying to be moved is in the same spot on the board
#print(f'{board_orig} => {self}')
#is_current_piece = board_orig is self
is_current_piece = True
# check if the destination is not empty, if so, do destination specific checks
is_piece_class = isinstance(board_dest, ChessPiece)
# setting all these values being checked within the conditional to true, cuz if they don't have to be ran, they should still be true to return the true result of all the booleans combined
not_taking_friendly_piece = True
if is_piece_class:
# determines whether an enemy piece is being taken
not_taking_friendly_piece = board_dest.player != self.player
print(f'within_bounds={within_bounds}, different_position={different_position}, is_current_piece={is_current_piece}, not_taking_friendly_piece={not_taking_friendly_piece}, ({within_bounds and different_position and is_current_piece and not_taking_friendly_piece})')
print(f'(other) is_piece_class={is_piece_class}, board_dim={board_dim}, move_col_valid={move_col_valid} ({move.from_col} -> {move.to_col}), move_row_valid={move_row_valid} ({move.from_row} -> {move.to_row})')
return within_bounds and different_position and is_current_piece and not_taking_friendly_piece