月度热点

网络推荐



本广告位招租!

推荐给好友 上一篇 | 下一篇

一个演示汉诺塔的脚本

主要是练习用tput来设置终端的前景,背景色,以及定位光标BSD爱好者乐园yF/AYo&~._,MS!q
水平菜,代码很长,让各位见笑了
5j+_"{j ^,k:CD?)w8w
^-u/l*Ma0Kn(a代码:
?*{7? O}&~3C b#!/bin/bashBSD爱好者乐园/QF+Knl

.n&]&kYWm##usage: sh $0 nBSD爱好者乐园n(h[C-XeB8F
##BSD爱好者乐园Z8Z|2@5A y(r
## ------------------->XBSD爱好者乐园\2g%S+K_z
## |BSD爱好者乐园r;[.\0F&S9Ke'gN
## |
G&UyM3D RH!\%k\## |
g;N^Yt+kH7Eb## |   disk 1 -------->     ()BSD爱好者乐园o&`4G z&Rl/F.l
## |   disk 2 -------->    (())
$_f5H!Xk## |   disk 3 -------->   ((()))BSD爱好者乐园Y"x`Q4W[
## |   disk 4 -------->  (((())))   BSD爱好者乐园 j(Q%|F_
## |   ............     ..........
(E _/iSl4gw!@## V   disk n-1 -->   ((((((()))))))
*|+~Rw k1Jn1V## Y   disk n --> ___(((((((())))))))______   _________________________   ________________________
w]i6P:Z##     ground -->|_________________________| |_________________________| |________________________|BSD爱好者乐园 l*Ae#\,?,x6XK
##                         A                             A                            ABSD爱好者乐园k4E2Lu f s;Fx
##                         |                             |                            |BSD爱好者乐园!}p:ZPr1z
##                         |                             |                            |BSD爱好者乐园.b,WG(ZbS
##                     source,1                        aid,2                  destination,3BSD爱好者乐园b\MG|/V0|6K CK4`
BSD爱好者乐园 ]x'H`6|6_@%l
usage="sh $0 non-negative number"BSD爱好者乐园)d*Fxn_/Y,C
disks=$1
$Tq-nI"lN.`colums=$((($(tput cols)-4)/3))
;?| _ j1s
PO-w6v t"@M C## 底座的 Y 坐标BSD爱好者乐园GE,a Wi}Sx
groundat=$(($(tput lines)-2))BSD爱好者乐园M#\ I2N A6x

J _;r7a,Er$R^}8C J## 底座source(或1)处,最顶层盘的中心坐标
ki6p vesourcex=$(($colums/2))
+v m#Lu#k_}gsourcey=$(($groundat-$disks))
?KEyT z2w:~B1J
b"|L/V#?kl## 底座aid(或2)处,最顶层盘的中心坐标BSD爱好者乐园 \;^3k;|G
aidx=$(($colums+2+$sourcex))BSD爱好者乐园 `1`*w-I.OFw~3^
aidy=$(($groundat-1))BSD爱好者乐园 h1{(k.mk%ukK${y
aidfirst=0
wd"^M\/gx N
Z,d `XWvJ^## 底座destination(或3)处,最顶层盘的中心坐标BSD爱好者乐园1K,{ e,L H9cW s\B
destinationx=$(($colums*2+4+$sourcex))BSD爱好者乐园['xTH)mu&g2H
destinationy=$(($groundat-1))BSD爱好者乐园W)A4~!^k$w5^7L
destinationfirst=0BSD爱好者乐园0S5M:c)dza5|

3pN w+e R1oL6Scoordinate=''BSD爱好者乐园@/^ q(V[m,i"^N&p

7Z`z|/\6Vq4ru
wC;H@,Q.^B|initdraw()
5R*RKy7u/T ]~` T{BSD爱好者乐园UrQ` a?
    init_drawdisks
5H O)i5?#S8X    init_drawgroundBSD爱好者乐园lo&dzv e
}BSD爱好者乐园2fQM qw7Rq

["yxoOinit_drawground()
)I1{"nn/^(kL.^1X{
+ymM| v    index=1BSD爱好者乐园3kI-m;IG8NP0E
    tput cup $groundat 0BSD爱好者乐园)o| g"{ @
   
_&j&c uT    for i in 1 2 3
8tsIM2n.M7?Ch    do
9p*MhzTOtput setab $((1+$i))BSD爱好者乐园9E,_%H.^b;_
while(($index<=$i*$colums+($i-1)*2))
.Q8nt#Y}h\2t#y{xdoBSD爱好者乐园-AbL4p_
     echo -ne ' '
