用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。
• 如果没有可移动的空位且无法合并,则游戏结束。
希望这个实现对你有帮助!
相关文章:
用C++编写一个2048的小游戏
以下是一个简单的2048游戏的实现。这个实现使用了控制台输入和输出,适合在终端或命令行环境中运行。 2048游戏的实现 1.游戏逻辑 2048游戏的核心逻辑包括: • 初始化一个4x4的网格。 • 随机生成2或4。 • 处理玩家的移动操作(上、下、左、…...
为何SAP S4系统中要设置MRP区域?MD04中可否同时显示工厂级、库存地点级的数据?
【SAP系统PP模块研究】 一、物料主数据的MRP区域设置 SAP ECC系统中想要指定不影响MRP运算的库存地点,是针对库存地点设置MRP标识,路径为:SPRO->生产->物料需求计划->计划->定义每一个工厂的存储地点MRP,如下图所示: 另外,在给物料主数据MMSC扩充库存地点时…...
Windows10官方系统下载与安装保姆级教程【U盘-官方ISO直装】
Windows 10 官方系统安装/重装 制作启动盘的U盘微软官网下载Win10安装包创建启动盘U盘 安装Win10 本文采用U盘安装Windows10官方系统。 制作启动盘的U盘 微软官网下载Win10安装包 微软官网下载Win10安装包链接:https://www.microsoft.com/zh-cn/software-downloa…...
第05章 07 切片图等值线代码一则
绘制脑部切面图的阈值等值线是一个常见的任务,通常涉及使用VTK(Visualization Toolkit)库来处理医学图像数据。以下是一个基于VTK/C的示例代码,展示如何读取脑部DICOM图像数据,应用阈值过滤器来提取特定组织的等值线&a…...
【深度学习】线性回归的简洁实现
线性回归的简洁实现 在过去的几年里,出于对深度学习强烈的兴趣,许多公司、学者和业余爱好者开发了各种成熟的开源框架。 这些框架可以自动化基于梯度的学习算法中重复性的工作。 目前,我们只会运用: (1)通…...
渗透测试技法之口令安全
一、口令安全威胁 口令泄露途径 代码与文件存储不当:在软件开发和系统维护过程中,开发者可能会将口令以明文形式存储在代码文件、配置文件或注释中。例如,在开源代码托管平台 GitHub 上,一些开发者由于疏忽,将包含数据…...
【R语言】数学运算
一、基础运算 R语言中能实现加、减、乘、除、求模、取整、取绝对值、指数、对数等运算。 x <- 2 y <- 10 # 求模 y %% x # 整除 y %/% x # 取绝对值 abs(-x) # 指数运算 y ^x y^1/x #对数运算 log(x) #log()函数默认情况下以 e 为底 双等号“”的作用等同于identical(…...
小游戏源码开发搭建技术栈和服务器配置流程
近些年各种场景小游戏开发搭建版本层出不穷,山东布谷科技拥有多年海内外小游戏源码开发经验,现为从事小游戏源码开发或游戏运营的朋友们详细介绍小游戏开发及服务器配置流程。 一、可以对接到app的小游戏是如何开发的 1、小游戏源码开发的需求分析: 明…...
深度学习|表示学习|卷积神经网络|输出维度公式|15
如是我闻: 在卷积和池化操作中,计算输出维度的公式是关键,它们分别可以帮助我们计算卷积操作和池化操作后的输出大小。下面分别总结公式,并结合解释它们的意义: 1. 卷积操作的输出维度公式 当我们对输入图像进行卷积时…...
cpp智能指针
普通指针的不足 new和new[]的内存需要用delete和deletel]释放。 程序员的主观失误,忘了或漏了释放。 程序员也不确定何时释放。 普通指针的释放 类内的指针,在析构函数中释放。 C内置数据类型,如何释放? new出来的类,本身如…...
【面试题】 Java 三年工作经验(2025)
问题列表 为什么选择 spring boot 框架,它与 Spring 有什么区别?spring mvc 的执行流程是什么?如何实现 spring 的 IOC 过程,会用到什么技术?spring boot 的自动化配置的原理是什么?如何理解 spring boot 中…...
MOS的体二极管能通多大电流
第一个问题:MOS导通之后电流方向可以使任意的,既可以从D到S,也可以从S到D。 第二个问题:MOS里面的体二极管电流可以达到几百安培,这也就解释了MOS选型的时候很少考虑体二极管的最大电流,而是考虑DS之间电流…...
Node.js下载安装及环境配置教程 (详细版)
Node.js:是一个基于 Chrome V8 引擎的 JavaScript 运行时,用于构建可扩展的网络应用程序。Node.js 使用事件驱动、非阻塞 I/O 模型,使其非常适合构建实时应用程序。 Node.js 提供了一种轻量、高效、可扩展的方式来构建网络应用程序࿰…...
嵌入式MCU面试笔记2
目录 串口通信 概论 原理 配置 HAL库代码 1. 初始化函数 2. 数据发送和接收函数 3. 中断和DMA函数 4. 中断服务函数 串口通信 概论 我们知道,通信桥接了两个设备之间的交流。一个经典的例子就是使用串口通信交换上位机和单片机之间的数据。 比较常见的串…...
代码随想录算法【Day34】
Day34 62.不同路径 思路 第一种:深搜 -> 超时 第二种:动态规划 第三种:数论 动态规划代码如下: class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n,…...
《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》重印P126、P131勘误
勘误:打圈的地方有指数二字。 指数滤波器本身是错误的概念,我在书上打了一个叉,排版人员误删了。 滤波器部分从根本上有问题,本来要改,但是时间不够了。 和廖老师讨论多次后,决定大动。指数滤波器的概念…...
vim多文件操作如何同屏开多个文件
[rootxxx ~]# vimdiff aa.txt bb.txt cc.txt #带颜色比较的纵向排列打开的同屏多文件操作 示例: [rootxxx ~]# vimdiff -o aa.txt bb.txt cc.txt #带颜色比较的横向排列打开的同屏多文件操作 示例: [rootxxx ~]# vim -O aa.txt bb.txt c…...
day6手机摄影社区,可以去苹果摄影社区学习拍摄技巧
逛自己手机的社区:即(手机牌子)摄影社区 拍照时防止抖动可以控制自己的呼吸,不要大喘气 拍一张照片后,如何简单的用手机修图? HDR模式就是让高光部分和阴影部分更协调(拍风紧时可以打开&…...
渗透测试之WAF规则触发绕过规则之规则库绕过方式
目录 Waf触发规则的绕过 特殊字符替换空格 实例 特殊字符拼接绕过waf Mysql 内置得方法 注释包含关键字 实例 Waf触发规则的绕过 特殊字符替换空格 用一些特殊字符代替空格,比如在mysql中%0a是换行,可以代替空格 这个方法也可以部分绕过最新版本的…...
C语言【基础篇】之流程控制——掌握三大结构的奥秘
流程控制 🚀前言🦜顺序结构💯 定义💯执行规则 🌟选择结构💯if语句💯switch语句💯case穿透规则 🤔循环结构💯for循环💯while循环💯do -…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...
