Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
cs50 python Tictoe极小极大算法_Python_Algorithm_Cs50_Tic Tac Toe_Minimax - Fatal编程技术网

cs50 python Tictoe极小极大算法

cs50 python Tictoe极小极大算法,python,algorithm,cs50,tic-tac-toe,minimax,Python,Algorithm,Cs50,Tic Tac Toe,Minimax,我目前正在cs50 AI中解决这个问题,我们需要为玩Tictatcoe制作一个minimax算法。我的算法根本不起作用(打败电脑真的很容易),我想知道我做错了什么。我也非常确定我所有的其他函数都是正确的,只有minimax函数是错误的。非常感谢您的帮助,谢谢大家 import math, copy X = "X" O = "O" EMPTY = None def initial_state(): """

我目前正在cs50 AI中解决这个问题,我们需要为玩Tictatcoe制作一个minimax算法。我的算法根本不起作用(打败电脑真的很容易),我想知道我做错了什么。我也非常确定我所有的其他函数都是正确的,只有minimax函数是错误的。非常感谢您的帮助,谢谢大家



import math, 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.
    """
    xplayer = 0
    yplayer = 0
    for row in board:
        for column in row:
            if column == 'X':
                xplayer += 1
            elif column == 'O':
                yplayer += 1

    if xplayer == yplayer:
        return X
    else:
        return O


def actions(board):
    """
    Returns set of all possible actions (i, j) available on the board.
    """
    ans = set()
    rownum = 0
    colnum = 0
    for row in board:
        colnum = 0
        for column in row:
            if not column:
                ans.add((rownum, colnum))
            colnum += 1
        rownum += 1

    return ans

def result(board, action):
    """
    Returns the board that results from making move (i, j) on the board.
    """
    if board[action[0]][action[1]] != None :
        raise BoardError("Tried to place on full square")
    move = player(board)
    newboard = copy.deepcopy(board)
    newboard[action[0]][action[1]] = move
    return newboard


def winner(board):
    """
    Returns the winner of the game, if there is one.
    """


    for i in range(3):
        sum = 0
        for j in range(3):
            if board[i][j] == 'X':
                sum += 1
            elif board[i][j] == 'O':
                sum -= 1
        if sum == 3:
            return X
        elif sum == -3:
            return O

    for j in range(3):
        sum = 0
        for i in range(3):
            if board[i][j] == 'X':
                sum += 1
            elif board[i][j] == 'O':
                sum -= 1
        if sum == 3:
            return X
        elif sum == -3:
            return O
    if board[0][0] == board[1][1] == board[2][2]:
        return board[0][0]
    if board[2][0] == board[1][1] == board[0][2]:
        return board[2][0]
    return None


def terminal(board):
    """
    Returns True if game is over, False otherwise.
    """
    if winner(board):
        return True
    if not actions(board):
        return True
    return False



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
    else:
        return 0

def minimax(board):
    """
    Returns the optimal action for the current player on the board.
    """
    if player(board) == X:
        aim = 1
    elif player(board) == O:
        aim = -1
    if terminal(board):
        return None


    possiblemoves = actions(board)
    for move in possiblemoves:
        newboard = result(board,move)

        #if move leads to the aimed score, return move
        if utility(newboard) == aim:
            return move

        #if nodes down the chain return a value cos they have reached the aim, return this current move
        if minimax(newboard):
            return move


    aim = 0

    #change the aim to be a draw since winning is no longer possible
    for move in possiblemoves:
        newboard = result(board,move)


        if utility(newboard) == aim:
            return move

        if minimax(newboard):
            return move

    #all the moves will result in a loss, so i just return the first move
    return possiblemoves[0]
基本上X的目标是最大化,O的目标是最小化。我对算法所做的是根据玩家的不同,首先根据玩家的不同寻找会导致1或-1的移动。然后,如果这没有发生,寻找导致0(平局)的移动。
然后,只需返回任何移动,因为这意味着玩家将失败。

您似乎有许多不必要的函数,并且您的minimax代码看起来比需要的复杂得多。基本上,游戏需要4个主要功能:

  • 极小极大本身
  • 从一个位置获得所有可能的移动(除非你想在minimax内循环)
  • 确定一个玩家是否赢了
  • 确定电路板是否已满
另外,您是否查看过Wikipedia等网站上的minimax伪代码

function minimax(node, depth, maximizingPlayer) is
    if depth = 0 or node is a terminal node then
        return the heuristic value of node
    if maximizingPlayer then
        value := −∞
        for each child of node do
            value := max(value, minimax(child, depth − 1, FALSE))
        return value
    else (* minimizing player *)
        value := +∞
        for each child of node do
            value := min(value, minimax(child, depth − 1, TRUE))
        return value
以下是总体思路:

  • 检查当前板是否为赢、平或输,并根据信息返回值,通常返回-1、0或1。这是伪代码中的第一条if语句
  • 然后从if-else语句中查看是轮到它还是对手
  • 在里面,你可以设置麦汁可能的分数作为起始值。如果只返回-1、0或1,则分别将-2和2设置为最大/最小值就足够了
  • 现在,您可以在该位置运行所有可能的移动
  • 您将新值设置为另一个minimax调用返回值的最大/最小值,其中玩家回合已更改
  • 在这个递归循环之后,您将返回一个值,该值将给出从给定电路板开始的最佳路径

  • 深度是没有必要的,因为井字游戏是一个简单的游戏,我们总是可以达到一个最终状态。您可以使用深度来确保计算机将通过向启发式返回值添加深度来选择最短的获胜路径。但是我建议你先让它工作起来,不要让事情复杂化:)

    如果minimax(newboard):return move
    这将返回任何不会导致平局的移动。@n.'。对不起,我不明白/不明白:x
    如果实用程序(新板)=目标:返回移动
    。在这里,如果你发现一个移动,结果立即赢得,你返回它<代码>如果minimax(newboard):返回移动如果您发现移动(…),则返回该移动。填写省略号。@n.“代词是m。”。我明白了,基本上在链的下游,任何移动都会被返回,因为我正在检查每个节点的所有3个端点。即使是平局也会被退回,对吗?哦,是的,什么都可以。为了成为一个最小-最大算法,您的程序需要实际找到某个值的最小值或最大值。这通常包括首先评估所有动作,然后找到可能的最佳动作,然后返回。你从不考虑哪一个运动是最好的。你只喜欢立即胜出,而不是你以后评估的其他动作。使
    minimax
    返回一个元组
    (移动,结果)
    ,收集所有移动,然后只返回一个结果最好的(最小或最大)。