跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 实现 2048 游戏核心逻辑解析

C++ 2048 游戏实现涉及棋盘初始化、随机数生成、用户输入响应及移动合并逻辑。核心数据结构为 4x4 二维数组,通过遍历与条件判断实现数字滑动与同值合并。胜负判定基于是否达到 2048 数值或棋盘无法继续移动。代码展示了上下左右四个方向的移动算法及游戏结束检测机制。

宁静发布于 2026/3/29更新于 2026/9/1058 浏览
C++ 实现 2048 游戏核心逻辑解析

2048 游戏规则简述

在动手编写之前,先明确核心机制:棋盘初始随机生成两个数字(通常是 2 或 4),玩家通过方向键移动方块,相同数字碰撞合并,目标达成 2048。若棋盘填满且无法移动则结束。

因此,我们可以将开发流程拆解为几个关键步骤:初始化界面、随机生成数字、处理用户输入、更新界面以及判断游戏状态。

1. 初始化游戏界面

我们需要一个二维数组来模拟 4x4 的棋盘,每个元素代表一个格子,初始值设为 0。

#define SIZE 4
int gameBoard[SIZE][SIZE] = {0};

这里定义了 SIZE 常量,方便后续统一修改棋盘大小。所有元素初始化为 0 表示空位。

2. 随机生成数字

游戏开始时,需要在棋盘的两个空白格中随机填入 2 或 4。使用 <cstdlib> 和 <ctime> 库可以生成伪随机数。

注意,实际运行时建议调用 srand(time(NULL)) 初始化随机种子,否则每次运行生成的序列可能相同。生成坐标后,将数值赋给对应位置即可。

#include <cstdlib>
#include <ctime>

void generateRandomNumbers() {
    srand(time(NULL)); // 初始化随机种子
    int x1 = rand() % SIZE;
    int y1 = rand() % SIZE;
    int x2 = rand() % SIZE;
    int y2 = rand() % SIZE;

    int num1 = (rand() % 2 + 1) * 2;
    int num2 = (rand() % 2 + 1) * 2;

    gameBoard[x1][y1] = num1;
    gameBoard[x2][y2] = num2;
}

3. 处理用户输入

捕捉用户的键盘操作,根据输入指令触发相应的移动逻辑。这里使用 getchar() 获取字符,并通过 switch 语句分发到不同方向的处理函数。

void processUserInput() {
    char userInput = getchar();
    switch (userInput) {
        case 'w':
            moveUp(gameBoard);
            break;
        case 's':
            moveDown(gameBoard);
            break;
        case 'a':
            moveLeft(gameBoard);
            break;
        case 'd':
            moveRight(gameBoard);
            break;
        default:
            break;
    }
}

4. 更新游戏界面

这是最核心的部分。当用户按下方向键时,需要将数字向指定方向移动,并填充空白格子。如果相邻的两个格子数字相同,则合并为一个,数值翻倍。

以向上移动为例,遍历每一列,从第二行开始检查。如果遇到非零元素,尝试将其向上'浮'直到遇到边界或其他数字。如果上方数字与当前相同,则合并。

bool moveUp(int board[SIZE][SIZE]) {
    bool moved = false;
    for (int j = 0; j < SIZE; j++) {
        for (int i = 1; i < SIZE; i++) {
            if (board[i][j] != 0) {
                int k = i;
                while (k > 0 && board[k-1][j] == 0) {
                    board[k-1][j] = board[k][j];
                    board[k][j] = 0;
                    k--;
                    moved = true;
                }
                if (k > 0 && board[k-1][j] == board[k][j]) {
                    board[k-1][j] *= 2;
                    board[k][j] = 0;
                    moved = true;
                }
            }
        }
    }
    return moved;
}

// 向下、向左、向右的逻辑类似,只需调整循环方向和比较索引
bool moveDown(int board[SIZE][SIZE]) {
    bool moved = false;
    for (int j = 0; j < SIZE; j++) {
        for (int i = SIZE - 2; i >= 0; i--) {
            if (board[i][j] != 0) {
                int k = i;
                while (k < SIZE - 1 && board[k+1][j] == 0) {
                    board[k+1][j] = board[k][j];
                    board[k][j] = 0;
                    k++;
                    moved = true;
                }
                if (k < SIZE - 1 && board[k+1][j] == board[k][j]) {
                    board[k+1][j] *= 2;
                    board[k][j] = 0;
                    moved = true;
                }
            }
        }
    }
    return moved;
}

