【问题标题】:Debugging a stack level too deep error - Ruby调试堆栈级别太深的错误 - Ruby
【发布时间】:2017-10-25 00:41:51
【问题描述】:

我正在构建一个井字游戏,其中用户可以玩电脑,或者电脑可以互相玩。在构建 AI 时,我遇到了以下错误。我该如何调试呢?我知道这与某处的循环有关,但我找不到它。

ttt-with-ai-project-cb-000/lib/players/computer.rb:13:in `each': stack level too deep (SystemStackError)
        from ttt-with-ai-project-cb-000/lib/players/computer.rb:13:in `detect'
        from ttt-with-ai-project-cb-000/lib/players/computer.rb:13:in `check_move'
        from ttt-with-ai-project-cb-000/lib/players/computer.rb:8:in `move'
        from ttt-with-ai-project-cb-000/lib/game.rb:61:in `wargame_turn'
        from ttt-with-ai-project-cb-000/lib/game.rb:64:in `wargame_turn'
        from ttt-with-ai-project-cb-000/lib/game.rb:64:in `wargame_turn'
        from ttt-with-ai-project-cb-000/lib/game.rb:64:in `wargame_turn'
        from ttt-with-ai-project-cb-000/lib/game.rb:64:in `wargame_turn'
         ... 11900 levels...
        from bin/tictactoe:37:in `block in run_game'
        from bin/tictactoe:35:in `times'
        from bin/tictactoe:35:in `run_game'
        from bin/tictactoe:79:in `<main>'


违规方法

lib/players/computer.rb

def move(board)
    check_move(board)
end

def check_move(board)
    win_combo = Game::WIN_COMBINATIONS.detect do |indices|
    board.cells[indices[0]] == token && board.cells[indices[1]] == token || board.cells[indices[1]] == token && board.cells[indices[2]] == token || board.cells[indices[0]] == token && board.cells[indices[2]] == token
    end

    win_combo.detect {|index| board.cells[index] == " "}.join if win_combo
end


lib/game.rb

def wargame_turn
    input = current_player.move(board)

    if !board.valid_move?(input)
        wargame_turn
    else
        board.update(input, current_player)
    end
end


bin/tictactoe 在#run_game 中调用以下块中的方法:

100.times do 
    game = Game.new(Players::Computer.new("X"), player_2 = Players::Computer.new("O"))
    game.wargames
    if game.winner == "X"
        x_wins += 1
    elsif game.winner == "O"
        x_wins += 1
    elsif game.draw?
        draws += 1
    end
end

【问题讨论】:

  • 一目了然,我猜 Computer#check_move 正在为任何给定的板配置生成相同的建议移动。如果这是真的,并且如果该移动未能满足 !board.valid_move 测试,那么您将进入无限循环,wargame_turn 递归调用自身直到死亡。

标签: ruby stack-level


【解决方案1】:

你可以使用红宝石Tracer class:

ruby -r tracer your_main_script.rb

此外,您可以查看您的代码并查看循环可能发生的位置:

def wargame_turn

  input = current_player.move(board)

  if !board.valid_move?(input)

    wargame_turn #### HERE'S A POTENTIAL INFINITE LOOP

所以问题的核心似乎在:

if !board.valid_move?(input)

这可能是一个好的开始。

【讨论】:

    猜你喜欢
    • 2013-10-05
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多