LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   【Tetris Game -- based on a shell script】(new algorithm) (https://www.linuxquestions.org/questions/programming-9/tetris-game-based-on-a-shell-script-new-algorithm-911496/)

crulat 11-02-2011 10:35 AM

【Tetris Game -- based on a shell script】(new algorithm)
 
1 Attachment(s)
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


theNbomr 11-03-2011 08:39 AM

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.

Juako 11-03-2011 09:04 AM

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" :tisk:. 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?

crulat 11-03-2011 09:25 AM

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

Juako 11-03-2011 09:37 AM

Quote:

Originally Posted by crulat (Post 4514904)
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?

crulat 11-03-2011 10:04 AM

Quote:

Originally Posted by Juako (Post 4514882)
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" :tisk:. 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!

crulat 11-03-2011 08:56 PM

I made some changes to the source code just now!

crulat 11-11-2011 07:39 AM

Tetris Game Version 2.0 Beta1 released

Juako 11-11-2011 07:45 AM

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.

crulat 11-11-2011 10:01 PM

I have the source code optimized once again just now!

lyle_s 11-12-2011 04:10 PM

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.

crulat 11-12-2011 09:33 PM

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?

Juako 11-13-2011 05:56 AM

Quote:

Originally Posted by crulat (Post 4522636)
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.

crulat 11-16-2011 05:09 AM

Tetris Game Version 2.0 Beta2 is available now!

crulat 11-20-2011 08:05 PM

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!


All times are GMT -5. The time now is 11:44 AM.