分析
贪吃蛇整个游戏过程就是玩家控制蛇在限定区域内重复移动、吃食的过程,因此实现这个小游戏需要一条蛇、一个限定区域以及食物。我们可以用一个数组来表示限定区域,对这个区域而言,我们希望有初始化的方法以及在终端打印的方法;对于蛇来讲,我们希望可以对其初始化、移动以及吃食的方法;食物的话,要求比较简单,只需要在没有食物的时候产生新的食物就可以。
活动区域
我选择一维的字符数组来作为活动区域的载体,当储存元素为字符'S'
时表示为蛇;元素为字符'F'
时表示为食物;元素为字符'+'
时表示为边界,其余的空闲空间则储存字符'0'
。游戏的过程,本质上就是对这些字符的处理。实现区域的初始化和打印方法非常简单,是实现贪吃蛇过程中最简单的部分了。
蛇
我使用了一个类似双端队列的数据结构来表示蛇,不过它比双端队列简单多了,只需要实现双端队列的几个操作就可以了。unshift()
用来在队列前端添加元素,pop()
用来删除队列末端的元素,get_head()
用来获取队首。值得注意的是,前面我用字符数组来实现活动区域,结果也用字符数组来实现这个储存位置的队列,结果给自己挖了一个大坑。蛇在限定区域内不断移动,就是通过操作储存位置的队列来实现的。
蛇移动的话,就是在队首添加元素,在队末删除元素。
1 | void move_snake(int x) { |
类似移动,吃食不过是不删除队末的元素。
1 | void eat_snake(int x) { |
食物
使用库函数rand()
随机产生食物,注意,要在没有食物的时候产生!
主函数
实现上面的各个函数后,整个贪吃蛇就呼之欲出了。首先初始化活动区域,初始化蛇,然后循环不断获取用户输入,产生下一个移动位置,蛇对其作出反应,打印活动区域。这其中有一个需要注意的点就是,蛇不能对与运动方向相反的指令作出响应,就是不能调头返回。
其他
我实现的贪吃蛇是控制台程序,为了美观,需要清屏、关闭回显、隐藏光标等美化操作。清屏与关闭回显,我使用了库函数中的system()
函数;隐藏光标,我使用了这提供的方法。要注意的是,对终端设置后记得在退出时将设置修改回来。还有一个,贪吃蛇需要判断键盘是否有输入,有的话需要及时读入,了解到有这么一个库函数kbhit()
实现了这个功能,不过linux下的C并没有这个头文件,我谷歌了一个kbhit()
在linux下的实现,在这,感觉这才是这个程序的重点哈,不过,水平太菜,只好直接复制了。
源程序: 这里