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>