2048源代码~~小游戏。C++实现

每一个学习软件工程的人,都很想自己写出游戏的代码,我也不例外,但是,能写出一些小游戏的代码,并不能说明你很厉害,而只能说明你对于这门语言你比较熟悉了。

2048这个游戏,是一两年前很火的游戏,不过现在也没什么人在玩了,闲来没事,就写了一下这个游戏,控制台上实现的,目前我还不会写窗口,所以很多东西都只能在控制台上来实现了。

2048这个小游戏,主要的是上下左右移动后,相同的数合并,不相同的数原样输出,而你就是要判断每一行或每一列有没有相同的,还有一点就是,数字有移动,就产生新的数,没有,什么都不用做。

下面是头文件的:

class New2048
{
public:
	New2048()                       //构造函数,初始话数据。
	{ 
		for (int i = 0; i < 4; i++)
		for (int j = 0; j < 4; j++)
			a[i][j] = 0;
		num = 0;
	}
	void make_frame();             //打印框架函数。
	void display_num();            //打印数字函数。
	void creat_num();              //随机产生数函数
	void RightMove();              //右移函数
	void LeftMove();               //左移函数
	void UpMove();		       //上移函数
	void DownMove();	       //下移函数
	int cheak();                   //检查游戏是否结束函数
	void clean();                  //清理显示出来的数字
	~New2048(){}

private:
	int a[4][4];
	int num;
};


下面是各个函数的cpp文件:

