计算机知识分享网

【shell】贪吃蛇小游戏

#!/bin/bash

#方向为1上2右3下4左
dir_u=1
dir_r=2
dir_d=3
dir_l=4
dir=$dir_u
#m为面板宽度,n为面板高度
m=60
n=20
#蛇的起始位置
a=$[m/2]
b=$[n-1]
#食物产生的位置
food_x=
food_y=
#蛇的长度
l=0
#蛇头数组下标
sum=0
len=0
#记录蛇头运行轨迹数组
x=()
y=()
#记录蛇撞击自己次数
h=0

#主函数入口
main(){	
	run
}

#产生食物随机数
ran_xy(){
	food_y=$[RANDOM %($m-2)+2]
	food_x=$[RANDOM %($n-2)+2]
}

#开始
init(){
	printf "\033[1;1H"
	printf "\033[2J"
	for i in $(seq $n)
	do
		for j in $(seq $m)
		do
		test $i -eq 1 -o $i -eq $n  \
			-o $j -eq 1 -o $j -eq $m \
			 &&printf "☒" || printf " "
		done
		printf "\n"
	done
	printf "    w:上    a:左    s:下     d:右     q:退出\n"
	printf "\033[%d;%dHo\n" $food_x $food_y
	snake
}

#刷新地图
run(){
#stty -echo取消跳动
	stty -echo
	printf "\033[?25l"
	ran_xy
	while true;do
		init
		move
		eat
		read -t 0.3 -n 1 key
		test "$key" = "q" && break
		test "$key" = "w" -a $dir != $dir_d && dir=$dir_u
		test "$key" = "a" -a $dir != $dir_r && dir=$dir_l
		test "$key" = "s" -a $dir != $dir_u && dir=$dir_d
		test "$key" = "d" -a $dir != $dir_l && dir=$dir_r
		test $h -eq 1 && break
	done	
	printf "\033[?25h\033[%d;1H" $[n+4]
	stty echo
}

#移动操作
move(){	
	let sum++
	x[$sum]=$a
	y[$sum]=$b
	case "$dir" in
	1)	let b--
	;;
	2)	let a++
	;;
	3)	let b++
	;;
	4)	let a--
	esac
	bump
}

#游戏结束
game_kill(){
	printf "\033[7;20H"
        printf "\033[2J"
	echo -e "\033[31;60;1m  Game Over\033[39;49;0m"
	printf "\n\n"
	echo -e "\033[32;60;1m                 您的成绩为:$[l*10] 分\033[39;49;0m"
	break
}

#画蛇
snake(){
	printf "\033[%d;%dH@\n" "$b" "$a"
        for j in $(seq 0 $l);do
		len=$[sum-$j]
		printf "\033[%d;%dH0" ${y[$len]} ${x[$len]}
	done
}

#蛇吃食物时
eat(){
	if test $food_y -eq $a && test $food_x -eq $b;then
		ran_xy
		let l++
	fi
}

#撞击时处理方法
bump(){
	test $a -eq 1 -o $b -eq 1 -o $a -eq $m -o $b -eq $n && game_kill
	for k in $(seq 0 $l);	do
		len=$[sum-$k]
	if test ${y[$len]} -eq $b && test ${x[$len]} -eq $a;then
		let h++
		game_kill
	fi
	done
}

main

#Shell