水平菜,代码很长,让各位见笑了
代码:
#!/bin/bash
##usage: sh $0 n
##
## ------------------->X
## |
## |
## |
## | disk 1 --------> ()
## | disk 2 --------> (())
## | disk 3 --------> ((()))
## | disk 4 --------> (((())))
## | ............ ..........
## V disk n-1 --> ((((((()))))))
## Y disk n --> ___(((((((())))))))______ _________________________ ________________________
## ground -->|_________________________| |_________________________| |________________________|
## A A A
## | | |
## | | |
## source,1 aid,2 destination,3
usage="sh $0 non-negative number"
disks=$1
colums=$((($(tput cols)-4)/3))
## 底座的 Y 坐标
groundat=$(($(tput lines)-2))
## 底座source(或1)处,最顶层盘的中心坐标
sourcex=$(($colums/2))
sourcey=$(($groundat-$disks))
## 底座aid(或2)处,最顶层盘的中心坐标
aidx=$(($colums+2+$sourcex))
aidy=$(($groundat-1))
aidfirst=0
## 底座destination(或3)处,最顶层盘的中心坐标
destinationx=$(($colums*2+4+$sourcex))
destinationy=$(($groundat-1))
destinationfirst=0
coordinate=''
initdraw()
{
init_drawdisks
init_drawground
}
init_drawground()
{
index=1
tput cup $groundat 0
for i in 1 2 3
do
tput setab $((1+$i))
while(($index<=$i*$colums+($i-1)*2))
do
echo -ne ' '
index=$(($index+1))
done
tput sgr0
echo -n ' '
index=$(($index+2))
done
tput cup $(tput lines) 0
}
init_drawdisks()
{
for((offset=0,n=$disks;n>0;n--,offset++))
do
drawdisk $(($colums/2)) $(($groundat-1-$offset)) $((2+($n-1)*2)) $n
done
}
drawdisk()
## 画一个中心在 ($1,$2),长度为 $3 的盘子
## 盘子的序号 $4 决定盘子的颜色
{
disk=''
for((tmp=$3/2;tmp>0;tmp--)); do disk=${disk}')'; done
for((tmp=$3/2;tmp>0;tmp--)); do disk='('${disk}; done
tput setab $(($4%8+1))
tput cup $2 $(($1-$3/2))
echo -n "$disk"
tput sgr0
}
destroydisk()
## 将中心位置为 ($1,$2),长度为 $3 的盘子销毁
{
tput cup $2 $(($1-$3/2))
empty=''
for((tmp=$3;tmp>0;tmp--)); do empty=' '$empty; done
echo -n "$empty"
tput cup 0 0
}
moving()
## 将第 $5 个盘子从 ($1,$2) 移动到 ($3,$4)
{
verticaltop=$(($groundat-1-$disks))
horizspace=$(($3-$1))
x=$1
y=$2
length=$((2+($5-1)*2))
while(($y>=$verticaltop))
do
destroydisk $x $y $length
y=$(($y-1))
drawdisk $x $y $length $5
# sleep 0.5
done
sign=$(($horizspace<0?-1:1))
while(($3-$x!=0))
do
destroydisk $x $y $length
x=$(($x+1*$sign))
drawdisk $x $y $length $5
# sleep 0.5
done
while(($y<$4))
do
destroydisk $x $y $length
