If you would like a file with answers, please contact javajackdev@gmail.com and we will give you the URL.

--------------------------------------------------------------------------

Contents

  • Welcome!
  • Mission 1: Name Yourself — Variables and Strings
  • Mission 2: Hit — Functions
  • Mission 3.1: Hit or Stand — Conditional Statements
  • Mission 3.2: Hit or Stand — Booleans
  • Mission 3.3: Hit or Stand — Using Boolean Expressions
  • Mission 4.1: Better Strategy — Introducing Functions
  • Mission 4.2: Better Strategy — Writing Functions
  • Mission 4.3: Better Strategy — Introduction to Arrays
  • Mission 5: Organize Your Code — Comments on Commenting
  • Mission 6.1: Total Value With More than Two Cards — Loop Setup
  • Mission 6.2: Total Value With More than Two Cards — Make the Loop Loop
  • Mission 7.1: Cleaning Up Your Code — Incrementation Shortcuts
  • Mission 7.2: Cleaning Up Your Code — For Loops
  • Mission 8.1: Betting — Nested Conditionals and More Functions with Parameters
  • Mission 8.2: Betting — Do it Yourself: Functions with Parameters
  • Mission 9.1: Double Down — Multiple If Statements in a Row
  • Mission 9.2: Double Down — Else if
  • Mission 9.3: Double Down — And and Or
  • Mission 10.1: Hit or Stand Based on the Dealer's Hand — More Practice with If Statements and Boolean Expressions
  • Mission 10.2: Hit or Stand Based on the Dealer's Hand — Even More Practice with If Statements and Boolean Expressions
  • Mission 11.1: Card Counting — Simple Work With If and Elseif
  • Mission 11.2: Card Counting — Making Arrays
  • Mission 11.3: Card Counting — Arrayception
  • Mission 11.4: Card Counting — Using Conditionals to Fix a Problem
  • Mission 11.5: Card Counting — Using Variables as Parameters
  • Mission 11.6: Card Counting — Using Functions to Eliminate Duplicate Code
  • Mission 11.7: Card Counting — Using More Functions to Eliminate More Duplicate Code
  • Mission 12.1: Ace as 11 or 1 — Advanced Logic
  • Mission 12.2: Ace as 11 or 1 — Preparing to Implement Advanced Logic
  • Mission 12.3: Ace as 11 or 1 — Implementing Advanced Logic (Putting Everything Together with Most Complicated If-Else Statements Ever)
  • The End!
  • --------------------------------------------------------------------------

    Welcome!

    Hello, and welcome to JSJack's Casino! We hear you want to learn to program, and to make vast sums of money doing it. Well, you've come to the right place! We're going to teach you how to write a program to ensure you make bank playing Blackjack. In the process, you'll learn the fundamentals of programming, as well as some intense Blackjack strategies. The tutorial may take a while, but you can log back in later to finish it. By the end, you'll have an awesome Blackjack program, complete with betting and even card counting! Use the buttons to the right to play a hand or two. Then click continue to learn how to program the computer to play for you!

    For those of you who don't know what Blackjack is, it's a card game in which every player tries to get a hand with a value of as close to, but no more than, 21 as possible. Face cards are worth 10 points, the Ace can be 1 or 11, and every other card is worth its face value. You play against a dealer. You and the dealer will each be dealt two cards at the beginning of the game. You will be able to see one of the dealer's. You will then have the option to "hit" (get another card) as many times as you'd like. Once you don't want any more cards, you "stand." Be careful! If the value of your cards exceeds 21, you "bust," that is, you lose! Once you stand, the dealer will draw cards. The dealer must hit if the total value of his/her cards is less than 17, and must stand if it is 17 or greater. When determining this, an Ace is counted as an 11. If the dealer busts and you don't, you win. If no one busts, whoever has a higher hand wins. A few more important things: If either player is initially dealt 21, that's a "Blackjack" and that player wins. If the players tie, the dealer wins (unless both players have Blackjack. Then it's just a tie.) If you get 5 cards without busting, you win. There are some more rules, including betting, but we'll get into those later. If you want more information, click here.

    --------------------------------------------------------------------------

    Mission 1: Name Yourself — Variables and Strings

    Let's get down to business! During the course of this tutorial, it is important to remember you are not programming the entire game. You're programming what you want to do when it is your turn in the game. We've written some code to tell the dealer how to respond when you tell it you want to hit or stand. It is also potentially useful to know that you will be programming in a language called JavaScript. There are many different programming languages, but the concepts underlying each are the same. Once you understand how to program in one language, it is easy to learn another!

    At the top of the page is a link to a glossary of concepts and terms and another link to a page with all of the lessons on it. These will help you later on in the tutorial if you need a reminder of how to do something.

    We don't want this tutorial to feel impersonal, so the first step is for you to name yourself. Your name needs to be stored in a variable so the computer can use it in the game and tutorial. A variable is simply something that stores a value, or piece of information. What you need to do is make a variable called name and set its value to your name. To do this, type

    var name = "yourname";

    in the box below the cards.

    There are a few important things to note here. First, "name" is the name of the variable. The var in front of name tells the computer that name is a variable. yourname, like any other series of letters, is called a string and must be enclosed in quotes. The = assigns the value on the right ("yourname") to the variable on the left (name). (The spaces on either side of = aren't necessary but make the code look neater.) The semicolon tells the computer that the line of code has been completed. That's it! Click submit and watch your name appear below your cards. (Since you didn't tell the computer you wanted to do anything regarding the gameplay, it didn't give you any more cards but still proceeded to play the game. Don't worry, that's the next step!

    --------------------------------------------------------------------------

    Mission 2: Hit — Functions

    Hello there, [NAME]! Nice to meet you. Good work on the first mission. Now it's time to learn how to program the computer to play the game!

    A function, also known as a method, is a short line of code that makes the computer do stuff. You'll learn how to write a function later, but for now, try one we wrote that hits. (Remember, hitting is asking the dealer for a card, not attacking him or her.) To do that, on the line below the one where you set your name, type

    hit();

    "hit" is the name of the function. Every function name is always followed by open and closed parentheses (). And notice that the semicolon is once again present to end the line. Hit submit, and the dealer will deal you cards until you bust! Every time the dealer asks your program what it wants to do, it says hit. That's not a very good Blackjack strategy, but that's ok. You know how to make the computer do things, and, as the tutorial goes on, your program will get better and better at winning. One final thing to notice here: No matter how many blank lines you put between your naming command and your hitting command, the computer will still do the same thing. Try it!

    If your code is not working or your name is no longer displaying correctly, make sure your code looks like this. (Even if it seems like your code is working, it's always a good idea to check our solution just in case you have a small error.)

    --------------------------------------------------------------------------

    Mission 3.1: Hit or Stand — Conditional Statements

    Alrighty, [NAME]! You are now successfully playing Blackjack. You'll bust every time, but that's what we're about to fix. We're going to get into some serious stuff here, so this mission will be divided into multiple parts.

    In Blackjack you obviously don't want to hit every time because you'll end up busting. What you want to do is hit under some circumstances and stand under others. Fortunately, programming languages have a simple way to do these kinds of conditional actions with if-else statements. Esentially you tell the computer if something is true, do A, otherwise do B. In JavaScript, the syntax for this statement is

    if (somethingtrue) { A; } else { B; }

    Else is JavaScript's word for "otherwise." Delete hit(); and type the above statement into the box on the right below your name-setting command. We'll fill it in soon. Notice that there are semicolons after the commands A and B but not after if() and else. The braces { } following if() and else surround the command (A or B) that is performed in each case. Just like it doesn't matter how many blank lines are between two commands, the indentations don't matter either. They just make it easier to read, which is especially important if you are working with other people.

    Now we need to replace somethingtrue, A, and B with commands the computer can read. A and B are easy. We want to hit if something is true and stand if it's not, so replace A with hit(); and B with stand();. stand() is another function we wrote for you. For now, just replace somethingtrue with true. (JavaScript knows what true means although somethingtrue is just gibberish.) Your code should now look like

    if (true) { hit(); } else { stand(); }

    Press submit to check your work. The game will hit every time because the statement in the parentheses after if is literally always true.

    --------------------------------------------------------------------------

    Mission 3.2: Hit or Stand — Booleans

    Excellent! Now we just need to replace true with something that you want to be true before you hit. First, you need to understand booleans. A boolean is a type of variable that is either true or false. true is a simple boolean.

    Hitting every time isn't very useful, so now we need to use a boolean expression, or comparison. A boolean expression returns true or false based on whether the comparison being made is true or false. "Return" simply means "give the computer a value based on evaluated code." There are a few comparisons you can make between variables and numbers:

    Try replacing true with

    3 === 3

    and press submit. Since 3 does in fact equal 3, the computer will hit! Now, replace one of the 3's with a 4 and press submit. Your player should now stand every time because 3 does not equal 4; that is, the expression returns false and so the computer skips over the if statement and straight to the else statement. Try experimenting with comparing numbers using <= and other operators.

    You can also compare the values of variables. Try replacing the expression inside the parentheses after if with

    name === "[NAME]"

    The program will evaluate this as true and hit every turn! This is because you set name to hold "[NAME]." Instead of comparing a number to a number, you are comparing a variable to a string. Replace "[NAME]" with a different string, and it will evaluate as false and the program will stand. Try it!

    There's one other cool thing you can do with boolean expressions. What if you wanted to see if something is not equal to something else? An ! means "not" in boolean expressions. So, !== checks to see if the thing on the left is NOT equal to the thing on the right and returns true if it is unequal and false if it is equal. It's the opposite of ===. Try replacing the === in the statement comparing name to a string that isn't your name with !==. The computer will now evaluate this statement as true and will once again hit every turn.

    --------------------------------------------------------------------------

    Mission 3.3: Hit or Stand — Using Boolean Expressions

    Alright, so this is all fine and dandy, but how does it help with Blackjack? Let's start with something simple. We wrote a function for you called secondDealtCardVal(). This function does something you haven't seen before: It returns a value just like a boolean expression does. Recall that hit() and stand() simply make stuff happen but don't give any information. A function that returns a value can be treated like any other value. That means it can be set to a variable to store the value returned by the function, similar to how you set "[NAME]" to name. For example, if you had a function called findYourName() that returned a string containing your name, you could rewrite the first line as

    var name = findYourName();

    This line would do the same thing. The findYourName function doesn't exist because that would require the computer to read your mind, so don't try this one!

    Anyway, secondDealtCardVal() returns the value of the second card you were dealt. For instance, if the second card you got was a Jack, it would return 10. If it was a 4, it would return 4. A very simple conditional statement for this hit or stand task would be "if the second card dealt to me is less than 7, hit, otherwise, stand." This will increase your winning percentage because if one of your cards is a low number, you are less likely to bust so you can afford to hit. (Of course, this is a very imperfect strategy but we'll improve it later.) So, we need to put a statement that checks to see how the value of the second card dealt compares to 7 inside the parentheses of the if statement. Remember how we said you can assign secondDealtCardVal() to a variable? Well you can also compare it to a variable or number with the same boolean expressions described above!

    We said we were going to check to see if the value of the last card dealt was less than 7, so make the if statement read

    if(secondDealtCardVal() < 7)

    Now, hit submit and play the game a few times. Observe how your program tells the dealer it wants to hit if your second card is a 2, 3, 4, 5, or 6 and otherwise stands! (We're counting the ace as an 11 in secondDealtCardVal() and you will continue to do so in the following code we will have you write. The game engine will still count an Ace as 1 or 11, but this is more difficult to deal with, so we won't have you worry about that yet. As a result, your code won't be perfectly evaluating the game, but towards the end of the tutorial we'll have you fix the problem.)

    Notice that, given the 6 comparisons from mission 3.2 (===, <, >, <=, >=, !==), there are more ways than one to write the conditional statement inside the parentheses following if. For example, you could say that secondDealtCardVal() should be less than or equal to 6, which is the same thing as saying less than 7 since the values are whole numbers. You could also say 7 is greater than secondDealtCardVal(). What else could you say? Try it out! You can also try numbers other than 6 and see if you win more often!

    Before going to the next step, let's talk a little bit about the order the computer does things. The computer starts reading your code at the top and moves down line by line. So, the first thing that happens is you tell the computer your name. Then you tell it to check if it should hit, and finally to stand, if you don't hit. If you change the order of the code, the computer will process things in a different order. For example, if you put the name declaration at the end, it will assign the name after you take a card. The computer is so fast, this probably will be hardly noticeable! You'll see a case when the order is crucial later.

    If your code is not working properly, make sure it looks like this.

    --------------------------------------------------------------------------

    Mission 4.1: Better Strategy — Introducing Functions

    Whew! That was a long mission. But you did it, and now you're really starting to understand how to use the computer's power of logic. The strategy we just designed is, of course, not a very good one. The value of the last card you were dealt really has very little bearing on whether you should hit because the first card you were dealt could be anything! Let's fix that problem.

    The program would work a lot better if it hit every time the TOTAL value of ALL your cards was less than, say, 17, and stand otherwise. (Notice that these are the rules the dealer is playing by. Playing by these rules will improve your chances of winning, but the dealer still has a higher chance because the dealer wins in the event of a tie.)

    This is a bit tricky. Instead of checking the value of the last dealt card, we need to check the value of both cards. So, secondDealtCardVal() needs to be replaced by a function that returns the total value of the two cards. Let's call that function totalValue(). Replace secondDealtCardVal() with totalValue().

    The second part is easy. The total value needs to be less than 17, so we just replace 7 with 17! That line should now read

    if (totalValue() < 17) {

    Press submit. What happens? The game tells you there is an error because a function is undefined. The problem is that totalValue() doesn't exist! secondDealtCardVal() exists because we wrote it for you, but we didn't write totalValue(). That's your job!

    --------------------------------------------------------------------------

    Mission 4.2: Better Strategy — Writing Functions

    A function is a command that represents a block of code. You've been using some we wrote for you, namely hit() and stand(). Every time the command is given, the computer finds where the function is written, does what it says, and then returns to the rest of the code. To start writing a function, go to the end of your code, after the last brace of the else statement, and type

    function totalValue(){ }

    function must be included at the beginning of your code to tell the computer this is a function. When it sees this, it knows to use this code when the function is called. The braces { } after totalValue() will contain the code that the function executes.

    Let's take a quick break here to discuss naming rules and conventions. First, no two variables or functions can have the same name! When you name a variable or function in JavaScript, you can use letters, numbers, and underscores, but cannot start with a number. Names of two or more words are usually either written with the first word lowercase and all other words capitalized (totalValue) or every word lowercase and separated with an underscore (total_value). You can use either name for totalValue(), but you MUST use the same name every time! That is, if you write

    function total_value(){ }

    here you must write

    if(total_value() < 17){

    above.

    Anyway, now we're going to make this function do something. Remember, this function needs to return a value. Between the braces of the function, type

    return 3;

    and run the program. totalValue() now always returns 3. Because 3 is less than 17, the computer will always hit.

    You can make the computer evaluate mathematical expressions, too. Replace "3" with "3 + 18" and run the program. Now totalValue() returns the sum of 3 and 18 (21) so the program will call stand(). In most programming languages, there are 5 mathematical operators available: + is used for addition, - is used for subtraction, * for multiplication, / for division, and % for modulus. Modulus divides the two numbers and returns the remainder.

    --------------------------------------------------------------------------

    Mission 4.3: Better Strategy — Introduction to Arrays

    Ok. We know how to add numbers, but now we need to figure out what the numbers are. Before, you used secondDealtCardVal() to find the value of one card. Unfortunately for you, there's no firstDealtCardVal() function, so you need to understand how the cards in your hand are stored. The values of the cards are stored in an array called handValue. An array is a numbered list of data. To access something in this array, one types

    handValue[position]

    where position is replaced by a number or numerical variable representing the spot in the list you want information from. There is one confusing thing here: JavaScript, like most programming languages, starts numbering arrays at 0. So, the first spot in the array is 0, the second is 1, and so on. (This is another common mistake. Don't forget!) This means that handValue[0] will return the value stored at the first position in the handValue array, that is, the value of the first card in your hand. Likewise, handValue[1] returns the value of the second card. (That's all that secondDealtCardVal() is doing! So, there will be no need to use that function anymore.)

    As you may have guessed, you can add these values together just as you would regular numbers. So, replace

    return 3 + 18;

    with

    return handValue[0] + handValue[1];

    This will add the values of your two cards and return them to the boolean expression in the if statement, where it will compare the sum to 17! Click submit, and observe how the computer only hits when the value of both cards is less than 17. Huzzah! (Yes, we know its still not a great strategy and your code ignores any other cards you are dealt, but wait till mission 6!)

    An important note: Just like with other variables, arrays must have var in front of them if you are creating them. After you create any type of variable, you no longer need to refer to it with var.

    If your code is not working properly, make sure it looks like this.

    --------------------------------------------------------------------------

    Mission 5: Organize Your Code — Comments on Commenting

    Well, it looks like you're well on your way to becoming a professional Blackjack programmer, [NAME]! But your code is getting a bit complicated. It's very important to remember what each part of your code does in case you need to edit it later. Fortunately, you can comment it. Comments are notes in your code that the computer ignores. You can type anything you want in comments without worrying about the computer doing something weird.

    Commenting is extremely important when you are working in groups; no one wants to trawl through code just to understand what a function does. As not commenting may incite the wrath of angry programmers, you'll always want to comment.

    There are two types of comment notation in JavaScript. The first is a single line comment. It is written like this

    //type your comment here

    Anything on the line after the two slashes will be skipped over by the computer. This can be used for adding notes or for "commenting out" lines of code that you want the computer to skip.

    You can also put a comment on a line after a piece of code. For example,

    function totalValue(){ //type your comment here

    The computer will still see the function declaration because it is before the // but will not see the comment. This is very useful for adding notes about what a line does.

    The other type of comment is a multiline comment. It begins with /* and ends with */ For example,

    /* part 1 of comment part two of comment part three of comment */

    The computer will skip over all three of those lines!

    Add some comments to your code to remind yourself what's happening at each step, and then hit submit. Nothing different should happen!

    To see some commenting suggestions, click here.

    --------------------------------------------------------------------------

    Mission 6.1: Total Value With More than Two Cards — Loop Setup

    If you've played the game a few times, you may have noticed that your program does a decent job determining if it should hit or stand the first time, but then keeps making the same decision every time until you bust! That's no good! The problem is that no matter how many card you have, totalValue() is only summing the value of the first two.

    An obvious solution is to change the return line in totalValue(){ to

    return handValue[0] + handValue[1] + handValue[2];

    but there are two problems with this. Make this change, click submit, and you'll see the first one. When you have only two cards, handValue[2] (which would check the third card) doesn't exist and so JavaScript returns "undefined". For some stupid reason, it doesn't warn you of this, but you'll see that the program stands every time as a result. Even if it didn't make this error, it would only add the first three cards you get; not very helpful when you have four cards in your hand.

    We can fix both these problems with loops. There are two kinds of loops. The first and most basic kind is a while loop. It's syntax looks like

    while(somethingtrue){ }

    This should remind you of an if statement. When the computer reaches this while loop, it will do whatever is inside the braces { } over and over as long as the argument inside the parentheses ( ) remains true. Once the argument is false, the computer will skip the loop and continue reading the code after the loop. But be careful! If the argument in the parentheses is always true, the loop will never end, and the game and possibly even your entire web browser will crash. That would really be a downer. Therefore, it is important that you, for this step, literally write somethingtrue and not something that the computer can read. But don't worry too much: We automatically save your progress, so you won't have to start over from mission 1 if that happens.

    Delete the return statement in the totalValue() function and replace it with the basic while loop structure. What we are going to do is declare a variable that holds the length of the hand. We will declare another that is a counter which will count how many times we've gone through the loop, and one more that will hold the sum of the values of the cards in your hand. This last variable is the important one: It will be returned by the function. To declare these variables, write, immediately before the while loop,

    var length = handValue.length; //set length to the size of the hand var counter = 0; //counter variable, starts at 0 var sum = 0; //sum of card values, to be returned

    The comments don't need to be written, of course, but will be helpful for you. Remember, you can name the variables whatever you want as long as your consistent. Take another look at the first line you just wrote. length is a variable defined by JavaScript that holds the length of the array. Writing arrayName.length returns the length of the array. Finally, note that every time this function is called, it will reset length to the current length of this array. That is important, because the size of your hand can change every turn.

    Press submit to check your structure.

    --------------------------------------------------------------------------

    Mission 6.2: Total Value With More than Two Cards — Make the Loop Loop

    Every time we run through the loop, we need to add the value of the current spot in the array to the variable sum and then increment the counter by one to keep track of our place in the array. Inside the braces { } of the while loop, write

    sum = sum + handValue[counter]; counter = counter + 1;

    Don't get scared by all the variables, its simpler than you think. Notice var appears nowhere in this line: You only use it when creating a variable. The first line sets sum to itself (initially zero) plus the value of the card at position counter. This may seem a little strange, but recall that counter is just a variable representing a number. It starts at 0, so this line is initially just like saying

    sum = sum + handValue[0];

    The second line sets counter to itself plus one, so the second time it runs through the loop the first line will get the value at position 1, the third time will get the value at positon 2, and so on. Remember when we promised you'd see a case where the order of commands was crucial? This is one. It is important that the adjustment of counter occurs after that of sum or else the first spot would be skipped.

    Now we just need to replace somethingtrue with a boolean expression telling the computer to run through the loop until it has gone through the whole hand. Since counter is counting the position in the hand, we can compare this value to length, the variable that represents the size of the hand. Inside the parentheses following while, write

    counter < length

    Some tricky stuff: Why did we use < instead of <=? Remember that counter, like the positions in an array, starts at 0. However, when .length "counts" and returns the size of an array, it starts at 1. So, if you have an array with 4 items in it, the last position is 3 and .length will return 4. 3 is the last number that is less than 4, so position 3 is the last position that will be added to sum. Once counter is incremented to 4, the statement in the while loop will be false because 4 is equal to, not less than, the size of the array and the loop will then be skipped. The program will continue after the loop. If you used <=, the computer would try to find something at position 4 and you'd have another problem due to JavaScript returning "undefined."

    Now all that's left is to return sum, the total value of all cards. After the closing brace of the while loop, write

    return sum;

    Press submit, and observe how the computer makes a different decision when you have more cards!

    If your code is not working properly, make sure your totalValue() function looks like this. This is not the entire program! For most of the rest of the tutorial, we will only be showing you the new parts of the code because the program is getting so long. We deleted comments since your comments don't need to be identical to ours, but you should keep yours.

    --------------------------------------------------------------------------

    Mission 7.1: Cleaning Up Your Code — Incrementation Shortcuts

    Programmers are lazy. We don't like to type more than we have to if at all possible. As a result, programming languages have many shortcuts. Since you're going to be a programmer, you should learn to be lazy too.

    Our totalValue() function could benefit from a few of these shortcuts. First, we'll take a look at the section

    sum = sum + handValue[counter]; counter = counter + 1;

    Just look at all that unnecessary repetition! sum = sum? Clearly typing that's a waste of effort. Fortunately, we can modify both of those statements using the operator +=. Using this operator, the first line now reads

    sum += handValue[counter];

    This line does exactly the same thing as the line it replaces! Pretty awesome. Change the second line yourself following this example and then press submit. The program will work in exactly the same way. The same thing can be done with the other 4 operators: -=, *=, /=, and %=.

    Think that's enough simplification? Wrong. Programmers are even lazier than that. Take a look at the second line, and imagine how often you would have to write

    += 1

    if you were to keep making loops with counters. Too much work! Try replacing the second line with

    counter++;

    and press submit. The code does the same thing. This shortcut only exists for incrementing by 1. If you want to increment by any other number, you have to write it out. There is, however, also a shortcut for

    variable -= 1;

    It is

    variable--;

    That's as lazy as we're going to get with incrementing, but don't fear! There are more shortcuts to know.

    --------------------------------------------------------------------------

    Mission 7.2: Cleaning Up Your Code — For Loops

    Take a look at your while loop. Wouldn't it be better with fewer lines of code? Yes, it would. There is a special kind of while loop for use with counters called a for loop. A for loop basically combines all of the manipulations of the while loop and counter variable into one line. The following function is exactly the same as the one you are using with a while loop

    function totalValue(){ var length = handValue.length; var sum = 0; var counter = 0; for(counter = 0; counter < length; counter++){ sum += handValue[counter]; } return sum; }

    Much prettier! All that happened is "while" was changed to "for" and the incrementation of the counter was moved into the parentheses. So, the basic for loop structure is

    for(initialize counter; counter boundary (boolean expression); counter incrementation){ }

    The counter should still be declared before the for loop. Note each command in the parentheses is separated by semicolons, but there is no semicolon after the last command. You can think of this as three separate lines of code with the parentheses. Press submit, and notice the program does exactly the same thing with the for loop as it did with the while loop. There are instances when you should use a while loop and not a for loop, but we won't go into them in this tutorial. Also note that a poorly set boundary condition in a for loop will cause an infinite loop and crash your program just like it does in a while loop.

    Alright, we're satisfied. Enough laziness for now! (It's not all about laziness though...In general, having fewer lines of code is easier to read!)

    --------------------------------------------------------------------------

    Mission 8.1: Betting — Nested Conditionals and More Functions with Parameters

    Now that your code has been modified to reflect the lazy programmer you're becoming, it's time to get back to the game. As you may have realized, Blackjack is a little boring if there's nothing on the line. So, we're going to introduce betting.

    For those of you who don't know, you bet at the very beginning of a hand, before you are dealt cards. If you lose the hand, the dealer takes your money. If you win, you get your money back and the dealer pays you as much as you bet. If you win with a Blackjack, the dealer pays you 150% of what you bet.

    We've written a bet function for you, called bet(). Clearly, bet() needs to know how much you want to bet. So, we need some way to give it information. We will do this by passing a parameter. A parameter is data passed, or given, to a function and is written inside a function's parentheses. (Now you know what those are for!) bet() requires a parameter that is a number that represents how much you want to bet. So, if you want to bet $4, you would write

    bet(4);

    Easy, right? The problem is you can only bet at the beginning of the hand, so we need some way of telling the program that. Sounds like a job for if statements! Basically, you need to say, if it's the beginning of hand, bet a certain amount. If it's not the beginning of the hand, determine whether you should hit or stand. Try this on your own! The following information and hints will be helpful:

    See what you can figure out, and don't be frustrated if you can't get it! This is hard stuff. When you get it to work, press submit a few times to see if your program makes or loses money. (From now on you will get an error if your program does not bet money. If you run out of money, press the "reset money" button.)

    If your code is not working properly, make sure it looks like this.

    --------------------------------------------------------------------------

    Mission 8.2: Betting — Do it Yourself: Functions with Parameters

    Dang, that was a real toughie! We took the training wheels off in that one, but you made it through, and now your game will be much more fun. However, take a moment and try to bet more money than you actually have. You will be left with a negative amount of money! A casino would never let you bet more money than you actually have, so we need to modify your program so it doesn't bet more money than you have. (Reset your money before continuing.)

    This is going to require writing an improved bet function. We'll call it safeBet(). (Remember, you can call your function anything you want as long as you use the same name everywhere.) This function is going to be a bit different than the last function you wrote, totalValue(), in two ways. First, totalValue() returned something: the value of your cards. safeBet() is going to be a replacement for bet(), so it needs to bet but not return anything.

    The second difference is that totalValue() does not require any parameters — nothing needs to go between its parentheses. However, bet() takes a parameter: the amount of money you want to bet. Therefore, safeBet() needs to take this parameter as well. We'll actually give safeBet() two parameters: one will be the amount you want to bet, the other will set the limit you don't want your total amount of money to fall below. To avoid having a negative amount of money, you can set the limit to 0. However if you need some money left over to buy dinner after your trip to the casino, you can set the limit to 10. We'll call these two parameters betAmount and limit, respectively.

    The syntax for defining a function with a parameter is the same as that of defining any other function, except the variables you want as parameters should be written inside the parentheses, separated by commas. So, the betSafe() declaration should look like

    function safeBet(betAmount, limit){ }

    Write this at the bottom of your code, either before or after the totalValue() declaration.

    Now, replace the bet() command you wrote in mission 8.1 with safeBet(). When you include parameters in a function, you must pass these parameters when calling it; otherwise it won't work. To bet $4 and ensure that you will not have a negative amount of money, write

    safeBet(4, 0);

    This notation assigns 4 to betAmount and 0 to limit. Press submit. The game won't start because you didn't bet anything. That's because we haven't told safeBet() to do anything yet. Let's start by just telling it to bet a certain amount and not worry about the limit yet. This will require using the bet() function inside the safeBet() function. Write bet(); between the braces of the safeBet() declaration. We need bet() to bet the same amount that we told safeBet() to bet, so tell bet() to bet betAmount. Your function declaration should now look like

    function safeBet(betAmount, limit){ bet(betAmount); }

    Press submit, and your program should now bet $4, just like it did with bet(). Let's take a look at what's happening. When you call safeBet(4, 0), it sets betAmount to 4. safeBet() then uses bet() to bet betAmount, so the end result is that safeBet() bets 4! Currently, the second variable — the limit — does nothing, so let's now make safeBet() take it into account.

    We've created a function called totalMoney() that returns how much money you have. If you try to bet so much money that it would drive the amount of money you have below the limit you set, safeBet() needs to reduce your bet. Basically, safeBet() needs to adjust the value of betAmount if the total amount of money you have minus betAmount would leave you with less money than the limit you set. Delete bet() and replace it with an if statement that represents the conditional statement in bold. Don't put anything between the braces of the if statement yet. There will be no else statement.

    Now we just need to fill in the braces. If betAmount would drive you below the limit you set, you need to adjust betAmount so it puts you at the limit but not below. The simplest way to do this is to set bet amount equal to the total amount of your money minus the limit, like so

    betAmount = totalMoney() - limit;

    Let's talk about the logic here. Betting betAmount
    will mean that the amount of money you have after the function is called is

    totalMoney() - betAmount

    Since

    betAmount = totalMoney() - limit

    you will be left with

    totalMoney() - (totalMoney() - limit)

    which equals

    totalMoney() - totalMoney() + limit

    which equals limit! Since this command will be run if betAmount would reduce your total money to less than limit, this command will reset betAmount so it only reduces your total money to limit. Nice! At the end of your function, write

    bet(betAmount);

    so it bets the modified betAmount. Then set your limit to 0, bet more money than you have, and press submit to test it out. You should be left with no money!

    If your code is not working properly, make sure it looks like this.

    --------------------------------------------------------------------------

    Mission 9.1: Double Down — Multiple If Statements in a Row

    With the addition of betting, we can also add a part of the game called doubling down. When you double down, you double your bet and then only get one more card. You can only double down immediately after being dealt to; That is, you cannot hit and then double down. This can be a good thing to do if you have 10 or 11 points in your hand at the beginning because you won't bust and there's a high probability you'll get a card worth 10 points and have a winning hand. We'll just double down when you have 10 points in your hand at first. (For the following missions, remember that we are still only counting an Ace as 11 in your program.)

    We've written a function for you called doubleDown(). You will need to add another if statement checking to see if the value of your hand is 10 and if it is the program will need to double down. Let's think about where to put this if statement. It needs to be inside the first else statement along with the hit/stand if-else statements because it is another option for the computer to consider when planning its move. This also means it is not done at the beginning of the hand. It also needs to be checked before the computer checks to see if it should hit, for two reasons. First, after you hit you are no longer allowed to double down. Second, the range of total value that makes the program hit (range < 17) includes the range that makes it double down (range === 10). Order is important in this case. The included range must be placed first; if it were placed second it would never be reached because range < 17 would be true for a value of 10, causing you to hit when you want to double down. So, make an if statement that checks to see if the total value is 10 and, if so, doubles down and place it within the first else statement but above the if statement checking the total value. Press submit a few times, and when it does double down, you may get an error. We'll correct that on the next page.

    --------------------------------------------------------------------------

    Mission 9.2: Double Down — Else if

    This error is because of the way the language reads if statements. JavaScript first checks the double down if statement, and if it is true it doubles down. However, it then also checks the hit if statement following it. If the card you were given on the double down is a low card, it will also try to hit because the total value of the cards will still be less than 17. (Notice that this contradicts what we said in the previous paragraph about the second statement possibly getting skipped. Once this problem is fixed, the previous paragraph will hold true.) Since you are not allowed to double down and then hit, especially not on the same turn, you get an error. Even if you don't get this error because the card you are given in the double down is large enough, your program is being inefficient by doubling down and then still checking if it should hit.

    To fix this problem, we will use another piece of if-else statements called else if. As the name suggests, else if is similar to else but takes a conditional statement in parentheses just like if does. Replace the hit-checking if (the second if statement) with else if, but don't delete the parentheses or conditional statement inside them. Now, the computer will read as follows: If the total value is 10, double down. It then skips over the else if and else statements. However, if the total value is not 10, it checks to see if it's less than 17. If it is it hits and skips the final else statement. If it's not, it reads the else statement and stands. Click submit a few times and watch the program double down occasionally and not get errors. (Because it won't double down unless the total value is 10, it may take a while before you see this occur.)

    If your code is not working properly, make sure it looks like this.

    --------------------------------------------------------------------------

    Mission 9.3: Double Down — And and Or

    So now you have a functional and reasonable way for the computer to double down. But the computer's strategy isn't ideal. Recall that we said you'll want to double down if the value of your cards is 10 or 11, not just 10. How do we do that? One way would be to add another else if statement after the if statement checking to see if the total value is 11. But that's a lot of writing, and programmers are lazy. So, we have a boolean "or" operator. It looks like this: || (The vertical line can be typed by pressing shift and \. \ is located above your return/enter key.)

    So, we need to add an or statement to

    if(totalValue() === 10){

    so it reads

    if(totalValue() === 10 || totalValue() === 11){

    This just means that the code contained in the if statement will be run if the total value is 10 or 11. Try it!

    The logic for when to double down is still imperfect. If the dealer has a high card showing, the chances of you beating the dealer on a double down are slim. So, we need to check to see if the value of the dealer's up card is less than 7 AND your total value is either a 10 or 11. Just like there is an "or" operator, there is an "and" or. It is &&. We have also written a function for you that returns the value of the dealers up card, called dealerUpCard(). So, change the if statement to read

    if(dealerUpCard() < 7 && (totalValue() === 10 || totalValue() === 11)){

    Note the parentheses around the two components of the or statement. This groups the or statement and compares it with the dealerUpCard() expression using && to insure that the dealer's up card is less than 7 and your total card value is either 10 or 11. To better understand how these parentheses work, observe that if they were placed like

    if((dealerUpCard() < 7 && totalValue() === 10) || totalValue() === 11){

    either your total value would have to equal 10 and the dealers up card would have to be less than 7, or your total value would have to equal 11 and the dealer's up card could be anything. If there were no internal parentheses,

    if(dealerUpCard() < 7 && totalValue() === 10 || totalValue() === 11){

    the code would be evaluated from left to right, which would do the same thing as the previous parenthetical placement. This makes no sense for our purposes, so arrange the parentheses as we had them initially (around the two components of the or statement).

    Click submit a few times. When your program doubles down, it will have a good chance of winning. This ensures that you make double the money when you can and don't risk losing double the money very often. Nice.

    (You may have noticed you've been getting an awful lot of double down situations this mission. Yes, we rigged the deck. We'll stop doing that soon.)

    --------------------------------------------------------------------------

    Mission 10.1: Hit or Stand Based on the Dealer's Hand — More Practice with If Statements and Boolean Expressions

    You're pretty much an if statement master now, so let's use your knowledge to further improve your program's logic. Currently the program hits when you have a total value of no more than 16 and stands otherwise. This is what the dealer is forced to do, so you have no advantage over the dealer. We're going to give you an advantage by changing whether your program hits or stands based on the value of the dealer's face-up card. If the dealer has a high up card, he/she probably will not be required to take a hit and so will probably not bust. Therefore, you will need a high hand to win. However, if the dealer has a low card showing, he/she will have to hit and is likely to bust. Notice that this logic is based on the fact that the most likely card value a player will draw is 10.

    Let's take this a step at a time. First, modify your program so it hits if you have a total card value of less than 17 and the dealer's upcard is higher than 6. Here are some helpful hints:

    If your code is not working properly, take a look at this example. This is not the only way to do this. You could also use nested if statements instead of &&s, but that tends to get very messy so &&s are generally preferred.

    --------------------------------------------------------------------------

    Mission 10.2: Hit or Stand Based on the Dealer's Hand — Even More Practice with If Statements and Boolean Expressions

    Beautiful work, [NAME]. Now let's finish this up. In the last section we said that if the dealer has a low card showing, he/she will have to hit and is likely to bust. So, modify the program so it also hits if the dealer's upcard is less than or equal to 6 and your total value is less than 12.

    Combining the instructions from this section and the past one, you need to make the program hit if you have a total card value of less than 17 and the dealer's upcard is higher than 6 and also hit if the dealer's upcard is less than or equal to 6 and your total value is less than 12. Here are some hints:

    Don't get discouraged if it doesn't work! This is pretty complicated.

    If your code is not working properly, take a look at these examples.

    --------------------------------------------------------------------------

    Mission 11.1: Card Counting — Simple Work With If and Elseif

    Now you have a really solid algorithm to figure out whether your program should double down, hit, or stand! However, the program still just bets the same amount of money every time. Wouldn't it be better if you could bet more when you thought you were going to win? That's right, it would be. You may have heard of something called "card counting." It's one of the many things that gets people thrown out of casinos because card counters win too much money. That's awesome. And we're not going to throw you out, so you can count all the cards you want!

    The basic premise behind card counting is that you will win more often when there are more high cards left in the deck. This is primarily because the dealer will bust more often, you are more likely to get a Blackjack, and your hands will be higher. We will implement a card counting method known as the "Hi-Lo" method. In this method, the lowest cards (2-6) are assigned a card counting value of 1. The highest cards (10-Ace) are assigned a value of -1. The cards in the middle (7-9) are assigned a value of 0. When a card is played, a card counter adds it to a running total in his/her head. When that total is higher, it means that more low cards have been played and therefore there are more high cards left in the deck. This is a good time to bet higher because you are more likely to win. If the number is lower, you should bet lower because you are more likely to lose. If you'd like more information on card counting, click here.

    People are, of course, imperfect and can be distracted when counting cards. They may forget their count and then will not know how much to bet. Computers, however, are perfect and will not forget, so they are ideal to use for card counting. It is going to be a long and confusing process to implement card counting, but you'll learn a lot along the way and once you're finished your program will make a lot of money!

    The first step is to determine when card counting should occur. The easiest way to program card counting will be to have the computer count up the values of all the cards on the field at the end of each hand, after a winner has been determined. We've made a boolean called handEnd that is true when it is the end of a hand. So, let's add a new if statement to the beginning of your code, right before the if statement checking to see if it's the beginning of the game, that checks to see if it's the end of the game. Don't make it do anything yet. Also, make sure you change the if statement checking if it's the beginning of the game to an else if statement so your program doesn't try to hit at the end of the game. Press submit. Your code should not behave any differently than it did before.

    If you're having problems, make sure the beginning of your code looks like this.

    --------------------------------------------------------------------------

    Mission 11.2: Card Counting — Making Arrays

    Now we need to fill in the if statement. Everything in this section will be done inside the if statement you just wrote.

    Remember arrays? Back in mission 4.3 you used an array we made called handValue to read the values of the cards in your hands. Hopefully you enjoyed that, because card counting is going to use a lot of arrays! (In case you did forget, arrays are just lists of data.) The first array we will make (let's call it cardCountVal) will keep track of the card counting values (-1, 0, or 1) for each card value (2-11, because all face cards are worth 10). Recall that arrays have numbered positions, starting at 0, and data is stored at each position. Since the values of the cards are consecutive from 2-11, for convenience we will start using cardCountVal at position 2 and use the positions to represent the card values. We will set each position to its the appropriate card counting value. We will effectively ignore positions 0 and 1.

    First, declare the array by typing

    var arrayName = [];

    Now we need to set the array. There are many different ways to set arrays. The first follows the form

    arrayName[position] = value;

    So, to set position 2 of cardCountVal to the value 1, its appropriate value according to the Hi-Lo card counting method, you type

    cardCountVal[2] = 1;

    To set multiple values in an array, you must repeat this statement form for each position. Inside the if statement you just created, set all positions to their corresponding value and press submit. An objective complete message should appear.

    Wasn't that horrible having to type all those lines? That's right, it was. Fortunately, there's a shortcut of the form

    arrayName = [value1, value2, value3, ...]

    where each value is the value given to that position. Delete the long list of commands you just wrote and recreate the array in this method. Keep in mind, the positions start at 0. We don't need positions 0 and 1, so you can set them to anything you want. We'd recommend being boring and setting them to 0, like this

    cardCountVal = [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, -1, -1]

    Press submit. Wasn't that nice?

    Try not to get too mad at us here, but we're now going to suggest recreating this array in a more complicated manner, using for loops. Although it's not a time saver in this case, imagine if you had an array with 1000 items in it. That would be really annoying to declare using the above method, and the chance of you making a mistake would be very high! So, write some for loops to go through the array and set each position to its appropriate value. Here are some helpful hints:

    When you're done, press submit to check your work, but notice that your code still won't do anything. Also, note that every time you reach the end of the hand, your code will recreate this same array. That's very inefficient and a terrible programming practice, but we're not going to worry about that here.

    If you're having problems, make sure the beginning of your code looks like one of these examples. Both examples accomplish the exact same thing.

    Check your if-else statements against this example.

    --------------------------------------------------------------------------

    The End!

    Congratulations! You've completed our tutorial. You now have an awesome Blackjack-playing computer program, written by you, as well as lots of knowledge about programming.

    Think about all the stuff you've learned: You can use if-else statements to make the computer do different things under different circumstances. You can use loops to make it repeat tasks. You can make it do math. You can store information. You can write functions to make all your programming easier. And best of all, you've learned how to think about everyday problems and figure out how to make a computer solve them.

    So what do you do now? If you'd like to keep playing around with this Blackjack program, there is always more that can be done! You can tweak the numbers in your code to change how your program hits, stands, bets, and doubles down to figure out what will make you the most money. You can try implementing more complicated and better card counting methods such as the Hi-Opt II method that we suggested earlier. You can also try implementing different types of betting strategies, such as the Martingale strategy. You'll notice that most of these strategies require knowing if you won the last hand. We'll set a boolean called wonLastHand to true when you win a hand and to false when you lose. You know everything you need to to make this strategy work! Have fun! (And comment your code!)

    The entire program that we wrote during this tutorial can be seen at the bottom of this page. If you ever accidentally mess something up and your program stops working, take a look at this code to fix it.

    If you're sick of Blackjack, there are many other programming tutorials on the Internet that will give you more practice and teach you more advanced concepts. You now know a lot about JavaScript, but that doesn't mean you have to keep using JavaScript! There are many different programming languages around, such as Python, Ruby, Java, C, and PHP, that you could also learn. The syntax will be different, but the theory and logic behind them is still the same.

    Thanks for playing, and happy coding!

    var name = "[NAME]"; //card counting if(handEnd){ var cardCountVal = []; //declare array for card count values //reset card count when deck is reshuffled if(reshuffled){ cardCount = 0; } //make array of card counting values assignCardCountVals(2, 6, 1); assignCardCountVals(7, 9, 0); assignCardCountVals(10, 11, -1); //count the cards countCards(handValue); countCards(dealerHandValue); } //bet else if(handStart){ var cardCountBet = cardCount + 21; safeBet(cardCountBet, 0); } else{ //account for Aces being 1 or 11 var haveAce = false; var numberOfAces = aceCount(handValue); var highValue = highestValue(numberOfAces); if(aceCount(handVal) > 0){ haveAce = true; } //see if you should double down if(dealerUpCard() < 7 && (totalValue() === 10 || totalValue() === 11)){ doubleDown(); } //see if you should hit else if(dealerUpCard() > 6 && ((totalValue() < 17 && !haveAce) || (highValue < 18 && haveAce))){ hit(); } //see if you should hit part 2 else if(dealerUpCard() <= 6 && totalValue() < 12){ hit(); } //otherwise, stand else{ stand(); } } //returns the highest non-busting value of a hand with Aces //takes the number of Aces in your hand as a parameter //could rewrite to take totalValue() as a parameter so it could check other hands function highestValue(aces){ var highVal = totalValue(); var counter = 0; for(counter = 1; counter <= aces; counter++){ if(highVal > 21){ highVal -= 10; } } return highestValue; } //returns the number of Aces in a hand //takes the hand as a parameter function aceCount(hand){ var aces = 0; var counter = 0; for(counter = 0; counter < sizeof(hand); counter++){ if(hand[counter] === 11){ aces++; } } return aces; } //returns the total value of all the cards in your hand //could rewrite to take handValue as a parameter so it could find the value //of other hands function totalValue(){ var length = handValue.length; var sum = 0; var counter = 0; for(counter = 0; counter < length; counter++){ sum += handValue[counter]; } return sum; } //bets an amount of money that won't make your total money fall below a //certain value //parameter betAmount is the amount you want to bet, &limit is the value //you don't want to fall below //the amount bet will be betAmount minus some value so you don't fall below limit function safeBet(betAmount, limit){ if(totalMoney() - betAmount < limit){ betAmount = totalMoney() - limit; } bet(betAmount); } //creates an array of card count values for every card in the deck //parameter start is the first card you want to assign to a particular value, //end is the last, and val is the value to assign function assignCardCountVals(start, end, val){ var counter = 0; for(counter = start; counter <= end; counter++){ cardCountVal[counter] = val; } } //counts the cards in a particular hand based off the cardCountVal array //parameter hand is the hand you want to count function countCards(hand){ var counter = 0; for(counter = 0; counter < sizeof(hand); counter++){ cardCount += cardCountVal[hand[counter]]; } }