翻了一下以前的代码,发现去年国庆写的2048有点意思,于是搬过来纪念一下
#include<iostream>
#include<cstdio>
#include<time.h>
#include<cstdlib>
#include <conio.h>//kbhit()函数
//宏定义----------------------------------------------------------
#define JUG_empty 1//juge结果
#define JUG_merge 2//juge结果
#define JUG_collision 3//juge结果
#define JUG_nonum 4//juge结果
#define MOV_empty 1//move类型匹配
#define MOV_merge 2//move类型匹配
#define MOV_noaction 3//move类型匹配
#define MOV_auto 4//move类型匹配
//命名空间声明----------------------------------------------------
using namespace std;
//自定义数据类型--------------------------------------------------
enum n_dir {Left,Right,Up,Down};
//方向类型
//函数声明--------------------------------------------------------
int Move(n_dir dir,int move=1);//返回MOV_类型的结果。move表示是否移动
//块移动
int Random(int min,int max);
//取随机整数
void StartScr();
//开始界面
void GameScr();
//游戏界面
void prinum(int);
//按照固定大小打印数字
int Juge(short &num,short &des,short move = MOV_auto);
//块移动
void Welcome();
//欢迎界面
void Padding(int);
//空格填充
//全局变量--------------------------------------------------------
short wide=4,hight=4,//区域大小考虑到可选择性,所以用了变量,默认为4×4区域
*map;//区域
unsigned grade=0;
//
int main()
{
srand((unsigned)time(NULL));//置随机数种子
//---------------------欢迎界面---------------------
Welcome();
//---------------------开始界面---------------------
StartScr();
return 0;
}
void prinum(int a)
{
//这里只考虑最大数字为四位数的所以块大小是1×4的长方形
int len=0,leftblank,b=a;
while(b)
{
len++;
b/=10;
}
leftblank=(4-len)/2;
int i;
for(i=1;i<=leftblank;i++)
putchar(' ');
cout<<a;
for(i=1;i<=4-len-leftblank;i++)
putchar(' ');
}
int Random(int min,int max)
{
return rand()%(max-min+1)+min;
}
void StartScr()
{
//---------------------开始游戏---------------------
//以下将一维数组二维化:[i][j]=[i*wide+j]
map = new short [wide*hight];//设置区域大小
grade=0;//分数归零
for(int i=0;i<hight;i++)
{
for(int j=0;j<wide;j++)
{
map[i*wide+j]=-1;//无数的标志
}
}
map[Random(0,wide*hight-1)]=2;//map记录数值
GameScr();
delete []map;
}
void GameScr()
{
int key1,key2,result;
system("cls");//清屏
int i=0;
cout<<"---------";
prinum(grade);
cout<<"----------"<<endl;
for(i=0;i<=wide;i++)
cout<<"----";
cout<<"----"<<endl;
for(i=0;i<wide*hight;i++)
{
if(i%wide==0)
cout<<"| ";
if(map[i]==-1)
cout<<" ";
else
prinum(map[i]);
if((i+1)%wide==0)
cout<<" |"<<endl;//行尾
}
for(i=0;i<=wide;i++)
cout<<"-----";
while(1)
{
if(kbhit())//当键盘被按下
{
key1=getch();
if(key1==224)//方向键
{
key2=getch();//键值
if(key2==72)//上
result=Move(Up);
else if(key2==80)//下
result=Move(Down);
else if(key2==75)//左
result=Move(Left);
else if(key2==77)//右
result=Move(Right);
}
else //数字键
{
if(key1=='w'||key1=='W')//上
result=Move(Up);
else if(key1=='s'||key1=='S')//下
result=Move(Down);
else if(key1=='a'||key1=='A')//左
result=Move(Left);
else if(key1=='d'||key1=='D')//右
result=Move(Right);
}
//---------------------刷新显示---------------------
system("cls");//清屏
int i=0;
cout<<"---------";
prinum(grade);
cout<<"----------"<<endl;
for(i=0;i<=wide;i++)
cout<<"----";
cout<<"----"<<endl;
for(i=0;i<wide*hight;i++)
{
if(i%wide==0)
cout<<"| ";
if(map[i]==-1)
cout<<" ";
else
prinum(map[i]);
if((i+1)%wide==0)
cout<<" |"<<endl;//行尾
}
for(i=0;i<=wide;i++)
cout<<"-----";
if(Move(Up,0)==MOV_noaction && Move(Down,0)==MOV_noaction && Move(Left,0)==MOV_noaction && Move(Right,0)==MOV_noaction)
{
//已经不能移动了
cout<<endl<<"----------GameOver----------"<<endl;
}
}
}
}
int Move(n_dir dir,int move)
{
int i,j,k,num,des,result,count,moveresult=MOV_noaction;
short *list;
if(dir == Up)
{
list = new short [hight];//记录合并位置
for(j=0;j<wide;j++)
{
count=0;
for(i=1;i<hight;i++)//行上移
{
if(map[i*wide+j]!=-1)
{
num=i;
des=i-1;
while(1)//跳过空位置
{
result=Juge(map[num*wide+j],map[des*wide+j],MOV_noaction);//返回判断结果
if(result == JUG_empty)//判断为空位置
{
moveresult=MOV_empty;
if(move)
Juge(map[num*wide+j],map[des*wide+j]);//移到空位置
des--;
num--;
if(des<0)//目标超界跳出
break;
continue;
}
else if(result == JUG_merge)//结果为合并
{
for(k=0;k<count;k++)
if(des==list[k])//目标位置已经被合并过了
goto up_out;
moveresult=MOV_merge;
if(move)
{
grade+=map[num*wide+j];
Juge(map[num*wide+j],map[des*wide+j]);//合并
list[count++]=des;//记录合并位置
}
up_out:
break;
}
else
break;
}
}
}
}
delete []list;
}
else if(dir == Down)
{
list = new short [hight];//记录合并位置
for(j=0;j<wide;j++)
{
count=0;
for(i=hight-2;i>=0;i--)//行下移
{
if(map[i*wide+j]!=-1)
{
num=i;
des=i+1;
while(1)//跳过空位置
{
result=Juge(map[num*wide+j],map[des*wide+j],MOV_noaction);//返回判断结果
if(result == JUG_empty)//判断为空位置
{
moveresult=MOV_empty;
if(move)
Juge(map[num*wide+j],map[des*wide+j]);//移到空位置
des++;
num++;
if(des>hight-1)//目标超界跳出
break;
continue;
}
else if(result == JUG_merge)//结果为合并
{
for(k=0;k<count;k++)
if(des==list[k])//目标位置已经被合并过了
goto down_out;
moveresult=MOV_merge;
if(move)
{
grade+=map[num*wide+j];
Juge(map[num*wide+j],map[des*wide+j]);//合并
list[count++]=des;//记录合并位置
}
down_out:
break;
}
else
break;
}
}
}
}
delete []list;
}
else if(dir == Left)
{
list = new short [wide];//记录合并位置
for(i=0;i<hight;i++)
{
count=0;
for(j=1;j<wide;j++)//行左移
{
if(map[i*wide+j]!=-1)
{
num=j;
des=j-1;
while(1)//跳过空位置
{
result=Juge(map[i*wide+num],map[i*wide+des],MOV_noaction);//返回判断结果
if(result == JUG_empty)//判断为空位置
{
moveresult=MOV_empty;
if(move)
Juge(map[i*wide+num],map[i*wide+des]);//移到空位置
des--;
num--;
if(des<0)//目标超界跳出
break;
continue;
}
else if(result == JUG_merge)//结果为合并
{
for(k=0;k<count;k++)
if(des==list[k])//目标位置已经被合并过了
goto left_out;
moveresult=MOV_merge;
if(move)
{
grade+=map[i*wide+num];
Juge(map[i*wide+num],map[i*wide+des]);//合并
list[count++]=des;//记录合并位置
}
left_out:
break;
}
else
break;
}
}
}
}
delete []list;
}
else if(dir == Right)
{
list = new short [wide];//记录合并位置
for(i=0;i<hight;i++)
{
count=0;
for(j=wide-2;j>=0;j--)//行左移
{
if(map[i*wide+j]!=-1)
{
num=j;
des=j+1;
while(1)//跳过空位置
{
result=Juge(map[i*wide+num],map[i*wide+des],MOV_noaction);//返回判断结果
if(result == JUG_empty)//判断为空位置
{
moveresult=MOV_empty;
if(move)
Juge(map[i*wide+num],map[i*wide+des]);//移到空位置
des++;
num++;
if(des<0)//目标超界跳出
break;
continue;
}
else if(result == JUG_merge)//结果为合并
{
for(k=0;k<count;k++)
if(des==list[k])//目标位置已经被合并过了
goto right_out;
moveresult=MOV_merge;
if(move)
{
grade+=map[i*wide+num];//加分
Juge(map[i*wide+num],map[i*wide+des]);//合并
list[count++]=des;//记录合并位置
}
right_out:
break;
}
else
break;
}
}
}
}
delete []list;
}
if(move&&moveresult!=MOV_noaction)
{
int posi=Random(0,wide*hight-1);
while(map[posi]!=-1)//保证是空位
posi=Random(0,wide*hight-1);
if(Random(1,8)<8)//2的几率:4的几率=8:1
map[posi]=2;
else
map[posi]=4;
}
return moveresult;
}
int Juge(short &num,short &des,short move)//num一定不是-1
{
if(des==-1)//目的地无数
{
if(move==MOV_auto||move==MOV_empty)
{
des=num;//数值转移
num=-1;//置空
}
return JUG_empty;
}
else //目的地有数
{
if(num==des)//数值一样
{
if(move==MOV_auto||move==MOV_merge)
{
des+=num;//合并
num=-1;//置空
}
return JUG_merge;
}
else
return JUG_collision;
}
}
//
//欢迎界面
//
void Welcome()
{
Padding(-10);printf("欢迎来到2048!!!\n");
Padding(-10);printf("上下左右为wsad键或方向键,感受这款经典游戏带来的快感吧!\n");
system("pause");
}
//
//显示一定数量的空格
//参数1:相对偏移
void Padding(int shift)
{
int total=20,i;
total+=shift;
for(i=0;i<total;i++)
{
putchar(' ');
}
}