Jump To …

turbo21.coffee

class to handl each lane of cards

class Lane

  constructor: (g, num) ->
    @g = g
    @cards = []
    @total = 0
    @num = num
    @cards = Array()
    @el = $('<div class="lane" id="lane' + @num + '"></div>').appendTo(@g.lanesView)
    $('<div class="lanenum vert">' + @num + '</div>').appendTo(@el)
    @el.on('click', @click);
    @laneTotalView = $('<div class="lanetotal"></div>').appendTo(@el);
    @laneScoreView = $('<div class="lanescore" id="lanescore' + @num + '"></div>').appendTo(@g.laneScores);


  getTotal: ->
    t = 0
    haveAce = false
    for c in @cards
      n = c.num
      n = 10 unless n < 11
      t += n
      if (c.num == 1)
        haveAce = true

    if haveAce
      nt = t + 10
      t = nt unless nt > 21
    t

  click: =>
    return unless @g.currentCard

    top = @cards.length * 25 + 55
    @cards.push(@g.currentCard)
    $('<div class="card ' + @g.currentCard.viewClass() + '" style="top:' + top + 'px"></div>').appendTo(@el)

    t = @getTotal()
    @laneTotalView .text(t)

    if (t > 21)
      @resetLane()
      @busted()

    else if @isBlackjack()
      @resetLane()
      @gotBlackjack()

    else if t == 21
      @resetLane()
      @got21()

    else if @cards.length == 5
      @resetLane()
      @got5Cards()

    if !@g.drawCard()
      @g.gameOver()

  resetLane: ->
    @cards = []
    @el.find('.card').remove()
    @laneTotalView.text('')

  isBlackjack: ->
    return false unless @cards.length == 2
    (@cards[0].num == 1 && @cards[1].num > 9) || (@cards[1].num == 1 && @cards[0].num > 9)

  busted: ->
    @g.busted(@)
    @animateLane('busted')

  gotBlackjack: ->
    @g.gotBlackjack(@)
    @animateLane('blackjack')

  got21: ->
    @g.got21(@)
    @animateLane('got21')

  got5Cards: ->
    @g.got5Cards(@)
    @animateLane('got5cards')


  animateLane: (type) ->
    @el.addClass(type)
    window.setTimeout("$('#lane" + @num + "').removeClass('" + type + "')", 200)
    window.setTimeout("$('#lane" + @num + "').addClass('" + type + "')", 220)
    window.setTimeout("$('#lane" + @num + "').removeClass('" + type + "')", 421)

  flashScore: (score) ->
    @laneScoreView.text(score)
    window.setTimeout("$('#lanescore" + @num + "').text('')", 422)

class to handle the draw pile

class Pile

  constructor: ->
    @cards = []
    @el = $('<div class="thepile"></div>');
    for i in [1..52] by 1
      c = $('<div class="card card-back"></div>').appendTo(@el)
      c.css('left', (i-1)*8)
      @cards.push(c)

  removeOne: ->
    $('.thepile .card:last').remove()
    @cards.pop()

Main game class

class Turbo21 extends Game

constructor

  constructor: ->
    @game_key = 'turbo21'
    super
    @snd =
      card: new Audio('/lib/games/snd/card-dealt.mp3')
      beep: new Audio('/lib/games/snd/beep.mp3')
      pop: new Audio('/lib/games/snd/pop1.mp3')
      explode: new Audio('/lib/games/snd/explode1.mp3')
      bust: new Audio('/lib/games/snd/glass-break1.mp3')
      deck: new Audio('/lib/games/snd/shuffle-short.mp3')
    @snd.beep.volume = 0.3
    @snd.explode.volume = 0.8

    @deck = new Deck()
    @currentCard = false
    @buildUI()
    @drawCard()


  newGame: =>
    super
    @snd.deck.play()
    @deck = new Deck()
    @currentCard = false
    @buildUI()
    @drawCard()

  buildUI: ->
    super
    @lanesView = $('<div class="lanes clearfix"></div>').appendTo(@el);
    @laneScores = $('<div class="lanescores clearfix"></div>').appendTo(@el)

make the lanes

    @lanes = [
      new Lane(@,1),
      new Lane(@,2),
      new Lane(@,3),
      new Lane(@,4),
      new Lane(@,5),
    ]

    @pile = new Pile();
    @pile.el.appendTo(@el)
    @upcardView = $('<div class="card upcard"></div>').appendTo(@el)

draws a card from the pile, and puts it in the up card view.

  drawCard: ->
    if @deck.deck.length < 1
      return false

    @snd.card.play()

    if @currentCard
      @upcardView.removeClass(@currentCard.viewClass())
    @currentCard = @deck.draw(1)
    @pile.removeOne();
    @upcardView.addClass(@currentCard.viewClass())
    true

  got21: (lane) ->
    @snd.beep.play()
    @updateScore(20)
    lane.flashScore(20)

  gotBlackjack: (lane) ->
    @snd.explode.play()
    @updateScore(50)
    lane.flashScore(50)

  got5Cards: (lane) ->
    @snd.pop.play()
    @updateScore(10)
    lane.flashScore(10)

  busted: (lane) ->
    @snd.bust.play()
    @updateScore(-5)
    lane.flashScore(-5)

  updateScore: (score) ->
    @score += score
    @scoreView.text(@score)

  gameOver: ->
    super
    @upcardView.addClass('card-back').removeClass(@currentCard.viewClass())
    @currentCard = false
    alert('Game Over!');

$ ->
  $.g = new Turbo21