本文为大大维原创,最早于博客园发表,转载请注明出处!!!

前几天由于忙着过年串门,游戏机的计划搁置了几天。这两天终于空出了一块时间,抽空写了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. 大大维的游戏机计划1--贪吃蛇v1

    本文为大大维原创,最早于博客园发表,转载请注明出处!!! 虽然本人一直是个免费的游戏测试员(/手动滑稽),但一直有着一个游戏架构师的梦想.正如马爸爸所说,梦想还是要有的,万一实现了呢? 这些天放寒假, ...

  2. 图扑软件正式加入腾讯智维生态发展计划,智能 IDC 开启数字经济新征程

    4 月 23 日,主题为<智汇科技,维新至善>的腾讯数据中心智维技术研讨会在深圳胜利召开,发布了腾讯智维 2.0 技术体系,深度揭秘了智维 2.0 新产品战略和技术规划.图扑软件(High ...

  3. BOS物流管理系统-第一天

    BOS物流管理系统-第一天-系统分析.环境搭建.前端框架 BoBo老师 整体项目内容目标: 对项目概述的一些理解 亮点技术的学习 注意学习方式:优先完成当天代码. 其他内容. 最终: 学到新的技术,会 ...

  4. Web 应用架构基础课(转载)

    Web 应用架构基础课 初级 web 应用开发者必学的基础网络架构概念 web 应用主流架构概览 上图便是我司(Storyblocks)网络架构的很好展现.如果你还没成为经验老道的 web 工程师,可 ...

  5. [转][darkbaby]任天堂传——失落的泰坦王朝(上)

    前言:   曾经一再的询问自我;是否真的完全了解任天堂这个游戏老铺的真实本质?或许从来就没有人能够了解,世间已经有太多的真相被埋没在谎言和臆测之中.作为 一个十多年游龄的老玩家,亲眼目睹了任天堂从如日 ...

  6. MySQL自动化运维之用mysqldump和mysqlbinlog实现某一数据库的每周全备和每天差异备份,并添加到执行计划【热备】

    案例: 线上有一数据库,需要每周全备一次,每天差备一次[安全起见还是差备吧,不要增备,不要吝啬磁盘哦,而且差备恢复还很快] 1.每周对数据库hellodb做完全备份 crontab任务计划: * * ...

  7. vijos1334 NASA的食物计划(二维费用的背包问题)

    背景 NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安 全技术问题一直大伤脑筋,因此在各方压力下终止了航天 飞机的历史,但是此类事情会不会在以后发生,谁也无法 保证,在遇到这类航天问题时,解决方 ...

  8. 洛谷 P1507 NASA的食物计划 【二维费用背包】 || 【DFS】

    题目链接:https://www.luogu.org/problemnew/show/P1507 题目背景 NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安全技术问题一直大伤脑筋,因此在各方压力 ...

  9. Linux 的计划任务(运维基础|可用于提权)

    Linux操作系统定时任务系统 Cron 入门 先写笔记: crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数 crontab -l //列出某个用户 ...

随机推荐

  1. JUnit----单元测试

    为什么进行单元测试? 1. 重用测试, 应付将来实现的变化. 2. 明确指定我的东西是没问题的. Failure, error的区别? Failure只测试失败, Error指程序本身出错 1. ne ...

  2. AVR编程_如何通过软件复位AVR?(转)

    源:http://blog.sina.com.cn/s/blog_493520900100bpos.html Question 如何通过软件复位AVR? Answer 如果你想通过软件复位AVR,你应 ...

  3. Jquery 源码学习

    https://www.youtube.com/watch?v=qeMFEz_ufZc http://stackoverflow.com/questions/7194784/analysing-the ...

  4. Quick Cocos2dx Http通讯

    服务端:Python 通讯协议:Http 参考文章: 1 用python实现一个基本的http server服务器 http://blog.sina.com.cn/s/blog_416e3063010 ...

  5. CodeForces 621A Wet Shark and Odd and Even

    水题 #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #inclu ...

  6. centos7中yum安装ntfs-3g

    CentOS默认源里没有ntfs3g,想要添加ntfs支持,无非是自己下载编译安装或者加源yum安装. 新安装了一个CentOS7,用的是添加aliyun的epel源来yum安装的方式,简单易行. 1 ...

  7. leetcode--007 word break I

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+4AAAC5CAIAAAA55fI7AAAZa0lEQVR4nO3dPW7bQIMG4L2MT6B7+A

  8. jstree使用小结(三)

    操作节点的这几个事件都比较简单: 如下 var $tree=$('#tree1'); $tree.jstree({...}); //选中节点 $tree.on('select_node.jstree' ...

  9. EntityFrameWork分页

    EF分页代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using Sy ...

  10. windows下Nodejs环境部署

    前言 Nodejs是基于v8引擎的轻量级框架,其特点为事件驱动.非阻塞.单线程.异步回调等. Nodejs相对于其他运行在服务器端的语言,容易学习,使用方便. 本文将介绍windows下Nodejs的 ...