LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-02-2011, 10:35 AM   #1
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Rep: Reputation: Disabled
Thumbs up 【Tetris Game -- based on a shell script】(new algorithm)


Hi all, i have successfully developed a shell version of the Tetris Game based on a new algorithm yesterday all by myself, below is the link of the source code that i posted at a Linux/Unix forum the first in China:
http://bbs.chinaunix.net/thread-3614425-1-1.html
I'd love to know that someone can be able to optimize my source code and enhance it!
Rename the attachment Tetris_Game.txt to Tetris_Game.sh before you run it!
how to play with it?
Code:
bash Tetris_Game.sh [runlevel] [previewlevel] [speedlevel]


I made a copy of my source code below:
Code:
#!/bin/bash
# Tetris Game  // The Art Of Shell Programming

############################################################################################
#                                                                                          #
#   Author : YongYe <expertshell@gmail.com>                                                #
#   Version: 6.0 11/01/2011 BeiJing China [Updated 04/18/2012]                             #
#   License: GPLv3                                                                         #
#   Latest Version:  https://github.com/yongye/shell                                       #
#   Download Link1:  http://bash.deta.in/Tetris_Game.sh                                    #
#   Download Link2:  http://bbs.chinaunix.net/thread-3614425-1-1.html                      #
#                                                                                          #
#                                                                         [][][]           #
#   Algorithm:  [][][]                                                [][][][]             #
#               []                  [][][]                     [][][]     [][]             #
#   [][] [][]   []  [][][][]  [][][][][]    [][]             [][][]       []   [][] [][]   #
#   [] row []   []  [] (x-m)*zoomx  [][]    [] cos(a) -sin(a)  [][]       []   []  m  []   #
#   []     [] = []  []              []   *  []                 []         [] + []     []   #
#   [] col []   []  [] (y-n)*zoomy  []      [] sin(a)  cos(a)  []         []   []  n  []   #
#   [][] [][]   []  [][][][]  [][][][]      [][]             [][]         []   [][] [][]   #
#               []                                                        []               #
#               [][][]                                                [][][]               #
#                                                                                          #
############################################################################################

box0=(4 30)
box1=(4 30 4 32)
box2=(4 30 5 32)
box3=(4 28 4 30 4 32)
box4=(4 28 4 30 5 30)
box5=(4 28 5 30 6 32)
box6=(4 30 5 28 5 32)
box7=(4 28 5 30 6 32 7 34)
box8=(4 30 5 28 5 30 5 32)
box9=(4 30 5 28 5 32 6 30)
box10=(4 28 4 30 4 32 4 34)
box11=(4 28 5 28 5 30 5 32)
box12=(4 28 4 30 5 30 5 32)
box13=(4 28 4 30 5 28 5 30)
box14=(4 28 4 34 5 30 5 32)
box15=(4 26 4 28 4 30 4 32 4 34)
box16=(4 30 5 28 5 30 5 32 6 30)
box17=(4 28 4 32 5 30 6 28 6 32)
box18=(4 28 4 32 5 28 5 30 5 32)
box19=(4 28 4 30 5 30 6 30 6 32)
box20=(4 28 5 28 6 28 6 30 6 32)
box21=(4 28 4 30 5 30 5 32 6 32)
box22=(4 26 4 34 5 28 5 30 5 32)
box23=(4 26 4 34 5 28 5 32 6 30)
box24=(4 26 5 28 6 30 7 32 8 34)
box25=(4 28 4 32 5 26 5 30 5 34)
box26=(4 28 4 34 5 30 5 32 6 30 6 32 7 28 7 34)
box27=(4 30 5 28 5 32 6 26 6 30 6 34 7 28 7 32 8 30)
box28=(4 30 5 28 5 30 5 32 6 26 6 28 6 30 6 32 6 34 7 28 7 30 7 32 8 30)
box29=(4 26 4 28 4 30 4 34 5 30 5 34 6 26 6 28 6 30 6 32 6 34 7 26 7 30 8 26 8 30 8 32 8 34)
box30=(4 30 5 28 6 26 6 34 7 28 7 32 7 36 8 22 8 30 8 38 9 24 9 28 9 32 10 26 10 34 11 32 12 30)

