C++ 适合新手的贪吃蛇小项目
这是我的第一个C项目虽然很简短 但写完还是蛮有成就感的1.设计思路如何设计蛇身可以看作一个双端队列队头是蛇头队尾为蛇通过出入队来控制蛇身。如何移动蛇身可以简化为只有头和尾动中间的部分并不需要移动。控制光标移动打印新蛇头删除旧蛇尾即可。如何检测碰撞因为程序很小可以设置一个数组记录每个坐标是否已有实体每次移动检测蛇头的坐标。2.可能遇到的问题打印格式错乱该项目在终端中运行windows终端默认大小为80*40而地图为120*40可能需要重新设置终端的显示大小和缓冲区大小。输入时注意是否超过缓冲区大小如果超过会导致一些意外的错误。比如终端大小80*40缓冲区120*40你每行输入100个字符可能开始几行显示正常但后面可能会出现如直接跳过输入的错误。坐标错乱坐标是从(0,0)开始如果程序开始之前终端有其他输入会导致坐标错乱。最好先使用cls清空终端。无法自动的移动问题_getch()是阻塞式输入会一直等待用户输入期间暂停程序的运行。使用_kbhit()它会检测是否有待输入内容如果无就返回不会阻塞程序运行。3.代码展示#pragma once #include iostream #include deque #include windows.h #include ctime #include vector #include conio.h #include algorithm using namespace std; struct Snake { char image; // 用于表示蛇身体的图标 short x, y; // 坐标 }; class snakeGame { private: enum MapSize { height 40, // x width 120 // y }; // 地图尺寸行高40列宽120 HANDLE hout; // 控制台输出句柄用于光标操作 COORD pos; // 光标位置的结构题 char dir; // 蛇头移动方向 double speed 300; // 移动速度 dequeSnake snake; // 双端队列队头为蛇头队尾为蛇尾 short food_x, food_y; // 食物的坐标 int score 0; // 得分 // 不要用bool其在c中位压缩1bit一个bool无法取元素地址且访问慢 vectorchar maptag; // 时间换空间标记地图坐标0表示安全1表示墙或蛇身 public: snakeGame(); // 构造函数 void printMap(); // 创建地图 void displayInfo(); // 显示得分速度蛇长 void gotoxy(short x, short y); // 将控制台光标移动到(x,y)处 void HideCursor(); // 隐藏光标让画面更干净 void initSnake(); // 初始化蛇身 void printSnakeHead(); // 打印蛇头 int WrongLocation(); // 判断食物生产位置是否和蛇身冲突 void createFood(); // 生产食物 void clearSnaketail(Snake tail); // 擦除蛇尾用空格覆盖 void judgeCrash(const Snake ); // 检测蛇头是否撞墙或与蛇身重叠 void foodEaten(); // 当蛇吃到食物加分加速生产新食物 void userInput(); // 处理用户输入 };#include snake.h void snakeGame::gotoxy(short x, short y) { // STD_OUTPUT_HANDLE 申请操作标准输出设备的权限 // GetStdHandle 是系统给的句柄后面队屏幕的操作需要使用这个通行证 hout GetStdHandle(STD_OUTPUT_HANDLE); pos {x, y}; // SetConsoleCursorPosition是Windows系统提供的底层移动函数 // hout告诉系统哪个设备pos告诉系统将光标放在哪个坐标 SetConsoleCursorPosition(hout, pos); } void snakeGame::displayInfo() { // 使用固定的两行显示信息 gotoxy(0, height 3); cout 速度: speed ms ; cout 得分: score ; cout 蛇长: snake.size() ; } void snakeGame::printMap() { // height 40,width 120 // 注意终端尺寸不要超出了不然会显示错误 maptag.assign(height * width, 0); short i; for (i 0; i width; i) { cout #; maptag[static_castsize_t(i)] 1; // 标记格子被占用 } cout i; for (i 1; i height - 1; i) { gotoxy(0, i); // 光标移到(0,i) cout #; maptag[static_castsize_t(i * width)] 1; gotoxy(width - 1, i); cout # i; maptag[static_castsize_t((i 1) * width - 1)] 1; } gotoxy(0, height - 1); int temp (height - 1) * width; for (i 0; i width; i) { cout #; maptag[static_castsize_t(temp i)] 1; } cout i; cout \n贪吃蛇: 1.按方向键开始游戏 2. * 代表食物 3.空格暂停游戏\n 4.按\v\加快速度 5. 按\b\减慢速度\n; } void snakeGame::HideCursor() { HANDLE handle GetStdHandle(STD_OUTPUT_HANDLE); // 获取屏幕控制许可 CONSOLE_CURSOR_INFO CursorInfo; // 创建一个光标信息体变量存放光标 GetConsoleCursorInfo(handle, CursorInfo); // 用句柄去系统那将当前光标取出来存放到CursorInfo里 CursorInfo.bVisible false; // 光标不可见 SetConsoleCursorInfo(handle, CursorInfo); // 把修改后的光标信息写回系统让设置生效 } void snakeGame::initSnake() { // 初始化蛇身并打印 snake.push_front({, width / 2, height / 2}); maptag[height / 2 * width width / 2] 1; gotoxy(width / 2, height / 2); cout ; for (short i 0; i 2; i) { short x width / 2; short y static_castshort(height / 2 i 1); snake.push_back({, x, y}); maptag[static_castsize_t(y * width x)] 1; gotoxy(x, y); cout ; } } void snakeGame::printSnakeHead() { // 蛇移动只用处理蛇头和蛇尾其余部分无需处理 auto iter snake.begin(); gotoxy(iter-x, iter-y); cout iter-image; // 新蛇头 iter; gotoxy(iter-x, iter-y); cout (iter-image ); // 原来的蛇头变蛇身重新打印 } int snakeGame::WrongLocation() { if (maptag[static_castsize_t(food_x food_y * width)] 1) return 1; return 0; } void snakeGame::createFood() { do { food_x static_castshort(rand() % (width - 2) 2); food_y static_castshort(rand() % (height - 2) 2); } while (WrongLocation()); gotoxy(food_x, food_y); cout *; } void snakeGame::clearSnaketail(Snake tail) { // 用空格覆盖蛇尾而非清屏避免了闪烁 gotoxy(tail.x, tail.y); cout ; maptag[static_castsize_t(tail.y * width tail.x)] 0; } void snakeGame::judgeCrash(const Snake s) { // 检查是否碰撞 if (maptag[static_castsize_t(s.y * width s.x)] 1) { gotoxy(width / 2 - 10, height / 2); cout 游戏结束你的分数是 score 分(回车继续) endl; dir static_castchar(_getch()); runtime_error quit(游戏结束正常退出); throw quit; } } void snakeGame::foodEaten() { speed max(speed*0.8, 100.0); score; createFood(); } void snakeGame::userInput() { char ch; switch (ch static_castchar(_getch())) // 输入控制带反向检测 { case W: case w: if (dir ! s) dir w; break; case S: case s: if (dir ! w) dir s; break; case A: case a: if (dir ! d) dir a; break; case D: case d: if (dir ! a) dir d; break; case V: case v: speed max(speed * 0.9, 100.0); displayInfo(); break; case B: case b: speed * 1.5; displayInfo(); break; case : gotoxy(width / 2, height); cout 游戏已暂停任意键继续; _getch(); gotoxy(width / 2, height); cout ; break; default: break; } } snakeGame::snakeGame() { system(mode con cols128 lines64); // 设置终端大小 system(cls); // 清空屏幕 HideCursor(); // 隐藏光标 srand(static_castunsigned int(time(NULL))); // 随机种子 maptag.assign(width * height, 0); // 初始化maptag Snake head, tail; // 蛇头和蛇尾 printMap(); // 打印地图 initSnake(); // 初始化蛇身 head snake.front(); // 蛇头 tail snake.back(); // 蛇尾 dir w; // 默认初始向上移动 createFood(); // 创建食物 while (true) { // _getch()是阻塞式输入程序等待用户输入在此期间程序会暂停执行 // _kbhit()检查缓冲区是否有等待输入的流如果没有就马上返回不会阻塞程序执行。 if (_kbhit()) { userInput(); // 处理用户输入 } if (dir s) // 更改蛇头坐标 { // 如果新头不合法游戏就结束所以直接修改原蛇头图标没有影响(只是修改无打印) snake.front().image ; head.y; } else if (dir w) { snake.front().image ; --head.y; } else if (dir a) { snake.front().image ; --head.x; } else if (dir d) { snake.front().image ; head.x; } // 判断是否撞墙或吃到自己 try { judgeCrash(head); // 这里的得用新的head因为snake.front()坐标处maptag肯定是1 } catch (runtime_error quitSignal) { throw quitSignal; } // 更新蛇头 snake.push_front(head); // 新蛇头入队 maptag[static_castsize_t(head.y * width head.x)] 1; printSnakeHead(); // 依据是否吃到食物更新蛇尾 if (head.x food_x head.y food_y) { foodEaten(); displayInfo(); } else { clearSnaketail(tail); // 没吃到食物就删除蛇尾 snake.pop_back(); // 尾元素出队 tail snake.back(); // 新蛇尾 } // 添加延迟不然蛇移动过快 Sleep(static_castDWORD(speed)); } }#include iostream #include snake.h int main() { try { snakeGame game; } catch (runtime_error gameEnd) { // 结束 system(cls); cout gameEnd.what(); getch(); } return 0; }

