大大维的游戏机计划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 //列出某个用户 ...
随机推荐
- Scratch2.0例—接苹果
Scratch2.0例—接苹果 [教学目标] 1. 学习例子,能用和构造条件 ,并把此条件插入到 中:能理解和应用,当条件成立时,不执行积木内的脚本. 2. 对比和 两个积木:前者用于无条件的重复执行 ...
- The 2014 ACMICPC Asia Regional Guangzhou Online
[A]-_-/// [B]线段树+位运算(感觉可出) [C]地图BFS,找最长线 [D]地图BFS,加上各种复杂情况的最短路-_- [E]-_-/// [F]三分+圆与线段的交点,计算几何 [G]-_ ...
- CSS Font-family常用设置
font-family: "Avenir Next", Avenir, "Helvetica Neue", Helvetica, "Lantinghe ...
- Is it possible to run native sql with entity framework?
For .NET Framework version 4 and above: use ObjectContext.ExecuteStoreCommand() if your query return ...
- compass scss blueprint
[转载] 今天在执行compass create my-grid –using blueprint 命令时发现报错 google了一下,说是新版compass已经不包括compass-bluprint ...
- java中try 与catch的使用
(2011-10-08 17:08:43) 转载▼ 标签: 杂谈 分类: Java try{//代码区}catch(Exception e){//异常处理}代码区如果有错误,就会返回所写异常的处理. ...
- OPENCV直方图与匹配
直方图可以用来描述不同的参数和事物,如物体的色彩分布,物体的边缘梯度模版以及目标位置的当前假设的概率分布. 直方图就是对数据进行统计的一种方法,并且将统计值定义到一系列定义好的bin(组距)中,获得一 ...
- 用HTML 格式导出Excel
只需按照如下格式写就可,在<head> 里面嵌套table,必须修改html的命名空间,加上一些描述.保存为xls文件 <html xmlns:x="urn:schemas ...
- mysql表明保存不了,多了空格都不行啊
mysql表明保存不了,多了空格都不行啊
- 初步了解php,实现注册及登录
直接上图(数据库是用wamp实现的) 注册页 html 及 php 代码 登陆页 html 及 php 代码