Blackjack
Play the game or view the source code.3. Moving to the Next Hand
Normally the player will only have one hand to play, so once he or she finishes the dealer's hand is played (step 4). However, if the player split (and possibly resplit), we need to repeat step 2 for each of the additional hand that has been created.
The startNextHand()
function takes care of this, using the
globals numPlayerHands
and curPlayerHand.
function startNextHand() { // Unhighlight the current hand. removeClassName(player[curPlayerHand].fieldNode, "activeField"); // Go on to the next player hand or the dealer. curPlayerHand++; if (curPlayerHand >= numPlayerHands) { startDealer(); return; } else { addClassName(player[curPlayerHand].fieldNode, "activeField"); // Enable/disable buttons. DisablePlayButtons(); // Give a split hand a second card. if (player[curPlayerHand].split) setTimeout(playerHit, dealTimeDelay); } }
First it makes sure the current player hand is unhighlighted by resetting
its style class. Then it increments curPlayerHand
and checks it
against numPlayerHands
to determine if there are any more player
hands yet to play. If not, it simply calls startDealer()
and exits
(moving to step 4).
If is another player hand however, it must have been from a split. So we
highlight the next playing area, disable the play buttons and set a timer to
call playerHit()
. This causes a second card to be dealt to the
new hand after a short delay, just like a second card was dealt to the original
hand when it was split.
In this way, the round starts over in step 2 but with the next hand in the
players[]
array as the current one.
4. The Dealer's Turn
At this stage, the player has finished with his or her hand and any
additional hands created by splitting. Now it's the dealer's turn. The
startDealer()
function performs this step.
function startDealer() { var i, allBusts; // Enable/disable buttons. DisablePlayButtons(); // If player has busted on all hands, end the round. allBusts = true; for (i = 0; i < numPlayerHands; i++) if (player[i].getScore() <= 21) allBusts = false; if (allBusts) { endRound(); return; } // Otherwise, highlight the dealer's hand, show the down card and score and // play the hand. addClassName(dealer.fieldNode, "activeField"); dealer.cardsNode.firstChild.firstChild.style.visibility = ""; dealer.scoreTextNode.nodeValue = dealer.getScore(); setTimeout(playDealer, dealTimeDelay); }
First it disables all the play buttons. Then it checks to see if the player busted (on all player hands). If that's the case, the dealer doesn't need to take any cards. The player has already lost all bets.
When the dealer does have to play, we highlight the dealer area, show the
dealer's face down card and score, and set a timer to call the
playerDealer
function.
This function first checks the dealer's score. By rule, if it is less than
17, the dealer has to take another card. So a timer is set to call the
dealToDealer()
function and we exit.
function playDealer() { var d; // Get and show the dealer's score. d = dealer.getScore(); dealer.scoreTextNode.nodeValue = d; // If the dealer's total is less than 17, set up to deal another card. if (d < 17) { setTimeout(dealToDealer, dealTimeDelay); return; } // Check if the dealer busted. if (d > 21) dealer.scoreTextNode.nodeValue = "Busted (" + d + ")"; // Dealer is done, unhighlight the hand and end the round. removeClassName(dealer.fieldNode, "activeField"); endRound(); } function dealToDealer() { // Give the dealer another card and check the result. dealer.addCard(getNextCard(), false); playDealer(); }
All the dealToDealer()
function does is add a card to
the dealer's hand and call playDealer()
again. Using a timer
causes a short delay between each card, similar to how the initial cards for
the round were dealt.
Within playDealer()
, when the dealer's score is 17 or more we
call the endRound()
function. This moves us to step 5.