#!/bin/sh
#create by coonzhang 20060101
#//////////////////////////////////////////////////////////////
function display()
{
local pt_x pt_y i
for ((i = 0; i < 12*22; i++))
do
((pt_x=($i%12)*2+10))
((pt_y=$i/12+10))
echo -en "\e[30m\e[4${_MAP[$i]}m\e[${pt_y};${pt_x}H[]\e[30m\e[40m"
done
}
#//////////////////////////////////////////////////////////////
function blocked()
{
local i
for ((i = 0; i < 4; i++)); do
if [[ ${BOX[$i]} == $1 ]]; then return 0; fi
done
if [[ ${_MAP[$1]} != 0 ]]; then return 1; fi
}
#//////////////////////////////////////////////////////////////
function move()
{
MOVE=$(($MOVE+1)); local i
for ((i = 0; i < 4; i++)); do
blocked $((${BOX[$i]}+$1))
if [[ $? == 1 ]]; then return 1; fi
done
for ((i = 0; i < 4; i++)); do _MAP[${BOX[$i]}]=0; done
for ((i = 0; i < 4; i++)); do BOX[$i]=$((${BOX[$i]}+$1)); done
for ((i = 0; i < 4; i++)); do _MAP[${BOX[$i]}]=$INDEX; done
display; return 0;
}
#//////////////////////////////////////////////////////////////
function rotate()
{
local i x y
for ((i = 0; i < 4; i++)); do
if [[ ${VAR[$INDEX-1]} == 2 ]] && [[ ${PST[0]} == 1 ]]
then
((x=${PST[$i*2+1]}-${PST[$i*2]}))
((y=0-(${PST[$i*2]}+${PST[$i*2+1]})))
else
((x=0-(${PST[$i*2]}+${PST[$i*2+1]})))
((y=${PST[$i*2]}-${PST[$i*2+1]}))
fi
blocked $((${BOX}+$y*12+$x))
if [[ $? == 1 ]]; then return; fi
done
for ((i = 0; i < 4; i++)); do _MAP[${BOX[$i]}]=0; done
for ((i = 0; i < 4; i++)); do
if [[ ${VAR[$INDEX-1]} == 2 ]] && [[ ${PST[0]} == 1 ]]
then
((x=${PST[$i*2+1]}-${PST[$i*2]}))
((y=0-(${PST[$i*2]}+${PST[$i*2+1]})))
else
((x=0-(${PST[$i*2]}+${PST[$i*2+1]})))
((y=${PST[$i*2]}-${PST[$i*2+1]}))
fi
BOX[$i]=$((${BOX[$i]}+$y*12+$x));
done
for ((i = 0; i < 4; i++)); do _MAP[${BOX[$i]}]=$INDEX; done
for ((i = 0; i < 8; i+=2)); do NEW[$i]=$((0-${PST[$i+1]})); NEW[$i+1]=${PST[$i]}; done
if [[ ${VAR[$INDEX-1]} == 2 ]] && [[ ${PST[0]} == 1 ]]; then
for ((i = 0; i < 8; i++)); do PST[$i]=$((0-${NEW[$i]})); done
else
PST=(${NEW[@]}); fi; display
}
#//////////////////////////////////////////////////////////////
function score()
{
local loop=1 lines=0
while (($loop <= 20))
do
for ((j = 1; j <= 10; j++)); do
if ((${_MAP[$loop*12+$j]} == 0)); then break; fi
done
if (( $j >= 11 )); then
for ((k = $loop; k >= 2; k--)); do
for ((l = 1; l <= 10; l++)); do
_MAP[$k*12+$l]=$((${_MAP[($k-1)*12+$l]}))
done
done
display; loop=1; lines=$((lines+1)); continue;
fi
((loop=$loop+1))
done
((SCORE=$SCORE+100*$lines*$lines))
echo -en "\e[31m\e[40m\e[30;36HScore:$SCORE"
}
#//////////////////////////////////////////////////////////////
function bottom()
{
while ((1)); do
move 12; if [[ $? == 1 ]]; then checkend $?; break; fi
done
}
#//////////////////////////////////////////////////////////////
function checkend()
{
if [[ $1 == 1 ]]; then
if [[ $MOVE == 1 ]]; then
OVER=1; initmap; display;
local pt_x pty
echo -en "\e[31m\e[40m\e[20;17HGame Over!"
else
score; initbox; fi
fi
return $1;
}
#//////////////////////////////////////////////////////////////
function shownext()
{
local pt_x pt_y i
((next_x=10+12*2+5))
((next_y=10+1+3))
for ((i = 0; i < 4; i++)); do
((pt_x=${next_x}+${DEC[($INDEX-1)*8+$i*2]}*2))
((pt_y=${next_y}+${DEC[($INDEX-1)*8+$i*2+1]}))
echo -en "\e[30m\e[40m\e[${pt_y};${pt_x}H[]\e[30m\e[40m"
done
for ((i = 0; i < 4; i++)); do
((pt_x=${next_x}+${DEC[($NEXTBOX-1)*8+$i*2]}*2))
((pt_y=${next_y}+${DEC[($NEXTBOX-1)*8+$i*2+1]}))
echo -en "\e[30m\e[4${NEXTBOX}m\e[${pt_y};${pt_x}H[]\e[30m\e[40m"
done
}
#//////////////////////////////////////////////////////////////
function initbox()
{
INDEX=$NEXTBOX; MOVE=0;
for ((i = 0; i < 8; i++)); do PST[$i]=${DEC[($INDEX-1)*8+$i]}; done
for ((i = 0; i < 4; i++)); do ((index=$OHO+${PST[$i*2]}+${PST[$i*2+1]}*12)); BOX[$i]=$index; done
for ((i = 0; i < 4; i++)); do _MAP[${BOX[$i]}]=$INDEX; done
((NEXTBOX=$RANDOM%7+1)); shownext; display;
}
#//////////////////////////////////////////////////////////////
function initmap()
{
for ((i = 0 i < 22; i++)); do
for ((j = 0; j < 12; j++)); do
((index=$i*12+$j))
if [[ $i == 0 ]] || [[ $i == 21 ]]; then _MAP[$index]=4;
elif [[ $j == 0 ]] || [[ $j == 11 ]]; then _MAP[$index]=4;
else _MAP[$index]=0; fi
done
done
}
#//////////////////////////////////////////////////////////////
function quit()
{
echo -e "\e[0m"; echo -e "\e[?25h\e[50;0H"; exit
}
#//////////////////////////////////////////////////////////////
clear
echo -ne "\e[30m\e[40m\e[?25l"
HELP="q:退出 8:旋转 4:向左 6:向右 5:向下 Space:落底"
echo -en "\e[37m\e[40m\e[33;2H$HELP"
((OHO=12*2+12/2-1))
((NEXTBOX=$RANDOM%7+1))
SIG_QUIT=45 SIG_ROTATE=46 SIG_LEFT=47 SIG_RIGHT=48 SIG_DOWN=49 SIG_BOTTOM=50
if [[ "$1" == "Play" ]]
then
VAR=(1 2 2 2 4 4 4)
DEC=(0 -1 1 -1 0 0 1 0 0 -1 0 0 0 1 0 2 -1 -1 0 -1 0 0 1 0 0 -1 1 -1 -1 0 0 0 -1 -1 0 -1 0 0 0 1 0 -1 1 -1 0 0 0 1 0 -1 -1 0 0 0 1 0)
OVER=0; SCORE=0; initmap; initbox;
trap "quit;" $SIG_QUIT
trap "rotate;" $SIG_ROTATE;
trap "move -1;" $SIG_LEFT
trap "move 1;" $SIG_RIGHT;
trap "move 12; checkend $?;" $SIG_DOWN;
trap "bottom;" $SIG_BOTTOM;
while ((1))
do
if [[ $OVER == 1 ]]; then sleep 1; continue; fi
local i; for ((i = 0; i < 5130; i++)); do echo -en ""; done
move 12; checkend $?;
done
else
$0 "Play" &
PID=$!
while ((1))
do
read -s -n1 key
if [[ $key == "q" ]]; then kill -$SIG_QUIT $PID; break;
elif [[ $key == "8" ]]; then kill -$SIG_ROTATE $PID;
elif [[ $key == "4" ]]; then kill -$SIG_LEFT $PID;
elif [[ $key == "6" ]]; then kill -$SIG_RIGHT $PID;
elif [[ $key == "5" ]]; then kill -$SIG_DOWN $PID;
elif [[ "[$key]" == "[]" ]]; then kill -$SIG_BOTTOM $PID;
elif [[ $OVER == 1 ]]; then kill -$SIG_QUIT $PID; break;
fi
done
fi
quit
#//////////////////////////////////////////////////////////////
|
|
|