C++小游戏2048
发布时间
阅读量:
阅读量
游戏界面
#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<ctime>
#include<conio.h>
#include<Windows.h>
using namespace std;
int getlim(int a)
{
int sum=0;
for(int i=1;;i++)
{
if(a!=0)
sum+=1;
else
break;
a=a/10;
}
return sum;
}
int getlim(int a[])
{
for(int i=0;;i++)
if(a[i]==-1)
return i-1;
}
代码解读
首先编写一个重载函数,并用于计算数值及其一维数组中有效数字的数量;进一步编写该函数以显示游戏界面,并接收一个四乘四矩阵作为输入参数;从而展示出游戏的界面。
首先编写一个重载函数,并用于计算数值及其一维数组中有效数字的数量;进一步编写该函数以显示游戏界面,并接收一个四乘四矩阵作为输入参数;从而展示出游戏的界面。
void showx(int b[4][4])
{
for(int i=0;i<4;i++)
{for(int j=0;j<4;j++)
cout<<b[i][j];
cout<<endl;
}
}
void show_2()
{
cout<<"■";
for(int i=1;i<=4;i++)
cout<<setw(8)<<"■";
cout<<endl;
}
void show_1()
{
for(int i=1;i<=17;i++)
cout<<"■";
cout<<endl;
}
void show_4(int a)
{
int n;
n=getlim(a);
switch(n)
{
case 1:cout<<"■"<<setw(3)<<a<<setw(3)<<' ';break;
case 2:cout<<"■"<<setw(4)<<a<<setw(2)<<' ';break;
case 3:cout<<"■"<<setw(4)<<a<<setw(2)<<' ';break;
case 4:cout<<"■"<<setw(5)<<a<<' ';break;
case 0:cout<<"■"<<setw(6)<<' ';
}
}
void show_3(int a[])
{
show_4(a[0]);show_4(a[1]);show_4(a[2]);show_4(a[3]);
cout<<"■"<<endl;
}
void show(int a[4][4])
{
for(int i=0;i<4;i++)
{
int b[4];
for(int j=0;j<4;j++) b[j]=a[i][j];
show_1();show_2();show_3(b);show_2();
}
show_1();
}
代码解读

