如何在 Bash 中绘制 Hangman 而无需为每个案例嵌入 echo 语句?
How can I draw Hangman in Bash without embedding echo statements for each case?
我正在 Bash 做一个刽子手的任务。它完全可以工作,但是它的一部分编码非常糟糕,以至于会引起一种瘙痒。我说的是打印 "hanging the man"
的进度
print_hangman(){
if [[ $attempts = 0 ]]
then
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
elif [[ $attempts = 1 ]]
then
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo "_______________"
elif [[ $attempts = 2 ]]
then
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 3 ]]
then
echo " "
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 4 ]]
then
echo " __________"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 5 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 6 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " | |"
echo " | |"
echo " | |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 7 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " | |"
echo " | |"
echo " | |"
echo " / |"
echo " / |"
echo " |"
echo "_______________|"
elif [[ $attempts = 8 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " | |"
echo " | |"
echo " | |"
echo " / \ |"
echo " / \ |"
echo " |"
echo "_______________|"
elif [[ $attempts = 9 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " ----| |"
echo " | |"
echo " | |"
echo " / \ |"
echo " / \ |"
echo " |"
echo "_______________|"
elif [[ $attempts = 10 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " ----|---- |"
echo " | |"
echo " | |"
echo " / \ |"
echo " / \ |"
echo " |"
echo "_______________|"
fi
}
Bash 中有没有办法让这段代码占用更少的行数?我在想,也许你可以采用标准,然后只为正在更改的行编写行。例如,在 attempt = 1 时,您只需更改 13 行中的一行。
也许吧?
#!/bin/bash
read -r -d '' hex <<'EOF'
1f8b080025bbce580003535040055c0ac3488067b038841a02f16860b0f8
ae862a02689eab21ec3bead84b1f015cbe438acdc1e254320488f55d0dba
216802f1faf131f1282a6ae26bd0b4d0dc331802f4f41d2133881118d6be
d347f30c127f58f82e06c37731a85a0685ef74816098fb0e44d0d777004c
bdfc0d8a090000
EOF
mapfile -d$'4' frames < <(printf "%b" $(sed 's/../\x& /g' <<<"$hex") |gzip -d)
#here you have the array "frames[@]" - with the pictures
for frame in "${frames[@]}"
do
clear
printf "%s\n" "$frame"
sleep 0.3
done
你的 bash
不支持 mapfile -d
,你可以使用 mapfile -d ....
代替 mapfile -d ....
行:
n=0
while IFS=$'4' read -r -d $'4' f
do
frames[$n]="$f"
let n++
done < <(printf "%b" $(sed 's/../\x& /g' <<<"$hex") |gzip -d)
工作原理:
- 图片存储为 gzip 十六进制编码字符串。
sed 's/../\x& /g'
将字符串转换为 \x1f \x8b
的列表
printf "%b"
打印字符
- 最后
gzip -d
解码整个流
- "stream" 是一系列帧,每个帧除以
^L
(CTRL-L) 字符
-
mapfile
使用分隔符 ^L
将流读入数组 frame
- 完成:)
输出 - 每帧如下所示
________________
|
|
|
|
|
_______________|
|
|
|
|
|
|
|
|
|
|
|
_______________|
__________
|
|
|
|
|
|
|
|
|
|
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
|
|
|
|
|
|
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
| |
| |
| |
|
|
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
| |
| |
| |
/ |
/ |
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
| |
| |
| |
/ \ |
/ \ |
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
----| |
| |
| |
/ \ |
/ \ |
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
----|---- |
| |
| |
/ \ |
/ \ |
|
_______________|
如何创建十六进制字符串
- 每帧创建一个文件,例如
xx00
、xx01
、...
- 使用下面的
make_hex.sh
作为bash make_hex.sh xx*
mk_stream() {
for file in "$@"
do
cat "$file"
printf "%c" $'4'
done
}
mk_stream "$@" | gzip | xxd -ps
我正在 Bash 做一个刽子手的任务。它完全可以工作,但是它的一部分编码非常糟糕,以至于会引起一种瘙痒。我说的是打印 "hanging the man"
的进度print_hangman(){
if [[ $attempts = 0 ]]
then
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
elif [[ $attempts = 1 ]]
then
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo "_______________"
elif [[ $attempts = 2 ]]
then
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 3 ]]
then
echo " "
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 4 ]]
then
echo " __________"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 5 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 6 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " | |"
echo " | |"
echo " | |"
echo " |"
echo " |"
echo " |"
echo "_______________|"
elif [[ $attempts = 7 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " | |"
echo " | |"
echo " | |"
echo " / |"
echo " / |"
echo " |"
echo "_______________|"
elif [[ $attempts = 8 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " | |"
echo " | |"
echo " | |"
echo " / \ |"
echo " / \ |"
echo " |"
echo "_______________|"
elif [[ $attempts = 9 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " ----| |"
echo " | |"
echo " | |"
echo " / \ |"
echo " / \ |"
echo " |"
echo "_______________|"
elif [[ $attempts = 10 ]]
then
echo " __________"
echo " | |"
echo " | |"
echo " _/_\_ |"
echo " |_| |"
echo " | |"
echo " ----|---- |"
echo " | |"
echo " | |"
echo " / \ |"
echo " / \ |"
echo " |"
echo "_______________|"
fi
}
Bash 中有没有办法让这段代码占用更少的行数?我在想,也许你可以采用标准,然后只为正在更改的行编写行。例如,在 attempt = 1 时,您只需更改 13 行中的一行。
也许吧?
#!/bin/bash
read -r -d '' hex <<'EOF'
1f8b080025bbce580003535040055c0ac3488067b038841a02f16860b0f8
ae862a02689eab21ec3bead84b1f015cbe438acdc1e254320488f55d0dba
216802f1faf131f1282a6ae26bd0b4d0dc331802f4f41d2133881118d6be
d347f30c127f58f82e06c37731a85a0685ef74816098fb0e44d0d777004c
bdfc0d8a090000
EOF
mapfile -d$'4' frames < <(printf "%b" $(sed 's/../\x& /g' <<<"$hex") |gzip -d)
#here you have the array "frames[@]" - with the pictures
for frame in "${frames[@]}"
do
clear
printf "%s\n" "$frame"
sleep 0.3
done
你的 bash
不支持 mapfile -d
,你可以使用 mapfile -d ....
代替 mapfile -d ....
行:
n=0
while IFS=$'4' read -r -d $'4' f
do
frames[$n]="$f"
let n++
done < <(printf "%b" $(sed 's/../\x& /g' <<<"$hex") |gzip -d)
工作原理:
- 图片存储为 gzip 十六进制编码字符串。
sed 's/../\x& /g'
将字符串转换为\x1f \x8b
的列表
printf "%b"
打印字符- 最后
gzip -d
解码整个流 - "stream" 是一系列帧,每个帧除以
^L
(CTRL-L) 字符 -
mapfile
使用分隔符^L
将流读入数组 - 完成:)
frame
输出 - 每帧如下所示
________________
|
|
|
|
|
_______________|
|
|
|
|
|
|
|
|
|
|
|
_______________|
__________
|
|
|
|
|
|
|
|
|
|
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
|
|
|
|
|
|
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
| |
| |
| |
|
|
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
| |
| |
| |
/ |
/ |
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
| |
| |
| |
/ \ |
/ \ |
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
----| |
| |
| |
/ \ |
/ \ |
|
_______________|
__________
| |
| |
_/_\_ |
|_| |
| |
----|---- |
| |
| |
/ \ |
/ \ |
|
_______________|
如何创建十六进制字符串
- 每帧创建一个文件,例如
xx00
、xx01
、... - 使用下面的
make_hex.sh
作为bash make_hex.sh xx*
mk_stream() {
for file in "$@"
do
cat "$file"
printf "%c" $'4'
done
}
mk_stream "$@" | gzip | xxd -ps