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

前几天由于忙着过年串门,游戏机的计划搁置了几天。这两天终于空出了一块时间,抽空写了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. iframe载入等待

    <style> #pageloading{position:absolute; left:0px; top:0px;background:white url('../images/load ...

  2. Extjs4中的常用组件:Grid、Tree和Form

    至此我们已经学习了Data包和布局等API.下面我们来学习作为Extjs框架中我们用得最多的用来展现数据的Grid.Tree和Form吧! 目录: 5.1. Grid panel 5.1.1. Col ...

  3. linux分区-df

    转自:http://baike.baidu.com/link?url=tyonI3NCB3F-ytIQz72PY-8uAaUQgfFFXbyKAea1e2NiB_t5AsE0MLOLc2LcqOiS ...

  4. ucos系统初始化及启动过程

    之前在ucos多任务切换中漏掉了一个变量, OSCtxSwCtr标识系统任务切换次数 主要应该还是用在调试功能中 Ucos系统初始化函数为OSInit(),主要完成以下功能 全局变量初始化 就绪任务表 ...

  5. IOS开发之IOS8.0最新UIAlertController 分类: ios技术 2015-01-20 14:24 144人阅读 评论(1) 收藏

    最近苹果更新的IOS8 对以前进行了很大的修改, 更新的API也让人捉急,据说iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.比如全新的UIPrese ...

  6. 【转】Linux正则表达式使用指南

    正则表达式是一种符号表示法,用于识别文本模式.Linux处理正则表达式的主要程序是grep.grep搜索与正则表达式匹配的行,并将结果输送至标准输出. 1. grep匹配模式 grep按下述方式接受选 ...

  7. 一个php开发的用于路由器的小功能

    最近接到一个需求,假设有A.B.C 三台主机.现A主机要访问C主机上的一个脚本,并且根据A传递的参数给C主机,同时接受C主机返回来的数据.但是现在A主机不能直接通过url.IP访问C主机,需要借由主机 ...

  8. Thinking in scala (7)---- f(n)=f(n-1)+2f(n-2)+3f(n-3)

    <计算机程序的构造和解释>中的练习1.11: 函数f,如果n<3,那么f(n) = n;如果n>=3,那么 f(n)=f(n-1)+2f(n-2)+3f(n-3) 有了上面的公 ...

  9. List学习笔记

    List 特点:1.有序.2.可重复. ArrayList: 底层是数组,数组是有下标的. 会自动扩容,底层默认初始化容量是10,扩大之后的容量预设是原来容量的一半(jdk 1.8).以前好像是原容量 ...

  10. java系列-JDBC的封装

    参考:http://blog.csdn.net/liuhenghui5201/article/details/16369773 一. 1.加载驱动-->>封装    --->> ...