一个简单的2048小游戏

cpp 复制代码
#include <iostream>
#include <windows.h>   // 用于颜色和光标
#include <conio.h>     // 用于 _kbhit() 和 _getch()
#include <ctime>
#include <cstdlib>
using namespace std;

// ---------- 颜色控制 ----------
enum Color {
    BLACK = 0,
    DARK_BLUE = 1,
    DARK_GREEN = 2,
    DARK_CYAN = 3,
    DARK_RED = 4,
    DARK_MAGENTA = 5,
    DARK_YELLOW = 6,
    GRAY = 7,
    DARK_GRAY = 8,
    BLUE = 9,
    GREEN = 10,
    CYAN = 11,
    RED = 12,
    MAGENTA = 13,
    YELLOW = 14,
    WHITE = 15
};

HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

void setColor(Color color) {
    SetConsoleTextAttribute(hConsole, color);
}

void gotoxy(int x, int y) {
    COORD pos = { (short)x, (short)y };
    SetConsoleCursorPosition(hConsole, pos);
}

// ---------- 游戏变量 ----------
int board[4][4] = { 0 };
int score = 0;
bool gameOver = false;
bool win = false;

// 随机生成一个方块 (2 或 4)
void addRandomTile() {
    int emptyCells[16][2];
    int count = 0;
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (board[i][j] == 0) {
                emptyCells[count][0] = i;
                emptyCells[count][1] = j;
                count++;
            }
        }
    }
    if (count == 0) return;
    int idx = rand() % count;
    int r = emptyCells[idx][0];
    int c = emptyCells[idx][1];
    board[r][c] = (rand() % 10 == 0) ? 4 : 2; // 10% 概率生成 4
}

// ---------- 核心移动逻辑 ----------
// 向左滑动一行 (返回是否移动)
bool slideRow(int row[4]) {
    bool moved = false;
    // 1. 压缩 (去掉空格)
    int temp[4] = { 0 };
    int idx = 0;
    for (int i = 0; i < 4; i++) {
        if (row[i] != 0) temp[idx++] = row[i];
    }
    // 2. 合并
    for (int i = 0; i < 3; i++) {
        if (temp[i] != 0 && temp[i] == temp[i + 1]) {
            temp[i] *= 2;
            score += temp[i];
            if (temp[i] == 2048) win = true;
            temp[i + 1] = 0;
            i++; // 跳过已合并的
        }
    }
    // 3. 再次压缩
    int result[4] = { 0 };
    idx = 0;
    for (int i = 0; i < 4; i++) {
        if (temp[i] != 0) result[idx++] = temp[i];
    }
    // 4. 检查是否改变了
    for (int i = 0; i < 4; i++) {
        if (row[i] != result[i]) moved = true;
        row[i] = result[i];
    }
    return moved;
}

bool moveLeft() {
    bool moved = false;
    for (int i = 0; i < 4; i++) {
        if (slideRow(board[i])) moved = true;
    }
    return moved;
}

bool moveRight() {
    bool moved = false;
    for (int i = 0; i < 4; i++) {
        int row[4];
        for (int j = 0; j < 4; j++) row[j] = board[i][3 - j];
        if (slideRow(row)) {
            moved = true;
            for (int j = 0; j < 4; j++) board[i][3 - j] = row[j];
        }
    }
    return moved;
}

bool moveUp() {
    bool moved = false;
    for (int j = 0; j < 4; j++) {
        int col[4];
        for (int i = 0; i < 4; i++) col[i] = board[i][j];
        if (slideRow(col)) {
            moved = true;
            for (int i = 0; i < 4; i++) board[i][j] = col[i];
        }
    }
    return moved;
}

bool moveDown() {
    bool moved = false;
    for (int j = 0; j < 4; j++) {
        int col[4];
        for (int i = 0; i < 4; i++) col[i] = board[3 - i][j];
        if (slideRow(col)) {
            moved = true;
            for (int i = 0; i < 4; i++) board[3 - i][j] = col[i];
        }
    }
    return moved;
}

// 检查是否还能继续 (有空位或相邻相等)
bool canContinue() {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (board[i][j] == 0) return true;
            if (i < 3 && board[i][j] == board[i + 1][j]) return true;
            if (j < 3 && board[i][j] == board[i][j + 1]) return true;
        }
    }
    return false;
}

// ---------- 绘制棋盘 ----------
Color getTileColor(int value) {
    switch (value) {
    case 2: return DARK_GRAY;
    case 4: return DARK_YELLOW;
    case 8: return DARK_RED;
    case 16: return RED;
    case 32: return MAGENTA;
    case 64: return DARK_MAGENTA;
    case 128: return DARK_BLUE;
    case 256: return BLUE;
    case 512: return DARK_CYAN;
    case 1024: return CYAN;
    case 2048: return YELLOW;
    default: return WHITE;
    }
}

