贪吃蛇小游戏(c语言)

1.效果展示

屏幕录制 2024-04-28 205129

2.基本功能

贪吃蛇地图绘制
蛇吃食物的功能 (上、下、左、右方键控制蛇的动作)
蛇撞墙死亡
蛇撞自身死亡
计算得分
蛇身加速、减速
暂停游戏

3.技术要点

C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。

4.WIN32 API

WIN32 API是windows操作系统最基本的API之一,它定义了windows操作系统的各种操作的函数和数据结构,WIN32 API也就是Windows 32位平台的应用程序编程接口。

4.1控制台程序

我们平时运行代码的时候那个黑色框程序其实就是控制台程序

然后可以使用cmd命令来控制黑色框的长度和宽度:设置控制台窗口的大小:200行,50列

mode con cols=200 lines=50

参考:mode | Microsoft Learn

然后通过命令来修改控制台名字

title 贪吃蛇

效果:

参考:mode | Microsoft Learn

通过c语言的system函数来实现:

#include <stdio.h>
int main()
{
 //设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,50⾏,200列
 system("mode con cols=200 lines=50");
 //设置cmd窗⼝名称
 system("title 贪吃蛇"); 
 return 0;
}
4.2控制屏幕上的坐标COORD

参考:COORD 结构 - Windows Console | Microsoft Learn

COORD是windowsAPI中定义的一个结构体,它可以表示字符在屏幕上的坐标,最左上角的位置坐标是(0,0)。

COORD类型的声明:
typedef struct _COORD {
 SHORT X;
 SHORT Y;
} COORD, *PCOORD;

给坐标赋值:

COORD pos = { 10, 15 };
4.3.GetStdHandle(简单了解会用即可)

相关了解:GetStdHandle 函数 - Windows Console | Microsoft Learn

GetStdHandle是⼀个Windows API函数。它用于从⼀个特定的标准设备(标准输入、标准输出或标准错误)中取得⼀个句柄(用来标识不同设备的数值),使用这个句柄可以操作设备。
 HANDLE GetStdHandle(DWORD nStdHandle);

例:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

HANDLE是一种类型;

4.4.GetConsoleCursorInfo(会用即可)
相关了解: GetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

例:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
4.5.CONSOLE_CURSOR_INFO(简单了解会用即可)

这是一个结构体,包含了控制台的光标的相关信息:

