示例#1
0
def get_best_score(board):
    """
    Recursive helper function for minimax that returns the best score by player
    """
    # Base case, return the result of the board
    if terminal(board):
        return utility(board)
    else:
        current_player = player(board)
        empty_positions = get_positions_of_value(board, EMPTY)
        if current_player == X:
            # Initialize best score with lowest possible number
            best_score = float("-inf")
            # Check each available move on the board
            for pos in empty_positions:
                board_result = result(board, pos)
                # Get result of that move
                score = get_best_score(board_result)
                # Check against existing best score and get max for X player
                best_score = max(best_score, score)
            return best_score
        elif current_player == O:
            # Initialize best score with highest possible number
            best_score = float("inf")
            # Check each available move on the board
            for pos in empty_positions:
                board_result = result(board, pos)
                # Get result of that move
                score = get_best_score(board_result)
                # Check against existing best score and get min for O player
                best_score = min(best_score, score)
            return best_score
        else:
            raise ValueError('Player must be X or O.')
示例#2
0
def actions(board):
    """
    Returns set of all possible actions (i, j) available on the board.
    """
    if terminal(board):
        return None
    else:
        empty_positions = get_positions_of_value(board, EMPTY)
        return empty_positions
示例#3
0
def winner(board):
    """
    Returns the winner of the game, if there is one.
    """
    player = None
    # Get positions of two players
    x_positions = get_positions_of_value(board, X)
    o_positions = get_positions_of_value(board, O)
    # Get all sets of winning positions
    winning_positions = get_winning_position_sets()
    # Compare them with positions occupied by each player
    for win_set in winning_positions:
        if win_set.issubset(x_positions):
            player = X
            break
        elif win_set.issubset(o_positions):
            player = O
            break
    return player
示例#4
0
def terminal(board):
    """
    Returns True if game is over, False otherwise.
    """
    empty_positions = get_positions_of_value(board, EMPTY)
    # If the board is full, the game is over
    if not empty_positions:
        game_over = True
    # If either player has won, the game is over
    elif utility(board) in [-1, 1]:
        game_over = True
    else:
        game_over = False
    return game_over
示例#5
0
def result(board, action):
    """
    Returns the board that results from making move (i, j) on the board.
    """
    empty_positions = get_positions_of_value(board, EMPTY)
    if action not in empty_positions:
        raise ValueError('This move is illegal.')
    # Make deep copy of board to prevent direct mutation
    board_copy = deepcopy(board)
    current_player = player(board_copy)
    row, col = action
    # Take the action on the copy of the board
    board_copy[row][col] = current_player
    return board_copy
示例#6
0
def minimax(board):
    """
    Returns the optimal action for the current player on the board.
    """
    if terminal(board):
        return None
    else:
        best_action = None
        current_player = player(board)
        empty_positions = get_positions_of_value(board, EMPTY)
        if current_player == X:
            # Initialize best score with lowest possible number
            best_score = float("-inf")
            # Check each available move on the board
            for pos in empty_positions:
                board_result = result(board, pos)
                # Get result of that move
                score = get_best_score(board_result)
                # Check against existing best score
                # X player wants a higher score
                if (score > best_score):
                    best_score = score
                    best_action = pos
                # Naive pruning
                if best_score == 1:
                    break
            return best_action
        elif current_player == O:
            best_action = None
            # Initialize best score with highest possible number
            best_score = float("inf")
            # Check each available move on the board
            for pos in empty_positions:
                board_result = result(board, pos)
                # Get result of that move
                score = get_best_score(board_result)
                # Check against existing best score
                # O player wants a lower score
                if (score < best_score):
                    best_score = score
                    best_action = pos
                # Naive pruning
                if best_score == -1:
                    break
            return best_action
        else:
            raise ValueError('Player must be X or O.')