unit=[]
toph=3
modw=5
width=25
height=30
scorelevel=0
prelevel=${3:-6} 
speedlevel=${4:-0}
((hh=2*width+modw+6))
coltab=(1\;{30..37}\;{40..47}m)
((prelevel=prelevel<1?6:prelevel))
((speedlevel=speedlevel>30?0:speedlevel))

value(){ echo $?; }      
piece(){ box=(${!1}); }
coord(){ kbox="${sup}"; }
signa(){ kill -24 ${pid}; }
limit(){ ((map[u/2-toph]=0)); }
shown(){ ptbox && locus="${sup}"; }
initi(){ ((map[index]=(pam[index]=0))); }
check(){ (( map[index] == 0 )) && break; }
erase(){ printf "${oldpie//[]/  }\e[0m\n"; }
radom(){ piece box$((RANDOM%runlevel))[@]; }
resum(){ stty ${oldtty} && printf "\e[?25h\e[36;4H\n"; }
stime(){ (( ${1} == ${2} )) && { ((++${3})); ((${1}=0)); }; }
ptbox(){ oldpie="${cdn}" && printf "\e[${colpie}${cdn}\e[0m\n"; }
pause(){ (( ${2} == 0 )) && kill -s STOP ${1} || kill -s CONT ${1}; }
point(){ ((${1}=mid[${#mid[@]}/2])) && ((${2}=mid[${#mid[@]}/2${3}1])); }

convert()
{ 
   [[ ${oldx} ]] && ((y=newy+(vor[i+1]-oldy)${2}2))
   eval ${1}+=\"${x} ${y} \"
}

quit()
{
   case ${#} in
        0) printf "\e[?25h\e[36;26HGame Over!\e[0m\n" ;;
        1) signa
           resum ;;
        2) resum ;;
   esac
           exit
}

getrunlevel()
{
   local k
   k=${1:-31}
   ((runlevel=(k < 0 || k > 30)?31:k+1))
}

lowerside()
{
   local i row col
   set -- ${box[@]} 
   col[$2]=${1} 
   row[$2]="${1} ${2}" && shift 2
   while (( ${#} != 0 )); do
         (( col[$2] < ${1} )) && col[$2]=${1}
         row[$2]="${col[$2]} ${2}" && shift 2
   done
   echo ${row[@]}
}

update()
{ 
   local coor
   coor="\e[${i};${j}H"
   (( map[index] == 0 )) && printf "${coor}  " || printf "${coor}\e[${pam[index]}${unit}\e[0m"
}

replace()
{ 
   local uplink downlink
   ((downlink=(j-toph)*width+u/2-toph))
   ((uplink=(j-toph-1)*width+u/2-toph))
   ((map[downlink]=map[uplink]))
   eval pam[downlink]=\"${pam[uplink]}\"
}

loop()
{
   local i j index
   for((i=toph+1; i<=height+toph; ++i)); do
        for((j=modw+1; j<=2*(width-1)+modw+1; j+=2)); do
             ((index=(i-toph-1)*width+j/2-toph))
             ${1}
        done
        ${2}  
   done
}

cycle()
{
   local u 
   for((u=modw+1; u<=2*(width-1)+modw+1; u+=2)); do
        ${1} 
   done
}

mappiece()
{
   (( j <= 2*(width-1)+modw+1 )) && continue
   ((++line))
   for((j=i-1; j>=toph+1; --j)); do
        cycle replace
   done
        cycle limit
}

preview()
{
   local vor clo clu i
   vor=(${!1})
   for((i=0; i!=${#vor[@]}; i+=2)); do
        ((clo=vor[i+1]-(${3}-hh)))
        smobox+="\e[$((vor[i]-1));${clo}H${unit}"
   done
   clu="${!2}" && printf "${clu//[]/  }\e[${!4}${smobox}\e[0m\n"
}

pipepiece()
{
   smobox=""
   (( ${5} != 0 )) && {
   radom
   eval ${1}="(${box[@]})"
   colpie="${coltab[RANDOM%${#coltab[@]}]}"
   eval ${6}=\"${colpie}\"
   preview box[@] ${3} ${4} colpie
   } || {
   eval ${1}="(${!2})"
   eval ${6}=\"${!7}\"
   preview ${2} ${3} ${4} ${7}
   }
   eval ${3}=\"${smobox}\"
}

invoke()
{
   local arya aryb aryc i
   arya=($(eval echo pvbox{1..${prelevel}}))
   for((i=0; i!=prelevel-1; ++i)); do
        aryb=(r${arya[i]} r${arya[i+1]}[@] ${arya[i]})
        aryc=($((12*(2-i))) ${1} s${aryb[0]} sr${arya[i+1]}) 
        pipepiece ${aryb[@]} ${aryc[@]} 
   done
}

showpiece()
{
   local smobox 
   colpie="${srpvbox1}"
   olbox=(${rpvbox1[@]})
   invoke ${#}
   smobox=""
   radom
   eval rpvbox${prelevel}="(${box[@]})"
   eval srpvbox${prelevel}=\"${coltab[RANDOM%${#coltab[@]}]}\"
   preview box[@] crsbox $(((3-prelevel)*12)) srpvbox${prelevel}
   crsbox="${smobox}"
   box=(${olbox[@]})
}

drawpiece()
{
   (( ${#} == 1 )) && {
      radom
      colpie="${coltab[RANDOM%${#coltab[@]}]}"
      coordinate box[@] shown 
   } || {
   colpie="${srpvbox1}"
   coordinate rpvbox1[@] shown 
   }
   oldpie="${cdn}"
   if ! movepiece locus; then
      kill -24 ${PPID}
      signa && quit
   fi
}

bmob()
{
   local x y
   set -- ${vor[@]}
   x=${1} && y=${2} && shift 2
   while (( ${#} != 0 )); do
         if (( x >= ${1} )); then 
            x=${1} && ((y=y>${2}?${2}:y))
         fi
         shift 2
   done
   echo ${x} ${y} ${x} $((y+6)) $((x+3)) ${y} $((x+3)) $((y+6))
}

bomb()
{
   local j p q scn vor sbos index boolp boolq
   sbos="\040\040"
   vor=(x-1 y-2 x-1 y x-1 y+2 x y-2 x y x y+2 x+1 y-2 x+1 y x+1 y+2)
   for((j=0; j!=${#vor[@]}; j+=2)); do
        ((p=vor[j])) && ((q=vor[j+1]))
        ((index=(p-toph-1)*width+q/2-toph))
        boolp="p > toph && p <= height+toph"
        boolq="q <= 2*width+modw && q > modw"
        if (( boolp && boolq )); then
              scn+="\e[${p};${q}H${sbos}"
              initi 
        fi
   done
   sleep 0.03 && printf "${scn}\n"
} 

delrow()
{
   local i x y len index line vor
   vor=(${locus})
   len=${#vor[@]}
   (( len == 16 )) && vor=($(bmob))
   for((i=0; i!=${#vor[@]}; i+=2)); do
        ((x=vor[i])) && ((y=vor[i+1]))
        (( len == 16 )) && bomb || {
           ((index=(x-toph-1)*width+y/2-toph))
           ((map[index]=1))
           pam[index]="${colpie}"
        }
   done
   line=0 && loop check mappiece
   (( line == 0 )) && return
   printf "\e[1;34m\e[$((toph+10));$((hh+36))H$((scorelevel+=line*200-100))\e[0m\n"
   (( scorelevel%5000 < line*200-100 && speedlevel < 20 )) && printf "\e[1;34m\e[$((toph+10));$((hh+24))H$((++speedlevel))\e[0m\n"
   loop update
}        

gettime()
{
   local i d h m s vir Time color
   trap "quit" 24 
   ((d=0, h=0, m=0, s=0))
   vir=----------------
   color="\e[1;33m"
   printf "\e[2;6H${color}${vir}[\e[2;39H${color}]${vir}\e[0m\n"
   while :; do
         sleep 1 &
         stime s 60 m && stime m 60 h && stime h 24 d
         for i in d h m s; do
             (( $(eval echo \${#${i}}) != 2 )) && Time[i]="0${!i}" || Time[i]="${!i}"
         done    
         printf "\e[2;23H${color}Time ${Time[d]}:${Time[h]}:${Time[m]}:${Time[s]}\e[0m\n"
         wait && ((++s))
   done
}
 
persig()
{
   local sigswap pid i j
   pid=${1} 
   for i in {25..31}; do
       trap "sig=${i}" ${i}
   done
   trap "signa; quit" 24
   while :; do
         for ((j=0; j!=30-speedlevel; ++j)); do
              sleep 0.02
              sigswap=${sig}
              sig=0
              case ${sigswap} in
              25)  transform -1                   ;;
              26)  transform  1                   ;;
              27)  transform  0 -2                ;;
              28)  transform  0  2                ;;
              29)  transform  1  0                ;;
              30)  transform -1  0                ;;
              31)  transform $(value $(bottom)) 0 ;;
              esac
         done
         transform 1  0
   done
}

getsig()
{
   local pid key arry pool oldtty sig
   pid=${1} && arry=(0 0 0)
   pool="$(printf "\e")" && oldtty="$(stty -g)"
   trap "quit 0" INT TERM && trap "quit 0 0" 24
   printf "\e[?25l"
   while read -s -n 1 key; do
         arry[0]=${arry[1]} && arry[1]=${arry[2]}
         arry[2]=${key} && sig=0
         if   [[ "[${key}]" == "${unit}" ]]; then sig=31      
         elif [[ "${key}${arry[1]}" == "${pool}${pool}" ]]; then quit 0
         elif [[ "${arry[0]}" == "${pool}" && "${arry[1]}" == "[" ]]; then
                 case ${key} in
                 A)    sig=25         ;;
                 B)    sig=29         ;;
                 D)    sig=27         ;;
                 C)    sig=28         ;;
                 esac
         else
                 case ${key} in
                 W|w)  sig=25         ;;
                 T|t)  sig=26         ;;
                 S|s)  sig=29         ;;
                 A|a)  sig=27         ;;
                 D|d)  sig=28         ;; 
                 U|u)  sig=30         ;; 
                 P|p)  pause ${pid} 0 ;;
                 R|r)  pause ${pid} 1 ;;
                 Q|q)  quit 0         ;;
                 esac
         fi
                 (( sig != 0 )) && kill -${sig} ${pid}
   done
}

bottom()
{  
   local i j max col row 
   max=($(lowerside))
   for((i=0; i!=height; ++i)); do
        for((j=0; j!=${#max[@]}; j+=2)); do 
             row="max[j]+i == height+toph"
             col="map[(max[j]+i-toph)*width+max[j+1]/2-toph] == 1"
             (( col || row )) && return ${i}
        done 
   done
}

movepiece()
{
   local i j x y vor index boolx booly 
   vor=(${!1})
   len=${#vor[@]}
   for((i=0; i!=${#vor[@]}; i+=2)); do    
        ((x=vor[i]+dx)) && ((y=vor[i+1]+dy))
        ((index=(x-toph-1)*width+y/2-toph))
        (( index < 0 || index > 749 )) && return 1
        boolx="x <= toph || x > height+toph"
        booly="y > 2*width+modw || y <= modw"
        (( boolx || booly )) && return 1
        if (( map[index] == 1 )); then
              if (( len == 2 )); then
                    for((j=height+toph; j>x; --j)); do
                         (( map[(j-toph-1)*width+y/2-toph] == 0 )) && return 0
                    done
              fi
              return 1
        fi
   done 
   return 0  
}

cross()
{
   local i j one index
   one=(${locus})
   ((i=one[0]))
   ((j=one[1]))
   ((index=(i-toph-1)*width+j/2-toph))
   (( map[index] == 1 )) && printf "\e[${i};${j}H\e[${pam[index]}${unit}\e[0m\n"
}

coordinate()
{
   local i sup vor
   vor=(${!1})
   for((i=0; i!=${#vor[@]}; i+=2)); do    
        cdn+="\e[${vor[i]};${vor[i+1]}H${unit}"
        sup+="${vor[i]} ${vor[i+1]} "
   done
   ${2} 
}

optimize()
{
   for j in dx dy; do
       if (( j != 0 )); then
             case ${j} in
                  dx) k=i   ;;
                  dy) k=i+1 ;;
             esac
             ${1}
       fi
   done
}

addbox()
{
   for((i=0; i!=${#box[@]}; i+=2)); do
        ((box[k]+=j))
   done
}

increment()
{
   local i j
   optimize addbox
   coordinate box[@] shown
   box=(${locus})
}

move()
{
   if movepiece locus; then
        erase
        (( len == 2 )) && cross
        increment
   else
        (( dx == 1 )) && {
        delrow  
        drawpiece 
        showpiece
        }
   fi
}

midpoint()
{
   local mid
   mid=(${!1})
   (( ${#mid[@]}%4 == 0 )) && point ${2} ${3} + || point ${3} ${2} -
}

multiple()
{
   local x y vor newy oldx oldy
   vor=(${!1})
   for((i=0; i!=${#vor[@]}; i+=2)); do
        ((x=vor[i])) && ((y=vor[i+1]))
        ${2} ${3} "${4}"
        ((newy=y)) && ((oldx=vor[i])) && ((oldy=vor[i+1]))    
   done 
}

algorithm()
{
   local row col 
   for((i=0; i!=${#vbox[@]}; i+=2)); do # row=(x-m)*zoomx*cos(a)-(y-n)*zoomy*sin(a)+m
        ((row=m+vbox[i+1]-n))           # col=(x-m)*zoomx*sin(a)+(y-n)*zoomy*cos(a)+n
        ((col=(vbox[i]-m)*dx+n))        # a=-pi/2 zoomx=+1 zoomy=+1 dx=0 dy=0 
        mbox+="${row} ${col} "          # a=-pi/2 zoomx=-1 zoomy=+1 dx=0 dy=0
   done                                 # a=+pi/2 zoomx=+1 zoomy=-1 dx=0 dy=0
}

boxadd()
{
   for((i=0; i!=${#tbox[@]}; i+=2)); do
        ((tbox[k]+=j))
   done
}

vector()
{
   local i j k dx dy
   ((dx=mp-p))
   ((dy=nq-q))
   optimize boxadd
}

abstract()
{
   multiple ${1} ${2} ${3} "${4}"
   eval ${3}="(${!3})"
   midpoint ${3}[@] ${5} ${6} 
}

rotate()
{     
   local m n p q mp nq tbox mbox vbox kbox 
   (( arg == 2 )) && return
   midpoint box[@] mp nq 
   abstract box[@]  convert vbox "/" m n
   algorithm && mbox=(${mbox}) && dx=0
   abstract mbox[@] convert tbox "*" p q
   vector && coordinate tbox[@] coord
   if movepiece kbox; then
       erase && locus="${kbox}"
       ptbox && box=(${kbox})
   fi
}

transform()
{ 
   local dx dy cdn len arg 
   dx=${1}
   dy=${2}
   arg=${#}
   (( arg == 2 )) && move || rotate 
}

matrix()
{
   one=" "
   sr="\e[0m"
   two="${one}${one}"
   tre="${one}${two}"
   cps="${two}${tre}"
   spc="${cps}${cps}"         
   colbon="\e[1;36m"
   mcol="\e[1;33;40m"
   trx="${unit}${unit}"
   fk0="${colbon}${unit}${sr}"
   fk1="${colbon}${trx}${sr}"
   fk2="${colbon}${unit}${trx}${sr}"
   fk3="${colbon}${trx}${trx}${sr}"
   fk4="${mcol}${unit}${sr}"
   fk5="${spc}${spc}"
   fk6="${mcol}${unit}${trx}${sr}"
   fk="${tre}${fk0}${two}${fk3}${two}${fk3}"
   fk7="${fk1}${one}${fk1}${fk}${fk4}${two}${two}"
   fk8="${fk0}${one}row${one}${fk0}${tre}${fk0}${two}${fk0}${one}(x-m)*zoomx${two}"
   fk9="${one}=${one}${fk0}${two}${fk0}${spc}${tre}${one}${fk0}${tre}*${two}"
   fk10="${spc}${cps}${two}${fk0}${two}${fk0}${one}+${one}${fk0}${cps}${fk0}"
   fk11="${tre}${one}${fk0}${two}cos(a)${one}sin(a)${two}${fk0}${two}${fk0}${tre}${fk0}${two}m${two}${fk0}"
   fk12="${one}col${one}${fk0}${tre}${fk0}${two}${fk0}${one}(y-n)*zoomy${two}${fk0}${cps}${one}"
   fk13="${one}-sin(a)${one}cos(a)${two}${fk0}${two}${fk0}${tre}${fk0}${two}n${two}${fk0}"
   fk14="${fk1}${one}${fk1}${fk}${cps}${one}"
   fk15="${fk1}${two}${fk0}${tre}${fk1}${one}${fk1}"
   printf "\e[$((toph+23));${hh}HAlgorithm:${sr}${two}${fk2}${one}${fk5}${fk5}${fk2}${fk4}\n"
   printf "\e[$((toph+30));${hh}H${spc}${two}${fk0}${two}${two}${cps}${fk5}${fk5}${fk0}\n"
   printf "\e[$((toph+25));${hh}H${fk7}${fk1}${spc}${tre}${fk1}${two}${fk0}${tre}${fk1}${one}${fk1}\n"
   printf "\e[$((toph+26));${hh}H${fk8}${fk0}${fk4}${fk11}\e[$((toph+28));${hh}H${fk0}${fk12}${fk0}${fk13}\n"
   printf "\e[$((toph+24));${hh}H${two}${spc}${fk0}${spc}${tre}${two}${tre}${fk6}${fk5}${cps}${fk0}${fk4}\n"
   printf "\e[$((toph+22));${hh}H${tre}${fk5}${fk5}${fk5}${fk6}\e[$((toph+29));${hh}H${fk14}${fk1}${spc}${tre}${fk15}\n"
   printf "\e[$((toph+27));${hh}H${fk0}${cps}${fk0}${fk9}${fk0}${fk10}\e[$((toph+31));${hh}H${spc}${two}${fk2}${fk5}${fk5} ${fk2}\n"
}

boundary()
{
   clear
   boucol="\e[1;36m"
   for((i=modw+1; i<=2*width+modw; i+=2)); do
        printf "${boucol}\e[${toph};${i}H==\e[$((height+toph+1));${i}H==\e[0m\n"
   done
   for((i=toph; i<=height+toph+1; ++i)); do
        printf "${boucol}\e[${i};$((modw-1))H||\e[${i};$((2*width+modw+1))H||\e[0m\n"
   done
}

instruction()
{
   printf "\e[1;31m\e[$((toph+9));${hh}HRunLevel\e[1;31m\e[$((toph+9));$((hh+10))HPreviewLevel\e[0m\n"
   printf "\e[1;31m\e[$((toph+9));$((hh+24))HSpeedLevel\e[1;31m\e[$((toph+9));$((hh+36))HScoreLevel\e[0m\n"
   printf "\e[1;34m\e[$((toph+10));$((hh+36))H${scorelevel}\e[1;34m\e[$((toph+10));$((hh+24))H${speedlevel}\e[0m\n"
   printf "\e[1;34m\e[$((toph+10));${hh}H$((runlevel-1))\e[1;34m\e[$((toph+10));$((hh+10))H${prelevel}\e[0m\n"
   printf "\e[$((toph+13));${hh}HQ|q|ESC  ===   exit           U|u          ===   one step up\n"
   printf "\e[$((toph+14));${hh}HP|p      ===   pause          S|s|down     ===   one step down\n"
   printf "\e[$((toph+15));${hh}HR|r      ===   resume         A|a|left     ===   one step left\n"
   printf "\e[$((toph+16));${hh}HW|w|up   ===   rotate         D|d|right    ===   one step right\n"
   printf "\e[$((toph+17));${hh}HT|t      ===   transpose      Space|enter  ===   drop all down\n"
   printf "\e[1;36m\e[$((toph+19));${hh}HTetris Game  Version 6.0\n"
   printf "\e[$((toph+20));${hh}HYongYe <expertshell@gmail.com>\e[$((toph+21));${hh}H11/01/2011 BeiJing China [Updated 04/18/2012]\n"
}

     case ${1} in
     -h|--help)    echo "Usage: bash ${0} [runlevel] [previewlevel] [speedlevel]"
                   echo "Range: [ 0 =< runlevel <= 30 ]   [ previewlevel >= 1 ]   [ speedlevel <= 30 ]" ;;
     -v|--version) echo "Tetris Game  Version 6.0" ;;
     ${PPID})      getrunlevel ${2} && loop initi 
                   boundary && instruction
                   showpiece 0 && drawpiece 0
                   matrix && gettime &
                   persig ${!} ;;
     *)            bash ${0} ${$} ${1} ${2} ${3} &
                   getsig ${!} ;;
     esac
Attached Files
File Type: txt Tetris_Game.txt (18.0 KB, 67 views)

Last edited by crulat; 04-17-2012 at 12:21 PM.
 
Old 11-03-2011, 08:39 AM   #2
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Your effort is quite impressive. Sadly, after a short period of play, I got a repeated series of error messages, followed by a process termination:
Code:
./tetris.sh: cannot make pipe for process substitution: Too many open files
./tetris.sh: cannot make pipe for process substitution: Too many open files
./tetris.sh: line 258: <(echo ${!1} | xargs -n 2 | sort -n -k1): ambiguous redirect
./tetris.sh: cannot make pipe for command substitution: Too many open files
I was running 'GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)' on a Debian 6 host.

I will find it interesting to study your code, as I've never seen a shell script operate in such an interactive way.

--- rod.
 
Old 11-03-2011, 09:04 AM   #3
Juako
Member
 
Registered: Mar 2010
Posts: 202

Rep: Reputation: 84
Mad props!

I'm quite pleased with seeing this kind of stuff in bash. I'm too inclined to think about games and other seemingly "unrealizable" things written in it, "for the lulz", because of the challenge, and to bother all those people that always whine "use another laaanguaaaaage" . I hope to take some time whenever I can to help enhance the program. One thing that would be cool to add is dual mode playing, you know like the original Tetris where two players had half screen. Was fun hehehe.

Didn't look in depth, but more or less how many processes are running while the game is playing? And also, at a glance, I see you use few parameter substitutions, arguably your best chance in bash at minimizing calls to external programs (if that would be absolutely necessary though, I'll probably calling "sed"). Perhaps some tweaking in some of the multi-pipe lines might speed it up a little, and be related to the "many open files" ?

Also, can you write a bit on your approaches, and any tricky parts (any amount would be helpful) to speed up grasping the script?

Last edited by Juako; 11-03-2011 at 09:06 AM.
 
Old 11-03-2011, 09:25 AM   #4
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Original Poster
Rep: Reputation: Disabled
My script is the shell version of the classic Tetris Game!
It runs pretty well under Fedora15, and you can see the screenshot from the link that i have already given above:

http://bbs.chinaunix.net/thread-3614425-1-1.html
 
Old 11-03-2011, 09:37 AM   #5
Juako
Member
 
Registered: Mar 2010
Posts: 202

Rep: Reputation: 84
Quote:
Originally Posted by crulat View Post
My script is the shell version of the classic Tetris Game!
Yes, that it think was clear from the beginning...
Quote:
It runs pretty well under Fedora15, and you can see the screenshot from the link that i have already given above:
http://bbs.chinaunix.net/thread-3614425-1-1.html
Perhaps a different Bash version?
 
Old 11-03-2011, 10:04 AM   #6
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Juako View Post
Mad props!

I'm quite pleased with seeing this kind of stuff in bash. I'm too inclined to think about games and other seemingly "unrealizable" things written in it, "for the lulz", because of the challenge, and to bother all those people that always whine "use another laaanguaaaaage" . I hope to take some time whenever I can to help enhance the program. One thing that would be cool to add is dual mode playing, you know like the original Tetris where two players had half screen. Was fun hehehe.

Didn't look in depth, but more or less how many processes are running while the game is playing? And also, at a glance, I see you use few parameter substitutions, arguably your best chance in bash at minimizing calls to external programs (if that would be absolutely necessary though, I'll probably calling "sed"). Perhaps some tweaking in some of the multi-pipe lines might speed it up a little, and be related to the "many open files" ?

Also, can you write a bit on your approaches, and any tricky parts (any amount would be helpful) to speed up grasping the script?
There are two processes running while the game is playing:
bash $0 0 &--the one that running in the background, and
getsig $!--the one that running in the current shell, this function takes the $! as the parameter and it sends the input signals to the processes that running in the background, this is the way that the two processes communicate!
My laptop is running Fedora15, and this script runs pretty well under it,the multi-pipe lines are most needed and
necessary; in fact i have optimized my script as much as possible, as you can see that i have used so many function invocations, that is to say, the matter that result in "many open files" is mainly due to the distro of you Linux, not the
multi-pipe lines! For a better way to speed up the script, i know ,and i'm trying!
I'll add a detailed comments to the code when i'm free!

Last edited by crulat; 11-03-2011 at 08:53 PM.
 
Old 11-03-2011, 08:56 PM   #7
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Original Poster
Rep: Reputation: Disabled
I made some changes to the source code just now!
 
Old 11-11-2011, 07:39 AM   #8
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Original Poster
Rep: Reputation: Disabled
Tetris Game Version 2.0 Beta1 released
 
Old 11-11-2011, 07:45 AM   #9
Juako
Member
 
Registered: Mar 2010
Posts: 202

Rep: Reputation: 84
Hey the code looks so much better this time! Bet that it runs way smoother than version 1. Congrats man! Still haven't found the time to play with the code, but I definitely want to.
 
Old 11-11-2011, 10:01 PM   #10
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Original Poster
Rep: Reputation: Disabled
I have the source code optimized once again just now!
 
Old 11-12-2011, 04:10 PM   #11
lyle_s
Member
 
Registered: Jul 2003
Distribution: Slackware
Posts: 392

Rep: Reputation: 55
Amazing!

I always marveled at what could be done in sh, but this opened my eyes!

I ran
Code:
ulimit -n30000
before running it to avoid the too many open files errors.

After a while of having my mind blown, I started to get this:

Code:
./tetris: line 590: warning: run_pending_traps: bad value in trap_list[26]: (nil)
./tetris: line 590: warning: run_pending_traps: signal handler is SIG_DFL, resending 26 (SIGVTALRM) to myself
Still, amazing work!

Lyle.
 
Old 11-12-2011, 09:33 PM   #12
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Original Poster
Rep: Reputation: Disabled
Just run the script this way:
Code:
bash Tetris_Game.sh
The errors showed below:
Code:
./tetris: line 590: warning: run_pending_traps: bad value in trap_list[26]: (nil)
./tetris: line 590: warning: run_pending_traps: signal handler is SIG_DFL, resending 26 (SIGVTALRM) to myself
is really a bug that i'm trying my best to fix it!
The code below:
Code:
concxy()
{
   local x y sup 
   while read x y
   do    
       cdn="${cdn}\e[${x};${y}H${mrx}"
       sup="${sup} ${x} ${y}"
   done < <(srbox ${1})
   ${2}
}
is mainly the reason that result in the errors occurred while i running the script!
But, it seems nothing wrong with those code, as i have debugged it so much!
Any good solutions that can fix the bug will be appreciated!
I need all your participation!
Join me, why not?
 
Old 11-13-2011, 05:56 AM   #13
Juako
Member
 
Registered: Mar 2010
Posts: 202

Rep: Reputation: 84
Quote:
Originally Posted by crulat View Post
Join me, why not?
Some (I for an example) really whish, but don't have the time to intepret a respectable amount of uncommented code with nondescriptive identifiers: no function or var gives a clue about anything! And some functions are "one-lined".

Why don't you make your code friendlier? It won't impact in performance. That way you'll encourage participation.
 
1 members found this post helpful.
Old 11-16-2011, 05:09 AM   #14
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Original Poster
Rep: Reputation: Disabled
Tetris Game Version 2.0 Beta2 is available now!
 
Old 11-20-2011, 08:05 PM   #15
crulat
Member
 
Registered: Sep 2011
Location: BeiJing China
Posts: 34

Original Poster
Rep: Reputation: Disabled
Tetris Game Version 2.0 Beta3 released!
Features:
1.Bomb is enabled(ID=2)!
2.Customization is enabled under the given value range of coordinates!
3.Various kinds of color(64 kinds of color are available for randomly choose)!
4.Support 4-level preview(can preview the next 4 pieces generated randomly)!
The final version is coming soon!

Last edited by crulat; 02-27-2012 at 08:41 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
shell script to remove old files based on date WindozBytes Linux - General 12 06-04-2012 01:21 AM
wxWidgets on CodeBlock:Tetris Game - cannot find -lwxmsw_core stefanolima Programming 1 01-10-2010 01:14 AM
An question about tethereal.【relink】 operand Linux - Newbie 0 12-21-2005 07:10 PM
shell script version of round robin algorithm vishamr2000 Linux - Security 0 05-19-2005 04:45 AM
a small game design algorithm feetyouwell Programming 4 03-23-2004 03:08 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:16 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration