I want to implement a game loop in Ruby, but my current implementation receives a 'stack level too deep' (SystemStackError).
This is how far I got on my Tetris-like falling block game:
# falling block game
class Tetris
class EndGame < StandardError; end
def start
@canvas = Canvas.new
@canvas.banner = "New game"
@canvas.draw
update
end
def update
step
update
rescue EndGame
puts "Game over!"
end
def step
puts "Take one step..."
# TODO: do stuff here
end
# draws our game board
class Canvas
SIZE = 10
attr_accessor :banner, :board
def initialize
@board = SIZE.times.map { Array.new(SIZE) }
end
def update(point, marker)
x, y = point
@board[x, y] = marker
end
alias_method :draw, :to_s
def draw
[banner, separator, body, separator].join("\n")
end
private
def separator
"=" * SIZE
end
def body
@board.map do |row|
row.map { |e| e || " " }.join
end.join("\n")
end
end
end
game = Tetris.new
game.start
Produces this error:
Take one step...
Take one step...
Take one step...
Take one step...
Take one step...
Take one step...
Take one step...
Take one step...
Take one step...
Take one step...
gameloop.rb:20:in `puts': stack level too deep (SystemStackError)
from gameloop.rb:20:in `puts'
from gameloop.rb:20:in `step'
from gameloop.rb:13:in `update'
from gameloop.rb:14:in `update'
from gameloop.rb:14:in `update'
from gameloop.rb:14:in `update'
from gameloop.rb:14:in `update'
from gameloop.rb:14:in `update'
... 10067 levels...
from gameloop.rb:14:in `update'
from gameloop.rb:14:in `update'
from gameloop.rb:9:in `start'
from gameloop.rb:59:in `<main>'
UPDATE
Ruby does not enable Tail Call Optimizations by default, but it can be enabled in the Ruby VM.
RubyVM::InstructionSequence.compile_option = {
tailcall_optimization: true,
trace_instruction: false
}
Use a while true ... loop instead of recursion. You can also add a short sleep to avoid more updates than necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With