; BLACKJACK.MS2 by Mark Morley (May 22, 1997) ; ; You may copy and modify this program as you see fit. ; ; This program implements the card game known as "Blackjack". This version ; is a single player one. The dealer deals two cards for himself, and two ; cards for you. Face cards (Jacks, Queens, and Kings) are worth 10 points. ; Number cards are worth their numeric value. Aces are worth either 1 or 11. ; The object is to see who can get the closest to 21 without going over. ; Every time you click on "Hit Me", the dealer gives you another card. When ; you have gone as high as you dare, click on "Stay". Then the dealer flips ; over his hidden card and draws as many cards as he likes. In the event of ; a draw, the dealer wins. ; This function is used to initialize a new deck of cards. You pass it ; a string which is the variable name used to reference the deck. This ; particular game only uses one deck, but I may use these routines in ; other card games where I need more than one deck. ; ; I have 52 GIF images of cards in my directory. "as.gif" is the Ace of ; Spades, "5d.gif" is the Five of Diamonds,"qh.gif" is the Queen of Hearts ; and so on. There are another 52 GIF images that are "partial" cards ; (ie: they show a thin slice of the left side of each card). "asp.gif" ; is the (partial) Ace of Spade, for example. By displaying several partial ; cards beside each other it looks more like a hand of cards and takes less ; screen space. define initialize( deck ) varset( deck, 1, "as" ) varset( deck, 2, "2s" ) varset( deck, 3, "3s" ) varset( deck, 4, "4s" ) varset( deck, 5, "5s" ) varset( deck, 6, "6s" ) varset( deck, 7, "7s" ) varset( deck, 8, "8s" ) varset( deck, 9, "9s" ) varset( deck, 10, "ts" ) varset( deck, 11, "js" ) varset( deck, 12, "qs" ) varset( deck, 13, "ks" ) varset( deck, 14, "ah" ) varset( deck, 15, "2h" ) varset( deck, 16, "3h" ) varset( deck, 17, "4h" ) varset( deck, 18, "5h" ) varset( deck, 19, "6h" ) varset( deck, 20, "7h" ) varset( deck, 21, "8h" ) varset( deck, 22, "9h" ) varset( deck, 23, "th" ) varset( deck, 24, "jh" ) varset( deck, 25, "qh" ) varset( deck, 26, "kh" ) varset( deck, 27, "ac" ) varset( deck, 28, "2c" ) varset( deck, 29, "3c" ) varset( deck, 30, "4c" ) varset( deck, 31, "5c" ) varset( deck, 32, "6c" ) varset( deck, 33, "7c" ) varset( deck, 34, "8c" ) varset( deck, 35, "9c" ) varset( deck, 36, "tc" ) varset( deck, 37, "jc" ) varset( deck, 38, "qc" ) varset( deck, 39, "kc" ) varset( deck, 40, "ad" ) varset( deck, 41, "2d" ) varset( deck, 42, "3d" ) varset( deck, 43, "4d" ) varset( deck, 44, "5d" ) varset( deck, 45, "6d" ) varset( deck, 46, "7d" ) varset( deck, 47, "8d" ) varset( deck, 48, "9d" ) varset( deck, 49, "td" ) varset( deck, 50, "jd" ) varset( deck, 51, "qd" ) varset( deck, 52, "kd" ) ; This function shuffles a deck of cards. It does this by selecting 100 ; random pairs of cards and swapping them in the deck. The number 100 is ; arbitrary, but it should be large enough to mix them up a lot. define shuffle( deck ) i = 1 while i < 101 c1 = random( 1, 52 ) c2 = random( 1, 52 ) t = varget( deck, c1 ) varset( deck, c1, varget( deck, c2 ) ) varset( deck, c2, t ) i = i + 1 endwhile ; This functions draws a random card from the deck. It also marks that ; card as "DRAWN" so that it cannot be drawn again. define draw( deck ) i = 1 while i < 52 r = varget( deck, i ) if r != "DRAWN" varset( deck, i, "DRAWN" ) return r endif i = i + 1 endwhile ; In order to remember the current state of the shuffled deck, the dealer's ; hand, the player's hand, etc. this function is used to write all this ; information to a file. define savedeck( deck, file ) if output = open( file + ".deck", "w" ) i = 1 while i < 53 write( output, varget( deck, i ), "\n" ) i = i + 1 endwhile write( output, varget( "dhand", 1 ), "\n" ) write( output, varget( "dhand", 2 ), "\n" ) write( output, pnum, "\n" ) i = 1 while i <= pnum write( output, varget( "phand", i ), "\n" ) i = i + 1 endwhile close( output ) endif ; This is the counterpart to the savedeck() function. It is used to load ; in a previously saved deck, dealer's hand, and player's hand. It returns ; 0 if it fails and 1 if it succeeds. define loaddeck( deck, file ) if input = open( file + ".deck" ) i = 1 while i < 53 varset( deck, i, read( input ) ) i = i + 1 endwhile dnum = 2 varset( "dhand", 1, read( input ) ) varset( "dhand", 2, read( input ) ) pnum = num( read( input ) ) i = 1 while i <= pnum varset( "phand", i, read( input ) ) i = i + 1 endwhile close( input ) return 1 endif return 0 ; This function will add up the card values in the specified hand. It ; counts aces as 11 and remembers how many aces (if any) are in the hand. ; When it's done it checks to see if the total is over 21. If so, it ; begins subtracting 10 for each ace in the hand until the total is less ; than or equal to 21 or there are no more aces. In this way the total is ; always optimal. define add( hand, num ) aces = 0 total = 0 i = 1 while i <= num c = varget( hand, i ) t = left( c, 1 ) if t == "a" total = total + 11 aces = aces + 1 elif t >= "2" and t <= "9" total = total + num( t ) else total = total + 10 endif i = i + 1 endwhile while total > 21 and aces > 0 total = total - 10 aces = aces - 1 endwhile return total ; This is the main routine where all the fun begins... define main ; First we check and see if we are starting a new game or not. We start a ; new game if the cookie "DECKFILE" is not set, or if the third argument ; to the program is "new" (meaning that the user clicked the "new game" ; button - see below), or if the loaddeck() function fails (presumably ; because somebody deleted the temorary file on us). file = getcookie( "DECKFILE" ) if file == 0 or varget( "arg", 3 ) == "new" or \ loaddeck( "mydeck", file ) == 0 ; Initialize a new deck of cards and shuffle it. initialize( "mydeck" ) shuffle( "mydeck" ) ; Set a cookie that contains the file name where the "game in progress" ; will be saved. In order to get a unique file name we are using the ; time() function to make it. file = time( "%Y%d%m%H%M%S" ) setcookie( "DECKFILE", file ) ; Draw two cards for the dealer. "dnum" keeps track of how many cards ; are in the dealer's hand, and the array "dhand" holds the list of cards. dnum = 2 varset( "dhand", 1, draw( "mydeck" ) ) varset( "dhand", 2, draw( "mydeck" ) ) ; Do the same thing for the player's hand. pnum = 2 varset( "phand", 1, draw( "mydeck" ) ) varset( "phand", 2, draw( "mydeck" ) ) endif ; Display a title and begin the screen display. print( "
Dealer:\n" ) ; If the game is not finished yet we display the first card in the dealer's ; hand face down. This means we display the gif file "ep.gif". We also ; set "i" to 2 to indicate that the "last" card is the second one. This ; makes more sense when you look at what we do when we *are* finished... if not finished print( " | \nPlayer: " ) ; If we are not finished yet we define two buttons the player can click ; on. "Hit Me" calls this same program but passes the argument "hitme" ; to it. Likewise the "Stay" button calls this same program but passes ; it the argument "stay". if not finished print( "[Hit Me] " ) print( "[Stay] " ) endif ; Whether we are finished or not, this button allows the user to start a ; new game. It works like the previous two, calling this same program ; but passing the argument "new" to it. print( "[New Game]\n" ) ; Here we display all but the last card in the player's hand as partial ; GIF images (remember I have two sets of 52 images - whole cards and ; "partial" cards). i = 1 while i < pnum print( " |