相关新闻

前端性能优化实战:从Lighthouse核心指标到自动化监控

前端性能优化实战:从Lighthouse核心指标到自动化监控

1. 项目概述:为什么我们需要一个“灯塔”来照亮前端性能?如果你是一名前端开发者,或者正在负责一个Web产品的用户体验,那么你一定对“页面加载慢”、“交互卡顿”、“用户流失率高”这些词不陌生。在追求极致用户体验的今天&#…

2026/8/2 7:07:09阅读更多 →
从星号梯形到循环控制:编程入门项目的深度解析与实践

从星号梯形到循环控制:编程入门项目的深度解析与实践

1. 从“画星星”到理解循环控制:一个被低估的编程入门项目很多编程新手在接触循环结构时,都觉得“画个星号梯形”这种题目太简单、太“小儿科”了,无非就是几个for循环嵌套,打印一堆*和空格。我刚开始学编程时也这么想&#xff0c…

2026/8/2 7:05:09阅读更多 →
照片视频丢失不要急!北京德智康多媒体素材数据恢复

照片视频丢失不要急!北京德智康多媒体素材数据恢复

照片视频丢失不要急!北京德智康多媒体素材数据恢复摄影师、短视频创作者、家庭用户的硬盘、存储卡里存放大量照片、原始视频素材。格式化存储卡、硬盘损坏、素材误删除,丢失的影像资料很难重新拍摄,损失难以估量。多媒体文件碎片多&#xff0…

