学习记录,使用图形库编程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:棋盘方块中偶尔出现数字不居中的问题,暂时还不知道如何解决
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)