Very powerful shell written by Tetris

Source: Internet
Author: User
Tags imap

A Tetris that was written on the web with a Linux shell script.

It's the best shell I've ever seen written. Share a bit.

The original author's information is in the gaze of the script.

: Click to download



#!/bin/bash # Tetris game# 10.21.2003 xhchen<[email][email protected][/email]> #APP declarationAPP_NAME= "$ {0##*[\\/]} "app_version=" 1.0 "#颜色定义cRed =1cgreen=2cyellow=3cblue=4cfuchsia=5ccyan=6cwhite=7colortable= ($cRed $ Cgreen $cYellow $cBlue $cFuchsia $cCyan $cWhite) #位置和大小iLeft =3itop=2 ((itrayleft = ILeft + 2)) ((Itraytop = iTop + 1)) (Itra Ywidth =)) ((Itrayheight =)) #颜色设置cBorder = $cGreencScore = $cFuchsiacScoreValue = $cCyan #控制信号 # change game use two processes, one for receiving input, One for the game flow and display interface; #当前者接收到上下左右等按键时 to inform the latter by sending signal to the latter. sigrotate=25sigleft=26sigright=27sigdown=28sigalldown=29sigexit=30 #七中不同的方块的定义 # by rotation.  There may be several types of display styles for each block box0= (0 0 0 1 1 0 1 1) box1= (0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3) box2= (0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0) box3= (0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1) box4= (0 1 0 2 1 1 2 1 1 0 1 1 1 2 2 2 0 1 1 1 2 0 2 1 0 0 1 0 1 1 1 2) box5= (0 1 1 1 2 1 2 2 1 0 1 1 1 2 2 0 0 0 0 1 1 1 2 1 0 2 1 0 1 1 1 2) box6= (0 1 1 1 1 2 2 1 1 0 1 1 1 2 2 1 0 1 1 0 1 1 2 1 0 1 1 0 1 1 2) #全部当中方块的定义都放到box变量中box = (${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@] {${box5[@]} ${box6[@]}) #各种方块旋转后可能的样式数目countBox = (1 2 2 2 4 4 4) #各种方块再box数组中的偏移offsetBox = ( 0 1 3 5 7) #每提高一个速度级须要积累的分数iScoreEachLevel =50 #be greater than 7 #执行时数据sig =0 #接收到的signaliScore =0 #总分iLevel =0 #速度级boxNew = () #新下落的方块的位置定义cBoxNew =0 #新下落的方块的颜色iBoxNewType =0 #新下落的方块的种类iB Oxnewrotate=0 #新下落的方块的旋转角度boxCur = () #当前方块的位置定义cBoxCur =0 #当前方块的颜色iBoxCurType =0 #当前方块的种类iBoxCurR Otate=0 #当前方块的旋转角度boxCurX =-1 #当前方块的x坐标位置boxCurY =-1 #当前方块的y坐标位置iMap = () #背景方块图表 #初始化全部背景 The block is-1, which means no block for ((i = 0; i < itrayheight * itraywidth; i++)); Do imap[$i]=-1;        Done #接收输入的进程的主函数function Runaskeyreceiver () {local Piddisplayer key Akey Sig Cesc STTY piddisplayer=$1 akey= (0 0 0) cesc= ' echo-ne "\033" ' cspace= ' Echo-ne "\040" ' #保存终端属性.        When Read-s reads the terminal key, the terminal's properties are temporarily changed. #假设在read-S program is unfortunately killed, may cause terminal confusion, #须要在程序退出时恢复终端Property. stty= ' stty-g ' #捕捉退出信号 trap "myexit;"                INT term trap "myexitnosub;" $sigExit #隐藏光标 Echo-ne "\033[?25l" While:do #读取输入. Note-S does not echo.                -N read to a character immediately return read-s-N 1 key Akey[0]=${akey[1]} Akey[1]=${akey[2]} akey[2]= $key sig=0 #推断输入了何种键 if [[$key = = $cESC && ${akey[1] } = = $cESC]] then #ESC键 myexit elif [[${akey [0]} = = $cESC && ${akey[1]} = = "["]] then if [[$key = = "A"]]; Then sig= $sigRotate #< up key > elif [[$key = = "B"]]; Then sig= $sigDown #< down arrow > elif [[$key = = "D"]]; Then sig= $sigLeft #< left arrow > elif [[$key = = "C"]];                      Then sig= $sigRight #< right >  Fi elif [[$key = = "W" | | $key = = "W"]]; Then sig= $sigRotate #W, W elif [[$key = = "S" | | $key = = "S"]]; Then sig= $sigDown #S, S elif [[$key = = "a" | | $key = = "a"]]; Then sig= $sigLeft #A, A elif [[$key = = "D" | | $key = = "D"]]; Then sig= $sigRight #D, D elif [["[$key]" = = "[]"];                Then sig= $sigAllDown #空格键 elif [[$key = = "Q" | | $key = = "Q"]] #Q, q                        Then Myexit fi if [[$sig! = 0]] Then #向还有一进程发送消息 kill-$sig $pidDisplayer fi Done} #退出前的恢复functio        n Myexitnosub () {local y #恢复终端属性 stty $sTTY ((y = iTop + itrayheight + 4) #显示光标 Echo-e "\033[?25h\033[${y};0h" exit} function Myexit () {#通知显示进程须要退出 kill-$sigExit $pidDisplayEr myexitnosub} #处理显示和游戏流程的主函数function runasdisplayer () {Local sigthis Initdraw #挂载各种信号的处理函        The trap "sig= $sigRotate;" $sigRotate trap "sig= $sigLeft;" $sigLeft trap "sig= $sigRight;" $sigRight Trap "sig= $sigDown;" $sigDown trap "sig= $sigAllDown;" $sigAllDown trap "showexit;" $sigExit Whil                E:do #依据当前的速度级iLevel不同, set the number of times for the corresponding loop for ((i = 0; i < 21-ilevel; i++))                         Do sleep 0.02 sigthis= $sig sig=0 #依据sig变量推断是否接受到对应的信号 if ((sigthis = = sigrotate));        Then boxrotate; #旋转 elif ((sigthis = = Sigleft));        Then Boxleft; #左移一列 elif ((sigthis = = sigright));        Then Boxright; #右移一列 elif ((sigthis = = Sigdown));        Then Boxdown; #下落一行 elif (Sigthis = = sIgalldown));        Then Boxalldown;        #下落究竟 fi done #kill-$sigDown $$ boxdown #下落一行        Done} #BoxMove (y, x), can the test be enough to move the block to the position (x, y), return 0 to be able, 1 can not function Boxmove () {Local J I x y xTest ytest                Ytest=$1 xtest=$2 for ((j = 0; J < 8; J + + 2)) does ((i = j + 1))                ((y = ${boxcur[$j]} + ytest))                ((x = ${boxcur[$i]} + xTest)) if ((Y < 0 | | y >= itrayheight | | x < 0 | | x >= itraywidth)) Then #撞到墙壁了 return 1 fi if (${ima                P[y * itraywidth + x]} =-1) then #撞到其它已经存在的方块了 return 1  Fi done return 0;} #将当前移动中的方块放到背景方块中去, #并计算新的分数和速度级. (That is, a block falls to the exact part) function Box2map () {Local J I x y xp YP line #将当前移动中的方块放到背景方块中去 for ((j= 0; J < 8; J + = 2)) do ((i = j + 1)) ((y = ${boxcur[$j]} + Boxcury)) ((x = ${boxc ur[$i]} + Boxcurx)) ((i = y * itraywidth + x)) imap[$i]= $cBoxCur done #消去可被消去  The line line=0 for ((j = 0; J < Itraywidth * Itrayheight; j + + Itraywidth)) does for ((i = j + iTrayWidth-1; I >= J; i--)) do if ((${imap[$i]} = =-1)); Then break; Fi done if ((i >= j)); then continue; Fi ((line++)) for ((i = j-1; I >= 0; i--)) Does (( x = i + itraywidth)) imap[$x]=${imap[$i]} done for ((i = 0; i < IT Raywidth; i++)) do imap[$i the]=-1 done if (line = = 0); then return; Fi #依据消去的行数line计算分数和速度级 ((x = ILEFT + itraywidth * 2 + 7) ((y = iTop + one)) ((Iscore + = line * 2-1)) #显示新的分数 Echo-ne "\033        [1m\033[3${cscorevalue}m\033[${y};${x}h${iscore} "if ((iscore% Iscoreeachlevel < line * 2-1))                        Then if ((Ilevel <) and then ((ilevel++)) ((y = ITop +)) #显示新的速度级 Echo-ne "\033[3${cscorevalue}m\033[${y};${x}h${i Level} "Fi fi echo-ne" \033[0m "#又一次显示背景方块 for ((y = 0; Y < Itrayheight; y++)) do ((YP = y + itraytop + 1)) ((XP = Itrayleft + 1)) ((i = y * IT                raywidth)) Echo-ne "\033[${yp};${xp}h" for ((x = 0; x < Itraywidth + x + +))                      Do ((j = i + x)) if ((${imap[$j]} = = 1) and then          Echo-ne "Else Echo-ne" \033[1m\033[7m\033[3${imap[$j        ]}m\033[4${imap[$j]}m[]\033[0m "fi Done" #下落一行function Boxdown () {                Local y S ((y = Boxcury + 1)) #新的y坐标 if Boxmove $y $boxCurX #測试能否够下落一行 Then s= "' Drawcurbox 0 '" #将旧的方块抹去 ((Boxcury = y)) s= "$s ' drawcurbox 1 '" #显示新的下落 The rear block Echo-ne $s else #走到这儿, assuming it cannot fall Box2map #将当前移动中的方块贴  To the Background box Randombox #产生新的方块 fi} #左移一列function Boxleft () {local x s ((x = Boxcurx-                1)) If Boxmove $boxCurY $x then s= ' Drawcurbox 0 ' ((Boxcurx = x)) S= $s ' drawcurbox 1 ' echo-ne $s fi} #右移一列function boxright () {local x s ((x = Boxcur X + 1)) if BoxmovE $boxCurY $x then s= ' Drawcurbox 0 ' ((Boxcurx = x)) s= $s ' drawcurbox 1 ' Echo-ne $s fi} #下落究竟function Boxalldown () {local k J I x y idown s idown= $iTrayHeig  HT #计算一共须要下落多少行 for ((j = 0; J < 8, J + + 2)) do ((i = j + 1)) ((y = ${boxcur[$j]} + Boxcury)) ((x = ${boxcur[$i]} + Boxcurx)) for ((k = y + 1; k < Itrayheig Ht k++)) do ((i = k * itraywidth + x)) if ((${imap[$i]}! =-1)) ; Then break; Fi Done ((k-= y + 1)) if (($iDown > $k)); Then idown= $k; Fi done s= ' Drawcurbox 0 ' #将旧的方块抹去 ((Boxcury + = Idown)) s= $s ' drawcurbox 1 ' #显示新的 Falling behind the block Echo-ne $s box2map #将当前移动中的方块贴到背景方块中 randombox #产生新的方块} #旋转方块function        Boxrotate () {Local ICount itestrotate boxtest J i s icount=${countbox[$iBoxCurType]} #当前的方块经旋转能够产生的样式的数目 #计算旋转后的新 ((itestrotate = iboxcurrotate + 1)) if ((Itestrotate >= iCount) then (Itestro Tate = 0) fi #更新到新的样式, save old style (but not display) for ((j = 0, I = (${offsetbox[$iBoxCurType]} + $iTestRotate) * 8; J < 8; J + +, i++)) do boxtest[$j]=${boxcur[$j]} boxcur[$j]=${box[$i]} done if Boxmove $boxCurY $boxCurX #測试旋转后是否有空间放的下 then #抹去旧的方块 for (j = 0; J < 8; j + +)) do boxcur[$j]=${boxtest[$j]} done s= ' Drawcurbox 0 ' #画上新的方块 for (j = 0, I = (${offsetbox[$iBoxCurType]} + $iTestRotate) * 8; J < 8; J + +,            i++)) do boxcur[$j]=${box[$i]} done s= $s ' drawcurbox 1 '     Echo-ne $s iboxcurrotate= $iTestRotate else #不能旋转, or continue to use the old style for   (j = 0; J < 8; J + +)) do boxcur[$j]=${boxtest[$j]} done fi} #DrawCurBox (Bdraw), draw the currently moving block, Bdraw to 1, draw on, Bdraw to 0, erase the block.

