用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。 • 处理玩家的移动操作(上、下、左、…...
【设计模式-行为型】状态模式
一、什么是状态模式 什么是状态模式呢,这里我举一个例子来说明,在自动挡汽车中,挡位的切换是根据驾驶条件(如车速、油门踏板位置、刹车状态等)自动完成的。这种自动切换挡位的过程可以很好地用状态模式来描述。状态模式…...
CentOS/Linux Python 2.7 离线安装 Requests 库解决离线安装问题。
root@mwcollector1 externalscripts]# cat /etc/os-release NAME=“Kylin Linux Advanced Server” VERSION=“V10 (Sword)” ID=“kylin” VERSION_ID=“V10” PRETTY_NAME=“Kylin Linux Advanced Server V10 (Sword)” ANSI_COLOR=“0;31” 这是我系统的版本,由于是公司内网…...
【flutter版本升级】【Nativeshell适配】nativeshell需要做哪些更改
flutter 从3.13.9 升级:3.27.2 nativeshell组合库中的 1、nativeshell_build库替换为github上的最新代码 可以解决两个问题: 一个是arg("--ExtraFrontEndOptions--no-sound-null-safety") 在新版flutter中这个构建参数不支持了导致的build错误…...
使用 Vue 3 的 watchEffect 和 watch 进行响应式监视
Vue 3 的 Composition API 引入了 <script setup> 语法,这是一种更简洁、更直观的方式来编写组件逻辑。结合 watchEffect 和 watch,我们可以轻松地监视响应式数据的变化。本文将介绍如何使用 <script setup> 语法结合 watchEffect 和 watch&…...
使用shell命令安装virtualbox的虚拟机并导出到vagrant的Box
0. 安装virtualbox and vagrant [rootolx79vagrant ~]# cat /etc/resolv.conf #search 114.114.114.114 nameserver 180.76.76.76-- install VirtualBox yum install oraclelinux-developer-release-* wget https://yum.oracle.com/RPM-GPG-KEY-oracle-ol7 -O /etc/pki/rpm-g…...
MySQL 基础学习(3):排序查询和条件查询
MySQL 查询与条件操作:详解与技巧 在本文中,我们将探讨 MySQL 中的查询操作及其相关功能,包括别名、去重、排序查询和条件查询等,并总结一些最佳实践和注意事项。 一、使用别名(AS) 在查询中,…...
2025数学建模美赛|赛题翻译|E题
2025数学建模美赛,E题赛题翻译 更多美赛内容持续更新中......
solidity高阶 -- 继承
Solidity是一种面向区块链的智能合约编程语言,广泛应用于以太坊等区块链平台。继承是Solidity中一个非常重要的特性,它允许开发者通过创建子合约来扩展父合约的功能,从而实现代码的复用和层次化设计。本文将通过具体实例详细介绍Solidity语言…...
SpringBoot统一数据返回格式 统一异常处理
统一数据返回格式 & 统一异常处理 1. 统一数据返回格式1.1 快速入门1.2 存在问题1.3 案列代码修改1.4 优点 2. 统一异常处理 1. 统一数据返回格式 强制登录案例中,我们共做了两部分⼯作 通过Session来判断⽤⼾是否登录对后端返回数据进⾏封装,告知前端处理的结果 回顾 后…...
C语言学习强化
前言 数据的逻辑结构包括: 常见数据结构: 线性结构:数组、链表、队列、栈 树形结构:树、堆 图形结构:图 一、链表 链表是物理位置不连续,逻辑位置连续 链表的特点: 1.链表没有固定的长度…...
反馈驱动、上下文学习、多语言检索增强等 | Big Model Weekly 第55期
点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 01 A Bayesian Approach to Harnessing the Power of LLMs in Authorship Attribution 传统方法严重依赖手动特征,无法捕捉长距离相关性,限制了其有效性。最近的研究利用预训练语言模型的…...
Redis 详解
简介 Redis 的全称是 Remote Dictionary Server,它是一个基于内存的 NoSQL(非关系型)数据库,数据以 键值对 存储,支持各种复杂的数据结构 为什么会出现 Redis? Redis 的出现是为了弥补传统数据库在高性能…...
git reset (取消暂存,保留工作区修改)
出现这种情况的背景:我不小心把node_modules文件添加到暂存区了,由于文件过大,导致不能提交,所以我想恢复之前的状态,但又不想把修改的代码恢复为之前的状态,所以使用这个命令可以只恢复暂存区的状态&#…...
C++ 自定义字面量
在C11中,用户自定义字面量(User-Defined Literals)为程序员提供了前所未有的灵活性和便利性,它允许我们根据自己的需求定义字面量,从而使代码更加直观、易读且富有表现力。 什么是用户定义字面量? 在C中&…...
2024年面对不确定性
24年处在了十字路口,面对工作、家庭、生活的责任,一切变得不确定了,量子力学给了我们新的认识世界的角度,不确定性才是这个世界的底色,我们怎么选择? 不停的思考 霍金在大设计书中给出了深刻的哲学思想&a…...
Coze插件开发之基于已有服务创建并上架到扣子商店
Coze插件开发之基于已有服务创建并上架到扣子商店 在应用开发中,需要调用各种插件,以快速进行开发。但有时需要调用的插件在扣子商店里没有,那怎么办呢? 今天就来带大家快速基于已有服务创建一个新的插件 简单来讲,就是…...
Oracle 创建用户和表空间
Oracle 创建用户和表空间 使用sys 账户登录 建立临时表空间 --建立临时表空间 CREATE TEMPORARY TABLESPACE TEMP_POS --创建名为TEMP_POS的临时表空间 TEMPFILE /oracle/oradata/POS/TEMP_POS.DBF -- 临时文件 SIZE 50M -- 其初始大小为50M AUTOEXTEND ON -- 支持…...
企业微信开发009_使用WxJava企业微信开发框架_封装第三方应用企业微信开发002_并且实现多企业授权访问---企业微信开发011
继续接上一节来贴代码: 接下来看 config部分的代码,这部分代码,系统启动的时候,就会执行,从而把配置的一些,配置读取出来,创建,针对每个企业微信的,操作service. 首先看yml配置文件中配置部分: 可以先看一下demo中: 提供了一个配置的示例,当然这个是针对 企业内部自建应用 …...
机器学习 - 初学者需要弄懂的一些线性代数的概念
一、单位矩阵 在数学中,单位矩阵是一个方阵,其主对角线上的元素全为1,其余元素全为0。单位矩阵在矩阵乘法中起到类似于数字1在数值乘法中的作用,即任何矩阵与单位矩阵相乘,结果仍为原矩阵本身。 单位矩阵的定义&…...
【学术会议-第五届机械设计与仿真国际学术会议(MDS 2025) 】前端开发:技术与艺术的完美融合
重要信息 大会官网:www.icmds.net 大会时间:2025年02月28日-03月02日 大会地点:中国-大连 会议简介 2025年第五届机械设计与仿真国际学术会议(MDS 2025) 将于2025年02月28-3月02日在中国大连召开。MDS 2025将围绕“机械设计”…...
RabbitMQ 分布式高可用
文章目录 前言一、持久化与内存管理1、持久化机制2、内存控制1、命令行2、配置文件 3、内存换页4、磁盘控制 二、集群1、Erlang的分布式特性2、RabbitMQ的节点类型2.1、磁盘节点 (Disk Node)2.2、内存节点 (RAM Node) 3、构建集群3.1 普通集群3.2 镜像队列3.3、高可用实现方案3…...
海康工业相机 SDK对接 Hikvision
有C#基础的,可以参考下,直接上代码 BaseResult 来自于Nuget包,搜Rotion可以搜出来 LS.Standard.Data 海康的接口操作,要先引用相应的dll using MvCamCtrl.NET; using PCZD.Commons.Data.CameraModel; using PCZD.Data; using Sys…...
开发技巧,vue 中的动态组件的引用 component + is
在项目中很多时候有切换 tab 的场景,一般来说都是用 v-if 或者 v-show 然后根据各种条件来控制显示隐藏。 其实我们可以使用 vue 中的动态组件,也能实现这个效果 <!-- currentTab 改变时组件也改变 --> <component :is"currentTab"…...
MySQL 二进制安装(正式篇)
Author:Arsen Date:2025/01/24 官方参考文档:点击链接跳转 目录 规划下载安装管理FAQ 规划 OSMySQL Server Version备注CentOS 7.9 or Linux - Generic8.0.33(GNU libc) 2.17 下载 二进制包下载地址:https://downloads.mysql.…...
MongoDB 数据库备份和恢复全攻略
在当今数据驱动的时代,数据库的稳定运行和数据安全至关重要。MongoDB 作为一款流行的 NoSQL 数据库,以其灵活的文档模型和高扩展性备受青睐。然而,无论数据库多么强大,数据丢失的风险始终存在,因此掌握 MongoDB 的备份…...
K8S部署DevOps自动化运维平台
持续集成(CI) 持续集成强调开发人员提交了新代码之后,立刻自动的进行构建、(单元)测试。根据测试结果,我 们可以确定新代码和原有代码能否正确地集成在一起。持续集成过程中很重视自动化测试验证结果&#…...
工业相机 SDK 二次开发-Sherlock插件
本文介绍了 sherlock 连接相机时的插件使用。通过本套插件可连接海康的工业相机。 一.环境配置 1. 拷贝动态库 在用户安装 MVS 目录下按照如下路径 Development\ThirdPartyPlatformAdapter 找到目 录为 DalsaSherlock 的文件夹,根据 Sherlock 版本找到…...
分布式版本控制系统:Git
1 Git概述 Git官网:https://git-scm.com/ Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目Git易于学习,占地面积小,性能极快。它具有廉价的本地库、方便的暂存区域和多个工作流分支等特性…...
页高速缓存与缓冲区缓存的应用差异
页高速缓存(Page Cache)与缓冲区缓存(Buffer Cache)是计算机系统中用于提高数据访问性能的两种不同类型的缓存机制,它们的差异主要体现在以下几个方面: 缓存目的 页高速缓存:主要用于加速对磁…...
