基于C语言的贪吃蛇实现

头文件

#pragma once
#include<stdio.h>
#include<Windows.h>
#include<stdbool.h>
#include<locale.h>
#include<time.h>
#define KEY_PRESS(vk) ( (GetAsyncKeyState(vk) & 1) ? 1 : 0)
#define POS_X 24
#define POS_Y 5
#define FOOD L'鼠'
#define WALL L'墙'
#define BODY L'蛇'
//类型声明
//蛇方向
enum DIRECTION
{UP = 1,//上DOWM,//下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 GameRun(pSnake ps);
//欢迎界面
void WelcomeToGame();
//打印地图
void CreateMap();
//初始化蛇
void InitSnake(pSnake ps);
//创建食物
void CreatteFood(pSnake ps);
//蛇的移动
void SnakeMove(pSnake ps);
//判断吃到了没?
int NextIsFood(pSnakeNode pNextNode,pSnake ps);
//吃了食物
void EatFood(pSnakeNode pNextNode, pSnake ps);
//没吃
void NoFood(pSnakeNode pNextNode, pSnake ps);
//撞墙和撞自己
void KillByWall(pSnake ps);
void KillBySelf(pSnake ps);
//游戏善后
void GameEnd(pSnake ps);

实现文件

#define _CRT_SECURE_NO_WARNINGS
#include"snake.h"
void SetPos(short x, short y)
{COORD pos = { x, y };HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为posSetConsoleCursorPosition(hOutput, pos);
}
void WelcomeToGame()
{SetPos(40, 14);printf("欢迎游玩贪吃蛇小游戏\n");SetPos(42, 20);system("pause");system("cls");SetPos(40, 14);wprintf(L"用 ↑ ↓ ← →,按F3加速 按F4减速\n");SetPos(40, 15);wprintf(L"加速分数更高\n");SetPos(42, 20);system("pause");system("cls");SetPos(0, 0);
}
void CreateMap()
{//上int i;for(i = 0;i<29;i++)wprintf(L"%lc", WALL);//左for (i = 0; i <= 25; i++){SetPos(0, i);wprintf(L"%lc", WALL);}//右for (i = 0; i <= 25; i++){SetPos(56, i);wprintf(L"%lc", WALL);}//下SetPos(0, 26);for (i = 0; i < 29; i++)wprintf(L"%lc", 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()");}cur->next = NULL;cur->x = POS_X + 2 * i;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->_score = 0;ps->_food_weight = 10;ps->_sleep_time = 200;//msps->_status = OK;
}
void CreatteFood(pSnake ps)
{int x = 0;int y = 0;//x 2~54//y 1~25
again:do {x = rand() % 53 + 2;y = rand() % 25 + 1;} while ((x % 2) != 0);//x y 不能生成在蛇身上pSnakeNode cur = ps->_pSnake;while(cur){if (x == cur->x && y == cur->y){goto again;}cur = cur->next;}//创建食物结点pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));if (pFood == NULL){perror("CreatFood::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)
{//设置窗口大小system("mode con cols=100 lines=30");system("title 贪吃蛇");//光标隐藏HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);//影藏光标操作CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(houtput, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false;				//隐藏控制台光标SetConsoleCursorInfo(houtput, &CursorInfo);//设置控制台光标状态//打印欢迎界面  //功能介绍WelcomeToGame();//绘制地图CreateMap();//创建蛇InitSnake(ps);//创建食物CreatteFood(ps);//设置游戏相关信息
}
void printfHelpInfo()
{SetPos(64, 20);wprintf(L"%ls",L"不能穿墙,不能啃自己");SetPos(64, 21);printf("欢迎游玩贪吃蛇小游戏\n");SetPos(64, 22);wprintf(L"用 ↑ ↓ ← →,按F3加速 按F4减速\n");SetPos(64, 23);wprintf(L"加速分数更高\n");SetPos(64, 24);wprintf(L"空格是暂停哦");SetPos(64, 25);wprintf(L"By 我");
}
void Pause()
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE))break;}
}
int NextIsFood(pSnakeNode pNextNode, pSnake ps)
{return (ps->_pFood->x == pNextNode->x && ps->_pFood->y == pNextNode->y);
}
void EatFood(pSnakeNode pNextNode, pSnake ps)
{//头插法ps->_pFood->next = ps->_pSnake;ps->_pSnake = ps->_pFood;//释放NEXT的结点free(pNextNode);pNextNode = NULL;pSnakeNode cur = ps->_pSnake;//打印蛇while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->_score += ps->_food_weight;//重新创建食物CreatteFood(ps);
}
void NoFood(pSnakeNode pNextNode, pSnake ps)
{pNextNode->next = ps->_pSnake;ps->_pSnake = pNextNode;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;cur = 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;cur = cur->next;}
}
void SnakeMove(pSnake ps)
{//蛇要去的下一个结点pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNextNode == NULL){perror("SNAKENODDE :: malloc()");return;}switch (ps->_dir){case UP:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y - 1;break;case DOWM: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); pNextNode = NULL;}else{NoFood(pNextNode, ps);}KillByWall(ps);KillBySelf(ps);
}
void GameRun(pSnake ps)
{//打印帮助信息printfHelpInfo();do{SetPos(64, 10);printf("总分:%8d\n",ps->_score);SetPos(64, 11);printf("当前食物分数:%4d\n", ps->_food_weight);//调用宏if (KEY_PRESS(VK_UP) && ps->_dir != DOWM){ps->_dir = UP;}else if (KEY_PRESS(VK_DOWN) && ps->_dir != UP){ps->_dir = DOWM;}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_F3))//加速{if (ps->_food_weight <= 200){ps->_sleep_time -= 30;ps->_food_weight *= 2;}}else if (KEY_PRESS(VK_F4))//减速{if (ps->_food_weight >= 2){ps->_sleep_time += 30;ps->_food_weight /= 2;}}else if (KEY_PRESS(VK_ESCAPE)){ps->_status = END_NORMAL;}SnakeMove(ps);//走一步啊Sleep(ps->_sleep_time);//打印总分数和食物的分值} while (ps->_status == OK);
}
void GameEnd(pSnake ps)
{SetPos(24, 12);switch (ps->_status){case END_NORMAL:printf("已主动结束游戏");break;case KILL_BY_WALL:printf("您撞墙了");break;case KILL_BY_SELF:printf("您撞到了自己");break;}SetPos(0, 27);//释放链表pSnakeNode cur = ps->_pSnake;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
}

