C语言-请实现一个控制台的2048小游戏

 

#include<stdio.h>

 

#include<stdlib.h>

 

#include<time.h>

 

#include<windows.h>

 

//打印函数,打印出游戏界面

 

//如果是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;

 

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值