求助:2048小游戏

ij131214 2026-04-21 20:52:13

任务描述
本关任务:编写一个 2048 小游戏。
相关知识
为了完成本关任务,你需要掌握:C 语言基础。
游戏规则
首先我们来描述一下 2048 游戏的规则;
1.游戏开始的时候,在一个 5*5 的二维空间,随机产生 2;
2.可以选择上下左右的滑动,如果遇到相同的数字,该数字乘 2;
3.滑动结束后,检测是否有剩余的空间,如果有,则在该位置随机生成 2;
4.然后继续步骤 2.
5.如果检测到有数字 2048,游戏胜利,则游戏结束;无法继续滑动,游戏失败,游戏结束。
基于以上规则,我们设计游戏结构:
生成二维 5*5 的空间,以数组 map[5][5] 描述,随机种子数 rand();
滑动的函数 move();由于四个方向的移动代码类似,可以专门写一个移动的类实现;
检测是否可以移动的函数,gameover();
在终端显示的类 display;
对于初学者,我们可以先写出一维空间的“2048”;
核心功能
1. 游戏失败
主要思想:如果数组当中还有 0,说明还能移动,返回 0,说明游戏还没结束呢。25 个格子全部有数字,都不为 0,接下来判断5行,5 列。每相邻两个数字,是否有相同的,如果有,说明通过移动还可以动,return 1 说明 25 个格子全部都有数字,都不为 0,而且各个方向无论怎么移动都不能合并,那么游戏结束  game over。
代码:
1. #define SIZE    25
2. #define width    5
3. int is_dead()
4. {
5.     int i, j;
6.     for(i = 0; i < SIZE; i++)
7.     {
8.         if(!arr[i])
9.         {
10.             return 0;
11.         }
12.     }
13.     for(i = 0; i < SIZE; i += width)
14.     {
15.         for(j = i; j < i + width-1; j++)
16.         {
17.             if(arr[j] == arr[j + 1])
18.             {
19.                 return 0;
20.             }
21.         }
22.     }
23.     for(i = 0; i < width; i++)
24.     {
25.         for(j = i; j < i + width*(width-1); j += width)
26.         {
27.             if(arr[j] == arr[j + width])
28.             {
29.                 return 0;
30.             }
31.         }
32.     }
33.     return 1;
34. }
功能实现
1. 生成新数字
主要思想:在移动或者合并的循环中,根据生成的随机数,对 SIZE 进行取模,达到生成一定概率的数,此程序生成数为 2.
2. 判断游戏是否过关
主要思想:遍历二维数组,找出数组中的最大值,如果最大值等于 2048 ,表示游戏过关。
3. 合并计算得分
主要思想:判断相邻两个数字是否相等,如果相等将当前数字乘以 2,并且消除。
4. 完成向上移动代码函数
5. 完成向下移动代码函数
6. 完成向左移动代码函数
7. 完成向右移动代码函数
编程要求
根据提示,在右侧编辑器 /** Begin **/  到  /** End **/  处补充代码。
测试说明
代码测评成功后:
启动平台游戏代码:
进入终端,进入 
cd /data/workspace/myshixun/step2/ 

输入以下命令:将当前地址设为 c++ 寻址动态链接库的地址 
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./ 

将 student.cpp 编译成动态链接库。 
g++ student.cpp -fPIC -shared -o libstudent.so 

将 main.cpp 编译并连接动态链接库。 
g++ main.cpp -L. -lstudent -o main 

完成后输入: 
./main game 
后开始游戏;


