用C++编写一个2048的小游戏

以下是一个简单的2048游戏的实现。这个实现使用了控制台输入和输出,适合在终端或命令行环境中运行。


2048游戏的实现


1.游戏逻辑
2048游戏的核心逻辑包括:

• 初始化一个4x4的网格。

• 随机生成2或4。

• 处理玩家的移动操作(上、下、左、右)。

• 合并相同的数字。

• 检查游戏是否结束(胜利或失败)。


2.代码实现


```cpp
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>

using namespace std;

const int GRID_SIZE = 4;
const int WINNING_SCORE = 2048;

void initializeGrid(vector<vector<int>>& grid) {
    for (int i = 0; i < GRID_SIZE; ++i) {
        grid.push_back(vector<int>(GRID_SIZE, 0));
    }
}

void printGrid(const vector<vector<int>>& grid) {
    for (const auto& row : grid) {
        for (int val : row) {
            cout << val << "\t";
        }
        cout << endl;
    }
    cout << endl;
}

void addRandomTile(vector<vector<int>>& grid) {
    vector<pair<int, int>> emptyCells;
    for (int i = 0; i < GRID_SIZE; ++i) {
        for (int j = 0; j < GRID_SIZE; ++j) {
            if (grid[i][j] == 0) {
                emptyCells.push_back({i, j});
            }
        }
    }
    if (!emptyCells.empty()) {
        pair<int, int> cell = emptyCells[rand() % emptyCells.size()];
        grid[cell.first][cell.second] = (rand() % 2) ? 2 : 4;
    }
}

bool canMove(const vector<vector<int>>& grid) {
    for (int i = 0; i < GRID_SIZE; ++i) {
        for (int j = 0; j < GRID_SIZE; ++j) {
            if (grid[i][j] == 0) return true;
            if (i > 0 && grid[i][j] == grid[i - 1][j]) return true;
            if (j > 0 && grid[i][j] == grid[i][j - 1]) return true;
            if (i < GRID_SIZE - 1 && grid[i][j] == grid[i + 1][j]) return true;
            if (j < GRID_SIZE - 1 && grid[i][j] == grid[i][j + 1]) return true;
        }
    }
    return false;
}

void compress(vector<int>& row) {
    vector<int> temp(GRID_SIZE, 0);
    int k = 0;
    for (int i = 0; i < GRID_SIZE; ++i) {
        if (row[i] != 0) {
            temp[k++] = row[i];
        }
    }
    for (int i = 0; i < GRID_SIZE; ++i) {
        row[i] = temp[i];
    }
}

void merge(vector<int>& row) {
    for (int i = 0; i < GRID_SIZE - 1; ++i) {
        if (row[i] == row[i + 1] && row[i] != 0) {
            row[i] *= 2;
            row[i + 1] = 0;
        }
    }
}

void moveLeft(vector<vector<int>>& grid) {
    for (auto& row : grid) {
        compress(row);
        merge(row);
        compress(row);
    }
}

void moveRight(vector<vector<int>>& grid) {
    for (auto& row : grid) {
        reverse(row.begin(), row.end());
        compress(row);
        merge(row);
        compress(row);
        reverse(row.begin(), row.end());
    }
}

void moveUp(vector<vector<int>>& grid) {
    for (int col = 0; col < GRID_SIZE; ++col) {
        vector<int> temp(GRID_SIZE, 0);
        for (int row = 0; row < GRID_SIZE; ++row) {
            temp[row] = grid[row][col];
        }
        compress(temp);
        merge(temp);
        compress(temp);
        for (int row = 0; row < GRID_SIZE; ++row) {
            grid[row][col] = temp[row];
        }
    }
}

void moveDown(vector<vector<int>>& grid) {
    for (int col = 0; col < GRID_SIZE; ++col) {
        vector<int> temp(GRID_SIZE, 0);
        for (int row = 0; row < GRID_SIZE; ++row) {
            temp[row] = grid[row][col];
        }
        reverse(temp.begin(), temp.end());
        compress(temp);
        merge(temp);
        compress(temp);
        reverse(temp.begin(), temp.end());
        for (int row = 0; row < GRID_SIZE; ++row) {
            grid[row][col] = temp[row];
        }
    }
}

bool isGameOver(const vector<vector<int>>& grid) {
    for (const auto& row : grid) {
        for (int val : row) {
            if (val == WINNING_SCORE) return true;
        }
    }
    return !canMove(grid);
}

int main() {
    srand(static_cast<unsigned int>(time(0)));
    vector<vector<int>> grid;
    initializeGrid(grid);
    addRandomTile(grid);
    addRandomTile(grid);

    while (true) {
        printGrid(grid);
        char move;
        cout << "Enter move (W/A/S/D): ";
        cin >> move;

        switch (move) {
            case 'W':
            case 'w':
                moveUp(grid);
                break;
            case 'A':
            case 'a':
                moveLeft(grid);
                break;
            case 'S':
            case 's':
                moveDown(grid);
                break;
            case 'D':
            case 'd':
                moveRight(grid);
                break;
            default:
                cout << "Invalid move. Try again." << endl;
                continue;
        }

        addRandomTile(grid);

        if (isGameOver(grid)) {
            printGrid(grid);
            cout << "Game Over! " << (grid[0][0] == WINNING_SCORE ? "You Win!" : "You Lose!") << endl;
            break;
        }
    }

    return 0;
}
```

