Created
          August 7, 2017 22:53 
        
      - 
      
 - 
        
Save john-science/889ccf1959282c5623c8e699864cfa70 to your computer and use it in GitHub Desktop.  
Revisions
- 
        
john-science created this gist
Aug 7, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,265 @@ #!/bin/bash # # Centipede game # # v2.0 # # Author: [email protected] # # Functions drawborder() { # Draw top tput setf 6 tput cup $FIRSTROW $FIRSTCOL x=$FIRSTCOL while [ "$x" -le "$LASTCOL" ]; do printf %b "$WALLCHAR" x=$(( $x + 1 )); done # Draw sides x=$FIRSTROW while [ "$x" -le "$LASTROW" ]; do tput cup $x $FIRSTCOL; printf %b "$WALLCHAR" tput cup $x $LASTCOL; printf %b "$WALLCHAR" x=$(( $x + 1 )); done # Draw bottom tput cup $LASTROW $FIRSTCOL x=$FIRSTCOL while [ "$x" -le "$LASTCOL" ]; do printf %b "$WALLCHAR" x=$(( $x + 1 )); done tput setf 9 } apple() { # Pick coordinates within the game area APPLEX=$[( $RANDOM % ( $[ $AREAMAXX - $AREAMINX ] + 1 ) ) + $AREAMINX ] APPLEY=$[( $RANDOM % ( $[ $AREAMAXY - $AREAMINY ] + 1 ) ) + $AREAMINY ] } drawapple() { # Check we haven't picked an occupied space LASTEL=$(( ${#LASTPOSX[@]} - 1 )) x=0 apple while [ "$x" -le "$LASTEL" ]; do if [ "$APPLEX" = "${LASTPOSX[$x]}" ] && [ "$APPLEY" = "${LASTPOSY[$x]}" ]; then # Invalid coords... in use x=0 apple else x=$(( $x + 1 )) fi done tput setf 4 tput cup $APPLEY $APPLEX printf %b "$APPLECHAR" tput setf 9 } growsnake() { # Pad out the arrays with oldest position 3 times to make snake bigger LASTPOSX=( ${LASTPOSX[0]} ${LASTPOSX[0]} ${LASTPOSX[0]} ${LASTPOSX[@]} ) LASTPOSY=( ${LASTPOSY[0]} ${LASTPOSY[0]} ${LASTPOSY[0]} ${LASTPOSY[@]} ) RET=1 while [ "$RET" -eq "1" ]; do apple RET=$? done drawapple } move() { case "$DIRECTION" in u) POSY=$(( $POSY - 1 ));; d) POSY=$(( $POSY + 1 ));; l) POSX=$(( $POSX - 1 ));; r) POSX=$(( $POSX + 1 ));; esac # Collision detection ( sleep $DELAY && kill -ALRM $$ ) & if [ "$POSX" -le "$FIRSTCOL" ] || [ "$POSX" -ge "$LASTCOL" ] ; then tput cup $(( $LASTROW + 1 )) 0 stty echo echo " GAME OVER! You hit a wall!" gameover elif [ "$POSY" -le "$FIRSTROW" ] || [ "$POSY" -ge "$LASTROW" ] ; then tput cup $(( $LASTROW + 1 )) 0 stty echo echo " GAME OVER! You hit a wall!" gameover fi # Get Last Element of Array ref LASTEL=$(( ${#LASTPOSX[@]} - 1 )) #tput cup $ROWS 0 #printf "LASTEL: $LASTEL" x=1 # set starting element to 1 as pos 0 should be undrawn further down (end of tail) while [ "$x" -le "$LASTEL" ]; do if [ "$POSX" = "${LASTPOSX[$x]}" ] && [ "$POSY" = "${LASTPOSY[$x]}" ]; then tput cup $(( $LASTROW + 1 )) 0 echo " GAME OVER! YOU ATE YOURSELF!" gameover fi x=$(( $x + 1 )) done # clear the oldest position on screen tput cup ${LASTPOSY[0]} ${LASTPOSX[0]} printf " " # truncate position history by 1 (get rid of oldest) LASTPOSX=( `echo "${LASTPOSX[@]}" | cut -d " " -f 2-` $POSX ) LASTPOSY=( `echo "${LASTPOSY[@]}" | cut -d " " -f 2-` $POSY ) tput cup 1 10 #echo "LASTPOSX array ${LASTPOSX[@]} LASTPOSY array ${LASTPOSY[@]}" tput cup 2 10 echo "SIZE=${#LASTPOSX[@]}" # update position history (add last to highest val) LASTPOSX[$LASTEL]=$POSX LASTPOSY[$LASTEL]=$POSY # plot new position tput setf 2 tput cup $POSY $POSX printf %b "$SNAKECHAR" tput setf 9 # Check if we hit an apple if [ "$POSX" -eq "$APPLEX" ] && [ "$POSY" -eq "$APPLEY" ]; then growsnake updatescore 10 fi } updatescore() { SCORE=$(( $SCORE + $1 )) tput cup 2 30 printf "SCORE: $SCORE" } randomchar() { [ $# -eq 0 ] && return 1 n=$(( ($RANDOM % $#) + 1 )) eval DIRECTION=\${$n} } gameover() { tput cvvis stty echo sleep $DELAY trap exit ALRM tput cup $ROWS 0 exit } ###########################END OF FUNCS########################## # Prettier characters but not supported # by all termtypes/locales #SNAKECHAR="\0256" # Character to use for snake #WALLCHAR="\0244" # Character to use for wall #APPLECHAR="\0362" # Character to use for apples # # Normal boring ASCII Chars SNAKECHAR="@" # Character to use for snake WALLCHAR="X" # Character to use for wall APPLECHAR="o" # Character to use for apples # SNAKESIZE=3 # Initial Size of array aka snake DELAY=0.2 # Timer delay for move function FIRSTROW=3 # First row of game area FIRSTCOL=1 # First col of game area LASTCOL=40 # Last col of game area LASTROW=20 # Last row of game area AREAMAXX=$(( $LASTCOL - 1 )) # Furthest right play area X AREAMINX=$(( $FIRSTCOL + 1 )) # Furthest left play area X AREAMAXY=$(( $LASTROW - 1 )) # Lowest play area Y AREAMINY=$(( $FIRSTROW + 1)) # Highest play area Y ROWS=`tput lines` # Rows in terminal ORIGINX=$(( $LASTCOL / 2 )) # Start point X - use bc as it will round ORIGINY=$(( $LASTROW / 2 )) # Start point Y - use bc as it will round POSX=$ORIGINX # Set POSX to start pos POSY=$ORIGINY # Set POSY to start pos # Pad out arrays ZEROES=`echo |awk '{printf("%0"'"$SNAKESIZE"'"d\n",$1)}' | sed 's/0/0 /g'` LASTPOSX=( $ZEROES ) # Pad with zeroes to start with LASTPOSY=( $ZEROES ) # Pad with zeroes to start with SCORE=0 # Starting score clear echo " Keys: W - UP S - DOWN A - LEFT D - RIGHT X - QUIT If characters do not display properly, consider changing SNAKECHAR, APPLECHAR and WALLCHAR variables in script. Characters supported depend upon your terminal setup. Press Return to continue " stty -echo tput civis read RTN tput setb 0 tput bold clear drawborder updatescore 0 # Draw the first apple on the screen # (has collision detection to ensure we don't draw # over snake) drawapple sleep 1 trap move ALRM # Pick a random direction to start moving in DIRECTIONS=( u d l r ) randomchar "${DIRECTIONS[@]}" sleep 1 move while : do read -s -n 1 key case "$key" in w) DIRECTION="u";; s) DIRECTION="d";; a) DIRECTION="l";; d) DIRECTION="r";; x) tput cup $COLS 0 echo "Quitting..." tput cvvis stty echo tput reset printf "Bye Bye!\n" trap exit ALRM sleep $DELAY exit 0 ;; esac done