void drawBoard() {
    gotoxy(0, 0);
    setColor(WHITE);
    cout << "╔═══════════════════════════╗" << endl;
    for (int i = 0; i < 4; i++) {
        cout << "║";
        for (int j = 0; j < 4; j++) {
            int val = board[i][j];
            setColor(WHITE);
            cout << " ";
            if (val == 0) {
                cout << "    ";
            }
            else {
                setColor(getTileColor(val));
                // 对齐:数字占4格
                if (val < 10) cout << "  " << val << " ";
                else if (val < 100) cout << " " << val << " ";
                else if (val < 1000) cout << " " << val;
                else cout << val;
            }
            setColor(WHITE);
            cout << " ";
        }
        cout << "║" << endl;
    }
    cout << "╚═══════════════════════════╝" << endl;
    setColor(WHITE);
    cout << "得分: " << score << "      ";
    if (win) {
        setColor(YELLOW);
        cout << "你赢了! (按 R 继续挑战)";
        setColor(WHITE);
    }
    else if (gameOver) {
        setColor(RED);
        cout << "游戏结束! (按 R 重新开始)";
        setColor(WHITE);
    }
    cout << endl;
    cout << "操作: WASD 移动 | R 重启 | Q 退出" << endl;
}

// ---------- 游戏控制 ----------
void resetGame() {
    for (int i = 0; i < 4; i++)
        for (int j = 0; j < 4; j++)
            board[i][j] = 0;
    score = 0;
    gameOver = false;
    win = false;
    addRandomTile();
    addRandomTile();
    drawBoard();
}

void processMove(bool moved) {
    if (moved) {
        addRandomTile();
        drawBoard();
        if (win) {
            // 赢了依然可以继续
        }
        if (!canContinue()) {
            gameOver = true;
            drawBoard();
        }
    }
}

// ---------- 主函数 ----------
int main() {
    system("title 2048 游戏");
    system("mode con: cols=40 lines=25");

    // 隐藏光标
    CONSOLE_CURSOR_INFO cursorInfo;
    GetConsoleCursorInfo(hConsole, &cursorInfo);
    cursorInfo.bVisible = false;
    SetConsoleCursorInfo(hConsole, &cursorInfo);

    srand((unsigned)time(nullptr));
    resetGame();

    while (true) {
        if (_kbhit()) {
            int key = _getch();
            bool moved = false;

            if (key == 224) { // 方向键
                key = _getch();
                switch (key) {
                case 75: moved = moveLeft(); break;  // 左
                case 77: moved = moveRight(); break; // 右
                case 72: moved = moveUp(); break;    // 上
                case 80: moved = moveDown(); break;  // 下
                }
                if (moved) processMove(moved);
            }
            else {
                switch (tolower(key)) {
                case 'a': moved = moveLeft(); break;
                case 'd': moved = moveRight(); break;
                case 'w': moved = moveUp(); break;
                case 's': moved = moveDown(); break;
                case 'r': resetGame(); break;
                case 'q': return 0;
                }
                if (moved) processMove(moved);
            }
            drawBoard(); // 刷新显示
        }
        Sleep(50);
    }
    return 0;
}

这个放在vs2022上就可以直接运行,不同的数字为了区分用了不同的颜色

WASD 或 方向键(↑↓←→) 移动方块

R:重新开始

Q:退出游戏

游戏规则

每次移动,所有方块会滑向对应方向,相同数字的方块相遇时会合并(数值相加),并增加分数。

每移动一次,棋盘空位会随机生成一个新方块(2 或 4)。

当棋盘被填满且无法再进行任何合并时,游戏结束。

拼出 2048 方块即为胜利(但仍可继续挑战更高分数)

相关推荐
小小数媒成员10 小时前
【8.29-8.31】游戏见闻*
游戏
hkNaruto16 小时前
【游戏】低帧率策略游戏类帧同步保障公平性软件详细设计文档
网络·游戏
科技小登20 小时前
企业DDoS防护方案实战测试:高防CDN、高防IP与SDK游戏盾如何配置
tcp/ip·游戏·ddos
2501_9160074720 小时前
Flutter与游戏App加固避坑指南:如何为混合开发与高交互应用选对安全方案?
安全·flutter·游戏·ios·小程序·uni-app·iphone
只是甲1 天前
《魔法学院救援记》游戏介绍
游戏·vibe coding·学习中游戏·游戏中学习·培养孩子学习兴趣
每周报刊4 天前
竞速座舱级视界:爱攻 AGP497UCZD 超宽 QDOLED 显示器解析
数据结构·游戏·计算机外设
X12499281814 天前
无畏契约更新后卡顿掉帧怎么办?黑屏闪退、游戏打不开解决方法
游戏
wind100324 天前
VC++ 运行库 vcredist 安装失败|CLR 80131522 报错完整修复
开发语言·c++·游戏
Behaviour4 天前
Unity游戏HybridCLR 热更新接入实战
游戏·unity·游戏引擎