如何在递归函数中实现一个值?

How to achieve a value in recursion function?

我尝试用 Python 编写 minimax nim 游戏。我几乎完成了代码。但是,我无法解决一个非常棘手的问题。我无法达到算法的 'best movement'。我从 (5, Max) 位置开始,算法输出应该是 (4, Min)。我的算法解决了具有效用值的整棵树,但无法 return 达到最佳运动。

def startposition():
    return 5, 'max'


def terminalstate(state):
    if state == (0, 'min') or state == (0, 'max'):
        return True
    else:
        return False


def minimax(state):
    turn,heap=state
    if terminalstate(state):
        return utilitystatic(state)
    else:
        if heap == 'min':
            value = 250
            for x in successorsgenerator(state):
                value = min(value, minimax(x))
            result = state, value
        elif heap == 'max':
            value = -250
            for x in successorsgenerator(state):
                value = max(value, minimax(x))
            result = state, value

        print(result)
    return value


def utilitystatic(state):
    turn, heap = state
    assert terminalstate(state)
    if state[1] == 'max':
        return -100
    elif state[1] == 'min':
        return 100
    assert False


def successorsgenerator(state):
    successors = []
    state = toggle(state)
    newstate = decrease(state)
    i = 0
    while newstate[0] >= 0 and i < 3:
        successors.append(newstate)
        i += 1
        newstate = decrease(newstate)
    print('successors:', successors)
    return successors


def toggle(state):
    state = list(state)
    state[1] = 'min' if state[1] == 'max' else 'max'
    state = tuple(state)
    return state


def decrease(state):
    state = state[:0] + (state[0] - 1,) + state[1:2]
    return state


stick = startposition()
result = minimax(stick)
print('result:', result)

minimax() 中,您目前只能找到后继状态的最佳值(最小值或最大值取决于玩家),但还不能准确记住每个深度级别的最佳后继状态。如果您不将该信息存储在内存中,您将无法判断哪一步是最好的。所以,你会想尝试这样的事情:

def minimax(state):
    turn,heap=state
    if terminalstate(state):
        return utilitystatic(state), _
    else:
        if heap == 'min':
            value = 250
            best_succ = None
            for x in successorsgenerator(state):
                val, _ = minimax(x)
                if val < value:
                    value = val
                    best_succ = x
            result = state, value
        elif heap == 'max':
            value = -250
            best_succ = None
            for x in successorsgenerator(state):
                val, _ = minimax(x)
                if val > value:
                    value = val
                    best_succ = x
            result = state, value

        print(result)
    return value, best_succ

经过一些小改动,我们现在将导致最佳值的继任者 x 存储在 best_succ 中,因此也能够准确判断哪个继任者是最好的(而不是只能说出它的价值)

如果您不想将整个移动序列存储在内存中(often/usually 不必要),只需从生成当前游戏状态的可能子项开始。不要 运行 极小化你当前的状态,只是找到可能的下一步。假设从您所在的位置(A、B、C)有 3 种可能的移动。现在 运行 A 上的 minimax 算法并将结果与​​移动 A 的描述一起存储。对 B 和 C 重复。现在你应该有类似的东西:

A: 3.5
B: 1.2
C: -7.1

请记住,这些不是采取这些行动后立即产生的游戏状态的启发式值。从最大化玩家的角度来看,它们代表了当前玩家选择该着法后,其他玩家在未来可以迫使当前玩家获得的最小值。

在此示例中,着法 A 最适合最大化玩家,而着法 C 最适合最小化玩家。