2048C++

2048C++,第1张

学习记录,使用图形库编程2048。效果展示如下:

通过整形二维数组存放棋盘内16个值,并且通过sprintf函数转换为字符型再显示于棋盘上。

核心在于用键盘 *** 作时,棋盘内数字移动的问题。使用了嵌套循环,利用双层for循环依次遍历每行每列,并将每行或每列的每一个值对前一个值进行覆盖,如此循环三次即可。代码如下: 

void Up(int arr[4][4], int* max, int* score)//向上移动函数
{
	int tmp = 3;
	int x = 0, y = 0;
	while (tmp--)//按下W,遍历整个数组,使每列每行的元素根据前列的值向上移动或停止一行,重复3次
	{
		for (x = 0; x < 4; x++)
		{
			for (y = 1; y < 4; y++)
			{
				while (1)
				{
					if (arr[x][y - 1] == 0)
					{
						arr[x][y - 1] = arr[x][y];
						arr[x][y] = 0;
						break;
					}
					else if (arr[x][y - 1] == arr[x][y] && arr[x][y - 1] != 2048)
					{
						*score += arr[x][y - 1];
						arr[x][y - 1] *= 2;
						arr[x][y] = 0;
						if (arr[x][y - 1] > *max)
						{
							*max = arr[x][y - 1];
						}
						break;
					}
					else
					{
						break;
					}
				}
			}
		}
	}
}

之后是每移动一次后会随机产生一个随机值,显示在任意位置。而在产生随机值需要寻找当前二维数组中的最小数,来确保产生的随机值不能小于最小数。由于知识储备少,没有想到好的方法,便采用了先将二维数组转换为一维数组,再对一维数组进行冒泡排序的方法找到最小值。完整代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 
#include 
#include 
#include 
#define length 80
#define space 15
#define amount 2

void Randnum(int arr[4][4])//初始随机值
{
	int count = amount;
	int x = 0;
	int y = 0;
	int z = 0;
	for (y = 0; y < 4; y++)
	{
		for (x = 0; x < 4; x++)
		{
			arr[x][y] = 0;
		}
	}
	while (count)
	{
	    x = rand() % 4;
		y = rand() % 4;
		z = rand() % 5;
		if (z == 0)
		{
			if (arr[x][y] == 0)
			{
				arr[x][y] = 4;
				count--;
			}
		}
		else
		{
			if (arr[x][y] == 0)
			{
				arr[x][y] = 2;
				count--;
			}
		}
	}
}
void Map(int arr[4][4])//图形输出
{
	char tmp[5];
	int y = 0, x = 0;
	for (y = 0; y < 4; y++)
	{
		for (x = 0; x < 4; x++)
		{
			if (arr[x][y] != 0)
			{
				sprintf(tmp, "%d", arr[x][y]);
			}
			else
			{
				sprintf(tmp, "%c", ' ');
			}
			int width = textwidth(tmp);
			int height = textheight(tmp);
			setfillcolor(RGB(74, 154, 214));
			settextcolor(WHITE);
			settextstyle(40, 15, "微软雅黑");
			setbkmode(TRANSPARENT);
			solidroundrect(space * (x + 1) + length * x, space * (y + 1) + length * y, space * (x + 1) + length * x + length, space * (y + 1) + length * y + length, 20, 20);
			outtextxy(space * (x + 1) + length * x + (length - width) / 2, space * (y + 1) + length * y + (length - height) / 2, tmp);
		}
	}
}
void Up(int arr[4][4], int* max, int* score);
void Down(int arr[4][4], int* max, int* score);
void Left(int arr[4][4], int* max, int* score);
void Right(int arr[4][4], int* max, int* score);
void AddRandnum(int arr[4][4], int* max);

