cli-games/simon/simon

85 lines
2.5 KiB
Bash
Executable File

#!/bin/bash
# Thanks for playing.
# Visit me at https://stormdragon.tk
# Released under the terms of the WTFPL http://wtfpl.net
# Follow me on GNU Social: https://social.stormdragon.tk/storm
# There are 2 sets of keybindings. uijk or erdf.
# The lowest note is e or u, with r or i being the next highest.
# Finally d or j follow by f and k for the ascending pitches.
# Note the arrow keys may also be used.
# Down is lowest with left, then right, then up in order of pitch.
get_key() {
# Arrow keys translate to upper case letters.
# Up arrow is A
# Down arrow is B
# Left arrow is D
local __key
local __lastKey
while [[ -z "$__key" && -z "$__lastKey" ]]; do
read -t 001 -rsn1 __key
while [[ "$__key" =~ [[:cntrl:][:punct:]] ]]; do
# Key may be an arrow or something else, so remove punct and cntrl characters and try again.
if [[ -n "$__key" ]]; then
__lastKey="$__key"
else
__key="$__lastKey"
break
fi
read -t 001 -rsn1 __key
done
done
# Return __key if it contains a letter.
# If it doesn't, then a punctuation key was pressed, so return __lastKey instead.
[[ -n "$__key" ]] && echo "$__key" || echo "$__lastKey"
}
# Simon notes
notes=("sq E4" "sq C#4" "sq A3" "sq E3")
#Original note.
pattern=($(($RANDOM % 4)))
#Here is the main loop of the program
continue=1
while [ $continue -ne 0 ]; do
# Play the pattern to match
for i in ${pattern[@]} ; do
play -qV0 -n synth .5 ${notes[$i]} norm -9 &> /dev/null
done
# Loop to read the player's input and compare it to the pattern
# Clear the player variable
unset player
i=0
while : ; do
key="$(get_key)"
key="$(echo "$key" | tr 'Afk' '0')"
key="$(echo "$key" | tr 'Cdj' '1')"
key="$(echo "$key" | tr 'Dir' '2')"
key="$(echo "$key" | tr 'Beu' '3')"
player=(${player[@]} $key)
# make sure the pressed key exists in the array.
if [[ "$key" =~ [0-3] ]]; then
play -qV0 -n synth .5 ${notes[$key]} norm -9 & &> /dev/null
fi
# make sure the player pattern is the same as the computer generated one
if [ "${player[$i]}" != "${pattern[$i]}" ]; then
continue=0
break
fi
# If the arrays are equal then break the loop, else increment i.
if [ ${#player[@]} -eq ${#pattern[@]} ]; then
break
else
((i++))
fi
done
if [ $continue -ne 0 ]; then
# sleep slightly longer than the length of one note.
sleep .6
pattern=(${pattern[@]} $(($RANDOM % 4)))
fi
done
echo "You got $((${#pattern[@]} - 1)) correct."
exit 0