小游戏:贪吃蛇

🎁个人主页:我们的五年

🔍系列专栏:贪吃蛇

🌷追光的人,终会万丈光芒

 

 

目录

🏝1.头文件:

 🏝2.实现文件:

🏝3.测试文件 :


 

 前言:这个在学习C语言的对知识点进行巩固的一个小游戏,后面也会持续带来一下小游戏。喜欢的帖子们可以点点关注。

相关系列文章:贪吃蛇
 

🏝1.头文件:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<locale.h>
#include<windows.h>
#include<time.h>

#define POS_X 24
#define POS_Y 5
#define WALL L'□'
#define BODY L'●'
#define FOOD L'●'

//类型声明

//蛇的方向
enum DIECTION {
	UP = 1,
	DOWN,
	LEFT,
	RIGHT
};

//贪吃蛇的状态
// 正常,撞墙,撞到自己,正常退出。

enum GAME_STATUS
{
	OK,            //正常
	KILL_BY_WALL,  //撞墙
	KILL_BY_SLEF,  //撞到自己
	END_NORMAL     //正常退出
};
//蛇身节点
typedef struct SnakeNode {

	short x;
	short y;
	struct SncakeNode* 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 GameStart(pSnake snake);

//欢迎界面打印
void WelcomeToGame();

//初始化蛇
void InitSnake(pSnake ps);

//创建食物
void CreateFood(pSnake ps);

//游戏运行
void GameRun(pSnake ps);

int NextIsFood(pSnakeNode pn, pSnake ps);

void SnakeMove(pSnake ps);

void EatFood(pSnakeNode pn, pSnake ps);

void NotFood(pSnakeNode pn, pSnake ps);

void KillByWall(pSnake ps);

void KillBySelf(pSnake ps);

void Game_End(pSnake ps);

 🏝2.实现文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"snake.h"

void SetPos(short x, short y)
{
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { x,y };
	SetConsoleCursorPosition(houtput, pos);
}
void WelcomeToGame()
{
	SetPos(35, 13);
	wprintf(L"欢迎来到贪吃蛇小游戏\n");
	SetPos(37, 20);
	system("pause");
	system("cls");

	SetPos(35, 8);wprintf(L"按↑向上移动");
	SetPos(35, 9);wprintf(L"按↓向下移动");
	SetPos(35, 10);wprintf(L"按←向左移动");
	SetPos(35, 11);wprintf(L"按→向右移动");
	SetPos(35, 12);wprintf(L"按F3减速");
	SetPos(35, 13);wprintf(L"按F4加速");
	SetPos(35, 14); wprintf(L"加速可以得到更高的分数");
	SetPos(35, 18);
	system("pause");
	system("cls");

}

CreateMap()
{
	//上
	for (int i = 0; i < 29; i++)
		wprintf(L"%lc", L'□');
	//下
	SetPos(0, 26);
	for (int i = 0; i < 29; i++)
		wprintf(L"%lc", L'□');
	//左
	for (int i = 1; i <=25; i++)
	{
		SetPos(0, i);
		wprintf(L"%lc\n", L'□');
	}
	//右
	for (int i = 1; i <= 25; i++)
	{
		SetPos(56, i);
		wprintf(L"%lc\n", L'□');
	}
}

void InitSnake(pSnake ps)
{
	int i = 0;
	pSnakeNode cur = NULL;
	for (; i < 5; i++)
	{
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("InitSnake::malloc()");
			return;
		}
		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->_status = OK;
	ps->_food_weight = 10;
	ps->_sleep_time = 200;
	//设置贪吃蛇属性
}
void CreateFood(pSnake ps)
{
	int x = 0;
	int y = 0;

	//生成食物的坐标是2的倍数
	//且在方框里面
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("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=100 lines=30");//设置窗口大小为100列,30行
	system("title 贪吃蛇");  //设置窗口名字为:贪吃蛇
	//影藏光标
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursor;
	GetConsoleCursorInfo(houtput, &cursor);
	cursor.bVisible = false;
	SetConsoleCursorInfo(houtput, &cursor);

	//1.打印欢迎界面
	//功能介绍
	WelcomeToGame();
	
	//2.绘制地图
	CreateMap();

	//3.创建蛇
	InitSnake(ps);

	//4.创建食物
	CreateFood(ps);

	SetPos(64, 13);
	wprintf(L"0.用↑←→↓控制蛇的移动");
	SetPos(64, 14);
	wprintf(L"1.不能穿墙,不能咬到自己");
	SetPos(64, 15);
	wprintf(L"2.F3减速,F4加速");
	SetPos(64, 16);
	wprintf(L"3.exc退出游戏");
	SetPos(64, 17);
	wprintf(L"4.按空格暂停游戏");

}
#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)
void Pause()
{
	while (1)
	{
		Sleep(100);
		if(KEY_PRESS(VK_SPACE))
			break;
	}
}

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\n", BODY);
		cur = cur->next;
	}
	ps->_score += ps->_food_weight;
	CreateFood(ps);
}


