Last active
August 16, 2020 03:19
-
-
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
This file contains hidden or 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/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" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Since you, like me, probably don't have a copy of functions.sh, you'll be wanting this or something like it: