155 lines
3.3 KiB
Bash
Executable file
155 lines
3.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
clear() {
|
|
printf "\x1b\x5b\x48\x1b\x5b\x32\x4a"
|
|
}
|
|
|
|
red() {
|
|
local red=$'\x1b\x5b\x33\x31\x6d'
|
|
local rst=$'\x1b\x28\x42\x1b\x5b\x6d'
|
|
printf %s%s%s "$red" "$1" "$rst"
|
|
}
|
|
|
|
blue() {
|
|
local blue=$'\x1b\x5b\x34\x34\x6d'
|
|
local rst=$'\x1b\x28\x42\x1b\x5b\x6d'
|
|
printf %s%s%s "$blue" "$1" "$rst"
|
|
}
|
|
|
|
underline() {
|
|
local ul=$'\x1b\x5b\x34\x6d'
|
|
local rst=$'\x1b\x28\x42\x1b\x5b\x6d'
|
|
printf %s%s%s "$ul" "$1" "$rst"
|
|
}
|
|
|
|
build_bucket() {
|
|
local row amt=$3
|
|
declare -n bkt=$1
|
|
|
|
bkt=(┏━━━━━━┓)
|
|
|
|
for (( row = $2; row > 0; row -= 1 )); do
|
|
if (( amt >= row )); then
|
|
bkt+=(┃"$(blue " ")"┃)
|
|
else
|
|
bkt+=("┃ ┃")
|
|
fi
|
|
done
|
|
|
|
bkt+=(┗━━━━━━┛)
|
|
}
|
|
|
|
render() {
|
|
local bkt_idx=$3 pour_idx=$4 moves=$5
|
|
local bkt_{one,two,three} {bkt_,}row meters
|
|
declare -n bkt_sizes=$1 bkt_amts=$2
|
|
|
|
build_bucket bkt_one "${bkt_sizes[0]}" "${bkt_amts[0]}"
|
|
build_bucket bkt_two "${bkt_sizes[1]}" "${bkt_amts[1]}"
|
|
build_bucket bkt_three "${bkt_sizes[2]}" "${bkt_amts[2]}"
|
|
|
|
for (( row = 0; row < ${#bkt_one[@]}; row += 1 )); do
|
|
printf "%s" "${bkt_one[$row]}"
|
|
(( bkt_row = (${#bkt_one[@]} - row) ))
|
|
|
|
if (( bkt_row <= ${#bkt_two[@]} )); then
|
|
printf " %s" "${bkt_two[$((${#bkt_one[@]} - 3 - $bkt_row))]}"
|
|
fi
|
|
|
|
if (( bkt_row <= ${#bkt_three[@]} )); then
|
|
printf " %s" "${bkt_three[$((${#bkt_one[@]} - 5 - $bkt_row))]}"
|
|
fi
|
|
|
|
printf "\n"
|
|
done
|
|
|
|
meters=("${bkt_amts[0]}"/8L "${bkt_amts[1]}"/5L "${bkt_amts[2]}"/3L)
|
|
meters[$bkt_idx]=$(red "${meters[$bkt_idx]}")
|
|
|
|
if [[ -n $pour_idx ]]; then
|
|
meters[$pour_idx]=$(underline "${meters[$pour_idx]}")
|
|
fi
|
|
|
|
printf " %s %s %s\n" "${meters[@]}"
|
|
printf "\n"
|
|
printf "Move #%d\n" "$moves"
|
|
}
|
|
|
|
cleanup() {
|
|
tput cnorm
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
tput civis
|
|
|
|
moves=0 win=0 bkt_idx=0 pour_idx=
|
|
sizes=(8 5 3) amts=(0 0 0)
|
|
|
|
while (( ! win )); do
|
|
clear
|
|
render sizes amts "$bkt_idx" "$pour_idx" "$moves"
|
|
read -rsn 1 key
|
|
|
|
case $key in
|
|
f)
|
|
if [[ -z $pour_idx ]]; then
|
|
amts[$bkt_idx]=${sizes[$bkt_idx]}
|
|
(( moves += 1 ))
|
|
fi
|
|
;;
|
|
e)
|
|
if [[ -z $pour_idx ]]; then
|
|
amts[$bkt_idx]=0
|
|
(( moves += 1 ))
|
|
fi
|
|
;;
|
|
p)
|
|
if [[ -z $pour_idx ]]; then
|
|
pour_idx=$bkt_idx
|
|
else
|
|
if (( pour_idx != bkt_idx )); then
|
|
(( moves += 1 ))
|
|
(( space = sizes[$pour_idx] - amts[$pour_idx] ))
|
|
|
|
if (( amts[$bkt_idx] <= space )); then
|
|
(( amts[$pour_idx] += amts[$bkt_idx] ))
|
|
(( amts[$bkt_idx] = 0 ))
|
|
else
|
|
(( amts[$bkt_idx] -= space ))
|
|
(( amts[$pour_idx] += space ))
|
|
fi
|
|
fi
|
|
|
|
bkt_idx=$pour_idx pour_idx=
|
|
fi
|
|
;;
|
|
$'\x1b')
|
|
read -rsn 2 arrow
|
|
|
|
case $arrow in
|
|
$'\x4f\x43'|$'\x5b\x43')
|
|
if [[ -z $pour_idx ]] && (( bkt_idx < 2 )); then
|
|
(( bkt_idx += 1 ))
|
|
elif [[ -n $pour_idx ]] && (( pour_idx < 2 )); then
|
|
(( pour_idx += 1 ))
|
|
fi
|
|
;;
|
|
$'\x4f\x44'|$'\x5b\x44')
|
|
if [[ -z $pour_idx ]] && (( bkt_idx > 0 )); then
|
|
(( bkt_idx -= 1 ))
|
|
elif [[ -n $pour_idx ]] && (( pour_idx > 0 )); then
|
|
(( pour_idx -= 1 ))
|
|
fi
|
|
esac
|
|
esac
|
|
|
|
for amt in "${amts[@]}"; do
|
|
if (( amt == 4 )); then
|
|
win=1
|
|
fi
|
|
done
|
|
done
|
|
|
|
clear
|
|
render sizes amts "$bkt_idx" "$pour_idx" "$moves"
|
|
read -rsn 1
|