Tetris: Difference between revisions
Content added Content deleted
Childishbeat (talk | contribs) |
Childishbeat (talk | contribs) m (Added BASH code for Tetris) |
||
Line 17: | Line 17: | ||
No further requirement about randomizer / rotation system / DAS / colors / difficulty levels / score / hold, but you may do it if you wish. |
No further requirement about randomizer / rotation system / DAS / colors / difficulty levels / score / hold, but you may do it if you wish. |
||
=={{header|BASH}}== |
|||
<lang BASH>#!/bin/bash |
|||
# Tetris Game |
|||
# 10.21.2003 xhchen |
|||
# http://read.pudn.com/downloads99/sourcecode/game/404711/tetris.sh__.htm |
|||
# Copyright (C) xhchen |
|||
#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 |
|||
#boxes |
|||
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[@]} ${box5[@]} ${box6[@]}) |
|||
countBox=(1 2 2 2 4 4 4 ) |
|||
offsetBox=(0 1 3 5 7 11 15) |
|||
#score |
|||
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 |
|||
RunAsKeyReceiver() { |
|||
local pidDisplayer key aKey sig cESC sTTY |
|||
pidDisplayer=$1 |
|||
aKey=(0 0 0) |
|||
cESC=`echo -ne "\033"` |
|||
cSpace=`echo -ne "\040"` |
|||
sTTY=`stty -g` |
|||
trap "MyExit;" INT TERM |
|||
trap "MyExitNoSub;" $sigExit |
|||
echo -ne "\033[?25l" |
|||
while : |
|||
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 |
|||
} |
|||
MyExitNoSub(){ |
|||
local y |
|||
stty $sTTY |
|||
((y = iTop + iTrayHeight + 4)) |
|||
echo -e "\033[?25h\033[${y};0H" |
|||
exit |
|||
} |
|||
MyExit(){ |
|||
kill -$sigExit $pidDisplayer |
|||
MyExitNoSub |
|||
} |
|||
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 : |
|||
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 |
|||
} |
|||
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; |
|||
} |
|||
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 "\033[1m\033[3${cScoreValue}m\033[${y};${x}H${iScore} " |
|||
if ((iScore % iScoreEachLevel < line * 2 - 1)) |
|||
then |
|||
if ((iLevel < 20)) |
|||
then |
|||
((iLevel++)) |
|||
((y = iTop + 14)) |
|||
echo -ne "\033[3${cScoreValue}m\033[${y};${x}H${iLevel} " |
|||
fi |
|||
fi |
|||
echo -ne "\033[0m" |
|||
for ((y = 0; y < iTrayHeight; y++)) |
|||
do |
|||
((yp = y + iTrayTop + 1)) |
|||
((xp = iTrayLeft + 1)) |
|||
((i = y * iTrayWidth)) |
|||
echo -ne "\033[${yp};${xp}H" |
|||
for ((x = 0; x < iTrayWidth; x++)) |
|||
do |
|||
((j = i + x)) |
|||
if ((${iMap[$j]} == -1)) |
|||
then |
|||
echo -ne " " |
|||
else |
|||
echo -ne "\033[1m\033[7m\033[3${iMap[$j]}m\033[4${iMap[$j]}m\040\040\033[0m" |
|||
fi |
|||
done |
|||
done |
|||
} |
|||
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 |
|||
} |
|||
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 |
|||
} |
|||
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 |
|||
} |
|||
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 |
|||
} |
|||
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 |
|||
} |
|||
DrawCurBox(){ |
|||
local i j t bDraw sBox s |
|||
bDraw=$1 |
|||
s="" |
|||
if (( bDraw == 0 )) |
|||
then |
|||
sBox="\040\040" |
|||
else |
|||
sBox="\040\040" |
|||
s=$s"\033[1m\033[7m\033[3${cBoxCur}m\033[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"\033[${i};${t}H${sBox}" |
|||
done |
|||
s=$s"\033[0m" |
|||
echo -n $s |
|||
} |
|||
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 "\033[${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 "\033[1m\033[7m\033[3${cBoxNew}m\033[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 "\033[${i};${t}H\040\040" |
|||
done |
|||
echo -ne "\033[0m" |
|||
} |
|||
InitDraw(){ |
|||
clear |
|||
RandomBox |
|||
RandomBox |
|||
local i t1 t2 t3 |
|||
#draw border |
|||
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++)) |
|||
do |
|||
((t1 = i + iTop + 2)) |
|||
echo -ne "\033[${t1};${t2}H\040\040" |
|||
echo -ne "\033[${t1};${t3}H\040\040" |
|||
done |
|||
((t2 = iTop + iTrayHeight + 2)) |
|||
for ((i = 0; i < iTrayWidth + 2; i++)) |
|||
do |
|||
((t1 = i * 2 + iLeft + 1)) |
|||
echo -ne "\033[${iTrayTop};${t1}H\040\040" |
|||
echo -ne "\033[${t2};${t1}H\040\040" |
|||
done |
|||
echo -ne "\033[0m" |
|||
#draw score & level prompt |
|||
echo -ne "\033[1m" |
|||
((t1 = iLeft + iTrayWidth * 2 + 7)) |
|||
((t2 = iTop + 10)) |
|||
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 + 13)) |
|||
echo -ne "\033[3${cScore}m\033[${t2};${t1}HLevel" |
|||
((t2 = iTop + 14)) |
|||
echo -ne "\033[3${cScoreValue}m\033[${t2};${t1}H${iLevel}" |
|||
echo -ne "\033[0m" |
|||
} |
|||
ShowExit(){ |
|||
local y |
|||
((y = iTrayHeight + iTrayTop + 3)) |
|||
echo -e "\033[${y};0HGameOver!\033[0m" |
|||
exit |
|||
} |
|||
#Start from here. |
|||
if [[ $1 != "--go" ]] |
|||
then |
|||
$0 --go& |
|||
RunAsKeyReceiver $! |
|||
exit |
|||
else |
|||
RunAsDisplayer |
|||
exit |
|||
fi </lang> |
|||
=={{header|Microsoft Small Basic}}== |
=={{header|Microsoft Small Basic}}== |
||
This game was coded by Small Basic coder Kenneth Kasajian. |
This game was coded by Small Basic coder Kenneth Kasajian. |