此博客记录制作字符游戏-智能蛇的学习经历。实验环境:Ubuntu。
贪吃蛇,是一款经典的益智游戏。我们可以设计算法,通过算法捕捉和传递智能。设计出能自动跑着吃食物的智能蛇。
首先,用自顶向下、逐步加精的设计模式先给出整个程序的伪代码。
输出字符矩阵
WHILE not 游戏结束 DO
wait(time)
ch=whereGoNext(Hx,Hy,Fx,Fy)
CASE ch DO
‘A’:左前进一步,break
‘D’:右前进一步,break
‘W’:上前进一步,break
‘S’:下前进一步,break
END CASE
输出字符矩阵
END WHILE
输出 Game Over!!!
这个框架还是很不错的。
接着,是最关键的算法设计。算法的好坏直接决定蛇的智商高低。先前有不少人做过关于贪吃蛇算法的研究,网上也有很多资料。也可以看笔者的另一篇文章:字符版本贪吃蛇游戏设计及算法这里只实现了老师给的最简单的贪婪算法。
// Hx,Hy: 头的位置
// Fx,Fy:食物的位置
function whereGoNext(Hx,Hy,Fx,Fy) {
// 用数组movable[3]={“a”,”d”,”w”,”s”} 记录可走的方向
// 用数组distance[3]={0,0,0,0} 记录离食物的距离
// 分别计算蛇头周边四个位置到食物的距离。H头的位置,F食物位置
// 例如:假设输入”a” 则distance[0] = |Fx – (Hx-1)| + |Fy – Hy|
// 如果 Hx-1,Hy 位置不是Blank,则 distance[0] = 9999
// 选择distance中存最小距离的下标p,注意最小距离不能是9999
// 返回 movable[p]
}
为了做出较好的字符界面,使界面不像调用system(“cls”)那般闪烁不友好,则学习有关VT100控制码编程的知识。主要涉及一些光标移动的操作。
用到的控制码:\033[y;xH 设置光标位置
不得不说,用VT100控制码不好写程序,不断调试,直到最终能达到满意的效果。
上面控制码中的y是纵向的即行数,x是横向的即列数,如图:
——————>x
|(1,1)(1,2)(1,3)
|(2,1)
|
|
y
而且\033[0;0H和\033[1;1H代表的是同一个位置,也就意味着光标位置是从(1,1)开始的。
搞清这些十分重要,要时刻保持清醒的头脑,否则就陷入苦苦的调试旋涡……
另外一个我在编程中遇到的问题是输出时没有清空缓冲区,这个bug是致命的,将使你的程序惨不忍睹。一种方法是在每次printf时加上’\n’,另一种方法是调用fflush(stdout)。
制作字符游戏-智能蛇的过程是有趣的,虽然自己并未实现高级的贪吃蛇算法,但制作出一个像样的游戏也是成就满满。最终效果如图: