Scoring  

Tracking your winnings

        


Now all we have to do is associate the winning hands with money values and keep a running total of the player's bankroll. We are using the standard 9/6 Jacks pay table with five units bet each hand. Two additional input controls have been added to the form to display money won on each hand and the running total.

We have also added an onLoad handler to the body tag of the page:
<body onLoad="ResetCards()">
This ensures that the form controls show the proper values when the user loads or reloads the page.

New code is shown below in red. The changed form is shown in blue.

Click the "Deal" button to see the hand re-deal.
Click the "Hold" buttons to hold individual cards.
Click the "Draw" button to replace the unheld cards.
Click the "Play again" button to turn over the cards.

Card images from Oxymoron.

Code in the page header

<script language="JavaScript" type="text/javascript">
<!--

// define the contructor for Card objects
function Card(s, r, c, ns, nr, cm ) {
  this.suit = s ;
  this.rank = r ;
  this.color = c ;
  this.numsuit = ns ;
  this.numrank = nr ;
  this.cardmask = cm ;
  this.held = false ;
}

// define a copy function for cards
function CopyCard(cardfrom, cardto) {
  var i ;
	
  for (i in cardfrom)
    cardto[i] = cardfrom[i] ;
}

// define a swap function for cards
function SwapCard(c1, c2) {
var c0 = new Card(null, null, null) ;

  CopyCard(c1, c0) ;
  CopyCard(c2, c1) ;
  CopyCard(c0, c2) ;
}

// define a shuffle method for the deck
function ShuffleCards() {
var i = 0 , r1 = 0 ;

  for (i = 0 ; i < this.length ; i++ ) {
    r1 = Math.floor(Math.random() * this.length) ;
    SwapCard(this[i], this[r1]) ;
  }
}

// extend the definition of arrays by adding a new method
Array.prototype.shuffle = ShuffleCards ;

// shuffle the deck and deal a hand
function ShuffleDeal() {
var i ;
var vImageSrc = null ;
var vCardImg = null ;
var vHold = null ;

  nBankroll -= 5 ;
  Deck.shuffle() ;
  for (i = 0 ; i < 5 ; i++ ) {
    CopyCard(Deck[i], Hand[i]) ;
    vImageSrc = "graphics/cards/" + Hand[i].rank + Hand[i].suit + ".gif" ;
    vCardImg = "CardImg" + i ;
    vHold = "Hold" + i ;
    document[vCardImg].src = vImageSrc ;
    Hand[i].held = false ;
    document.PForm1[vHold].value = "Hold"
  }		
  document.PForm2.btDeal.value = " ... " ;
  document.PForm2.btDraw.value = " Draw " ;
  document.PForm2.btCardReset.value = " ... " ;
	
  document.PForm3.txtbankroll.value = nBankroll ;
}

// reset the card backs
function ResetCards() {
var i ;
var vImageSrc = "graphics/cards/b.gif" ;
var vCardImg = null ;

  for (i = 0 ; i < 5 ; i++ ) {
    vCardImg = "CardImg" + i ;
    vHold = "Hold" + i ;
    document[vCardImg].src = vImageSrc ;
    document.PForm1[vHold].value = " ... "
  }	
  document.PForm2.btDeal.value = " Deal " ;
  document.PForm2.btDraw.value = " ... " ;
  document.PForm2.btCardReset.value = " ... " ;
  
  document.PForm3.txtresult.value = "" ;
  document.PForm3.txtwin.value = "" ;
  document.PForm3.txtbankroll.value = nBankroll ;
}

// hold or unhold a card
function HoldCard(pWhich) {
var vHold = "Hold" + pWhich ;
var vValue = null ;

  if (GameState != 1) return ;

  if (Hand[pWhich].held) {
    vValue = " Hold " ;
  }
  else {
    vValue = "[HELD]" ;	
  }
  Hand[pWhich].held = ! Hand[pWhich].held ;
  document.PForm1[vHold].value = vValue ;
}

// fill in unheld cards
function Redeal() {
var i ;
var j = 5 ;
var vImageSrc = null ;
var vHold = null ;
var vCardImg = null ;

  for (i = 0 ; i < 5 ; i++ ) {
    if (! Hand[i].held) {
      CopyCard(Deck[j], Hand[i]) ;
      vImageSrc = "graphics/cards/" + Hand[i].rank + Hand[i].suit + ".gif" ;
      vCardImg = "CardImg" + i ;
      document[vCardImg].src = vImageSrc ;
      j++ ;		
    }
    vHold = "Hold" + i ;
    document.PForm1[vHold].value = " ... " ;
    Hand[i].held = true ;
  }
  document.PForm2.btDeal.value = " ... " ;
  document.PForm2.btDraw.value = " ... " ;
  document.PForm2.btCardReset.value = " Play again " ;
}

