Skip to content

Instantly share code, notes, and snippets.

@smartwatermelon
Last active August 16, 2020 03:19
Show Gist options
  • Save smartwatermelon/229c8788b2afb7b9e5a0f68e46c03c05 to your computer and use it in GitHub Desktop.
Save smartwatermelon/229c8788b2afb7b9e5a0f68e46c03c05 to your computer and use it in GitHub Desktop.
Rock, Paper, Scissors in bash, based on @cassidoo's interview question from November 24, 2019
#!/usr/bin/env bash
set -eu -o pipefail
# shellcheck source=/Users/andrewrich/etc/functions.sh
. "$HOME/etc/functions.sh"
readonly R="ROCK" P="PAPER" S="SCISSORS"
about () {
cat <<EOF
$( basename "$0" ) by Andrew Rich <[email protected]>
Based on @cassidoo's interview question from https://buttondown.email/cassidoo/archive/be-careful-with-your-words-once-they-are-said/
Rock/Paper/Scissors: https://en.wikipedia.org/wiki/Rock_paper_scissors
Truth table: https://www.skeptic.com/wordpress/wp-content/uploads/Rock-paper-scisscors-510px.jpg
EOF
}
syntax () {
cat <<EOF
Usage: $( basename "$0" ) <THROW>
Possible values for THROW are ROCK, PAPER, SCISSORS
The first letter of the value is sufficient.
Examples:
$ rps ROCK
=> Computer throws PAPER: Computer wins!
$ rps SCISSORS
=> Computer throws PAPER: You win!
$ rps PAPER
=> Computer throws PAPER: It's a draw!
EOF
}
function get_player_throw () {
# this function gets the player throw interactively if they didn't enter one
read -e -r -n 1 -p "Rock, Paper, Scissors (or Quit): " THROW
THROW=$( toUpper "${THROW}" )
echo "${THROW}"
}
function player_opts () {
# this function processes/validates the player-entered options
# get the first letter and capitalize it
# if it matches R P S Q, return; else call get_player_throw to get a new entry
PLAYER_OPT="$( toUpper "$1" )"
PLAYER_OPT="${PLAYER_OPT:0:1}"
while ! [[ "${PLAYER_OPT}" =~ ^(R|P|S|Q)$ ]]; do
PLAYER_OPT=$( get_player_throw )
done
echo "${PLAYER_OPT}"
}
function computer_throw () {
# this function returns the computer's throw
shuf -n 1 -e R P S
}
function play () {
# this function plays PLAYER_THROW against COMP_THROW and returns the winner
PLAYER_THROW=$1
COMP_THROW=$2
[ "$PLAYER_THROW" == "$COMP_THROW" ] && ( echo "TIE"; return )
case $PLAYER_THROW in
'R')
case $COMP_THROW in
'P') echo 'Computer';;
'S') echo 'Player';;
esac;;
'P')
case $COMP_THROW in
'R') echo "Player";;
'S') echo 'Computer';;
esac;;
'S')
case $COMP_THROW in
'R') echo "Computer";;
'P') echo 'Player';;
esac;;
esac
}
if [ $# != 1 ]; then
about; syntax; THROW="$( get_player_throw )"
else
THROW="$1"
fi
PL="$( player_opts "$THROW" )"
while [ "${PL}" != "Q" ]; do
CO="$( computer_throw )"
PL_OUT=$( eval echo "\$${PL}" )
CO_OUT=$( eval echo "\$${CO}" )
echo -e "\n$PL_OUT vs $CO_OUT: $(play "$PL" "$CO")"
THROW=""
PL="$( player_opts "$THROW" )"
done
echo -e "\nGoodbye!\n"
@wgmyers
Copy link

wgmyers commented Aug 16, 2020

Since you, like me, probably don't have a copy of functions.sh, you'll be wanting this or something like it:

function toUpper() {
  echo ${1^^}
}

@smartwatermelon
Copy link
Author

Thanks @wgmyers, I blanked on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment