首页 > 解决方案 > tic tac toe minimax 函数上的无效动作错误

问题描述

我正在尝试在cs50ai中为tic tac toe编写一个minimax算法,但我似乎无法理解它。我似乎无法理解如何从 maxval 和 minval 之间的递归中获取值。我的脚本如何找到游戏状态的值并将其与无限值进行比较,以及如何将该值与 for 循环检查的初始移动相关联?目前我的代码总是引发无效操作的异常。这让我觉得它一直在运行,直到板为空,然后尝试执行另一个操作。我已经做了很多阅读和查看不同的代码,但我不知道如何使这项工作。任何帮助和提示表示赞赏。

"""
Tic Tac Toe Player
"""

import math
import copy

X = "X"
O = "O"
EMPTY = None


def initial_state():
    """
    Returns starting state of the board.
    """
    return [[EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY]]


def player(board):
    """
    Returns player who has the next turn on a board.
    """
    if terminal(board):
        return None
    if board == initial_state():
        return X
    if checkturn(board) == X:
        return X
    elif checkturn(board) == O:
        return O

    #return turn
    #raise NotImplementedError


def actions(board):
    """
    Returns set of all possible actions (i, j) available on the board.
    """
    action_set = set()
    coord_x = 0
    coord_y = 0
    board_size = 3
    for row in board:
        for item in row:
            if item is None:
                action_set.add((coord_x, coord_y))

            coord_y += 1
            if coord_y == board_size:
                coord_y = 0
        coord_x += 1

    return action_set

    #raise NotImplementedError


def result(board, action):
    """
    Returns the board that results from making move (i, j) on the board.
    """
    # If the action is not in the action set raise an exception that the move is invalid
    #
    # DISCUSS THIS WITH HAMISH
    action_set = actions(board)
    # Make a copy of the previous boards to reference
    parentboard = copy.deepcopy(board)

    if parentboard[action[0]][action[1]] is not None:
        raise Exception("Invalid action")
    #Make a new updated board to return so we don't overwrite the old ones
    if action in action_set:
        newboard = board
        newboard[action[0]][action[1]] = player(board)
        return newboard


def winner(board):
    """
    Returns the winner of the game, if there is one.
    """
    row = [[board[0][0], board[0][1], board[0][2]],
           [board[1][0], board[1][1], board[1][2]],
           [board[2][0], board[2][1], board[2][2]]]

    col = [[board[0][0], board[1][0], board[2][0]],
           [board[0][1], board[1][1], board[2][1]],
           [board[0][2], board[1][2], board[2][2]]]
    diag = [[board[0][0], board[1][1], board[2][2]],
            [board[2][0], board[1][1], board[0][2]]]
    for item in row:
        win = check_xo(item)
        if win is not None:
            return win
    for item in col:
        check_xo(item)
        if win is not None:
            return win
    for item in diag:
        check_xo(item)
        if win is not None:
            return win



    #raise NotImplementedError


def terminal(board):
    """
    Returns True if game is over, False otherwise.
    """
    action_set = actions(board)
    # Check if the actionset is empty. IF so game is over(True)
    if len(action_set) == 0:
        return True
    # Check if someone has won the game. If so game is over (True).
    if winner(board) == X or winner(board) == O:
        return True
    else:
        return False

    #raise NotImplementedError


def utility(board):
    """
    Returns 1 if X has won the game, -1 if O has won, 0 otherwise.
    """
    if winner(board) == X:
        return 1
    elif winner(board) == O:
        return -1
    elif winner(board) is None:
        return 0
    #raise NotImplementedError


def minimax(board):
    """
    Returns the optimal action for the current player on the board.
    """
    #if terminal(board):
    #    return None
    if player(board) == X:
        v = -math.inf
        for action in actions(board):
            v = minval(result(board, action))
            if v > value:
                return action

    if player(board) == O:
        v = math.inf
        for action in actions(board):
            v = maxval(result(board, action))
            if v < value:
                return action



# My added functions start #
def maxval(board):
    if terminal(board):
        return utility(board)
    value = -math.inf
    for action in actions(board):
        max(value, minval(result(board, action)))
    return value


# Find the move that produces the highest Value

def minval(board):
    if terminal(board):
        return utility(board)
    value = -math.inf
    for action in actions(board):
        min(value, maxval(result(board, action)))
    return value


def checkturn(board):
    xCount = 0
    oCount = 0
    # Count how many Os and Xs are on the board
    for i in board:
        for j in i:
            if j == X:
                xCount += 1
            if j == O:
                oCount += 1
    #If O is less than x, then it's O's turn, otherwise it's Xs turn
    if oCount < xCount:
        return O
    else:
        return X


def check_xo(item):
    if item == ['X', 'X', 'X']:
        return X
    if item == ['O', 'O', 'O']:
        return O
    else:
        return None

标签: python

解决方案


我正在尝试做同样的事情,但是每当我运行我的代码时,我都会选择我的播放器并放一个动作然后下一回合出错


推荐阅读