def minimax(board, depth, player, alpha=-np.inf, beta=np.inf, eval_func='pos_score', king_version=False): if depth == 0: if eval_func == 'pos_score': return pos_score_sum(board) elif eval_func == 'mobi': return mobility(board) elif eval_func == 'pos_mobi': return pos_plus_mobi(board) elif eval_func == 'king_pos_score': # this is for King Othello return king_pos_score_sum(board) if not king_version: game = Othello() else: game = KingOthello() game.board = board game.current_player = player possible_moves = game.find_all_valid_moves() if possible_moves: if player == BLACK: # maximizing player max_eval = -np.inf for move in possible_moves: game_copy = deepcopy(game) game_copy.take_move(move[0], move[1]) eval = minimax(game_copy.board, depth - 1, opposite(player), alpha, beta) max_eval = max(max_eval, eval) alpha = max(alpha, eval) if beta <= alpha: break return max_eval else: # WHITE, minimizing player min_eval = np.inf for move in possible_moves: game_copy = deepcopy(game) game_copy.take_move(move[0], move[1]) eval = minimax(game_copy.board, depth - 1, opposite(player), alpha, beta) min_eval = min(min_eval, eval) beta = min(beta, eval) if beta <= alpha: break return min_eval else: # no possible move for current player game.switch_turn() possible_moves = game.find_all_valid_moves( ) # check whether opponent has moves if possible_moves: return minimax(game.board, depth - 1, opposite(player), alpha, beta) # hand over to opponent, nothing changed else: # the opponent has no moves either, game over return pos_score_sum(game.board)
def mobility(board): # defined number of possible moves : black - white g1 = Othello() g1.board = board g1.current_player = BLACK score_black = len(g1.find_all_valid_moves()) g1.current_player = WHITE score_white = len(g1.find_all_valid_moves()) return score_black - score_white