首页 > 其他分享 >2048小游戏【C语言版】单文件编写

2048小游戏【C语言版】单文件编写

时间:2024-07-22 21:59:44浏览次数:15  
标签:map now int 2048 next ++ 小游戏 C语言 change

设计思路

  1. 游戏地图和初始设置
    • 使用一个 4x4 的二维数组 map 来表示游戏地图。
    • 初始时,所有位置的值均为 0。
    • score 记录玩家得分,move_num 记录移动次数。
  2. 随机生成数字
    • 在地图上随机选择一个空位置生成 2 或 4。
    • 只有在地图发生变化时才会生成新数字。
  3. 游戏菜单
    • 使用 menu() 函数显示当前的游戏状态,包括地图、得分和移动次数。
    • 提示玩家使用 W、A、S、D 键进行移动。
  4. 玩家移动
    • 使用 move() 函数读取玩家输入,并根据输入的方向调用相应的移动函数 (up()left()down()right())。
    • 每个移动函数都负责处理特定方向的移动,并更新地图。
  5. 移动逻辑
    • 移动时首先合并相同的数字,然后将非零元素向目标方向移动填补空格。
    • change 变量用于记录地图是否发生变化,以决定是否生成新数字。
  6. 游戏结束判断
    • 使用 over() 函数检查游戏是否结束。
    • 游戏结束的条件是:地图没有空位且没有相邻的相同数字。
    • 若游戏结束,输出最终得分和移动次数。

细节分析

  • 随机数生成:使用 rand() 函数生成随机位置和数字,但未处理随机数种子的初始化位置,可能会导致每次运行的结果相同。
  • 输入处理:使用 getch() 函数获取用户输入,并根据输入调用相应的移动函数。
  • 移动实现:每个方向的移动函数都按照特定的顺序检查并合并相同的数字,然后移动非零元素。
  • 游戏结束检测:遍历整个地图,检查是否还有空位或相邻的相同数字。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h> // 用于 getch 函数

int map[4][4] = {0}; // 游戏地图
int score = 0;       // 玩家得分
int move_num = -1;   // 移动次数
int game_over = 1;   // 游戏结束标志,0表示游戏结束
int change = 1;      // 跟踪地图是否发生变化,0表示没有变化
char input;          // 控制方向

// 函数声明
void start();
void randIntNum();
void menu();
void move();
int up();
int left();
int down();
int right();
int over();

// 在数组中随机生成一个位置并赋值2或4
void randIntNum()
{
    int i, j, n;
    if (change >= 1) // 只有在地图变化时才生成新数字
    {
        do
        {
            i = rand() % 4; // 随机行索引
            j = rand() % 4; // 随机列索引
        } while (map[i][j] != 0); // 确保位置为空

        n = rand() % 2;               // 随机选择0或1
        map[i][j] = (n == 0) ? 2 : 4; // 将2或4赋值给选中的位置

        move_num++; // 增加移动计数
    }
}

// 显示游戏菜单
void menu()
{
    system("cls"); // 清屏
    int i, j;
    printf("                 欢迎来到2048\n");
    printf("     ----------------------------------------\n");
    printf("     W——UP S——DOWN A——LEFT D——RIGHT\n");
    printf("     请按0退出游戏。\n");
    printf("     MOVE:%d          SCORE:%d\n", move_num, score);
    printf("     \n     |-------------------------------------------|\n");
    for (i = 0; i <= 3; i++)
    {
        for (j = 0; j <= 3; j++)
        {
            printf("     ");
            if (map[i][j] == 0)
                printf("|     ");
            else
                printf("|%5d", map[i][j]);
        }
        printf("     |\n     |-------------------------------------------|\n");
    }
}

// 处理玩家的移动
void move()
{
    char ch = getch(); // 从键盘读取控制输入
    change = 0;        // 重置变化跟踪器
    switch (ch)
    {
    case '0':                            // 如果玩家输入'0'
        printf("确定要退出吗?(y/n)\n"); // 确认退出
        ch = getchar();
        if (ch == 'y' || ch == 'Y') // 如果是,退出游戏
            exit(0);
        break;
    case 'w': // 上移
    case 'W':
        up();
        break;
    case 'a': // 左移
    case 'A':
        left();
        break;
    case 's': // 下移
    case 'S':
        down();
        break;
    case 'd': // 右移
    case 'D':
        right();
        break;
    default: // 无效输入
        printf("无效输入,请重新输入!\n");
        break;
    }
}

