C++实现2048

在冬令营没意思了就写起了2048。。。

一开始写了个特别粗劣的、没有界面优化的简易版。。。

然后被嘲讽了“真难看”

于是又做了界面优化。

然后改bug改出一堆。。。

先来个更新日志

V1.0.0
2018.1.15发布
最初版本
-------------------------------------------
V2.0.0
2018.1.16发布
大型更新:界面进行了全面优化。
大型更新:支持5*5,6*6格式了。
大型更新:可以在本地保存成绩了。
大型更新:增加“分数”,评分标准与原版游戏相似。
-------------------------------------------
V2.0.1
2018.1.16发布
修复:修复了保存成绩的bug。
-------------------------------------------
V2.0.2
2018.1.16发布
优化:算法优化。
优化:独立头文件。
更新:支持4096+的数字颜色。
修复:修复了无效输入会引起不停“正在处理”的显示。
优化:增加错误信息提示“无效的动作”。
优化:优化了保存成绩的选项。
修复:修复了int型和unsigned型比较时可能出现的bug。
鸣谢 ytj 的大力资瓷。
-------------------------------------------
V2.0.3
2018.1.17发布
优化:优化了按键之后的提示信息。
优化:程序空间优化,可以删除2048.h这个文件了。

-------------------------------------------

接下来就是代码,非常简单的控制台小游戏。。。

(博主辛辛苦苦写了好久代码,引用请注明出处,谢谢!!!)

(发现bug可以私信我)

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <list>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <functional>
#include <bitset>
#include <ctime>
#include <windows.h>
#include <conio.h>
#include <io.h>
#include <process.h>
#define getch _getch

#define up 1
#define down 2
#define left 3
#define right 4

using std::string;
using std::vector;
using std::cin;
using std::cout;
using std::printf;
using std::rand;
using std::freopen;
using std::fclose;
#define endl '\n'