'yYpHW7E E _@     index=$(($index+1))BSD爱好者乐园6N.k yVG)hvEns
done
)TnJX:?)fljvtput sgr0
jr [ Ab5w]#}N,Hecho -n '  '
$`go;a"O$BK-c+mQindex=$(($index+2))
\ t(M BCLg)O_    doneBSD爱好者乐园lK/s wP
BSD爱好者乐园L_&N}r9j
    tput cup $(tput lines) 0BSD爱好者乐园q)]5|Hzt
}BSD爱好者乐园 m{@wp(w7qF
BSD爱好者乐园E(xN?K']QS
init_drawdisks()
1N+k/K On9R/}v2{3w{BSD爱好者乐园I#Bs[B2FJ
    for((offset=0,n=$disks;n>0;n--,offset++))
ZQ+`,YavS    doBSD爱好者乐园9Z[0thpY
drawdisk $(($colums/2)) $(($groundat-1-$offset)) $((2+($n-1)*2)) $nBSD爱好者乐园2_%h t z s4x9M9J|jZTv
    done
!t"RR3c6N U1J$C}
1[;s*P4D I9Y1c4vBSD爱好者乐园N6Cp\ ]Ay#]
drawdisk()
O&ckv|2{'o## 画一个中心在 ($1,$2),长度为 $3 的盘子BSD爱好者乐园I Ze L9|3qx
## 盘子的序号 $4 决定盘子的颜色BSD爱好者乐园(x/G:D n7NV*Q$T
{
E q ?$da2u    disk=''
L xFZ'E    for((tmp=$3/2;tmp>0;tmp--)); do disk=${disk}')'; done
P$H2w1w]9w;G_    for((tmp=$3/2;tmp>0;tmp--)); do disk='('${disk}; done
y Jcr$W)P    tput setab $(($4%8+1))BSD爱好者乐园'[9cAw] S~"_?A
    tput cup $2 $(($1-$3/2))BSD爱好者乐园4uDFa.x;mVPB
    echo -n "$disk"BSD爱好者乐园?"S7M'Y:U6B(^ v:o2P
    tput sgr0
/H4s*OM*n*i}BSD爱好者乐园3u'B-k:s|8e? r;}q S
BSD爱好者乐园R)@l%r9kz |
destroydisk()BSD爱好者乐园 l1w'xV%[f0M3?
## 将中心位置为 ($1,$2),长度为 $3 的盘子销毁BSD爱好者乐园A)Z(`;GS0^/x
{BSD爱好者乐园K;{LF }v
    tput cup $2 $(($1-$3/2))
6I8W$qjw'jM6RS!N4X    empty=''
h qM6{q;LM?    for((tmp=$3;tmp>0;tmp--)); do empty=' '$empty; doneBSD爱好者乐园(]h"Dia ^-t%Lr{Q%L
    echo -n "$empty"
M#N%|R|EPIq5hn    tput cup 0 0
pjo$WC v+t8@g$deR6O}BSD爱好者乐园!c]M8S^7iOM|