function Drawcurbox () {local I J T Bdraw SBox s bdraw=$1 s= "" if ((Bdraw = = 0) Then sbox= "\040\040" Else sbox= "[]" s= $s "\033[1m\033[7m\033[3${cboxcur}m\0 33[4${cboxcur}m "fi for (j = 0; J < 8; J + + 2)) does ((i = itraytop + 1 + ${boxcur[ $J]} + Boxcury)) ((t = itrayleft + 1 + 2 * (Boxcurx + ${boxcur[$j + 1]})) #\033[y;xh, cursor to (x , y) at s= $s "\033[${i};${t}h${sbox}" done s= $s "\033[0m" echo-n $s} #更新新的方块function Ran Dombox () {local I J T #更新当前移动的方块 iboxcurtype=${iboxnewtype} iboxcurrotate=${iboxnewrotate} Cboxcur=${cboxnew} for ((j = 0; J < ${#boxNew [@]}; j + +)) do boxcur[$j]=${boxnew[$j]} Done #显示当前移动的方块 if ((${#boxCur [@]} = = 8) Then #计算当前方块该从顶端哪一行 "Take" out for (j = 0, t =4; J < 8; J + = 2)) do if ((${boxcur[$j]} < T)); Then t=${boxcur[$j]}; Fi done ((Boxcury =-T)) for ((j = 1, i = -4, t =; J < 8; J + = 2)) Do if ((${boxcur[$j]} > i)); Then i=${boxcur[$j]}; Fi if ((${boxcur[$j]} < T)); Then t=${boxcur[$j]}; Fi done ((Boxcurx = (iTrayWidth-1-i-t)/2)) #显示当前移动的方块 Echo-ne ' Drawcurbox 1 ' #假设方块一出来就没处放, Game over! if! Boxmove $boxCurY $boxCurX then kill-$sigExit ${ppid} showexi T fi fi #清除右边预显示的方块 for ((j = 0; J < 4; J + +)) do ((i = ITo P + 1 + j)) ((t = ileft + 2 * itraywidth + 7)) Echo-ne "\033[${i};${t}h" Don E #随机产生新的方块 ((Iboxnewtype = RANDOM% ${#offsetBox [@]}) ((iboxnewrotate = RANDOM% ${countbox[$iBoxNewType])) for ((j = 0, I = (${offsetbox[$iBoxNewType]} + $iBoxNewRotat e) * 8; J < 8; J + +, i++)) do boxnew[$j]=${box[$i]}; Done ((cboxnew = ${colortable[random% ${#colorTable [@]}]}) #显示右边预显示的方块 Echo-ne "\033[1m\033[7m\0 33[3${cboxnew}m\033[4${cboxnew}m "for (j = 0; J < 8; J + + 2)) does ((i = iTop + 1 + ${boxne w[$j])) ((t = ileft + 2 * itraywidth + 7 + 2 * ${boxnew[$j + 1]})) Echo-ne "\033[${i};${t} H[] "Done Echo-ne" \033[0m "} #初始绘制function Initdraw () {Clear Randombox #随机产生方块. In this case, the right pre-display form is fast Randombox #再随机产生方块. The block on the right pre-display form is updated, the original block will start to fall local I t1 T2 T3 #显示边框 echo-ne "\033[1m" Echo-ne "\033[3${cborder }m\033[4${cborder}m "((t2 = ileft + 1)) ((T3 = ILeft + itraywidth * 2 + 3)) for ((i = 0; i < itrayheight; i++)) does ((T1 = i + ITop + 2)) Echo-ne "\03 3[${t1};${t2}h| | " Echo-ne "\033[${t1};${t3}h| |" Done ((t2 = iTop + itrayheight + 2)) for ((i = 0; i < Itraywidth + 2; i++)) Does ((t 1 = i * 2 + ileft + 1) echo-ne "\033[${itraytop};${t1}h==" Echo-ne "\033[${t2};${t1}h==" Done Echo-ne "\033[0m" #显示 "score" and "Level" Echo-ne "\033[1m" (T1 = ileft + itrayw Idth * 2 + 7)) ((t2 = ITop +)) Echo-ne "\033[3${cscore}m\033[${t2};${t1}hscore" ((t2 = iTop + 11) ) Echo-ne "\033[3${cscorevalue}m\033[${t2};${t1}h${iscore}" ((t2 = iTop +) Echo-ne "\033[3${CSC Ore}m\033[${t2};${t1}hlevel "((t2 = ITop +)) Echo-ne" \033[3${cscorevalue}m\033[${t2};${t1}h${ilevel} " Echo-ne "\033[0m"} #退出时显示GameOVer!function Showexit () {Local Y ((y = itrayheight + itraytop + 3)) echo-e "\033[${y};0hgameover!\033[0m" exit} #显示使用方法. function usage{cat << eofusage: $APP _namestart Tetris game. -H,--help display this Help and exit--version output version information and exiteof} #游戏主程 The order starts here. if [["$" = = "-H" | | "$" = = "--help"]; Then Usageelif [["$" = = "--version"]]; Then echo "$APP _name $APP _version" Elif [["$" = = "--show"]]; Then #当发现具有參数--show, execute the display function Runasdisplayerelse bash $--show& #以參数--show to execute the program again Runaskeyreceiver $! #以上一行产生的进程的进程号作为參数fi



Very powerful shell written by Tetris

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.