21 (Part 1)

Last night, I began work on a new program in VBScript which I’m calling 21. It’s roughly based on the rules for Blackjack, where you get random “cards” dealt to you and the object is to get as close to 21 as you can without going over. Now, I didn’t manage to finish this program last night since a certain fiancée I have wanted to chat with me (go figure!) but as I was preparing for bed I figured that a little script-based program like 21 would actually work quite well as a teaching tool since 1) the rules are pretty simple and straightforward, so you don’t get bogged down in a bunch of heavy code; and, 2) it actually still has areas where you can go profoundly deep.

So it’s a good thing I didn’t finish it, because now I can go over it a bit more organically here on the blog. In other words, you can see closer to “real time” how I flesh out concepts when I’m working on a program.

Overview

First of all, we need to know what the basic gist of the program is going to be. Obviously, 21 is a Blackjack lookalike—but that doesn’t tell us enough about it to start programming. We need to look at the rules.

The first rule is that there are two players: the user and the dealer. The dealer will be controlled by the computer code. The user is going to be the person who runs the program.

The object of the game is to get “cards” in your hand that get as close to 21, but not over. The user bets a small sum (say, $1 for the game) and begins. The user can always select to receive another card, as long as the current total in his hand is less than 21. (We can also let the user be an idiot and select a card if his hand value is equal to 21 too.) The user can also decide to “hold” at any point, and the value of the cards he holds will be his “score” for the round. If the user goes over 21, he “busts” and loses automatically, thus giving the dealer the $1 (this, incidentally, is part of what gives the dealer the edge in the game—he doesn’t have to play if the user busts first).

Assuming the user does not bust, the dealer then plays. The dealer must either meet or beat the score of the user’s hand, without going bust himself. If the dealer gets the same score as the user (that is, he “meets” the user’s score) then it is considered a tie, and the $1 is given back to the user. If the dealer beats the user’s hand, the dealer wins the $1. If the dealer busts, the user wins back both the $1 he bet and another $1 as reward for winning.

In 21, we will not use an actual deck of cards (i.e., having an Ace, 2 – 10, Jack, Queen, and King), but instead we will use a random number generator. To give the user a little more control of what goes on, we will give him the option of selecting from two different types of card. Card type 1 will be a card that will have a value between 3 and 7. Card type 2 will be a card that will have a value between 1 and 11 (this value is selected so that it is possible for a user to get 21 after only two draws, by drawing a 10 and an 11, or to even go bust after only two draws by drawing two 11s).

The game begins by drawing a “Pot” card from Card Type 2. The Pot card will be used by both the dealer and the user to begin their hand. Thereafter, each player will draw their own unique cards for their hand. In other words, suppose the Pot card at the beginning is 8. Both the user’s current score and the dealer’s current score is 8. But, the user will draw his own card (say, a 7) and his new total will be the sum of the Pot card and the user’s new card, in this case 15. Meanwhile the dealer’s is still 8. Supposing the player holds at 15, the dealer can then select to draw a card (say, a 10)—and his total will then be the Pot card plus the dealer’s new card, or in this case 18.

Program Structure

At this point, we can begin to think a bit about the structure of the program. I am going to select a menu-type interface (since we’re using VBScript), where the user will be able to select numbers to determine actions. We will therefore have the main program controlled by a DO … LOOP WHILE loop, which I will explain in detail as we get to it. Essentially, the program will loop until the while condition is satisfied, which we will define as being two conditions: 1) the user terminates the program; 2) the user has no more money.

Note: in order for us to implement (2) above, this will require us to keep track of the user’s bankroll. For instance, we can begin the game as a whole by having the user start with $10. At any point the user gets to $0, the game is over. Likewise, at any point the user wishes to exit the game, the game will end and his winnings will be displayed.

So the basic gist of the program will begin thus:

HEADER INFORMATION (i.e., where all the constants and variables
                          are created)

BEGIN MAIN PROGRAM LOOP:

     PLAY A ROUND OF THE GAME

     DETERMINE IF GAME OVER

