您的当前位置:首页shell编程俄罗斯方块

shell编程俄罗斯方块

2022-09-20 来源:乌哈旅游


#!/bin/bash # Tetris Game

# 10.21.2003 xhchen

############################################################################### # 因为HP 上没有 usleep by CHENCHENG

############################################################################### # #include # #include #

# int main(int argc, char **argv) # {

# int nRet;

# nRet = usleep(atol(argv[1]));

# //printf(\"%ld %d\\n\# return 0; # }

###############################################################################

#color definition cRed=1 cGreen=2 cYellow=3 cBlue=4 cFuchsia=5 cCyan=6 cWhite=7

colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)

#size & position iLeft=3 iTop=2

((iTrayLeft = iLeft + 2)) ((iTrayTop = iTop + 1)) ((iTrayWidth = 10)) ((iTrayHeight = 15))

#style definition cBorder=$cGreen cScore=$cFuchsia cScoreValue=$cCyan

#control signal

sigRotate=25 sigLeft=26 sigRight=27 sigDown=28 sigAllDown=29 sigExit=30

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 1 2)

box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box6[@]})

countBox=(1 2 2 2 4 4 4) offsetBox=(0 1 3 5 7 11 15)

iScoreEachLevel=50 #be greater than 7 #Runtime data sig=0 iScore=0 iLevel=0

boxNew=() #new box

cBoxNew=0 #new box color iBoxNewType=0 #new box type

iBoxNewRotate=0 #new box rotate degree boxCur=() #current box

cBoxCur=0 #current box color iBoxCurType=0 #current box type

iBoxCurRotate=0 #current box rotate degree boxCurX=-1 #current X position boxCurY=-1 #current Y position iMap=()

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 \"\\33\"`

${box5[@]}

cSpace=`echo -ne \"\\40\"` sTTY=`stty -g`

trap \"MyExit;\" INT TERM trap \"MyExitNoSub;\" $sigExit

echo -ne \"\\33[?25l\" while [[ 1 ]] do

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

MyExit

elif [[ ${aKey[0]} == $cESC && ${aKey[1]} == \"[\" ]] then

if [[ $key == \"A\" ]]; then sig=$sigRotate elif [[ $key == \"B\" ]]; then sig=$sigDown elif [[ $key == \"D\" ]]; then sig=$sigLeft elif [[ $key == \"C\" ]]; then sig=$sigRight fi

elif [[ $key == \"W\" || $key == \"w\" ]]; then sig=$sigRotate elif [[ $key == \"S\" || $key == \"s\" ]]; then sig=$sigDown elif [[ $key == \"A\" || $key == \"a\" ]]; then sig=$sigLeft elif [[ $key == \"D\" || $key == \"d\" ]]; then sig=$sigRight elif [[ \"[$key]\" == \"[]\" ]]; then sig=$sigAllDown elif [[ $key == \"Q\" || $key == \"q\" ]] then

MyExit fi

if [[ $sig != 0 ]] then

kill -$sig $pidDisplayer fi done }

function MyExitNoSub() {

local y

stty $sTTY

((y = iTop + iTrayHeight + 4)) echo -e \"\\33[?25h\\33[${y};0H\" exit }

function MyExit() {

kill -$sigExit $pidDisplayer MyExitNoSub }

function RunAsDisplayer() {

local sigThis InitDraw

trap \"sig=$sigRotate;\" $sigRotate trap \"sig=$sigLeft;\" $sigLeft trap \"sig=$sigRight;\" $sigRight trap \"sig=$sigDown;\" $sigDown

trap \"sig=$sigAllDown;\" $sigAllDown trap \"ShowExit;\" $sigExit

while [[ 1 ]] do

for ((i = 0; i < 21 - iLevel; i++)) do

usleep 20000 sigThis=$sig sig=0

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 }

function BoxMove()

{

local j i x y xTest yTest yTest=$1 xTest=$2

for ((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)) then

return 1 fi

if ((${iMap[y * iTrayWidth + x]} != -1 )) then

return 1 fi done return 0; }

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 = ${boxCur[$i]} + boxCurX)) ((i = y * iTrayWidth + x)) iMap[$i]=$cBoxCur done

line=0

for ((j = 0; j < iTrayWidth * iTrayHeight; j += iTrayWidth)) do

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--))

do

((x = i + iTrayWidth)) iMap[$x]=${iMap[$i]} done

for ((i = 0; i < iTrayWidth; i++)) do

iMap[$i]=-1 done done

if ((line == 0)); then return; fi

((x = iLeft + iTrayWidth * 2 + 7)) ((y = iTop + 11))

((iScore += line * 2 - 1))

echo -ne \"\\33[1m\\33[3${cScoreValue}m\\33[${y};${x}H${iScore} \" if ((iScore % iScoreEachLevel < line * 2 - 1)) then

if ((iLevel < 20)) then

((iLevel++)) ((y = iTop + 14))

echo -ne \"\\33[3${cScoreValue}m\\33[${y};${x}H${iLevel} \" fi fi

echo -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)) then