// 向上移动
int up()
{
    int now, next;
    int i, j, k;
    for (j = 0; j < 4; j++)
    {
        for (i = 0; i < 4; i++)
        {
            now = map[i][j];
            {
                k = i + 1;
                while (k < 4)
                {
                    next = map[k][j];
                    if (next != 0)
                    {
                        if (now == next)
                        {
                            change = 1;
                            score += map[k][j] * 2;
                            map[i][j] = 2 * map[k][j];
                            map[k][j] = 0;
                        }
                        k = 4;
                    }
                    k++;
                }
            }
        }
    }
    // 将非零元素向上移动,填补空格
    for (j = 0; j < 4; j++)
    {
        for (i = 0; i < 4; i++)
        {
            now = map[i][j];
            if (now == 0)
            {
                k = 1 + i;
                while (k < 4)
                {
                    next = map[k][j];
                    if (next != 0)
                    {
                        change = 1;
                        map[i][j] = next;
                        map[k][j] = 0;
                        k = 4;
                    }
                    k++;
                }
            }
        }
    }
    return change;
}

// 向右移动
int right()
{
    int i, j;
    int now, next, k;
    for (i = 0; i < 4; i++)
    {
        for (j = 3; j >= 0; j--)
        {
            now = map[i][j];
            k = j - 1;
            while (k >= 0)
            {
                next = map[i][k];
                if (next != 0)
                {
                    if (next == now)
                    {
                        change = 1;
                        score += map[i][k] * 2;
                        map[i][j] = map[i][k] * 2;
                        map[i][k] = 0;
                    }
                    k = -1;
                }
                k--;
            }
        }
    }
    // 将非零元素向右移动,填补空格
    for (i = 0; i < 4; i++)
    {
        for (j = 3; j >= 0; j--)
        {
            now = map[i][j];
            if (now == 0)
            {
                k = j - 1;
                while (k >= 0)
                {
                    next = map[i][k];
                    if (next != 0)
                    {
                        change = 1;
                        map[i][j] = map[i][k];
                        map[i][k] = 0;
                        k = -1;
                    }
                    k--;
                }
            }
        }
    }
    return change;
}

// 向左移动
int left()
{
    int i, j;
    int now, next, k;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            now = map[i][j];
            k = j + 1;
            while (k < 4)
            {
                next = map[i][k];
                if (next != 0)
                {
                    if (now == next)
                    {
                        change = 1;
                        score += 2 * map[i][k];
                        map[i][j] = map[i][k] * 2;
                        map[i][k] = 0;
                    }
                    k = 4;
                }
                k++;
            }
        }
    }
    // 将非零元素向左移动,填补空格
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            now = map[i][j];
            if (now == 0)
            {
                k = j + 1;
                while (k < 4)
                {
                    next = map[i][k];
                    if (next != 0)
                    {
                        change = 1;
                        map[i][j] = map[i][k];
                        map[i][k] = 0;
                        k = 4;
                    }
                    k++;
                }
            }
        }
    }
    return change;
}

// 向下移动
int down()
{
    int i, j;
    int now, next, k;
    for (j = 0; j < 4; j++)
    {
        for (i = 3; i >= 0; i--)
        {
            now = map[i][j];
            if (now != 0)
            {
                k = i - 1;
                while (k >= 0)
                {
                    next = map[k][j];
                    if (next != 0)
                    {
                        if (now == next)
                        {
                            change = 1;
                            score += map[k][j] * 2;
                            map[i][j] = map[k][j] * 2;
                            map[k][j] = 0;
                        }
                        k = -1;
                    }
                    k--;
                }
            }
        }
    }
    // 将非零元素向下移动,填补空格
    for (j = 0; j < 4; j++)
    {
        for (i = 3; i >= 0; i--)
        {
            now = map[i][j];
            if (now == 0)
            {
                k = i - 1;
                while (k >= 0)
                {
                    next = map[k][j];
                    if (next != 0)
                    {
                        change = 1;
                        map[i][j] = map[k][j];
                        map[k][j] = 0;
                        k = -1;
                    }
                    k--;
                }
            }
        }
    }
    return change;
}

