| !Blackjack Dealer by Ashok Desai; | |
| !To use, put this file in your Inform working directory and write the line; | |
| !include "blackjack.inf' immediately after the room object that you want; | |
| !your dealer to be located in. At present you may only have one blackjack; | |
| !dealer in your game. The dealer's Stickat value can be adjusted to make; | |
| !him play more or less recklessly. To insert prizes for winning and forfeits; | |
| !for losing, replace the blackjackwin and blackjacklose routines with what; | |
| !you would like to happen when the player wins or loses a game, such as paying; | |
| !out or giving an object. There is also a routine called Blackjackcost. Normally; | |
| !this always returns true, but you can replace it with a routine of your own.; | |
| !Blackjackcost is checked before the game starts if there isn't one already in; | |
| !progress, and cancels the attempt if it returns false. You should include any; | |
| !error messages (i.e. "you don't have enough money to play") with the checking; | |
| !routine.; | |
| !Declare the globals used by the code. Pack_of_cards holds a; | |
| !shuffleable deck of 52 cards, currentcard represents the current; | |
| !position in the deck, cardhand and cardace are used when the code; | |
| !needs to calculate the best value of a pontoon hand.; | |
| array pack_of_cards -->52; | |
| Global currentcard = 0; | |
| array cardhand --> 2; | |
| array cardace --> 2; | |
| !The next few routines are lifted or adapted from those written in; | |
| !the user manual for Inform. Why change something that works?; | |
| [PrintCard n; | |
| switch(n%13) { | |
| 0: print "Ace"; | |
| 1 to 9: print n%13 + 1; | |
| 10: print "Jack"; 11: print "Queen"; 12: print "King"; | |
| } | |
| print " of "; | |
| switch(n/13) { | |
| 0: print "Hearts"; 1: print "Clubs"; | |
| 2: print "Diamonds"; 3: print "Spades"; | |
| } | |
| ]; | |
| !I deleted the part of this routine that writes the exact order of; | |
| !all the cards in the deck, but it's otherwise identical.; | |
| [ Reorder i j; | |
| !Shuffle, using the Dylan Thurston method; | |
| for (i=1:i<52:i++) pack_of_cards --> i = i; | |
| pack_of_cards-->0 = 0; | |
| for (i=1:i<52:i++) { | |
| j = random(i+1) - 1; | |
| pack_of_cards-->i = pack_of_cards-->j; pack_of_cards-->j = i; | |
| } | |
| ]; | |
| !This routine simply grabs the next card in line, points the deck; | |
| !to the next card along, and returns the appropriate value. In; | |
| !other words, read this into an attribute when you want to take a; | |
| !card off the deck; | |
| [getcard x; | |
| x = pack_of_cards --> currentcard; | |
| currentcard = currentcard + 1; | |
| return x; | |
| ]; | |
| !This routine is called when a player gets a new card. It ; | |
| !increments the total for non-ace cards if the new card is not; | |
| !an ace, and increments the number of aces if it is. It is | |
| !necessary to keep these two values separate so that the code can; | |
| !figure out how many aces to convert into 11's.; | |
| [addcard x player; | |
| !0 means add to the player's hand. 1 means add to the dealer's hand; | |
| x = x%13+1; | |
| if (x > 10) x = 10; !if it's a picture card, make it worth 10; | |
| if (x == 1) cardace-->player = cardace-->player + 1; | |
| else cardhand-->player = cardhand-->player + x; | |
| ]; | |
| !This beauty calculates the exact value of each hand. Basically,; | |
| !it takes the total value of all non-ace cards, then goes through; | |
| !all the aces checking to see if having this one at 11 would cause; | |
| !the player to go bust, if all the others were valued at 1.; | |
| [pontoonvalue player x f; | |
| x = cardhand-->player; | |
| for (f=1:f<=cardace-->player:f++) | |
| if (x + 11 + cardace-->player - f <= 21) x = x + 11; else x = x + 1; | |
| return x; | |
| ]; | |
| !This routine ends the game, tidies things up, and rewards the; | |
| !player if a reward is on offer.; | |
| [endgame winner dealer; | |
| if (winner == 0) Blackjack_Win(); | |
| else Blackjack_lose(); | |
| dealer.gameon = 0; | |
| return;]; | |
| [blackjack_win; | |
| print_ret "The dealer glares at you. ~Beginner's luck,~ he snarls.";]; | |
| [blackjack_lose; | |
| print_ret "~Sorry friend,~ says the dealer with a smile, ~you lose!~";]; | |
| !For some reason, the code cannot access the return value of a replaced function; | |
| !directly, so we need to fool it into doing so indirectly with a ghost routine; | |
| [blackjack_test; | |
| return blackjack_cost();]; | |
| [blackjack_cost; return true;]; | |
| !And now the dealer himself.; | |
| Object -> gambler "gambler" | |
| with name "gambler", | |
| gameon 0, stick 0, stickat 17, | |
| !N.B. stickat is the value at which the Gambler will not risk taking another; | |
| !card, unless he knows he has to beat a higher value to win. Set it higher and; | |
| !he will go bust more easily. Set it lower, and he will play more carefully but; | |
| !will be easier to beat as he will stick at a lower value. The gambler will never; | |
| !stick if you have already stuck and his value is less than yours.; | |
| description "A man with a deck of cards. (Type <ask gambler about | |
| rules> and maybe he will tell you how to play!)", | |
| !The game's commands must all be spoken to the dealer.; | |
| life[c1 c2 f;answer: switch (noun) { | |
| !The deal command initialises a new game, if none is in progress; | |
| 'deal' : if (self.gameon == 0) {if (blackjack_test() == true) { | |
| !First, we initialise the necessary values and tell the dealer; | |
| !that the game is on; | |
| reorder(); self.gameon = 1; self.stick = 0; | |
| for (f=0:f<2:f++) {cardhand-->f = 0; cardace-->f = 0;} | |
| !Next, we deal two cards each to both players, and tell them what they are and their totals; | |
| c1 = getcard(); c2 = getcard(); addcard(c1,0); | |
| addcard(c2,0); print "The gambler deals you the "; | |
| printcard (c1); print " and the "; printcard (c2); | |
| print ", for a running total of "; print pontoonvalue(0); | |
| print "."; | |
| c1 = getcard(); c2 = getcard(); addcard(c1,1); addcard | |
| (c2,1); print "^To himself, he deals the "; printcard (c1); | |
| print " and the "; printcard (c2); print ", for a running | |
| total of "; print pontoonvalue(1); print ".^"; | |
| !Finally we check to see if either player has Pontoon; | |
| if (pontoonvalue(1) == 21) {print "^~Pontoon!~ shouts the | |
| dealer triumphantly, ~I win!~^"; endgame(1,self);} | |
| else if (pontoonvalue(0) ==21) {print "^You smugly show | |
| the gambler your Pontoon hand.^"; endgame(0,self);} | |
| return; | |
| } else return;} | |
| else print_ret "You're halfway through a game, you might | |
| as well finish it."; | |
| !Now we need to tell the dealer what happens if a player accepts; | |
| !a new card, and how it should react.; | |
| 'twist', 'hit', 'again', 'another' : if (self.gameon == 1) | |
| {c1 = getcard(); addcard (c1,0); | |
| !Deal to the player, make sure you're not bust; | |
| print "The gambler deals you the "; printcard (c1); | |
| print ".";if (pontoonvalue(0) > 21) {print " You have gone | |
| bust!^"; endgame(1,self);} else {print " Your current | |
| total is "; print pontoonvalue(0); print ".^"; | |
| !Check to see if the dealer wants a card, and if he goes bust.; | |
| if ((pontoonvalue(1) <= self.stickat || pontoonvalue(1) < | |
| pontoonvalue(0)) && self.stick ~= 1) {c1 = getcard(); | |
| addcard(c1,1); print "The dealer draws the "; printcard | |
| (c1); if (pontoonvalue(1) > 21) {print " and goes bust!^"; | |
| endgame(0,self); return;} else {print " for a running | |
| total of "; print pontoonvalue(1); print ".";}} | |
| else if (self.stick == 0) {self.stick = 1; print "The | |
| gambler sticks at "; print pontoonvalue(1); print ".^";} | |
| else {print "You need to beat "; print pontoonvalue(1); | |
| print ".^";}} | |
| !And round off the action, or complain if no game is in progress; | |
| return;} else print_ret "There is no game in progress - <say deal> | |
| first."; | |
| !Last part now! This is what happens when the player sticks.; | |
| 'stick', 'stay', 'stand' : if (self.gameon == 1) { | |
| print "You stick at "; print pontoonvalue(0); print ".^"; | |
| !We tell the player what value they have stuck upon. Now the; | |
| !dealer will continue drawing cards until he either goes bust; | |
| !or beats the player's total. Note that if he already stuck, he; | |
| !won't be able to do this as the while loop will never trigger.; | |
| while (pontoonvalue(1) < pontoonvalue(0) && | |
| self.stick ~= 1) {c1 = getcard(); addcard(c1,1); | |
| print "The dealer draws the "; printcard(c1); | |
| if (pontoonvalue(1) > 21) {print " and goes bust!^"; | |
| endgame(0,self); return;} else {print " for a running | |
| total of "; print pontoonvalue(1); print ".^";}} | |
| print "The gambler sticks at "; print pontoonvalue(1); | |
| print ".^"; | |
| !This part is technically not necessary, but better safe than; | |
| !sorry. It checks to see which player has won. To be honest, if; | |
| !it gets to this point in the code then mathematically the dealer; | |
| !should already have won, but I put it like this so that people; | |
| !could more easily fiddle with the code.; | |
| if (pontoonvalue(0) > pontoonvalue (1)) endgame(0,self); | |
| else endgame(1,self); return;} else print_ret "There is no | |
| game in progress - <say deal> first."; | |
| !You can continue the answer case statement here if you want to; | |
| !make the dealer respond to other words too.; | |
| };print_ret "The gambler doesn't seem to care for that."; | |
| !And, as promised in the description earlier, here the rules of; | |
| !the game are briefly explained.; | |
| ask : switch (second) { | |
| 'rules', 'game', 'pontoon', 'cards', 'play' : print_ret "The gambler | |
| smiles, ~This is a very simple game friend, you'll get the hang of it | |
| in no time. Just <say deal> and I'll deal | |
| you two cards, and another two for myself. The idea is to get as close | |
| to 21 without going over. Face cards like the king, queen and jack are | |
| all worth 10 points. The Ace is worth either one or eleven, depending | |
| on which would be better for you. Provided you haven't 'gone bust' you | |
| can ask me for another card - just <say twist> - and I can do the same. | |
| If you're happy with your score you can <say stick> instead. Whoever | |
| gets closer to 21 wins the hand, if we draw then I win the hand. Oh and | |
| to show it's all above board and no cheating is going on, I'll shuffle | |
| the cards at the beginning of each hand.~"; | |
| };print_ret "The gambler doesn't seem to care for that.";], | |
| has animate static; | |
Xet Storage Details
- Size:
- 10.3 kB
- Xet hash:
- 4163cce2c50193b61a4e89b3c9a00cbbb88f79cfbef5ae1fcb92be028364ce25
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.