《贪吃蛇小游戏 1.0》源码

好久不见!

终于搞好了简易版贪吃蛇小游戏(C语言版),邀请你来玩一下~

目录

Snake.h

Snake.c

test.c


Snake.h

#include<stdio.h>
#include<windows.h>
#include<stdbool.h>
#include<stdlib.h>
#include<time.h>#define POS_X 24
#define POS_Y 5#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'//类型的声明//蛇的方向
enum DIRECTION
{UP,DOWN,LEFT,RIGHT
};//蛇的状态
//正常,撞墙,撞到自己,正常退出
enum GAME_STATUS
{OK,KILL_BY_WALL,KILL_BY_SELF,END_NORMAL
};//蛇身的节点类型
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 _food_weight;//一个食物的分数int _score;//总分数int _sleep_time;//休息时间,时间越短,速度越快,时间越长,速度越慢
}Snake, * pSnake;//函数的声明//定位光标的位置
void SetPos(short x, short y);//游戏的初始化
void GameStart(pSnake ps);//打印欢迎界面
void WelcomeToGame();//打印地图
void CreateMap();//初始化蛇身
void InitSnake(pSnake ps);//创建食物
void CreateFood(pSnake ps);//游戏运行的逻辑
void GameRun(pSnake ps);//蛇移动,走一步
void SnakeMove(pSnake ps);//判断下一个坐标是否是食物
int NextIsFood(pSnakeNode pn, pSnake ps);//下一个位置是食物,就吃掉食物
void EatFood(pSnakeNode pn, pSnake ps);//下一个位置不是食物
void NoFood(pSnakeNode pn, pSnake ps);//检测蛇是否撞墙
void KillByWall(pSnake ps);//检测蛇是否撞到自己
void KillBySelf(pSnake ps);//游戏善后的工作
void GameEnd(pSnake ps);

Snake.c

