#!/bin/bash
max_x=40
max_y=40
hx=20 hy=20
tx=20 ty=20
len=1
cur_len=0
need_food=1
level0=0.1
level1=0.05
level2=0.025
direct=u
input(){
echo -ne "\033[?25l"
local aKey=(0 0 0 0)
local cESC=`echo -ne "\033"`
local index
while :
do
read -s -n 1 key
aKey=( "${aKey[@]:1}" "$key")
if [[ $key${aKey[2]} = $cESC$cESC ]] ; then kill -29 $1; break
elif [[ "${aKey[@]:1:2}$key" = "${cESC} [A" ]] ; then kill -25 $1 ## direct=u
elif [[ "${aKey[@]:1:2}$key" = "${cESC} [B" ]] ; then kill -26 $1 ## direct=d
elif [[ "${aKey[@]:1:2}$key" = "${cESC} [C" ]] ; then kill -27 $1 ## direct=r
elif [[ "${aKey[@]:1:2}$key" = "${cESC} [D" ]] ; then kill -28 $1 ## direct=l
else continue
fi
done
echo -ne "\033[?25h"
}
draw_head(){
tput cup $2 $(( $1<<1 ))
echo -ne "\033[1;47m \033[m"
}
draw_tail(){
tput cup $2 $(( $1<<1 ))
echo -ne "\033[1;40m \033[m"
}
run(){
trap '[[ $direct != d ]] && direct=u' 25
trap '[[ $direct != u ]] && direct=d' 26
trap '[[ $direct != l ]] && direct=r' 27
trap '[[ $direct != r ]] && direct=l' 28
trap 'exit' 29
while :
do
eval "[[ \"\$m${hx}_${hy}\" = f ]] && (( ++len )) && need_food=1"
draw_head $hx $hy
eval m${hx}_${hy}=$direct
case $direct in
u) (( --hy )); (( hy < 0 )) && break ;;
d) (( ++hy )); (( hy > max_y )) && break ;;
r) (( ++hx )); (( hx > max_x )) && break ;;
l) (( --hx )); (( hx < 0 )) && break ;;
esac
eval "[ -n \"\${m${hx}_${hy}}\" -a ! \"\${m${hx}_${hy}}\" = f ] && break"
(( ++cur_len ))
if (( len < cur_len )) ; then
(( --cur_len ))
eval local d=\$m${tx}_${ty}
draw_tail $tx $ty
unset m${tx}_${ty}
case $d in
u) (( --ty ));;
d) (( ++ty ));;
r) (( ++tx ));;
l) (( --tx ));;
esac
fi
if [ $need_food = 1 ] ; then
draw_food && need_food=0
fi
sleep $level1
done
kill $1
}
draw_food(){
local fx=$(( $RANDOM % max_x + 1 ))
local fy=$(( $RANDOM % max_y + 1 ))
eval local f=\$m${fx}_${fy}
if [[ -z $f ]] ; then
tput cup $fy $(( $fx<<1 ))
eval m${fx}_${fy}=f
echo -ne "\033[1;45m \033[m"
return 0
fi
return 1
}
draw_wall(){
for (( i=0; i<=max_x; i++ ))
do
tput cup 0 $(( $i<<1 ))
eval m${i}_0=w
echo -ne "\033[1;46m \033[m"
done
for (( i=0; i<=max_x; i++ ))
do
eval m${i}_$max_y=w
tput cup $max_y $(( $i<<1 ))
echo -ne "\033[1;46m \033[m"
done
for (( j=0; j<=max_y; j++ ))
do
tput cup $j 0
echo -ne "\033[1;46m \033[m"
tput cup $j $(( max_x<<1 ))
echo -ne "\033[1;46m \033[m"
eval m0_$j=w m${max_x}_$j=w
done
}
clear
draw_wall
run $$&
input $!