January 12, 2015 by Daniel P. Clark

Vanilla JavaScript – Stepping into the language

When you see “vanilla JavaScript” it’s titled for not having any added “flavors” of JavaScript.  Not to be confused with the Vanilla-JS framework.  In other words it’s the unadulterated original language.  On my blog post about JavaScript being easy with jQuery I received a few comments about JavaScript being easy anyway.  jQuery is designed so that you “Write Less, Do More” … which ‘would’ make it easier.  But I decided to write a little game in pure JavaScript just to get the experience.

I’m not using this as a proof of difficulty.  What I’m sharing here is simply a walk through of a game being designed in JavaScript.  And I did it for fun.

My first thought in picking a game was “What would be the easiest card game to program?”  If you guessed High Card, then you were close… honestly I think the gimmick “52 Card Pick-up” would be technically the easiest game.  Because in high card you have two players draw a card and you have to evaluate a winner.  In 52 Card Pick-up you simply drop all of the cards, and then pick them all up.  That’s one action each way.  But that’s not where my mind went when I though of the easiest card game to program.

Black Jack

My first thought was Black Jack.  In Black Jack you draw cards in the aim for being the closest to 21 without going over.  That to me seemed like a rather simple game to implement so I sat down and started typing.

The first thing you need is a deck of cards.  I had started typing out an Array of cards var cards = [“Ah”, “2h”, “3h” … but then I thought “I don’t want to type out all of these cards”.  I’ve done it before and there’s no reason I should have to again.  So I decided to let the language build the deck for me.  We know there are 13 values of card which are called at face value, and we know we have 4 suits of each face value.  So we can simply loop over each suit and each face value and insert them into the deck of cards.

var face = 'A23456789TJQK';
var suit = 'hcds';
var cards = [];
for (var s = 0; s < suit.length; s++) {
  for (var f = 0; f < face.length; f++) {
    cards.push(face[f] + suit[s]);
  }
}

If you don’t understand this for loop there are three parts within the parenthesise that implement the working loop.  the first part var s = 0; creates the value 0 in the variable s which is what the loop will work with. The middle parameter is the condition on which the loop will continue: s < suit.length; (while s is less than the length of suit).  While this is true the loop continues.  And the third option will increment the variable s by 1 each time the loop is completed (s++).

I won’t be discussing all of the language parts.  I’m writing this as though you have some understanding of programming, but allowing some teaching on bits that may seem foreign.

As of JavaScript 1.7 other for loop features have been added to allow the behaviour of the familiar each pattern.  For that you can read the documentation on Iterators and Generators.  It’s a useful addition to the language.  I won’t be using it in this walk through.

If you’re not familiar with push and pop methods they are simply methods that push something onto the end of an Array, or pop the end item off and returns it.  And Arrays are lists of course… that is its meaning.

So now that we have a deck of cards we need to shuffle them.  In the interest of time I knew that there would be a published way to shuffle an Array in JavaScript.  So I did a search online and found the language itself didn’t have the method, but there was an excellent piece of code on StackOverflow for doing this.  So add this code:

//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com/array/shuffle [v1.0]
function shuffle(o){ //v1.0
    for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

And we can now shuffle our deck of cards.  If you want to write your own shuffle method look into Math.random().  It’ll be the tool to make your shuffle method possible.

To shuffle our cards we simply need to call shuffle on the cards and re-assign the shuffled cards to cards.

cards = shuffle(cards);

Now we have a shuffled deck of cards.  Feel free to console.log(cards); and see for yourself.  Now we need two players.  We need the dealer, and the player.

var playerHand = [];
var dealerHand = [];

var players = [playerHand,dealerHand];

I’ve created the players Array in order to help when dealing the cards out:

for (var p = 0;p<players.length;p++){
  players[p].push(cards.pop());
  players[p].push(cards.pop());
}

Here I go over the player Array and deal each player two cards by popping it off the deck and pushing it into the player hand.  The p variable here is simply an index in the Array.  The first time it’s 0 and selects the player at the beginning of the player Array.  In other words the first player.  And after the first loop p changed to 1 thereby selecting the second player and then dealing them two cards.

Now we have two cards in each players hand.  Now we just need to show the user who’s playing the game and give him, or her, the option to draw a card or stay with the hand held.  So let’s create a function for the display.

function turn(){
  return prompt("The dealer is showing: " + dealerHand[0] +
    "\nYou have: " + playerHand +
    "\nEnter h for Hit or s for Stay");
}

Now that we have a method for the text to display, lets display it and give the user control of the game.  Notice dealerHand[0], this is only showing one of the dealers cards.

var action = "";
do {
  action = turn();
  if (action == "h") {
    playerHand.push(cards.pop());
  }
} while(action != "s");

So this will eternally display the turn information until the user hits s and enter to quit.  If the player hits h then another card will be dealt to the players hand.  And then the prompt display shows up again.  Once the user hits s we need to show the end values of the game.  Since the dealer has only been showing one card this whole time we need to know what the hands are for the user to figure out if he, or she, won.

alert("The dealer is showing: " + dealerHand +
  "\nYou have: " + playerHand);

And there you go.  With this both I and you have successfully written a Black Jack game.  It doesn’t have any rules yet, and it can’t tell you who won.  But the basics of the game are finished.

Determining a Winner

Lets continue on this game development journey.  Before we can determine a winner we have to determine the value of each individual card.  This is the function I came up with:

function cardWorth(card){
  card = card[0];
  if (card=='A'){
    return 1;
  } else if (!!parseInt(card)){
    return parseInt(card);
  } else{
    return 10;
  }
}

Here we set that we’re only interested in the first character of the string card[0].  Since that holds the face value of the card.  Next we check if it’s an ace with if (card == ‘A’) and if so we return 1 as the value.  I realize that Ace can be either 1 or 11 in value, I decided to write another method to handle that.  In the next conditional statement I check if the string is an Integer value else if (!!parseInt(card))parseInt will turn a String into an Integer if it is indeed an Integer.  If it’s not an Integer then parseInt will return “NaN”(Not a Number).  I use double exclamation points to turn the result from parseInt as either true or false (known as a boolean).  So if parseInt is successful it becomes true because of !! and then we simply call return parseInt() since the face card value is the Black Jack value.  Lastly in Black Jack 10, Jack, Queen, and King are all worth 10 points so we just return 10 (if the card is not an Ace of an Integer).  Now we have a method for the card value.

As for figuring out Aces we want to know how many Aces are held because now that we’ve already counted the value of Ace as 1.  So then for every Ace in the hand the value could be +10 per Ace.

function aceQuantity(hand){
  qty = 0;
  for (var card = 0;card<hand.length;card++){
    if (hand[card][0] == 'A'){
      qty++;
    }
  }
  return qty;
}

So now that we can determine a cards worth and count how many Aces we have we are ready to get the hand worth.

function getWorth(hand){
  cumulative = [0];
  for (var card = 0;card<hand.length;card++){
    cumulative[0] += cardWorth(hand[card]);
  }
  for (var a = 0;a<aceQuantity(hand);a++){
    cumulative.push(cumulative[cumulative.length-1] + 10);
  }
  return dropObvious(cumulative);
}

The first for loop here simply adds the value of each card to the first value within the Array called cumulative.  The reason to use an Array is because we want to display all of the possible values that hand currently has.  If a person is holding an Ace that can be 1 or 11.  The second for loop takes the value of the hand and adds an extra value of +10 to the list for every Ace in the hand by adding it to the original total hand worth and inserting this new potential value at the end of the Array.  From there we just need to return the values of the hand with return cumulative.  As you can see I threw in the method call dropObvious.  Here’s the code I wrote for that:

function dropObvious(worthes){
  while (worthes.length > 1){
    if (worthes[worthes.length-1] <= 21){
      break;
    } else {
      worthes.pop();
    }
  }
  return worthes;
}

The dropObvios method is written to drop all values that are above 21 up until the first value in the Array.  We want to return at least one value regardless.  The Array that is coming in to this method will be numbered from smallest to greatest.  So we drop all the numbers from the right to the left until it’s 21 or less or only one entry remains.

Now we have what we need to check the player and dealer hands.  But we also need to consider the dealer.  The dealer will typically draw a card if his hand is below 17.

var dealerHitWhenBelow = 17;
function dealDealer(){
  while (getWorth(dealerHand) < dealerHitWhenBelow){
    dealerHand.push(cards.pop())
  }
}

I’ve set the variable for dealerHitWhenBelow outside of dealDealer because we want to keep configurable items, like this, in one location.  A good spot for settings is at the beginning of the file.

Now let’s change our main method for reading the hand values:

function turn(){
  return prompt("The dealer is showing: " + dealerHand[0] + " worth " + getWorth([dealerHand[0]]) +
    "\nYou have: " + playerHand + " worth " + getWorth(playerHand) +
    "\nEnter h for Hit or s for Stay");
}

And when we cycle through the game we will now do it this way:

var action = "";
do{
  action = turn();
  if (action == "h") {
    playerHand.push(cards.pop());
  }
  if (getWorth(playerHand) > 21) {
    break;
  }
}while(action != "s");

dealDealer();

Here I’ve added a break to exit the loop if the players hand busts.  Also I made a call to dealDealer() after the players turn ends.  Next we need to declare who won.  So lets make a comparison method:

function comparePlayerDealer(player, dealer){
  if (player > 21) {
    return "You Bust!";
  } else if (dealer > 21) {
    return "Dealer Busts!";
  } else if (player == dealer){
    return "Push!";
  } else if (player > dealer){
    return "You Win!";
  } else {
    return "You Lose!";
  }
}

And now to put the update at the end of the game we do:

var playerWorth = getWorth(playerHand);
var dealerWorth = getWorth(dealerHand);

alert("The dealer is showing: " + dealerHand + " worth " + dealerWorth +
      "\nYou have: " + playerHand + " worth " + playerWorth +
      "\n" + comparePlayerDealer(playerWorth.pop(),dealerWorth.pop()));

And that’s it!  We have a working Black Jack game which can tell you who won.  The only features missing are splitting your hand, doubling down, and multiple players.  Feel free to have a crack at those yourself.

Summary

This project gave me a bit of nostalgia.  It reminded me of when I first learned Python and I didn’t understand what Objects or Classes were.  I wrote a lot of code without those back in the day.  Maybe it goes back further then that… when I would write some code in qBasic.

Well this project was a lot of fun.  If you found things not working when you put this together it’s possible it wasn’t in the right order.  The functions needed to be declared before they get called, so I put the code that runs right away at the end.  I’ve included a working example link for you here: http://jsfiddle.net/9p2kvw6h/

I know I didn’t explain everything.  But that was not my intent.  I wanted to show more the process.  It’s good practice to read code and glean understanding from it.  If something here doesn’t make sense to you then you should experiment with it and try some changes.  See what happens.  It’s best if you learn by doing.

As always I hope this was an enjoyable read for you!  Please comment, share, subscribe to my RSS Feed, and follow me on twitter @6ftdan!

God Bless!
-Daniel P. Clark

Image by a.pasquier via the Creative Commons Attribution-ShareAlike 2.0 Generic License.

#article#Black Jack#blog#game#javascript#language#post#program#programming

Leave a Reply

Your email address will not be published / Required fields are marked *