END MAIN PROGRAM LOOP

DISPLAY END RESULTS

Now we need to better define what constitutes PLAY(ing) A ROUND OF THE GAME. So let’s look at the next level of structure:

SELECT A POT CARD

     ROUND IS PLAYED

RESULTS OF ROUND

Now let’s drill down into what happens when a ROUND IS PLAYED:

USER PLAYS

IF USER DOESN’T LOSE, DEALER PLAYS

Finally, we need to define both what USER PLAYS means and what DEALER PLAYS means. So first, USER PLAYS:

BEGIN USER TURN LOOP:

     PRESENT OPTIONS (user can draw type 1, type 2, or hold)

          IF USER SELECTS TO HOLD
               END USER TURN AS HOLD

          IF USER SELECTS TYPE 1
               DRAW TYPE 1 CARD
          IF USER SELECTS TYPE 2
               DRAW TYPE2 CARD

          ADD NEW CARD TO USER TOTAL

          IF USER BUSTS
               END USER TURN AS LOSS     

END USER TURN LOOP

This loop will terminate either if the user holds (i.e., END USER TURN AS HOLD) or busts (i.e., END USER TURN AS LOSS).

Now let’s examine the DEALER TURN. This only occurs IF USER DOESN’T LOSE:

BEGIN DEALER TURN LOOP:

     USE STATISTICS TO DECIDE WHICH TYPE OF CARD TO DRAW

     ADD NEW CARD TO DEALER TOTAL

     IF DEALER TOTAL > 21
          END DEALER TURN AS USER WIN

     IF DEALER TOTAL > USER TOTAL
          END DEALER TURN AS DEALER WIN

    IF DEALER TOTAL = USER TOTAL
          END DEALER TURN AS TIE

END DEALER TURN LOOP

Note that in the above, the loop will go until the dealer either busts, ties the user, or beats the user. Furthermore, if the dealer ties, right now we’re going to just make it a tie. In the future, we can add AI that will determine whether or not the dealer would like to draw again. (For instance, suppose that the user’s score is 14 and he holds. If the dealer reaches 14, he can still draw a card of type 1 (which is 3 – 7) and be guaranteed of a win—but for now, to keep it simple, we’ll just force the tie.)

So now let’s put the entire structure together:

21 PROGRAM STRUCTURE

HEADER INFORMATION

BEGIN MAIN PROGRAM LOOP:

     SELECT A POT CARD

          BEGIN USER TURN LOOP:

               PRESENT OPTIONS

               IF USER SELECTS TO HOLD
                    END USER TURN AS HOLD

               IF USER SELECTS TYPE 1
                    DRAW TYPE 1 CARD
               IF USER SELECTS TYPE 2
                    DRAW TYPE2 CARD

               ADD NEW CARD TO USER TOTAL

               IF USER BUSTS
                    END USER TURN AS LOSS     

          END USER TURN LOOP

          IF USER HASN’T LOST

               BEGIN DEALER TURN LOOP:

                    USE STATISTICS TO DECIDE WHICH TYPE OF CARD
                    TO DRAW

                    ADD NEW CARD TO DEALER TOTAL

                   IF DEALER TOTAL > 21
                        END DEALER TURN AS USER WIN

                   IF DEALER TOTAL > USER TOTAL
                        END DEALER TURN AS DEALER WIN

                   IF DEALER TOTAL = USER TOTAL
                        END DEALER TURN AS TIE

              END DEALER TURN LOOP

     RESULTS OF ROUND

     DETERMINE IF GAME OVER

END MAIN PROGRAM LOOP

DISPLAY END RESULTS

So that’s the basic structure. Next up, we’ll begin to actually code some of this :-)

About CalvinDude

In real life, CalvinDude is known as Peter Pike. Peter is an author who lives in Colorado. He is a Presbyterian (more or less) and is sane (more or less). Other than that, the less you know the better off you are.
VBScript

1 response to 21 (Part 1)


  1. Pingback: CalvinDude.com » 21 (Part 2): InputBox

Leave a Reply