Ruby 调试TicTacToe中的递归MinMax
我正试图让minmax算法(计算机AI)在我的tic-tac-toe游戏中发挥作用。这件事我已经坚持了好几天了。基本上,我不明白为什么计算机AI只是将其标记(Ruby 调试TicTacToe中的递归MinMax,ruby,algorithm,tic-tac-toe,minmax,Ruby,Algorithm,Tic Tac Toe,Minmax,我正试图让minmax算法(计算机AI)在我的tic-tac-toe游戏中发挥作用。这件事我已经坚持了好几天了。基本上,我不明白为什么计算机AI只是将其标记(“O”)按顺序从电路板片0-8放置 例如,作为人类玩家,如果我选择1,那么计算机将选择0: O| X| 2 --+---+-- 3| 4| 5 --+---+-- 6| 7| 8 接下来,如果我选择4,那么计算机将选择2: O| X| O --+---+-- 3| X| 5 --+---+-- 6| 7| 8 等等: O|
“O”
)按顺序从电路板片0-8
放置
例如,作为人类玩家,如果我选择1
,那么计算机将选择0
:
O| X| 2
--+---+--
3| 4| 5
--+---+--
6| 7| 8
接下来,如果我选择4
,那么计算机将选择2
:
O| X| O
--+---+--
3| X| 5
--+---+--
6| 7| 8
等等:
O| X| O
--+---+--
O| X| O
--+---+--
X| 7| X
我已经尽可能多地调试了minmax算法,但是现在很难理解到底发生了什么
这是带有算法的ComputerPlayer
类(没有我所有的打印语句)。minmax
方法是我遇到很多麻烦的地方。(我不能100%确定是否使用最差分数
或相关逻辑。)
class ComputerPlayer最佳评分
@最佳移动=移动
最佳成绩=当前成绩
结束
其他的
如果当前_分数<最差_分数
最差评分=当前评分
结束
结束
结束
结束
返回最高分
结束
def分数(板)
如果board.winner==“O”#“O”==“O”,“nil”==“O”
10
elsif board.winner==“X”#“X”!=”O、‘无’!='O'
-10
elsif board.winner==零
0
结束
结束
结束
问题是minmax总是返回最佳分数
最小最大值例程在两个玩家之间不断切换。当被模拟的当前玩家是计算机玩家时,最佳分数是最高分数;当被模拟的当前玩家是人类玩家时,最佳分数是最低分数
我重写了该例程,以尝试迭代的所有剩余移动,并在本地哈希中跟踪相应的分数。完成后,将返回最佳分数并设置最佳移动,具体取决于当前模拟的玩家
def minmax(board, player_tracker = 0, iteration = 0) #minmax
if board.game_over?
return score(board, iteration)
end
new_marker = player_tracker.even? ? 'O' : 'X'
scores = {}
board.get_available_positions.each do |move|
new_board = board.place_piece(move, new_marker)
scores[move] = minmax(new_board, player_tracker + 1, iteration + 1)
end
if player_tracker.even?
@best_move = scores.sort_by {|_key, value| value}.reverse.to_h.keys[0]
else
@best_move = scores.sort_by {|_key, value| value}.to_h.keys[0]
end
return scores[@best_move]
end
<> P>为了提高准确性,我重写了记分程序,也考虑了创建棋盘得分所需的迭代。能够在1次迭代中获胜应该比在3次迭代中获胜更可取,对吗
def score(board, iteration)
# "O", "X", "nil"
if board.winner == "O" #'O' == 'O', 'nil' == 'O'
10.0 / iteration
elsif board.winner == "X" #'X' != 'O', 'nil' != 'O'
-10.0 / iteration
elsif board.winner == nil
0
else
raise "ERROR"
end
end
随着这两个例程的替换,计算机所采取的步骤似乎更符合逻辑。因此,分数散列将维护两名玩家的所有分数?分数是一个局部变量,它将在迭代中跟踪所有分数。因此,对于每个迭代,它将跟踪单个玩家的所有分数。
def score(board, iteration)
# "O", "X", "nil"
if board.winner == "O" #'O' == 'O', 'nil' == 'O'
10.0 / iteration
elsif board.winner == "X" #'X' != 'O', 'nil' != 'O'
-10.0 / iteration
elsif board.winner == nil
0
else
raise "ERROR"
end
end