这是我用Xcode编写的俄罗斯方块,我目前就读大一,很多东西还没有学,比如多线程什么的,导致方块不能实现自主下降,只能自己按‘s’来实现下降,不过这都无所谓,但是不知道为什么程序运行不了,看了好久都没看出错在哪里,希望能够得到大神的求助!感谢!
头文件,我也不知道是不是都用得上
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<curses.h>
全局变量
int i,j,a[25][10];
char l;
生成界面,我用的二维数组是a[25][10],周围边框的值为2,一共有6种方块,每一类型的方块都用一个数字表示,当随机生成一个数字后,相应的方块的坐标值为1,其余为0,即空格,我还同时计算出来方块最上面最下面最左边最右边的坐标方便移动和判断
int *shengcheng(int a[][10],int up)
{
int n,m,min,max,b[6]={1,2,3,4,5,6},c[8]={1,2,3,4,5,6,7,8},d[6],*p,flag=0,down;
srand((int)time(NULL));
n=b[rand()%6];
m=c[rand()%8];
d[0]=n;
d[1]=m;
switch(n)
{
case 1 :
{
if(a[1][m]==0&&a[2][m]==0&&a[3][m]==0&&a[3][m+1]==0&&m<=7)
{
a[1][m]=1;
a[2][m]=1;
a[3][m]=1;
a[3][m+1]=1;
min=m;
max=m+1;
down=up+2;
break;
}
else
{
flag=1;
break;
}
}
case 2 :
{
if(a[1][m]==0&&a[1][m+1]==0&&a[2][m]==0&&a[2][m+1]==0&&m<=7)
{
a[1][m]=1;
a[1][m+1]=1;
a[2][m]=1;
a[2][m+1]=1;
min=m;
max=m+1;
down=up+1;
break;
}
else
{
flag=1;
break;
}
}
case 3 :
{
if(a[1][m]==0&&a[2][m]==0&&a[3][m]==0&&a[4][m]==0)
{
a[1][m]=1;
a[2][m]=1;
a[3][m]=1;
a[4][m]=1;
min=m;
max=m;
down=up+3;
break;
}
else
{
flag=1;
break;
}
}
case 4 :
{
if(a[1][m]==0&&a[1][m+1]==0&&a[2][m+1]==0&&a[2][m+2]==0&&m<=6)
{
a[1][m]=1;
a[1][m+1]=1;
a[2][m+1]=1;
a[2][m+2]=1;
min=m;
max=m+2;
down=up+1;
break;
}
else
{
flag=1;
break;
}
}
case 5 :
{
if(a[1][m]==0&&a[1][m+1]==0&&a[1][m+2]==0&&a[2][m+1]==0&&m<=6)
{
a[1][m]=1;
a[1][m+1]=1;
a[1][m+2]=1;
a[2][m+1]=1;
min=m;
max=m+2;
down=up+1;
break;
}
else
{
flag=1;
break;
}
}
case 6 :
{
if(a[1][m]==0&&a[1][m+1]==0&&a[2][m]==0&&a[2][m-1]==0&&m>=2&&m<=7)
{
a[1][m]=1;
a[1][m+1]=1;
a[2][m]=1;
a[2][m-1]=1;
min=m-1;
max=m+1;
down=up+1;
break;
}
else
{
flag=1;
break;
}
}
}
d[2]=min;
d[3]=max;
d[4]=down;
d[5]=flag;
p=d;
printf("n=%d,m=%d,min=%d,max=%d,up=%d,down=%d,flag=%d\n",n,m,min,max,up,down,flag);
return(p);
}
生成的样子长这样
n是指生成的方块的种类,m是指生成的方块的坐标,ks和up在主函数里定义为1,是指旋转的基点,flag用来判断方块有没有出界,因为每一类型的方块大小不一样,对比了一下方块边界的坐标都没有错。
打印函数就不用多说
void jiemian(int a[][10])
{
for(i=0,j=0;j<10;j++)
{
a[i][j]=2;
printf("⬛️ ");
}
printf(" 𝙎𝐂𝙊𝑅𝐄:");
printf("\n");
for(i=1;i<24;i++)
{
j=0;
printf("⬛️ ");
a[i][j]=2;
for(j=1;j<9;j++)
{
if(a[i][j]==0)
printf("⬜️ ");
else
printf("🟧 ");
}
printf("⬛️ ");
a[i][j]=2;
printf("\n");
}
for(i=24,j=0;j<10;j++)
{
printf("⬛️ ");
a[i][j]=2;
}
printf("\n");
}
下面是旋转函数,我引用了旋转的基点ks,ks只会随着移动而改变不会随着旋转改变,而up,down,min,max则会随着旋转改变
int *xuanzhuan(int a[][10],int n,int m,int min,int max,int up,int down,int ks)
{
int static l=0;
int d[6],*p;
switch(n)
{
case 1 :
{
switch(l)
{
case 0 :
{
if(a[ks+1][m-1]==0&&a[ks+1][m+1]==0&&a[ks][m+1]==0&&m>=2)
{
a[ks][m]=0;
a[ks+2][m]=0;
a[ks+2][m+1]=0;
a[ks+1][m-1]=1;
a[ks+1][m+1]=1;
a[ks][m+1]=1;
l++;
min=min-1;
down=down-1;
goto end;
}
else
goto end;
}
case 1 :
{
if(a[ks][m-1]==0&&m>=2)
{
a[ks+1][m-1]=0;
a[ks+1][m+1]=0;
a[ks][m+1]=0;
a[ks][m-1]=1;
a[ks][m]=1;
a[ks+2][m]=1;
l++;
max=max-1;
down=down+1;
goto end;
}
else
goto end;
}
case 2 :
{
if(a[ks+1][m-1]==0&&a[ks+2][m-1]==0&&a[ks+1][m+1]==0&&m>=2)
{
a[ks][m-1]=0;
a[ks][m]=0;
a[ks+2][m]=0;
a[ks+1][m-1]=1;
a[ks+2][m-1]=1;
a[ks+1][m+1]=1;
l++;
max=max+1;
up=up+1;
goto end;
}
else
goto end;
}
case 3 :
{
if(a[ks][m]==0&&a[ks+2][m]==0&&a[ks+2][m+1]==0&&m<=7)
{
a[ks+1][m-1]=0;
a[ks+2][m-1]=0;
a[ks+1][m+1]=0;
a[ks][m]=1;
a[ks+2][m]=1;
a[ks+2][m+1]=1;
l=0;
min=min+1;
up=up-1;
goto end;
}
else
goto end;
}
}
}
case 3 :
switch(l)
{
case 0 :
{
if(a[ks+1][m-1]==0&&a[ks+1][m+1]==0&&a[ks+1][m+2]==0&&m>=2&&m<=6)
{
a[ks][m]=0;
a[ks+2][m]=0;
a[ks+3][m]=0;
a[ks+1][m-1]=1;
a[ks+1][m+1]=1;
a[ks+1][m+2]=1;
l++;
min=min-1;
max=max+2;
up=up+1;
down=down-2;
goto end;
}
else
goto end;
}
case 1 :
{
if(a[ks][m]==0&&a[ks+2][m]==0&&a[ks+3][m]==0)
{
a[ks+1][m-1]=0;
a[ks+1][m+1]=0;
a[ks+1][m+2]=0;
a[ks][m]=1;
a[ks+2][m]=1;
a[ks+3][m]=1;
l=0;
min=min+1;
max=max-2;
up=up-1;
down=down+2;
goto end;
}
else
goto end;
}
}
case 4 :
switch(l)
{
case 0 :
{
if(a[ks+1][m]==0&&a[ks+2][m]==0)
{
a[ks][m]=0;
a[ks+1][m+2]=0;
a[ks+1][m]=1;
a[ks+2][m]=1;
l++;
max=max-1;
down=down+1;
goto end;
}
else
goto end;
}
case 1 :
{
if(a[ks][m]==0&&a[ks+1][m+2]==0&&m<=6)
{
a[ks+1][m]=0;
a[ks+2][m]=0;
a[ks][m]=1;
a[ks+1][m+2]=1;
l=0;
max=max+1;
down=down-1;
goto end;
}
else
goto end;
}
}
case 5 :
switch(l)
{
case 0 :
{
if(a[ks+2][m+1]==0&&a[ks+1][m+2]==0)
{
a[ks][m]=0;
a[ks][m+2]=0;
a[ks+2][m+1]=1;
a[ks+1][m+2]=1;
l++;
min=min+1;
down=down+1;
goto end;
}
else
goto end;
}
case 1 :
{
if(a[ks+1][m]==0)
{
a[ks+2][m+1]=0;
a[ks+1][m]=1;
a[ks+1][m+2]=1;
l++;
min=min-1;
down=down-1;
goto end;
}
else
goto end;
}
case 2 :
{
if(a[ks+2][m+1]==0)
{
a[ks+1][m+2]=0;
a[ks+2][m+1]=1;
l++;
max=max-1;
down=down+1;
goto end;
}
else
goto end;
}
case 3 :
{
if(a[ks][m]==0&&a[ks][m+2]==0)
{
a[ks+1][m]=0;
a[ks+2][m+1]=0;
a[ks][m]=1;
a[ks][m+2]=1;
l=0;
max=max+1;
down=down-1;
goto end;
}
else
goto end;
}
}
case 6 :
switch(l)
{
case 0 :
{
if(a[ks+1][m+1]==0&&a[ks+2][m+1]==0)
{
a[ks][m+1]=0;
a[ks+1][m-1]=0;
a[ks+1][m+1]=1;
a[ks+2][m+1]=1;
l++;
min=min+1;
down=down+1;
goto end;
}
else
goto end;
}
case 1 :
{
if(a[ks][m+1]==0&&a[ks+1][m-1]==0&&m>=2&&m<=7)
{
a[ks+1][m+1]=0;
a[ks+2][m+1]=0;
a[ks][m+1]=1;
a[ks+1][m-1]=1;
l=0;
min=min-1;
down=down-1;
goto end;
}
else
goto end;
}
}
}
end:;
p=d;
d[0]=min;
d[1]=max;
d[2]=up;
d[3]=down;
d[4]=ks;
d[5]=m;
return p;
}
旋转之后的图我就不放上来了,因为我的循环出了问题导致输入一个字符就生成一个新的方块和原来旋转的方块连一起了看不清。
再就是移动函数
int *yidong(int a[][10],int m,char l,int min,int max,int up,int down,int ks)
{
int d[6],*p,flag=1;
switch(l)
{
case 'a' :
{
for(i=up;i<=down;i++)
{
for(j=min;j<=max;j++)
if(a[i][j]==1)
{
if(a[i][j-1]==0)
goto out;
else
{
flag=0;
goto und;
}
}
out:;
}
und:;
if(flag==1)
{
for(i=up;i<=down;i++)
for(j=min;j<=max;j++)
if(a[i][j]==1)
{
a[i][j-1]=1;
a[i][j]=0;
}
min=min-1;
max=max-1;
m=m-1;
}
break;
}
case 'd' :
{
for(i=up;i<=down;i++)
{
for(j=max;j>=min;j--)
if(a[i][j]==1)
{
if(a[i][j+1]==0)
goto eut;
else
{
flag=0;
goto uud;
}
}
eut:;
}
uud:;
if(flag==1)
{
for(i=up;i<=down;i++)
for(j=max;j>=min;j--)
if(a[i][j]==1)
{
a[i][j+1]=1;
a[i][j]=0;
}
min=min+1;
max=max+1;
m=m+1;
}
break;
}
case 's' :
{
for(j=min;j<=max;j++)
{
for(i=down;i>=up;i--)
if(a[i][j]==1)
{
if(a[i+1][j]==0)
goto rud;
else
{
flag=0;
goto tud;
}
}
rud:;
}
tud:;
if(flag==1)
for(j=min;j<=max;j++)
for(i=down;i>=up;i--)
if(a[i][j]==1)
{
a[i+1][j]=1;
a[i][j]=0;
}
up=up+1;
down=down+1;
ks=ks+1;
break;
}
}
d[0]=min;
d[1]=max;
d[2]=up;
d[3]=down;
d[4]=ks;
d[5]=m;
p=d;
printf("m=%d,min=%d,max=%d,up=%d,down=%d,ks=%d\n",m,min,max,up,down,ks);
return p;
}
这也没啥就是ks,min,max,uo,down会相应的改变
到了停止函数这里,我感觉函数没写错但运行就会出错
int tingzhi(int a[][10],int min,int max,int up,int down)
{
int flag=0;
for(j=min;j<=max;j++)
for(i=down;i>=up;i--)
if(a[i][j]==1)
if(a[i+1][j]!=0)
{
flag=1;
goto rrd;
}
rrd:;
if(flag==1)
for(j=min;j<=max;j++)
for(i=down;i>=up;i--)
if(a[i][j]==1)
a[i][j]=3;
printf("%d\n",flag);
return flag;
}
到了停止函数这里up,down,min,max就派上了用场,我通过对方块周围不超过它边界的坐标进行判断,判断方块下方是否是空格,只要有一个方块接触到底端都停止输入字符,将底端的方块坐标的值变成3,并且跳出循环生成新的方块
消除函数就是从下往上判断,最高到达第4排,判断是否有集满的一排,有就先将那一排的坐标全部清零,即变成空格,在讲在那一排上面的方块按原样下降一排
void xiaochu(int a[][10])
{
for(i=23;i>=4;i--)
{
for(j=1;j<=8;j++)
if(a[i][j]==0)
goto iid;
for(;i>=4;i--)
for(j=1;j<9;j++)
{
a[i][j]=a[i-1][j];
a[i-1][j]=0;
}
iid:;
}
}
结束函数,如果第三排都堆满的话游戏结束
int jieshu(int a[][10])
{
int flag=0;
for(i=3,j=1;j<9;j++)
{
if(a[i][j]==0)
flag=1;
}
return flag;
}
下面到了主函数
先是一堆声明和游戏开头
int main()
{
int flag=1,x,*p,*u,n,m,ks,min,max,up,down;
system("stty -icanon");
outloop:;
kaishi();
x=getchar();
printf("\n");
如果输入x=1的话游戏就开始了
if(x=='1')
{
do
{
up=ks=1;
do
{
p=shengcheng(a,up);
flag=*(p+5);
}while(flag==1);
n=*p;
m=*(p+1);
min=*(p+2);
max=*(p+3);
down=*(p+4);
printf("n=%d,m=%d,min=%d,max=%d,up=%d,down=%d,ks=%d,flag=%d\n",n,m,min,max,up,down,ks,flag);
jiemian(a);
do
{
l=getchar();
if(l==' ')
{
u=xuanzhuan(a,n,m,min,max,up,down,ks);
min=*u;
max=*(u+1);
up=*(u+2);
down=*(u+3);
ks=*(u+4);
m=*(u+5);
printf("\nmin=%d,max=%d,up=%d,down=%d,ks=%d,m=%d\n",min,max,up,down,ks,m);
}
else
{
u=yidong(a,m,l,min,max,up,down,ks);
min=*u;
max=*(u+1);
up=*(u+2);
down=*(u+3);
ks=*(u+4);
m=*(u+5);
printf("\nmin=%d,max=%d,up=%d,down=%d,ks=%d,m=%d\n",min,max,up,down,ks,m);
}
jiemian(a);
flag=tingzhi(a,min,max,up,down);
printf("%d\n",flag);
}while(flag==0);
xiaochu(a);
flag=jieshu(a);
}while(flag==1);
}
先定义up和ks为1,因为方块一定是从第一排开始的,生成函数有一个循环,防止方块出界,通过do~while循环判断方块是否还可以继续旋转或一定,一旦方块触底则不能在旋转或循环,因为旋转或循环的值都是等于1的值,而方块触底之后则已经变成了3,我觉得从这里开始就有问题了,因为它貌似不论方块是否触动,只要你一输入字符就直接跳出循环生成新方块了,因为一直卡在这里导致消除函数和结束函数都没有运行出来,然后就没有然后了。
图片长这样
按了空格之后转是转了,但是却跳出了循环生成了新的方块
困扰了我很久,想不通啊想不通!
我是一名大一新生,刚学完C语言就尝试做一些比较简单的小游戏,奈何水平有限,希望能得到大神的帮助,上面的用语如果有不专业的地方还请斧正!感谢!
来源:CSDN
作者:我是zcy啊
链接:https://blog.csdn.net/weixin_46249780/article/details/104620212