#!/bin/sh # Baccarat game, shell script written by Dave Taylor for Linux Journal function initializeDeck { card=1 while [ $card -lt 53 ] do deck[$card]=$card card=$(( $card + 1 )) done player[1]=-1; player[2]=-1; player[3]=-1; player[4]=-1; player[5]=-1 banker[1]=-1; banker[2]=-1; banker[3]=-1; banker[4]=-1; banker[5]=-1 } function pickCard { local errcount randomcard threshold=10 # max guesses for a card before we fall through errcount=0 while [ $errcount -lt $threshold ] do randomcard=$(( ( $RANDOM % 52 ) + 1 )) errcount=$(( $errcount + 1 )) if [ ${deck[$randomcard]} -ne 0 ] ; then picked=${deck[$randomcard]} deck[$picked]=0 # picked, remove it # echo randomly picked $picked return $picked fi done # If we get here, we've been uanble to randomly pick a card # so now we'll just step up until we find an available card randomcard=1 while [ ${deck[$randomcard]} -eq 0 ] do randomcard=$(( $randomcard + 1 )) done picked=$randomcard deck[$picked]=0 # picked, remove it # echo fell through, picked $picked return $picked } function shuffleDeck { count=1 while [ $count -le 52 ] do pickCard newdeck[$count]=$picked # echo " .. pickCard returned $picked" count=$(( $count + 1 )) done } function showCard { card=$1 if [ $card -lt 1 -o $card -gt 52 ] ; then echo "Bad card value: $card" exit 1 fi suite="$(( ( ( $card - 1) / 13 ) + 1))" rank="$(( $card % 13))" case $suite in 1 ) suite="Hearts" ;; 2 ) suite="Clubs" ;; 3 ) suite="Spades" ;; 4 ) suite="Diamonds" ;; * ) echo "Bad suite value: $suite"; exit 1 esac case $rank in 0 ) rank="King" ;; 1 ) rank="Ace" ;; 11) rank="Jack" ;; 12) rank="Queen" ;; esac cardname="$rank of $suite" } function handValue { # feed this as many cards as are in the hand. This uses weird Baccarat # hand value scoring: 1-9 are their own point values, 10,J,Q,K are 0 handvalue=0 # initialize for cardvalue do if [ $cardvalue -ge 0 ] ; then rankvalue=$(( $cardvalue % 13 )) case $rankvalue in 0|11|12 ) rankvalue=0 ;; 1 ) rankvalue=11 ;; esac handvalue=$(( $handvalue + $rankvalue )) fi done handvalue=$(( $handvalue % 10 )) } function dealBanker { # Banker draws a card banker[$nextbankercard]=${newdeck[$nextcard]} handValue ${banker[1]} ${banker[2]} ${banker[3]} bankerhandvalue=$handvalue echo -n "Banker takes a card: " showCard ${banker[$nextbankercard]} echo "$cardname (hand value = $bankerhandvalue)" } function showResult { # This determines who wins: "Banker", "Player" or "Tie". if [ $bankerhandvalue -gt $playerhandvalue ] ; then echo "Banker wins" result=1 elif [ $bankerhandvalue -lt $playerhandvalue ] ; then echo "Player wins" result=2 else echo "Tie" result=3 fi } ################################################################# #### The main code block .... initializeDeck shuffleDeck cat << EOF Welcome to Baccarat. You can choose to either stake the player or banker to win this game. Remember, face cards are worthless and all point values are modulo 10, with '9' the best possible hand value. We're using Punto Banco rules with this simulation, if you're already an expert... EOF player[1]=${newdeck[1]} player[2]=${newdeck[3]} nextplayercard=3 # player starts with two cards banker[1]=${newdeck[2]} banker[2]=${newdeck[4]} nextbankercard=3 # banker also has two cards nextcard=5 # we've dealt the first four cards already playerDrewCard=0 # not yet, at least # now we show both hands and call out the values... handValue ${player[1]} ${player[2]} playerhandvalue=$handvalue handValue ${banker[1]} ${banker[2]} bankerhandvalue=$handvalue # Step 1: show both hands, ascertain if there's an immediately endgame # situation where player or banker has 8 or 9... echo -n "** Player was dealt: " showCard ${player[1]} ; echo -n "$cardname, " showCard ${player[2]} ; echo "$cardname (hand value = $playerhandvalue)" echo -n "** Banker was dealt: " showCard ${banker[1]} ; echo -n "$cardname, " showCard ${banker[2]} ; echo "$cardname (hand value = $bankerhandvalue)" echo "" if [ $playerhandvalue -ge 8 -o $bankerhandvalue -ge 8 ] ; then echo -n "Play is complete. " showResult echo "" exit 0 fi # Step 2: Now, let's see if the player can draw a card. This can only # happen if the player has an initial total of 0-5 if [ $playerhandvalue -lt 6 ] ; then playerDrewCard=1 player[$nextplayercard]=${newdeck[$nextcard]} handValue ${player[1]} ${player[2]} ${player[3]} playerhandvalue=$handvalue echo -n "Player takes a card: "; showCard ${player[$nextplayercard]} echo "$cardname (hand value = $playerhandvalue)" nextplayercard=$(( $nextplayercard + 1 )) nextcard=$(( $nextcard + 1 )) fi # Step 3: the complicated rules of whether the Banker takes another # card or not, the essence of what makes Baccarat an interesting game... if [ $playerDrewCard -eq 0 ] ; then if [ $bankerhandvalue -lt 6 ] ; then dealBanker; fi else # Player drew a card. Now the rules get complicated... pdcRank=$(( ${player[3]} % 13 )) if [ $pdcRank -eq 2 -o $pdcRank -eq 3 ] ; then if [ $bankerhandvalue -lt 5 ]; then dealBanker; fi elif [ $pdcRank -eq 4 -o $pdcRank -eq 5 ] ; then if [ $bankerhandvalue -lt 6 ] ; then dealBanker; fi elif [ $pdcRank -eq 6 -o $pdcRank -eq 7 ] ; then if [ $bankerhandvalue -lt 7 ] ; then dealBanker; fi elif [ $pdcRank -eq 8 -a $bankerhandvalue -lt 3 ] ; then dealBanker; elif [ $pdcRank -eq 9 -o $pdcRank -eq 0 ] ; then if [ $bankerhandvalue -lt 4 ] ; then dealBanker; fi fi fi echo "" echo -n "Play is complete. " showResult echo "" exit 0