一、走马灯版本贪吃蛇

#!/bin/bash
declare -i MAP_WIDTH=60
declare -i MAP_HIGHT=20
declare -i MAP_X=20
declare -i MAP_Y=5
declare -i X=30
declare -i Y=30
declare -i LENGTH=4
declare -a X_ARR=()
declare -a Y_ARR=()
declare -i RANDOM_X=0
declare -i RANDOM_Y=0
declare -i COLOR_INDEX=15
DIR='d'
score=0
function end_of_game() {
kill -9 $!
echo -e "\e[0m"
echo -e "\e[?25h"
exit 1
}
function init_map() {
for i in $(seq ${MAP_X} $((${MAP_X} + ${MAP_WIDTH}))); do
echo -e "\e[${MAP_Y};${i}H@\e[0m"
echo -e "\e[$((${MAP_Y} + ${MAP_HIGHT}));${i}H@\e[0m"
done
for j in $(seq ${MAP_Y} $((${MAP_Y} + ${MAP_HIGHT}))); do
echo -e "\e[${j};${MAP_X}H@\e[0m"
echo -e "\e[${j};$((${MAP_X} + ${MAP_WIDTH}))H@\e[0m"
done
}
function init_map_lamp() {
while true :; do
let COLOR_INDEX=15
for i in $(seq ${MAP_X} $((${MAP_X} + ${MAP_WIDTH}))); do
let COLOR_INDEX++
sleep 0.003
echo -e "\e[38;5;${COLOR_INDEX}m\e[${MAP_Y};${i}H@\e[0m"
done
for j in $(seq ${MAP_Y} $((${MAP_Y} + ${MAP_HIGHT}))); do
let COLOR_INDEX++
sleep 0.003
echo -e "\e[38;5;${COLOR_INDEX}m\e[${j};$((${MAP_X} + ${MAP_WIDTH}))H@\e[0m"
done
for ((k = $((${MAP_X} + ${MAP_WIDTH})); k >= ${MAP_X}; k--)); do
let COLOR_INDEX--
sleep 0.003
echo -e "\e[38;5;${COLOR_INDEX}m\e[$((${MAP_Y} + ${MAP_HIGHT}));${k}H@\e[0m"
done
for ((m = $((${MAP_Y} + ${MAP_HIGHT})); m >= ${MAP_Y}; m--)); do
let COLOR_INDEX--
sleep 0.003
echo -e "\e[38;5;${COLOR_INDEX}m\e[${m};${MAP_X}H@\e[0m"
done
done
}
function draw_snake() {
clear
for ((i = 1; i < ${LENGTH}; i++)); do
echo -e "\e[${Y_ARR[$i]};${X_ARR[$i]}H*\e[0m"
done
echo -e "\e[${Y_ARR[$i]};${X_ARR[$i]}H$\e[0m"
echo -e "\e[5;32m\e[${RANDOM_Y};${RANDOM_X}H#\e[0m"
init_map
echo -e "\e[$(($MAP_Y + $MAP_HIGHT + 2));${MAP_X}H\e[32mSnake:${X},${Y}\e[0m\e[0m"
echo -e "\e[$(($MAP_Y + $MAP_HIGHT + 3));${MAP_X}H\e[32mFood :${RANDOM_X},${RANDOM_Y}\e[0m\e[0m"
echo -e "\e[$(($MAP_Y + $MAP_HIGHT + 4));${MAP_X}H\e[33mScore:${score}\e[0m\e[0m"
}
function gen_food() {
let flag=1
while [ $flag -eq 1 ]; do
let RANDOM_X=$(($RANDOM % $((${MAP_WIDTH} - 1)) + $((${MAP_X} + 1))))
let RANDOM_Y=$(($RANDOM % $((${MAP_HIGHT} - 1)) + $((${MAP_Y} + 1))))
for ((i = 0; i < ${LENGTH}; i++)); do
if [[ ${X_ARR[$i]} -eq ${RANDOM_X} && ${Y_ARR[$i]} -eq ${RANDOM_Y} ]]; then
break
fi
done
if [ $i -eq ${LENGTH} ]; then
flag=0
fi
done
}
function init() {
clear
echo -e "\e[0m"
echo -e "\e[?25l"
for i in $(seq 5); do
let pos_x=$((${MAP_WIDTH} / 2 - 2 + ${i}))+${MAP_X}
let pos_y=$(((${MAP_Y} + ${MAP_HIGHT}) / 2))+${MAP_Y}
X_ARR+=($pos_x)
Y_ARR+=($pos_y)
done
X=$pos_x
Y=$pos_y
gen_food
}
function move() {
case $DIR in
"w") Y=$Y-1 ;;
"s") Y=$Y+1 ;;
"a") X=$X-1 ;;
"q") end_of_game ;;
*) X=$X+1 ;;
esac
if [[ $X -eq ${RANDOM_X} && $Y -eq ${RANDOM_Y} ]]; then
((LENGTH++))
let score+=10
X_ARR[${LENGTH}]=$X
Y_ARR[${LENGTH}]=$Y
gen_food
return
fi
if [[ $X -le $MAP_X || $Y -le $MAP_Y || $X -ge $(($MAP_X + $MAP_WIDTH)) || $Y -ge $(($MAP_Y + $MAP_HIGHT)) ]]; then
end_of_game
fi
for ((i = 2; i <= ${LENGTH}; i++)); do
if [[ $X -eq ${X_ARR[$i]} && $Y -eq ${Y_ARR[$i]} ]]; then
end_of_game
fi
done
for ((i = 0; i <= ${LENGTH}; i++)); do
X_ARR[$i]=${X_ARR[$i + 1]}
Y_ARR[$i]=${Y_ARR[$i + 1]}
done
X_ARR[${LENGTH}]=$X
Y_ARR[${LENGTH}]=$Y
}
function main() {
init
draw_snake
{
init_map_lamp
} &
while :; do
OLD_DIR=$DIR
if ! read -n 1 -t 0.5 -s DIR; then
DIR=$OLD_DIR
fi
sleep 0.0001
move
draw_snake
done
}
main