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
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 = iTrayWidth * iTrayHeight; j > 0; j -= iTrayWidth)) do for ((i = j - iTrayWidth; i < j; i++)) do if ((${iMap[$i]} == -1)); then break; fi done if ((i < j)); then continue; fi
((line++)) for ((i = j - 1; i >= iTrayWidth; i--)) do ((x = i - iTrayWidth)) iMap[$i]=${iMap[$x]} 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[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
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[3${cBoxCur}m\33[4${cBoxCur}m" fi
#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
#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