3.代码说明

• 初始化网格:`initializeGrid`函数初始化一个4x4的网格,所有值初始化为0。

• 打印网格:`printGrid`函数打印当前网格的状态。

• 添加随机瓷砖:`addRandomTile`函数在网格的空位置随机添加一个2或4。

• 移动操作:`moveLeft`、`moveRight`、`moveUp`、`moveDown`函数分别处理左、右、上、下移动操作。

• 压缩和合并:`compress`和`merge`函数分别处理行或列的压缩和合并操作。

• 检查游戏结束:`isGameOver`函数检查游戏是否结束(胜利或失败)。


4.运行游戏
将上述代码保存为一个C++文件(例如`2048.cpp`),然后使用C++编译器编译并运行它。例如,使用g++编译器:

```sh
g++ -o 2048 2048.cpp
./2048
```

5.游戏玩法

• 使用W/A/S/D键控制方向(上/左/下/右)。

• 游戏目标是合并数字,直到出现2048。

• 如果没有可移动的空位且无法合并,则游戏结束。

希望这个实现对你有帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8834.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Spring】Spring启示录

目录 前言 一、示例程序 二、OCP开闭原则 三、依赖倒置原则DIP 四、控制反转IOC 总结 前言 在软件开发的世界里&#xff0c;随着项目的增长和需求的变化&#xff0c;如何保持代码的灵活性、可维护性和扩展性成为了每个开发者必须面对的问题。传统的面向过程或基于类的设计…

爬虫基础之爬取某基金网站+数据分析

声明: 本案例仅供学习参考使用&#xff0c;任何不法的活动均与本作者无关 网站:天天基金网(1234567.com.cn) --首批独立基金销售机构-- 东方财富网旗下基金平台! 本案例所需要的模块: 1.requests 2.re(内置) 3.pandas 4.pyecharts 其他均需要 pip install 模块名 爬取步骤: …

set集合

set集合 Set系列集合&#xff1a; 无序&#xff1a;存取顺序不一致 不重复&#xff1a;可以去除重复 无索引&#xff1a;没有带索引的方法&#xff0c;所以不能使用普通for循环遍历&#xff0c;也不能通过索引来获取元素 可以看出set是无序的存和打印的顺序不一样 Set接中的…

借DeepSeek-R1东风,开启创业新机遇

DeepSeek-R1的崛起 DeepSeek-R1的推出引发了广泛关注&#xff0c;在AI领域引起了一阵旋风。作为新一代的智能模型&#xff0c;它在多项任务中表现出了卓越的能力。普通人可以借助这个强大的工具&#xff0c;开启属于自己的创业之路&#xff0c;抓住时代带来的机遇。 内容创作…

项目集成Nacos

文章目录 1.环境搭建1.创建模块 sunrays-common-cloud-nacos-starter2.目录结构3.pom.xml4.自动配置1.NacosAutoConfiguration.java2.spring.factories 5.引入cloud模块通用依赖 2.测试1.创建模块 sunrays-common-cloud-nacos-starter-demo2.目录结构3.pom.xml4.application.ym…

系统安全及应用

一&#xff1a;账号安全控制 1.1 系统账号清理 1.1.1 将非登陆用户的Shell 设置为 /sbin/nologin (设置为这个解释器&#xff0c;禁止用户登陆&#xff09; [rootlocalhost ~]# usermod -s /sbin/nologin zhangsan #将用户zhangsan 的登录解释器 设置为 /sbin/n…

从源码深入理解One-API框架:适配器模式实现LLM接口对接

1. 概述 one-api 是一个开源的 API 框架&#xff0c;基于go语言开发&#xff0c;旨在提供统一的接口调用封装&#xff0c;支持多种 AI 服务平台的集成。通过 Gin 和 GORM 等框架&#xff0c;框架简化了多种 API 服务的调用流程。通过适配器模式实现了与多种 大模型API 服务的集…

[权限提升] 操作系统权限介绍

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 权限提升简称提权&#xff0c;顾名思义就是提升自己在目标系统中的权限。现在的操作系统都是多用户操作系统&#xff0c;用户之间都有权限控制&#xff0c;我们通过 Web 漏洞拿到的 Web 进程的…

