基本要求:
一条蛇在密闭的围墙内,在围墙内随机出现一个食物,通过键盘上的四个光标键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被吃掉,这时蛇的身体长一节,同时计1分;接着又出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁或身体交叉(蛇头撞到自己的身体)游戏结束。
算法核心:
使用单链表,并使用头插法。
编译环境: Dev c++
(不同的编译环境可能导致有些东西无法运行,但编写贪吃蛇的思想是一样的)
贪吃蛇的核心步骤:
1.如何让贪吃蛇移动:
(①让蛇自行前进。②改变蛇的移动方向)
①如何让蛇自行移动:
我们就需要一个移动光标的函数,这个函数的名字可以自行创建,但函数里面必须要包含以下内容(详情请看我举例,这里我把我的光标移动函数命名为gotoxy( ) )。在创建光标函数的时候我们需要引入一个头文件 #include<windows.h>。
当我们一个c语言 编译 运行 成功后,将会打开一个窗口,这时水平方向表示x轴,垂直方向表示y轴。但我们需要注意的是 x轴,y轴 的起始位置从0开始,所以在我的样例中,你会看见 pos.X = x-1; pos.Y = y-1; 这里我将x轴,y轴 的起始位置变成了从1开始。但如果你想让你的x轴,y轴 的起始位置从0开始,则需要将 pos.X = x; pos.Y = y;
#include<stdio.h>
#include<windows.h>
void gotoxy(int x,int y){ //用于移动光标
COORD pos;
pos.X = x-1; //起始位置从1开始
pos.Y = y-1;
/*
pos.X = x; //起始位置从0开始
pos.Y = y;
*/
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
int main(){
gotoxy(50,10);
printf("*********");
gotoxy(50,30);
printf("*********");
return 0;
}
运行如图所示:
说了光标函数,那么我们如何让蛇自行移动呢?
在这里我们先创建一个有关蛇信息的结构体,如下:
typedef struct snake{
int x,y;
struct snake *SnakeNext;
}SNAKE,*Snake;
在蛇移动之前,我们可以通过光标函数 gotoxy(),将蛇的初始化状态打印出来。
假设蛇的初始方向是 向左 那么这时我们只需要将蛇的蛇头的坐标变为向左后的坐标,这时蛇头的坐标已经变成了新的坐标。然后我们只需要一个循环将蛇的第一节身体变为蛇头以前的坐标,第二节身体变为第一节身体以前的坐标,然后依次类推。然后在用 上面提及到的光标函数 gotoxy(),将蛇依次打印出来。
那么这时我们会产生一个问题,随着蛇的移动,蛇的身体在运行窗口中可能会变得越来越长,这个不是因为 蛇的单链表中插入了数据,而是我们在蛇的移动中没有将蛇的尾部打印坐标对应的图案掩盖掉,这时我们只需要通过当蛇移动时,将蛇尾的坐标保留下来,然后在利用 光标函数 在这里打印一个 空格 从而掩盖蛇原先的蛇尾,每次移动我们都需要将蛇尾用空格进行掩盖。从而达到蛇移动的现象。
但是在蛇的运行过程中,我们会发现一个问题,就时蛇的移动速度太快了,那么这时我们该如何处理这个问题呢?
这时我们就需要用到一个新的函数 Sleep() 需要引入#include<windows.h>。
Sleep()函数:
功 能: 执行挂起一段时间 (简单的说:当程序运行到Sleep()函数这里时,程序将暂停多长时间然后在继续运行)
Eg: Sleep(50) 表示的是程序将暂停50毫秒
看到这我们会想这个Sleep()函数有什么用呢?
我们通过调节Sleep()函数里面值的大小,那么我们就可以来控制程序的运行时间,进而我们可以控制蛇的移动速度。从而可以使我们的贪吃蛇有了选择 游戏难度 的东西。
②如何让蛇改变移动方向:
在之前,我们需要了解两个函数,kbhit(),getch()。
函数名:kbhit()
功能及返回值: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。
用 法:int kbhit(void);
C++语言包含头文件: include <conio.h>。
C语言不需包含额外头文件。
在VC++6.0下为_kbhit()
功能及返回值同上;
函数名:getch():
所在头文件:conio.h
函数用途:从控制台读取一个字符,但不显示在屏幕上
函数原型:int getch(void)
返回值:读取的字符
例如:
char ch;或int ch;
getch();或ch=getch();
用getch();会等待你按下任意键,再继续执行下面的语句;
用ch=getch();会等待你按下任意键之后,把该键字符所对应的ASCII码赋给ch,再执行下面的语句。
通过kbhit(),getch()这两个函数我们就可以用来控制蛇的移动。
列如 我们通过W A S D 来控制方向,当我们按下W的时候这时我们只需要改变 蛇头 的坐标,然后重复 蛇自行移动 的步骤从而使蛇移动。
那么当我们什么都不按下的时候,怎么可以让蛇自行移动呢? 提示一下,我们可以将向上,向下,向左,向右,分别写一个函数,然后将其封装起来,然后在用一个死循环即可。
最后文章最后我将附上源码,供大家参考。
2.食物
(①产生随机食物②蛇吃食物)
①产生随机食物:
需要srand() 和 rand()函数
- 举例
include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main(){
srand((unsigned)time(NULL));
for(int i=0;i<5;i++)
{
//srand((unsigned)time(NULL)); 只能调用一次,否者会使产生的随机数相同
printf("%d ",rand()%5+1);
}
return 0;
}
这样产生的随机数就是1-5之间的随机函数
这二个函数的工作过程如下:
1) 首先给srand()提供一个种子,它是一个unsigned int类型,其取值范围从0~65535;
2) 然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到32767之间)
3) 根据需要多次调用rand(),从而不间断地得到新的随机数;
4) 无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。
②蛇吃食物:
当蛇头按照它的运行轨迹下一个坐标将要到达食物的坐标时我们利用链表的头插法将食物的坐标插入进链表中,这时我们就不能将蛇的尾部进行覆盖。
3.地图
利用光标函数,进行地图的打印。
4.死亡
当蛇撞到自己或者墙时表示死亡,我们可以用 exit(0) 来强制中断程序。需要头文件
#include<stdlib.h>
5.游戏背景颜色
需要导入头文件#include<stdlib.h>
system("color XY"); 中只需要改变X Y 的值就可以改变游戏背景的颜色。
6.头文件的创建
(对于头文件的保存我建议放在你贪吃蛇程序保存的位置)
相关步骤:
新建--源代码
保存:在保存类型的下拉列表中选择Header Files
写入函数,定义等
别忘了保存
引用:例:#include<路径\文件名.后缀>
//使用绝对路径
#include<C:\Users\lair\Desktop\自己定义的头文件名.h>
创建头文件
#ifndef 头文件名(大写)_H
#define 头文件名(大写)_H
内容
#endif
举例说明:
新建--源代码
保存:在保存类型的下拉列表中选择Header Files,然后产生一个 hello.h 的头文件
然后调用
文件路径的相关说明
对文件包含命令还要说明以下几点:
1. 包含命令中的文件名可以用双引号括起来,也可以用尖括号括起来。例如以下写法都是允许的:
#include"stdio.h"
#include<math.h>
但是这两种形式是有区别的:使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时 设置的),而不在源文件目录去查找;
使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找。用户编程时可根据 自己文件所在的目录来选择某一种命令形式。
.include<头文件名>和include"头文件名"
如:include<stdio.h>和include"stdio.h"
前者(使用<>),来引用stdio.h文件,是首先检索标准路径,看看这些文件夹下是否有该头文件;如果没有,也不会检索当前文件所在路径,并将报错。
后者(使用""),来引用stdio.h文件,是首先检索文件的当前路径;如果没有,再检索标准路径,看看这些文件夹下是否有该头文件。
源码:
https://blog.csdn.net/qq_40935723/article/details/86553671
百度云(我贪吃蛇的代码):
链接:https://pan.baidu.com/s/1kVvk_UgL0MR-BL9pcHTJtQ
提取码:lr78
以下是我游戏的运行图:
闯关模式
休闲模式
选着地图
选着难度
图一
图二
图三