平台会对你编写的代码进行测试:
预期输出:
1. 按【I】向上移动
2. 按【K】向下移动
3. 按【J】向左移动
4. 按【L】向右移动
5. 按【Ctrl + Z】退出游戏
6. 最大的数是:4
7. 总分是:12
8. 
9. +------------------  2048  ------------------+
10. +--------------------------------------------+
11. |        |        |        |        |        |
12. |        |       2|        |       4|       4|
13. |--------+--------+--------+--------+--------|
14. |        |        |        |        |        |
15. |        |        |        |        |       4|
16. |--------+--------+--------+--------+--------|
17. |        |        |        |        |        |
18. |        |        |        |        |        |
19. |--------+--------+--------+--------+--------|
20. |        |        |        |        |        |
21. |        |        |       2|        |        |
22. |--------+--------+--------+--------+--------|
23. |        |        |        |        |        |
24. |        |        |        |        |        |
25. +--------------------------------------------+
 

 

 

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <termios.h>

#include <string>

#include "2048.h"

 

//16

#define SIZE    25

#define width   5

#define height  5

#define UP      0x69

#define UP_B    0x49

#define DOWN    0x6b

#define DOWN_B  0x4b

#define RIGHT   0x6c

#define RIGHT_B 0x4c

#define LEFT    0x6a

#define LEFT_B  0x4a

 

int arr[SIZE] = {0};    //用来表示2048矩阵的一维数组,元素为0表示该位置为空

int is_move = 0;    //移动标志,如果发生了移动,置为1,产生随机数后归0

int is_merge = 0;   //合并标志,如果发生了合并,置为1,产生随机数后归0

int max;    //数组中当前最大值

int total;//总得分,为所有格子的数字之和

 

static struct termios oldt;

 

void my_restore_terminal_settings(void)

{

    tcsetattr(0, TCSANOW, &oldt);

}

 

void disable_terminal_return(void)

{

    struct termios newt;

    tcgetattr(0, &oldt);

    newt = oldt;

    newt.c_lflag &= ~(ICANON | ECHO);

    tcsetattr(0, TCSANOW, &newt);

    atexit(my_restore_terminal_settings);

}

 

void my_init(void)

{

    int i, random1, random2;

    random1 = rand() % SIZE;

    for(i = 0; i < 1; i++)

    {

        random2 = rand() % SIZE;

        if(random1 == random2)

        {

            i--;

        }

    }

    arr[random1] = 2;

    arr[random2] = 2;

}

 

int my_is_dead()

{

    int i, j;

    for(i = 0; i < SIZE; i++)

    {

        if(!arr[i])

        {

            return 0;

        }

    }

    for(i = 0; i < SIZE; i += width)

    {

        for(j = i; j < i + width-1; j++)

        {

            if(arr[j] == arr[j + 1])

            {

                return 0;

            }

        }

    }

    for(i = 0; i < width; i++)

    {

        for(j = i; j < i + width*(width-1); j += width)

        {

            if(arr[j] == arr[j + width])

            {

                return 0;

            }

        }

    }

    return 1;

}

 

/**

* my_max_num :找到此时最大的数字

* return :无返回值

*/

int my_max_num(void)

{

    int i;

    static int count = 0;

    for(i = 0; i < SIZE; i++)

    {

        /*************** Begin ***************/

       

     

        /*************** End ***************/

    }

    if(!count && 2048 == max)

    {

        count++;

        printf("恭喜过关,请按任意键继续!");

        getchar();

    }

    return max;

}

 

void my_print_game(void)

{

    system("clear");

    int i;

    printf("按【I】向上移动\n按【K】向下移动\n按【J】向左移动\n按【L】向右移动\n按【Ctrl + Z】退出游戏\n最大的数是:%d\n总分是:%d\n", my_max_num(), total);

    printf("\n");

    printf("+------------------  2048  ------------------+\n");

    printf("+--------------------------------------------+\n");

    printf("|        |        |        |        |        |\n");

    for(i = 0; i < SIZE; i++)

    {

        if(0 == i || width == i || 2*width == i || 3*width == i || 4*width ==i)

        {

            printf("|");

        }

        printf(0 == arr[i] ? "%9c|" : "%8d|", arr[i]);

        if((width-1) == i || (2*width-1) == i || (3*width-1) == i || (4*width-1)==i)

        {

            printf("\n");

            printf("|--------+--------+--------+--------+--------|\n");

            printf("|        |        |        |        |        |\n");

        }

    }

    printf("\n");

    printf("+--------------------------------------------+\n");

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

    if(my_is_dead())

    {

        int i;

        printf("game over!\n");

        printf("请按任意键重新开始!\n");

        getchar();

        for(i = 0; i < SIZE; i++)

        {

            arr[i] = 0;

        }

        my_init();

        my_print_game();

    }

}

 

