我正在尝试在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
答案 0 :(得分:0)
我是tryna,但我每次运行代码时都选择我的播放器,并先下一个动作,然后下一步骤出错。