Ruby 调试TicTacToe中的递归MinMax

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|

我正试图让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| 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