#!../bin/jacl # BLACKJACL # ----------------------------------------------------------------------------- # Copyright (C) Stuart Allen 2001. All rights resevered. # ----------------------------------------------------------------------------- # CONSTANTS FOR RESOURCES IN BLORB FILE constant IMAGE_blackjack 1 integer INDEX integer COUNTER integer NODE1 integer NODE2 integer cardA integer cardB integer cardC integer CHECK_STRATEGY 0 string status_text integer status_window 3 integer OFFSET {+update_status_window style reverse padstring status_text " " status_width write status_text cursor 0 1 write status_text cursor 0 2 write status_text cursor 1 1 write "BlackJACL" setstring status_text "Bankroll: $" score set OFFSET = status_width length INDEX status_text set OFFSET - INDEX set OFFSET - 1 cursor OFFSET 1 write status_text style normal } {+set_node1 set NODE1 = shoe set COUNTER = random set COUNTER + 4 repeat set NODE1 = NODE1(next) set COUNTER - 1; until COUNTER = 0 } {+set_node2 set NODE2 = end set COUNTER = random set COUNTER + 4 repeat set NODE2 = NODE2(previous) set COUNTER - 1; until COUNTER = 0 } # Optional rules integer SOFT_SEVENTEEN false ; DEALER HITS ON A SOFT SEVENTEEN integer DAS true ; ALLOWED TO DOUBLE AFTER SPIT location casino : casino {look execute "+display_table" } #include "card_shoe.library" integer best_move integer last_move constant hit 0 string MOVE_TYPE hit constant split 1 string MOVE_TYPE split constant stay 2 string MOVE_TYPE stayed constant double 3 string MOVE_TYPE doubled integer current_hand constant bet 1 constant result 2 constant total 3 constant aces 4 constant aces_as_one 5 constant cards 6 integer current_player constant money 1 constant hands 2 constant insurance 3 integer PREVIOUS_GAME_PHASE integer GAME_PHASE constant place_bet 1 constant players_turn 2 constant dealers_turn 3 grammar coach on >coach_on {+coach_on set CHECK_STRATEGY = 1 write "Basic strategy coach on.^^" if GAME_PHASE != place_bet execute "+display_table" endif } grammar coach off >coach_off {+coach_off set CHECK_STRATEGY = 0 write "Basic strategy coach off.^^" if GAME_PHASE != place_bet execute "+display_table" endif } grammar blankjacl >view_table grammar look >view_table {+view_table execute "+display_table" } grammar help >help grammar instructions >help {+help write "The aim of Blackjack is to have a hand with a total value closer" write "to 21 than the dealer without going over 21. Ten, Jack, Queen and King" write "are all worth 10, an Ace is worth 11 or 1, and all other cards are worth" write "their face value. An Ace is treated as 11 unless it would put your " write "hand over 21, in which case it is treated as 1.^^" write "There are two phases to the game of Blackjack. Firstly your must " write "place your bet, then you must playout the hand you are dealt. " write "When you are playing your hand, the commands available to you will be " write "displayed based on the current game situation. Unless you hand has " write "bust (gone over a total value of 21), you will always be able to 'hit' " write "(receive another card) or 'stay', (finish playing that hand).^^" write "If the dealers first card is an ace, you will be given the option to " write "take insurance against the dealer getting blackjack by typing the " write "command 'insurance'. This must be done before any other action " write "regarding your hand is taken.^^" write "If your two cards are of equal value, you will also be given the " write "opportunity to split your hand. This takes your two initial cards " write "and makes two one-card hands from them. This is done using the 'split' " write "command. These two hands are then played out one at a time as normal. " write "Be sure to pay attention to the indicator at the bottom of the screen " write "telling you which card you are currently playing.^^" write "If the first two card of any hand total 9, 10 or 11, you will be " write "given the opportunity to 'double'. In this case your initial bet will " write "be doubled and you will receive one more card only.^^" } grammar about >about {+about write "BlackJACL^" write "Copyright (c) 2001-2007 Stuart Allen^^" write "This program is free software; you can redistribute it and/or " write "modify it under the terms of the GNU General Public License " write "as published by the Free Software Foundation; either version 2 " write "of the License, or (at your option) any later version.^" write "This program is distributed in the hope that it will be useful, " write "but WITHOUT ANY WARRANTY; without even the implied warranty of " write "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " write "GNU General Public License for more details.^^" write "You should have received a copy of the GNU General Public License " write "along with this program; if not, write to the Free Software " write "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, " write "USA.^" } grammar insurance >insurance {+insurance if GAME_PHASE = place_bet execute "+display_table" return endif set INDEX = current_hand(bet) set INDEX / 2 set current_player(insurance) = INDEX set current_player(money) - INDEX execute "+display_table" } grammar double >double {+double if GAME_PHASE = place_bet execute "+display_table" return endif set current_player(money) - current_hand(bet) set current_hand(bet) * 2 execute "+basic_strategy_code" set last_move = double execute "+deal_cardhit {+hit if GAME_PHASE = place_bet execute "+display_table" return endif execute "+basic_strategy_code" set last_move = hit execute "+deal_card 20 if current_player(hands) = 1 if current_hand(total) = 21 execute "+play_out_dealer" else execute "+hand_finished" endif return endif if current_hand = hand_one set current_hand = hand_two else if current_hand(total) = 21 : hand_one(total) < 22 execute "+play_out_dealer" else execute "+hand_finished" endif return endif endif execute "+display_table" } grammar stay >stay {+stay if GAME_PHASE = place_bet execute "+display_table" return endif execute "+basic_strategy_code" set last_move = stay if current_player(hands) = 1 execute "+play_out_dealer" return endif if current_hand = hand_one set current_hand = hand_two execute "+display_table" else execute "+play_out_dealer" endif } grammar split >split {+split if GAME_PHASE = place_bet execute "+display_table" return endif execute "+basic_strategy_code" set last_move = split set hand_two(bet) = hand_one(bet) set current_player(money) - hand_two(bet) set current_player(hands) = 2 set hand_one(aces_as_one) = 0 set hand_one(cards) = 1 set hand_two(aces_as_one) = 0 set hand_two(cards) = 1 set FIRST = false set INDEX = FIRST_CARD repeat if INDEX(parent) = current_hand if FIRST = false set FIRST = INDEX else set SECOND = INDEX endif endif set INDEX = INDEX(next) until INDEX = PAST_LAST set SECOND(parent) = hand_two if SECOND(value) = 11 set hand_two(aces) = 1 set hand_one(aces) - 1 if FIRST(value) = 11 ; Splitting aces... set hand_one(total) = 11 set hand_two(total) = 11 execute "+deal_card noun4(aces_as_one) set noun4(total) - 10 set noun4(aces_as_one) + 1 endif } integer FIRST integer SECOND {+is_pair set FIRST = 0 set INDEX = FIRST_CARD repeat if INDEX(parent) = current_hand if FIRST = 0 set FIRST = INDEX(value) else set SECOND = INDEX(value) return endif endif set INDEX = INDEX(next) until INDEX = PAST_LAST } {+intro set max_rand = end set max_rand - d1_two_diamonds set max_rand / 2 set max_rand - 8 image IMAGE_blackjack execute "+shuffle_decks" # Set the number of hands for the player back to one (dealer can only have one) set current_player = kryten set current_player(hands) = 1 set current_hand = hand_one set GAME_PHASE = place_bet set PREVIOUS_GAME_PHASE = place_bet write "^^BlackJACL^^" write "Blackjack pays 3:2^" write "Dealer must draw to 16 and stay on all 17s.^" write "Double allowed after split, two decks in shoe.^" write "Insurance pays 2 to 1^^" write "Select your initial bet to start playing.^" } {+play_out_dealer if SOFT_SEVENTEEN = true execute "+soft" else execute "+hard" endif execute "+hand_finished" } {+hand_finished execute "+determine_winner 16 endif } integer RESULT {+determine_winner ; Player bust... if noun4(total) > 21 set noun4(result) = 1 return endif ; Player got Blackjack... if noun4(total) = 21 if noun4(cards) = 2 if current_player(hands) = 1 if dealers_hand(total) = 21 if dealers_hand(cards) = 2 ; ...and so did the dealer... set current_player(money) + noun4(bet) ; Pay two to one on insurance set current_player(money) + current_player(insurance) set current_player(money) + current_player(insurance) set noun4(result) = 2 return endif endif set INDEX = noun4(bet) set INDEX / 2 set COUNTER = noun4(bet) set COUNTER * 2 set COUNTER + INDEX set current_player(money) + COUNTER set noun4(result) = 3 return endif endif endif ; The dealer got Blackjack if dealers_hand(total) = 21 if dealers_hand(cards) = 2 set noun4(result) = 4 ; Pay two to one on insurance set current_player(money) + current_player(insurance) set current_player(money) + current_player(insurance) return endif endif ; Player equal with dealer... if noun4(total) = dealers_hand(total) set current_player(money) + noun4(bet) set noun4(result) = 2 return endif ; Dealer bust... if dealers_hand(total) > 21 set current_player(money) + noun4(bet) set current_player(money) + noun4(bet) set noun4(result) = 5 return endif ; Player higher than delear... if noun4(total) > dealers_hand(total) set current_player(money) + noun4(bet) set current_player(money) + noun4(bet) set noun4(result) = 6 return endif ; Player not bust, dealer not bust, player lower than dealer... set noun4(result) = 7 } {+display_result if noun4(result) = 1 write " -- You bust." return endif if noun4(result) = 2 write " -- Push" return endif if noun4(result) = 3 write " -- Blackjack!" return endif if noun4(result) = 4 write " -- Dealer got Blackjack." return endif if noun4(result) = 5 write " -- Dealer bust." return endif if noun4(result) = 6 write " -- You won." return endif if noun4(result) = 7 write " -- Dealer won." return endif } {+deal_initial ; Set the number of hands for the player back to one (dealer can only have one) set current_player(hands) = 1 set current_player(insurance) = 0 set current_hand = hand_one ; Reset the player's stats set dealers_hand(aces) = 0 set dealers_hand(aces_as_one) = 0 set dealers_hand(total) = 0 set dealers_hand(cards) = 0 set hand_one(aces) = 0 set hand_one(aces_as_one) = 0 set hand_one(total) = 0 set hand_one(cards) = 0 set hand_two(aces) = 0 set hand_two(aces_as_one) = 0 set hand_two(total) = 0 set hand_two(cards) = 0 if PASSED_NEAR_END = true execute "+shuffle_decks" endif ; Deal the initial cards out in the correct order execute "+deal_cardomega2 {+omega2 write "The current Omega-II count is " execute "+display_counthighlow {+highlow write "The current HIGH-LOW count is " execute "+display_countko {+ko write "The current KO count is " execute "+display_countbet {+bet if GAME_PHASE = players_turn write "You can't place a bet until the start of the next hand.^" execute "+display_table" return endif if $integer < 25 : $integer > 1000 write "This table has a minimum bet of $25 and a maximum bet of $1000.^" execute "+display_table" return endif set GAME_PHASE = players_turn set current_player(money) - $integer set current_hand(bet) = $integer execute "+deal_initial" } object dealer : dealer static short name "dealer" object dealers_hand : dealer_hand object kryten: myself self me james bond has ANIMATE short name "player one" quantity 42 money 2000 parent casino player object hand_one : hand one short name "first hand" object hand_two : hand two short name "second hand" integer TEMP integer BACKUP {+basic_strategy_check if PREVIOUS_GAME_PHASE = place_bet : CHECK_STRATEGY = 0 return endif if last_move != best_move write "^You should have " MOVE_TYPE[best_move] !^ endif #write " (LAST: " MOVE_TYPE[last_move] " BEST: " MOVE_TYPE[best_move] ")^" } {+basic_strategy_table set current_hand(cards) = 3; DONT DO THE PAIRS CHECK AS THERE ARE NO REAL CARDS set current_hand(aces) = 0; set current_hand(aces_as_one) = 0; set current_hand(total) = 4 # PLAYER LOOP repeat execute "+dealer_loop" set current_hand(total) + 1 until current_hand(total) = 21 } {+dealer_loop set dealers_hand(total) = 2 repeat execute "+basic_strategy_code" if best_move = stay write "S " endif if best_move = hit write "H " endif if best_move = double write "D " endif set dealers_hand(total) + 1 until dealers_hand(total) = 12 write "^" } {+basic_strategy_code execute "+is_pair" if current_hand(cards) = 2 if FIRST = SECOND # CURRENT HAND IS A PAIR if FIRST = 11 set best_move = split return endif if FIRST = 10 set best_move = stay return endif if FIRST = 9 if dealers_hand(total) = 7 : dealers_hand(total) > 9 set best_move = stay else set best_move = split endif return endif if FIRST = 8 set best_move = split return endif if FIRST = 7 if dealers_hand(total) > 7 set best_move = hit else set best_move = split endif return endif if FIRST = 6 if dealers_hand(total) = 2 : dealers_hand(total) > 6 set best_move = hit else set best_move = split endif return endif if FIRST = 5 if dealers_hand(total) > 9 set best_move = hit else set best_move = double endif return endif if FIRST = 4 if dealers_hand(total) = 5 : dealers_hand(total) = 6 set best_move = split else set best_move = hit endif return endif # MUST BE A PAIR OF 3s OR 2s. BOTH HAVE SAME STRATEGY if dealers_hand(total) < 5 : dealers_hand(total) > 7 set best_move = hit else set best_move = split endif return endif endif if current_hand(aces) > current_hand(aces_as_one) # CURRENT HAND IS A SOFT TOTAL if current_hand(total) > 18 set best_move = stay return endif if current_hand(total) = 18 if dealers_hand(total) > 8 set best_move = hit else set best_move = stay endif return endif set best_move = hit return endif # CURRENT HAND IS A HARD TOTAL if current_hand(total) > 16 set best_move = stay return endif if current_hand(total) > 12 # HAND IS 13 TO 16 if dealers_hand(total) < 7 set best_move = stay else set best_move = hit endif return endif if current_hand(total) = 12 if dealers_hand(total) < 4 : dealers_hand(total) > 6 set best_move = hit return endif set best_move = stay endif if current_hand(total) = 11 if dealers_hand(total) = 11 set best_move = hit else set best_move = double endif return endif if current_hand(total) = 10 if dealers_hand(total) > 9 set best_move = hit else set best_move = double endif return endif if current_hand(total) = 9 if dealers_hand(total) = 2 : dealers_hand(total) > 6 set best_move = hit else set best_move = double endif return endif set best_move = hit } {+header set PREVIOUS_GAME_PHASE = GAME_PHASE } {+footer execute "+basic_strategy_check" write "Bankroll: $" current_player(money) if GAME_PHASE = place_bet write "^At this point in the game you can: bet [amount]" endif if GAME_PHASE = players_turn if current_player(hands) = 2 write " (currently playing " current_hand{the} ")" endif write "^At this point in the game you can:" if current_hand(cards) = 2 if current_player(hands) = 1 if dealers_hand(cards) = 1 if dealers_hand(total) = 11 if current_player(insurance) = 0 write " insurance" endif endif endif endif endif if current_hand(cards) = 2 if current_player(hands) = 1 execute "+is_pair" if FIRST = SECOND write " split" endif endif endif if current_hand(total) = 9 : current_hand(total) = 10 : current_hand(total) = 11 if current_player(hands) = 2 if current_hand(cards) = 1 if DAS = 1 write " double" endif endif else if current_hand(cards) = 2 write " double" endif endif endif write " hit stay" endif write "^" set score = current_player(money) }