通过C语言设计的贪吃蛇游戏(控制台终端)
一、项目介绍
当前通过控制台终端实现一个贪吃蛇小游戏,实现游戏的绘制、更新、控制等功能。
二、实现效果


三、完整代码
下面贴出的代码在Windows系统上编译运行,需要使用conio.h头文件中的getch()函数来获取键盘输入,用于控制蛇的移动。可以通过按下’w’、‘s’、‘a’、'd’四个键来分别控制蛇的向上、向下、向左、向右移动。同时还有一个暂停函数Pause(),用于控制蛇的移动速度,可以根据需要调整暂停时间。
设计思路:
程序定义了一些常量,包括游戏界面的宽度和高度、不同状态下的符号表示等,并在全局变量中定义了蛇头、蛇身、食物等的位置、得分、长度、行进方向等参数。同时还定义了一个二维字符数组board,用于表示整个游戏界面。
在InitGame()函数中进行游戏初始化,设置游戏界面的边框、蛇头、蛇身、随机生成食物等操作。
DrawGame()函数用于绘制游戏画面,将board数组中的字符逐行输出,并在末尾输出得分。UpdateGame()函数用于更新游戏状态,包括蛇的移动、游戏结束判断等。CheckGameOver()函数用于检查游戏是否结束,包括墙壁碰撞、蛇身碰撞、得分达到上限等情况。GenerateFood()函数用于随机生成食物位置,调用rand()函数获取随机数并进行判断。Move()函数用于蛇的移动,根据当前行进方向进行移动。Control()函数用于用户操作,读取键盘输入并更新蛇的行进方向。Pause()函数用于控制游戏速度,通过调用Sleep()函数控制暂停时间。GameOver()函数用于输出最终得分和游戏结束信息,并直接退出程序。

