大大维的游戏机计划3--2048v1
本文为大大维原创,最早于博客园发表,转载请注明出处!!!
前几天由于忙着过年串门,游戏机的计划搁置了几天。这两天终于空出了一块时间,抽空写了2048。
由于笔者前面自制了一个类似2048的游戏,所以写起来也算是轻车熟路,花了两个晚上也就差不多了。
废话少说,先将代码copy一份过来!
后续这几天,笔者想先写一个拼图小游戏,然后想办法将这几个游戏中共同存在的全屏刷新闪屏的问题给解决了。
另外,整个程序代码均为笔者原创,引用或转载请注明出处!
/**--------------------------------------------------------------**/
/**名称:大大维的2048v1 日期:2017/2/1**/
/**描述:简单地实现了2048的基本功能 **/
/**存在的问题:由于使用了全局刷新,游戏运行中会出现闪屏现象;
不能够存储玩家的游戏记录;由于不是图形化界面,用户界面较丑;
不能改变游戏的地图大小 **/
/**笔者会在后续版本逐步完善这些问题!!! **/
/**-------------------------------------------------------------**/
/**申明: 1.本程序由大大维独自编写,转载、引用请注明出处
2.本程序注释掉的部分,笔者认为理论上可以替代后续的代码,
但存在错误。笔者未发现错误原因,如有高手发现,请联系笔者
3.程序中若存在BUG请联系笔者
4.笔者联系方式 1329423134@qq.com **/
/**-------------------------------------------------------------**/
#include<iostream>
#include<string>
#include<vector>
#include<ctime>
#include<cstdlib>
#include<conio.h>
using namespace std;
constexpr unsigned HIGH=;
constexpr unsigned LENG=;
///当前地图状态:READY,即(),可以进行moveAndAddData()操作;WAIT,即[],可以进行chooseMapSpace()操作
enum state {READY,WAIT};
///当前操作块的移动方向:UP,上;DOWN,下;LEFT,左;RIGHT,右;DEFAULT,其他
enum dir {UP,DOWN,LEFT,RIGHT,DEFAULT};
class Map2048
{
public:
Map2048();///构造函数,初始化数据
void moveAndAddData();///移动和相加选中块的数据
///地图压缩
void mapSortToUp();
void mapSortToDown();
void mapSortToLeft();
void mapSortToRight();
void dataCreate(unsigned persentOf2);///生成新data
bool isLive();///是否存活判断
void printMap();///地图打印
dir setDir();///输入操作块的移动方向
string dataToPrintData(int n);///data到printData的转换函数
unsigned getScore();
private:
unsigned data[HIGH][LENG];///设要显示数据为x,data=log2(x),空白时,data=0
string printData[HIGH][LENG];///存储规范化的输出数据
unsigned score;
}; Map2048::Map2048()
{
for(int i=; i<HIGH; i++)
for(int j=; j<LENG; j++)
{
data[i][j]=;
}
for(int i=; i<HIGH; i++)
for(int j=; j<LENG; j++)
printData[i][j]=dataToPrintData(data[i][j]);
bool initFlag=true;
while(initFlag)
{
srand((unsigned)time(NULL));
int x1=rand()%HIGH,y1=rand()%LENG,x2=rand()%HIGH,y2=rand()%LENG;
if(x1!=x2&&y1!=y2)
{
initFlag=false;
data[x1][y1]=data[x2][y2]=;
printData[x1][y1]=dataToPrintData(data[x1][y1]);
printData[x2][y2]=dataToPrintData(data[x2][y2]);
}
}
score=;
} void Map2048::moveAndAddData()
{
dir DIR=setDir();
switch(DIR)
{
case UP:
{
mapSortToUp();
for(int n=; n<LENG; n++)
for(int m=; m<HIGH; m++)
if(data[m][n]==data[m-][n])
{
data[m-][n]*=;
data[m][n]=;
printData[m-][n]=dataToPrintData(data[m-][n]);
printData[m][n]=dataToPrintData(data[m][n]);
score+=data[m-][n];
}
mapSortToUp();
break;
}
case DOWN:
{
mapSortToDown();
for(int n=; n<LENG; n++)
for(int m=HIGH-; m>=; m--)
if(data[m][n]==data[m+][n])
{
data[m+][n]*=;
data[m][n]=;
printData[m+][n]=dataToPrintData(data[m+][n]);
printData[m][n]=dataToPrintData(data[m][n]);
score+=data[m+][n];
}
mapSortToDown();
break;
}
case LEFT:
{
mapSortToLeft();
for(int m=; m<HIGH; m++)
for(int n=; n<LENG; n++)
if(data[m][n]==data[m][n-])
{
data[m][n-]*=;
data[m][n]=;
printData[m][n-]=dataToPrintData(data[m][n-]);
printData[m][n]=dataToPrintData(data[m][n]);
score+=data[m][n-];
}
mapSortToLeft();
break;
}
case RIGHT:
{
mapSortToRight();
for(int m=; m<HIGH; m++)
for(int n=LENG-; n>=; n--)
if(data[m][n]==data[m][n+])
{
data[m][n+]*=;
data[m][n]=;
printData[m][n+]=dataToPrintData(data[m][n+]);
printData[m][n]=dataToPrintData(data[m][n]);
score+=data[m][n+];
}
mapSortToRight();
break;
}
case DEFAULT:
break;
}
} void Map2048::mapSortToUp()///地图向上压缩
{
for(int n=; n<LENG; n++)
for(int m=; m<HIGH; m++)
if(data[m][n]==)
for(int k=m; k<HIGH; k++)
if(data[k][n]!=)
{
data[m][n]=data[k][n];
data[k][n]=;
printData[m][n]=dataToPrintData(data[m][n]);
printData[k][n]=dataToPrintData(data[k][n]);
break;
}
} void Map2048::mapSortToDown()///地图向下压缩
{
for(int n=LENG-; n>=; n--)
for(int m=HIGH-; m>=; m--)
if(data[m][n]==)
for(int k=m; k>=; k--)
if(data[k][n]!=)
{
data[m][n]=data[k][n];
data[k][n]=;
printData[m][n]=dataToPrintData(data[m][n]);
printData[k][n]=dataToPrintData(data[k][n]);
break;
}
} void Map2048::mapSortToLeft()///地图向左压缩
{
for(int m=; m<HIGH; m++)
for(int n=; n<LENG; n++)
if(data[m][n]==)
for(int k=n; k<LENG; k++)
if(data[m][k]!=)
{
data[m][n]=data[m][k];
data[m][k]=;
printData[m][n]=dataToPrintData(data[m][n]);
printData[m][k]=dataToPrintData(data[m][k]);
break;
}
} void Map2048::mapSortToRight()///地图向右压缩
{
for(int m=HIGH-; m>=; m--)
for(int n=LENG-; n>=; n--)
if(data[m][n]==)
for(int k=n; k>=; k--)
if(data[m][k]!=)
{
data[m][n]=data[m][k];
data[m][k]=;
printData[m][n]=dataToPrintData(data[m][n]);
printData[m][k]=dataToPrintData(data[m][k]);
break;
}
} void Map2048::dataCreate(unsigned persentOf2)
{
vector<int> dataVecX;///加入一个矢量,记录空位置的x坐标
vector<int> dataVecY;///加入一个矢量,记录空位置的y坐标
for(int i=; i<HIGH; i++)
for(int j=; j<LENG; j++)
{
if(data[i][j]==)
{
dataVecX.push_back(i);
dataVecY.push_back(j);
}
}
if(!dataVecX.empty())
{
srand((unsigned)time(NULL));
auto k=rand()%dataVecX.size();///在空位中随机选择一个位置
if(rand()%<persentOf2)///根据2,4生成的比例随机生成新数据
data[dataVecX[k]][dataVecY[k]]=;
else
data[dataVecX[k]][dataVecY[k]]=;
printData[dataVecX[k]][dataVecY[k]]=dataToPrintData(data[dataVecX[k]][dataVecY[k]]);
}
} bool Map2048::isLive()
{
bool liveFlag=false;
for(int m=; m<HIGH; m++) ///确保没有空位置
for(int n=; n<LENG; n++)
if(data[m][n]==)
{
liveFlag=true;
return liveFlag;
}
// ///以下代码基于如下数学关系:反复使用向右,向下查询
// ///(最右行只向下,最底行只向右),可以遍历检查一遍元素自身是否与邻居相等
// for(int i=0; i<HIGH; i++)
// {
// for(int j=0; j<LENG; j++)
// {
// if(i!=HIGH-1&&j!=LENG-1)///非最右且非最下节点
// {
// if(data[i][j]==data[i][j+1]||data[i][j]==data[i+1][j])///向右,向下比较
// {
// liveFlag=true;
// return liveFlag;
// }
// }
// else if(i==HIGH-1&&j!=LENG-1)///非最右但是最下节点
// {
// if(data[i][j]=data[i][j+1])///向右比较
// {
// liveFlag=true;
// return liveFlag;
// }
// }
// else if(i!=HIGH-1&&j==LENG-1)///非最下但是最右节点
// {
// if(data[i][j]=data[i+1][j])///向下比较
// {
// liveFlag=true;
// return liveFlag;
// }
// }
// else///末尾节点,即最下且最右节点,无须比较,直接返回标志
// return liveFlag;
// }
// }
for(int m=; m<HIGH; m++) ///确保没有空位置
for(int n=; n<LENG; n++)
{
if((m==)&&(n==))
{
if(data[m][n]==data[m+][n]||data[m][n]==data[m][n+])
{
liveFlag=true;
return liveFlag;
}
}
else if((m==HIGH-)&&(n==LENG-))
{
if(data[m][n]==data[m-][n]||data[m][n]==data[m][n-])
{
liveFlag=true;
return liveFlag;
}
}
else if((m==)&&(n==LENG-))
{
if(data[m][n]==data[m+][n]||data[m][n]==data[m][n-])
{
liveFlag=true;
return liveFlag;
}
}
else if((m==HIGH-)&&(n==))
{
if(data[m][n]==data[m-][n]||data[m][n]==data[m][n+])
{
liveFlag=true;
return liveFlag;
}
}
else if((m==)&&(n!=)&&(n!=LENG-))
{
if(data[m][n]==data[m+][n]||data[m][n]==data[m][n-]||data[m][n]==data[m][n+])
{
liveFlag=true;
return liveFlag;
}
}
else if((m=HIGH-)&&(n!=)&&(n!=LENG-))
{
if(data[m][n]==data[m-][n]||data[m][n]==data[m][n-]||data[m][n]==data[m][n+])
{
liveFlag=true;
return liveFlag;
}
}
else if((n==)&&(m!=)&&(m!=HIGH-))
{
if(data[m][n]==data[m+][n]||data[m][n]==data[m-][n]||data[m][n]==data[m][n+])
{
liveFlag=true;
return liveFlag;
}
}
else if((n==LENG-)&&(m!=)&&(m!=HIGH-))
{
if(data[m][n]==data[m+][n]||data[m][n]==data[m-][n]||data[m][n]==data[m][n-])
{
liveFlag=true;
return liveFlag;
}
}
else
{
if(data[m][n]==data[m+][n]||data[m][n]==data[m-][n]||data[m][n]==data[m][n-]||data[m][n]==data[m][n+])
{
liveFlag=true;
return liveFlag;
}
}
}
} void Map2048::printMap()
{
cout<<" 2 0 4 8"<<endl;
cout<<"---------------------------------------------"<<endl;
for(int i=; i<HIGH; i++)
{
for(int j=; j<LENG; j++)
{
if(data[i][j]!=)
cout<<"| "<<printData[i][j]<<" ";
else
cout<<"| "<<" "<<" ";
}
cout<<"|"<<endl;
cout<<"---------------------------------------------"<<endl;
}
cout<<"SCORE= "<<score;
} dir Map2048::setDir()
{
char keydown=getch();///读取按键
switch(keydown)
{
case 'w':
return UP;
break;
case 'W':
return UP;
break;
case 's':
return DOWN;
break;
case 'S':
return DOWN;
break;
case 'a':
return LEFT;
break;
case 'A':
return LEFT;
break;
case 'd':
return RIGHT;
break;
case 'D':
return RIGHT;
break;
default:
return DEFAULT;
break;
}
} string Map2048::dataToPrintData(int m)
{ int count=;
///str的初始化基于如下数学关系:4*4的地图下,2048游戏能合成数,理论上最大值131072(2^17),即data最大为17
string str {m/+,(m/)%+,(m/)%+,(m/)%+,(m/)%+,m%+};
///对冗余0的处理
for(int i=; i<; i++)
{
if(str[i]=='')
{
count++;
str[i]=' ';
}
else
break;
}
switch(count)///格式调整
{
case :///不加break会在执行完第一条语句后自动执行break
{
str[]=str[];
str[]=str[];
str[]=str[];
str[]=str[];
str[]=' ';
break;
}
case :
{
str[]=str[];
str[]=str[];
str[]=str[];
str[]=' ';
break;
}
case :
{
str[]=str[];
str[]=str[];
str[]=' ';
str[]=' ';
break;
}
case :
{
str[]=str[];
str[]=' ';
break;
}
}
return str;
} unsigned Map2048::getScore()
{
return score;
} int main()
{
Map2048 map;
bool gameOverFlag=false;
map.printMap();
while(!gameOverFlag)
{
while(kbhit())
{
system("cls");
map.moveAndAddData();
map.dataCreate();///以50%为2,50%为4的规则生成新数据
map.printMap();
if(!map.isLive())
gameOverFlag=true;
}
}
cout<<endl<<"GAME OVER"<<endl;
cout<<"The Final Score Is: "<<map.getScore()<<endl;
getch();
}
老规矩,上几张游戏截图:(在codeblocks下编译)





