题目 贪吃蛇 程序说明
一功能实现
1.贪吃蛇正常的移动,wsad控制上下左右移动。
2.贪吃蛇每吃一个食物增长1格,分数加1.
3.分数每增加5分,食物数量增加一个。食物时间可以为20,30,40.分数随时间变化而变化。
4.空格为暂停,F可以加速5格。P为退出并保存。
5.蛇头碰墙,碰身体,反方向都视为死亡。
二 流程图
三 程序分析
链表头是蛇尾
1.创建链表,蛇的与食物的初始化
扫描二维码关注公众号,回复:
5560070 查看本文章
struct foood_node *fcreat_link(int m) //m的创建是为了后面食物的增加以及数据保存做准备,开始时为1
{
srand(time(NULL));
struct food_node *p,*ptail;
int i;
for(i=0;i<m;i++)
{
p = (struct food_node *)malloc(sizeof(struct food_node)); //创建一个节点
if(p == NULL)
{
free(fhead);
printf("failure\n");
return NULL;
}
p->date.x = rand()%38 + 21; //赋初值(根据边框坐标来定)
p->date.y = rand()%19 + 6;
p->date.time = (rand()%3+2)*10;
if(i == 0)
fhead = p;
else
ptail->next = p;
ptail = p;
p->next = NULL;
}
}
struct snake_node *creat_link(int n) //n的创建是为了后面蛇的身体增加以及数据保存做准备,开始时为3
{
struct snake_node *p,*ptail;
int i;
for(i=0;i<n;i++)
{
p = (struct snake_node *)malloc(sizeof(struct snake_node)); //创建一个节点
if(p == NULL)
{
free(head);
printf("failure\n");
return NULL;
}
p->date.x = 30+i;
p->date.y = 15;
p->date.dir = RIGHT;
if(i == 0)
head = p;
else
ptail->next = p; //将邻近的节点连起来
ptail = p;
p->next = NULL;
}
}
结构体定义见程序,此处不详解释
2.蛇的移动
将蛇身体的每一个节点依次将后一个结点的数据赋给前边的,并对最后一个数据判断此时方向对其作相应的操作,上下Y±1,左右 X±1;
p = head;
while(p!= NULL && p->next!=NULL)
{
p->date.x = p->next->date.x; //将每个节点的数据依次往后赋值;
p->date.y = p->next->date.y;
p->date.dir = p->next->date.dir;
p = p->next;
}
if(cur_dir == RIGHT || cur_dir == LEFT)
p->date.x += (cur_dir-3);
else
p->date.y += cur_dir;
p->date.dir = cur_dir;
3.蛇的增长
获得蛇头的下次节点位置(将来时);
while(p!= NULL && p->next!=NULL) //获得链表尾的节点数据,及蛇头的数据
p = p->next;
if(cur_dir == RIGHT || cur_dir == LEFT) //将蛇头的数据根据当前的方向进行移动操作
{
q.date.x = p->date.x + (cur_dir-3);
q.date.y = p->date.y;
}
else
{
q.date.x = p->date.x;
q.date.y = p->date.y + cur_dir;
}
判断蛇头及链尾的下一次位置(将来时)与食物的坐标进行比较,如果相等,则创建一个结点将 将来时的数据赋予,并将其连到链尾。不相等继续移动(判断时蛇不移动)。
pnew = (struct snake_node *)malloc(sizeof(struct snake_node)); //如果将来时的蛇头与食物坐标相同,那么创建一个节点,节点数据与将来时数据(食物坐标)相同,
pnew->date.x = q.date.x; //相等时,此时蛇不进行移动操作
pnew->date.y = q.date.y;
pnew->date.dir = cur_dir;
p = head;
while(p!=NULL)
{
pold = p;
p = p->next;
}
pold->next = pnew;
pnew->next = p;
4.食物的增加
食物采用的是链表,所以和蛇的增加相似
struct food_node *pnew,*pold,*p = fhead;
if(score%5 == 0)
{
foodlength++;
pnew = (struct food_node *)malloc(sizeof(struct food_node));
pnew->date.x = rand()%38 + 21;
pnew->date.y = rand()%19 + 6;
p->date.time = (rand()%3+2)*10;
p = fhead;
while(p!=NULL)
{
pold = p;
p = p->next;
}
pold->next = pnew;
pnew->next = p;
}
5.数据的保存于读取
1.保存
将版本,状态量,蛇的各个节点数据,食物节点数据,分数,蛇的长度,写入一个文件中,(注意格式);
fp = fopen("snake.dat","w"); //打开一个文件,以读的形式打开
if(fp == NULL)
{
perror("open write error");
return;
}
fwrite("SNAKEA",6,1,fp); //版本名
fwrite(&ver,4,1,fp); //版本序数
fwrite(&snakelength,4,1,fp); //蛇的长度
fwrite(&score,4,1,fp);· //分数
p = head;
while(p!= NULL) //蛇的每个节点数据
{
fwrite(&p->date,sizeof(struct snake_date),1,fp);
p = p->next;
}
fwrite(&foodlength,4,1,fp); //食物长度
q = fhead;
while(q != NULL) //食物的每个节点数据
{
fwrite(&q->date,sizeof(struct food_date),1,fp);
q = q->next;
}
fclose(fp);
2.读取要与写时顺序一致,(注意格式)
fread(&ver,4,1,fp);
if(ver == 1)
{
int i;
struct snake_node *p;
struct snake_date date1;
struct food_node *q;
struct food_date date2;
fread(&n,4,1,fp);
snakelength = n;
fread(&score,4,1,fp);
creat_link(snakelength); //读取蛇的长度
p = head;
for(i=0;i<n;i++) //根据蛇的长度创建相同长度的链表
{
fread(&date1,sizeof(struct snake_date),1,fp);
p->date = date1;
cur_dir = p->date.dir;
p = p->next;
}
fread(&m,4,1,fp);
foodlength = m;
fcreat_link(foodlength);
q = fhead;
for(i=0;i<m;i++)
{
fread(&date2,sizeof(struct food_date),1,fp);
q->date = date2;
q = q->next;
}
6.此处只详解了部分,其余的都比较容易看懂。
还有食物的判断,蛇头的撞墙,撞身体(就是将蛇头与身体的每个节点比较),画表格等(见下面链接可看详细程序);
编写时要仔细,认真,最好能把大纲列一下。
<ahref=“https://gitee.com/wlwcylsf/HKwork.git”>…