英文:
Recursive Minimax Function returns None instead of optimal score
问题
代码中的问题在于,max_value
和 min_value
函数的递归调用可能返回 None
,这会导致比较操作出错。为了解决这个问题,你可以在递归调用之前添加条件,以确保不会返回 None
。以下是修改后的代码:
def player(board):
if Terminal(board) != False:
return None
else:
if turn(board) == "X":
value, move = max_value(board)
return move
else:
value, move = min_value(board)
return move
def max_value(board):
if Terminal(board) != False:
return Utility(board), None
else:
v = -1000
move = None
for action in Actions(board):
aux, act = min_value(Result(board, action))
print(aux)
if aux is not None and aux > v:
v = aux
move = action
if v == 1:
return v, move
return v, move
def min_value(board):
if Terminal(board) != False:
return Utility(board), None
else:
v = 1000
move = None
for action in Actions(board):
aux, act = max_value(Result(board, action))
print(aux)
if aux is not None and aux < v:
v = aux
move = action
if v == -1:
return v, move
return v, move
这样,当 aux
为 None
时,不会执行比较操作,从而避免了出现 '>' not supported between instances of 'NoneType' and 'int'
错误。
英文:
I'm simply working on a Minimax algorithm that can play TicTacToe, For some reason the max_value and min_value functions occasionally return None.
def player(board):
if Terminal(board) != False:
return None
else:
if turn(board) == "X":
value,move = max_value(board)
return move
else:
value,move = min_value(board)
return move
def max_value(board):
if Terminal(board) != False:
return Utility(board),None
else:
v = -1000
move = None
for action in Actions(board):
aux,act = min_value(Result(board,action))
print(aux)
if aux > v:
v = aux
move = action
if v == 1:
return v,move
return v,move
def min_value(board):
if Terminal(board) != False:
return Utility(board),None
else:
v = 1000
move = None
for action in Actions(board):
aux,act = max_value(Result(board,action))
print(aux)
if aux < v:
v = aux
move = action
if v == -1:
return v,move
return v,move
Terminal returns state of the game,Action returns possible moves and result creates a board given an action.
The error I get is '>' not supported between instances of 'NoneType' and 'int'
pops up for if aux < v:
and if aux > v:
When I print aux, it occasionally appears as None
.
Thanks.
答案1
得分: 0
以下是您要翻译的内容的翻译部分:
"The code you have shared is fine.
The error message indicates that Utility
returns None
when you call it. This should not happen. Utility
should always return an integer when the game is over, and looking at your code it should return -1, 0 or 1.
There is also the possibility that Utility
returns None when the game is not over, but that Terminal
has a bug such that it returns something else than False
even when the game is not over.
Here is an implementation of the functions Terminal
and Utility
that do not produce the error you got, but make it work as expected.
In fact, I added all missing functions based on a board representation that is a string of 9 characters, and a game loop so you can play against the minimax algorithm:
<details>
<summary>英文:</summary>
The code you have shared is fine.
The error message indicates that `Utility` returns `None` when you call it. This should not happen. `Utility` should **always** return an integer when the game is over, and looking at your code it should return -1, 0 or 1.
There is also the possibility that `Utility` returns None when the game is not over, but that `Terminal` has a bug such that it returns something else than `False` even when the game is not over.
Here is an implementation of the functions `Terminal` and `Utility` that do not produce the error you got, but make it work as expected.
In fact, I added all missing functions based on a board representation that is a string of 9 characters, and a game loop so you can play against the minimax algorithm:
import re
def Utility(board):
m = re.findall(r"([XO])(?:\1\1(?:...)*$|..\1..\1|...\1...\1|.\1.\1..$)", board)
return -1 if "O" in m else len(m)
def Terminal(board):
return "O X"[Utility(board)+1].strip() or not board.count(".") and "draw"
def turn(board):
return "OX"[board.count(".") % 2]
def Actions(board):
return (i for i in range(9) if board[i] == ".")
def Result(board, action):
return board[:action] + turn(board) + board[action+1:]
board = "." * 9
while True: # Interactive game between human and minimax
print(f"{board[:3]}\n{board[3:6]}\n{board[6:]}")
winner = Terminal(board)
if winner:
print(f"Winner: {winner}")
break
if turn(board) == "X":
action = int(input("Your move (0..8)? "))
if board[action] != ".":
print("Invalid move. Try again.")
continue
else:
action = player(board)
print("minimax chooses", action)
board = Result(board, action)
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论