// evaluate the hand
function ScoreHand() {
var i, j, u, c0, c1, c2, c3, c4, m1, m2, m3, m4 ;
var vFlush = false ;
var vMaxnum = 0 ;
var vDiffnum = 0 ;
var vJacksPlus = false ;

  // check for flushes by making suits powers of two
  u  = Hand[0].numsuit ; 
  u |= Hand[1].numsuit ; 
  u |= Hand[2].numsuit ; 
  u |= Hand[3].numsuit ; 
  u |= Hand[4].numsuit ; 
  u = u & (u-1) ;   // zero if it's a flush
	vFlush = (u == 0) ;
	
  // make cards powers of two
  c0 = Hand[0].cardmask ;
  c1 = Hand[1].cardmask ;
  c2 = Hand[2].cardmask ;
  c3 = Hand[3].cardmask ;
  c4 = Hand[4].cardmask ;

  // check for 1, 2, 3 and 4 of a kind using the card
  m1 = c0 | c1 ;
  m2 = c1 & c0 ;
  m2 |= c2 & m1 ;
  m1 |= c2 ;
  m2 |= c3 & m1 ;
  m1 |= c3 ;
  m2 |= c4 & m1 ;
  m1 |= c4 ;

  // m1 has bits for each rank represented
  // m2 has bits for each rank represented more than once
  
  // no pairs?
  if (m2 == 0) {

    // test for straights

    switch (m1) {
      case (31) :    // A-5
      case (62) :    // 2-6
      case (124) :   // 3-7
      case (248) :   // 4-8
      case (496) :   // 5-9
      case (992) :   // 6-10
      case (1984) :  // 7-J
      case (3968) :  // 8-Q
      case (7936) :  // 9-K
        if (vFlush) return 8 ;  // Straight Flush
        else return 4 ;         // Straight
        break ;
      case (7681) :  // 10-A
        if (vFlush) return 9 ;  // Royal Flush
        else return 4 ;         // Straight
        break ;
      default :
        if (vFlush) return 5 ;  // Flush
        else return 0 ;         // RAZGU
        break ;	
    }  
  }
  else {
    // pairs or better
		
    vMaxnum = 0 ;
    vDiffnum = 0 ;
    for (i = 0 ; i < 13 ; i++) {
      aRanks[i] = 0 ;
    }
		
    // how many cards of each rank do we have?
    for (i = 0 ; i < 5 ; i++) {
      j = Hand[i].numrank ;
      aRanks[j]++ ;
      if (aRanks[j] > vMaxnum)  
        vMaxnum = aRanks[j] ; 
    }
		
    // what's the maximum number we have of one rank?
    for (i = 0 ; i < 13 ; i++ ) {
      if (aRanks[i] > 0) { 
        vDiffnum++ ;
      }
    }
		
    switch(vMaxnum) {
      case 4 :
        return 7 ;                       // Four of a kind
        break ;
      case 3 :
        if (vDiffnum == 2) return 6 ;    // Full House
        else return 3 ;                  // Three of a kind
        break ;
      case 2 :
        if (vDiffnum == 3) {
          return 2 ;                     // Two pairs
        }
        else {
          for (i = 10 ; i < 13 ; i++) {
            if (aRanks[i] == 2 ) { 
              vJacksPlus = true ;
            } 
          }
          if (vJacksPlus || (aRanks[0] == 2)) {  
            return 1 ;                   // Jacks or Better 
          }
          else {
            return 0 ;                   // RAZGU
          }
        } 	
        break ;
      default:
        return 99 ;
        break;	
    }
  }
}

// show results
function ShowResults(pWhich) {
var nWin ;

  switch (pWhich) {
    case 0 : document.PForm3.txtresult.value = "(nothing)" ; break ;
    case 1 : document.PForm3.txtresult.value = "Jacks or Better" ; break ;
    case 2 : document.PForm3.txtresult.value = "Two pairs" ; break ;
    case 3 : document.PForm3.txtresult.value = "Three of a kind" ; break ;
    case 4 : document.PForm3.txtresult.value = "Straight" ; break ;
    case 5 : document.PForm3.txtresult.value = "Flush" ; break ;
    case 6 : document.PForm3.txtresult.value = "Full House" ; break ;
    case 7 : document.PForm3.txtresult.value = "Four of a kind" ; break ;
    case 8 : document.PForm3.txtresult.value = "Straight Flush" ; break ;
    case 9 : document.PForm3.txtresult.value = "Royal Flush" ; break ;
    default :  document.PForm3.txtresult.value = "Unexpected result" ; break ;
  }
			
  nWin = aPays[pWhich] ;
  nBankroll += nWin ;
		
  document.PForm3.txtwin.value = nWin ;
  document.PForm3.txtbankroll.value = nBankroll ;	
}