// 结束函数
int over()
{
    // 检查游戏是否结束
    game_over = 0;

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            //判断地图里是否还有空位
            if (map[i][j] == 0)
            {
                game_over = 1;
                break;
            }

            //判断是否有相同的两个数字挨在一起,若有则gameover改为1,
            if (i > 1)
            {
                if (map[i][j] == map[i - 1][j])
                    game_over = 1;
                break;
            }

            if (j > 1)
            {
                if (map[i][j] == map[i][j - 1])
                {
                    game_over = 1;
                    break;
                }
            }
        }

        if (game_over == 1)
            break;
    }

    if (game_over == 0) // 游戏结束
    {
        printf("游戏结束!\n最终得分:%d\n", score);
        printf("移动次数:%d\n", move_num);
    }
}
// 游戏开始函数
void start()
{
    srand((unsigned)time(NULL)); // 初始化随机数生成器

    while (game_over) // 游戏循环
    {
        randIntNum(); // 在随机位置生成初始数字
        menu();       // 显示菜单
        move();       // 处理玩家输入和移动
        over();
    }
}

int main()
{
    start(); // 开始游戏
    return 0;
}

标签:map,now,int,2048,next,++,小游戏,C语言,change
From: https://blog.csdn.net/qq_58204972/article/details/140619780

相关文章

  • 数据结构——堆(C语言版)
    树    树的概念:        树(Tree)是一种抽象数据结构,它由节点(node)的集合组成,这些节点通过边相连,把节点集合按照逻辑顺序抽象成图像,看起来就像一个倒挂着的树,也就是说数据结构中的树是根成朝上,叶子朝下。        树形结构中,⼦树之间不能有交集,否则就不......
  • C语言指针易混淆知识点总结
    指针定义指针是一个变量,存储另一个变量的内存地址,它允许直接访问和操作内存中的数据,使得程序能够以更灵活和高效的方式处理数据和内存。获取变量地址:使用取地址符&。访问地址上的数据:使用解引用符*。例子1指针是存储另一个变量地址的变量。通过使用取地址符&和解引用符......
  • 【C语言】Linux 飞翔的小鸟
    【C语言】Linux飞翔的小鸟零、环境部署安装Ncurses库sudoapt-getinstalllibncurses5-dev壹、编写代码代码如下:bird.c#include<stdio.h>#include<time.h>#include<stdlib.h>#include<signal.h>#include<curses.h>#include<sys/time.h>#include<u......
  • ##笔记day06-C语言基础:随机数、一维、二维数组、字符数组
    day07笔记1)rand生成随机数1)rand()随机函数头文件:#include<stdlib.h>函数原型:intrand(void);函数功能:生成大于等于0的随机整数参数:void返回值:生成的随机整数2)srand更新随机数种子(srand()函数用于给rand()函数设定种子)头文件:......
  • 20-c语言main函数参数`argc` 和 `argv[]` 解析
    argc和argv[]解析argc和argv[]是main函数的参数,用于处理命令行参数。一、示例命令行调用./a.out123345解释:./a.out是程序名,也是第一个参数。123和345是运行时传递的额外参数。二、main函数定义intmain(intargc,charconst*argv[]){re......
  • C语言结构体及位域
    一.结构体1.定义和声明结构体是由不同数据类型数据构成的组合型的数据结构,是用户自定义的数据类型。2.结构体类型的声明格式:struct结构体名{   成员列表};举个例子,写一个用来放学生信息的结构体structSTU{    charname[20];  //用来放学生姓名的数组......
  • 【保姆级讲解C语言中的运算符的优先级!】
    ......
  • C语言初学者入门指南
    C语言初学者入门指南        在编程的世界里,C语言被誉为“编程语言之母”,它是许多现代编程语言(如C++、Java、Python等)的基石。C语言以其高效、灵活和接近硬件的特性,在操作系统、嵌入式系统、游戏开发等多个领域发挥着重要作用。对于初学者而言,掌握C语言不仅能帮助你理......
  • 数据结构-C语言-排序(3)
            代码位置:test-c-2024:对C语言习题代码的练习(gitee.com)一、前言:1.1-排序定义:        排序就是将一组杂乱无章的数据按照一定的规律(升序或降序)组织起来。(注:我们这里的排序采用的都为升序)1.2-排序分类:常见的排序算法:插入排序a. 直接插......
  • C语言-常用算法-23
     题目:分数计算器程序源代码:#include<stdio.h>intgys(intx,inty){returny?gys(y,x%y):x;}intgbs(intx,inty){returnx/gys(x,y)*y;}voidyuefen(intfz,intfm){ints=gys(fz,fm);fz/=s;fm/=s;printf("结果是:%d/%d&quo......