void NotFood(pSnakeNode pn, pSnake ps)
{
	pn->next = ps->_pSnake;
	ps->_pSnake = pn;
	pSnakeNode cur = ps->_pSnake;
	pSnakeNode prev = ps->_pSnake;
	while (cur->next)
	{		
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		prev = cur;
		cur = cur->next;
	}
	prev->next = NULL;
	SetPos(cur->x, cur->y);
	wprintf(L"  ");
	free(cur);
	cur = NULL;
}

int NextIsFood(pSnakeNode pn,pSnake ps)
{
	return (pn->x == ps->_pFood->x && pn->y == ps->_pFood->y);
}

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_SLEF;
			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
	{
		NotFood(pNextNode,ps);
	}

	//撞到自己
	KillByWall(ps);

	//撞墙
	KillBySelf(ps);
}

void Game_End(pSnake ps)
{
	SetPos(24, 12);
	switch (ps->_status)
	{
	case KILL_BY_SLEF:
		printf("你撞到了自己,游戏结束\n");
		break;
	case KILL_BY_WALL:
		printf("你撞到墙了,游戏结束\n");
		break;
	case END_NORMAL:
		printf("你主动结束了游戏\n");
		break;
	}
	pSnakeNode cur = ps->_pSnake;
	while (cur)
	{
		pSnakeNode del = cur;
		cur = cur->next;
		free(del);
	}
}
void GameRun(pSnake ps)
{
	//打印帮助信息
	do
	{
		//打印总分数和食物的分值
		SetPos(64, 8);
		wprintf(L"总分数:%3d\n",ps->_score);
		SetPos(64, 9);
		wprintf(L"当前食物分数:%2d",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_F3))
		{
			//减速
			if (ps->_sleep_time < 320)
			{
				ps->_sleep_time += 30;
				ps->_food_weight -= 2;
			}
		}
		else if (KEY_PRESS(VK_F4))
		{
			//加速
			if (ps->_sleep_time > 80)
			{
				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);
}

🏝3.测试文件 :

#define _CRT_SECURE_NO_WARNINGS 1
#include"snake.h"

//完成的是对游戏的测试
void test()
{
	int ch;
	do
	{
		//创建贪吃蛇
		Snake snake = { 0 };

		//初始化游戏
		GameStart(&snake);

		//运行游戏
		GameRun(&snake);

		//结束游戏—善后工作
		Game_End(&snake);
		SetPos(20, 13);
		printf("游戏结束,再来一局吗?Y/N");
		SetPos(20, 14);
		ch=getchar();
		while(getchar()!='\n');
	} while (ch == 'y' || ch == 'Y');
	SetPos(0, 26);
}
int main()
{
	//设置适配本地环境
	setlocale(LC_ALL, "");
	srand((unsigned int)time(NULL));
	test();
	return 0;
}

 

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

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

相关文章

探索 去中心化的Web3.0

随着区块链技术的日益成熟和普及&#xff0c;Web3&#xff08;Web 3.0&#xff09;已经成为一个无法忽视的趋势。Web3不仅仅是一个技术概念&#xff0c;更是一个去中心化、透明、用户数据拥有权归还给用户的互联网新时代。在这篇文章中&#xff0c;我们将深入探讨Web3技术的核心…

uniApp项目总结

前言 大半年的时间&#xff0c;项目从秋天到春天&#xff0c;从管理后台到APP再到数据大屏&#xff0c;技术栈从vue3到uniApp再到nuxt3&#xff0c;需求不停的改&#xff0c;注释掉代码都快到项目总体的三分之一。 一&#xff0c;项目技术栈分析 1.1 项目框架 当前&#xf…

30V-STM32设计项目

30V-STM32设计 一、项目描述 (已验证) 基于STM32c8t6芯片设计的开发板&#xff0c;支持4-30V宽电压输入&#xff0c;串口模式自动下载功能&#xff0c;支持串口和STlink&#xff0c;方式下载程序 二、原理图介绍 电源电路采用了DCDCLDO电路&#xff0c;如果是外接DC头供电的话&…

坚蛋运动新质生产力实践——“AI健康”战略引领产品和服务创新

进入AI时代&#xff0c;全球互联网企业均开启了以大模型及其应用为代表的第四次工业革命的激烈竞赛。坚蛋运动已在全国范围内布局300门店&#xff0c;预计实现2024年500、2025年1000门店&#xff0c;作为国内运动健康产业的头部品牌&#xff0c;坚蛋运动率先提出并推动“AI健康…

广州大学《软件工程》实验报告三软件设计

广州大学学生实验报告&#xff08;三&#xff09; 开课学院及实验室&#xff1a; 学院 年级/专业/班 姓名 学号 实验课程名称 软件工程导论实验 成绩 实验项目名称 软件设计 指导老师 一、实验目的 掌握软件设计建模技术&#xff0c;能够撰写软件设计文…

判断经济形势最常用的统计指标有哪些

分析判断经济形势常常围绕以下四大目标进行&#xff1a;经济增长、充分就业、物价稳定、国际收支平衡。这四大目标相互联系、相互影响、相互制约&#xff0c;宏观调控的目的在于恰当处理这四方面的关系&#xff0c;寻求一个最佳平衡点。通过全面观察这四大指标&#xff0c;可以…

postCss基本介绍

&#x1f31f;什么是postCss&#xff1f; 我个人的理解postCss就是css界的babel&#xff0c;它提供一个过程&#xff0c;而在这个过程中&#xff0c;去干什么就是你自己的事情&#xff0c;所以很多人写插件&#xff0c;去做代码转换&#xff0c;或者兼容等等。 babel 提供过程 …

新的全息技术突破计算障碍

一种突破性的方法利用基于Lohmann透镜的衍射模型实时创建计算机生成全息图&#xff08;CGH&#xff09;&#xff0c;在保持3D可视化质量的同时&#xff0c;大大降低了计算负荷要求。 全息显示为制作逼真的三维图像提供了一条令人兴奋的途径&#xff0c;这种图像给人以连续深度…

Pytest精通指南(26)钩子函数-依赖执行(pytest-dependency)

文章目录 前言应用场景插件安装注意事项参数分析函数名称依赖实现方式类下函数路径实现方式通过设置别名指定依赖定义依赖范围作用于类作用于模块作用于包作用于会话拓展-非常重要 前言 pytest-dependency的主要用途是确保测试用例按照指定的依赖关系顺序执行。 在一个复杂的测…

R语言绘制动态网络图Network教程WGCNA

今天分享的笔记是使用NetworkD3对WGCNA的共表达网络进行可视化&#xff0c;创建交互式动态网络图&#xff0c;展示基因之间的相互关系&#xff0c;可以用于转录组或者其他调控网络展示。 加权基因共表达网络分析 (WGCNA, Weighted correlation network analysis)是用来描述不同…

数值分析复习:Richardson外推和Romberg算法

文章目录 Richardson外推Romberg&#xff08;龙贝格&#xff09;算法 本篇文章适合个人复习翻阅&#xff0c;不建议新手入门使用 本专栏&#xff1a;数值分析复习 的前置知识主要有&#xff1a;数学分析、高等代数、泛函分析 本节继续考虑数值积分问题 Richardson外推 命题&a…

Python环境找不到解决方法

Python环境找不到 打开设置&#xff1a;Ctrl Alt S 添加Local Interpreter... 打开System Interpreter&#xff0c;找到本地安装的Python.exe路径&#xff0c;然后一路点OK Trust Project 如果打开工程时&#xff0c;出现如下对话框&#xff0c;请勾选 Trust projects in ...&…

CDN技术:全球化的数字内容快速分发系统

CDN技术&#xff1a;全球化的数字内容快速分发系统 在今天的互联网世界中&#xff0c;内容分发网络&#xff08;CDN&#xff09;技术起着至关重要的作用。它通过全球分布的服务器网络&#xff0c;快速、安全地将内容送达世界各地的用户&#xff0c;极大地提升了网页加载速度和…

使用 ollama 部署最新的Llama 3 70B本地模型

一、ollama是什么? 在本地启动并运行大型语言模型。运行Llama 3&#xff0c;Mistral, Gemma, Code Llama和其他模型。自定义并创建您自己的。 综合优点&#xff1a; 快速下载容器自动运行大模型&#xff0c;现在下载&#xff0c;马上上手。本地利用 cpu 运行大模型&#xff0c…

java:Java中的异常处理

目录 异常的概念与体系结构 异常的概念&#xff1a; 异常的体系结构&#xff1a; 异常的处理方式 防御式编程&#xff1a; 异常的抛出&#xff1a; 异常的捕获&#xff1a; finally&#xff1a; 代码示例&#xff1a; 异常的处理流程 自定义异常类 举例&#xff1a…

【Hadoop3.3.6】数据块副本放置策略及解析EditLog和FsImage

目录 一、摘要二、正文2.1 环境说明2.2 网络拓扑2.3 Hadoop副本放置策略介绍2.4 解析EditLog和Fsimage镜像文件三、小结一、摘要 通过解析存储于NameNode节点上的日志文件EditLog和镜像文件(元数据)Fsimage来反向验证HDFS的数据块副本存放策略,其目的是希望加深对Hadoop的数…

2024HVV在即| 最新漏洞CVE库(1.5W)与历史漏洞POC总结分享!

前言 也快到护网的时间了,每年的护网都是一场攻防实战的盛宴,那么漏洞库就是攻防红蓝双方人员的弹药库,红队人员可以通过工具进行监测是否存在历史漏洞方便快速打点,而蓝队则可以对资产进行梳理和监测历史漏洞,及时处理和修复,做好准备. 下面分享的…

【电控笔记5.4】pwm延迟

PWM延迟 1标准采样法 Td=MCU计算延迟+输出延迟 Tcon=电流控制周期 Ts=PWM载波周期 Td=1.5Ts(6.3节 ) 电流环跟PWM采样周期同步 2修改采样法

YOLOv5改进 | Conv篇 | 利用CVPR2024-DynamicConv提出的GhostModule改进C3(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是CVPR2024的最新改进机制DynamicConv其是CVPR2024的最新改进机制&#xff0c;这个论文中介绍了一个名为ParameterNet的新型设计原则&#xff0c;它旨在在大规模视觉预训练模型中增加参数数量&#xff0c;同时尽量不增加浮点运算&#x…

如何使用 ArcGIS Pro 快速为黑白地图配色

对于某些拍摄时间比较久远的地图&#xff0c;限于当时的技术水平只有黑白的地图&#xff0c;针对这种情况&#xff0c;我们可以通过现在的地图为该地图进行配色&#xff0c;这里为大家讲解一下操作方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微…