用VC++6.0的控制台实现2048小游戏的程序
感谢这位大侠的无私分享,仔细学习这个程序以后收获很多,试着添加一些注释
源程序是从开源中国看到的,原作者是 刘地(sir?)
地址为http://.oschina./code/snippet_593413_46040
geek_monkey于2015年3月5日为拜读该程序,受益匪浅
为了方便自己,以及更多初学者阅读,我试着写了写了注释供参考
我是C语言初学者,如有错误电脑维修网希望指正。轻喷
复制代码 代码如下:
#include
#include
#include
#include
int x[4][4],y[4][4],z=0,o=0;//z表示的是当前矩阵中的非零数字的数量,z为16则说明数字排满了,本局输了
//o表示最大数字的值,本例设定的是1024
typedef int ro[4]; //ro代表具有4个元素的整型数组
ro p=x, q=y;//P是整型指针数组,有4组,每组有4个元素。p[1]=x[1]=(x+1)
void sho()//显示函数
{
int i,j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(p[i][j]==0)
{
printf("- ");//没有放置数字(也就是数字为0时)显示一个小横杠
}
else
{
printf("%-4d ",p[i][j]);//显示位宽为4的整数,-表示左对齐
}
}
printf("nn");
}
printf("nn");
}
void over()//将2维数组左右对调
{
int i,j;
ro r;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
q[i][3-j]=p[i][j];
}
r=p,p=q,q=r;
}
void left()//将2维数组逆时针转动90°
{
int i,j;
ro r;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
q[3-j][i]=p[i][j];
}
r=p,p=q,q=r;
}
void right()//将2维数组顺时针转动90°
{
int i,j;
ro r;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
q[j][3-i]=p[i][j];
}
r=p,p=q,q=r;
}
void inc()//此函数的作用是在0数字的位置上随机放置一个2或者4
{
int i,j,k;
for(;;)
{
k=rand()%16,i=k/4,j=k%4;//这个操作可以保证i,j小于等于4,不会放到二维数组外边
if(p[i][j]==0)break;//确认p[i][j]是空白的,然后才能放置2或者4
}
if(rand()%2) //随机产生2或者4,理论上rand()%2的结果,0,1,几率各占一半
{
p[i][j]=4;
}
else
{
p[i][j]=2;
}
z++;
}
void merge(char c)
{
int i,j,k,t;
sitch(c)//注,这个stitch没有default,也没有给按下右方向键的处理语句。即,按下右方向键,则跳过sitch
{
case 'H'://检测到按了上方向键
right();//顺时针转动90度
break;
case 'K'://左
over();//左右对称换
break;
case 'P'://下
left(); //逆90
break;
}
//上边这个sitch语句是将矩阵变换,将数字推向上,左或者下的操作转换为推向右的操作。
//下边这个循环语句的功能是,把每一行的数字都往右边推,数字大小一样则合并。
for(i=0;i<4;i++)//一行一行地检测
{
for(j=k=3;j>=0 && p[i][j]==0;j--);//从第i行的右边开始,向左找非零元素。也就是要让p[i][j]不为0的时候,结束本条for语句
if(j<0)continue;//经过下边的右推操作,第i行最左边的值也非0,说明此行操作结束,跳出i的for循环,执行i+1行的右推操作
t=p[i][j],p[i][j]=0,p[i][k]=t;//P[i][j]是P[i][k]左边的一个数。这里的j的值是由上一条语句找出来的,通过t传值保证了这个p[i][k]不为0
for(j--;j>=0;j--)
{
t=p[i][j];
if(t!=0)//如果p[i][j]不为0,就检测它与右侧的p[i][k]是否为相同
{
p[i][j]=0;
if(p[i][k]==t)
{
z--,p[i][k]+=t;//相同则加倍,非0数字的数量减少一个
o=(t==512);//t为512代表最大值是1024,此时o==1,游戏以胜利结束
}
else
{
k--,p[i][k]=t;//不停则将p[i][j]的值赋给p[i][k],即数据右移动一位
}
}
}
}
sitch(c)
{
case 'H'://按下,上方向键,矩阵逆时针旋转90°。这个操作与之前那个sitch正好相反
left();
break;
case 'K'://左右对调
over();
break;
case 'P':
right();
break;
}
inc();
}
int main()
{
char a,b;
srand(time(NULL));
inc();
inc();//放置两个初始值
sho();
hile(z<16 && !o)//游戏结束条件,z==16或者o==1
{
a=getch();
if(a==-32)//方向键的第一个字节为-32.char是无符的,这里为什么是-32还没弄明白
{
b=getch();
if(b==72||b==75||b==77||b==80)
{
merge(b);
sho();
}
}
}
if(o)
{
printf("congratulations!");
}
else
{
printf("sorry, you failed!");
}
getch();
return 0;
}
空调维修
- 温岭冰箱全国统一服务热线-全国统一人工【7X2
- 荆州速热热水器维修(荆州热水器维修)
- 昆山热水器故障码5ER-昆山热水器故障码26
- 温岭洗衣机24小时服务电话—(7X24小时)登记报
- 统帅热水器售后维修服务电话—— (7X24小时)登
- 阳江中央空调统一电话热线-阳江空调官方售后电
- 乌鲁木齐阳春燃气灶厂家服务热线
- 珠海许昌集成灶售后服务电话-全国统一人工【
- 乌鲁木齐中央空调维修服务专线-乌鲁木齐中央空
- 新沂热水器故障电话码维修-新沂热水器常见故障
- 诸城壁挂炉24小时服务热线电话
- 靖江空调24小时服务电话-——售后维修中心电话
- 空调室外滴水管维修(空调室外排水管维修)
- 九江壁挂炉400全国服务电话-(7X24小时)登记报修
- 热水器故障码f.22怎么解决-热水器f0故障解决方法
- 营口热水器售后维修服务电话—— 全国统一人工