Shell script Implementation Tetris

Source: Internet
Author: User
Tags clear screen

Draw is to draw out the graphical interface keytest is to get the keyboard Tetris is the whole game

tetris.sh

#!/bin/bashapp_name= "${0##*[\\/]}" app_version= "1.0" #颜色定义iSumColor =7# total colors cred=1# red cgreen=2# green cyellow=3# Yellow cblue= 4# Blue cfuchsia=5# Magenta ccyan=6# cyan (bluish green) cwhite=7# White # position and size marginleft=3# border left margin margintop=2# border top margin ((mapleft=marginleft+2)) # Checkerboard Left margin ((maptop= $marginTop + 1) #棋盘上边距mapWidth =10# checkerboard width mapheight=15# Checkerboard Height # color setting cborder= $cGreencScore =$ cfuchsiacscorevalue= $cCyan # Control Signal # game uses two processes, one for receiving input, one for game flow and display interface, #当前者接收到上下左右等按键时 to notify the latter by sending signal to the latter. sigrotate=25# up key sigleft=26sigright=27sigdown=28sigalldown=29# space bar sigexit=30# block definition, 7 Big class 19 styles # The first 8 bits are square coordinates, The Post 2 position is the place where the box just appeared box0_0= (0 0 0 1 1 0 1 1 0 4) box1_0= (0 1 1 1 2 1 3 1 0 3) box1_1= (1 0 1 1 1 2 1 3-1 3) box2_0= (0 0 1 0 1 1 2 1 0 4) box2_1= (0 1 0 2 1 0 1 1 0 3) box3_0= (0 1 1 0 1 1 2 0 0 4) box3_1= (0 0 0 1 1 1 1 2 0 4) box4_0= (0 2 1 0 1 1 1 2 0 3) box4  _1= (0 1 1 1 2 1 2 2 0 3) box4_2= (1 0 1 1 1 2 2 0-1 3) box4_3= (0 0 0 1 1 1 2 1 0 4) box5_0= (0 0 1 0 1 1 1 2 0 3) box5_1= (0 1 0 2 1 1 2 1 0 3) box5_2= (1 0 1 1 1 2 2 2-1 3) box5_3= (0 1 1 1 2 0 2 1 0 4) box6_0= (0 1 1 0 1 1 1 2 0 3) box6_1= (0 1 1 1 1 22 1 0 3) box6_2= (1 0 1 1 1 2 2 1-1 3) box6_3= (0 1 1 0 1 1 2 1 0 4) isumtype=7# block type Total boxstyle= (1 2 2 2 4 4 4) #各种方块旋转后可能的样式数目i scoreeachlevel=50# boost A level required score # run time Data sig=0# received signaliscore=0# score ilevel=0# speed Level boxnext= () #下一个方块iboxNextColor =0# The color of the next block iboxnexttype=0# the next block type iboxnextstyle=0# the next block style boxcur= () #当前方块的位置定义iBoxCurColor =0# The color of the current block iboxcurtype=0# The type of the current block iboxcurstyle=0# the current square's style boxcurx=-1# the current square's x-coordinate position boxcury=-1# the current square's y-coordinate position map= () #棋盘图表 # initializes all background squares to 1, indicating no block for (i = 0 ; I < mapheight * MAPWIDTH; i++)) domap[$i]=-1done# The main function of the process receiving the input functions Runaskeyreceiver () {local Piddisplayer key Akey Sig Cesc sttypiddisplayer=$ 1akey= (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, #需要在程序退出时恢复终端属性. stty= ' stty-g ' #捕捉退出信号trap "myexit;" INT quittrap "myexitnosub;" $sigExit # Hide cursor Echo-ne "\033[?25l" while:d o# read input. Note-S does not echo,-N reads a character immediately returns READ-S-N 1 keyakey[0]=${akey[1]}akey[1]=${akey[2]}akey[2]= $keysig =0# determines what key is entered if [[$key = = $cESC & amp;& ${akey[1]} = = $cESC]]then#esc key Myexitelif [[${akey[0]} = = $cESC && ${akey[1]} = = "["]]thenif [[$key = = "A"]]; Then sig= $sigRotate #< up key >elif [[$key = = "B"]]; Then sig= $sigDown #< down key >elif [[$key = = "D"]]; Then sig= $sigLeft #< left arrow >elif [[$key = = "C"]]; Then sig= $sigRight #< right arrow >fielif [[$key = = "W" | | $key = = "W"]]; Then sig= $sigRotate #w, welif [[$key = = "S" | | $key = = "S"]]; Then sig= $sigDown #s, selif [[$key = = "a" | | $key = = "a"]]; Then sig= $sigLeft #a, aelif [[$key = = "D" | | $key = = "D"]]; Then sig= $sigRight #d, Delif [["[$key]" = = "[]"]; Then sig= $sigAllDown # SPACEBAR elif [[$key = = ' Q ' | | $key = = ' Q ']] #Q, qthenmyexitfiif [[$sig! = 0]]then# Send a message to another process kill-$sig $ Piddisplayerfidone} #退出前的恢复MyExitNoSub () {Local y# restore terminal properties STTY $sTTY ((y = margintop + mapheight + 4) #显示光标echo-E "\033[?25h \033[${y};0h "Exit}myexit () {#通知显示进程需要退出kill-$sigExit $pidDisplayerMyExitNoSub} #处理显示和游戏流程的主函数RunAsDisplayer () { Local sigthisinitdraw# mount a variety of signal processing function trap "sig= $sigRotate;" $sigRotatetrap "sig= $siGleft, "$sigLefttrap" sig= $sigRight, "$sigRighttrap" sig= $sigDown; "$sigDowntrap" sig= $sigAllDown; "$sigAllDowntrap" showexit; "$sigExitwhile:d o# depending on the current speed level ilevel, set the number of times for the corresponding loop for ((i = 0; i < 21-ilevel; i++)) dosleep 0.02sigthis= $sigsig = 0# according to the SIG variable to determine whether to accept the corresponding signal 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; #下落到底fidone #kill-$sigDown $ $BoxDown # drop Line done} #绘制当前方块, pass the first argument, 0 means erase the current block, 1 means draw the current square drawcurbox () { Local I x y bErase sboxberase=$1if ((bErase = = 0)) thensbox= "\040\040" #用两个空格擦除elsesBox = "[]" Echo-ne "\033[1m\033[3${iboxc Urcolor}m\033[4${iboxcurcolor}m "Fifor ((i = 0; i < 8; i + = 2)) do ((y = maptop + 1 + ${boxcur[$i]} + Boxcury)) ((x = MapLe FT + 1 + 2 * (Boxcurx + ${boxcur[$i + 1]})) Echo-ne "\033[${y};${x}h${sbox}" Doneecho-ne "\033[0m"} #移动方块 #boxmove (y, x), test Try to move the block to (y, x) position, return 0, 1 can not BoxmovE () {Local I x y xPos yposypos=$1xpos=$2for ((i = 0; i < 8; i + 2)) do# block relative to checkerboard coordinates ((y = YPos + ${boxcur[$i]})) ((x = XPos +  ${boxcur[$i + 1]})) if ((Y < 0 | | y >= mapheight | | x < 0 | | x >= mapwidth)) then# hit the wall, return 1fiif (${map[y * mapwidth + x]} =-1)) then# hit another existing block, return 1fidonereturn 0; #将方块贴到棋盘上Box2Map () {Local i J x y line# the current moving block to the corresponding area for the chessboard for ((i = 0; i < 8; i + 2)) do# calculates the coordinates of the block relative to the chessboard (y = ${boxcur[$i]} + Boxcury)) ((x = ${boxcur[$i + 1]} + Boxcurx)) map[y*mapwidth+x]= $iBoxCurColor # assigns the block color to the map doneline=0for ((i = 0; i < Maphe ight; i++) dofor ((j = 0; J < Mapwidth; J + +)) do# If there is a gap on the board, jump out of the loop [[${map[i*mapwidth+j]}-eq-1]] && breakdone[$j-lt $ Mapwidth] && continue# The current line can be eliminated, can eliminate the number of rows plus one ((line++)) #第i行可被消除, 0 lines to the i-1 row all down one line, starting from the first i-1 line to move for (j = i*mapwidth-1; j >= 0; j--) do ((x = j + mapwidth) map[$x]=${map[$j]}done# because a row is moved down, the No. 0 line is empty for ((i = 0; i < mapwidth; i++)) domap[$i]=-1donedone[$li Ne-eq 0] && return# calculates fractions and speed levels based on the number of rows eliminated (x = MarginLeft + Mapwidth * 2 + 7)) ((y = margintop + one)) ((Iscore + = line * 2-1)) #显示新的分数echo-ne "\033[1m\033[3${cscorevalue}m\033[${y}; ${x}h${iscore} "if ((iscore% Iscoreeachlevel < line * 2-1)) thenif ((Ilevel <) and then ((ilevel++)) ((y = ma Rgintop +)) #显示新的速度级echo-ne "\033[3${cscorevalue}m\033[${y};${x}h${ilevel}" Fifiecho-ne "\033[0m" #重新显示背景方块for ( (i = 0; i < mapheight; i++))  do# the checkerboard's coordinates with respect to the screen ((y = i + maptop + 1)) ((x = mapleft + 1)) Echo-ne "\033[${y};${x}h" for ((j = 0; J < Mapwidth; J + +))-Do ((TMP = i * mapwidth + j)) if ((${map[$tmp]} = =-1)) Thenecho-ne "Elseecho-ne" \033[1m\033[3${map[$tmp]}m\033[4${map[$tmp]}m []\033[0m "Fidonedone} #左移一格BoxLeft () {local x ((x = boxCurX-1)) If Boxmove $boxCurY $xthenDrawCurBox 0 ((Boxcurx = x)) DRAWCU Rbox 1fi} #右移一格BoxRight () {local x ((x = Boxcurx + 1)) if Boxmove $boxCurY $xthenDrawCurBox 0 ((Boxcurx = x)) Drawcurbox 1fi} #向下 Move one grid Boxdown () {Local Y ((y = Boxcury + 1)) #新的y坐标if boxmove $y $boxCurX # Test If you can drop a row thendrawcurbox 0# erase the old block ((Boxcury = y)Drawcurbox # shows the new whereabouts of the rear block else# come here, if you can't fall box2map# the current moving block is pasted into the background box createbox# generate a new block fi} #下落到底BoxAllDown () {Local Y idown# calculates the number of rows that can fall idown=0 ((y = Boxcury + 1)) while Boxmove $y $boxCurXdo ((y++)) ((idown++)) Donedrawcurbox 0# erase the old block (boxc UrY + = Idown)) Drawcurbox # shows the new falling block box2map# the current moving block to the background box createbox# create a new block} #翻转BoxRotate () {[${boxstyle[$ Iboxcurtype]}-eq 1] && return ((Rotatestyle = (iboxcurstyle + 1)% ${boxstyle[$iBoxCurType]}) #将当前方块保存到boxTmpbox tmp= (' eval ' echo ${boxcur[@]} ') boxcur= (' eval ' echo ${box ' $iBoxCurType ' _ ' $rotateStyle ' [@]} ') if Boxmove $boxCurY $box curx# Test if there is space after rotation then# erase the old block boxcur= (' eval ' echo ${boxtmp[@]} ') Drawcurbox 0boxcur= (' eval ' echo ${box ' $iBoxCurType ' _ ' $rotateStyle ' [@]} ') Drawcurbox 1iboxcurstyle= $rotateStyleelse # cannot rotate, or continue to use the old style boxcur= (' eval ' echo ${boxtmp[@]} ' ) fi} #准备下一个方块PrepareNextBox () {Local I x y# clears the right pre-displayed block if (${#boxNext [@]}! = 0)), thenfor ((i = 0; i < 8; i + = 2)) do ((Y = margintop + 1 + ${boxnext[$i]})) ((x = marginleft + 2 * mapwidTh + 7 + 2 * ${boxnext[$i + 1]})) Echo-ne "\033[${y};${x}h\040\040" donefi# randomly generate pre-explicit squares (Iboxnexttype = random% Isumtype) ( (Iboxnextstyle = RANDOM% ${boxstyle[$iBoxNextType]})) ((Iboxnextcolor = RANDOM% $iSumColor + 1)) boxnext= (' eval ' echo ${box ' $iBoxNextType ' _ ' $iBoxNextStyle ' [@]} ') #显示右边预显示的方 Block Echo-ne "\033[1m\033[3${iboxnextcolor}m\033[4${iboxnextcolor}m" for ((i = 0; i < 8; i + = 2)) do ((y = margintop + 1 + ${ boxnext[$i])) ((x = marginleft + 2 * mapwidth + 7 + 2 * ${boxnext[$i + 1]})) Echo-ne "\033[${y};${x}h[" "Doneecho-ne" \033 [0m} #显示新方块CreateBox () {if ((${#boxCur [@]} = = 0); then# current block does not exist ((Iboxcurtype = RANDOM% Isumtype)) ((Iboxcurstyle = RAN DOM% ${boxstyle[$iBoxCurType]}) ((Iboxcurcolor = RANDOM% $iSumColor + 1)) else# the current block already exists and assigns the next block to the current block iboxcurtype= $iBoxN exttype;iboxcurstyle= $iBoxNextStyle; iboxcurcolor= $iBoxNextColorfi # current block array boxcur= (' eval ' echo ${box ' $iBoxCurType ' _ ' $iBoxCurStyle ' [@]} ') #初始化方块起始坐标boxCurY =boxcur[8];boxcurx=boxcur[9];D Rawcurbox # Draw the current square if! BoxmovE $boxCurY $boxCurXthenkill-$sigExit $PPIDShowExitfiPrepareNextBox} #绘制边框DrawBorder () {clearlocal I y x1 x2# display Border Echo-ne  "\033[1m\033[3${cborder}m\033[4${cborder}m" ((x1 = marginleft + 1)) #左边框x坐标 ((x2 = x1 + 2 + mapwidth * 2)) #右边框x坐标for ((i = 0; i < mapheight; i++)) do ((y = i + margintop + 2)) Echo-ne "\033[${y};${x1}h| |" #绘制左边框echo-ne "\033[${y};${x2}h| |" #绘制右边框done ((x1 = margintop + mapheight + 2)) for ((i = 0; i < Mapwidth + 2; i++)) do ((y = i * 2 + marginleft + 1)) Echo-n E "\033[${maptop};${y}h==" #绘制上边框echo-ne "\033[${x1};${y}h==" #绘制下边框doneecho-ne "\033[0m" #显示 "score" and "level" the words echo- Ne "\033[1m" ((y = marginleft + mapwidth * 2 + 7)) ((x1 = margintop +)) Echo-ne "\033[3${cscore}m\033[${x1};${y}hscore" (( X1 = margintop + one)) Echo-ne "\033[3${cscorevalue}m\033[${x1};${y}h${iscore}" ((x1 = margintop +) Echo-ne "\033[3${cSc Ore}m\033[${x1};${y}hlevel "((x1 = margintop +)) Echo-ne" \033[3${cscorevalue}m\033[${x1};${y}h${ilevel} "Echo-ne" \ 033[0m "}initdraw () {clear# clear screen drawborder# Draw border Createbox# Create block} #退出时显示GameOVer! Showexit () {Local Y ((y = mapheight + maptop + 3)) echo-e "\033[${y};1hgameover!\033[0m" Exit} #游戏主程序在这儿开始. if [[[] "= ="--ve Rsion "]; Thenecho "$APP _name $APP _version" Elif [["$" = = "--show"]]; then# when a parameter--show is found, run the display function Runasdisplayerelsebash $--show& #以参数--show Run the program again Runaskeyreceiver $!# The process number of the process generated by the above line as the parameter fi


