井字游戏minimax功能无效的操作错误

时间:2020-04-27 14:33:52

标签: python

我正在尝试在CS50ai中为井字游戏编写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

1 个答案:

答案 0 :(得分:0)

我是tryna,但我每次运行代码时都选择我的播放器,并先下一个动作,然后下一步骤出错。