def check_corners(game: ReversiGame) -> tuple[int, int]: """Return a tuple representing the number of corner taken by each side :param game: the game state to be checked :return: (corner taken by black, corner taken by white) """ board = game.get_game_board() corner_black, corner_white = 0, 0 for i in [0, game.get_size() - 1]: for j in [0, game.get_size() - 1]: if board[i][j] == BLACK: corner_black += 1 elif board[i][j] == WHITE: corner_white += 1 return corner_black, corner_white
def _value_eval(self, game: ReversiGame, piece: str) -> Union[float, int]: """The evaluation function for minimax. For Positional Player, the evaluation function will evaluate the positional advantage of the pieces on the board. Preconditions: - piece in {BLACK, WHITE} :param game: the current game state for evaluation :return: value evaluated from the current game state """ if game.get_winner() is not None: if game.get_winner() == piece: # win return math.inf elif game.get_winner() == 'Draw': # draw return 0 else: # lose return -math.inf else: num_black, num_white = game.get_num_pieces( )[BLACK], game.get_num_pieces()[WHITE] corner_black, corner_white = check_corners(game) board_filled = (num_black + num_white) / (game.get_size()**2) if piece == BLACK: if board_filled < 0.80: # early to middle game return 10 * (corner_black - corner_white) + len( game.get_valid_moves()) else: # end game return num_black / num_white else: if board_filled < 0.80: # early to middle game return 10 * (corner_white - corner_black) + len( game.get_valid_moves()) else: # end game return num_white / num_black
def positional_early(game: ReversiGame, selected_board_weight: list, player: str) -> Union[float, int]: """Evaluates a board based on the positional advantage of black Preconditions: player in {BLACK, WHITE} """ if player == BLACK: opponent = WHITE else: opponent = BLACK eval_so_far = 0 board = game.get_game_board() for i in range(game.get_size() - 1): for j in range(game.get_size() - 1): if board[i][j] == player: eval_so_far += selected_board_weight[i][j] elif board[i][j] == opponent: eval_so_far -= selected_board_weight[i][j] return eval_so_far
def _value_eval(self, game: ReversiGame, piece: str) -> Union[float, int]: """The evaluation function for minimax. For Positional Player, the evaluation function will evaluate the positional advantage of the pieces on the board. Preconditions: - piece in {BLACK, WHITE} :param game: the current game state for evaluation :return: value evaluated from the current game state """ if game.get_winner() is not None: if game.get_winner() == piece: # win return math.inf elif game.get_winner() == 'Draw': # draw return 0 else: # lose return -math.inf else: num_black, num_white = game.get_num_pieces( )[BLACK], game.get_num_pieces()[WHITE] board_filled = (num_black + num_white) / (game.get_size()**2) if game.get_size() == 8: selected_board_weight = BOARD_WEIGHT_8 else: selected_board_weight = BOARD_WEIGHT_6 if board_filled < 0.80: return positional_early(game, selected_board_weight, piece) else: if piece == BLACK: return num_black / num_white if piece == WHITE: return num_white / num_black return 0