6Zd!tL l Rmoving()BSD爱好者乐园,uca fzp
## 将第 $5 个盘子从 ($1,$2) 移动到 ($3,$4)
{Q;TL3Jwl{8e/})H{BSD爱好者乐园A P&u{1a+SMZ
    verticaltop=$(($groundat-1-$disks))BSD爱好者乐园0| eT6wA
    horizspace=$(($3-$1))BSD爱好者乐园 }u[.f9d dD;A;v
    x=$1BSD爱好者乐园'y}q M7\
    y=$2
9w:O+M {?(KB    length=$((2+($5-1)*2))
v7f(F&lA7}BSD爱好者乐园7P*PwP5X,[ u
    while(($y>=$verticaltop))
b7lY\0pF4oo    doBSD爱好者乐园'[7Fbj0_$E B8z%I
destroydisk $x $y $length
k8{Jp }y=$(($y-1))
y@'I H \4rdrawdisk $x $y $length $5BSD爱好者乐园:CMIH:kK:M+w:{
# sleep 0.5BSD爱好者乐园gSjI,Pr M
    done
%}m2}"@&q s([-QBSD爱好者乐园 d:m:c Yx;EB~V
    sign=$(($horizspace<0?-1:1))
?,MS&H-PK    while(($3-$x!=0))
F2rf[*@.Im!g6Fl]j    doBSD爱好者乐园E.[_(q#p+b
destroydisk $x $y $lengthBSD爱好者乐园] A&Bk$YQ+D W"Y
x=$(($x+1*$sign))BSD爱好者乐园3KH@!D^6^Gw
drawdisk $x $y $length $5BSD爱好者乐园VH$m},u0v9i#J
# sleep 0.5BSD爱好者乐园 A;@,Lw#kS8i*|5b
    done
I `Rhfe,`BSD爱好者乐园 d D!u ^j:rv E
    while(($y<$4))
T4kl(Q3NQY    do
8w,g4p|C.DO2C+tGdestroydisk $x $y $length
v8{P%pu'Mn]'my=$(($y+1))
7` ue'T/r?SKPdrawdisk $x $y $length $5BSD爱好者乐园$H#d4lV!d S
# sleep 0.5BSD爱好者乐园Q,Je&h?nd%C.i
    doneBSD爱好者乐园Jz/q!Ou d{/ps%j
}BSD爱好者乐园-i7SYp"CXa$vee

/tl7zI0rf+x/c%xhanoi()
]9k-_:aL{
4p9Mo3A U!em^ l    bool1=$(($disks%2))
qK&R_#O6iA nt   
.k1e.M3Q"egN5`m    for((s=1;s<2**$disks;s++))BSD爱好者乐园A"uDfi:c
    {
'P NMBrrindex=$(factor $s | sed 's/.*: //;s/2 /2\n/g' | grep '^2$' -c)BSD爱好者乐园,j~z/U~1d
step=$(((s/(2**$index)+1)/2))BSD爱好者乐园;O3Ht&af
index=$(($index+1))
1Gi~|HYbool2=$(($index%2))BSD爱好者乐园aGp!A!H
fromtonum=''
q _J#WC:IBSD爱好者乐园8GP|)jKci2K
        ## 求出第 s 步时,应将第 $index 个盘子从底座(1或2或3)移动到底座(1或2或3)BSD爱好者乐园;~R&O*M,s,PR4g
if(($bool1==$bool2))BSD爱好者乐园 fB*C;tm cA0y
then
S3n y&X'W r     case $(($step%3)) in
Zq.[V:^`  1)
ZSRuFE      fromtonum='1 3';;
W.M8X8r$C  2)BSD爱好者乐园|ixx6Svb/MP
      fromtonum='3 2';;BSD爱好者乐园E*i!v |!t
  0)
#_0Z9\)CB$C'Bmm      fromtonum='2 1';;BSD爱好者乐园!o!{ke ?
     esacBSD爱好者乐园RX,jJ5]Q
else
*J\-U3J'J     case $(($step%3)) in
.eT6h uin6K+u9W  1)BSD爱好者乐园/rs/B$Cg{5zE0D"S
      fromtonum='1 2';;BSD爱好者乐园 i OdF#gHV"Q"O q/N6a
  2)
t$R3?)A~w      fromtonum='2 3';;BSD爱好者乐园u YTh8}3xu
  0)BSD爱好者乐园WQ/@GJ8?
      fromtonum='3 1';;BSD爱好者乐园:R9C3]:]-z/D^?
     esacBSD爱好者乐园v1ET;I-qo[
fiBSD爱好者乐园8o,b9x2s5f
fromtonum=${fromtonum}" $index"
^K2RR;e[UBSD爱好者乐园7p R#z)R%W qZ8s
## 按照盘子序号和底座序号计算出移动的源及目的的坐标 coordinateBSD爱好者乐园 {B wP:g7l XZ
_getcoordinat $fromtonumBSD爱好者乐园~ @8F T-v7] L(]_#B
BSD爱好者乐园 RN%yx'O`_ i1s4O \
tput cup $groundat $(($colums+1+$colums/2))
'?L{uzXp _tput setab 3
Y nO-Hxftput setaf 0BSD爱好者乐园+r$n)V A g*Kv6f
echo $sBSD爱好者乐园 R)RFu:zD
tput sgr0BSD爱好者乐园An&Xq^&P~-a

6I,qa%a*h-Gg4wz## 移动盘子BSD爱好者乐园!^Pi F w0A"V
moving $coordinate
O8o7J1b6p3}4h#wBSD爱好者乐园/n!H"J4w;l
    }
T d'yk9R)ys;wBSD爱好者乐园"c3b!^&s9M VP;g
}
#sx9]p"J;P&~6q
x8{M-sjFQ_U_getcoordinat()BSD爱好者乐园3W3jkT}e[;l
## 第 $3 个盘子要从底座 $1 移动到底座 $2,据此计算出移动的源坐标和目的坐标
8_ A/x fJG+p{
)LL/E2{'R    case "$1" inBSD爱好者乐园8rTu[-mw.Kw
1)
j1ER,^ rJ-}\-T     coordinate="$sourcex $sourcey "BSD爱好者乐园9umxA j'q s
     sourcey=$(($sourcey+1));;BSD爱好者乐园#vT#lu d-J {B/G_
2)
6D6rJY] em,]     coordinate="$aidx $aidy "BSD爱好者乐园(n-Nyb`"UxM,i
     aidy=$(($aidy+1));;BSD爱好者乐园8{ SX lDp
BSD爱好者乐园)u(Zr9N!u"Q$p2M
3)BSD爱好者乐园)}O5@^W'@u/`
     coordinate="$destinationx $destinationy "BSD爱好者乐园$l8Cd/[y1s
     destinationy=$(($destinationy+1));;BSD爱好者乐园$El)~xj%ns?
    esacBSD爱好者乐园0M[0k(baGYU

u'i{.x&t(iQNCp2|t    case "$2" in
&na'{4[1K?1)
%a v3o$?0f~U     sourcey=$(($sourcey-1))
zv[-D0nB7O%Lg     coordinate=${coordinate}"$sourcex $sourcey";;BSD爱好者乐园 afrSj[aVP\q0d
2)
2J!h&{&u7Y8hv7Q2|l     aidy=$(($aidy-1*$aidfirst))BSD爱好者乐园}.t\mNN t'b'w*K
     coordinate=${coordinate}"$aidx $aidy"
o3KTN y)saz%y*t-R     aidfirst=1;;
$\SsJ0R;]"d$l1mI3)
%RV }4O#Z     destinationy=$(($destinationy-1*$destinationfirst))
b1OoN+AE\     coordinate=${coordinate}"$destinationx $destinationy"
d Ak1l B!i1n     destinationfirst=1;;
b.wL h%dP;a'`    esac
8Gj L g s6FZA
Hhb.v`%t    coordinate=${coordinate}" $3"BSD爱好者乐园W bIJ6Db-SG#I r^
}
#a.htV!M5]-rBSD爱好者乐园7pr5u{ U6^7e)L9v
################ 开始 #####################
4x*yy4a&I'^`^l[[ -z "$disks" || "$disks" =~ [^[:digit:]] ]] && echo "usage: ""$usage" && exitBSD爱好者乐园} x*a6z uHM
(( $disks+2>$groundat || (2+($disks-1)*2)*3+4>$(tput cols))) && echo "screen is too small, reseize it" && exit
)w$DgnXerhtput clear
R,{e6w&sSwGtput civisBSD爱好者乐园 W.jU@ TU(HUJ
initdrawBSD爱好者乐园v iI Sd#C|,e,p
stty -echoBSD爱好者乐园-nXX$v _;F/T:ir@

]Jj&J#ssleep 0.5BSD爱好者乐园w&W^8oC
for((i=5;i>=0;i--))BSD爱好者乐园x$U9nP/~0b
doBSD爱好者乐园c3BD1@ IE+Hg+_
    tput cup $(($(tput lines)/2)) $(($(tput cols)/2-2))BSD爱好者乐园5n aSI7}Zq"I
    tput setab $iBSD爱好者乐园sR E+{z;r
    echo ' '$i' '
8pR2I$r g~"E    sleep 0.6BSD爱好者乐园GjyD*w2[K ]
    tput sgr0
!Cd} E4A| j'Z    tput cup $(($(tput lines)/2)) $(($(tput cols)/2-2))
7dr+C:}J@    echo '   '
\"A"X9C,Apv4w}x||    sleep 0.4BSD爱好者乐园 j"k"f6CW']F;Q
doneBSD爱好者乐园4ug(_z A+jG$v
tput sgr0
+k%oLU;hftput cup $(($(tput lines)/2)) $(($(tput cols)/2))BSD爱好者乐园0H1`,D!F/z,I/Ql0o8?{
echo " "
C!i'~)p1q w p1whanoiBSD爱好者乐园 f4S az%Jc

']VYO:d5LV2h(mstty echo
3~'azc mtput resetBSD爱好者乐园&z*}Hl&}`9q{4C/u
tput sgr0BSD爱好者乐园6?z]|*x t
tput cup $(tput lines) 0
!wG[$Pu x@:wtput cnorm
[版权声明]BSD爱好者乐园站内文章,如来源不是互联网,则均系原创或翻译之作,可随意转载,或以此为基础进行演译,但务必以链接形式注明原始出处和作者信息,否则属于侵权行为。另对本站转载他处文章,俱有说明,如有侵权请联系本人,本人将会在第一时间删除侵权文章。
TAG: shell脚本 汉诺塔
 

评分:0

我来说两句

seccode