mian.c

#define _CRT_SECURE_NO_WARNINGS
#include"snake.h"
void test()
{char ch = 'n';do {system("cls");//创建贪吃蛇Snake snake = { 0 };//初始化游戏GameStart(&snake);//运行游戏GameRun(&snake);//游戏结束GameEnd(&snake);SetPos(20, 20);printf("还玩么?玩的话输入Y(先删除空格):");scanf("%c", &ch);} while (ch == 'Y');
}
int main()
{//设置本地化setlocale(LC_ALL, "");srand((unsigned int)time(NULL));test();return 1;
}

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

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

相关文章

网址分类-杂项

网址分类 Python可视化库matplotlibplotnineseaborn 科学计算库numpy scipy数据分析库pandas 人工智能opencvkeras 工具网站电子工具 Python 可视化库 matplotlib matplotlib官网 plotnine plotnine seaborn seaborn 科学计算库 numpy numpy官网 scipy scipy官网 …

ORAN C平面 Section Extension 23

ORAN C平面Section扩展23用于任意symbol模式的调制压缩参数。此section扩展允许为一个或多个“SymPrbPatterns”指定多组“mcScaleReMask、csf和mcScaleOffset”值。“SymPrbPattern”用于指定一组PRB&#xff0c;这些PRB可以跨越使用prbPattern指定的整个PRB范围&#xff08;频…

重生奇迹mu坐骑怎么升级

重生奇迹mu坐骑怎么升级 1、前期&#xff0c;都是主线任务&#xff0c;我们必须要跟着主线任务走&#xff0c;前面的话升级一次需要的经验很少的&#xff0c;一天下来可以升级100级是轻轻松松的&#xff0c;主线任务是比较多的&#xff0c;我们跟着任务一直做差不多可以到150级…

dspbuilder中使用signalcompiler时报错Error during compilation: Fitter failed,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

计算机组成原理【CO】Ch7 I/O大题

目录 I/O大题解题方法 I/O接口 各种I/O方式的特点 I/O端口编址 程序查询方式 中断控制方式 DMA控制方式 程序中断的工作流程 程序中断的工作流程 DMA方式和中断方式的区别 I/O大题解题方法 CPU 程序查询中断DMA I/O接口的类型 按字传输&#xff1a;每次传输一个字 程…

【C++】日期类Date(详解)

&#x1f525;个人主页&#xff1a;Forcible Bug Maker &#x1f525;专栏&#xff1a;C 目录 前言 日期类 日期类实现地图 获取某年某月的天数&#xff1a;GetMonthDay 检查日期合法&#xff0c;构造函数&#xff0c;拷贝构造函数&#xff0c;赋值运算符重载及析构函数…

【数据结构2-线性表】

数据结构2-线性表 1 线性表-数组2 线性表-单链式结构2.1 前插顺序单链表2.2 后插顺序单链表2.3 循环单链表2.4 双向链表 总结 线性表、栈、队列、串和数组都属于线性结构。 线性结构的基本特点是除第一个元素无直接前驱&#xff0c;最后一个元素无直接后继之外&#xff0c;其他…

linux实用C++库之json

目录 1 介绍2 内容 1 介绍 本博客用来记录linux下json库的基本使用。 2 内容 安装&#xff1a; 使用&#xff1a; CMakeLists.txt编写&#xff1a;

.net反射(Reflection)

文章目录 一.概念&#xff1a;二.反射的作用&#xff1a;三.代码案例&#xff1a;四.运行结果&#xff1a; 一.概念&#xff1a; .NET 反射&#xff08;Reflection&#xff09;是指在运行时动态地检查、访问和修改程序集中的类型、成员和对象的能力。通过反射&#xff0c;你可…

【游戏专区】飞机大战

打过飞机的人都知道&#xff0c;不是那么好打滴&#xff0c;求得麻袋&#xff0c;甩掉你那脑子里的黄色信息。活不多说&#xff0c;我们开始吧。 1、easyX的原理 基于Windows图形编程&#xff0c;将Windows下的复杂程序过程进行封装&#xff0c;仅给用户提供一个简单熟悉的接…

21.组件组成

组件组成 组件最大的优势就是可复用性 当使用构建步骤时&#xff0c;我们一般会将 Vue 组件定义在一个单独的 .vue 文件中&#xff0c;这被叫做单文件组件(简称 SFC) 组件组成结构 <template><div>承载标签</div> </template> <script> expor…

【软件测试】正交表测试例题

【软件测试】正交表测试 例题1答案 例题2答案 例题3答案 例题1 很多Word编辑器都有字体修饰功能&#xff0c;可以将一个字加粗、倾斜、以及加上下划线。一个字可以同时被加粗和倾斜&#xff0c;也可以同时被倾斜和加下划线。三种因子Bold, Italic, Underline的效果可以任意组合…

计算机组成原理【CO】Ch3 存储系统

文章目录 考纲3.1 存储系统概述3.2 主存储器3.3 主存储器与CPU的连接3.4 外部存储器3.5 高速缓冲存储器3.6 虚拟存储器 【※】存储系统总体流程图【※】各个部件的存储位置计算机存储相关硬件与数据结构说明进程控制块&#xff08;PCB&#xff09;页表页表始址页表始址寄存器&a…

传感器融合 | 适用于自动驾驶场景的激光雷达传感器融合项目_将激光雷达的高分辨率成像+测量物体速度的能力相结合

项目应用场景 面向自动驾驶场景的激光雷达传感器融合&#xff0c;将激光雷达的高分辨率成像测量物体速度的能力相结合&#xff0c;项目是一个从多个传感器获取数据并将其组合起来的过程&#xff0c;可以更加好地进行环境感知。项目支持 ubuntu、mac 和 windows 平台。 项目效果…

CGLIB动态代理

文章目录 前言概要SpringBoot中使用小结 前言 当我们需要在Java中实现动态代理时&#xff0c;通常会考虑使用 JDK原生动态代理 或者 CGLIB动态代理。 我这里说一下CGLIB动态代理&#xff0c;并给出一个例子。 概要 CGLIB&#xff08;Code Generation Library&#xff09;是一…

ROS分布式通讯配置

4WD 必读&#xff1a;分布式通讯是相对于用虚拟机来连接小车上主机来说&#xff0c;如果是 4WD 笔记本无主 机用户&#xff0c;不存在分布式通讯一说。 1.4WD 用户单笔记设置一&#xff0c;连接底盘和雷达还有摄像头。 因为虚拟机带宽问题&#xff0c;无法保证摄像头正常运行。…

python-selenium +Chrome driver环境配置

selenium Chrome driver环境配置_chromedriver 122.0.6261.112-CSDN博客

asp.net core 8.0 使用 Autofac ioc 容器 具体实例

要在ASP.NET Core 8.0项目中具体实现使用Autofac作为IOC容器&#xff0c;我们将遵循一个明确的示例&#xff0c;从创建新项目到配置Autofac&#xff0c;并演示如何注册和解析服务。 步骤 1: 创建ASP.NET Core 8.0项目 首先&#xff0c;使用Visual Studio或命令行工具创建一个…

初始ansible变量及实例配置

目录 1、为什么要使用变量 2、变量分类 3、 变量详解 3.1 vars,vars_files , group_vars 3.1 .1 vars 剧本中定义变量 3.1.2 vars_file 将变量存放到一个文件中&#xff0c;并在剧本中引用 3.1.3 group_vars 创建一个变量文件给某个组使用 实例1-根据不同的主机…

Oracle中排查谁把表数据删除更新——delete、drop、truncate

一、Oracle删除表或数据方法 简单的说Oracle中的delete、drop、truncate三个命令都可以将数据清除; Oracle中清除数据delete、drop、truncate相同点 序号描述1truncate和不带where条件的delete、以及drop都会删除表内的数据 ①【truncat table】比 【delete 】速度快,且使…