echo -ne \" \" else

echo -ne \"\\33[1m\\33[7m\\33[3${iMap[$j]}m\\33[4${iMap[$j]}m[]\\33[0m\" fi done

done }

function BoxDown() {

local y s

((y = boxCurY + 1))

if BoxMove $y $boxCurX then

s=\"`DrawCurBox 0`\" ((boxCurY = y))

s=\"$s`DrawCurBox 1`\" echo -ne $s else

Box2Map 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 = boxCurX + 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=$iTrayHeight for ((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; fi done

((k -= y + 1))

if (( $iDown > $k )); then iDown=$k; fi done

s=`DrawCurBox 0` ((boxCurY += iDown)) s=$s`DrawCurBox 1` echo -ne $s Box2Map RandomBox }

function BoxRotate() {

local iCount iTestRotate boxTest j i s iCount=${countBox[$iBoxCurType]} ((iTestRotate = iBoxCurRotate + 1)) if ((iTestRotate >= iCount)) then

((iTestRotate = 0)) fi

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

for ((j = 0; j < 8; j++)) do

boxCur[$j]=${boxTest[$j]} done fi }

function DrawCurBox() {

local i j t bDraw sBox s bDraw=$1

s=\"\"

if (( bDraw == 0 )) then

sBox=\"\\40\\40\" else

sBox=\"[]\"

s=$s\"\\33[1m\\33[7m\\33[3${cBoxCur}m\\33[4${cBoxCur}m\" fi

for ((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}\" done

s=$s\"\\33[0m\" echo -n $s

}

function RandomBox() {

local i j t

#change current box

iBoxCurType=${iBoxNewType} iBoxCurRotate=${iBoxNewRotate} cBoxCur=${cBoxNew}

for ((j = 0; j < ${#boxNew[@]}; j++)) do

boxCur[$j]=${boxNew[$j]} done

if (( ${#boxCur[@]} == 8 )) then

#calculate current box's starting position 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 = 20; 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`

if ! BoxMove $boxCurY $boxCurX then

kill -$sigExit ${PPID} ShowExit fi fi

#clear old box

for ((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++)) do

boxNew[$j]=${box[$i]}; done

((cBoxNew = ${colorTable[RANDOM % ${#colorTable[@]}]}))

#display new box

echo -ne \"\\33[1m\\33[7m\\33[3${cBoxNew}m\\33[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[]\" done

echo -ne \"\\33[0m\" }

function InitDraw() {

clear

RandomBox RandomBox local i t1 t2 t3

#draw border echo -ne \"\\33[1m\"

echo -ne \"\\33[3${cBorder}m\\33[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==\" done

echo -ne \"\\33[0m\"

#draw score & level prompt echo -ne \"\\33[1m\"

((t1 = iLeft + iTrayWidth * 2 + 7)) ((t2 = iTop + 10))

echo -ne \"\\33[3${cScore}m\\33[${t2};${t1}HScore\" ((t2 = iTop + 11))

echo -ne \"\\33[3${cScoreValue}m\\33[${t2};${t1}H${iScore}\" ((t2 = iTop + 13))

echo -ne \"\\33[3${cScore}m\\33[${t2};${t1}HLevel\" ((t2 = iTop + 14))

echo -ne \"\\33[3${cScoreValue}m\\33[${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 $! exit else

RunAsDisplayer exit fi

因篇幅问题不能全部显示,请点此查看更多更全内容