2048小游戏的玩法解析
2048有16个格子,玩法规则也非常的简单,一开始方格内会出现2或者4等这两个小数字,2出现的概率要大4,玩家只需要上下左右其中一个方向来移动出现的数字,所有的数字就会想滑动的方向靠拢,相同的数字相撞时会叠加靠拢并将原来的位置置空,而滑出的空白方块就会随机出现一个数字2/4,然后一直这样,不断的叠加,直到不能上下左右移动并且没有空位置或者四个方向没有相同的就说明用户输了。有些2048有些当玩出2048就算胜利,有的则不会胜利,直到玩死。如果你是一个数字爱好者,或者是比较有天赋的数学天才,就算不是数学天才,一般的玩家也能够玩转这款游戏,感兴趣的话就去下载体验一番! [2]
2048下游戏分析
2048游戏是个4*4的16个方格,所以我们首先要声明一个全局的二维数组变量map来表示4*4的方格和保存里面的数据以及和一个全局的int分数变量
int map[4][4]={0};//表示地图
int fen=0;//表示分数
1)当2048游戏打开,首先会产生一个2或者4,并且2的概率要大于4,所以第一步我们要写一个产生随机数的函数。
void sui();来产生一个2/4的数字
2)打印界面函数,根据map二维数组中的数字在窗口上画上对应的图片即可,或者如果认为画图片会影响效率也可以自己画一个黄色的矩形,并且在合适的位置上打印出数字,但是需要算坐标点,麻烦点,而且我认为并不比贴图片好多少。每张图片的大小为(100*100);