2026/8/2 7:05:09阅读更多 →
GHelper:重新定义华硕笔记本硬件控制的轻量级架构革命

GHelper:重新定义华硕笔记本硬件控制的轻量级架构革命

GHelper:重新定义华硕笔记本硬件控制的轻量级架构革命 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, Ex…

2026/8/2 8:21:25阅读更多 →
Unity游戏自动翻译终极指南:5分钟实现全自动汉化

Unity游戏自动翻译终极指南:5分钟实现全自动汉化

Unity游戏自动翻译终极指南:5分钟实现全自动汉化 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 还在为外语Unity游戏而苦恼吗?XUnity.AutoTranslator为你提供了一站式解决方案&am…

2026/8/2 8:21:25阅读更多 →
OWASP TOP 10 2021核心风险解析与开发测试协同防御实践

OWASP TOP 10 2021核心风险解析与开发测试协同防御实践

1. 项目概述:为什么OWASP TOP 10是安全测试的“必修课”?如果你是一名开发者,可能觉得写代码实现功能是第一要务,安全是安全团队的事。如果你是一名测试工程师,或许认为功能测试、性能测试已经够忙了,安全测…

2026/8/2 8:21:25阅读更多 →
蛋白质语言模型与进化隔绝策略:AI驱动抗菌肽发现实战指南

