Last active
June 1, 2022 09:50
-
-
Save seb-jones/f36f8881274fd66fe8319a588d4c3296 to your computer and use it in GitHub Desktop.
Blackjack Game written in Bash Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/bash | |
# | |
# Simple Blackjack game written in Bash. To play, give this file | |
# execute permissions and run it: | |
# chmod u+x bashjack.sh | |
# ./bashjack.sh | |
# | |
# Alternatively you can run Bash with this file as an argument: | |
# bash bashjack.sh | |
# | |
# Input keys are indicated by single characters surrounded by | |
# brackets. For example, '(h)it' can be read as 'Press h to hit.' | |
# | |
# The '-d' option may be used to specify the delay between messages: | |
# ./bashjack.sh -d '0.2' | |
# | |
# This value is passed as an argument to the `sleep` command, and | |
# defaults to '1'. | |
# | |
# Written by Seb Jones (https://sebj.co.uk) | |
getopts "d:" message_delay | |
message_delay=${OPTARG:-"1"} | |
declare -a deck player_hand dealer_hand | |
function new_deck | |
{ | |
cards=( | |
"Two|2" | |
"Three|3" | |
"Four|4" | |
"Five|5" | |
"Six|6" | |
"Seven|7" | |
"Eight|8" | |
"Nine|9" | |
"Ten|10" | |
"Jack|10" | |
"Queen|10" | |
"King|10" | |
"Ace|1" | |
) | |
suites=( | |
"Diamonds" | |
"Hearts" | |
"Clubs" | |
"Spades" | |
) | |
for suite in ${suites[@]}; do | |
for card in ${cards[@]}; do | |
echo "$suite|$card" | |
done | |
done | |
} | |
function card_suite | |
{ | |
echo "$1" | cut --delimiter="|" --fields="1,1" | |
} | |
function card_name | |
{ | |
echo "$1" | cut --delimiter="|" --fields="2,2" | |
} | |
function card_value | |
{ | |
echo "$1" | cut --delimiter="|" --fields="3,3" | |
} | |
function card_is_ace | |
{ | |
[[ "$(card_name $1)" == "Ace" ]] | |
} | |
function card_is_face | |
{ | |
pattern='^(Jack|Queen|King)$' | |
[[ "$(card_name $1)" =~ $pattern ]] | |
} | |
function card_full_name | |
{ | |
echo "$(card_name $1) of $(card_suite $1)" | |
} | |
function card_abbreviation | |
{ | |
if (card_is_face $1 || card_is_ace $1); then | |
name=$(card_name $1) | |
name=${name:0:1} | |
else | |
name="$(card_value $1)" | |
fi | |
suite=$(card_suite $1) | |
echo "$name-${suite:0:1}" | |
} | |
function hand_value | |
{ | |
sorted_hand=($(echo "$@" | tr ' ' "\n" | sort --field-separator='|' --key='3,3n')) | |
declare -i value=0 | |
for card in ${sorted_hand[@]}; do | |
card_value=$(card_value $card) | |
value=$((value + card_value)) | |
done | |
if [[ $value -lt 12 ]]; then | |
for card in ${sorted_hand[@]}; do | |
if card_is_ace $card; then | |
value+=10 | |
fi | |
if [[ $value -gt 12 ]]; then | |
break | |
fi | |
done | |
fi | |
echo $value | |
} | |
function hand_abbreviation | |
{ | |
echo -n "( " | |
for card in $@; do | |
echo -n "$(card_abbreviation $card) " | |
done | |
echo ")" | |
} | |
function hand_is_bust | |
{ | |
[[ $(hand_value $@) -gt 21 ]] | |
} | |
function hand_is_blackjack | |
{ | |
[[ $# -eq 2 && $(hand_value $@) -eq 21 ]] | |
} | |
function echo_with_delay | |
{ | |
echo -e $@ | |
sleep $message_delay | |
} | |
function hit_dealer | |
{ | |
card=${deck[0]} | |
deck=(${deck[@]:1}) | |
dealer_hand+=($card) | |
echo_with_delay "\nDealer draws $(card_full_name $card)" | |
} | |
function hit_player | |
{ | |
card=${deck[0]} | |
deck=(${deck[@]:1}) | |
player_hand+=($card) | |
echo_with_delay "\nPlayer draws $(card_full_name $card)" | |
} | |
function player_turn | |
{ | |
input="" | |
until [[ $input == "s" ]]; do | |
echo_with_delay "\nPlayer hand: $(hand_value ${player_hand[@]}) $(hand_abbreviation ${player_hand[@]})\n\n(h)it or (s)tay?" | |
read -s -n 1 input | |
input=${input,,} | |
if [[ $input == "h" ]]; then | |
hit_player | |
if hand_is_bust ${player_hand[@]}; then | |
return 1; | |
fi | |
fi | |
done | |
echo_with_delay "\nPlayer stays." | |
return 0; | |
} | |
function dealer_turn | |
{ | |
echo_with_delay "\nDealer reveals $(card_full_name ${dealer_hand[1]})." | |
dealer_hand_value=$(hand_value ${dealer_hand[@]}) | |
echo_with_delay "\nDealer hand: $dealer_hand_value $(hand_abbreviation ${dealer_hand[@]})." | |
player_hand_value=$(hand_value ${player_hand[@]}) | |
until [[ $dealer_hand_value -ge 17 || $dealer_hand_value -gt $player_hand_value ]]; do | |
hit_dealer | |
dealer_hand_value=$(hand_value ${dealer_hand[@]}) | |
echo_with_delay "\nDealer hand: $dealer_hand_value $(hand_abbreviation ${dealer_hand[@]})." | |
done | |
if hand_is_bust ${dealer_hand[@]}; then | |
return 1; | |
fi | |
echo_with_delay "\nDealer stays." | |
return 0 | |
} | |
function new_game | |
{ | |
deck=($(new_deck | shuf)) | |
player_hand=(${deck[@]:0:2}) | |
dealer_hand=(${deck[@]:2:2}) | |
deck=(${deck[@]:4}) | |
echo_with_delay "\nPlayer draws $(card_full_name ${player_hand[0]}) and $(card_full_name ${player_hand[1]})." | |
if hand_is_blackjack ${player_hand[@]}; then | |
if hand_is_blackjack ${dealer_hand[@]}; then | |
echo_with_delay "\nDealer has $(card_full_name ${dealer_hand[0]}) and $(card_full_name ${dealer_hand[1]})." | |
echo_with_delay "\nBoth players have blackjack. Game is a draw." | |
else | |
echo_with_delay "\nBlackjack!" | |
fi | |
return | |
elif hand_is_blackjack ${dealer_hand[@]}; then | |
echo_with_delay "\nDealer has $(card_full_name ${dealer_hand[0]}) and $(card_full_name ${dealer_hand[1]})." | |
echo_with_delay "\nDealer has blackjack. Dealer wins." | |
return | |
fi | |
echo_with_delay "\nDealer shows $(card_full_name ${dealer_hand[0]})." | |
if ! player_turn; then | |
echo_with_delay "\nPlayer bust." | |
return | |
fi | |
if ! dealer_turn; then | |
echo_with_delay "\nDealer bust." | |
return | |
fi | |
player_hand_value=$(hand_value ${player_hand[@]}) | |
dealer_hand_value=$(hand_value ${dealer_hand[@]}) | |
echo_with_delay "\nPlayer has $player_hand_value. Dealer has $dealer_hand_value." | |
if [[ $player_hand_value -gt $dealer_hand_value ]]; then | |
echo_with_delay "\nPlayer wins." | |
elif [[ $player_hand_value -lt $dealer_hand_value ]]; then | |
echo_with_delay "\nDealer wins." | |
else | |
echo_with_delay "\nGame is a draw." | |
fi | |
} | |
function menu_loop | |
{ | |
input="" | |
until [[ $input == "q" ]]; do | |
echo_with_delay "\n(p)lay or (q)uit?" | |
read -s -n 1 input | |
input=${input,,} | |
if [[ $input == "p" ]]; then | |
new_game | |
fi | |
done | |
return 0 | |
} | |
menu_loop | |
exit 0 |
Alright thanks for proper explanation.
Get Outlook for Android<https://aka.ms/AAb9ysg>
…________________________________
From: Seb Jones ***@***.***>
Sent: Tuesday, April 19, 2022 12:21:37 AM
To: seb-jones ***@***.***>
Cc: Abiodun Johnson ***@***.***>; Mention ***@***.***>
Subject: Re: seb-jones/bashjack.sh
@seb-jones commented on this gist.
________________________________
Please can you explain to me the codes how it works in order to defend it? Let's assume the total dealer is 21. Please I need your urgent reply. Thanks.
@biodun73<https://github.com/biodun73> Unfortunately I'd strongly recommend not using this code for your assignment. It was written purely as an exercise in seeing what I could make BASH do, and should not be considered good code. In the real world a proper programming language should be used for this kind of application. BASH scripts should really only be used for simple automation tasks.
—
Reply to this email directly, view it on GitHub<https://gist.github.com/f36f8881274fd66fe8319a588d4c3296#gistcomment-4136914>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ACXKNTMYJSIKLKLF6KAYT4LVFXG6DANCNFSM5TWR45DQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
Cool code Seb! I am just messing around in bash and dissected yours line by line to help me learn some new tricks!
In which area of code do you use like there?
…On Wed, 1 Jun 2022, 10:30 DrakeCoding, ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
Cool code Seb! I am just messing around in bash and dissected yours line
by line to help me learn some new tricks!
—
Reply to this email directly, view it on GitHub
<https://gist.github.com/f36f8881274fd66fe8319a588d4c3296#gistcomment-4185717>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACXKNTKA7KF4SF4OKCG6HIDVM4GP3ANCNFSM5TWR45DQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@biodun73 Unfortunately I'd strongly recommend not using this code for your assignment. It was written purely as an exercise in seeing what I could make BASH do, and should not be considered good code. In the real world a proper programming language should be used for this kind of application. BASH scripts should really only be used for simple automation tasks.