一.编程环境:
二.编程思路:
-
打开一个图形窗口。
-
定义一条蛇。
-
定义(生成)一只小鸡
-
定义蛇的初始化方向
-
do{
获取键盘输入按键。
把蛇显示在图形窗口中。
把小鸡显示在图形窗口中。
移动蛇(其中包括:1.把原来的蛇在图形窗口中隐藏 2.移动蛇3.移动后看有没有撞墙或咬到自己4.看有没有吃到鸡(若吃到鸡,把原来的鸡隐藏,生成新的鸡的坐标,把蛇的长度加长))。}while(输入的按键不是ESC);
(while循环结束,游戏结束) -
当蛇的长度小于游戏目标时,在窗口上显示“You lost!” 否则显示“Congratulations! you won!”
关闭程序
三.数据结构的选取{逻辑结构,存储结构,数据的运算}:
- 程序设计中的蛇选取什么样的数据结构。对于数据结构的选取主要看对数据进行什么样的操作。
- 蛇:在以上的编程思路中,蛇有两个动作,一是移动,二是增长。蛇的移动即蛇各部分坐标的改变,蛇的增长即链表或者数组中元素的增多。
- 蛇:对于逻辑结构需选举用线性结构,对于存储结构,可选顺序存储结构和链式存储结构。具体选择哪一种先分析蛇的增长。
- 假设蛇增长的一段加在蛇末尾,但蛇末尾有三个方向如下图1.0,具体加在什么坐标上还得判断最后一块的移动方向比较麻烦,所以加在末尾的方法舍去。
图1.0:
- 假设加在蛇中间,中间有这么多快加在哪两块中间也不好判断,所以舍去。
- 假设加在头的位置,这就好实现,只需要在头后面加一块,让这块继承头的坐标,同时根据蛇移动方向,让蛇头沿着移动方向移动一块的距离即可,即更新头的坐标,如下图2.0。
- 图2.0:
- 既然要在顶头插入元素,为了避免大量元素移动应该选择链式存储结构。
- 链式存储结构有单链表,单循环链表,双链表,双循环链表等,因为蛇的移动方式:每一块移动后的坐标为其前驱的坐标,头结点则沿着移动方向移动一块的距离。根据移动方式需要找前驱结点,所以采用双向链表,且为带头结点的双向链表。又因为更改每一块的坐标时需要从蛇尾开始改,所以还需一个尾指针,故最终选取带头结点和尾指针的双链表。
四.编程中部分关键代码实现细节:
1.蛇的数据类型的设计:
typedef struct body_ {
int x;//蛇身体所在横坐标
int y;//蛇身体所在纵坐标
struct body_* prex;//前驱指针
struct body_* next;//后继指针
}*body, BODY;
2.小鸡的数据类型的设计:
typedef struct Chicken_ {
//鸡所在的横纵坐标
int x;
int y;
}*chicken,CHICKEN;
3.定义蛇:
body rear = NULL;//蛇尾指针
//生成蛇头
BODY Head;
Head.next = NULL;
Head.prex = NULL;
Head.x = 400;//蛇头的x,y坐标
Head.y = 400;
//蛇的长度
int Snake_len = 1;
4.定义小鸡:
CHICKEN Chi;
Chi.x = 20 + rand() % (800 - 20 + 1);//随机生成小鸡坐标 (20~800间)
Chi.y = 20 + rand() %(800 - 20 + 1);
5.图形窗口建立:
initgraph(820, 920);//打开一个长820像素,宽920像素的窗口
//该窗口大小的设计得先经过设计如下图3.0,黑色区域为蛇和鸡出现的区域,外面为边框
图3.0:
6.画地图蓝色边框(该边框算法见杭电oj 2052题:Picture)
void Creat_map()
{
//画边框
setfillcolor(BLUE); //选择填充颜色
for (int i = 0; i <= 820; i = i + size)
{
for (int j = 0; j <= 820; j = j + size)
{
if (i == 0 || i == 820)
{
//bar3d(int left, int top, int right, int bottom, int depth, int topflag, PIMAGE pimg = NULL); // 画有边框三维填充矩形
fillrectangle(i, j, i + size, j + size);
}
else
{
if (j == 0 || j == 820)
{
fillrectangle(i, j, i + size, j + size);
}
}
}
}
}
7.显示蛇:
void Show_Snake(body Head)
{
body p = Head;
setfillcolor(RED); //选择蛇的填充颜色
while (p)
{
fillrectangle(p->x, p->y, p->x + size, p->y + size);
p = p->next;
}
}
//把蛇的每一个节点显示出来,显示为一个正方形,蛇的节点坐标为正方形的左上角坐标,正方形左下角坐标等于左上角分别加上宽度
8.显示小鸡:
void Show_Chicken(chicken Chi)
{
setfillcolor(YELLOW); //选择鸡的填充颜色
fillcircle(Chi->x+size/2, Chi->y+size/2 ,size/2);
}
//和显示蛇的方式差不多,这里显示的是以鸡的坐标为正方形的左上角坐标且宽度为siz