蛋白质语言模型与进化隔绝策略:AI驱动抗菌肽发现实战指南

1. 项目概述:当AI“阅读”蛋白质,如何发现被进化遗忘的宝藏如果你关注过最近的生物技术新闻,可能会被“AI发现全新抗生素”这样的标题刷屏。这背后,一个核心的驱动力就是蛋白质语言模型。它不像我们熟知的ChatGPT那样处理人类语言…

2026/8/2 8:21:25阅读更多 →
基于ROS与激光雷达的移动机器人定点导航系统搭建与调优实践

基于ROS与激光雷达的移动机器人定点导航系统搭建与调优实践

1. 项目概述:从“能跑”到“会跑”的跨越如果你玩过松灵SCOUT MINI PRO,或者类似的四轮差速底盘,最开始的新鲜感可能就是让它前后左右动起来。但玩过几次后,一个更实际的需求就会冒出来:能不能让它自己从A点跑到B点&am…

2026/8/2 8:21:25阅读更多 →
从匹配滤波器到误码率:最佳接收技术在现代通信系统中的应用与实战

从匹配滤波器到误码率:最佳接收技术在现代通信系统中的应用与实战

1. 项目概述:从“最佳接收”说起,为什么它依然是通信工程师的必修课? 最近在调试一个CAN总线项目,客户反馈在特定工况下偶发数据错误,排查硬件和协议栈都没问题,最后把矛头指向了物理层的信号质量。为了定位…

2026/8/2 8:19:24阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:10阅读更多 →
限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

更多请点击: https://intelliparadigm.com 第一章:AI模板批量生成的核心价值与落地全景 AI模板批量生成正从实验性工具演进为现代软件工程的关键基础设施。它通过语义理解、上下文感知与结构化约束,将重复性高、模式明确的代码/文档/配置生成…

2026/8/2 0:00:12阅读更多 →
如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南 【免费下载链接】web-archives Browser extension for viewing archived and cached versions of web pages, available for Chrome, Edge and Safari 项目地址: https://gitcode.com/gh_mirrors/we/web-a…

2026/8/2 0:00:13阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:10阅读更多 →
限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

更多请点击: https://intelliparadigm.com 第一章:AI模板批量生成的核心价值与落地全景 AI模板批量生成正从实验性工具演进为现代软件工程的关键基础设施。它通过语义理解、上下文感知与结构化约束,将重复性高、模式明确的代码/文档/配置生成…

2026/8/2 0:00:12阅读更多 →
如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南 【免费下载链接】web-archives Browser extension for viewing archived and cached versions of web pages, available for Chrome, Edge and Safari 项目地址: https://gitcode.com/gh_mirrors/we/web-a…

2026/8/2 0:00:13阅读更多 →
无损视频剪辑终极指南:如何实现快速高效的多媒体处理

无损视频剪辑终极指南:如何实现快速高效的多媒体处理

无损视频剪辑终极指南:如何实现快速高效的多媒体处理 【免费下载链接】lossless-cut The swiss army knife of lossless video/audio editing 项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut 在数字媒体创作领域,视频编辑处理的质量损…

2026/8/2 1:29:34阅读更多 →
AI辅助本科论文写作:8大工具评测与高效使用指南

AI辅助本科论文写作:8大工具评测与高效使用指南

1. 本科生论文写作的AI辅助现状本科毕业论文是每个大学生必须跨越的一道坎。记得我当年写论文时,光是文献检索就花了整整两周时间,打印的参考文献堆满了半个书桌。如今AI技术的发展为学术写作带来了革命性变化,合理使用这些工具可以节省80%以…

2026/8/2 2:32:55阅读更多 →
如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手

如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手

如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase 还在为抢不到热门演唱会门票…

2026/8/2 2:09:20阅读更多 →