#include
#include
#include
#include
//打印函数,打印出游戏界面
//如果是0的话就为空,否则打印出数值
void print(int a[4][4], int count)
{
for (int i = 0; i < 4; i++)
{
printf(" --- "); //打印的是第一行的横线
}
printf("\n");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (j == 0)
{
printf("|"); //打印的是第一列的竖线
}
if (a[i][j] == 0)
{
printf(" |"); //如果每一个a[i][j]里面是0则打印出竖线
}
else
{
printf("%3d |", a[i][j]); //如果每一个a[i][j]里面b不是0则打印出竖线
}
}
printf("\n");
for (int h = 0; h < 4; h++)
{
printf(" --- ");//打印出剩下行的横线
}
printf("\n");
}
printf("请使用wsad进行游戏\n");
printf("当前得分为:%d\n", count);
}
//为一开始生成随机的两个坐标
void start(int a[4][4])
{
srand((unsigned)time(NULL));//用时间作为随机数的种子
int x, y;
x = rand() % 4;
y = rand() % 4;
a[x][y] = 2; //一开始随机的数为2
x = rand() % 4;
y = rand() % 4;
while (a[x][y] == 2)
{
x = rand() % 4;
y = rand() % 4;
}
a[x][y] = 2;
return;
}
//每一回合过后都随机生成一个新的2
void fresh(int a[4][4])
{
srand((unsigned)time(NULL));
int x, y;
x = rand() % 4;
y = rand() % 4;
while (a[x][y] != 0)
{
x = rand() % 4;
y = rand() % 4;
}
a[x][y] = 2;
return;
}
//判断是否游戏结束
//游戏结束的标志就是无论从那个方向都没有可以合成的格子了
//算法就是先从行判断,然后从列判断
//如果游戏结束了就返回0,否则返回1
int is_die(int a[4][4])
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
if (a[i][j] == a[i][j + 1])
{
//如果有相等的就是可以合成,游戏还没有结束
return 1;
}
if (a[j][i] == a[j + 1][i])
{
return 1;
}
}
}
//走到这一步就说明游戏结束了
return 0;
}
int can(int a[4][4])
{
return 1;
}
//主函数,通过输入来进行移动
//进行操作的时候分四种情况
//算法为:先检查有没有可以合并的格子,如果有就合并,然后再紧凑
void run(int a[4][4])
{
char b;
scanf_s("%c", &b, 1);
char c = getchar();
switch (b) {
case 'w':
//上一操作
for (int j = 0; j < 4; j++)
{
//j代表列
for (int i = 3; i > 0; i--)
{
if (a[i][j] != 0)
{
//如果这个格子不等于零就检测能否合并
for (int h = i - 1; h >= 0; h--)
{
if (a[h][j] != 0)
{
if (a[h][j] == a[i][j])
{
//相等的话就合并,然后并到hj的格子里
a[h][j] *= 2;
a[i][j] = 0;
//之后要忽略掉已经合并的格子
i = h; //这里要特别注意一下,不知道是不是到了外层循环结束了之后自动给他减一
break;
}
else
{
break;
}
}
}
}
}
}
//这里要进行紧凑操作,逐行扫描
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 3; k++)
{
//找到一个为0的格子之后把不为0的最近的格子值赋值上来,然后被赋值的格子变0
//一直检查完为止,最后一行是不用检查的,因为最后一行为0也没有格子可以上移
if (a[k][j] == 0)
{
//找最近的不为0的格子
for (int l = k + 1; l < 4; l++)
{
if (a[l][j] != 0)
{
a[k][j] = a[l][j];
a[l][j] = 0;
break;
}
}
}
}
}
break;
case 's':
//下移操作,与上移操作行检查顺序相反,其他都一样
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 3; i++)
{
if (a[i][j] != 0)
{
for (int h = i + 1; h <= 3; h++)
{
if (a[h][j] != 0)
{
if (a[h][j] == a[i][j])
{
//可以合并
a[h][j] *= 2;
a[i][j] = 0;
i = h;
break;
}
else {
break;
}
}
}
}
}
}
//进行紧凑处理
for (int j = 0; j < 4; j++)
{
for (int i = 3; i > 0; i--)
{
if (a[i][j] == 0)
{
for (int k = i - 1; k >= 0; k--)
{
if (a[k][j] != 0)
{
a[i][j] = a[k][j];
a[k][j] = 0;
break;
}
}
}
}
}
break;
case 'a':
//左移操作
for (int i = 0; i < 4; i++)
{
for (int j = 3; j > 0; j--)
{
if (a[i][j] != 0)
{
for (int k = j - 1; k >= 0; k--)
{
if (a[i][k] != 0)
{
//要找第一个不等于0的格子
if (a[i][k] == a[i][j])
{
a[i][k] *= 2;
a[i][j] = 0;
j = k;
break;
}
else
{
break;
}
}
}
}
}
}
//进行紧凑处理
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
if (a[i][j] == 0)
{
for (int k = j + 1; k < 4; k++)
{
if (a[i][k] != 0)
{
a[i][j] = a[i][k];
a[i][k] = 0;
break;
}
}
}
}
}
break;
case 'd':
//右移操作
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
if (a[i][j] != 0)
{
for (int k = j + 1; k < 4; k++)
{
if (a[i][k] != 0)
{
if (a[i][k] == a[i][j])
{
a[i][k] *= 2;
a[i][j] = 0;
j = k;
break;
}
else
{
break;
}
}
}
}
}
}
//进行紧凑处理
for (int i = 0; i < 4; i++)
{
for (int j = 3; j > 0; j--)
{
if (a[i][j] == 0)
{
for (int k = j - 1; k >= 0; k--)
{
if (a[i][k] != 0)
{
a[i][j] = a[i][k];
a[i][k] = 0;
break;
}
}
}
}
}
default:
break;
}
}
int main(int *argc,char *argv[])
{
int a[4][4] = { 0 };
int count = 0;//记录游戏分数
start(a);
print(a, count);
run(a);
count++;
system("cls");
fresh(a);
print(a, count);
Sleep(50);
while (1) {
if (is_die(a) == 1)
{
//游戏还可以继续进行
run(a);
fresh(a);
system("cls");
count++;
print(a, count);
Sleep(5);
}
else
{
system("cls");
printf("游戏结束,最终得分为:%d\n", count);
}
}
return 0;
}