void my_rand_num(void)

{

    while(is_move || is_merge) // 判断上否可以移动或者合并;如果可以在剩下的格子中产生随机数字,对应数组下标,将对应下表赋值为2

    {

        /*************** Begin ***************/

       

       

        /*************** End ***************/

    }

    is_move = 0;

    is_merge = 0;

}

 

 

void my_move_go(int loop_count, int current_i, int direction)

{

    int i;

    for(i = 0; i < loop_count; i++)

    {

        if(arr[current_i] && !arr[current_i + direction])

        {

            arr[current_i + direction] = arr[current_i];

            arr[current_i] = 0;

            current_i += direction;

            is_move = 1;

        }

    }

}

 

/**

* my_move_up : 向下移动,不管数字是否相同,全部一个一个的向下移动

* return : 无返回值

*/

void my_move_up(void)

{

    /*************** Begin ***************/

   

    /*************** End ***************/

}

 

/**

* my_move_down : 向下移动,不管数字是否相同,全部一个一个的向下移动

* return : 无返回值

*/

void my_move_down(void)

{

    /*************** Begin ***************/

   

    /*************** End ***************/

}

 

/**

* my_move_right : 向右移动,不管数字是否相同,全部一个一个的向右移动

* return : 无返回值

*/

void my_move_right(void)

{

    /*************** Begin ***************/

   

    /*************** End ***************/

}

 

/*

* my_move_left : 向左移动,不管数字是否相同,全部一个一个的向左移动

* return : 无返回值

*/

void my_move_left(void)

{

    /*************** Begin ***************/

   

    /*************** End ***************/

}

 

/*

* current_i : 合并格子的当前下标

* direction : 上一个格子距离下一个格子的距离,也是游戏棋盘的边长

* merge : 合并函数,只负责一次合并,把接受当前数字下标,把它上或者下或者右的格子合并一个

* return : 无返回值

*/

void merge(int current_i, int direction)

{

    if(arr[current_i] && arr[current_i + direction] && arr[current_i] == arr[current_i + direction])

    {

        /*************** Begin ***************/

       

        /*************** End ***************/

    }

}

 

void my_move_up_pre(void)

{

    my_move_up();

    int i, j, direction = width;

    for(i = 0; i < width; i++)

    {

        for(j = i; j < i + (width-1)*width; j += width)

        {

            merge(j, direction);

        }

    }

    my_move_up();

}

 

void my_move_down_pre(void)

{

    my_move_down();

    int i, j, direction = -5;

    for(i = width - 1; i >= 0; i--)

    {

        for(j = i + (width-1)*width; j >= width; j -= width)

        {

            merge(j, direction);

        }

    }

    my_move_down();

}

 

void my_move_right_pre(void)

{

    my_move_right();

    int i, j, direction = -1;

    for(i = width - 1; i >= 0; i--)

    {

        for(j = width * i + (width-1); j > width * i; j--)

        {

            merge(j, direction);

        }

    }

    my_move_right();

}

 

void my_move_left_pre(void)

{

    my_move_left();

    int i, j, direction = 1;

    for(i = 0; i <= (width-1); i++)

    {

        for(j = width * i; j < width * i + (width-1); j++)

        {

            merge(j, direction);

        }

    }

    my_move_left();

}

 

//游戏主函数,控制游戏流程

void my_run(){

    srand(time(NULL));

    my_init();

    my_print_game();

    disable_terminal_return();

    int p=0;

    while(1)

    {

        /**

            判断输入 结合上面的功能函数,使游戏运行起来

        */

        /*************** Begin ***************/

       

        /*************** End ***************/

    }

}

 

...全文
995 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

70,038

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