void Keyget(int arr[4][4], int* max, int* score)//截取键盘值
{
	int key = _getch();
	switch (key)//w s a d
	{
	case 87:Up(arr, max, score);//max此时就是地址,没必要再对max取地址传参
		break;
	case 83:Down(arr, max, score);
		break;
	case 65:Left(arr, max, score);
		break;
	case 68:Right(arr, max, score);
		break;
	}
}
void Up(int arr[4][4], int* max, int* score)//向上移动函数
{
	int tmp = 3;
	int x = 0, y = 0;
	while (tmp--)//按下W,遍历整个数组,使每列每行的元素根据前列的值向上移动或停止一行,重复3次
	{
		for (x = 0; x < 4; x++)
		{
			for (y = 1; y < 4; y++)
			{
				while (1)
				{
					if (arr[x][y - 1] == 0)
					{
						arr[x][y - 1] = arr[x][y];
						arr[x][y] = 0;
						break;
					}
					else if (arr[x][y - 1] == arr[x][y] && arr[x][y - 1] != 2048)
					{
						*score += arr[x][y - 1];
						arr[x][y - 1] *= 2;
						arr[x][y] = 0;
						if (arr[x][y - 1] > *max)
						{
							*max = arr[x][y - 1];
						}
						break;
					}
					else
					{
						break;
					}
				}
			}
		}
	}
}
void Down(int arr[4][4], int* max, int* score)
{
	int tmp = 3;
	int x = 0, y = 0;
	while (tmp--)//按下W,遍历整个数组,使每列每行的元素根据前列的值向下移动或停止一行,重复3次
	{
		for (x = 0; x < 4; x++)
		{
			for (y = 0; y < 3; y++)
			{
				while (1)
				{
					if (arr[x][y + 1] == 0)
					{
						arr[x][y + 1] = arr[x][y];
						arr[x][y] = 0;
						break;
					}
					else if (arr[x][y + 1] == arr[x][y] && arr[x][y + 1] != 2048)
					{
						*score += arr[x][y + 1];
						arr[x][y + 1] *= 2;
						arr[x][y] = 0;
						if (arr[x][y + 1] > *max)
						{
							*max = arr[x][y + 1];
						}
						break;
					}
					else
					{
						break;
					}
				}
			}
		}
	}
}
void Left(int arr[4][4], int* max, int* score)
{
	int tmp = 3;
	int x = 0, y = 0;
	while (tmp--)//按下W,遍历整个数组,使每列每行的元素根据前列的值向左移动或停止一行,重复3次
	{
		for (y = 0; y < 4; y++)
		{
			for (x = 1; x < 4; x++)
			{
				while (1)
				{
					if (arr[x - 1][y] == 0)
					{
						arr[x - 1][y] = arr[x][y];
						arr[x][y] = 0;
						break;
					}
					else if (arr[x - 1][y] == arr[x][y] && arr[x - 1][y] != 2048)
					{
						*score += arr[x - 1][y];
						arr[x - 1][y] *= 2;
						arr[x][y] = 0;
						if (arr[x - 1][y] > *max)
						{
							*max = arr[x - 1][y];
						}
						break;
					}
					else
					{
						break;
					}
				}
			}
		}
	}
}
void Right(int arr[4][4], int* max, int* score)
{
	int tmp = 3;
	int x = 0, y = 0;
	while (tmp--)//按下W,遍历整个数组,使每列每行的元素根据前列的值向右移动或停止一行,重复3次
	{
		for (y = 0; y < 4; y++)
		{
			for (x = 0; x < 3; x++)
			{
				while (1)
				{
					if (arr[x + 1][y] == 0)
					{
						arr[x + 1][y] = arr[x][y];
						arr[x][y] = 0;
						break;
					}
					else if (arr[x + 1][y] == arr[x][y] && arr[x + 1][y] != 2048)
					{
						*score += arr[x + 1][y];
						arr[x + 1][y] *= 2;
						arr[x][y] = 0;
						if (arr[x + 1][y] > *max)
						{
							*max = arr[x + 1][y];
						}
						break;
					}
					else
					{
						break;
					}
				}
			}
		}
	}
}
void AddRandnum(int arr[4][4], int* max, int* min)//每 *** 作一次随机生成一个值,五分之一是当前最大值的一半,五分之一是最大值,五分之三最小值
{
	int x = 0;
	int y = 0;
	int z = 0;
	while (1)
	{
		x = rand() % 4;
		y = rand() % 4;
		z = rand() % 4;
		if (z == 0)
		{
			if (arr[x][y] == 0)
			{
				arr[x][y] = ((*max) / 2);
				break;
			}
		}
		else if (z == 2)
		{
			if (arr[x][y] == 0)
			{
				arr[x][y] = *max;
				break;
			}
		}
		else
		{
			if (arr[x][y] == 0)
			{
				arr[x][y] = *min;
				break;
			}
		}
	}
}
void Scoreboard(int* score, int* max)//计分板函数
{
	char str[] = "SCORE :";
	char str1[] = "Max:";
	char num[5] = { 0 };
	char maxc[5] = { 0 };
	setfillcolor(RGB(232, 225, 206));
	solidroundrect(395, 15, 580, 380, 20, 20);
	settextcolor(RGB(250, 210, 20));
	settextstyle(40, 20, "微软雅黑");
	setbkmode(TRANSPARENT);
	outtextxy(410, 50, str);
	setfillcolor(RGB(172, 247, 253));
	solidroundrect(410, 140, 565, 365, 20, 20);
	sprintf(num, "%d", *score);
	sprintf(maxc, "%d", *max);
	settextcolor(WHITE);
	settextstyle(40, 20, "微软雅黑");
	outtextxy(440, 150, num);
	outtextxy(440, 310, maxc);
	outtextxy(440, 250, str1);
}
int Minfind(int arr[4][4])//寻找最小数
{
	int str[16];
	int tmp = 0;
	int x = 0, y = 0, i = 0;
	for (x = 0; x < 4; x++)
	{
		for (y = 0; y < 4; y++)
		{
			str[i] = arr[x][y];
			i++;
		}
	}
	for (x = 15; x > 0; x--)
	{
		for (y = 0; y < x; y++)
		{
			if (str[y] > str[y + 1])
			{
				tmp = str[y];
				str[y] = str[y + 1];
				str[y + 1] = tmp;
			}
		}
	}
	for (x = 0; x < 16; x++)
	{
		if (str[x] != 0)
		{
			return str[x];
		}
	}
}
int main()
{
	srand((unsigned int)time(NULL));
	int min = 2;
	int max = 4;
	int count = 0;
	int score = 0;
	int arr[4][4];
	Randnum(arr);
	ExMessage msg;
	initgraph(length * 4 + space * 5 + 200, length * 4 + space * 5);
	while (1)
	{
		BeginBatchDraw();
		setbkcolor(RGB(215, 255, 240));
		cleardevice();
		Scoreboard(&score, &max);
		Map(arr);
		EndBatchDraw();
		Keyget(arr, &max, &score);
		min = Minfind(arr);
		AddRandnum(arr, &max, &min);
		printf("%d ", min);
	}
	getchar();
	return 0;
}

存在的BUG:棋盘方块中偶尔出现数字不居中的问题,暂时还不知道如何解决

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/756710.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-30
下一篇 2022-04-30

发表评论

登录后才能评论

评论列表(0条)

保存