#include"Snake.h"//定位光标的位置
void SetPos(short x, short y)
{//获取标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定位控制台里面光标的位置COORD pos = { x,y };SetConsoleCursorPosition(houtput, pos);
}//打印欢迎界面
void WelcomeToGame()
{SetPos(46, 14);wprintf(L"欢迎来到贪吃蛇小游戏\n");SetPos(50, 20);//让“按任意位置继续”的位置好看些system("pause");system("cls");SetPos(30, 14);wprintf(L"用 ↑ . ↓ . ← . → 分别控制蛇的移动, F3为加速,F4为减速\n");SetPos(44, 16);wprintf(L"加速将能得到更高的分数\n");SetPos(48, 20);system("pause");system("cls");}//打印地图
void CreateMap()
{int i = 0;//上for (i = 0; i < 29; i++){wprintf(L"%c", WALL);}//下SetPos(0, 26);for (i = 0; i < 29; i++){wprintf(L"%c", WALL);}//左for (i = 1; i < 26; i++){SetPos(0, i);wprintf(L"%c", WALL);}//右for (i = 1; i < 26; i++){SetPos(56, i);wprintf(L"%c", WALL);}}//初始化蛇身
void InitSnake(pSnake ps)
{int i = 0;pSnakeNode cur = NULL;for (i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("InitSnake()::malloc()");return;}cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;//头插法插入链表if (ps->_pSnake == NULL)//指向蛇头的指针为空,空链表{ps->_pSnake = cur;}else//非空链表{cur->next = ps->_pSnake;ps->_pSnake = cur;}}//此时五个节点的链表已创建好,开始打印蛇身cur = ps->_pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//设置贪吃蛇的属性ps->_dir = RIGHT;//蛇的方向ps->_status = OK;//蛇的状态ps->_food_weight = 10;//一个食物的分数ps->_score = 0;//总分数ps->_sleep_time = 200; //单位是毫秒}//创建食物
void CreateFood(pSnake ps)
{int x = 0;int y = 0;//x生成是2的倍数//x:2~54//y:1~25
again:do{x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 != 0);//食物的坐标和蛇身结点的坐标不能冲突pSnakeNode cur = ps->_pSnake;while (cur){if (cur->x == x && cur->y == y){goto again;}cur = cur->next;}//创建食物的节点pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));if (pFood == NULL){perror("CreateFood()::malloc()");return;}pFood->x = x;pFood->y = y;pFood->next = NULL;SetPos(x, y);wprintf(L"%lc", FOOD);ps->_pFood = pFood;
}void GameStart(pSnake ps)
{//0.先设置窗口大小,再光标隐藏system("mode con cols=115 lines=30");system("title 贪吃蛇");HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false; //隐藏控制台光标SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态//1.打印游戏界面 + 功能介绍WelcomeToGame();//2.绘制地图CreateMap();//3.创建蛇InitSnake(ps);//4.创建食物CreateFood(ps);
}//右侧提示信息的打印
void PrintHelpInfo()
{SetPos(67, 12);wprintf(L"%ls", L"提示信息如下:");SetPos(67, 14);wprintf(L"%ls", L"1.不能穿墙,不能咬到自己");SetPos(67, 15);wprintf(L"%ls", L"2.用 ↑ . ↓ . ← . → 分别控制蛇的移动");SetPos(67, 16);wprintf(L"%ls", L"3.按F3加速,按F4减速");SetPos(67, 20);wprintf(L"%ls", L"云边有个稻草人@版权");
}#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)//暂停游戏
void Pause()
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE)){break;}}
}//判断下一个节点是否是食物
int NextIsFood(pSnakeNode pn, pSnake ps)
{return (ps->_pFood->x == pn->x && ps->_pFood->y == pn->y);
}//吃食物
void EatFood(pSnakeNode pn, pSnake ps)
{//头插法将食物插入链表ps->_pFood->next = ps->_pSnake;ps->_pSnake = ps->_pFood;//释放下一个位置的节点free(pn);pn = NULL;pSnakeNode cur = ps->_pSnake;//打印蛇while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->_score += ps->_food_weight;//重新创建食物CreateFood(ps);}void NoFood(pSnakeNode pn, pSnake ps)
{//头插pn->next = ps->_pSnake;ps->_pSnake = pn;//打印蛇身pSnakeNode cur = ps->_pSnake;while (cur->next->next != NULL){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//将最后一个节点打印成空白字符SetPos(cur->next->x, cur->next->y);printf("  ");//释放最后一个节点free(cur->next);//将倒数第二个节点的地址置为空cur->next = NULL;
}void KillByWall(pSnake ps)
{if (ps->_pSnake->x == 0 || ps->_pSnake->x == 56 || ps->_pSnake->y == 0 || ps->_pSnake->y == 26){ps->_status = KILL_BY_WALL;}
}void KillBySelf(pSnake ps)
{pSnakeNode cur = ps->_pSnake->next;while (cur){if (ps->_pSnake->x == cur->x && ps->_pSnake->y == cur->y){ps->_status = KILL_BY_SELF;break;}cur = cur->next;}
}void SnakeMove(pSnake ps)
{//创建一个节点,表示蛇即将到达的下一个节点pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNextNode == NULL){perror("SnakeMove()::malloc()");return;}switch (ps->_dir){case UP:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y - 1;break;case DOWN:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y + 1;break;case LEFT:pNextNode->x = ps->_pSnake->x - 2;pNextNode->y = ps->_pSnake->y;break;case RIGHT:pNextNode->x = ps->_pSnake->x + 2;pNextNode->y = ps->_pSnake->y;break;}//检测下一个坐标处是否是食物if (NextIsFood(pNextNode, ps)){EatFood(pNextNode, ps);}else{NoFood(pNextNode, ps);}//检测蛇是否撞墙KillByWall(ps);//检测蛇是否撞到自己KillBySelf(ps);
}//运行游戏
void GameRun(pSnake ps)
{//打印帮助信息PrintHelpInfo();do{//打印总分数和食物的分值SetPos(64, 10);printf("总分数:%d\n", ps->_score);SetPos(64, 11);printf("每个食物得分:%2d\n", ps->_food_weight);if (KEY_PRESS(VK_UP) && ps->_dir != DOWN){ps->_dir = UP;}else if (KEY_PRESS(VK_DOWN) && ps->_dir != UP){ps->_dir = DOWN;}else if (KEY_PRESS(VK_LEFT) && ps->_dir != RIGHT){ps->_dir = LEFT;}else if (KEY_PRESS(VK_RIGHT) && ps->_dir != LEFT){ps->_dir = RIGHT;}else if (KEY_PRESS(VK_SPACE)){Pause();}else if (KEY_PRESS(VK_ESCAPE)){ps->_status = END_NORMAL;}else if (KEY_PRESS(VK_F3)){if (ps->_sleep_time > 80){ps->_sleep_time -= 30;ps->_food_weight += 2;//⼀个⻝物分数最⾼是20分}}else if (KEY_PRESS(VK_F4)){if (ps->_sleep_time > 2){ps->_sleep_time += 30;ps->_food_weight -= 2;//⼀个⻝物分数最低是2分}}//蛇每次⼀定之间要休眠的时间,时间短,蛇移动速度就快Sleep(ps->_sleep_time);SnakeMove(ps);} while (ps->_status == OK);
}//游戏善后工作
void GameEnd(pSnake ps)
{SetPos(44, 12);switch (ps->_status){case END_NORMAL:printf("您主动退出游戏\n");break;case KILL_BY_WALL:printf("撞到墙上了,游戏结束\n");break;case KILL_BY_SELF:printf("撞到自己了,游戏结束\n");break;}//释放蛇身的链表pSnakeNode cur = ps->_pSnake;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
}

test.c

#include<locale.h>
#include "Snake.h"//完成的是游戏的测试逻辑
void test()
{int ch = 0;do{system("cls");//创建贪吃蛇Snake snake = { 0 };//初始化游戏//1.打印游戏界面//2.功能介绍//3.绘制地图//4.创建蛇//5.创建食物//6.设置游戏的相关信息GameStart(&snake);//运行游戏GameRun(&snake);//结束游戏GameEnd(&snake);SetPos(30, 15);printf("再来一局吗? Y/N");ch = getchar();while (getchar() != '\n');} while (ch == 'Y' || ch == 'y');SetPos(0, 27);
}int main()
{setlocale(LC_ALL, "");srand((unsigned int)time(NULL));test();return 0;
}


分享一首宝藏歌曲 

Not Angry_Chris James_高音质在线试听_Not Angry歌词|歌曲下载_酷狗音乐

如有不正确的地方不妨大胆的提出来哦~

我是云边有个稻草人

期待与你的下一次相遇

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 11 Container with Most Water 解题思路和python代码

题目&#xff1a; You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]). Find two lines that together with the x-axis form a container, such that the co…

基于comsol模拟微穿孔板和卷曲通道的混合吸声器低频吸声

研究背景&#xff1a; 具有深亚波长厚度&#xff08;5cm&#xff09;的吸收器对低频声音&#xff08;<500Hz&#xff09;的衰减在噪声控制工程中引起了极大的兴趣。然而&#xff0c;由于低频声音的强穿透性和普通材料的弱固有分散性&#xff0c;这是一项具有挑战性的任务。…

算法知识点————贪心

贪心&#xff1a;只考虑局部最优解&#xff0c;不考虑全部最优解。有时候得不到最优解。 DP&#xff1a;考虑全局最优解。DP的特点&#xff1a;无后效性&#xff08;正在求解的时候不关心前面的解是怎么求的&#xff09;&#xff1b; 二者都是在求最优解的&#xff0c;都有最优…

电脑无法无线投屏的解决办法

在前司的时候经常遇到电脑无法使用无线投屏器的情况&#xff0c;今天就来聊聊如何解决。 1.不会连接。这种情况&#xff0c;经常发生在WIN10升级WIN11之后&#xff0c;一般是两种办法&#xff0c;一种是同时按键盘上的WINDOWS和K键&#xff0c;右下角就会出来连接的图标&#…

TryHackMe 第7天 | Web Fundamentals (二)

继续介绍一些 Web hacking 相关的漏洞。 IDOR IDOR (Insecure direct object reference)&#xff0c;不安全的对象直接引用&#xff0c;这是一种访问控制漏洞。 当 Web 服务器接收到用户提供的输入来检索对象时 (包括文件、数据、文档)&#xff0c;如果对用户输入数据过于信…

kubelet 运行机制、功能 全面分析

Kubelet 在Kubernetes集群中&#xff0c;在每个Node&#xff08;又称为Minion&#xff09;上都会启动一个Kubelet服务进程。该进程用于处理Master下发到本节点的任务&#xff0c;管理Pod及Pod中的容器。每个Kubelet进程都会在API Server上注册节点自身的信息&#xff0c;定期向…

攻防世界----->Replace

前言&#xff1a;做题笔记。 下载 查壳。 upx32脱壳。 32ida打开。 先运行看看&#xff1a; 没有任何反应&#xff1f; 猜测又是 地址随机化(ASLR)---遇见过。 操作参考&#xff1a; 攻防世界----&#xff1e;Windows_Reverse1_dsvduyierqxvyjrthdfrtfregreg-CSDN博客 然后…

算法6:模拟运算

文章目录 z字形变幻外观数列数青蛙 题目均来自于力扣 z字形变幻 class Solution { public:string convert(string s, int numRows) {int n s.size();if(n < numRows || numRows 1) return s;int d 2 * numRows - 2;string res;for(int j 0; j < n; j d){res s[j]; …

嵌入式硬件设计知识详解

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

游戏盒子推广全攻略:从用户洞察到策略实施

在移动互联网时代&#xff0c;游戏盒子的推广已经成为众多游戏代理商和开发者的重要课题。面对激烈的市场竞争&#xff0c;如何高效吸引并留住玩家&#xff0c;成为游戏盒子推广的关键。本文将结合Xinstall这一专业App推广工具&#xff0c;探讨游戏盒子推广的有效策略。 一、市…

爱心曲线公式大全

local r a*((math.sin(angle) * math.sqrt(math.abs(math.cos(angle)))) / (math.sin(angle) 1.4142) - 2 * math.sin(angle) 2) local x r * math.cos(angle) -- 计算对应的x值 local z r * math.sin(angle) 1.5*a - --曲线公式绘画 local function generateParabola()…

VMware Tools 安装和配置

1. 使用 ISO 映射文件&#xff0c;并且选择.iso文件 2. 启动虚拟机&#xff0c;如果 VMware Tools 是灰色的&#xff0c;那么卸载 open-vm-tools&#xff08;不要重装&#xff09;&#xff0c;重新启动虚拟机。卸载可以参考&#xff1a;重装 open-vm-tools-CSDN博客 3. 拷贝挂载…

关于mac下的nvm设置淘宝镜像源

1. 进入配置文件修改镜像源 vim ~/.bash_profile增加下面内容 export NVM_NODEJS_ORG_MIRRORhttps://npmmirror.com/mirrors/node/2. 查看远程node镜像 nvm ls-remote3. 下载镜像 nvm install 14.17.64. 使用镜像 nvm use 14.17.6

Vue入门-指令学习-v-show和v-if

v-show&#xff1a; 作用&#xff1a;控制元素的显示隐藏 语法&#xff1a;v-show"表达式" 表达式值true显示&#xff0c;false隐藏 v-if 作用&#xff1a;控制元素的显示隐藏&#xff08;条件渲染&#xff09; 语法&#xff1a; vif"表达式" 表达式tr…

No.8 笔记 | SQL 查询语句:数据探索的钥匙

2024/10/7 心记 - 致在路上默默奋斗的你 在当今数字化的时代&#xff0c;网络安全已成为我们生活中不可或缺的一部分。它如同守护数字世界的隐形盾牌&#xff0c;保护着我们的隐私、数据和整个社会的稳定运行。 学习网络安全&#xff0c;是踏上一段充满挑战与机遇的征程。 每一…

leetcode C++特性 AIDL的一些细节

leetcode细节 C的一些特性 【C基础】std::move用法介绍-CSDN博客 c thread的join和joinable的区别_thread joinable-CSDN博客 C线程介绍_std::thread 头文件-CSDN博客 https://blog.csdn.net/weixin_46645965/article/details/136259902 【C】—— 观察者模式-CSDN博客 C 迭…

知识图谱入门——5:Neo4j Desktop安装和使用手册(小白向:Cypher 查询语言:逐步教程!Neo4j 优缺点分析)

Neo4j简介 Neo4j 是一个基于图结构的 NoSQL 数据库&#xff0c;专门用于存储、查询和管理图形数据。它的核心思想是使用节点、关系和属性来描述数据。图数据库非常适合那些需要处理复杂关系的数据集&#xff0c;如社交网络、推荐系统、知识图谱等领域。 与传统的关系型数据库…

erlang学习:Linux命令学习9

sed命令介绍 sed全称是&#xff1a;Stream EDitor&#xff08;流编辑器&#xff09; Linux sed 命令是利用脚本来处理文本文件&#xff0c;sed 可依照脚本的指令来处理、编辑文本文件。Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等 sed 的运行…

Windows环境下使用Docker配置MySQL数据库

用Docker配置数据库&#xff0c;无论是做开发&#xff0c;还是做生产部署&#xff0c;都非常的方便 它不需要单独安装数据库&#xff0c;也不用担心出现各种环境的配置问题。 本文将分享用Docker配置数据库的步骤&#xff0c;这里用MySQL举例。 其他的数据库如MSSQL&#xf…

信息学奥赛复赛复习14-CSP-J2021-03网络连接-字符串处理、数据类型溢出、数据结构Map、find函数、substr函数

PDF文档回复:20241007 1 P7911 [CSP-J 2021] 网络连接 [题目描述] TCP/IP 协议是网络通信领域的一项重要协议。今天你的任务&#xff0c;就是尝试利用这个协议&#xff0c;还原一个简化后的网络连接场景。 在本问题中&#xff0c;计算机分为两大类&#xff1a;服务机&#x…