惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
About on SuperTechFans
月光博客
月光博客
Jina AI
Jina AI
F
Fortinet All Blogs
博客园 - 聂微东
The Cloudflare Blog
美团技术团队
B
Blog RSS Feed
N
Netflix TechBlog - Medium
罗磊的独立博客
The GitHub Blog
The GitHub Blog
I
InfoQ
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Apple Machine Learning Research
Apple Machine Learning Research
H
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
阮一峰的网络日志
阮一峰的网络日志
V
V2EX

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解
简易贪吃蛇
myLv · 2026-05-03 · via 博客园_首页

Snake Game

一个使用C++实现的控制台简易贪吃蛇小游戏,刚开始做项目训练。

使用方式

使用W,S,A,D来实现上下左右移动,Q退出,P暂停。

注意事项

  • 要C++ 11或以上的版本
  • 作者是在读大学生,如果你对我的代码有任何问题或优化方法,请务必告知❤️❤️

代码

#include <iostream>
#include <random>
#include <vector>
#include <Windows.h>
#include <conio.h>
#include <fstream>
using namespace std;

const int WIDTH  = 22;
const int LENGTH = 32;

// 蛇头的朝向
enum Direction {
	UP,
	DOWN,
	LEFT,
	RIGHT
};

class GameMap {
public:
	char gameMap[WIDTH][LENGTH];	// 游戏地图
	int food_x, food_y;	// 食物的坐标
	int Score;	// 得分
	int Round;	// 轮次
	int AllTimeHigh_score;	// 历史最高得分

public:
	GameMap()
	{
		for (int j = 0; j < LENGTH; j++) gameMap[0][j] = gameMap[WIDTH - 1][j] = '-';	// 上下边界
		for (int i = 1; i < WIDTH-1; i++) gameMap[i][0] = gameMap[i][LENGTH - 1] = '|';	// 左右边界
		for (int i = 1; i < WIDTH - 1; i++) for (int j = 1; j < LENGTH - 1; j++) gameMap[i][j] = ' ';	// 中间清空

		Score = Round = AllTimeHigh_score = 0;	// 初始化,Round用0是因为程序员的第一是0

		generate_food();
	}

	void generate_food()
	{
		random_device rd;
		mt19937 gen(rd());

		uniform_int_distribution<> dist_x(1, WIDTH - 2);	food_x = dist_x(gen);
		uniform_int_distribution<> dist_y(1, LENGTH - 2);	food_y = dist_y(gen);

		gameMap[food_x][food_y] = '$';
	}

	void show()
	{
		system("cls");  // 清屏刷新
		cout << "All-time high score: " << loadHighScore() << ", Round: " << Round << ", Score: " << Score << endl;
		for (int i = 0; i < WIDTH; i++)
		{
			for (int j = 0; j < LENGTH; j++) cout << gameMap[i][j];
			cout << endl;
		}
	}

	int loadHighScore()
	{
		ifstream ifs("AllTimeHighScore.txt", ios::in);
		int hs = 0;
		if (ifs >> hs) return hs;
		return 0;
	}

	void saveHighScore(int hs)
	{
		ofstream ofs("AllTimeHighScore.txt", ios::out);
		ofs << hs;
	}
};

class Snake : public GameMap {
private:
	vector<pair<int, int>> mySnake;	// 蛇的坐标
	int head_x, head_y;	// 蛇头
	Direction Dir;		// 蛇头朝向

public:
	Snake()
	{
		head_x = 10, head_y = 15;
		mySnake.push_back(make_pair(head_x, head_y));
		mySnake.push_back(make_pair(head_x, head_y-1));	// 初始时设置蛇的长度为2

		gameMap[head_x][head_y] = '0';
		gameMap[head_x][head_y] = 'o';

		Dir = RIGHT;
	}

	bool control_direction()
	{
		if (_kbhit())
		{
			char key = _getch();
			switch (key)
			{
				case 'w': if(Dir != DOWN)	Dir = UP;		break;
				case 's': if(Dir != UP)		Dir = DOWN;		break;
				case 'a': if(Dir != RIGHT)	Dir = LEFT;		break;
				case 'd': if(Dir != LEFT)	Dir = RIGHT;	break;
				case 'p': system("pause");	break;
				case 'q': return false;
			}
		}
		return true;
	}

	bool move()
	{
		// 更新头部
		switch (Dir)
		{
			case UP:    head_x--; break;
			case DOWN:  head_x++; break;
			case LEFT:  head_y--; break;
			case RIGHT: head_y++; break;
		}
		mySnake.insert(mySnake.begin(), make_pair(head_x, head_y));

		// 撞墙检测
		if (head_x <= 0 || head_x >= WIDTH-1 || head_y <= 0 || head_y >= LENGTH-1)
		{
			cout << "You hit the wall!" << endl;
			return false;
		}

		// 撞到自己检测
		for (int i = 1; i < (int)mySnake.size(); i++)
			if (mySnake[i].first == head_x && mySnake[i].second == head_y)
			{
				cout << "You are eating yourself!" << endl;
				return false;
			}

		// 吃到食物了
		if (head_x == food_x && head_y == food_y)
		{
			if (Round < 3) Score += 5;
			else if (Round < 7) Score += 10;
			else if (Round < 10) Score += 15;
			else if (Round < 30) Score += 20;
			else if (Round < 50) Score += 25;
			else if (Round < 100) Score += 30;
			else Score += 50;
			
			generate_food();
			Round++;
		}
		// 没吃到,要删除蛇尾
		else
		{
			gameMap[mySnake.back().first][mySnake.back().second] = ' ';
			mySnake.pop_back();
		}

		gameMap[head_x][head_y] = '0';
		gameMap[mySnake[1].first][mySnake[1].second] = 'o';

		return true;
	}

	void run()
	{
		while (true)
		{
			bool q = control_direction();
			if (!move() || !q)
			{
				cout << "Game over!" << endl;
				if (Score > AllTimeHigh_score) saveHighScore(Score);
				return;
			}
			show();
			if (Round < 3) Sleep(1000);
			else if (Round < 7) Sleep(700);
			else if (Round < 10) Sleep(500);
			else if (Round < 30) Sleep(400);
			else if (Round < 50) Sleep(300);
			else if (Round < 100) Sleep(200);
			else Sleep(100);
		}
	}
};

int main()
{
	Snake snake;
	snake.run();
	return 0;
}

如果你喜欢的话,能不能给我的github处也点各⭐:https://github.com/Shu-Jvan/Snake-Game