Nombre: Space.bash
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