【C/C++ 11】贪吃蛇游戏

一、题目

贪吃蛇游戏机制是通过控制蛇上下左右移动并吃到食物得分。

蛇头碰到墙壁或者碰到蛇身就游戏结束。

食物随机生成,蛇吃到食物之后蛇身变长,蛇速加快。

二、算法

1. 初始化游戏地图并打印,地图的边缘是墙,地图的每个坐标都有属性(EMPTY、WALL、FOOD、HEAD、BODY),通过<Window.h>库里面的函数控制光标跳转和颜色。

2. 初始化蛇,蛇是一个单独的类,类里面的属性有蛇头、蛇身、长度、速度,蛇头一个SnakeNode节点,蛇身是一个SnakeNode指针,每个SnakeNode都是一个x、y坐标,用于表示蛇在地图上的位置。

3. 随机生成食物,蛇移动的下一步如果是食物则得分,若下一步是墙壁或蛇身则游戏失败。

4. 通过键盘输入控制方向,若键盘没有输入则保持方向不变。

三、代码

#define _CRT_SECURE_NO_WARNINGS 1

#pragma warning (disable:4996)
#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <ctime>
#include <vector>
using namespace std;

#define ROW 22
#define COL 42

#define EMPTY 0
#define WALL  1
#define FOOD  2
#define HEAD  3
#define BODY  4

#define COL_WALL  6
#define COL_FOOD  12
#define COL_SNAKE 10

#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define SPACE 32
#define ESC 27
#define ENTER 13

int g_map[ROW][COL] = { 0 };
int g_grade = 0;

void CursorJump(int x, int y)
{
	COORD pos;    //定义光标位置的结构体变量
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);        //设置光标位置
}

void Color(int x)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);    //设置颜色
	// 6——土黄色    7——白色    10——绿色    12——红色
}

void SysInit()
{
	srand((unsigned int)time(NULL));
	system("title 贪吃蛇");
	system("mode con cols=84 lines=23");    //设置终端窗口大小
	CONSOLE_CURSOR_INFO curInfo;    //光标信息结构体变量
	curInfo.dwSize = 1;
	curInfo.bVisible = FALSE;        //光标光标隐藏不可见
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &curInfo);    //设置光标信息
}

void MapInit()
{
	for (int i = 0; i < ROW; ++i)
	{
		for (int j = 0; j < COL; ++j)
		{
			CursorJump(2 * j, i);
			if (i == 0 || i == ROW - 1 || j == 0 || j == COL - 1)
			{
				Color(COL_WALL);
				g_map[i][j] = WALL;
				cout << "■";
			}
			else
			{
				g_map[i][j] = EMPTY;
				cout << "  ";
			}
		}
	}
	Color(7);
	CursorJump(0, ROW);
	cout << "当前得分是:" << g_grade;
}

void RandFood()
{
	int row, col;
	do
	{
		row = rand() % ROW;
		col = rand() % COL;
	} while (g_map[row][col] != EMPTY);
	g_map[row][col] = FOOD;
	Color(COL_FOOD);
	CursorJump(2 * col, row);
	cout << "●";
}

class Snack
{
public:
	Snack()
	{
		len = 2;
		rate = 3000;

		head.x = COL / 2;
		head.y = ROW / 2;
		g_map[head.y][head.x] = HEAD;

		body.resize(ROW * COL, Pos(0, 0));
		for (int i = 0; i < len; ++i)
		{
			body[i].x = head.x - i - 1;
			body[i].y = head.y;
			g_map[body[i].y][body[i].x] == BODY;
		}
	}

	void PrintSnake(int flag)
	{
		if (flag)
		{
			// 打印蛇
			Color(COL_SNAKE);
			CursorJump(2 * head.x, head.y);
			cout << "◆";
			for (int i = 0; i < len; ++i)
			{
				CursorJump(2 * body[i].x, body[i].y);
				cout << "◇";
			}
		}
		else
		{
			// 覆盖蛇
			if (body[len - 1].x != 0)
			{
				CursorJump(2 * body[len - 1].x, body[len - 1].y);
				cout << "  ";
			}
		}
	}

	void Judge(int x, int y)
	{
		if (g_map[head.y + y][head.x + x] == FOOD)
		{
			// 得分
			g_grade += 10;

			len++;
			if (rate > 1000)
				rate -= 50;
			Color(7);
			CursorJump(0, ROW);
			cout << "当前得分是:" << g_grade;
			RandFood();
		}
		else if (g_map[head.y + y][head.x + x] == WALL
			|| g_map[head.y + y][head.x + x] == BODY)
		{
			// 失败
			Sleep(2000);
			Color(7);
			system("cls");
			cout << "           GAME OVER!          " << endl;
			cout << "            游戏失败!          " << endl;
			exit(0);
		}
	}

