Last active
May 12, 2022 15:25
-
-
Save Hayao0819/caad8ef3952bdfef7287ef8c5d71e03c to your computer and use it in GitHub Desktop.
計算をして遊ぶゲーム miniは最小限の実装
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/env bash | |
#-- Initilize script --# | |
set -eu | |
# shellcheck source=/dev/null | |
source /dev/stdin < <(curl -sL "https://github.com/Hayao0819/FasBashLib/releases/download/v0.2.1/fasbashlib.sh") | |
#-- Define --# | |
AvailableNumbers=() | |
NumberOfStart=5 | |
TargetNumber=10 | |
#-- Functions --# | |
HelpMessage(){ echo "There is nothing"; } | |
GetExprNumbers(){ | |
local _NPrefix="" _Before="" _Chr | |
while read -r _Chr; do | |
if grep -qx "^[0-9]\+$" <<< "$_Chr"; then | |
echo "${_NPrefix-""}${_Chr}" | |
_NPrefix="" | |
else | |
case "$_Chr" in | |
"-") | |
if grep -qx "^[0-9]\+$" <<< "$_Before"; then | |
_NPrefix="" | |
else | |
_NPrefix="-" | |
fi | |
;; | |
esac | |
fi | |
_Before="$_Chr" | |
done < <(BreakChar <<< "$*") | |
} | |
# RemoveMatchLine <String> < <(PrintArray "${array[@]}") | |
RemoveMatchLine(){ | |
local i unseted=false | |
while read -r i; do | |
if [[ "$i" != "${1}" ]] || [[ "${unseted}" = true ]]; then | |
echo "$i" | |
else | |
unseted=true | |
fi | |
done | |
unset unseted i | |
} | |
# Loop [回数] [コマンド] | |
Loop(){ | |
local _T="$1" | |
shift 1 || return 1 | |
ForEach "$@" < <(yes "" | head -n "$_T") | |
} | |
# ゲームのメイン関数 | |
Game.Main(){ | |
local InputExpr | |
Game.Start | |
while true; do | |
! Game.Ask || break | |
done | |
Game.Result | |
} | |
Game.Start(){ | |
echo "四則演算をして最終的に\"$TargetNumber\"を作ろう" | |
# NumberOfStart回、0~9で乱数を取得してAvailableNumbersに追加 | |
# shellcheck disable=SC2016 | |
Loop "$NumberOfStart" eval 'ArrayAppend AvailableNumbers <<< $(( RANDOM % 10 ))' | |
} | |
Game.Result(){ | |
echo "最終的に残ったのは${AvailableNumbers[0]}" | |
if [[ "${AvailableNumbers[0]}" = "${TargetNumber}" ]]; then | |
echo "クリア!" | |
else | |
echo "失敗!" | |
fi | |
exit 0 | |
} | |
Game.Ask(){ | |
local UsedNumber=() | |
echo "今回使える数字は以下のとおりです" | |
PrintArray "${AvailableNumbers[@]}" | ForEach echo "・ {}" | |
echo -n "式を入力してください: " | |
read -r InputExpr | |
echo | |
# 指定された式の数字が使えるかどうかを確認 | |
local Num | |
while read -r Num; do | |
if ! PrintArray "${AvailableNumbers[@]}" | grep -qx -- "$Num"; then | |
echo "${Num}は使えません!" | |
AvailableNumbers+=("${UsedNumber[@]}") | |
unset UsedNumber | |
return 1 # 異常終了して関数を再度呼び出す | |
else | |
UsedNumber+=("$Num") | |
readarray -t AvailableNumbers < <(PrintArray "${AvailableNumbers[@]}" | RemoveMatchLine "$Num") | |
fi | |
done < <(GetExprNumbers "$InputExpr") | |
AvailableNumbers+=("$(( "$InputExpr" ))") 2> /dev/null | |
# もし数字が1つだけならゲームを終了する | |
if [[ "${#AvailableNumbers[@]}" = 1 ]]; then | |
return 0 | |
else | |
return 2 | |
fi | |
} | |
Game.Main |
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/env bash | |
#-- Initilize script --# | |
set -eu | |
# shellcheck source=/dev/null | |
source /dev/stdin < <(curl -sL "https://github.com/Hayao0819/FasBashLib/releases/download/v0.2.1/fasbashlib.sh") | |
#-- Define --# | |
AvailableNumbers=() | |
NumberOfStart=5 | |
TargetNumber=10 | |
ExprHistory=() | |
#-- Functions --# | |
HelpMessage(){ echo "There is nothing"; } | |
# ShiftArray <Array> <Number> | |
ShiftArray(){ | |
readarray -t "$1" < <(PrintEvalArray "$1" | sed "1,${2-"1"}d") | |
} | |
#ParseExpr(){ sed -E "s|([0-9]+)|\1\n|g" <<< "${*}" | sed -E -e "s|(\+)|\1\n|g" -e "s|(\-)|\1\n|g" -e "s|(\*)|\1\n|g" -e "s|(\/)|\1\n|g" | grep -v "^$"; } | |
GetExprNumbers(){ | |
local _NPrefix="" _Before="" _Chr | |
while read -r _Chr; do | |
if grep -qx "^[0-9]\+$" <<< "$_Chr"; then | |
echo "${_NPrefix-""}${_Chr}" | |
_NPrefix="" | |
else | |
case "$_Chr" in | |
"-") | |
if grep -qx "^[0-9]\+$" <<< "$_Before"; then | |
_NPrefix="" | |
else | |
_NPrefix="-" | |
fi | |
;; | |
esac | |
fi | |
_Before="$_Chr" | |
done < <(BreakChar <<< "$*") | |
} | |
# CheckNum <Number> | |
CheckNum(){ | |
! grep -q -- "\." <<< "$1" | |
} | |
# Loop [回数] [コマンド] | |
Loop(){ | |
local _T="$1" | |
shift 1 || return 1 | |
ForEach "$@" < <(yes "" | head -n "$_T") | |
} | |
# RemoveMatchLine <String> < <(PrintArray "${array[@]}") | |
RemoveMatchLine(){ | |
local i unseted=false | |
while read -r i; do | |
if [[ "$i" != "${1}" ]] || [[ "${unseted}" = true ]]; then | |
echo "$i" | |
else | |
unseted=true | |
fi | |
done | |
unset unseted i | |
} | |
# ゲームのメイン関数 | |
Game.Main(){ | |
Game.Start | |
while true; do | |
! Game.Ask || break #Game.Askが正常終了した時にループを終了する | |
done | |
Game.Result | |
} | |
Game.Start(){ | |
echo "四則演算をして最終的に\"$TargetNumber\"を作ろう" | |
# NumberOfStart回、0~9で乱数を取得してAvailableNumbersに追加 | |
# shellcheck disable=SC2016 | |
if [[ "${#AvailableNumbers[@]}" == 0 ]]; then | |
Loop "$NumberOfStart" eval 'ArrayAppend AvailableNumbers <<< $(( RANDOM % 10 ))' | |
fi | |
echo "今回使える数字は以下のとおりです" | |
} | |
Game.Result(){ | |
echo "最終的に残ったのは${AvailableNumbers[0]}" | |
if [[ "${AvailableNumbers[0]}" = "${TargetNumber}" ]]; then | |
echo "クリア!" | |
else | |
echo "失敗!" | |
fi | |
exit 0 | |
} | |
# Exit Code | |
# 0: 関数を終了 | |
# 1: 使用できない数字 | |
# 2: まだ俺のバトルフェイズは終了してないぜ! | |
# 3: 不正な入力 | |
Game.Ask(){ | |
local UsedNumber=() | |
local InputExpr PreviousExpr | |
PrintArray "${AvailableNumbers[@]}" | ForEach echo "・ {}" | |
echo -n "(式)> " | |
read -r InputExpr | |
# 空白を削除 | |
InputExpr="$(RemoveBlank <<< "$InputExpr")" | |
# 通常以外のコマンド?的なもの | |
PreviousExpr="$(PrintArray "${ExprHistory[@]}" | tail -n 1)" # 履歴から前回の式だけ取り出す | |
case "$InputExpr" in | |
"back" | "undo") | |
[[ "${#ExprHistory[@]}" = 0 ]] && return 2 | |
# 前回の式で使われた数字を元に戻す | |
ArrayAppend AvailableNumbers < <(GetExprNumbers "$(cut -d "=" -f 1 <<< "${PreviousExpr}")") | |
# 前回の式で追加された数字を削除する | |
readarray -t AvailableNumbers < <(PrintArray "${AvailableNumbers[@]}" | RemoveMatchLine "$(cut -d "=" -f 2 <<< "${PreviousExpr}")") | |
# 履歴から前回の式を削除する | |
readarray -t ExprHistory < <(PrintArray "${ExprHistory[@]}" | sed -e '$d') | |
return 2 | |
;; | |
"help") | |
HelpMessage | |
return 2 | |
;; | |
"history") | |
PrintArray "${ExprHistory[@]}" | ForEach echo "- {}" | |
return 2 | |
;; | |
"clear") | |
echo -e "\x1b\x5b\x48\x1b\x5b\x32\x4a\c" | |
return 2 | |
;; | |
"exit") | |
return 0 | |
esac | |
# 入力された文字の確認 | |
# shellcheck disable=SC2143 | |
if [[ -z "${InputExpr}" ]]; then | |
#echo "式を入力してください。" | |
return 3 | |
elif [[ -n "$(grep -v -e "[0-9]+" -e "+" -e "-" -e "*" -e "/" <<< "$InputExpr")" ]]; then | |
echo "式以外が入力されました。" | |
return 3 | |
fi | |
# 改行を出力 | |
echo | |
# 指定された式の数字が使えるかどうかを確認 | |
local Num | |
while read -r Num; do | |
if ! PrintArray "${AvailableNumbers[@]}" | grep -qx -- "$Num"; then | |
echo "${Num}は使えません!" | |
AvailableNumbers+=("${UsedNumber[@]}") | |
unset UsedNumber | |
return 1 # 異常終了して関数を再度呼び出す | |
else | |
UsedNumber+=("$Num") | |
readarray -t AvailableNumbers < <(PrintArray "${AvailableNumbers[@]}" | RemoveMatchLine "$Num") | |
fi | |
done < <(GetExprNumbers "$InputExpr") | |
# 計算結果 | |
local CalculatedValue="$(( "$InputExpr" ))" | |
AvailableNumbers+=("${CalculatedValue}") | |
# もし数字が1つだけならゲームを終了する | |
if [[ "${#AvailableNumbers[@]}" = 1 ]]; then | |
return 0 | |
else | |
# 異常終了してこの関数を再度呼び出す | |
ExprHistory+=("${InputExpr}=${CalculatedValue}") | |
return 2 | |
fi | |
} | |
#-- Parse args --# | |
ParseArg LONG="help,target:,jamaica,number:" SHORT="ht:jn:" -- "$@" && eval set -- "${OPTRET[*]}" | |
while true; do | |
case "$1" in | |
"--target" | "-t") | |
CheckNum "$2" || { echo "小数は利用できません。"; exit 1; } | |
TargetNumber="$2" | |
shift 2 | |
;; | |
"--jamaica" | "-j") | |
TargetNumber="$(( (RANDOM % 6 + 1) * 10 + (RANDOM % 6 + 1)))" | |
shift 1 | |
;; | |
"--number" | "-n") | |
tr "," "\n" <<< "$2" | ForEach CheckNum "{}" || { echo "小数は利用できません。"; exit 1; } | |
readarray -t AvailableNumbers < <(tr "," "\n" <<< "$2") | |
shift 2 | |
;; | |
"--help" | "-h") | |
HelpMessage | |
shift 1 | |
;; | |
"--") | |
break | |
shift 1 | |
;; | |
esac | |
done | |
Game.Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fascodeで晒した時のバージョン
https://gist.github.com/Hayao0819/caad8ef3952bdfef7287ef8c5d71e03c/0a31a4716347d07ca352d71f279d49709d110995