bool moveLeft(int board[SIZE][SIZE]) {
    bool moved = false;
    for (int i = 0; i < SIZE; i++) {
        for (int j = 1; j < SIZE; j++) {
            if (board[i][j] != 0) {
                int k = j;
                while (k > 0 && board[i][k-1] == 0) {
                    board[i][k-1] = board[i][k];
                    board[i][k] = 0;
                    k--;
                    moved = true;
                }
                if (k > 0 && board[i][k-1] == board[i][k]) {
                    board[i][k-1] *= 2;
                    board[i][k] = 0;
                    moved = true;
                }
            }
        }
    }
    return moved;
}

bool moveRight(int board[SIZE][SIZE]) {
    bool moved = false;
    for (int i = 0; i < SIZE; i++) {
        for (int j = SIZE - 2; j >= 0; j--) {
            if (board[i][j] != 0) {
                int k = j;
                while (k < SIZE - 1 && board[i][k+1] == 0) {
                    board[i][k+1] = board[i][k];
                    board[i][k] = 0;
                    k++;
                    moved = true;
                }
                if (k < SIZE - 1 && board[i][k+1] == board[i][k]) {
                    board[i][k+1] *= 2;
                    board[i][k] = 0;
                    moved = true;
                }
            }
        }
    }
    return moved;
}

5. 判断游戏结束

游戏结束通常有两种情况:一是达到了胜利条件(出现 2048),二是失败条件(棋盘已满且无相邻可合并项)。

bool isGameWon() {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (gameBoard[i][j] == 2048) {
                return true;
            }
        }
    }
    return false;
}

bool isGameOver() {
    bool canMove = false;
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            // 如果有空位,说明还能继续
            if (gameBoard[i][j] == 0) {
                canMove = true;
                break;
            }
            // 检查右侧是否有相同数字
            if (j < SIZE - 1 && gameBoard[i][j] == gameBoard[i][j + 1]) {
                canMove = true;
                break;
            }
            // 检查下方是否有相同数字
            if (i < SIZE - 1 && gameBoard[i][j] == gameBoard[i + 1][j]) {
                canMove = true;
                break;
            }
        }
        if (canMove) break;
    }
    return !canMove;
}

通过以上模块组合,即可完成基础版 2048 的核心逻辑。重点在于数组操作与状态判断的准确性。

目录

  1. 2048 游戏规则简述
  2. 1. 初始化游戏界面
  3. 2. 随机生成数字
  4. 3. 处理用户输入
  5. 4. 更新游戏界面
  6. 5. 判断游戏结束

更多推荐文章

查看全部
  • 前缀和算法:从一维到二维的实战应用
  • Android 插件化技术:动态创建 Activity 模式详解
  • 原生 JS 实现点击 li 标签输出索引
  • C++ 继承机制详解:概念、访问控制与虚拟继承
  • 命令行大模型工具交互实践:小巧的 MCPHost
  • C++ 实现 2048 小游戏核心逻辑解析
  • 开源 AI 联网搜索工具 OpenWebSearch MCP 升级,支持多引擎与流式响应
  • 使用 MCP 协议实现 Dify 与 MySQL 的深度整合
  • 基于 SpringBoot 的图书租借系统设计与实现
  • 数据结构基础:单向链表实现与原理
  • 零次方机器人发布轮式人形机器人 Zerith-H1 及操作基础模型 Zerith-V0
  • Web 应用架构解析与安全漏洞实战指南
  • Python 基础语法入门:常量、变量与运算符
  • 网络安全技术入门:渗透测试、二进制逆向与安全研发
  • Java 线程池核心原理与实战配置
  • 大模型的 6 项核心技术:Transformer、预训练与 RLHF 等
  • 用 webdav-server 搭一个轻量文件共享服务
  • 网络安全系统学习路线:从基础到进阶的完整指南
  • 数据结构:图论基础
  • RK1820 协处理器在 RK3588 系统中的分工与架构解析

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online