我如何为 nim 游戏 python 编写极小极大算法?
How can I programme a minimax algorithm for nim game python?
我试图在 python 中编写极小极大算法。但这太令人困惑了。我是递归函数的新手。我的思维结构在某处有错误,但我无法解决。我的 minimax 树 returns 带有“-100”,必须为 100 才能获得真实答案。如果有任何遗漏或不清楚,请告诉我。谢谢
def startposition():
return 2, 'max'
def terminalstate(state):
if state == (0, 'min') or state == (0, 'max'):
return True
else:
return False
def minimax(state):
if terminalstate(state):
return utilitystatic(state)
else:
if state[1] == 'min':
value = -250
for x in successorsgenerator(state):
value = max(value, minimax(x))
elif state[1] == 'max':
value = 250
for x in successorsgenerator(state):
value = min(value, minimax(x))
return value
def utilitystatic(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()
exit = minimax(stick)
print('last result', exit)
我解决了我的问题。我需要将 value = min(value, minimax(x)) 更改为 value = max(value, minimax(x)) 并将 250 更改为 -250。问题解决了。
如果最小玩家先走,从最大玩家的角度来看代码是正确的。按照 minimax 的工作方式,最小层应该 return 其所有可能状态中的最小值(因为最小玩家也在优化他们的移动)。所以你不应该切换你的最小和最大调用,而是哪个玩家先。
这是您的可视化状态树:https://imgur.com/a/0iRFc.jpg(我显然没有足够的代表来显示图像)。递归的顶层将占用
max(-250, -100)
和return -100。因为游戏开始时最大玩家以 2 个筹码完成他的移动,所以这是有道理的。如果要将 return 值切换为 100,则需要将游戏更改为最大玩家先玩(因为在这种游戏场景中,谁先玩谁就赢)。
我试图在 python 中编写极小极大算法。但这太令人困惑了。我是递归函数的新手。我的思维结构在某处有错误,但我无法解决。我的 minimax 树 returns 带有“-100”,必须为 100 才能获得真实答案。如果有任何遗漏或不清楚,请告诉我。谢谢
def startposition():
return 2, 'max'
def terminalstate(state):
if state == (0, 'min') or state == (0, 'max'):
return True
else:
return False
def minimax(state):
if terminalstate(state):
return utilitystatic(state)
else:
if state[1] == 'min':
value = -250
for x in successorsgenerator(state):
value = max(value, minimax(x))
elif state[1] == 'max':
value = 250
for x in successorsgenerator(state):
value = min(value, minimax(x))
return value
def utilitystatic(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()
exit = minimax(stick)
print('last result', exit)
我解决了我的问题。我需要将 value = min(value, minimax(x)) 更改为 value = max(value, minimax(x)) 并将 250 更改为 -250。问题解决了。
如果最小玩家先走,从最大玩家的角度来看代码是正确的。按照 minimax 的工作方式,最小层应该 return 其所有可能状态中的最小值(因为最小玩家也在优化他们的移动)。所以你不应该切换你的最小和最大调用,而是哪个玩家先。
这是您的可视化状态树:https://imgur.com/a/0iRFc.jpg(我显然没有足够的代表来显示图像)。递归的顶层将占用
max(-250, -100)
和return -100。因为游戏开始时最大玩家以 2 个筹码完成他的移动,所以这是有道理的。如果要将 return 值切换为 100,则需要将游戏更改为最大玩家先玩(因为在这种游戏场景中,谁先玩谁就赢)。