#include <stdio.h>
#include <stdlib.h>
#include <conio.h> //需要使用getch()函数
#include <time.h> //需要使用time()函数
#include <Windows.h>#define WIDTH 40 //游戏界面宽度
#define HEIGHT 20 //游戏界面高度//定义符号常量,表示各种不同的状态
#define BLANK ' ' //空白
#define WALL '*' //墙壁
#define SNAKEHEAD '@' //蛇头
#define SNAKEBODY 'o' //蛇身
#define FOOD '$' //食物//定义坐标结构体
struct Position
{int x; //横坐标int y; //纵坐标
};//定义枚举类型,表示游戏状态
enum GameState
{Over = -1, //游戏结束Running = 0, //游戏进行中Win = 1 //游戏胜利
};int score = 0; //得分
struct Position head; //蛇头位置
struct Position body[WIDTH * HEIGHT]; //蛇身位置
struct Position food; //食物位置
char board[WIDTH][HEIGHT]; //游戏界面
int length = 3; //蛇身长度,初始为3
int direction = 0; //蛇的行进方向,0表示向右,1表示向下,2表示向左,3表示向上//函数声明
void InitGame(); //初始化游戏界面和蛇的初始位置
void DrawGame(); //绘制游戏画面
void UpdateGame(); //更新游戏状态
enum GameState CheckGameOver(); //检查游戏是否结束
void GenerateFood(); //生成随机食物
void Move(); //蛇的移动
void Control(); //用户操作,控制蛇的移动
void Pause(); //游戏暂停
void GameOver(); //游戏结束int main()
{srand(time(NULL)); //用当前时间作为随机数种子,使每次运行的随机食物位置不同InitGame(); //初始化游戏DrawGame(); //绘制游戏画面while (1){UpdateGame(); //更新游戏DrawGame(); //绘制游戏画面Control(); //用户操作,控制蛇的移动Pause(); //游戏暂停 }return 0;
}//初始化游戏界面和蛇的初始位置
void InitGame()
{for (int i = 0; i < WIDTH; i++){for (int j = 0; j < HEIGHT; j++){if (i == 0 || j == 0 || i == WIDTH - 1 || j == HEIGHT - 1) //设置墙壁board[i][j] = WALL;elseboard[i][j] = BLANK; //其他为空白}}//初始化蛇的位置,由一个蛇头和两节身体组成,初始位置在游戏界面的中心head.x = WIDTH / 2;head.y = HEIGHT / 2;board[head.x][head.y] = SNAKEHEAD;body[0].x = head.x - 1;body[0].y = head.y;board[body[0].x][body[0].y] = SNAKEBODY;body[1].x = head.x - 2;body[1].y = head.y;board[body[1].x][body[1].y] = SNAKEBODY;GenerateFood(); //生成随机食物
}//绘制游戏画面
void DrawGame()
{system("cls"); //清屏,避免前一帧的内容残留for (int i = 0; i < HEIGHT; i++){for (int j = 0; j < WIDTH; j++){printf("%c", board[j][i]); //输出一个字符}printf("\n"); //每行输出完后,换行}printf("Score: %d\n", score); //输出得分
}//更新游戏状态
void UpdateGame()
{Move(); //蛇的移动enum GameState state = CheckGameOver(); //检查游戏是否结束if (state != Running) //如果游戏结束,则进行相应操作{GameOver();}
}//检查游戏是否结束
enum GameState CheckGameOver()
{//蛇头碰到墙壁,游戏结束if (board[head.x][head.y] == WALL)return Over;//蛇头碰到蛇身,游戏结束for (int i = 0; i < length; i++){if (head.x == body[i].x && head.y == body[i].y)return Over;}//吃到食物后,更新分数和蛇的长度,并生成新的食物if (head.x == food.x && head.y == food.y){score += 10;length++;GenerateFood();}//蛇的长度达到游戏界面总格子数减去墙壁的个数,也就是蛇填满游戏界面,游戏胜利if (length == (WIDTH - 2) * (HEIGHT - 2) - 4)return Win;return Running; //游戏继续进行
}//生成随机食物
void GenerateFood()
{int x, y;do{x = rand() % (WIDTH - 2) + 1; //随机x坐标,排除在边框上的墙壁位置y = rand() % (HEIGHT - 2) + 1; //随机y坐标,排除在边框上的墙壁位置} while (board[x][y] != BLANK); //如果随机到的位置不为空白,则重新随机food.x = x;food.y = y;board[x][y] = FOOD; //在随机位置生成食物
}//蛇的移动
void Move()
{//更新蛇身的位置,从后往前移动for (int i = length - 1; i > 0; i--){body[i].x = body[i - 1].x;body[i].y = body[i - 1].y;board[body[i].x][body[i].y] = SNAKEBODY;}//更新蛇头的位置switch (direction) //根据蛇头行进方向进行移动{case 0: //向右head.x++;break;case 1: //向下head.y++;break;case 2: //向左head.x--;break;case 3: //向上head.y--;break;}board[head.x][head.y] = SNAKEHEAD; //更新蛇头位置board[body[length - 1].x][body[length - 1].y] = BLANK; //清除蛇尾
}//用户操作,控制蛇的移动
void Control()
{if (kbhit()) //如果有按键按下{char ch = getch(); //获取按键字符switch (ch){case 'w':if (direction != 1) //避免蛇头掉头direction = 3;break;case 's':if (direction != 3)direction = 1;break;case 'a':if (direction != 0)direction = 2;break;case 'd':if (direction != 2)direction = 0;break;case 'q':GameOver(); //按下'q'键退出游戏break;}}
}//游戏暂停
void Pause()
{Sleep(150); //每次循环暂停一段时间,控制蛇的移动速度
}//游戏结束
void GameOver()
{system("cls"); //清屏,输出最终得分和游戏结束信息printf("Game over!\n");printf("Your score: %d\n", score);exit(0); //直接退出程序
}
相关文章:
通过C语言设计的贪吃蛇游戏(控制台终端)
一、项目介绍 当前通过控制台终端实现一个贪吃蛇小游戏,实现游戏的绘制、更新、控制等功能。 二、实现效果 三、完整代码 下面贴出的代码在Windows系统上编译运行,需要使用conio.h头文件中的getch()函数来获取键盘输入,用于控制蛇的移动。…...
c++实现Qt信号和槽机制
文章目录 简介信号槽信号与槽的连接 特点观察者模式定义观察者模式结构图 实现简单的信号和槽 简介 信号槽机制与Windows下消息机制类似,消息机制是基于回调函数,Qt中用信号与槽来代替函数指针,使程序更安全简洁。 信号和槽机制是 Qt 的核心…...
【Linux】五、进程
一、冯诺依曼体系结构 存储器:指的是内存; 输入设备:键盘、摄像头、话筒,磁盘,网卡; 输出设备:显示器、音响、磁盘、网卡; 中央处理器(CPU):运算器…...
使用 OpenCV 和 Python 卡通化图像-附源码
介绍 在本文中,我们将构建一个有趣的应用程序,它将卡通化提供给它的图像。为了构建这个卡通化器应用程序,我们将使用 python 和 OpenCV。这是机器学习令人兴奋的应用之一。在构建此应用程序时,我们还将了解如何使用 easygui、Tkinter 等库。在这里,您必须选择图像,然后应…...
GitLab不同角色对应的权限
Owner(拥有者): 拥有者是项目或组的创建者,拥有最高级别的权限。他们可以添加、删除项目成员,修改项目设置,管理访问权限,并进行项目转让。在组级别,他们还可以添加或删除子组和项目…...
手写一个简易的布隆过滤器
1.什么是布隆过滤器 布隆过滤器(Bloom Filter)是1970年由布隆(人名)提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,…...
阿里云快速部署开发环境 (Apache + Mysql8.0)
本文章的内容截取于云服务器管理控制台提供的安装步骤,再整合前人思路而成,文章末端会提供原文连接 ApacheMysql 8.0部署MySQL数据库(Linux)步骤一:安装MySQL步骤二:配置MySQL步骤三:远程访问My…...
侧边栏的打开与收起
侧边栏的打开与收起 <template><div class"box"><div class"sideBar" :class"showBox ? : controller-box-hide"><div class"showBnt" click"showBox!showBox"><i class"el-icon-arrow-r…...
贝叶斯学习
贝叶斯 贝叶斯学习的背景贝叶斯定理举例 概览选择假设— MAPMAP举例 选择假设 — 极大似然 MLML 举例: 抛硬币问题 极大似然 & 最小二乘Nave Bayesian Classifier (朴素贝叶斯分类器)举例1:词义消歧 (Word Sense Disambiguation)举例 2: 垃圾邮件过滤 从垃圾邮件…...
Java并发系列之六:CountDownLatch
CountDownLatch作为开发中最常用的组件,今天我们来聊聊它的作用以及内部构造。 首先尝试用一句话对CountDownLatch进行概括: CountDownLatch基于AQS,它实现了闩锁,在开发中可以将其用作任务计数器。 若想要较为系统地去理解这些特性ÿ…...
24数据结构-图的基本概念与存储结构
目录 第六章 图6.1 图的基本概念知识回顾 6.2 图的储存结构(邻接矩阵法)1. 数组表示法(1) 有向图,无向图的邻接矩阵 2. 定义邻接矩阵的结构3. 定义图的结构4. 构造图G5. 特点 第六章 图 6.1 图的基本概念 图是一种非线性结构 图的特点&am…...
自然语言处理学习笔记(三)————HanLP安装与使用
目录 1.HanLP安装 2.HanLP使用 (1)预下载 (2)测试 (3)命令行 (4)测试样例 3.pyhanlp可视化 4. HanLP词性表 1.HanLP安装 HanLP的 Python接口由 pyhanlp包提供,其安装…...
CS 144 Lab Five -- the network interface
CS 144 Lab Five -- the network interface TCP报文的数据传输方式地址解析协议 ARPARP攻击科普 Network Interface 具体实现测试tcp_ip_ethernet.ccTCPOverIPv4OverEthernetAdapterTCPOverIPv4OverEthernetSpongeSocket通信过程 对应课程视频: 【计算机网络】 斯坦福大学CS144…...
Mecha
一、Mecha Mecha 是一个开源的多云 Kubernetes 管理平台,旨在简化和统一在多个云提供商上运行 Kubernetes 集群的管理和操作。它是由阿里巴巴集团开发和维护的项目。 Mecha 的主要目标是提供一个统一的界面和工具,使用户能够更轻松地在不同的云提供商上…...
Apache RocketMQ之集成RocketMQ_MQTT 安装部署协议
Apache RocketMQ 安装说明 安装步骤 参考快速开始 https://rocketmq.apache.org/zh/docs/quickStart/01quickstart 安装可视化rocketmq_dashboard下载地址 https://rocketmq.apache.org/zh/docs/4.x/deployment/03Dashboard/ 安装rocketmq_mqtt https://rocketmq.apache.o…...
Oracle多行数据合并为一行数据,并将列数据转为字段名
Oracle多行数据合并为一行数据 实现查询效果原数据 方式一:MAX()数据效果SQL 方式二:LISTAGG()数据效果 方式三:WM_CONCAT()数据效果 实现查询效果 原数据 FZPROJECTVALUE1电脑$16001手机$121导管$12电脑$22手机$22 方式一:MAX…...
MySQL5.7 与 MariaDB10.1 审计插件兼容性验证
这是一篇关于发现 MariaDB 审计插件导致 MySQL 发生 crash 后,展开适配验证并进行故障处理的文章。 作者:官永强 爱可生DBA 团队成员,擅长 MySQL 运维方面的技能。热爱学习新知识,亦是个爱打游戏的宅男。 本文来源:原创…...
PyTorch Lightning教程五:Debug调试
如果遇到了这样一个问题,当一次训练模型花了好几天,结果突然在验证或测试的时候崩掉了,这个时候其实是很奔溃的,主要还是由于没有提前知道哪些时候会出现什么问题,本节会引入Lightning的Debug方案 1.fast_dev_run参数 …...
末流211无科研保研经验分享
文章目录 个人背景夏令营哈工大威海西工大光电北航软院北邮计算机中科大科学岛 预推免东南软件北航计算机 写在最后心路历程寄语 个人背景 院校:末流211专业背景:计算机科学与技术排名:夏令营7 / 126,预推免3 / 126英语ÿ…...
日期选择器多选换行
<el-form-item label"日期选择"><div class"multi-date-picker"><div class"date-item"><span class"dateIcon"><el-icon><Calendar /></el-icon></span><span class"dateIt…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
