import "listUtil" print " "*31 + "Black Jack" print " "*15 + "Creative Computing Morristown, New Jersey" print; print; print fna = function(q); return q - 11*(q >= 22); end function hands = [[]]*15 // hands(i,j) is the jth card in hand i (P) handValue = [0]*15 // total value of each hand (Q) deck = [] // the deck being dealt from (C) playerMoney = [0]*8 // total $ for each player (T) roundWinnings = [0]*7 // total $ won/lost this hand for each player (S) betPerHand = [0]*15 // bet for each hand (B) cardNames = " A 2 3 4 5 6 7 8 9 10 J Q K".split reshuffle = function print "Reshuffling" globals.deck = range(1,13)*4 deck.shuffle end function // Function to draw a card from the deck (reshuffling if needed) getCard = function if not deck then reshuffle return deck.pop end function // Function to get a name for the given card, preceded by "a" or "an" a = function(cardNum) article = "a" + "n" * (cardNum == 1 or cardNum == 8) return article + " " + cardNames[cardNum] end function // Function to evaluate the given hand. Total is usually put into // handValue(handNum). Totals have the following meaning: // 2-10...Hard 2-10 // 11-21...Soft 11-21 // 22-32...Hard 11-21 // 33+ or -1...Busted evalHand = function(handNum) result = 0 for card in hands[handNum] result = addCardToTotal(result, card) end for return result end function // Function to add a card into a total hand value. addCardToTotal = function(total, card) if total < 0 then return total // (already busted) x1 = card; if x1 > 10 then x1 = 10 q1 = total + x1 if total < 11 then if card == 1 then return total + 11 // (ace) return q1 + 11 * (q1 >= 11) end if total = q1 + (total <= 21 and q1 > 21) if total >= 33 then total = -1 return total end function // Print one of those totals as it should appear to the user. displayTotal = function(total) return total - 11 * (total >= 22) end function // Get a yes/no response from the user getYesNo = function(prompt) while true inp = input(prompt).upper if inp and (inp[0] == "Y" or inp[0] == "N") then return inp[0] end while end function // Get a number, within a given range, from the user getNumber = function(prompt, minVal=0, maxVal=500) while true result = input(prompt).val if result == floor(result) and minVal <= result <= maxVal then return result print "Please enter a number from " + minVal + " to " + maxVal end while end function // Get one of a list of one-letter (uppercase) options. getOption = function(prompt, options) while true result = input(prompt).upper if result and options.indexOf(result[0]) != null then return result[0] print "Type " + options[:-1].join(", ") + " or " + options[-1] + " please" end while end function getBets = function print "Bets:" for i in range(0, numPlayers-1) betPerHand[i] = getNumber("# " + (i+1) + "? ", 1, 500) end for end function playOneRound = function globals.roundWinnings = [0] * numPlayers if deck.len < (numPlayers+1) * 2 then reshuffle getBets print "PLAYER ", "" for i in range(0, numPlayers-1) print i+1, " " hands[i] = [] end for print "DEALER" hands[numPlayers] = [] for row in [1,2] print " ", "" for i in range(0, numPlayers) hands[i].push getCard if row == 1 or i < numPlayers then print " " + (cardNames[hands[i][-1]] + " ")[:2], " " end if end for print end for dealerCard0 = hands[numPlayers][0] dealerCard1 = hands[numPlayers][1] // Test for insurance if dealerCard0 == 1 and getYesNo("Any insurance? ") == "Y" then print "Insurance Bets" for i in range(0, numPlayers-1) insurance = getNumber("# " + (i+1) + "? ", 0, betPerHand[i]/2) roundWinnings[i] = insurance * (3 * (dealerCard1 >= 10) - 1) end for end if // Test for dealer blackjack if (dealerCard0==1 and dealerCard1 > 9) or (dealerCard0 > 9 and dealerCard1==1) then print; print "Dealer has " + a(dealerCard1) + " in the hole for Blackjack" for i in range(0, numPlayers) handValue[i] = evalHand(i) end for else // no dealer blackjack if dealerCard0 == 1 or dealerCard0 >= 10 then print; print "No dealer Blackjack." end if // now play the hands for i in range(0, numPlayers-1) playHand i end for handValue[numPlayers] = evalHand(numPlayers) // (evaluate dealer hand) // Test for playing the dealer's hand... we only do so if // there are any player hands with cards left. anyLeft = false for i in range(0, numPlayers-1) if hands[i] or hands[i+8] then anyLeft = true end for if not anyLeft then print "Dealer had " + a(hands[numPlayers][1]) + " concealed." else // Play dealer's hand. dispTotal = displayTotal(handValue[numPlayers]) print "Dealer has " + a(hands[numPlayers][1]) + " concealed" + " for a total of " + dispTotal + "." while handValue[numPlayers] > 0 and dispTotal <= 16 card = getCard if hands[numPlayers].len == 2 then print "Draws ", "" print cardNames[card], " " hands[numPlayers].push card handValue[numPlayers] = evalHand(numPlayers) dispTotal = displayTotal(handValue[numPlayers]) end while if hands[numPlayers].len > 2 then if handValue[numPlayers] < 0 then print " ---Busted" else print " ---Total is " + dispTotal end if print end if end if tallyResults end function playHand = function(handNum, prompt=null, allowSplit=true) if not prompt then prompt = "Player " + (handNum % 8 + 1) while hands[handNum] options = ["H", "S", "D"] + ["/"] * allowSplit choice = getOption(prompt + "? ", options) if choice == "S" then // player wants to stand handValue[handNum] = evalHand(handNum) if handValue[handNum] == 21 and hands[handNum].len == 2 then print "Blackjack" roundWinnings[handNum] += 1.5 * betPerHand[handNum] betPerHand[handNum] = 0 discardHand handNum else print "Total is " + displayTotal(handValue[handNum]) end if break else if choice == "D" or choice == "H" then // hit or double down handValue[handNum] = evalHand(handNum) if choice == "D" then betPerHand[handNum] *= 2 card = getCard print "Received " + a(card), " " hands[handNum].push card handValue[handNum] = evalHand(handNum) if handValue[handNum] < 0 then print "...Busted" discardHand handNum roundWinnings[handNum] = -betPerHand[handNum] betPerHand[handNum] = 0 end if prompt = "Hit" if choice == "D" then; print; break; end if else if choice == "/" then // split card1 = hands[handNum][0]; if card1 > 10 then card1 = 10 card2 = hands[handNum][1]; if card2 > 10 then card2 = 10 if card1 != card2 then print "Splitting not allowed." continue end if hand2 = handNum + 8 hands[hand2] = [hands[handNum].pop] betPerHand[hand2] = betPerHand[handNum] card = getCard print "First hand receives " + a(card) hands[handNum].push card card = getCard print "Second hand receives " + a(card) hands[hand2].push card if card1 != 1 then // Now play the two hands playHand handNum, "Hand 1", false playHand hand2, "Hand 2", false end if break end if allowSplit = false end while end function discardHand = function(handNum) hands[handNum] = [] handValue[handNum] = 0 end function tallyResults = function dealerTotal = displayTotal(evalHand(numPlayers)) for i in range(0, numPlayers-1) playerHandATotal = displayTotal(evalHand(i)) playerHandBTotal = displayTotal(evalHand(i+8)) // calculate roundWinnings[i], which is the $ won/lost for player i roundWinnings[i] = roundWinnings[i] + betPerHand[i]*sign(playerHandATotal - dealerTotal) + betPerHand[i+8]*sign(playerHandBTotal - dealerTotal) betPerHand[i+8] = 0 s = "Player " + (i+1) + " " s += ["loses", "pushes", "wins"][sign(roundWinnings[i])+1] if roundWinnings[i] != 0 then s += " " + abs(roundWinnings[i]) playerMoney[i] += roundWinnings[i] playerMoney[numPlayers] -= roundWinnings[i] s = (s + " "*25)[:25] + "Total = " + playerMoney[i] print s discardHand i discardHand i+8 end for print "Dealer's total = " + playerMoney[numPlayers] print end function // Main program starts here if getYesNo("Do you want instructions? ") == "Y" then print "This is the game of 21. As many as 7 players may play the" print "game. On each deal, bets will be asked for, and the" print "players' bets should be typed in. The cards will then be" print "dealt, and each player in turn plays his hand. The" print "first response should be either 'D', indicating that the" print "player is doubling down, 'S', indicating that he is" print "standing, 'H', indicating he wants another card, or '/'," print "indicating that he wants to split his cards. After the" print "initial response, all further responses should be 'S' or" print "'H', unless the cards were split, in which case doubling" print "down is again permitted. In order to collect for" print "blackjack, the initial response should be 'S'." print end if numPlayers = getNumber("Number of players? ", 1, 7) print // main loop! while true playOneRound end while