	void Move(int x, int y)
	{
		Judge(x, y);
		PrintSnake(0);
		int tail = len - 1;
		g_map[body[tail].y][body[tail].x] = EMPTY;
		while (tail > 0)
		{
			body[tail].x = body[tail - 1].x;
			body[tail].y = body[tail - 1].y;
			--tail;
		}
		body[0].x = head.x;
		body[0].y = head.y;
		g_map[body[0].y][body[0].x] = BODY;
		head.x += x;
		head.y += y;
		g_map[head.y][head.x] = HEAD;
		PrintSnake(1);
	}

	void Run(int x, int y)
	{
		int t = 0;
		while (1)
		{
			if (t == 0)
				t = rate;

			while (--t)
			{
				if (kbhit() != 0)
					break;
			}

			if (t == 0)
				Move(x, y);
			else
				break;
		}
	}

	void Play()
	{
		int dir = RIGHT;
		int old = dir;
		while (1)
		{
			switch (dir)
			{
			case 'w':
			case 'W':
			case UP:
				Run(0, -1);
				old = dir;
				break;
			case 's':
			case 'S':
			case DOWN:
				Run(0, 1);
				old = dir;
				break;
			case 'a':
			case 'A':
			case LEFT:
				Run(-1, 0);
				old = dir;
				break;
			case 'd':
			case 'D':
			case RIGHT:
				Run(1, 0);
				old = dir;
				break;
			case SPACE:
				system("pause>nul");
				break;
			case ESC:
				system("cls");
				cout << "   ESC 退出游戏" << endl;
				exit(0);
			}

			dir = getch();
			switch (dir)
			{
			case 'w':
			case 'W':
			case UP:
			case 's':
			case 'S':
			case DOWN:
				if (old == UP || old == DOWN)
					dir = old;
				break;
			case 'a':
			case 'A':
			case LEFT:
			case 'd':
			case 'D':
			case RIGHT:
				if (old == LEFT || old == RIGHT)
					dir = old;
				break;
			case SPACE:
			case ESC:
				break;
			default:
				dir = old;
			}
		}
	}

private:
	struct Pos
	{
		int x, y;

		Pos() {}
		Pos(int x1, int y1)
			: x(x1), y(y1)
		{}
	};

	Pos head;
	vector<Pos> body;
	int len;
	int rate;
};

int main()
{
	SysInit();
	MapInit();
	RandFood();

	Snack s;
	s.Play();

	return 0;
}

四、测试

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

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

相关文章

19.HarmonyOS App(JAVA)依赖布局DependentLayout使用方法

layout/ability_main.xml 显示位置不对&#xff1a;检查布局文件ohos:lef_of "id:tuzi",比如显示在兔子的左侧&#xff0c;这里就会显示不对。 需要id前没有$符号。改为&#xff1a; ohos:lef_of "$id:tuzi" <?xml version"1.0" encodi…

服务器学习

云服务器通常是通过多台物理服务器协同工作来提供的。云服务提供商使用大规模的数据中心&#xff0c;这些数据中心包含许多物理服务器。这些物理服务器上运行着虚拟化技术&#xff0c;允许它们被分割成多个虚拟服务器实例。 当用户请求创建一个云服务器时&#xff0c;云服务提…

FreeCAD的python脚本编写

简介 FreeCAD是一款强大的开源CAD软件&#xff0c;可以与python无缝对解&#xff0c;使用python来驱动三维几何的构建&#xff0c;具有很高的灵活性。本文主要讨论一下录制宏的方法&#xff0c;以及如何驱动特定参数 方法 打开FreeCAD软件&#xff0c;点击录制宏按钮后&…

C++实现鼠标点击和获取鼠标位置(编译环境visual studio 2022)

