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 :-)

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