shell版俄罗斯方块(转)[@more@]
感谢各位兄弟的捧场,
属于旧瓶装新酒了,呵呵
如果你的终端可以显示出颜色,效果会好点
运行于GNU bash, version 2.05a.0(1)-release (i686-pc-linux-gnu)
[code:1:7a68d2722e]
#!/bin/bash
# Tetris Game
# 10.21.2003 xhchen
#color definitioncRed=1cGreen=2cYellow=3cBlue=4cFuchsia=5cCyan=6cWhite=7colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)#size & positioniLeft=3iTop=2((iTrayLeft = iLeft + 2))((iTrayTop = iTop + 1)) ((iTrayWidth = 10))((iTrayHeight = 15))#style definitioncBorder=$cGreencScore=$cFuchsiacScoreValue=$cCyan#control signalsigRotate=25sigLeft=26sigRight=27sigDown=28sigAllDown=29sigExit=30box0=(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 1 2)box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})countBox=(1 2 2 2 4 4 4)offsetBox=(0 1 3 5 7 11 15)iScoreEachLevel=50 #be greater than 7#Runtime datasig=0iScore=0iLevel=0boxNew=() #new boxcBoxNew=0 #new box coloriBoxNewType=0 #new box typeiBoxNewRotate=0 #new box rotate degreeboxCur=() #current boxcBoxCur=0 #current box coloriBoxCurType=0 #current box typeiBoxCurRotate=0 #current box rotate degreeboxCurX=-1 #current X positionboxCurY=-1 #current Y positioniMap=()for ((i = 0; i < iTrayHeight * iTrayWidth; i++)); do iMap[$i]=-1; donefunction RunAsKeyReceiver(){local pidDisplayer key aKey sig cESC sTTYpidDisplayer=$1aKey=(0 0 0)cESC=`echo -ne "33"`cSpace=`echo -ne "40"`sTTY=`stty -g`trap "MyExit;" INT TERMtrap "MyExitNoSub;" $sigExitecho -ne "33[?25l"while [[ 1 ]]doread -s -n 1 keyaKey[0]=${aKey[1]}aKey[1]=${aKey[2]}aKey[2]=$keysig=0if [[ $key == $cESC && ${aKey[1]} == $cESC ]]thenMyExitelif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]]thenif [[ $key == "A" ]]; then sig=$sigRotateelif [[ $key == "B" ]]; then sig=$sigDownelif [[ $key == "D" ]]; then sig=$sigLeftelif [[ $key == "C" ]]; then sig=$sigRightfielif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotateelif [[ $key == "S" || $key == "s" ]]; then sig=$sigDownelif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeftelif [[ $key == "D" || $key == "d" ]]; then sig=$sigRightelif [[ "[$key]" == "[]" ]]; then sig=$sigAllDownelif [[ $key == "Q" || $key == "q" ]]thenMyExitfiif [[ $sig != 0 ]]thenkill -$sig $pidDisplayerfidone}function MyExitNoSub(){local ystty $sTTY((y = iTop + iTrayHeight + 4))echo -e "33[?25h33[${y};0H"exit}function MyExit(){kill -$sigExit $pidDisplayerMyExitNoSub}function RunAsDisplayer(){local sigThisInitDrawtrap "sig=$sigRotate;" $sigRotatetrap "sig=$sigLeft;" $sigLefttrap "sig=$sigRight;" $sigRighttrap "sig=$sigDown;" $sigDowntrap "sig=$sigAllDown;" $sigAllDowntrap "ShowExit;" $sigExitwhile [[ 1 ]]dofor ((i = 0; i < 21 - iLevel; i++))dousleep 20000sigThis=$sigsig=0if ((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 $$BoxDowndone}function BoxMove(){local j i x y xTest yTestyTest=$1xTest=$2for ((j = 0; j < 8; j += 2))do((i = j + 1))((y = ${boxCur[$j]} + yTest))((x = ${boxCur[$i]} + xTest))if (( y < 0 || y >= iTrayHeight || x < 0 || x >= iTrayWidth))thenreturn 1fiif ((${iMap[y * iTrayWidth + x]} != -1 ))thenreturn 1fidonereturn 0;}function Box2Map(){local j i x y xp yp linefor ((j = 0; j < 8; j += 2))do((i = j + 1))((y = ${boxCur[$j]} + boxCurY))((x = ${boxCur[$i]} + boxCurX))((i = y * iTrayWidth + x))iMap[$i]=$cBoxCurdoneline=0for ((j = iTrayWidth * iTrayHeight; j > 0; j -= iTrayWidth))dofor ((i = j - iTrayWidth; i < j; i++))doif ((${iMap[$i]} == -1)); then break; fidoneif ((i < j)); then continue; fi((line++))for ((i = j - 1; i >= iTrayWidth; i--))do((x = i - iTrayWidth))iMap[$i]=${iMap[$x]}donefor ((i = 0; i < iTrayWidth; i++))doiMap[$i]=-1donedoneif ((line == 0)); then return; fi((x = iLeft + iTrayWidth * 2 + 7))((y = iTop + 11))((iScore += line * 2 - 1))echo -ne "33[1m33[3${cScoreValue}m33[${y};${x}H${iScore} "if ((iScore % iScoreEachLevel < line * 2 - 1))thenif ((iLevel < 20))then((iLevel++))((y = iTop + 14))echo -ne "33[3${cScoreValue}m33[${y};${x}H${iLevel} "fifiecho -ne "33[0m"for ((y = 0; y < iTrayHeight; y++))do((yp = y + iTrayTop + 1))((xp = iTrayLeft + 1))((i = y * iTrayWidth))echo -ne "33[${yp};${xp}H"for ((x = 0; x < iTrayWidth; x++))do((j = i + x))if ((${iMap[$j]} == -1))thenecho -ne " "elseecho -ne "33[1m33[3${iMap[$j]}m33[4${iMap[$j]}m[]33[0m"fidonedone}function BoxDown(){local y s((y = boxCurY + 1))if BoxMove $y $boxCurXthens="`DrawCurBox 0`"((boxCurY = y))s="$s`DrawCurBox 1`"echo -ne $selseBox2MapRandomBoxfi}function BoxLeft(){local x s((x = boxCurX - 1))if BoxMove $boxCurY $xthens=`DrawCurBox 0`((boxCurX = x))s=$s`DrawCurBox 1`echo -ne $sfi}function BoxRight(){local x s((x = boxCurX + 1))if BoxMove $boxCurY $xthens=`DrawCurBox 0`((boxCurX = x))s=$s`DrawCurBox 1`echo -ne $sfi}function BoxAllDown(){local k j i x y iDown siDown=$iTrayHeightfor ((j = 0; j < 8; j += 2))do((i = j + 1))((y = ${boxCur[$j]} + boxCurY))((x = ${boxCur[$i]} + boxCurX))for ((k = y + 1; k < iTrayHeight; k++))do((i = k * iTrayWidth + x))if (( ${iMap[$i]} != -1)); then break; fidone((k -= y + 1))if (( $iDown > $k )); then iDown=$k; fidones=`DrawCurBox 0`((boxCurY += iDown))s=$s`DrawCurBox 1`echo -ne $sBox2MapRandomBox}function BoxRotate(){local iCount iTestRotate boxTest j i siCount=${countBox[$iBoxCurType]}((iTestRotate = iBoxCurRotate + 1))if ((iTestRotate >= iCount))then((iTestRotate = 0))fifor ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))doboxTest[$j]=${boxCur[$j]}boxCur[$j]=${box[$i]}doneif BoxMove $boxCurY $boxCurXthenfor ((j = 0; j < 8; j++))doboxCur[$j]=${boxTest[$j]}dones=`DrawCurBox 0`for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))doboxCur[$j]=${box[$i]}dones=$s`DrawCurBox 1`echo -ne $siBoxCurRotate=$iTestRotateelsefor ((j = 0; j < 8; j++))doboxCur[$j]=${boxTest[$j]}donefi}function DrawCurBox(){local i j t bDraw sBox sbDraw=$1s=""if (( bDraw == 0 ))thensBox="4040"elsesBox="[]"s=$s"33[1m33[3${cBoxCur}m33[4${cBoxCur}m"fifor ((j = 0; j < 8; j += 2))do((i = iTrayTop + 1 + ${boxCur[$j]} + boxCurY))((t = iTrayLeft + 1 + 2 * (boxCurX + ${boxCur[$j + 1]})))s=$s"33[${i};${t}H${sBox}"dones=$s"33[0m"echo -n $s}function RandomBox(){local i j t#change current boxiBoxCurType=${iBoxNewType}iBoxCurRotate=${iBoxNewRotate}cBoxCur=${cBoxNew}for ((j = 0; j < ${#boxNew[@]}; j++))doboxCur[$j]=${boxNew[$j]}doneif (( ${#boxCur[@]} == 8 ))then#calculate current box's starting positionfor ((j = 0, t = 4; j < 8; j += 2))doif ((${boxCur[$j]} < t)); then t=${boxCur[$j]}; fidone((boxCurY = -t))for ((j = 1, i = -4, t = 20; j < 8; j += 2))doif ((${boxCur[$j]} > i)); then i=${boxCur[$j]}; fiif ((${boxCur[$j]} < t)); then t=${boxCur[$j]}; fidone((boxCurX = (iTrayWidth - 1 - i - t) / 2))echo -ne `DrawCurBox 1`if ! BoxMove $boxCurY $boxCurXthenkill -$sigExit ${PPID}ShowExitfifi#clear old boxfor ((j = 0; j < 4; j++))do((i = iTop + 1 + j))((t = iLeft + 2 * iTrayWidth + 7))echo -ne "33[${i};${t}H "done#get a random new box((iBoxNewType = RANDOM % ${#offsetBox[@]}))((iBoxNewRotate = RANDOM % ${countBox[$iBoxNewType]}))for ((j = 0, i = (${offsetBox[$iBoxNewType]} + $iBoxNewRotate) * 8; j < 8; j++, i++))doboxNew[$j]=${box[$i]};done((cBoxNew = ${colorTable[RANDOM % ${#colorTable[@]}]}))#display new boxecho -ne "33[1m33[3${cBoxNew}m33[4${cBoxNew}m"for ((j = 0; j < 8; j += 2))do((i = iTop + 1 + ${boxNew[$j]}))((t = iLeft + 2 * iTrayWidth + 7 + 2 * ${boxNew[$j + 1]}))echo -ne "33[${i};${t}H[]"doneecho -ne "33[0m"}function InitDraw(){clearRandomBoxRandomBoxlocal i t1 t2 t3#draw borderecho -ne "33[1m"echo -ne "33[3${cBorder}m33[4${cBorder}m"((t2 = iLeft + 1))((t3 = iLeft + iTrayWidth * 2 + 3))for ((i = 0; i < iTrayHeight; i++))do((t1 = i + iTop + 2))echo -ne "33[${t1};${t2}H||"echo -ne "33[${t1};${t3}H||"done((t2 = iTop + iTrayHeight + 2))for ((i = 0; i < iTrayWidth + 2; i++))do((t1 = i * 2 + iLeft + 1))echo -ne "33[${iTrayTop};${t1}H=="echo -ne "33[${t2};${t1}H=="doneecho -ne "33[0m"#draw score & level promptecho -ne "33[1m"((t1 = iLeft + iTrayWidth * 2 + 7))((t2 = iTop + 10))echo -ne "33[3${cScore}m33[${t2};${t1}HScore"((t2 = iTop + 11))echo -ne "33[3${cScoreValue}m33[${t2};${t1}H${iScore}"((t2 = iTop + 13))echo -ne "33[3${cScore}m33[${t2};${t1}HLevel"((t2 = iTop + 14))echo -ne "33[3${cScoreValue}m33[${t2};${t1}H${iLevel}"echo -ne "33[0m"}function ShowExit(){local y((y = iTrayHeight + iTrayTop + 3))echo -e "33[${y};0HGameOver!33[0m"exit}#Start from here.if [[ $1 != "--show" ]]then$0 --show&RunAsKeyReceiver $!exitelseRunAsDisplayerexitf
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8225414/viewspace-944848/
,如需转载,请注明出处,否则将追究法律责任。