void show();//打印界面图片
3)接受用户的方向输入,可以使用ege的getch来接受用户的输入,并使用switch判断用户输入的方向是否为wasd,并调用相匹配的方向函数
void input();//接受用户的输入,判断调用户输入并调用相应的方向函数
4)2048的核心算法,以上为例,遍历map二维数组,因为向上所以第一行不用遍历也就是也就是从mao[1][0]开始遍历,然后将第一行挪到第0行,将第二行挪到第一行,将第三行挪到第二行。首先先判断当前坐标点是否为空,当前坐标为空时,不用动,继续遍历下一个点,当前点如果不为空,判断当前点的上一个坐标点是否为空,当上一个坐标是为空时,则直接将当前坐标点的值赋给上一行坐标点,并将当前坐标点置0,如果上一行坐标点不为空,则判断上一行的坐标点和当前行的坐标点是否相同,如果相同则直接让上一行坐标点乘等2,并蒋当前点坐标清空。以此遍历map二维数组即可得将所有的数字向上移动一行,将整个遍历的的双重for循环在运行三次即可达到我们的预期效果。当有一次移动是我们都要判断游戏是否结束,如果输了则提示是否重玩,没有结束则产生新的坐标点,并刷新地图也就是调用show函数
void up();//向上
void down();//向下
void left();//左
voidright();//右
5)判断游戏是否结束,1没有空位置,2四个方向没有相同的数子就说明用户输入了。遍历整个二维数组,判断是否为0,为0说明还有空位置,直接结束pan函数,返回true,当不为0时,则以当前点为准,找到周围四个点,并判断四个点是越界,越界则不用管,是否有空位置或者是否和当前点值相同。则说明有空位或者又可以移动的,游戏没有结束,则返回true,当整个遍历结束后,则说明没有空位并且没有左右上下相同的,游戏结束,返回flase结束
int pan(void);//判断游戏是否结束
核心算法和分析就这么多。以下为不完整代码,需要和之前的核心算法进行一一对比。
#include "graphics.h" // 就是需要引用这个图形库
#include <cstdlib>
#include <ctime>
#include <stdio.h>
int map[4][4]={0};//全局地图
int fen=0;//分数
void init(void);//初始化参数
void sui(void);//产生随机数
void show(void);//打印界面
void up(void);//向上
void down(void);//向下
void right(void);//向右
void left(void);//向左
void input(void); //用户输入
int pan(void);//判断游戏是否结束
int main() {
setinitmode(0);//广告页去掉//将
initgraph(400, 450); // 初始化,显示一个窗口,这里和 TC 略有区别
//setbkcolor(RED);
srand(time(0));
init();
input();
getch();
closegraph(); // 关闭图形界面
return 0;
}
void init(){
PIMAGE img = newimage();
getimage(img, "F:\\image\\bj.jpg");
putimage(0,0,img);
delimage(img);
sui();
sui();
show();
}
void sui(){
//判断是否有空位置
int i = 0;
int x=0,y=0;
for(x=0;x<4;x++){
for(y=0;y<4;y++){
if(map[x][y]==0){//有空位置,可以产生随机数
i++;
}
}
}
while(i){//当i为0时说明没有空位置,所以while循环不会执行
x=rand()%4;//产生X坐标,4X4所以范围控制0-3
y=rand()%4;
if(map[x][y]==0){//判断产生的坐标是否为空
map[x][y]=rand()%20==4?4:2;//伪概率产生4或者2
fen+=map[x][y];
break;
}
}
}
void show(){
xyprintf(0,400,"分数:%6d",fen);
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
char path[32]={0};
sprintf(path,"F:\\image\\%d.png",map[i][j]);
PIMAGE img = newimage();
getimage(img, path);
putimage_withalpha(NULL,img,j*100,i*100,0,0,100,100);
// delimage(img);
}
}
}
void input(){
while(1){
int k = getch();
switch(k){
case 'w':
up();
break;
case 's':
down();
break;
case 'a':
left();
break;
case 'd':
right();
break;
}
}
}
void up(){
int x=0,y=0,k=0;
for(k=0;k<3;k++)
for(x=1;x<4;x++){
for(y=0;y<4;y++){//下面有数,上面为空
if(map[x][y]&&map[x-1][y]==0){
map[x-1][y]=map[x][y];
map[x][y]=0;
} //下面有数,上下相等
if(map[x][y]&&map[x-1][y]==map[x][y]){
map[x-1][y]*=2;
map[x][y]=0;
}
}
}
if(pan()==1){//没有结束
sui();
show();
}else{//结束
show();
//调用弹框,询问是否重玩
if(MessageBoxA(NULL,"你输了\n是否重新开始","提示",1)==1){
init();//重玩,重置
show();
return ;
}else{//结束
exit(-1);
}
}
}
void down(){
int x=0,y=0,k=0;
for(k=0;k<3;k++)
for(x=2;x>=0;x--){
for(y=0;y<4;y++){//当前坐标点有数,下一行为空
if(map[x][y]&&map[x+1][y]==0){
map[x+1][y]=map[x][y];
map[x][y]=0;
} //当前坐标点有数,并且和下一行相等
if(map[x][y]&&map[x+1][y]==map[x][y]){
map[x+1][y]*=2;
map[x][y]=0;
}
}
}
if(pan()==1){//没有结束
sui();
show();
}else{//结束
show();
//调用弹框,询问是否重玩
if(MessageBoxA(NULL,"你输了\n是否重新开始","提示",1)==1){
init();//重玩,重置
show();
return ;
}else{//结束
exit(-1);
}
}
}
void left(){
int x=0,y=0,k=0;
for(k=0;k<3;k++)
for(x=0;x<4;x++){
for(y=1;y<4;y++){//下面有数,上面为空
if(map[x][y]&&map[x][y-1]==0){
map[x][y-1]=map[x][y];
map[x][y]=0;
} //下面有数,上下相等
if(map[x][y]&&map[x][y-1]==map[x][y]){
map[x][y-1]*=2;
map[x][y]=0;
}
}
}
if(pan()==1){//没有结束
sui();
show();
}else{//结束
show();
//调用弹框,询问是否重玩
if(MessageBoxA(NULL,"你输了\n是否重新开始","提示",1)==1){
init();//重玩,重置
show();
return ;
}else{//结束
exit(-1);
}
}
}
void right(){
int x=0,y=0,k=0;
for(k=0;k<3;k++)
for(x=0;x<4;x++){
for(y=2;y>=0;y--){//下面有数,上面为空
if(map[x][y]&&map[x][y+1]==0){
map[x][y+1]=map[x][y];
map[x][y]=0;
} //下面有数,上下相等
if(map[x][y]&&map[x][y+1]==map[x][y]){
map[x][y+1]*=2;
map[x][y]=0;
}
}
}
//判断游戏结束
if(pan()==1){//没有结束
sui();
show();
}else{//结束
show();
//调用弹框,询问是否重玩
if(MessageBoxA(NULL,"你输了\n是否重新开始","提示",1)==1){
init();//重玩,重置
show();
return ;
}else{//结束
exit(-1);
}
}
}
int pan(){
//记录当前坐标点和周围四个方向坐标点的差值
int a[4][2]={{-1,0},{0,-1},{0,1},{1,0}};
for(int x=0;x<4;x++){
for(int y=0;y<4;y++){
if(map[x][y]==0){//空位置,游戏没有结束
return 1;
}
//找到周围的四个点坐标
for(int k=0;k<4;k++){
int nx=a[k][0]+x;
int ny=a[k][1]+y;
//数组越界不用管
if(nx<0||nx>3||ny<0||ny>3){
continue;
}
//周围四个点有空,游戏没有结束
if(map[nx][ny]==0){
return 1;
}
//周围四个点任一点与当前点相同,游戏没有结束
if(map[nx][ny]==map[x][y]){
return 1;
}
}
}
}
//当有空位置或者有四个方向相等的就说明游戏没有结束
//负责说明游戏结束
return -1;
}
浙公网安备 33010602011771号