1环境说明 2获取鼠标位置的接口 void GetMouseCurPoint() {POINT mypoint;for (int i 0; i < 100; i){GetCursorPos(&mypoint);//获取鼠标当前所在位置printf("% ld, % ld \n", mypoint.x, mypoint.y);Sleep(1000);} } 3操作鼠标左键和右键的接口 void Mo…

什么是功能安全?

前言 在上一家公司的时候&#xff0c;有幸参加过公司内部的技术分享会&#xff0c;有一个同事跟我们分享了功能安全的一些内容。在提问环节&#xff0c;我问了一个问题“什么是功能安全&#xff1f;”他回答不上来。这也是我们很多人在工作中常犯的一个问题&#xff1a;我们做了…

汽车租赁系统

目录 一.研究背景 二.系统架构 1、SSM 2、JAVA 3、MySQL 4、系统架构 三.系统功能 1、车辆管理 2、客户管理 3、销售管理 4、统计分析 四.系统实现 五.结论总结 一.研究背景 传统的销售与信息统计管理都主要依靠人工&#xff0c;处理出的销售数据量与使用管理系统…

vcruntime140.dll有什么作用?vcruntime140.dll缺失的解决方法分享

解决因缺少vcruntime140.dll文件引起的问题实际上是相对简单的尽管最近有许多人在抱怨该文件频繁丢失且不知道该如何处理。作为一个责任编辑&#xff0c;我认为有很大的必要向大家清楚地解释一下。让我们从探索vcruntime140.dll文件缺少的修复方法吧。 一.msvcp140.dll的作用 …

基于springboot就业信息管理系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;就业信息管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而…

2024年美赛数学建模E题思路分析 - 财产保险的可持续性

# 1 赛题 问题E&#xff1a;财产保险的可持续性 极端天气事件正成为财产所有者和保险公司面临的危机。“近年来&#xff0c;世界已经遭受了1000多起极端天气事件造成的超过1万亿美元的损失”。[1]2022年&#xff0c;保险业的自然灾害索赔人数“比30年的平均水平增加了115%”。…

FastCAE合作开发项目:可执行调试的脚本编辑器

开发内容 1. 要求能够编辑脚本内容 2. 要求能够高亮显示关键字、纯数字、单行注释、多行注释等 3. 要求能够设置断点功能 4. 要求能够进行运行求解器、单步运行、暂停、继续、终止等基本调试功能 5. 要求能够高亮执行脚本&#xff0c;分别展示单脚本行执行中与执行完成效果…

更新npm镜像源:淘宝镜像已过期,及时切换!

你好&#xff0c;我是小白Coding日志&#xff0c;一个热爱技术的程序员。在这里&#xff0c;我分享自己在编程和技术世界中的学习心得和体会。希望我的文章能够给你带来一些灵感和帮助。欢迎来到我的博客&#xff0c;一起在技术的世界里探索前行吧&#xff01; 前言 就在昨天…

第二卷《皈依的意义与方法》

甲二、别明皈依的方法 分二&#xff1a;初、事相皈依。二、理体皈依。 前面一科讲到“皈依的意义”——“能皈依的心”跟“所皈依的境”。 “能皈依的心”就是我们有一种祈求救护的心情&#xff1b;“所皈依的境”有二种&#xff1a;一种是“住持三宝”&#xff0c;或者讲外…

Git快速入门+常用指令+提交规范

目录 Git创建本地仓库 IDEA集成Git Git和IDEA连接使用2 忽略文件 本地仓库常用命令 远程仓库常用命令 分支常用命令 标签操作 提交规范 Git创建本地仓库 1、创建一个文件夹&#xff0c;右键选择Git Bash Here 2、选择下列其中一个方法 方法一&#xff1a;创建初始化…

【算法与数据结构】583、72、LeetCode两个字符串的删除操作+编辑距离

文章目录 一、583、两个字符串的删除操作二、72、编辑距离三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、583、两个字符串的删除操作 思路分析&#xff1a;本题的思路和115、不同的子序列差不多&#xff0c;只是变成…

vue3+threejs+koa可视化项目——模型文件上传(第四步)

文章目录 ⭐前言&#x1f496;往期node系列文章&#x1f496;threejs系列相关文章&#x1f496;vue3threejs系列 ⭐koa后端文件上传(koa-body)&#x1f496;自动创建目录&#x1f496;自定义目录上传&#x1f496;apifox自测上传接口 ⭐vue3前端上传模型文件&#x1f496; axio…

【测试运维】性能测试笔记文档第2篇:性能测试分类和指标(已分享,附代码)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论性能测试相关知识。入门阶段&#xff1a;认识性能测试分类-(负载测试、压力测试、并发测试、稳定性测试)&#xff0c;常用性能测试指标-(吞吐量、并发数、响应时间、点击数…)&#xff0c;性能测试工具选择。性能脚本&a…

口味多样的碱水贝果面包,香气饱满松松软软

这两天在吃一款碱趣贝果面包&#xff0c;感觉味道很不错&#xff0c;它是一种加热一下就可以吃的手工面包&#xff0c;口感十分独特。这款面包有着清香有韧性的表皮&#xff0c;里面松软可口&#xff0c;加热后更是香气四溢。 除了标准的原味全麦之外&#xff0c;碱趣贝果面包还…

提取人声消除背景音乐的工具?分享4款!

音乐是生活中不可或缺的调味品&#xff0c;我们常常会遇到一些音乐中的对话或人声干扰了我们的聆听体验。那么&#xff0c;有没有一种方法可以消除这些干扰&#xff0c;只留下纯净的背景音乐呢&#xff1f;答案是肯定的&#xff0c;下面为大家介绍4款能够消除人声保留背景音乐的…

LNMP.

一.mysl配置 1.安装mysql yum install mysql-server -y 2.进入mysql配置文件目录 cd /etc/my.cnf.d3.编辑mysql配置文件 vim mysql-server.cnf 在[mysqld]中添加: character-set-serverutf84.启动mysql服务 systemctl start mysqld5.登入mysql mysql 6.创建数据库 cre…

泡泡清新文艺的微社区系统PHP源码

泡泡微社区&#xff0c;小巧而强大&#xff0c;为您带来卓越的社区交流体验。 凭借GoZinc的先进架构&#xff0c;泡泡在保持轻盈身姿的同时&#xff0c;功能一应俱全。前端采用Vue3匠心打造&#xff0c;界面清新简约&#xff0c;三栏式布局仿若Twitter&#xff0c;让您一见倾心…