Bookmark and Share


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.

  if (curPlayerHand >= numPlayerHands) {
  else {
    addClassName(player[curPlayerHand].fieldNode, "activeField");

    // Enable/disable buttons.


    // 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.


  // 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) {

  // 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);

  // 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");

function dealToDealer() {

  // Give the dealer another card and check the result.

  dealer.addCard(getNextCard(), false);

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.