// Set game state
function SetGameState(pWhich) {
var x ;
	
  switch(pWhich) {
    case 0 :
      if (GameState != 2 ) return ;
      ResetCards() ; break ;
    case 1 : 
      if (GameState != 0 ) return ;	
      ShuffleDeal() ; break ;
    case 2 :
      if (GameState != 1 ) return ;
      Redeal() ; 
      x = ScoreHand() ;
      ShowResults(x) ;
      break ;	
    default :
      alert(pWhich) ;
    break ;	
  }
  GameState = pWhich ;
}

/* 
 * -- end of functions -- 
 */

var vRank = null, vSuit = null, vColor = null, vNumRank = 0, vNumSuit = 0, vCardMask = 0 ;
var GameState = 0 ; 
var nBankroll = 2000 ;

// scoring arrays
var aRanks = new Array(13) ;
for (i = 0 ; i < 13 ; i++) {
  aRanks[i] = 0 ;  
}

var aPays = [0, 5, 10, 15, 20, 30, 45, 125, 250, 4000] ;

// create and initialize our deck	
var Deck = new Array(52) ;

for (i = 0 ; i < 52 ; i++ ) {

  switch (Math.floor(i / 13) ) {
    case 0: vSuit = "Spades" ; vColor = "black" ; vNumSuit = 1 ; break ;
    case 1: vSuit = "Hearts" ; vColor = "red" ; vNumSuit = 2; break ;
    case 2: vSuit = "Diamonds" ; vColor = "red" ; vNumSuit = 4; break ;
    case 3: vSuit = "Clubs" ; vColor = "black" ; vNumSuit = 8; break ;
    default: vSuit = "Error" ; vColor = "green" ; break ;						
  } 
	
  switch (i % 13) {
    case 0: vRank = "Ace"    ; vCardMask = 1 ; break ;
    case 1: vRank = "Two"    ; vCardMask = 2 ; break ;
    case 2: vRank = "Three"  ; vCardMask = 4 ; break ;
    case 3: vRank = "Four"   ; vCardMask = 8 ; break ;
    case 4: vRank = "Five"   ; vCardMask = 0x10 ; break ;
    case 5: vRank = "Six"    ; vCardMask = 0x20 ; break ;
    case 6: vRank = "Seven"  ; vCardMask = 0x40 ; break ;
    case 7: vRank = "Eight"  ; vCardMask = 0x80 ; break ;
    case 8: vRank = "Nine"   ; vCardMask = 0x100 ; break ;
    case 9: vRank = "Ten"    ; vCardMask = 0x200 ; break ;
    case 10: vRank = "Jack"  ; vCardMask = 0x400 ; break ;
    case 11: vRank = "Queen" ; vCardMask = 0x800 ; break ;
    case 12: vRank = "King"  ; vCardMask = 0x1000 ; break ;
    default: vRank = "Error" ; break ;						
  } 
	
  vNumRank = (i % 13) ;
	
  Deck[i] = new Card(vSuit, vRank, vColor, vNumSuit, vNumRank, vCardMask) ;
}	

// create and initialize our poker hand
var Hand = new Array(5) ;

for ( i = 0 ; i < 5 ; i++ ) {
  Hand[i] = new Card(0, 0, 0) ;
}

ResetCards() ;
	
//-->
</script>


Code in the page

<table border=0 cellpadding=5 cellspacing=2><tr>

<td align=center colspan=5>

<input type="text" name="txtresult" length=10 value="">        
<input type="text" name="txtwin" length=10 value="">
<input type="text" name="txtbankroll" length=10 value="">

</td>

</tr><tr>

<td align=center>
<img name="CardImg0" src="graphics/cards/b.gif" border=0>
</td><td align=center>
<img name="CardImg1" src="graphics/cards/b.gif" border=0>
</td><td align=center>
<img name="CardImg2" src="graphics/cards/b.gif" border=0>
</td><td align=center>
<img name="CardImg3" src="graphics/cards/b.gif" border=0>
</td><td align=center>
<img name="CardImg4" src="graphics/cards/b.gif" border=0>
</td>

</tr><tr>
<FORM name="PForm1">

<td align=center>
<input type="button" name="Hold0" value=" ... " onClick="HoldCard(0)">
</td><td align=center>
<input type="button" name="Hold1" value=" ... " onClick="HoldCard(1)">
</td><td align=center>
<input type="button" name="Hold2" value=" ... " onClick="HoldCard(2)">
</td><td align=center>
<input type="button" name="Hold3" value=" ... " onClick="HoldCard(3)">
</td><td align=center>
<input type="button" name="Hold4" value=" ... " onClick="HoldCard(4)">

</td>
</FORM>

</tr><tr>

<td colspan=5 align=center>

<FORM name="PForm2">

<input type="button" name="btDeal" value=" Deal " onClick="SetGameState(1)">
<input type="button" name="btDraw" value=" ... " onClick="SetGameState(2)">
<input type="button" name="btCardReset" value=" ... " onClick="SetGameState(0)">

</FORM>

</td>

</tr></tr></table>