大大维的游戏机计划3--2048v1的更多相关文章
- 大大维的游戏机计划1--贪吃蛇v1
本文为大大维原创,最早于博客园发表,转载请注明出处!!! 虽然本人一直是个免费的游戏测试员(/手动滑稽),但一直有着一个游戏架构师的梦想.正如马爸爸所说,梦想还是要有的,万一实现了呢? 这些天放寒假, ...
- 图扑软件正式加入腾讯智维生态发展计划,智能 IDC 开启数字经济新征程
4 月 23 日,主题为<智汇科技,维新至善>的腾讯数据中心智维技术研讨会在深圳胜利召开,发布了腾讯智维 2.0 技术体系,深度揭秘了智维 2.0 新产品战略和技术规划.图扑软件(High ...
- BOS物流管理系统-第一天
BOS物流管理系统-第一天-系统分析.环境搭建.前端框架 BoBo老师 整体项目内容目标: 对项目概述的一些理解 亮点技术的学习 注意学习方式:优先完成当天代码. 其他内容. 最终: 学到新的技术,会 ...
- Web 应用架构基础课(转载)
Web 应用架构基础课 初级 web 应用开发者必学的基础网络架构概念 web 应用主流架构概览 上图便是我司(Storyblocks)网络架构的很好展现.如果你还没成为经验老道的 web 工程师,可 ...
- [转][darkbaby]任天堂传——失落的泰坦王朝(上)
前言: 曾经一再的询问自我;是否真的完全了解任天堂这个游戏老铺的真实本质?或许从来就没有人能够了解,世间已经有太多的真相被埋没在谎言和臆测之中.作为 一个十多年游龄的老玩家,亲眼目睹了任天堂从如日 ...
- MySQL自动化运维之用mysqldump和mysqlbinlog实现某一数据库的每周全备和每天差异备份,并添加到执行计划【热备】
案例: 线上有一数据库,需要每周全备一次,每天差备一次[安全起见还是差备吧,不要增备,不要吝啬磁盘哦,而且差备恢复还很快] 1.每周对数据库hellodb做完全备份 crontab任务计划: * * ...
- vijos1334 NASA的食物计划(二维费用的背包问题)
背景 NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安 全技术问题一直大伤脑筋,因此在各方压力下终止了航天 飞机的历史,但是此类事情会不会在以后发生,谁也无法 保证,在遇到这类航天问题时,解决方 ...
- 洛谷 P1507 NASA的食物计划 【二维费用背包】 || 【DFS】
题目链接:https://www.luogu.org/problemnew/show/P1507 题目背景 NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安全技术问题一直大伤脑筋,因此在各方压力 ...
- Linux 的计划任务(运维基础|可用于提权)
Linux操作系统定时任务系统 Cron 入门 先写笔记: crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数 crontab -l //列出某个用户 ...
随机推荐
- (转)java 从jar包中读取资源文件
(转)java 从jar包中读取资源文件 博客分类: java 源自:http://blog.csdn.net/b_h_l/article/details/7767829 在代码中读取一些资源文件 ...
- 跳舞链 Dancing Links
作为搜索里面的一个大头,终于刷了一部分题目了,跳舞链一般都有现成的模板来套...... 至于跳舞链的学习的话,我觉得http://www.cnblogs.com/grenet/p/3163550.ht ...
- hibernate---一级缓存, 二级缓存, 查询缓存
缓存: 内存开辟一块空间,把本来存在硬盘的东西放在内存里, 以后从内存读取. 一级缓存: session级别的缓存, session.load 二级缓存: 总的缓存.
- MFC中PeekMessage的使用,非阻塞消息循环
在程序设计的时候经常要进行一个数据循环,比如播放音乐需要循环的向缓冲区里面写入数据,在这个时候比较通用的方法是建立一个线程做事情,但是有时候不想创建多线程就可以使用微软提供的PeekMessage方法 ...
- Seajs是什么及其优缺点&如何使用?
这篇文章主要介绍了Seajs的相关知识和和学习心得,适合刚接触SeaJS的同学,需要的朋友可以参考下,有更好的新手教程或文档,欢迎推荐.分享! 1.Seajs简介 Seajs,一个Web模块加载框 ...
- label中添加图片
创建NSTextAttachment的对象,用来装在图片 将NSTextAttachment对象的image属性设置为想要使用的图片 设置NSTextAttachment对象bounds大小,也就是要 ...
- storybody中页面跳转
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if ([segue.destinationViewCont ...
- Java中的Runtime类
Runtime类描述了虚拟机一些信息.该类采用了单例设计模式,可以通过静态方法 getRuntime()获取Runtime类实例.下面演示了获取虚拟机的内存信息: package Main; publ ...
- 菊花加载第三方--MBprogressHUD 分类: ios技术 2015-02-05 19:21 120人阅读 评论(0) 收藏
上次说到了网络请求AFN,那么我们在网络请求的时候,等待期间,为了让用户不认为是卡死或程序出错,一般都会放一个菊花加载,系统有一个菊花加载类叫UIProgressHUD.但是我今天要说的是一个替代它的 ...
- PHPCMS快速建站系列之自定义分页函数
内容分页的实现方法:{pc:content action="lists" catid="$catid" order="id DESC" nu ...