namespace LYD
{
	void color(int a)
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
	}

	void set_color(int num)
	{
		switch (num)
		{
		case 0:color(0); return;
		case 2:color(112); return;
		case 4:color(96); return;
		case 8:color(224); return;
		case 16:color(80); return;
		case 32:color(208); return;
		case 64:color(64); return;
		case 128:color(192); return;
		case 256:color(16); return;
		case 512:color(48); return;
		case 1024:color(176); return;
		case 2048:color(144); return;
		default:color(160); return;
		}
	}
	
	void del(int num)
	{
		for (int i = 0; i<num; i++)
			printf("\b \b");
	}
	
	struct node
	{
		int val;
		string name;
	};
	node high[3];
	
	int edge = 4;
	int game[110][110];
	int x = 1, y = 1;
	int num = 0, score = 0;
	bool f = true;

	void print_screen()
	{
		system("cls");
		color(8);
		printf("┏");
		for (int i = 1; i <= edge; i++)
			printf("━━━┳");
		del(2);
		printf("┓\n");
		for (int i = 1; i <= edge; i++)
		{
			printf("┃");
			for (int j = 1; j <= edge; j++)
			{
				set_color(game[i][j]);
				printf("      ");
				color(8);
				printf("┃");
			}
			printf("\n");
			printf("┃");
			for (int j = 1; j <= edge; j++)
			{
				set_color(game[i][j]);
				if (game[i][j] != 0)
					printf("% 5d ", game[i][j]);
				else
					printf("      ");
				color(8);
				printf("┃");
			}
			printf("\n");
			printf("┃");
			for (int j = 1; j <= edge; j++)
			{
				set_color(game[i][j]);
				printf("      ");
				color(8);
				printf("┃");
			}
			printf("\n");
			if (i != edge)
			{
				printf("┣");
				for (int j = 1; j <= edge; j++)
					printf("━━━╋");
				del(2);
				printf("┫\n");
			}
		}
		printf("┗");
		for (int i = 1; i <= edge; i++)
			printf("━━━┻");
		del(2);
		printf("┛\n");
		printf("步数:%d\n", num);
		printf("得分:%d\n", score);
	}
	
	void randxy()
	{
		do
		{
			x = rand() % edge + 1;
			y = rand() % edge + 1;
		} while (game[x][y] != 0);
		int num = rand() % 10;
		if (num >= 2)
			game[x][y] = 2;
		else
			game[x][y] = 2;
	}
	
	bool check()
	{
		for (int i = 1; i <= edge; i++)
			for (int j = 1; j <= edge; j++)
				if (game[i][j] == 0)
					return true;
		for (int i = 1; i <= edge; i++)
		{
			for (int j = 1; j <= edge; j++)
			{
				if (i - 1 >= 1 && game[i - 1][j] == game[i][j])
					return true;
				if (j - 1 >= 1 && game[i][j - 1] == game[i][j])
					return true;
				if (i + 1 <= edge&&game[i + 1][j] == game[i][j])
					return true;
				if (j + 1 <= edge&&game[i][j + 1] == game[i][j])
					return true;
			}
		}
		return false;
	}
	
	bool check_move(int num)
	{
		vector <int> v;
		bool f1 = false;
		if (num == up)
		{
			for (int j = 1; j <= edge; j++)
			{
				f1 = false;
				for (int i = 1; i <= edge; i++)
				{
					if (game[i][j] != 0 && f1 == true)
						return true;
					if (game[i][j] != 0)
						v.push_back(game[i][j]);
					else
						f1 = true;
				}
				for (unsigned i = 0; i<v.size(); i++)
					if (i + 1<v.size() && v[i] == v[i + 1])
						return true;
				v.clear();
			}
		}
		if (num == down)
		{
			for (int j = 1; j <= edge; j++)
			{
				f1 = false;
				for (int i = edge; i >= 1; i--)
				{
					if (game[i][j] != 0 && f1 == true)
						return true;
					if (game[i][j] != 0)
						v.push_back(game[i][j]);
					else
						f1 = true;
				}
				for (unsigned i = 0; i<v.size(); i++)
					if (i + 1<v.size() && v[i] == v[i + 1])
						return true;
				v.clear();
			}
		}
		if (num == left)
		{
			for (int i = 1; i <= edge; i++)
			{
				f1 = false;
				for (int j = 1; j <= edge; j++)
				{
					if (game[i][j] != 0 && f1 == true)
						return true;
					if (game[i][j] != 0)
						v.push_back(game[i][j]);
					else
						f1 = true;
				}
				for (unsigned j = 0; j<v.size(); j++)
					if (j + 1<v.size() && v[j] == v[j + 1])
						return true;
				v.clear();
			}
		}
		if (num == right)
		{
			for (int i = 1; i <= edge; i++)
			{
				f1 = false;
				for (int j = edge; j >= 1; j--)
				{
					if (game[i][j] != 0 && f1 == true)
						return true;
					if (game[i][j] != 0)
						v.push_back(game[i][j]);
					else
						f1 = true;
				}
				for (unsigned j = 0; j<v.size(); j++)
					if (j + 1<v.size() && v[j] == v[j + 1])
						return true;
				v.clear();
			}
		}
		return false;
	}
	
	void Merge(int num)
	{
		vector <int> v;
		if (num == up)
		{
			for (int j = 1; j <= edge; j++)
			{
				for (int i = 1; i <= edge; i++)
				{
					if (game[i][j] != 0)
						v.push_back(game[i][j]);
					game[i][j] = 0;
				}
				for (unsigned i = 0; i<v.size(); i++)
				{
					if (i + 1<v.size() && v[i] == v[i + 1])
					{
						v[i] += v[i];
						f = true;
						score += v[i];
						for (unsigned k = i + 1; k<v.size(); k++)
							if (k + 1<v.size())
								v[k] = v[k + 1];
						v.pop_back();
					}
				}
				for (unsigned i = 1; i <= v.size(); i++)
					game[i][j] = v[i - 1];
				v.clear();
			}
		}
		if (num == down)
		{
			for (int j = 1; j <= edge; j++)
			{
				for (int i = edge; i >= 1; i--)
				{
					if (game[i][j] != 0)
						v.push_back(game[i][j]);
					game[i][j] = 0;
				}
				for (unsigned i = 0; i<v.size(); i++)
				{
					if (i + 1<v.size() && v[i] == v[i + 1])
					{
						v[i] += v[i];
						f = true;
						score += v[i];
						for (unsigned k = i + 1; k<v.size(); k++)
							if (k + 1<v.size())
								v[k] = v[k + 1];
						v.pop_back();
					}
				}
				for (unsigned i = edge, k = 0; k<v.size(); i--, k++)
					game[i][j] = v[k];
				v.clear();
			}
		}
		if (num == left)
		{
			for (int i = 1; i <= edge; i++)
			{
				for (int j = 1; j <= edge; j++)
				{
					if (game[i][j] != 0)
						v.push_back(game[i][j]);
					game[i][j] = 0;
				}
				for (unsigned j = 0; j<v.size(); j++)
				{
					if (j + 1<v.size() && v[j] == v[j + 1])
					{
						v[j] += v[j];
						f = true;
						score += v[j];
						for (unsigned k = j + 1; k<v.size(); k++)
							if (k + 1<v.size())
								v[k] = v[k + 1];
						v.pop_back();
					}
				}
				for (unsigned j = 1, k = 0; k<v.size(); j++, k++)
					game[i][j] = v[k];
				v.clear();
			}
		}
		if (num == right)
		{
			for (int i = 1; i <= edge; i++)
			{
				for (int j = edge; j >= 1; j--)
					if (game[i][j] != 0)
					{
						v.push_back(game[i][j]);
						game[i][j] = 0;
					}
				for (unsigned j = 0; j<v.size(); j++)
				{
					if (j + 1<v.size() && v[j] == v[j + 1])
					{
						v[j] += v[j];
						f = true;
						score += v[j];
						for (unsigned k = j + 1; k<v.size(); k++)
							if (k + 1<v.size())
								v[k] = v[k + 1];
						v.pop_back();
					}
				}
				for (unsigned j = edge, k = 0; k<v.size(); j--, k++)
					game[i][j] = v[k];
				v.clear();
			}
		}
	}
	
	void set_edge()
	{
		char c;
		system("cls");
		printf("请选择边长:\n");
		printf("1.4*4\n");
		printf("2.5*5\n");
		printf("3.6*6\n");
		printf("请输入...");
		while (1)
		{
			bool flag = 0;
			c = getch();
			switch (c)
			{
			case '1':edge = 4; flag = 1; break;
			case '2':edge = 5; flag = 1; break;
			case '3':edge = 6; flag = 1; break;
			}
			if (flag)
				break;
			else
				continue;
		}
	}
	
	void get()
	{
		freopen("2048-score.txt", "r", stdin);
		for (int i = 0; i<3; i++)
		{
			int a;
			cin >> a;
			high[i].val = 0;
			if (a == 1)
				cin >> high[i].name >> high[i].val;
		}
		fclose(stdin);
	}

	void high_score()
	{
		system("cls");
		color(6);
		printf("4*4\n");
		printf("第一名:");
		if (high[0].val)
			cout << high[0].name << endl;
		else
			cout << "无" << endl;
		printf("分数:%d\n", high[0].val);
		printf("\n");

		color(9);
		printf("5*5\n");
		printf("第一名:");
		if (high[1].val)
			cout << high[1].name << endl;
		else
			cout << "无" << endl;
		printf("分数:%d\n", high[1].val);
		printf("\n");

		color(10);
		printf("6*6\n");
		printf("第一名:");
		if (high[2].val)
			cout << high[2].name << endl;
		else
			cout << "无" << endl;
		printf("分数:%d\n", high[2].val);
		printf("\n");
		system("pause");
	}
	
	void help()
	{
		system("cls");
		printf("1.死后记录成绩\n");
		printf("2.目前最高支持到4096\n");
		printf("3.成绩保存在同目录下的\"2048-score.txt\"中。\n");
		printf("4.暂不开放颜色自主更改\n");
		printf("5.游戏使用上下左右方向键控制\n");
		system("pause");
	}
	
	void start()
	{
		char c;
	kaishi:
		system("cls");
		color(14);
		printf("2048 V2.0.2\n");
		color(10);
		printf("by ");
		color(9);
		printf("BCtt_YDLee\n");
		color(14);
		printf("\n");
		color(11);
		printf("\n");
		printf("1.开始游戏\n");
		printf("2.查看排行榜\n");
		printf("3.查看帮助\n");
		printf("4.读入成绩\n");
		printf("0.退出游戏\n");
		printf("请输入...");
		while (1)
		{
			c = getch();
			if (c == '1')
				break;
			if (c == '2')
			{
				high_score();
				goto kaishi;
			}
			if (c == '0')
				exit(0);
			if (c == '3')
			{
				help();
				goto kaishi;
			}
			if (c == '4')
			{
				get();
				goto kaishi;
			}
		}
	}
	
	void dead()
	{
		system("cls");
		printf("您最后的得分为:%d\n", score);
		printf("请留下您的名字:");
		string s;
		cin >> s;
		if (score >= high[edge - 4].val)
		{
			high[edge - 4].name = s;
			high[edge - 4].val = score;
		}
		freopen("2048-score.txt", "w", stdout);
		for (int i = 0; i<3; i++)
		{
			if (high[i].val)
			{
				cout << 1 << endl;
				cout << high[i].name << ' ' << high[i].val << endl;
			}
			else
				cout << 0 << endl;
		}
	}
	
}

int main()
{
	using namespace LYD;

	SetConsoleTitle("2048");

	srand((unsigned)time(NULL));
	memset(game, 0, sizeof(game));
	char c;
	start();
	set_edge();
	while (check())
	{
		if (f == true)
		{
			randxy();
			print_screen();
			num++;
		}
		f = false;
		c = getch();
		char direction;
		switch (c)
		{
		case 'H':direction = up;break;
		case 'P':direction = down;break;
		case 'K':direction = left;break;
		case 'M':direction = right;break;
		default:continue;
		}
		f = check_move(direction);
		if(f==false)
			printf("无效动作,请重试。");
		else
			printf("正在处理。。。"); 
		Merge(direction);
	}
	dead();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值