# include <iostream>
# include <Windows.h>
# include <time.h>
# include <conio.h>
# include "2048.h"
using namespace std;

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);    //获取句柄
void gotoxy(HANDLE hOut, int x, int y)            //输出位置的函数
{
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(hOut, pos);
}
void New2048::make_frame()                       //打印框架
{
	gotoxy(hOut, 0, 0);
	cout << "         得分" << endl;
	cout << "┏━━┳━━┳━━┳━━┓" << endl;
	cout << "┃    ┃    ┃    ┃    ┃" << endl;
	cout << "┣━━╋━━╋━━╋━━┫" << endl;
	cout << "┃    ┃    ┃    ┃    ┃" << endl;
	cout << "┣━━╋━━╋━━╋━━┫" << endl;
	cout << "┃    ┃    ┃    ┃    ┃" << endl;
	cout << "┣━━╋━━╋━━╋━━┫" << endl;
	cout << "┃    ┃    ┃    ┃    ┃" << endl;
	cout << "┗━━┻━━┻━━┻━━┛" << endl;
}
void New2048::clean()
{
	int k = 0, l = 0;
	for (int i = 2; i < 21, k < 4; i = i + 6)    //找到对应的框,输入空格
	{
		l = 0;
		for (int j = 2; j < 9; j = j + 2)
		{
			gotoxy(hOut, i, j);
			printf("    ");
			l++;
		}
		k++;
	}
}
void New2048::display_num()                          //打印数字
{
	int k = 0, l = 0;
	for (int i = 2; i < 21, k < 4; i = i + 6)    //找到对应的框,输入数字,这个尝试了好久,才搞定了。
	{
		l = 0;
		for (int j = 2; j < 9; j = j + 2)
		{
			gotoxy(hOut, i, j);          //找到各个位置并输出数字
			a[l][k] == 0 ? printf(" ") : printf("%d", a[l][k]);
			l++;
		}
		k++;
	}
	gotoxy(hOut, 13, 0);
	cout << num * 100;
	gotoxy(hOut, 0, 10);
}
void New2048::creat_num()                     //随机产生坐标位置和该位置的数 2 或 4
{
	int i, j, num;
	srand((unsigned)time(NULL));             //随机数产生初始化,不然产生的数一直相同        
	i = (rand() % (4)) + 0;
	j = (rand() % (4)) + 0;
	while (a[i][j])                           //该位置上的数不是0,重新产生
	{
		i = (rand() % (4)) + 0;
		j = (rand() % (4)) + 0;
	}
	num = (rand() % (4)) + 1;                //产生的是1就自增,是3便自减或自增,都可以的
	if (num == 1)
		++num;
	if (num == 3)
		--num;
	a[i][j] = num;
}
int New2048::cheak()
{
	int i, j, flag = 0, tag = 0;
	for (i = 0; i < 4; i++)                  //检查是否还有位置,有,tag = 1。
	{
		for (j = 0; j < 4; j++)
		{
			if (a[i][j] == 0)
			{
				tag = 1;
				break;
			}
		}
		if (tag == 1)
			break;
	}
	if (tag)                               //有,返回1。
		return 1;
	for (i = 0; i < 4; i++)                //检查左右的相邻是否有相等,是,flag = 1,退出循环
	{
		for (j = 0; j < 3; j++)
		{
			if (a[i][j] == a[i][j + 1])
			{
				flag = 1;
				break;
			}
		}
		if (flag == 1)
			break;
	}
	for (j = 0; j < 4; j++)                //检查上下的相邻是否有想等,是,flag = 1,退出循环
	{
		for (i = 0; i < 3; i++)
		{
			if (a[i][j] == a[i + 1][j])
			{
				flag = 1;
				break;
			}
		}
		if (flag == 1)
			break;
	}
	if (tag == 0 && flag == 0)            //flag = 0 和 tag = 0,游戏结束。
		return 0;
	else                                  //否则,继续游戏
		return 1;
}
void New2048::DownMove()                  //下移的情况
{
	int k, tag = 0;
	for (int i = 0; i < 4; i++)           //从每一列开始
	{
		int b[4] = { 0 };				 //定义一个临时数组来存储相加之后的情况
		k = 3;
		for (int j = 3; j > 0; j--)
		{
			if (a[j][i] != 0)
			{
				int flag = 0;
				for (int l = j - 1; l >= 0; l--)    //找是否有相同的数
				{
					if (a[l][i] != 0)
					{
						flag = 1;
						if (a[l][i] == a[j][i])
						{
							b[k--] = 2 * a[j][i];
							num++;         
							a[l][i] = a[j][i] = 0;
							break;
						}
						else
						{
							b[k--] = a[j][i];
							break;
						}
					}
				}
				if (flag == 0)
					b[k--] = a[j][i];
			}
		}
		b[k] = a[0][i];                 //最后一个没有检查,赋值过去,不管是否为0,都无所谓的
		for (int j = 0; j < 4; j++)     //检查是否有移动
		{
			if (a[j][i] != b[j])
			{
				tag = 1;
				break;
			}
		}
		for (int j = 0; j < 4; j++)    //将结果覆盖回去
			a[j][i] = b[j];
	}
	if (tag)                          //存在移动,产生新的数
		creat_num();
}
void New2048::LeftMove()                 //同上
{
	int k, tag = 0;
	for (int i = 0; i < 4; i++)
	{
		int b[4] = { 0 };
		k = 0;
		for (int j = 0; j < 3; j++)
		{
			if (a[i][j] != 0)
			{
				int flag = 0;
				for (int l = j + 1; l < 4; l++)
				{
					if (a[i][l] != 0)
					{
						flag = 1;
						if (a[i][l] == a[i][j])
						{
							b[k++] = 2 * a[i][j];
							num++;
							a[i][j] = a[i][l] = 0;
							break;
						}
						else
						{
							b[k++] = a[i][j];
							break;
						}
					}
				}
				if (flag == 0)
					b[k++] = a[i][j];
			}
		}
		b[k] = a[i][3];
		for (int j = 0; j < 4; j++)
		{
			if (a[i][j] != b[j])
			{
				tag = 1;
				break;
			}
		}
		for (int j = 0; j < 4; j++)
			a[i][j] = b[j];
	}
	if (tag)
		creat_num();
}
void New2048::RightMove()              //同上
{
	int k, tag = 0;
	for (int i = 0; i < 4; i++)
	{
		int b[4] = { 0 };
		k = 3;
		for (int j = 3; j > 0; j--)
		{
			if (a[i][j] != 0)
			{
				int flag = 0;
				for (int l = j - 1; l >= 0; l--)
				{
					if (a[i][l] != 0)
					{
						flag = 1;
						if (a[i][l] == a[i][j])
						{
							b[k--] = 2 * a[i][j];
							num++;
							a[i][j] = a[i][l] = 0;
							break;
						}
						else
						{
							b[k--] = a[i][j];
							break;
						}
					}
				}
				if (flag == 0)
					b[k--] = a[i][j];
			}
		}
		b[k] = a[i][0];
		for (int j = 0; j < 4; j++)
		{
			if (a[i][j] != b[j])
			{
				tag = 1;
				break;
			}
		}
		for (int j = 0; j < 4; j++)
			a[i][j] = b[j];
	}
	if (tag)
		creat_num();
}
void New2048::UpMove()
{
	int k, tag = 0;
	for (int i = 0; i < 4; i++)
	{
		int b[4] = { 0 };                 //定义一个临时数组来存储相加之后的情况
		k = 0;
		for (int j = 0; j < 3; j++)
		{
			if (a[j][i] != 0)
			{
				int flag = 0;
				for (int l = j + 1; l < 4; l++)    //找是否有相同的数
				{
					if (a[l][i] != 0)
					{
						flag = 1;
						if (a[l][i] == a[j][i])
						{
							b[k++] = 2 * a[j][i];
							num++;
							a[l][i] = a[j][i] = 0;
							break;
						}
						else
						{
							b[k++] = a[j][i];
							break;
						}
					}
				}
				if (flag == 0)
					b[k++] = a[j][i];
			}
		}
		b[k] = a[3][i];
		for (int j = 0; j < 4; j++)
		{
			if (a[j][i] != b[j])
			{
				tag = 1;
				break;
			}
		}
		for (int j = 0; j < 4; j++)      //将结果覆盖回去
			a[j][i] = b[j];
	}
	if (tag)
		creat_num();
}