多模态论文笔记——ViViT

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细解读多模态论文《ViViT: A Video Vision Transformer》&#xff0c;2021由google 提出用于视频处理的视觉 Transformer 模型&#xff0c;在视频多模态领域有…

【深度之眼cs231n第七期】笔记(三十一)

目录 强化学习什么是强化学习&#xff1f;马尔可夫决策过程&#xff08;MDP&#xff09;Q-learning策略梯度SOTA深度强化学习 还剩一点小尾巴&#xff0c;还是把它写完吧。&#xff08;距离我写下前面那行字又过了好几个月了【咸鱼本鱼】&#xff09;&#xff08;汗颜&#xff…

[免费]基于Python的Django博客系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的基于Python的Django博客系统&#xff0c;分享下哈。 项目视频演示 【免费】基于Python的Django博客系统 Python毕业设计_哔哩哔哩_bilibili 项目介绍 随着互联网技术的飞速发展&#xff0c;信息的传播与…

【Docker】Docker入门了解

文章目录 Docker 的核心概念Docker 常用命令示例&#xff1a;构建一个简单的 C 应用容器1. 创建 C 应用2. 创建 Dockerfile3. 构建镜像4. 运行容器 Docker 优势学习 Docker 的下一步 **一、Docker 是什么&#xff1f;****为什么 C 开发者需要 Docker&#xff1f;** **二、核心概…

如何跨互联网adb连接到远程手机-蓝牙电话集中维护

如何跨互联网adb连接到远程手机-蓝牙电话集中维护 --ADB连接专题 一、前言 随便找一个手机&#xff0c;安装一个App并简单设置一下&#xff0c;就可以跨互联网的ADB连接到这个手机&#xff0c;从而远程操控这个手机做各种操作。你敢相信吗&#xff1f;而这正是本篇想要描述的…

基于java线程池和EasyExcel实现数据异步导入

基于java线程池和EasyExcel实现数据异步导入 2.代码实现 2.1 controller层 PostMapping("import")public void importExcel(MultipartFile file) throws IOException {importService.importExcelAsync(file);}2.2 service层 Resource private SalariesListener sa…

linux asio网络编程理论及实现

最近在B站看了恋恋风辰大佬的asio网络编程&#xff0c;质量非常高。在本章中将对ASIO异步网络编程的整体及一些实现细节进行完整的梳理&#xff0c;用于复习与分享。大佬的博客&#xff1a;恋恋风辰官方博客 Preactor/Reactor模式 在网络编程中&#xff0c;通常根据事件处理的触…

Python爬虫学习第三弹 —— Xpath 页面解析 实现无广百·度

早上好啊&#xff0c;大佬们。上回使用 Beautiful Soup 进行页面解析的内容是不是已经理解得十分透彻了~ 这回我们再来尝试使用另外一种页面解析&#xff0c;来重构上一期里写的那些代码。 讲完Xpath之后&#xff0c;小白兔会带大家解决上期里百度搜索的代码编写&#xff0c;保…

docker安装MySQL8:docker离线安装MySQL、docker在线安装MySQL、MySQL镜像下载、MySQL配置、MySQL命令

一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull mysql:8.0.41 2、离线包下载 两种方式&#xff1a; 方式一&#xff1a; -&#xff09;在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -&#xff09;导出 # 导出镜…

特权模式docker逃逸

目录 1.环境 2.上线哥斯拉 3.特权模式逃逸 1.判断是否为docker环境 2.判断是否为特权模式 3.挂载宿主机磁盘到docker 4.计划任务反弹shell 1.环境 ubuntu部署一个存在CVE-2017-12615的docker: (ip:192.168.117.147) kali(ip:192.168.117.128) 哥斯拉 2.上线哥斯拉…

Direct2D 极速教程(1) —— 画图形

极速导航 Direct2D 简介创建新项目&#xff1a;001-DrawGraphics弄一个白窗口在窗口上画图 Direct2D 简介 大家在学 WINAPI 的时候的时候有没有想过&#xff0c;怎么在一副窗口上画图呢&#xff1f;大家知道 Windows 系统是 GUI 图形用户界面 系统&#xff0c;以 Graphics 图形…

(长期更新)《零基础入门 ArcGIS(ArcScene) 》实验七----城市三维建模与分析(超超超详细!!!)

城市三维建模与分析 三维城市模型已经成为一种非常普遍的地理空间数据资源,成为城市的必需品,对城市能化管理至关重要。语义信息丰富的三维城市模型可以有效实现不同领域数据与IS相信息的高层次集成及互操作,从而在城市规划、环境模拟、应急响应和辅助决策等众多领域公挥作用、…