输出界面如图。
查找需要合并的数
确定需要合并的数值位置,并记录在4x4的数组中。考虑到上下左右四种不同的操作方式,在程序设计中我们可以将所有这些操作统一转换为向左移动的方式,并利用矩阵转置等数学变换方法实现这一目标。通过这种方式不仅简化了代码逻辑还确保了算法的一致性和可维护性
void left_right(int a[4][4])
{
int b[4][4];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
b[i][j]=a[i][j];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
a[i][3-j]=b[i][j];
}
void left_up(int a[4][4])
{
int b[4][4];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
b[i][j]=a[i][j];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
a[i][j]=b[j][i];
}
int check_1(int a[4],int b[4])
{
int flag=0;
for(int i=0;i<4;i++) b[i]=0;
if(a[0]!=0)
{
if(a[0]==a[1]&&a[2]==a[3]&&a[2]!=0)
{b[0]=1;b[2]=1;flag=1;}
else if(a[0]==a[1])
{b[0]=1;flag=1;}
else if(a[1]==0&&a[0]==a[2])
{b[0]=1;flag=1;}
else if(a[1]==0&&a[2]==0&&a[0]==a[3])
{b[0]=1;flag=1;}
else if(a[1]==a[2]&&a[1]!=0)
{b[1]=1;flag=1;}
else if(a[1]==a[3]&&a[1]!=0&&a[2]==0)
{b[1]=1;flag=1;}
else if(a[2]==a[3]&&a[2]!=0)
{b[2]=1;flag=1;}
}
else
{
if(a[1]!=0)
{
if(a[1]==a[2])
{b[1]=1;flag=1;}
else if(a[1]==a[3]&&a[2]==0)
{b[1]=1;flag=1;}
else if(a[2]==a[3]&&a[2]!=0)
{b[2]=1;flag=1;}
}
else
{
if(a[2]==a[3]&&a[2]!=0)
{b[2]=1;flag=1;}
}
}
if(flag==0)
{
if(a[0]==0&&(a[1]!=0||a[2]!=0||a[3]!=0))
flag=1;
else if(a[1]==0&&(a[2]!=0||a[3]!=0))
flag=1;
else if(a[2]==0&&a[3]!=0)
flag=1;
}
return flag;
}
int check_left(int a[4][4],int b[4][4])
{
int flag[4],flagx=0;
for(int i=0;i<4;i++)
flag[i]=check_1(a[i],b[i]);
for(int i=0;i<4;i++)
if(flag[i]==1){flagx=1;}
return flagx;
}
int check_right(int a[4][4],int b[4][4])
{
left_right(a);
int flag;
flag=check_left(a,b);
left_right(a);
left_right(b);
return flag;
}
int check_up(int a[4][4],int b[4][4])
{
left_up(a);
int flag;
flag=check_left(a,b);
left_up(a);
left_up(b);
return flag;
}
int check_down(int a[4][4],int b[4][4])
{
left_up(a);
int flag;
flag=check_right(a,b);
left_up(a);
left_up(b);
return flag;
}
代码解读
查找结束条件
除了需要识别哪些地方需要进行数据整合外,在游戏运行过程中我们还需判断是否存在无法合并的数据项以及数据区域是否已无可用空间。
void check_zero(int a[4][4],int x[],int y[])
{
int sum=0;
for(int i=0;i<16;i++)
{x[i]=-1;y[i]=-1;}
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(a[i][j]==0)
{x[sum]=i;y[sum]=j;sum++;}
}
int check(int a[4][4],int b[4][4])
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(a[i][j]==0)
return 1;
int flag1,flag2;
flag1=check_left(a,b);
flag2=check_up(a,b);
if(flag1==0&&flag2==0)
return 0;
return 1;
}
代码解读
数字合并
基于我们获得的数组B, 我们能够了解数组A中哪些数值具有可合并性. 下述函数将实现对其中可合并数的具体操作, 完成其整合处理.
void change_1(int a[4],int b[4])
{
for(int i=0;i<4;i++)
if(b[i]==1)
{
if(a[i]==a[i+1])
{a[i]=a[i]*2;a[i+1]=0;}
else if(a[i]==a[i+2])
{a[i]=a[i]*2;a[i+2]=0;}
else if(a[i]==a[i+3])
{a[i]=a[i]*2;a[i+3]=0;}
}
}
void change_left(int a[4][4],int b[4][4])
{
for(int i=0;i<4;i++)
change_1(a[i],b[i]);
}
void change_right(int a[4][4],int b[4][4])
{
left_right(a);
left_right(b);
change_left(a,b);
left_right(a);
left_right(b);
}
void change_up(int a[4][4],int b[4][4])
{
left_up(a);
left_up(b);
change_left(a,b);
left_up(a);
left_up(b);
}
void change_down(int a[4][4],int b[4][4])
{
left_up(a);
left_up(b);
change_right(a,b);
left_up(a);
left_up(b);
}
代码解读
数组重排
将数字进行合并后会生成一个新的数组。依据游戏规则,在指定方向上补充缺失的位置,则需提供一个对重新排列后的数组进行操作的函数。
void reshape_1(int a[4])
{
int b[4],sum=0;
for(int i=0;i<4;i++)
{b[i]=a[i];a[i]=0;}
for(int i=0;i<4;i++)
{
if(b[i]!=0)
a[sum++]=b[i];
}
}
void reshape_left(int a[4][4])
{
for(int i=0;i<4;i++)
reshape_1(a[i]);
}
void reshape_right(int a[4][4])
{
left_right(a);
reshape_left(a);
left_right(a);
}
void reshape_up(int a[4][4])
{
left_up(a);
reshape_left(a);
left_up(a);
}
void reshape_down(int a[4][4])
{
left_up(a);
reshape_right(a);
left_up(a);
}
代码解读
数组插值
按照游戏规则,在每次操作完成后,我们需要在空位处随机填充新的数值。为了简化起见,我们将数值2随机分配至指定的两个空位位置。
void interp(int a[4][4])
{
int x[16],y[16],t,nan,lim,x1,y1;
check_zero(a,x,y);
lim=getlim(x);
if(lim!=0)
{
t=GetTickCount();
srand(t);
nan=rand()%lim;
}
else
nan=0;
x1=x[nan];y1=y[nan];
a[x1][y1]=2;
}
代码解读
整合游戏
所有功能模块均已实现。我们将流程整合到movex函数中以便于主程序调用。接着创建初始状态的beginx函数,并编写主程序即可。
void movex(int a[4][4],int b[4][4],char p)
{
int flag;
switch(p)
{
case'w':case'W':
flag=check_up(a,b);
if(flag)
{
change_up(a,b);
reshape_up(a);
interp(a);
}
break;
case's':case'S':
flag=check_down(a,b);
if(flag)
{
change_down(a,b);
reshape_down(a);
interp(a);
}
break;
case'a':case'A':
flag=check_left(a,b);
if(flag)
{
change_left(a,b);
reshape_left(a);
interp(a);
}
break;
case'd':case'D':
flag=check_right(a,b);
if(flag)
{
change_right(a,b);
reshape_right(a);
interp(a);
}
break;
}
}
void beginx(int a[4][4])
{
int t,x1,x2,y1,y2;
t=GetTickCount();srand(t);x1=rand()%4;y1=rand()%4;
do
{x2=rand()%4;y2=rand()%4;}while(x1==x2&&y1==y2);
a[x1][y1]=2;a[x2][y2]=2;
show(a);
}
int main()
{
while(1)
{
cout<<"输入w开始游戏,输入s退出游戏,游戏中输入q结束游戏"<<endl;
char q;
q=getch();
if(q=='s'||q=='S')
break;
int a[4][4]={0},b[4][4]={0},flag=1;
system("cls");
beginx(a);
while(1)
{
char p;
p=getch();
movex(a,b,p);
system("cls");
show(a);
flag=check(a,b);
if(flag==0)
{
cout<<"游戏结束"<<endl;
break;
}
if(p=='q')
{
cout<<"游戏结束"<<endl;
break;
}
}
}
return 0;
}
代码解读
附整体代码
#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<ctime>
#include<conio.h>
#include<Windows.h>
using namespace std;
void showx(int b[4][4])
{
for(int i=0;i<4;i++)
{for(int j=0;j<4;j++)
cout<<b[i][j];
cout<<endl;
}
}
int getlim(int a)
{
int sum=0;
for(int i=1;;i++)
{
if(a!=0)
sum+=1;
else
break;
a=a/10;
}
return sum;
}
int getlim(int a[])
{
for(int i=0;;i++)
if(a[i]==-1)
return i-1;
}
void show_2()
{
cout<<"■";
for(int i=1;i<=4;i++)
cout<<setw(8)<<"■";
cout<<endl;
}
void show_1()
{
for(int i=1;i<=17;i++)
cout<<"■";
cout<<endl;
}
void show_4(int a)
{
int n;
n=getlim(a);
switch(n)
{
case 1:cout<<"■"<<setw(3)<<a<<setw(3)<<' ';break;
case 2:cout<<"■"<<setw(4)<<a<<setw(2)<<' ';break;
case 3:cout<<"■"<<setw(4)<<a<<setw(2)<<' ';break;
case 4:cout<<"■"<<setw(5)<<a<<' ';break;
case 0:cout<<"■"<<setw(6)<<' ';
}
}
void show_3(int a[])
{
show_4(a[0]);show_4(a[1]);show_4(a[2]);show_4(a[3]);
cout<<"■"<<endl;
}
void show(int a[4][4])
{
for(int i=0;i<4;i++)
{
int b[4];
for(int j=0;j<4;j++) b[j]=a[i][j];
show_1();show_2();show_3(b);show_2();
}
show_1();
}
void left_right(int a[4][4])
{
int b[4][4];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
b[i][j]=a[i][j];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
a[i][3-j]=b[i][j];
}
void left_up(int a[4][4])
{
int b[4][4];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
b[i][j]=a[i][j];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
a[i][j]=b[j][i];
}
int check_1(int a[4],int b[4])
{
int flag=0;
for(int i=0;i<4;i++) b[i]=0;
if(a[0]!=0)
{
if(a[0]==a[1]&&a[2]==a[3]&&a[2]!=0)
{b[0]=1;b[2]=1;flag=1;}
else if(a[0]==a[1])
{b[0]=1;flag=1;}
else if(a[1]==0&&a[0]==a[2])
{b[0]=1;flag=1;}
else if(a[1]==0&&a[2]==0&&a[0]==a[3])
{b[0]=1;flag=1;}
else if(a[1]==a[2]&&a[1]!=0)
{b[1]=1;flag=1;}
else if(a[1]==a[3]&&a[1]!=0&&a[2]==0)
{b[1]=1;flag=1;}
else if(a[2]==a[3]&&a[2]!=0)
{b[2]=1;flag=1;}
}
else
{
if(a[1]!=0)
{
if(a[1]==a[2])
{b[1]=1;flag=1;}
else if(a[1]==a[3]&&a[2]==0)
{b[1]=1;flag=1;}
else if(a[2]==a[3]&&a[2]!=0)
{b[2]=1;flag=1;}
}
else
{
if(a[2]==a[3]&&a[2]!=0)
{b[2]=1;flag=1;}
}
}
if(flag==0)
{
if(a[0]==0&&(a[1]!=0||a[2]!=0||a[3]!=0))
flag=1;
else if(a[1]==0&&(a[2]!=0||a[3]!=0))
flag=1;
else if(a[2]==0&&a[3]!=0)
flag=1;
}
return flag;
}
int check_left(int a[4][4],int b[4][4])
{
int flag[4],flagx=0;
for(int i=0;i<4;i++)
flag[i]=check_1(a[i],b[i]);
for(int i=0;i<4;i++)
if(flag[i]==1){flagx=1;}
return flagx;
}
int check_right(int a[4][4],int b[4][4])
{
left_right(a);
int flag;
flag=check_left(a,b);
left_right(a);
left_right(b);
return flag;
}
int check_up(int a[4][4],int b[4][4])
{
left_up(a);
int flag;
flag=check_left(a,b);
left_up(a);
left_up(b);
return flag;
}
int check_down(int a[4][4],int b[4][4])
{
left_up(a);
int flag;
flag=check_right(a,b);
left_up(a);
left_up(b);
return flag;
}
void check_zero(int a[4][4],int x[],int y[])
{
int sum=0;
for(int i=0;i<16;i++)
{x[i]=-1;y[i]=-1;}
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(a[i][j]==0)
{x[sum]=i;y[sum]=j;sum++;}
}
int check(int a[4][4],int b[4][4])
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(a[i][j]==0)
return 1;
int flag1,flag2;
flag1=check_left(a,b);
flag2=check_up(a,b);
if(flag1==0&&flag2==0)
return 0;
return 1;
}
void change_1(int a[4],int b[4])
{
for(int i=0;i<4;i++)
if(b[i]==1)
{
if(a[i]==a[i+1])
{a[i]=a[i]*2;a[i+1]=0;}
else if(a[i]==a[i+2])
{a[i]=a[i]*2;a[i+2]=0;}
else if(a[i]==a[i+3])
{a[i]=a[i]*2;a[i+3]=0;}
}
}
void change_left(int a[4][4],int b[4][4])
{
for(int i=0;i<4;i++)
change_1(a[i],b[i]);
}
void change_right(int a[4][4],int b[4][4])
{
left_right(a);
left_right(b);
change_left(a,b);
left_right(a);
left_right(b);
}
void change_up(int a[4][4],int b[4][4])
{
left_up(a);
left_up(b);
change_left(a,b);
left_up(a);
left_up(b);
}
void change_down(int a[4][4],int b[4][4])
{
left_up(a);
left_up(b);
change_right(a,b);
left_up(a);
left_up(b);
}
void reshape_1(int a[4])
{
int b[4],sum=0;
for(int i=0;i<4;i++)
{b[i]=a[i];a[i]=0;}
for(int i=0;i<4;i++)
{
if(b[i]!=0)
a[sum++]=b[i];
}
}
void reshape_left(int a[4][4])
{
for(int i=0;i<4;i++)
reshape_1(a[i]);
}
void reshape_right(int a[4][4])
{
left_right(a);
reshape_left(a);
left_right(a);
}
void reshape_up(int a[4][4])
{
left_up(a);
reshape_left(a);
left_up(a);
}
void reshape_down(int a[4][4])
{
left_up(a);
reshape_right(a);
left_up(a);
}
void interp(int a[4][4])
{
int x[16],y[16],t,nan,lim,x1,y1;
check_zero(a,x,y);
lim=getlim(x);
if(lim!=0)
{
t=GetTickCount();
srand(t);
nan=rand()%lim;
}
else
nan=0;
x1=x[nan];y1=y[nan];
a[x1][y1]=2;
}
void movex(int a[4][4],int b[4][4],char p)
{
int flag;
switch(p)
{
case'w':case'W':
flag=check_up(a,b);
if(flag)
{
change_up(a,b);
reshape_up(a);
interp(a);
}
break;
case's':case'S':
flag=check_down(a,b);
if(flag)
{
change_down(a,b);
reshape_down(a);
interp(a);
}
break;
case'a':case'A':
flag=check_left(a,b);
if(flag)
{
change_left(a,b);
reshape_left(a);
interp(a);
}
break;
case'd':case'D':
flag=check_right(a,b);
if(flag)
{
change_right(a,b);
reshape_right(a);
interp(a);
}
break;
}
}
void beginx(int a[4][4])
{
int t,x1,x2,y1,y2;
t=GetTickCount();srand(t);x1=rand()%4;y1=rand()%4;
do
{x2=rand()%4;y2=rand()%4;}while(x1==x2&&y1==y2);
a[x1][y1]=2;a[x2][y2]=2;
show(a);
}
int main()
{
while(1)
{
cout<<"输入w开始游戏,输入s退出游戏,游戏中输入q结束游戏"<<endl;
char q;
q=getch();
if(q=='s'||q=='S')
break;
int a[4][4]={0},b[4][4]={0},flag=1;
system("cls");
beginx(a);
while(1)
{
char p;
p=getch();
movex(a,b,p);
system("cls");
show(a);
flag=check(a,b);
if(flag==0)
{
cout<<"游戏结束"<<endl;
break;
}
if(p=='q')
{
cout<<"游戏结束"<<endl;
break;
}
}
}
return 0;
}
代码解读
全部评论 (0)
还没有任何评论哟~
