有人喜欢挑战吗?最小最大井字游戏

Anyone fancy a challenge? minimax tic-tac-toe

我一直坚持为井字游戏实施极小极大算法。我每次都收到同样的错误(nil:NilClass (NoMethodError) 的未定义方法 `<'),但我和我现在问过的各种人似乎无法修复它。

我的minimax实现如下:

def minimax(current_board, current_player)
  if user_won?(current_board)
    return -10
  elsif computer_won?(current_board)
    return 10
  elsif tie?(current_board)
    return 0
  end

  available_squares = empty_squares(current_board)
  moves = []
  score = nil

  available_squares.each do |available_square|
    move = {}
    current_board[available_square] = COMPUTER_MARKER if current_player == 'computer'
    current_board[available_square] = PLAYER_MARKER if current_player == 'player'
    score = minimax(current_board, alternate_player(current_player))
    current_board[available_square] = INITIAL_MARKER
    move[available_square] = score
    moves.push(move)
  end

  best_move = nil
  best_score = current_player == 'computer' ? -Float::INFINITY : Float:: INFINITY

  if current_player == 'computer'
    moves.each do |hsh|
      hsh.each do |move, score|
        if score > best_score
          best_move = move
          best_score = score
        end
      end
    end
  else
    moves.each do |hsh| 
      hsh.each do |move, score|
        if score < best_score
          best_move = move
          best_score = score
        end
      end
    end
  end
  best_move
end

递归调用 minimax 时,它有时 returns nil,然后附加到 move 散列,其中 move 然后附加到 moves数组。这会导致 < 运算符引发上述异常。我不知道为什么要返回 nil

我只能假设我的逻辑有问题。也许我的板在尝试了可能的板状态后没有正确重置,但老实说,我不知道如何进行。我尝试了多种实现,但总是得到相同的错误。

我已经坚持了一个多星期,非常感谢您的帮助。

如果没有移动,则循环 available_squares.each 必须跟随 return 0

我想我找到了问题所在。在我的 if tie?(current_board) 条件下,tie? 应该采用参数 available_squares。这会停止引发异常。

此外,正如@Stefan 所指出的(归功于他),设置默认值可确保输出正确的值并将其写为:

score = minimax(current_board, alternate_player(current_player)) || 0

这就解决了。