#include<iostream>
#include<windows.h>
#include<string>
#include<stdlib.h>
#include<ctime>
#include<cmath>
#include<iomanip>
#include<conio.h> //读取方向键
using namespace std;
int pane[4][4]; //网格
int N=1; //网格内2的最大次方数
int M=0; //用于判断是否发生移动的判断数
int win=2048; //胜利数
int lastscore=0; //得分
void show() //显示函数
{
cout<<endl<<setw(40)<<"<2048>"<<endl<<endl<<setw(50)<<lastscore<<endl<<endl; //输出得分
cout<<setw(50)<<" |-----------------------|"<<endl;
for (int i=0;i<4;i++)
{
cout<<setw(24)<<" ";
for(int j=0;j<4;j++)
{
cout<<setw(2)<<"|"<<setw(4);
if (pane[i][j]==0)
cout<<" ";
else
{
if (pane[i][j]==2)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN); //颜色控制,同下
else if (pane[i][j]==4)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN);
else if (pane[i][j]==8)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_GREEN);
else if (pane[i][j]==16)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);
else if (pane[i][j]==32)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE);
else if (pane[i][j]==64)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);
else if (pane[i][j]==128||pane[i][j]==256||pane[i][j]==512)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);
else
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_BLUE);
cout<<pane[i][j];
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
if (j==3)
{
cout<<setw(2)<<"|"<<endl;
cout<<setw(50)<<" |-----------------------|"<<endl;
}
}
}
cout<<endl<<setw(60)<<"by zyx~"<<endl;
}
void newgame() //游戏初始化函数
{
N=1;
win=2048;
lastscore=0;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
pane[i][j]=0;
}
srand((unsigned)time(NULL)); //随机位置产生两个2
int m=rand()%4;
int n=rand()%4;
int p=rand()%4;
int q=rand()%4;
pane[m][n]=2;
pane[p][q]=2;
show();
}
int panduan(int x) //判断是否为2的k次方
{
int flag=0;
for (int n=1;n<=15;n++)
{
if (x==pow(2,n))
{
flag=1;
if (n>N)
N=n;
return flag;
}
}
return flag;
}
int moveupstraight() //上移至底
{
int a=1;
int k=1;
int p,q;
while (k)
{
k=0;
for (q=0;q<4;q++)
for (p=0;p<3;p++)
{
if (pane[p][q]==0&&pane[p+1][q]!=0)
{
pane[p][q]=pane[p+1][q];
pane[p+1][q]=0;
k=1;
a=2;
}
}
}
return a;
}
int movedownstraight() //下移至底
{
int a=1;
int k=1;
int p,q;
while (k)
{
k=0;
for (q=0;q<4;q++)
for (p=3;p>0;p--)
{
if (pane[p][q]==0&&pane[p-1][q]!=0)
{
pane[p][q]=pane[p-1][q];
pane[p-1][q]=0;
k=1;
a=2;
}
}
}
return a;
}
int moveleftstraight() //左移至底
{
int a=1;
int k=1;
int p,q;
while (k)
{
k=0;
for (p=0;p<4;p++)
for (q=0;q<3;q++)
{
if (pane[p][q]==0&&pane[p][q+1]!=0)
{
pane[p][q]=pane[p][q+1];
pane[p][q+1]=0;
k=1;
a=2;
}
}
}
return a;
}
int moverightstraight() //右移至底
{
int a=1;
int k=1;
int p,q;
while (k)
{
k=0;
for (p=0;p<4;p++)
for (q=3;q>0;q--)
{
if (pane[p][q]==0&&pane[p][q-1]!=0)
{
pane[p][q]=pane[p][q-1];
pane[p][q-1]=0;
k=1;
a=2;
}
}
}
return a;
}
int moveup() //上移
{
int b=moveupstraight();
M=0;
if (b==2)
M=1;
int flag=0;
for (int j=0;j<4;j++)
for (int i=0;i<3;i++)
{
if(pane[i][j]==pane[i+1][j]&&pane[i+1][j]!=0)
{
pane[i][j]=pane[i][j]+pane[i+1][j];
pane[i+1][j]=0;
lastscore+=pane[i][j];
flag=1;
M=1;
}
}
moveupstraight();
return flag;
}
int movedown() //下移
{
int b=movedownstraight();
M=0;
if (b==2)
M=1;
int flag=0;
for (int j=0;j<4;j++)
for (int i=3;i>0;i--)
{
if (pane[i][j]==pane[i-1][j]&&pane[i-1][j]!=0)
{
pane[i][j]=pane[i][j]+pane[i-1][j];
pane[i-1][j]=0;
lastscore+=pane[i][j];
flag=1;
M=1;
}
}
movedownstraight();
return flag;
}
int moveleft() //左移
{
int b=moveleftstraight();
M=0;
if (b==2)
M=1;
int flag=0;
for (int i=0;i<4;i++)
for (int j=0;j<3;j++)
{
if (pane[i][j]==pane[i][j+1]&&pane[i][j+1]!=0)
{
pane[i][j]=pane[i][j]+pane[i][j+1];
pane[i][j+1]=0;
lastscore+=pane[i][j];
flag=1;
M=1;
}
}
moveleftstraight();
return flag;
}
int moveright() //右移
{
int b=moverightstraight();
M=0;
if (b==2)
M=1;
int flag=0;
for (int i=0;i<4;i++)
for (int j=3;j>0;j--)
{
if (pane[i][j]==pane[i][j-1]&&pane[i][j-1]!=0)
{
pane[i][j]=pane[i][j]+pane[i][j-1];
pane[i][j-1]=0;
lastscore+=pane[i][j];
flag=1;
M=1;
}
}
moverightstraight();
return flag;
}
int testup() //判断是否能够上移
{
int flag=0;
for (int j=0;j<4;j++)
for(int i=0;i<3;i++)
{
if (panduan(pane[i][j]+pane[i+1][j])==1)
flag=1;
}
return flag;
}
int testdown() //判断是否能够下移
{
int flag=0;
for (int j=0;j<4;j++)
for(int i=3;i>0;i--)
{
if (panduan(pane[i][j]+pane[i-1][j])==1)
flag=1;
}
return flag;
}
int testleft() //判断是否能够左移
{
int flag=0;
for (int i=0;i<4;i++)
for(int j=0;j<3;j++)
{
if (panduan(pane[i][j]+pane[i][j+1])==1)
flag=1;
}
return flag;
}
int testright() //判断是否能够右移
{
int flag=0;
for (int i=0;i<4;i++)
for(int j=3;j>0;j--)
{
if (panduan(pane[i][j]+pane[i][j-1])==1)
flag=1;
}
return flag;
}
int panemax() //网格内最大数
{
int max=pane[0][0];
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
if (pane[i][j]>max)
max=pane[i][j];
return max;
}
int ifwin() //判断是否胜利
{
int flag=0;
if (panemax()==win)
{
cout<<setw(45)<<"You Win!"<<endl;
win=win*2;
flag=1;
}
return flag;
}
int iflose() //判断是否失败
{
int flag=0;
if (testup()+testdown()+testleft()+testright()==0)
{
cout<<setw(43)<<"Game Over!"<<endl;
flag=1;
}
return flag;
}
void addnewnumber() //产生随机新数
{
srand((unsigned)time(NULL));
int n;
int o=rand()%10;
if (o==0)
n=2;
else
n=1;
int newnumber=pow(2,n);
int remain=0;
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
if (pane[i][j]==0)
remain++;
int select=rand()%remain+1;
int location=1;
for (int p=0;p<4;p++)
for (int q=0;q<4;q++)
if (pane[p][q]==0)
{
if (location==select)
{
pane[p][q]=newnumber;
return;
}
location++;
}
}
int GetDirection() //获取方向键
{
int ret=0;
do
{
int ch=getch();
switch (ch)
{
case 72:
ret=1;
break;
case 80:
ret=2;
break;
case 75:
ret=3;
break;
case 77:
ret=4;
break;
default:
break;
}
} while (ret==0);
return ret;
}
void main() //主函数
{
system("color 07");
int start=1;
while (start==1)
{
system("cls");
newgame();
while (ifwin()+iflose()==0)
{
loop:
int c=GetDirection();
if (c==1)
moveup();
else if (c==2)
movedown();
else if (c==3)
moveleft();
else
moveright();
if (M)
addnewnumber();
system("cls");
show();
}
cout<<setw(43)<<"你最后成绩为:"<<lastscore<<endl;
if (testup()+testdown()+testleft()+testright()==0)
{
cout<<setw(60)<<"<若要重新开始请输入1,输入2结束>"<<endl;