Question

I need some help here, the scenario is the following: I have a recursive method for a Coffeescript class, and it executes itself exactly 4 times. I need to call another method from the same class right after this 4 iterations are completed, Let me illustrate a bit,

class Table
  constructor: (factor, zindex) ->
    @factor = factor
    @zindex = zindex
    @dealt = false
    @player = new Player 'player'
    @house = new Player 'house'
    this.setDealing()

  setDealing: ->
    self = this
    $('#deal').click ->
      self.deal $('.one-card:last'), 0 if self.amount > 0 && not self.dealt
      #When the call to self.deal() above is done I need to call checkWinner()
      #How Can I do this?

  deal: (card, times) ->
    $('#player-hand, #house-hand, #ask, #stop').show()
    @dealt = true
    self = this
    if (card.prev() || card.first()) && times < 4
      cardValue = this.getCardValue card
      if @zindex % 2 == 0 then @house.push cardValue else @player.push cardValue
      top = cardPlace + @factor
      right = 550 - (@factor * 1.4)
      card.animate
        'top': "+=#{top}"
        'right': "+=#{right}"
        350, ->
          card = card.prev()
          #Recursive Call is done Here!
          self.deal card, times + 1     
    @factor += 10
    @zindex += 1

  checkWinner: ->
    @player.isWinner()

As you can see, the recursive method is quite complex(or not..), and it takes some time to finish given that it does a number of animations(once per iteration). I have no idea how to call/chain another method to execute right after this recursive method is finally done.

How can I accomplish this? Thanks in advance!

Note: I placed one more line of code that was missing card = card.prev() which is needed for recursion to advance. Sorry about the confusion (if there was any)

Was it helpful?

Solution 3

Well, I cracked this one myself...

I had to look into JQuery's queue() and dequeue() methods, using them I can Actually orchestrate a sequence of events to be triggered, and you coordinate them by using time delays, Neat!

Here's How the result looks like now:

enableDealing: ->
    self = this
    $('#deal').bind 'click', ->
      self.disableHitting(); self.disableDealing()
      table = $('#table')

      table.queue "namedQueue", (next) ->
        self.deal $('.one-card:last'), 0
        next()

      table.delay 1900, "namedQueue"

      table.queue "namedQueue", (next) ->
        self.continue()

      table.dequeue('namedQueue')

The trick here is the 1900 miliseconds delay. Which is the time it take to finish the dealing.

I hope someone else finds it useful!

OTHER TIPS

I think that you should keep track of this function execution ; I mean keep a public variable

  var isRunning=false;

in the beginning of the function put this :

  isRunning=true;

and when recursion is done :

  isRunning=false;

If I understand this right:

Deal is the recursive function. It calls deal once if a certain condition is met. Once that condition is no longer met, it should continue down the method chain. There is another possible interpretation that you need to work with an internal chain, rather than an external one.

Right now, your stack looks like this Deal -> Deal -> Deal -> Deal

So you can do what you want with two simple changes. It always helps to think of it without the recursion, and then the answer is easier:

if (card.prev() || card.first()) && times < 4
  # <snip>
  #Recursive Call is done Here!
  return self.deal card, times + 1
else
  return self

Now you can call

$(selector).deal(arguments).show()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top