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

C++ 实现 2048 小游戏实战教程

C++ 实现 2048 游戏的核心在于二维数组的状态管理与移动合并算法。文章详细展示了如何初始化 4x4 棋盘,利用随机数填充初始数字,并通过方向键控制数据块的滑动与同值合并。重点解析了上下左右四个方向的移动逻辑实现,以及基于棋盘满员和相邻数值判断的游戏结束条件。

剑仙发布于 2026/3/29更新于 2026/10/25105 浏览
C++ 实现 2048 小游戏实战教程

2048 游戏规则简述

在动手写代码前,先明确一下核心规则:棋盘初始随机生成两个数字(2 或 4),玩家通过方向键移动方块。相同数字碰撞会合并翻倍,目标是合成 2048。若棋盘填满且无法移动,则游戏结束。

基于此,我们可以将开发流程拆解为五个关键步骤:初始化界面、随机生成数字、处理用户输入、更新与合并逻辑、判断胜负状态。

核心实现步骤

1. 初始化游戏界面

最基础的数据结构是一个二维数组。我们定义一个 4x4 的矩阵来代表棋盘,初始值全为 0,表示空格。

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

这里用宏定义 SIZE 方便后续维护,如果以后想改棋盘大小,只需改一处。

2. 随机生成数字

游戏开始时,需要在空位上填入 2 或 4。使用标准库的 rand() 函数配合取模运算即可实现伪随机分布。注意实际运行时建议加上 srand(time(NULL)) 来确保种子不同。

#include <cstdlib>
#include <ctime>

void generateRandomNumbers() {
    int x1, y1, x2, y2;
    // 简单起见,这里未做位置冲突检测,实际项目需增加循环重试
    do {
        x1 = rand() % SIZE;
        y1 = rand() % SIZE;
    } while (gameBoard[x1][y1] != 0);

    do {
        x2 = rand() % SIZE;
        y2 = rand() % SIZE;
    } while (gameBoard[x2][y2] != 0);

    // 生成 2 或 4
    gameBoard[x1][y1] = (rand() % 2 + 1) * 2;
    gameBoard[x2][y2] = (rand() % 2 + 1) * 2;
}

3. 处理用户输入

我们需要监听键盘事件。这里演示基础的字符捕获,根据 W/A/S/D 映射到上下左右操作。

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 (i < SIZE - 1 && gameBoard[i][j] == gameBoard[i + 1][j]) {
                canMove = true;
                break;
            }
            if (j < SIZE - 1 && gameBoard[i][j] == gameBoard[i][j + 1]) {
                canMove = true;
                break;
            }
        }
        if (canMove) break;
    }
    return !canMove;
}

通过以上模块的组合,我们就构建了一个完整的 2048 游戏内核。实际项目中,你可以在此基础上添加 UI 渲染、音效或计分系统。

目录

  1. 2048 游戏规则简述
  2. 核心实现步骤
  3. 1. 初始化游戏界面
  4. 2. 随机生成数字
  5. 3. 处理用户输入
  6. 4. 移动与合并逻辑
  7. 5. 判断游戏结束

更多推荐文章

查看全部
  • OpenCLEW 与 Java 融合:AI 系统工程化新范式
  • AIGC 时代的 Model Context Protocol(MCP)协议详解与实践
  • 动态规划路径类 DP 入门:3 道经典例题详解
  • Linux 一切皆文件:深入理解文件与文件 IO
  • CISP-PTE 认证含金量及报考指南
  • 从零开始实现决策树——手撕 CART 算法(C++)
  • AIGC 浪潮下的 Model Context Protocol (MCP) 详解
  • Web Unlocker API 获取亚马逊平台数据示例
  • 前端常用动画库实战:GSAP、Lottie、Swiper 与 AOS
  • React 集成 Microi 吾码低代码平台开发指南
  • CLIP 论文深度解读:基于自然语言监督的视觉模型迁移
  • AR/VR 与边缘计算融合下的测试扩展策略
  • YOLOv8与ROS结合构建机器人视觉感知系统
  • 大疆无人机开发入门:MSDK、PSDK 与上云 API 技术解析
  • Java 搭建 AI Agent 核心原理与实战落地方案
  • Jetson Orin NX 部署 Ollama 与 Llama 3.2
  • 基于 SpringBoot 和 Vue 的来访管理系统设计与数据库实现
  • MCP 协议详解:与 Function Call 的区别及 Python 实现
  • OpenSpec 完全使用指南:约束驱动 AI 编码
  • 实时交互式数字人系统构建实战:从架构到代码实现

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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