small medium large xlarge

Generic-user-small
23 Apr 2017, 06:36
Neil Thorne (1 post)

The book suggests trying to add an undo feature for the Game: Twelve. I have been at it for a couple hours and am having trouble. I am probably making it more complicated than it needs to be, or I am making a simple mistake somewhere.

My implementation listens for the Ctrl + U button press. Handling this button press is passed over to the game instance variable:

#twelve.rb
def button_down(id)
  ...
 if id == Gosu::KbU && button_down?(Gosu::KbLeftControl)
    @game.undo_action
  end
end

Before explaining the #undo_action, here is the extra setup over on game.rb:

Within the initialize method I create a @move_history instance variable. The idea is that @move_history is an array where each element is a snapshot of @squares each time the board changes.

#game.rb
def initialize(window)
  ...
  @move_history = []
  @move_history.push(@squares.collect {|square| Marshal.load(Marshal.dump(square)) })
end

I made my copy of the @squares instance variable by Marshalling because it doesn’t seem like dup or clone will work. It has something to do wth the fact that dup and clone do shallow copying. I found this marshalling trick on this stack overflow post

I push onto the @move_history instance variable at the very end of the #move method:

#game.rb
def move(square1, square2)
  ...
  @move_history.push(@squares.collect {|square| Marshal.load(Marshal.dump(square)) })
end

Lastly here is the #undo_action method:

#game.rb
def undo_action
  return if @move_history.size == 1
  @move_history.pop
  @squares = @move_history.last
end

The resulting behavior for the game is odd. Sometimes it works great. Other times the undo feature appears to not work, or works incorrectly via not displaying the correct previous move. My gut tells me that it all boils down to the copying. I’m wondering if some variables are just not getting cloned.

I would love to see others’ implementions of the undo feature. Or, I would also welcome help to my implementation. Thanks!

By the way, this book is awesome!!!

You must be logged in to comment