typedef struct _CONSOLE_CURSOR_INFO {
 DWORD dwSize;
 BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

其中

dwSize,由光标填充的字符单元格的百分比。 此值介于1到100之间。 光标外观会变化,范围从完全填充单元格到单元底部的水平线条。
bVisible,游标的可见性。 如果光标可见,则此成员为 TRUE。
例:
CursorInfo.bVisible = false; //隐藏控制台光标
4.6.SetConsoleCursorInfo(简单了解会用即可)

相关了解:SetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

SetConsoleCursorInfo可以 设置指定控制台屏幕缓冲区的光标的大和可见性
例:
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态
4.7.SetConsoleCursorPosition(简单了解会用即可)

相关了解:SetConsoleCursorPosition 函数 - Windows Console | Microsoft Learn

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调用SetConsoleCursorPosition函数将光标位置设置到指定的位置。
例:
COORD pos = { 10, 5};
 HANDLE hOutput = NULL;
 //获取标准输出的句柄(⽤来标识不同设备的数值)
 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 //设置标准输出上光标的位置为pos
 SetConsoleCursorPosition(hOutput, pos);

写贪吃蛇时为了方便可以将上面的初始化信息封装成一个函数

例:

//设置光标的坐标
void SetPos(short x, short y)
{
	//取句柄
	HANDLE hOutput = NULL;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	//移动光标位置
	COORD pos = { x, y };
	SetConsoleCursorPosition(hOutput, pos);
}
4.8.GetAsyncKeyState(简单了解会用即可)

相关了解:getAsyncKeyState 函数 (winuser.h) - Win32 apps | Microsoft Learn

键盘中每个按键都有与之对应的虚拟值。

获取按键情况,GetAsyncKeyState的函数原型如下:
SHORT GetAsyncKeyState(
 int vKey
);
GetAsyncKeyState 的返回值是short类型,在上⼀次调用 GetAsyncKeyState 函数后,如果返回的16位的short数据中,最高位是1,说明按键的状态是按下,如果最高是0,说明按键的状是抬起;如果最低位被置为1则说明,该按键被按过,否则为0。如果要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.
我们可以定义宏:
#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

虚拟键:虚拟键码 (Winuser.h) - Win32 apps | Microsoft Learn

5.地图

游戏地图效果:

其中有一些宽字符想要打印还要再作一些处理

5.1<locale.h>本地化(简单了解会用即可)
<locale.h>提供的函数用于控制C标准库中对于不同的地区会产生不⼀样行为的部分。
在标准中,依赖地区的部分有以下几项:
数字量的格式
货币量的格式
字符集
日期和时间的表示形式
这里我们主要是获得字符的修改。
5.2.类项

通过修改地区,程序可以改变它的行为来适应世界的不同区域。但地区的改变可能会影响库的许多部分,其中⼀部分可能是我们不希望修改的。所以C语言支持针对不同的类项进行修改,下面的⼀个宏,指定⼀个类项:
LC_COLLATE:影响字符串比较函数 strcoll() strxfrm()
LC_CTYPE:影响字符处理函数的行为。
LC_MONETARY:影响货币格式。
LC_NUMERIC:影响 printf() 的数字格式。
LC_TIME:影响时间格式 strftime() wcsftime()
LC_ALL - 针对所有类项修改,将以上所有类别设置为给定的语言环境。
相关了解: setlocale,_wsetlocale | Microsoft Learn
5.3setlocale函数
char* setlocale (int category, const char* locale);
setlocale 函数用于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。
setlocale 的第⼀个参数可以是前面说明的类项中的⼀个,那么每次只会影响⼀个类项,如果第⼀个参数是LC_ALL,就会影响所有的类项。
C标准给第二个参数仅定义了2种可能取值: "C" (正常模式)和 " " (本地模式)。
在任意程序执行开始,都会隐藏式执行调用:
setlocale(LC_ALL, "C");
当地区设置为"C"时,库函数按正常方式执行,小数点是⼀个点。
当程序运行起来后想改变地区,就只能显示调用setlocale函数。用" "作为第2个参数,调用setlocale 函数就可以切换到本地模式,这种模式下程序会适应本地环境。
比如:切换到我们的本地模式后就支宽字符(汉字)的输出等。
setlocale(LC_ALL, " ");//切换到本地环境
5.4.宽字符的打印
宽字符的字面量必须加上前缀“L”,否则 C 语言会把字面量当作窄字符类型处理。前缀“L”在单引
号前面,表示宽字符,对应 wprintf() 的占位符为 %lc ;在双引号前,表示宽字符串,对应 wprintf() 的占位符为 %ls
例:
#include<locale.h>
int main() {
 setlocale(LC_ALL, "");
 wchar_t ch1 = L'●';
 wchar_t ch2 = L'晚';
 wchar_t ch3 = L'成';
 wchar_t ch4 = L'★';
 
 printf("%c%c\n", 'a', 'b');
 
 wprintf(L"%lc\n", ch1);
 wprintf(L"%lc\n", ch2);
 wprintf(L"%lc\n", ch3);
 wprintf(L"%lc\n", ch4);
 return 0;
}

输出结果:

这里看到一个汉字或者一个宽字符需要占两个字符的位置,所以我们打印地图和对蛇,食物的坐标进行处理时一定要注意。

5.5.地图坐标

我们要设置一个40行,54列的地图:

5.6蛇身和食物
初始化状态,假设蛇是连续5个节点。
注意:蛇的每个节点的x坐标必须是2个倍数,否则可能会出现蛇的⼀个节点有⼀半出现在墙体中,
另外一半在墙外的现象,坐标不好对齐。
关于食物,就是在墙体内随机生成⼀个坐标(x坐标必须是2的倍数),坐标不能和蛇的身体重合,然后打印★。
效果如上图:
5.7数据结构设计

蛇每吃一个食物,蛇身就会变长一节,因此我们可以用链表来存蛇的信息,每一个结点只要记录好蛇的坐标就行,食物同样也是用这个链表来存。

typedef struct SnakeNode
 {
 int x;
 int y;
 struct SnakeNode* next;
}SnakeNode, * pSnakeNode;

然后维护蛇还要一个结构体:

typedef struct Snake
{
 pSnakeNode _pSnake;//维护整条蛇的指针
 pSnakeNode _pFood;//维护⻝物的指针
 enum DIRECTION _Dir;//蛇头的⽅向,默认是向右
 enum GAME_STATUS _Status;//游戏状态
 int _Socre;//游戏当前获得分数
 int _foodWeight;//默认每个⻝物10分
 int _SleepTime;//每⾛⼀步休眠时间
}Snake, * pSnake;

蛇的方向可以用枚举:

//⽅向
enum DIRECTION
{
 UP = 1,
 DOWN,
 LEFT,
 RIGHT
};

游戏的状态:

//游戏状态
enum GAME_STATUS
{
 OK,//正常运⾏
 KILL_BY_WALL,//撞墙
 KILL_BY_SELF,//咬到⾃⼰
 END_NOMAL//正常结束
};

6.游戏流程

7.游戏参考代码

c语言: 储存c代码 - Gitee.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/599402.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux搭建http发布yum源

1、搭建http源yum仓库 &#xff08;1&#xff09;在yum仓库服务端安装httpd yum -y install httpd &#xff08;2&#xff09;修改配置文件 我们httpd 中默认提供web 界面的位置是我们/var/www/html 目录&#xff0c;如果我们yum 源想指定目录&#xff0c;就需要修改蓝框2处…

【第6节课笔记】LagentAgentLego

Lagent 最中间部分的是LLM&#xff0c;即为大语言模型模块&#xff0c;他可以思考planning和调用什么action&#xff0c;再将其转发给动作执行器action executer执行。 支持的工具如下&#xff1a; Arxiv 搜索 Bing 地图 Google 学术搜索 Google 搜索 交互式 IPython 解释器 IP…

STM32循迹小车系列教程(三)—— 使用灰度传感器循迹

本章节主要讲解如何获取灰度传感器值以及如何使用灰度传感器循迹 灰度传感器简介 灰度传感器如图 1 所示&#xff1a; 灰度传感器 使用一对抗干扰较强的光电传感器&#xff0c;其中发射管的光源采用高亮白色聚光 LED&#xff0c;发射管端发出的光线通过不同环境背景的反射之…

软件系统安全设计规范(word原件)

1.1安全建设原则 1.2 安全管理体系 1.3 安全管理规范 1.4 数据安全保障措施 1.4.1 数据库安全保障 1.4.2 操作系统安全保障 1.4.3 病毒防治 1.5安全保障措施 1.5.1实名认证保障 1.5.2 接口安全保障 1.5.3 加密传输保障 1.5.4终端安全保障 软件资料清单列表部分文档…

嵌入式全栈开发学习笔记---C语言笔试复习大全13(编程题9~16)

目录 9.查找字符数组中字符位置&#xff08;输入hello e 输出2&#xff09;&#xff1b; 10、查找字符数组中字符串的位置&#xff08;输入hello ll 输出3&#xff09;&#xff1b; 11、字符数组中在指定位置插入字符&#xff1b;&#xff08;输入hello 3 a 输出heallo…

编程算法赛

1偶数累加 2、统计字符的数量 3、计算表达式的值 4、哥德巴赫猜想 5、进制的转换

英语学习笔记5——Nice to meet you.

Nice to meet you. 很高兴见到你。 词汇 Vocabulary Mr. 先生 用法&#xff1a;自己全名 / 姓 例如&#xff1a;Mr. Zhang Mingdong 或 Mr. Zhang&#xff0c;绝对不能是 Mr. Mingdong&#xff01; Miss 女士&#xff0c;小姐 未婚 用法&#xff1a;自己全名 / 姓 例如&#…

【论文阅读】Fuzz4All: Universal Fuzzing with Large Language Models

文章目录 摘要一、介绍二、Fuzz4All的方法2.1、自动提示2.1.1、自动提示算法2.1.2、自动提示的例子2.1.3、与现有自动提示技术的比较 2.2、fuzzing循环2.2.1、模糊循环算法2.2.2、Oracle 三、实验设计3.1、实现3.2、被测系统和baseline3.3、实验设置以及评估指标 四、结果分析4…

P8801 [蓝桥杯 2022 国 B] 最大数字

P8801 [蓝桥杯 2022 国 B] 最大数字 分析 dfs 思路&#xff1a;题目的意思&#xff0c;要让一个数最大&#xff0c;用贪心去考虑&#xff0c;从高位开始&#xff0c;对其进行a / b操作&#xff0c;使其变为9&#xff0c;可让该数最大 1.a 操作&#xff1a;1&#xff1b;b 操…

嵌入式学习<1>:建立工程、GPIO

嵌入式学习_part1 本部分笔记用于学习记录&#xff0c;笔记源头 >>b站江科大_STM32入门教程 建立工程、GPIO 开发环境&#xff1a;keil MDK、STM32F103C8T6 1 &#xff09;建立工程 &#xff08;1&#xff09;基于寄存器开发、基于标准库 或者 基于HAL库开发; &…

【代码随想录——哈希表】

1.哈希表理论基础 首先什么是 哈希表&#xff0c;哈希表&#xff08;英文名字为Hash table&#xff0c;国内也有一些算法书籍翻译为散列表&#xff0c;大家看到这两个名称知道都是指hash table就可以了&#xff09;。 那么哈希表能解决什么问题呢&#xff0c;一般哈希表都是用…

高素质高学历婚恋相亲交友平台有哪些?分享我的网上找对象成功脱单经历!

尽管觉得在社交软件上找到真爱的可能性很小&#xff0c;但我却时常看到别人成功的案例&#xff0c;这也让我跃跃欲试了。没想到&#xff0c;我真的成功了&#xff01;以下是我亲身使用过的一些方法&#xff0c;在此与大家分享&#xff0c;仅供参考哦&#xff01; &#x1f449;…

c++ cpp 在类中执行线程 进行恒定计算

在编程中&#xff0c;顺序执行是常见的模式&#xff0c;但是对cpu的利用率不是很高&#xff0c;采用线程池&#xff0c;又太麻烦了&#xff0c;原因是还得不断地把任务拆分&#xff0c;扫描返回值。 如果 初始化n个类的时候&#xff0c;传递数据自身即可异步计算&#xff0c;那…

六、文件查找

一、文件查找 1.查找文件内容 ​ 命令&#xff1a;grep keywords /dir_path/filename 2.查找系统命令 ​ 命令&#xff1a;which command 3.查找命令及配置文件位置 ​ 命令&#xff1a;whereis command 4.find查找 ​ find $find_path -name|-type|-perm|-size|-atime…

【前端】HTML基础(3)

文章目录 前言一、HTML基础1、表格标签1.1 基本使用1.2 合并单元格 2、列表标签2.1 无序列表2.2 有序列表2.3 自定义列表 3、 表单标签2.1 form标签2.2 input标签2.3 label标签2.4 select标签2.5 textarea标签 4、无语义标签5、HTML特殊字符 前言 这篇博客仅仅是对HTML的基本结…

RVM(相关向量机)、CNN_RVM(卷积神经网络结合相关向量机)、RVM-Adaboost(相关向量机结合Adaboost)

当我们谈到RVM&#xff08;Relevance Vector Machine&#xff0c;相关向量机&#xff09;、CNN_RVM&#xff08;卷积神经网络结合相关向量机&#xff09;以及RVM-Adaboost&#xff08;相关向量机结合AdaBoost算法&#xff09;时&#xff0c;每种模型都有其独特的原理和结构。以…

streamlit通过子目录访问

运行命令&#xff1a; streamlit hello 系统默认使用8501端口启动服务&#xff1a; 如果想通过子目录访问服务&#xff0c;可以这么启动服务 streamlit hello --server.baseUrlPath "app" 也可以通过以下命令换端口 streamlit hello --server.port 9999 参考&…

2024最新CTF入门的正确路线

目录 前言 一、什么是CTF比赛&#xff1f; 二、CTF比赛的流程 三、需要具备的知识 四、总结 前言 随着网络安全意识的增强&#xff0c;越来越多的人开始涉足网络安全领域&#xff0c;其中CTF比赛成为了重要的学习和竞赛平台。本人从事网络安全工作多年&#xff0c;也参加过…

甲小姐对话柳钢:CEO对股东最大的责任,是对成功的概率负责|甲子光年

只有看见最微小的事物&#xff0c;才能洞悉伟大的定律。 来源&#xff5c;甲子光年 作者&#xff5c;甲小姐 刘杨楠 编辑&#xff5c;栗子 商业史上&#xff0c;职业经理人成为“空降CEO”的故事往往胜少败多。 “究其原因有三条——容易自嗨、喊口号&#xff1b;不顾公司历…