#!/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 #//////////////////////////////////////////////////////////////