keytest.sh


#!/bin/bashgetkey () {akey= (0 0 0) #定义一个数组来保存3个按键cESC = ' Echo-ne ' \033 ' cspace= ' echo-ne ' \040 ' while:d oread-s-N 1 key
   
     #读取一个字符, read the word characters in key #echo $key #echo XXX akey[0]=${akey[1]} #第一个按键aKey [1]=${akey[2]} #第二个按键aKey [2]= $key        # Third key if [[$key = = $cESC && ${akey[1]} = = $cESC]]thenmyexitelif [[${akey[0]} = = $cESC && ${akey[1]} = = " [" ]] thenif [[$key = = "A"]]; then echo keyupelif [[$key = = "B"]]; then echo keydownelif [[$key = = "D"]]; then echo keyleftelif [[$key = = "C"]]; Then Echo Keyrightfifidone}getkey
   


draw.sh



#!/bin/bash# position and size marginleft=8# border left margin margintop=6# border top margin ((mapleft=marginleft+2)) #棋盘左边距 ((maptop= $marginTop + 1)) #  Checkerboard Top margin mapwidth=10# checkerboard width mapheight=15# Checkerboard Height # block definition, 7 categories 19 Styles # The first 8 bits are square coordinates, the last 2 bits is the position of the box when it first appeared box0_0= (0 0 0 1 1 0 1 1 0 4) box1_0= (0 1 1 1 2 1 3 1 0 3) box1_1= (1 0 1 1 1 2 1 3-1 3) box2_0= (0 0 1 0 1 1 2 1 0 4) box2_1= (0 1 0 2 1 0 1 1 0 3) box3_0= (0 1 1 0 1 1 2 0 0 4) box3_1= (0 0 0 1 1 1 1 2 0 4) box4_0= (0 2 1 0 1 1 1 2 0 3) box4_1= (0 1 1 1 2 1 2 2 0 3) box4_2= (1 0 1 1 1 2 2 0-1 3) box4_3= (0 0 0 1 1 1 2 1 0 4) box5_0= (0 0 1 0 1 1 1 2 0 3) box5_1= (0 1 0 2 1 1 2 1 0 3) box5_2= (1 0 1 1 1 2 2 2-1 3) box5_3= (0 1 1 1  2 0 2 1 0 4) box6_0= (0 1 1 0 1 1 1 2 0 3) box6_1= (0 1 1 1 1 2 2 1 0 3) box6_2= (1 0 1 1 1 2 2 1-1 3) box6_3= (0 1 1 0 1 1 2 1 0 4) #绘制边框DrawBorder () {clearlocal I y x1 x2# display border Echo-ne "\033[1m\033[32m\033[42m" ((x1 = marginleft + 1)) #左边框x坐标 ((x2 = x1 + 2 + mapwidth * 2)) #右边框x坐标for ((i = 0; i < mapheight; i++)) do ((y = i + margintop + 2)) Echo-ne "\033[${y};${x1}h| |" #绘制左边框echo-ne "\033[${y};${x2}h| |" #绘制右边框done((x1 = margintop + mapheight + 2)) for ((i = 0; i < Mapwidth + 2; i++))-do ((y = i * 2 + marginleft + 1)) Echo-ne "\033[${ maptop};${y}h== "#绘制上边框echo-ne" \033[${x1};${y}h== "#绘制下边框doneecho-ne" \033[0m "}drawbox () {Local I x y xPos yposypos=${ Box0_0[8]}xpos=${box0_0[9]}echo-ne "\033[1m\033[35m\033[45m" for ((i = 0; i < 8; i + = 2)) does ((y = maptop + 1 + ${box0_0 [$i]} + YPos)) ((x = mapleft + 1 + 2 * (${box0_0[$i + 1]} + XPos))) Echo-ne "\033[${y};${x}h[" Doneecho-ne "\033[0m"}initdraw () {clear# clear screen drawborder# draw Border Drawboxwhile:d Osleep 1done}initdraw





Shell script Implementation 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.