beefsack
beefsack

Reputation: 438

Using state_machine, how can I access event arguments from inside the :if lambda

I am using the state_machine gem to model a card game, and I have a transition condition that requires knowing the event arguments when drawing a card. Here is some example code.

class CardGame
  state_machine do
    before_transition :drawing_card => any, :do => :drawn_card
    event :draw_card
      transition :drawing_card => :end_of_round, :if => lambda {|game|
        # Check goes here, I require knowing which card was taken
        # which is passed as arguments to the event (:ace, :spaces)
      }
    end
  end

  def drawn_card(value, suit)
    # I can access the event arguments in the transition callbacks
  end
end

game = CardGame.new
game.draw_card(:ace, :spades)

I am thinking an alternative is to set the card suit and value on the object as variables, but it is much messier than using arguments to the event.

Thanks in advance :)

Upvotes: 4

Views: 1195

Answers (1)

Olly
Olly

Reputation: 7758

The main issue here is that a state machine probably doesn't belong in your CardGame class. Game state lies elsewhere. There are four main domain models I can see:

  • Card
  • Deck
  • Hand
  • Game

A Game will have one or more Decks (each of 52 Cards) and one or more Hands. (You might even want to have a Player class, where a player has-a Hand, your call).

As an example, a Deck will probably have a shuffle! and a deal method. A Hand will have a play method. This is where the rule logic might live.

The Game class will primarily consist of a loop such as the following:

def run
  deal               
  do 
    play_hands       
    check_for_winner 
  while(playing)
end

More devil in the detail of course but you might find this approach more refreshing and easier to test.

Upvotes: 2

Related Questions