#!/bin/bash # aceyduecey: dealer flips over two cards and you guess whether # the next card from the deck will or will not rank between # the two. For example, with a 6 and 8, a 7 is between the two, # but a 9 is not. function initializeDeck { # Start by creating the deck of cards card=1 while [ $card != 53 ] # 52 cards in a deck. You knew that, right? do deck[$card]=$card card=$(( $card + 1 )) done } function shuffleDeck { # It's not really a shuffle. It's a random extraction of card values # from the 'deck' array, creating newdeck[] as the "shuffled" deck count=1 while [ $count != 53 ] do pickCard newdeck[$count]=$picked count=$(( $count + 1 )) done } function pickCard { # This is the most interesting function: pick a random card from the deck # Uses the deck[] array to find an available card slot. local errcount randomcard threshold=10 # max guesses for a card before we fall through errcount=0 # Randomly pick a card that hasn't already been pulled from the deck # a max of $threshold times, fall through on fail (to avoid a possible # infinite loop where it keeps guessing the same already dealt card) while [ $errcount -lt $threshold ] do randomcard=$(( ( $RANDOM % 52 ) + 1 )) errcount=$(( $errcount + 1 )) if [ "${deck[$randomcard]}" != "0" ] ; then picked=${deck[$randomcard]} deck[$picked]=0 # picked, remove it return $picked fi done # If we get here, we've been unable to randomly pick a card, so we'll # just step through the array until we find an available card randomcard=1 while [ ${newdeck[$randomcard]} -eq 0 ] do randomcard=$(( $randomcard + 1 )) done picked=$randomcard deck[$picked]=0 # picked, remove it return $picked } function showCard { # This uses a div and a mod to figure out suit and rank, though # in this game only rank matters. Still, presentation is # important, so this helps make things pretty. card=$1 if [ $card -lt 1 -o $card -gt 52 ] ; then echo "Bad card value: $card" exit 1 fi # div and mod. See, all that math in school wasn't wasted! suit="$(( ( ( $card - 1) / 13 ) + 1))" rank="$(( $card % 13))" case $suit in 1 ) suit="Hearts" ;; 2 ) suit="Clubs" ;; 3 ) suit="Spades" ;; 4 ) suit="Diamonds" ;; * ) echo "Bad suit value: $suit"; exit 1 esac case $rank in 0 ) rank="King" ;; 1 ) rank="Ace" ;; 11) rank="Jack" ;; 12) rank="Queen" ;; esac cardname="$rank of $suit" } function dealCards { # Acey Deucey has two cards flipped up... card1=${newdeck[1]} # since deck is shuffled, we take card2=${newdeck[2]} # the top two cards from the deck card3=${newdeck[3]} # and pick card #3 secretly rank1=$(( ${newdeck[1]} % 13 )) # and let's get the rank values rank2=$(( ${newdeck[2]} % 13 )) # to make subsequent calculations easy rank3=$(( ${newdeck[3]} % 13 )) # to make subsequent calculations easy # Fix to make the king, default rank = 0, have rank = 13 if [ $rank1 -eq 0 ] ; then rank1=13; fi if [ $rank2 -eq 0 ] ; then rank2=13; fi if [ $rank3 -eq 0 ] ; then rank3=13; fi # Now let's organize them so that card1 is always lower than card2 if [ $rank1 -gt $rank2 ] ; then temp=$card1; card1=$card2; card2=$temp temp=$rank1; rank1=$rank2; rank2=$temp fi showCard $card1 ; cardname1=$cardname showCard $card2 ; cardname2=$cardname showCard $card3 ; cardname3=$cardname # shhh, it's a secret for now echo "I've dealt:" ; echo " $cardname1" ; echo " $cardname2" } function introblurb { cat << EOF Welcome to Acey Deucey. The goal of this game is for you to correctly guess whether the third card is going to be between the two cards I'll pull from the deck. For example, if I flip up a 5 of hearts and a jack of diamonds, you'd bet on whether the next card will have a higher rank than a 5 AND a lower rank than a jack (e.g., a 6, 7, 8, 9, or 10 of any suit). Ready? Let's go! EOF } ################################################################# #### The main code block .... games=0 won=0 if [ $# -gt 0 ] ; then # helpful info if a parameter is specified introblurb fi while [ /bin/true ] ; do # The main block starts here initializeDeck shuffleDeck dealCards splitValue=$(( $rank2 - $rank1 )) if [ $splitValue -eq 0 ] ; then echo "No point in betting when they're the same rank!" continue fi /bin/echo -n "The spread is $splitValue. Do you think the next card will " /bin/echo -n "be between them? (y/n/q) " read answer if [ "$answer" = "q" ] ; then echo "" echo "You played $games games and won $won times." exit 0 fi echo "I picked: $cardname3" # Is it between the values? Let's test. Remember, equal rank = lose if [ $rank3 -gt $rank1 -a $rank3 -lt $rank2 ] ; then # winner! winner=1 else winner=0 fi if [ $winner -eq 1 -a "$answer" = "y" ] ; then echo "You bet that it would be between the two, and it is. WIN!" won=$(( $won + 1 )) elif [ $winner -eq 0 -a "$answer" = "n" ] ; then echo "You bet that it would not be between the two, and it isn't. WIN!" won=$(( $won + 1 )) else echo "Bad betting strategy. You lose." fi games=$(( $games + 1 )) # how many times do you play? done exit 0