c语言实现greedy snake(贪吃蛇)

2024-03-25 08:10

本文主要是介绍c语言实现greedy snake(贪吃蛇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

##第一个小项目  大一学生寒假项目

最终实现效果如图

一.以C语言实现个人小项目

在我们快速学完了一个高级编程语言,就应该写一个小项目来加以巩固自己的学习成果。

所以今天,我们来尝试写一写greedy snake,对于大学生来说也是可以加强能力的存在。事不宜迟,我们开始吧。(Tips:我会加入一些外部链接,这些于编写遇到的问题有关,可以帮助你更好的解决)

外部文件的引入以及一些定义

#include <stdio.h>
#include <graphics.h> //与绘图文件有关
#include <conio.h>    //两个都需要
#include <stdlib.h>
#define SNAKE_NUM 500 //宏定义 规定好蛇的最大节数,以防溢出
enum DIR //枚举初始化方向
{UP,DOWN,LEFT,RIGHT,
};

解释:

我们在第四行引入的头文件是为了产生一个生成随机数的种子(所以我们引入了该头文件)

5函数名称: rand

函数原型: int rand(void);

函数功能: 产生0到32767间的随机整数(0到0x7fff之间)

函数返回: 随机整数

对于第二,第三行的头文件引入。

我在这里放好了它的下载官网,官网有下载说明,不复杂的

easyx文档 点击此处

二.蛇和食物的结构体定义

struct Snake
{int size; //蛇的长度int dir; //蛇的方向int speed; //蛇的速度POINT coor[SNAKE_NUM]; //坐标
}snake;struct food
{int x;int y;int r; //食物大小bool flag; //为后面判断食物是否被吃做准备DWORO color;  //规定食物的颜色
}food;

在这里,我们注意一下 POINT coor[] 是我们引入了相应的头文件,以有表示二维坐标的

函数。 后续创建实体的写法是---> snake[i].x = 坐标点 其中i是它的大小。

并且,这里的坐标轴与数学中的有些不同,y轴的正方向是朝下的,所以我们想让蛇向上移动最好是snake[i].y -= speed .这样蛇就是上移。

对于food(食物处),我们定义的x,y是为后续的随机坐标做好准备的。

三.数据的初始化

void GameInit()
{//init;初始化 graph 图形窗口initgraph(640,480);//设置随机数种子 GetTickCount 获取系统开机到当前运行所经过的时间srand(GetTickCount());//初始化蛇 一开始就有n节 n随你定义 这里我是3snake.size = 3;snake.speed = 5;snake.dir = RIGHT;//循环 这里是初始化蛇的位置 for (int i = 0; i < snake.size; i++) {snake.coor[i].x = 40 - 10*isnake.coor[i].y = 10;}//初始化食物,rand()是随机函数 来自头文件<stdlib.h>//一般把时间作为种子,时间在变化food.x = rand() % 640; // % n ---> 可以得到 0-(n-1)的数food.y = rand() % 480;food.color = RGB(rand() % 256, rand() % 256, rand() % 256);food.r = rand() % 10 + 5; //随机这个食物的半径 最小半径为5food.flag = true;
}

初始化的循环是为了 让蛇排列成行。 下标为0 是蛇头

四.图的绘制

void GameDraw()
{//双缓冲绘图 ---> 原因是会卡频//设置背景颜色setbkcolor(RGB(28,115,119)); //颜色可以按自己喜好的来cleardevice(); //清空绘图设备//绘制蛇setfillcolor(GREEN);for (int i = 0; i < snake.size; i++) {solidcircle(snake.coor[i].x,snake.coor[i].y, 5); //半径为5}//绘制食物if (food.flag){solidcircle(food.x, food.y, food.r);}EndBatchDraw();
}

1.头文件graphics.h包含cleardevice()函数,该函数在图形模式下清除屏幕并将当前位置设置为(0,0)。清除屏幕包括用当前背景色填充屏幕。

2.if条件判断是为了判断食物是否被吃 后刷新食物。

3.EndBatchDraw();---相关官方文档在这easyx文档

五.蛇的移动

//移动蛇
void snakemove()
{//移动是什么发生改变;坐标改变for (int i = snake.size; i > 0 ; i--){snake.coor[i] = snake.coor[i - 1];}//移动是什么发生改变switch (snake.dir){case UP:snake.coor[0].y-=snake.speed;if (snake.coor[0].y+10 <= 0) {snake.coor[0].y = 640;}//超出了上面的边界break;}switch (snake.dir){case DOWN:snake.coor[0].y+=snake.speed;if (snake.coor[0].y - 10 >= 640) {snake.coor[0].y = 0;}break;}switch (snake.dir){case LEFT:snake.coor[0].x-=snake.speed;if (snake.coor[0].x + 10 <= 0) {snake.coor[0].x = 640;}break;}switch (snake.dir){case RIGHT:snake.coor[0].x+=snake.speed;if (snake.coor[0].x - 10 >= 640) {snake.coor[0].x = 0;}break;}}

六.keyborad (键盘控制)

//通过按键操作
void keyControl()
{//判断有无按键if (_kbhit()) //检测是否有按键{//72 80 75 77 上下左右键值switch (_getch()){case 'w':case 'W':case 72://改变方向if (snake.dir != DOWN) {snake.dir = UP;}break;case 's':case 'S':case 80:if (snake.dir != UP) {snake.dir = DOWN;}break;case 'a':case 'A':case 75:if (snake.dir != RIGHT) {snake.dir = LEFT;}break;case 'd':case 'D':case 77:if (snake.dir != LEFT) {snake.dir = RIGHT;}break;}}
}

对于_kbhit() --->判断是否keyboard被按动 并返回bool值

_getch() ---> 获取按键信息

七.吃食物

void EatFood()
{if (snake.coor[0].x >= food.x - food.r && snake.coor[0].x <= food.x + food.r&& snake.coor[0].y >= food.y - food.r && snake.coor[0].y <= food.y + food.r){food.flag = false;snake.size++;}if (!food.flag){food.x = rand() % 640;food.y = rand() % 480;food.color = RGB(rand() % 256, rand() % 256, rand() % 256);food.r = rand() % 10 + 5;food.flag = true;}/*可以加一个分数,吃一个食物,加n分*/
}

TIPS:

这里的两个if判断语句

对于第一个if,是判定什么时候什么范围,蛇将这个食物给吃了  可以同过点到圆心的距离

即 d <= r(该圆半径)  (d为距离---为两个圆心的距离) 此时,两个圆相交便为吃了,否则,玩家的操作系数上升,不适宜游玩。

对于第二个if,是为了刷新被吃掉的食物。

八.游戏暂停

void stop()
{//判断是否键盘按动 和 是否为空格键if (_kbhit() && _getch() == ' '){while(1){if (_getch() == ' '){break;}}}
}

原理是:我们写一个死循环 while(1)---来占用进程,以达到暂停效果。 里面还有一个if判断是为了用户在按下一次的空格键下,打破循环,继续游戏。

二.主函数实现最终效果

int main()
{//在主函数调用,出现初始化结果GameInit();//防止闪退while(1) {GameDraw();snakemove();stop();keyControl();EatFood();Sleep(30); //防止太快移动,延迟}return 0;
}

注意,这里的stop()---游戏暂停函数一定要放到前面,否则会达不到暂停的效果。

在我们完成这些代码,F5调试时,可能有些人的蛇无法移动。

解决方案是:在shell(控制面板)来操控蛇的移动。就是那个黑框框。

也有不用在这个shell里面操作的方案,但是操作起来有些麻烦,所以还是用这个简单些的方案好一些。

最后我将这个project的源码放入,感兴趣的同学也可以通过这以上的代码自行输入,会有很多感悟。

谢谢。

这篇关于c语言实现greedy snake(贪吃蛇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/844365

相关文章

pandas中位数填充空值的实现示例

《pandas中位数填充空值的实现示例》中位数填充是一种简单而有效的方法,用于填充数据集中缺失的值,本文就来介绍一下pandas中位数填充空值的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是中位数填充?为什么选择中位数填充?示例数据结果分析完整代码总结在数据分析和机器学习过程中,处理缺失数

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Pandas使用AdaBoost进行分类的实现

《Pandas使用AdaBoost进行分类的实现》Pandas和AdaBoost分类算法,可以高效地进行数据预处理和分类任务,本文主要介绍了Pandas使用AdaBoost进行分类的实现,具有一定的参... 目录什么是 AdaBoost?使用 AdaBoost 的步骤安装必要的库步骤一:数据准备步骤二:模型

使用Pandas进行均值填充的实现

《使用Pandas进行均值填充的实现》缺失数据(NaN值)是一个常见的问题,我们可以通过多种方法来处理缺失数据,其中一种常用的方法是均值填充,本文主要介绍了使用Pandas进行均值填充的实现,感兴趣的... 目录什么是均值填充?为什么选择均值填充?均值填充的步骤实际代码示例总结在数据分析和处理过程中,缺失数

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

python实现svg图片转换为png和gif

《python实现svg图片转换为png和gif》这篇文章主要为大家详细介绍了python如何实现将svg图片格式转换为png和gif,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录python实现svg图片转换为png和gifpython实现图片格式之间的相互转换延展:基于Py

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.