Autor: Steve Parker.
Descripción: Script que emula el famoso juego de 1978.
Visto en nixshell
Y el libro Shell Scripting de Steve Parker, Capítulo 17. Página 464.
#!/bin/bash stty -echo tput civis clear cat - << EOF SPACE LEFT: a RIGHT: l FIRE: f QUIT: q Press any key. EOF read -s -n 1 row0=( 0 30 30 30 30 30 30 30 30 ) row1=( 0 20 20 20 20 20 20 20 20 ) row2=( 0 15 15 15 15 15 15 15 15 ) row3=( 0 10 10 10 10 10 10 10 10 ) row4=( 0 5 5 5 5 5 5 5 5 ) row5=( 0 1 1 1 1 1 1 1 1 ) aliens1=( '\033[1;32m|0|\033[0m' '\033[1;34m\-/\033[0m' '\033[1;35m:x:\033[0m' '\033[1;38m:#:\033[0m' '\033[1;33m!|!\033[0m' '\033[1;39m:-:\033[0m' ) aliens2=( '\033[1;32m:0:\033[0m' '\033[1;34m/-\\\033[0m' '\033[1;35m-x-\033[0m' '\033[1;38m-#-\033[0m' '\033[1;33m:|:\033[0m' '\033[1;39m-:-\033[0m' ) score=0 # farthest right that the *leftmost* alien can go to MAXRIGHT=46 # furthest right that the ship can go to FARRIGHT=73 # Ship's current position (x-axis) ship=30 # Cannon column; remains the same even if ship moves cannonX=$ship # Cannon height; 0 means it's ready to fire cannonY=0 # Positive direction to right, Negative to left direction=1 offset=20 bottom=20 ceiling=4 MAXCEILING=6 DELAY=0.4 drawrow() { # draw a row of aliens; return the index of any alien killed # note that only one alien can be killed at any time. alientype=$1 shift let row="$alientype * 2 + $ceiling" aliensonrow=`echo $@ | tr ' ' '+' | bc` if [ $aliensonrow -eq 0 ]; then # Nothing to do here. In particular, do not detect failure. # Just clear the previous line (it may contain the final explosion # on that row) and return. tput cup $row 0 printf "%80s" " " return 0 fi if [ $row -eq $bottom ]; then tput cup `expr $bottom - 4` 6 trap exit ALRM clear echo "YOU LOSE" sleep $DELAY stty echo tput cnorm exit 1 fi declare -a thisrow thisrow=( `echo $@` ) tput cup 0 0 printf "Score: %-80d" $score killed=0 # Clear the previous line tput cup `expr $row - 1` 0 printf "%80s" " " tput cup $row 0 printf "%80s" " " tput cup $row 0 printf "%-${offset}s" # Don't do this calculation in the for loop, it is slow even without expr if (( $offset % 2 == 0 )); then thisalien=${aliens1[$alientype]} else thisalien=${aliens2[$alientype]} fi # there are 8 aliens per row. for i in `seq 1 8` do value=${thisrow[$i]} avatar=$thisalien if [ $value -gt 0 ]; then # detect and mark a collision if [ $row -eq $cannonY ]; then let LEFT="$i * 4 + $offset - 4" let RIGHT="$i * 4 + $offset - 1" if [ $cannonX -ge $LEFT ] && [ $cannonX -le $RIGHT ]; then killed=$i avatar='\033[1;31m***\033[0m' ((score=$score + $value)) cannonY=0 fi fi fi if [ $value -eq 0 ]; then printf " " else echo -en "${avatar} " fi done return $killed } drawcannon() { # move the cannon up one if [ $cannonY -eq 0 ]; then # fell off the top of the screen return fi tput cup $cannonY $cannonX printf " " ((cannonY=cannonY-1)) tput cup $cannonY $cannonX echo -en "\033[1;31m*\033[0m" } drawship() { tput cup $bottom 0 printf "%80s" " " tput cup $bottom $ship # Show cannon state by its color in the spaceship if [ $cannonY -eq 0 ]; then col=31 else col=30 fi echo -en "|--\033[1;${col}m*\033[0m--|" } move() { # shift aliens left or right # move cannon, check for collision (sleep $DELAY && kill -ALRM $$) & # Change direction if hit the side of the screen if [ $offset -gt $MAXRIGHT ] && [ $direction -eq 1 ]; then # speed up if hit the right side of the screen DELAY=`echo $DELAY \* 0.90 | bc` direction=-1 ((ceiling++)) elif [ $offset -eq 0 ] && [ $direction -eq -1 ]; then direction=1 fi ((offset=offset+direction)) drawrow 0 ${row0[@]} row0[$?]=0 drawrow 1 ${row1[@]} row1[$?]=0 drawrow 2 ${row2[@]} row2[$?]=0 drawrow 3 ${row3[@]} row3[$?]=0 drawrow 4 ${row4[@]} row4[$?]=0 drawrow 5 ${row5[@]} row5[$?]=0 aliensleft=`echo ${row0[@]} ${row1[@]} ${row2[@]} ${row3[@]}\ ${row4[@]} ${row5[@]} \ | tr ' ' '+' | bc` if [ $aliensleft -eq 0 ]; then tput cup 5 5 trap exit ALRM echo "YOU WIN" sleep $DELAY #tput echo tput cnorm echo; echo; echo exit 0 fi drawcannon drawship } trap move ALRM clear drawship # Start the aliens moving... move while : do read -s -n 1 key case "$key" in a) [ $ship -gt 0 ] && ((ship=ship-1)) drawship ;; l) [ $ship -lt $FARRIGHT ] && ((ship=ship+1)) drawship ;; f) if [ $cannonY -eq 0 ]; then let cannonX="$ship + 3" cannonY=$bottom fi ;; q) clear echo "Goodbye!" tput cnorm stty echo trap exit ALRM sleep $DELAY exit 0 ;; esac done
Permisos: chmod 700 space.bash
Ejecución: ./space.bash
Movimientos del juego LEFT: a
RIGHT: l
FIRE: f
QUIT: q
0 comentarios:
Publicar un comentario