主函数的cpp文件:

# include <iostream>
# include <conio.h>
# include "2048.h"
using namespace std;

int main()
{
	while (1)
	{
		char ch;
		system("cls");                        //清屏
		system("color 3B");                   //改变背景和字体颜色
		New2048 s;
		s.make_frame();                       //打印框架
		s.creat_num();
		s.creat_num();                        //产生两个随机数
		s.display_num();                      //显示数字
		while (1)
		{
			ch = _getch();                   //如果不是VS的,_getch应该改成getch
			if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || 
				ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')
				break;
		}
p:		switch (ch)
		{
		case 's':
		case 'S':
		{
					while (s.cheak())
					{
						s.DownMove();             //下移
						s.clean();                //清理
						s.display_num();          //显示数字
						while (1)
						{
							ch = _getch();
							if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' ||
								ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')
								break;
						}
						goto p;
					}
		}break;
		case 'd':
		case 'D':
		{
					while (s.cheak())
					{
						s.RightMove();                //右移
						s.clean();                    //清理
						s.display_num();              //显示数字
						while (1)
						{
							ch = _getch();
							if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || 
								ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')
								break;
						}
						goto p;
					}
		}break;
		case 'a':
		case 'A':
		{
					while (s.cheak())
					{
						s.LeftMove();              //左移
						s.clean();                 //清理
						s.display_num();           //显示数字
						while (1)
						{
							ch = _getch();
							if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || 
								ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')
								break;
						}
						goto p;
					}
		}break;
		case 'w':
		case 'W':
		{
					while (s.cheak())
					{
						s.UpMove();               //上移
						s.clean();                //清理
						s.display_num();          //显示数字
						while (1)
						{
							ch = _getch();
							if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || 
								ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')
								break;
						}
						goto p;
					}
		}break;
		default:
			break;
		}                            //退出switch,游戏结束
		system("cls");               //清屏
		cout << "               PLAY AGAIN ? YES(Y) : NO(N)" << endl;
		while (1)
		{
			ch = _getch();
			if (ch == 'y' || ch == 'n' || ch == 'Y' || ch == 'N')
				break;
		}
		if (ch == 'y' || ch == 'Y')          //Y继续
			continue;
		else                                 //否则退出
			break;
	}
	return 0;
}

游戏开始图片:



游戏过程中的图片:



游戏结束图片:


这个或多或少的存在bug,如果发现了,欢迎来告诉我,好让我改正!~~


  • 16
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值