C语言实现2048小游戏

    xiaoxiao2025-10-20  9

     

    本文实例为大家分享了C语言实现2048游戏的具体代码,供大家参考,具体内容如下

     

    #include <stdio.h>

    #include <stdlib.h>

    #include <conio.h> /*使用getch()函数*/

    #include <time.h>

    #include <windows.h> /*使用Sleep()函数*/

     

    void Menu();//菜单

    void Rule_of_game();//游戏规则

    void Begin(int max); //开始

    void Table();//打印4×4方格

    int Random_number1();//产生2或4的随机数

    int Random_number2();//产生0、1、2、3的随机数

    int Get(int *p_cnt, int score);//输入指令

    void Move();//保留上一次的棋盘布局

    int If_move();//判断是否移动

    int Over();//判断是否结束

    void Establish_game();//创建用于保存最高分的文件

    void Write_max(int score);//向2048游戏-最高记录写入最高分

    int Read_max();//读出最高分记录的文件

    void Establish_file();//创建存档文件

    void Write_file(int *p_cnt, int scort);//存档

    int Read_file(int *p_cnt);//读档

    void again();//是否继续游戏

    int color(int c);//更改颜色

    void box_color(int x);//不同数值对应不同颜色

     

    int a[4][4] = {0};// 定义全局的二维数组

    int A[4][4]; //保留上一步的棋局

    char *name_max = "2048游戏-最高记录";

    char *name_file = "[空白]-2048游戏";

     

    int main() {

     system("mode con cols=90 lines=30");

     system("title 2048超级大大型游戏"); //程序标题

     system("color F0");//F 表示背景颜色,0表示前景颜色

     Menu();

     system("pause"); //暂停,输入任意键继续

     system("cls"); //清屏

     again(); //是否继续游戏

     return 0;

    }

     

    void Menu() //菜单

    {

     printf("\t\t╔══════════════════════════════════════════════╗\n");

     printf("\t\t║ 欢迎使用由[空白]制作的2048超级大大型游戏 ║\n");

     printf("\t\t╟──────────────────────────────────────────────╢\n");

     printf("\t\t║请输入选项:  ║\n");

     printf("\t\t║ ┌───┐ ║\n");

     printf("\t\t║ │ 1 │ 游戏规则 ║\n");

     printf("\t\t║ └───┘ ║\n");

     printf("\t\t║ ┌───┐ ║\n");

     printf("\t\t║ │ 2 │ 开始游戏 ║\n");

     printf("\t\t║ └───┘ ║\n");

     printf("\t\t║ ┌───┐ ║\n");

     printf("\t\t║ │ 3 │ 继续游戏 ║\n");

     printf("\t\t║ └───┘ ║\n");

     printf("\t\t║║\n");

     printf("\t\t║ │ 4 │ 退出游戏 ║\n");

     printf("\t\t║ ║\n");

     printf("\t\t\n");

     int x = 1, max = 0;

     while(x){

     switch(getch()){

     case '1':

     x = 0;

     Rule_of_game();//游戏规则

     Menu();

     break;

     case '2':

     x = 0;

     system("cls");//清屏

     Establish_game(name_file);//创建新的读档文件

     Establish_game(name_max);//创建新的保存最高记录的文件

     Begin(max); //开始游戏

     break;

     case '3':

     x = 0;

     system("cls");//清屏

     max = Read_max();//读取之前的最高记录

     Begin(max); //开始游戏

     break;

     case '4':

     exit(0);

     default:

     printf("输入了非法选项,请重新选择!\n");

     }

     }

    }

     

    void Rule_of_game()

    {

     system("cls");//清屏

     printf("╔══════════════════════════════════════════════════════════════════════════════════╗\n");

     printf("║本游戏通过按键W、S、A、D(不区分大小写)四个键分别控制滑块上移、下移、左移和右移。║\n");

     printf("║滑块移动的过程中,如有相邻且相等数字的滑块将会相加,并获得相应的分数。 ║\n");

     printf("║当棋盘上的所有位置均有数字,且不能合成,则游戏结束。本游戏未设置游戏成功。 ║\n");

     printf("║游戏过程中输入I即为存档并退出游戏,输入O即为读档,输入P则退出游戏。 ║\n");

     printf("║“开始游戏”则清除最高记录及存档、“继续游戏”则保存之前的最高记录,且可以读档。 ║\n");

     printf("╚══════════════════════════════════════════════════════════════════════════════════╝\n");

     system("pause");//暂停

     system("cls");//清屏

    }

     

    void Begin(int max)

    {

     int score = 0;

     int sign = 1;

     int h, l, cnt = 0;

     int *p_cnt = &cnt;

     while(1) {

     printf("\t\t╔══════════════════════════════════════════════╗\n");

     printf("\t\t║ 欢迎使用由[空白]制作的2048超级大大型游戏 ║\n");

     printf("\t\t╟──────────────────────────────────────────────╢\n");

     printf("\t\t║移动: ┌───┐ 存档: 读档: 退出: ║\n");

     printf("\t\t║ │ W │ ║\n");

     printf("\t\t║ ┌───┼───┼───┐ ┌───┐ ┌───┐ ┌───┐ ║\n");

     printf("\t\t║ │ A │ S │ D │ │ I │ │ O │ │ P │ ║\n");

     printf("\t\t║ └───┴───┴───┘ └───┘ └───┘ └───┘ ║\n");

     printf("\t\t╚══════════════════════════════════════════════╝\n");

     while(1){

     if(sign == 1){

     h = Random_number2();

     l = Random_number2();

     if(a[h][l] == 0){

      a[h][l] = Random_number1();

      cnt ++;

      break;

     }

     }

     else{

     break;

     }

     

     }

     Table();//打印棋盘

     printf("\t\t移动的步数:%d\t当前得分:%d\n\t\t最高记录:%d\n", cnt-1, score, max);

     Move();//保留棋盘

     score += Get(p_cnt, score);//得分

     sign = If_move();//判断棋盘是否有变动

     if(Over() == 0){

     if(max < score){//打破记录

     Establish_game(name_max);//清除之前的记录

     Write_max(score);//保存此次记录

     printf("\t\t恭喜您已打破记录!\n");

     }

     break;

     }

     system("cls"); //清屏

     }

    }

     

    void Table()

    {

     int h, l;

     for(h = 0; h < 4; h ++){

     if(h == 0){

     printf("\t\t\t┏━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━┓\n");

     }

     else {

     printf("\t\t\t┣━━━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫\n");

     }

     printf("\t\t\t┃ ┃ ┃ ┃ ┃\n");

     for(l = 0; l < 4; l ++){

     if(a[h][l] == 0){//如果二维数组与棋盘对应的位置为零,则不放入数据

     if(l == 0){

      printf("\t\t\t┃ ");

     }

     else {

      printf("┃ ");

     }

     }

     else{//否则放入与二维数组对应的数据

     if(l == 0){

      printf("\t\t\t┃");

      box_color(a[h][l]);//判断滑块的数值,给对应颜色

      printf("] ", a[h][l]);

      color(0);//恢复白色背景

     }

     else {

      printf("┃");

      box_color(a[h][l]);//判断滑块的数值,给对应颜色

      printf("] ", a[h][l]);

      color(0);//恢复白色背景

     }

     }

     }

     printf("┃\n");

     printf("\t\t\t┃ ┃ ┃ ┃ ┃\n");

     }

     printf("\t\t\t┗━━━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛\n");

    }

     

    int Random_number1()/*随机生成2 or 4*/

    {

     int s;

     srand( time(NULL) );

     s = ((unsigned)rand() % 2);

     s = s == 0 ? 2 : 4;

     return s;

    }

     

    int Random_number2()/*随机生成二维数组的下标*/

    {

     int x;

     x = ((unsigned)rand() % 4);

     return x;

    }

     

    int Get(int *p_cnt, int score)

    {

     int h, l, t, sum = 0;

     char ch;

     ch = getch();//输入字符

     switch (ch){

     /*滑块向上移动*/

     case 'w':

     case 'W':

     /*向上聚集数字*/

     for(l = 0; l < 4; l ++){

     for(t = 0; t < 4; t ++){

      for(h = 3; h > 0; h --){

      if(a[h-1][l] == 0){

      a[h-1][l] = a[h][l];

      a[h][l] = 0;

      }

      }

     }

     }

     /*竖直方向上,相邻且相同的数字相加*/

     for(l = 0; l < 4; l ++){

     for(h = 0; h < 3; h ++){

      if(a[h][l] == a[h+1][l]){

      a[h][l] += a[h+1][l];

      a[h+1][l] = 0;

      sum += a[h][l];

      }

     }

     }

     /*向上聚集数字*/

     for(l = 0; l < 4; l ++){

     for(t = 0; t < 4; t ++){

      for(h = 3; h > 0; h --){

      if(a[h-1][l] == 0){

      a[h-1][l] = a[h][l];

      a[h][l] = 0;

      }

      }

     }

     }

     break;

     case 's':

     case 'S':

     for(l = 0; l < 4; l ++){

     for(t = 0; t < 4; t ++){

      for(h = 0; h < 3; h ++){

      if(a[h+1][l] == 0){

      a[h+1][l] = a[h][l];

      a[h][l] = 0;

      }

      }

     }

     }

     for(l = 0; l < 4; l ++){

     for(h = 3; h > 0; h --){

      if(a[h][l] == a[h-1][l]){

      a[h][l] += a[h-1][l];

      a[h-1][l] = 0;

      sum += a[h][l];

      }

     }

     }

     for(l = 0; l < 4; l ++){

     for(t = 0; t < 4; t ++){

      for(h = 0; h < 3; h ++){

      if(a[h+1][l] == 0){

      a[h+1][l] = a[h][l];

      a[h][l] = 0;

      }

      }

     }

     }

     break;

     case 'a':

     case 'A':

     for(h = 0; h < 4; h ++){

     for(t = 0; t < 4; t ++){

      for(l = 3; l > 0; l --){

      if(a[h][l-1] == 0){

      a[h][l-1] = a[h][l];

      a[h][l] = 0;

      }

      }

     }

     }

     for(h = 0; h < 4; h ++){

     for(l = 0; l < 3; l ++){

      if(a[h][l] == a[h][l+1]){

      a[h][l] += a[h][l+1];

      a[h][l+1] = 0;

      sum += a[h][l];

      }

     }

     }

     for(h = 0; h < 4; h ++){

     for(t = 0; t < 4; t ++){

      for(l = 3; l > 0; l --){

      if(a[h][l-1] == 0){

      a[h][l-1] = a[h][l];

      a[h][l] = 0;

      }

      }

     }

     }

     break;

     case 'd':

     case 'D':

     for(h = 0; h < 4; h ++){

     for(t = 0; t < 4; t ++){

      for(l = 0; l < 3; l ++){

      if(a[h][l+1] == 0){

      a[h][l+1] = a[h][l];

      a[h][l] = 0;

      }

      }

     }

     }

     for(h = 0; h < 4; h ++){

     for(l = 3; l > 0; l --){

      if(a[h][l] == a[h][l-1]){

      a[h][l] += a[h][l-1];

      a[h][l-1] = 0;

      sum += a[h][l];

      }

     }

     }

     for(h = 0; h < 4; h ++){

     for(t = 0; t < 4; t ++){

      for(l = 0; l < 3; l ++){

      if(a[h][l+1] == 0){

      a[h][l+1] = a[h][l];

      a[h][l] = 0;

      }

      }

     }

     }

     break;

     case 'i':

     case 'I': //存档当前游戏格局

     Establish_file();//创建用于存档的文件

     Write_file(p_cnt, score);//调用存档函数

     break;

     case 'o':

     case 'O':

     sum = Read_file(p_cnt);//读档

     break;

     case 'p':

     case 'P':

     exit(0);//退出程序

     default:

     break;

     }

     

     return sum;

    }

     

    void Move()

    {

     int h, l;

     for(h = 0; h < 4; h ++){

     for(l = 0; l < 4; l ++){

     A[h][l] = a[h][l];

     }

     }

    }

     

    int If_move()

    {

     int h, l, sign = 0;

     for(h = 0; h < 4; h ++){

     for(l = 0; l < 4; l ++){

     if(a[h][l] != A[h][l]){//未进入条件框,说明滑块没有发生移动

     sign = 1;

     goto out;

     }

     }

     }

     out:

     return sign;

    }

     

    int Over()

    {

     int over = 0;

     int h, l;

     for(h = 0; h < 4; h ++){

     for(l = 0; l < 4; l ++){

     if(a[h][l] == 0){//有空格

     over = 1;//游戏继续

     return 1;

     }

     }

     }

     if(over == 0){//没有空格

     for(h = 0; h < 3; h ++){

     for(l = 0; l < 3; l ++){

     if(a[h][l] == a[h][l+1]){

      over = 1;//游戏继续

      break;

     }

     else if(a[h][l] == a[h+1][l]){

      over = 1;//游戏继续

      break;

     }

     }

     if(over == 1){

     break;

     }

     }

     }

     return over;//游戏结束

    }

     

    void Establish_game()//创建文件

    {

     int h;

     if(h = fopen(name_max, "wb") == NULL){ //函数fopen()返回NULL则创建文件失败

     printf("\t\t创建文件失败!程序即将自动退出 . . .\n");

     Sleep(3000);//睡眠3000毫秒,即停留3秒钟

     exit(0); //退出程序

     }

    }

     

    void Write_max(int score)//写入文件

    {

     /*FILE *fp是指向文件的指针*/

     FILE *fp=fopen(name_max,"at+");// at+读写打开或着建立一个文本文件;允许读写。

     if(fp==NULL) //函数fopen()返回NULL则创建文件失败

     {

     printf("\t\t保存最高分失败!程序即将自动退出 . . .");

     Sleep(3000);//睡眠3000毫秒,即停留3秒钟

     exit(0); //退出程序

     }

     else{

     fprintf(fp, "%d", score);//将score的值写入*pf指向的文件内

     }

     fclose(fp);//关闭*pf指向的文件

    }

     

    int Read_max()//读出文件

    {

     int max_score = 0;

     FILE *fp=fopen(name_max,"at+");// at+读写打开或着建立一个文本文件;允许读写。

     if(fp==NULL)

     {

     printf("\t\t读取失败!程序即将自动退出 . . .");

     Sleep(3000);//睡眠3000毫秒,即停留3秒钟

     exit(0); //退出程序

     }

     else{

     fscanf(fp, "%d", &max_score);//从*pf指向的文件内数值赋值给max_score

     }

     fclose(fp);//关闭*pf指向的文件

     

     return max_score;//返回最高记录的值

    }

     

    void Establish_file()//创建文件

    {

     int h;

     if(h = fopen(name_file, "wb") == NULL){ //函数fopen()返回NULL则创建文件失败

     printf("\t\t创建文件失败!程序即将自动退出 . . .\n");

     Sleep(3000);//睡眠3000毫秒,即停留3秒钟

     exit(0); //退出程序

     }

    }

     

    void Write_file(int *p_cnt, int score)

    {

     int h, l;

     FILE *fp=fopen(name_file,"at+");// at+读写打开或着建立一个文本文件;允许读写。

     if(fp==NULL)

     {

     printf("\t\t存档失败!程序即将自动退出 . . .\n");

     Sleep(3000);//睡眠3000毫秒,即停留3秒钟

     exit(0);

     }

     else{

     for(h = 0; h < 4; h ++){

     for(l = 0; l < 4; l ++){

     fprintf(fp, "%d ", a[h][l]);

     }

     }

     }

     fprintf(fp, "%d ", score);

     fprintf(fp, "%d ", *p_cnt-1);

     printf("\t\t存档成功!游戏即将自动退出 . . .\n");

     Sleep(3000); //睡眠3000毫秒,即停留3秒钟

     exit(0);

     fclose(fp);//关闭文件

    }

     

    int Read_file(int *p_cnt)

    {

     int h, l, score = 0;

     FILE *fp=fopen(name_file,"at+");// at+读写打开或着建立一个文本文件;允许读写。

     if(fp==NULL)

     {

     printf("\t\t读档失败!程序即将自动退出 . . .\n");

     Sleep(3000); //睡眠3000毫秒,即停留3秒钟

     exit(0);

     }

     else{

     for(h = 0; h < 4; h ++){

     for(l = 0; l < 4; l ++){

     fscanf(fp, "%d ", &a[h][l]);

     }

     }

     }

     fscanf(fp, "%d ", &score);

     fscanf(fp, "%d ", p_cnt);

     fclose(fp); //关闭文件

     

     return score;

    }

     

    void again()//是否继续游戏

    {

     printf("\t\t╔══════════════════════════════════════════════╗\n");

     printf("\t\t║ 您已失败 ║\n");

     printf("\t\t╟──────────────────────────────────────────────╢\n");

     printf("\t\t║是否继续:  ║\n");

     printf("\t\t║ ┌───┐ ║\n");

     printf("\t\t║ │ 1 │ 扶我起来,我还能再来一局! ║\n");

     printf("\t\t║ └───┘ ║\n");

     printf("\t\t║ ┌───┐ ║\n");

     printf("\t\t║ │ 2 │ 不了不了,我要学习! ║\n");

     printf("\t\t║ └───┘ ║\n");

     printf("\t\t╚══════════════════════════════════════════════╝\n");

     if(_getch() == '1'){

     system("cls");//清屏

     int h, l;

     for(h = 0; h < 4; h ++){

     for(l = 0; l < 4; l ++){

     a[h][l] = 0;

     A[h][l] = 0;

     }

     }

     Menu();//回到菜单

     }

     else {

     printf("\t\t游戏结束!\n");

     }

    }

     

    int color(int c)

    {

     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),

      BACKGROUND_INTENSITY |

      BACKGROUND_BLUE |

      BACKGROUND_RED |

      BACKGROUND_GREEN |

      c);

     return 0;

    }

     

    void box_color(int x)

    {

     switch(x){

     case 2:

     color(8);

     break;

     case 4:

     color(0);

     break;

     case 8:

     color(2);

     break;

     case 16:

     color(6);

     break;

     case 32:

     color(10);

     break;

     case 64:

     color(3);

     break;

     case 128:

     color(9);

     break;

     case 256:

     color(11);

     break;

     case 512:

     color(5);

     break;

     case 1024:

     color(13);

     break;

     case 2048:

     color(12);

     break;

     default :

     color(4);

     break;

     }

    }

    喜欢此篇文章或觉得这篇文章对你有帮助的读者可以分享给身边的朋友们。如果你是小白也可以回复“资料”领取大礼包一份,以及开发工具一份。

    最新回复(0)