|

楼主 |
发表于 2014-11-15 13:58:45
|
显示全部楼层
全部代码如下,运行有bug ,旋转会直接卡到边界里面去了,而且有时旋转会失灵,求解释
- #include<stdio.h>
- #include<conio.h>
- #include<malloc.h>
- #include<graphics.h>
- #define kuan 12
- #define gao 20
- typedef struct h //构建节点,a1,a2代表在矩阵中的坐标(a1,a2),x,y代表位移
- {
- int a1,a2,x,y;
- struct h *next;
- }h;
- typedef struct space //定义空间
- {
- int a[kuan][gao];
- }space;
- space *creatspace() //创建初始化空间,a[30][15]=0
- {
- int x,y;
- space *p;
- p=(space *)malloc(sizeof(space));
- for(x=0;x<kuan;x++)
- for(y=0;y<gao;y++)
- p->a[x][y]=0;
- return p;
- }
- void out(space *p) //空间输出
- {
- int x,y;
- for(x=0;x<kuan;x++)
- for(y=0;y<gao;y++)
- if(p->a[x][y]==1)
- {
-
- setcolor(YELLOW);
- bar(x*10,y*10,x*10+10,y*10+10);
- }
- }
- void outxiao(space *p) //空间输出
- {
- int x,y;
- for(x=0;x<kuan;x++)
- for(y=0;y<gao;y++)
- if(p->a[x][y]==1)
- {
-
- setcolor(BLACK);
- bar(x*10,y*10,x*10+10,y*10+10);
- }
- }
- h *creat(int n)
- {
- h *head,*p1,*p2,*p3,*p4;
- head=(h*)malloc(sizeof(h));
- p2=(h*)malloc(sizeof(h));
- p3=(h*)malloc(sizeof(h));
- p4=(h*)malloc(sizeof(h));
- p1=head;
- p1->next=p2;
- p2->next=p3;
- p3->next=p4;
- p4->next=NULL;
- p1->x=p2->x=p3->x=p4->x=p1->y=p2->y=p3->y=p4->y=2;
- if(n==0)
- {
- p1->a1=1;
- p1->a2=1;
- p2->a1=1;
- p2->a2=2;
- p3->a1=2;
- p3->a2=1;
- p4->a1=2;
- p4->a2=2;
-
-
-
-
- }
- if(n==1)
- {
- p1->a1=0;
- p1->a2=1;
- p2->a1=1;
- p2->a2=1;
- p3->a1=2;
- p3->a2=1;
- p4->a1=3;
- p4->a2=1;
- }
- if(n==2) //判定显示什么样的方块--|
- {
- p1->a1=0;
- p1->a2=0;
- p2->a1=0;
- p2->a2=1;
- p3->a1=0;
- p3->a2=2;
- p4->a1=1;
- p4->a2=2;
- }
- if(n==3)
- {
- p1->a1=0;
- p1->a2=1;
- p2->a1=1;
- p2->a2=1;
- p3->a1=1;
- p3->a2=2;
- p4->a1=2;
- p4->a2=1;
- }
- if(n==4)
- {
- p1->a1=0;
- p1->a2=1;
- p2->a1=1;
- p2->a2=1;
- p3->a1=1;
- p3->a2=2;
- p4->a1=2;
- p4->a2=2;
- }
- return head;
- }
- void xian(h *head) //显示
- {
- h *p;
- p=head;
- while(p!=0)
- {
- setfillcolor(GREEN);
- bar((p->a1+p->x)*10,(p->a2+p->y)*10,(p->a1+p->x)*10+10,(p->a2+p->y)*10+10);
- p=p->next;
- }
- }
- void xiao(h *head) //消失
- {
- h *p;
- p=head;
- while(p!=0)
- {
- setfillcolor(BLACK);
- bar((p->a1+p->x)*1,(p->a2+p->y)*10,(p->a1+p->x)*10+10,(p->a2+p->y)*10+10);
- p=p->next;
- }
- }
- void xuan(int n,space *p,h *head)
- /*
- 旋转
- n是显示方块的形状 0为长条,1为正方形,2。。。。
- space *p指向一个二维数组a[][]作为存储空间,储存已落地的方块,
- h *head存储方块在矩阵中的位置,如何在矩阵中(a1,a2),控制位移x,y;
- h *head 利用链表存储,遍历旋转
- 通过计算x+a1的坐标判定是否超越左边界,通过判定y+a2-1的坐标来判定是否超越右边界
- 通过判定旋转之后的坐标是否与当前存储空间的位置上冲突(判定当前空间p->a[x+a1][y+a2]是否为1)
- 是则反向旋转,令h *head 重新遍历,反向旋转,回到原位置。
- */
- {
-
- h*q; //定义一个指针,代替head指针遍历旋转
- q=head;
- int e=0; //判定指针,当需要回到原坐标时的判定
- int a; //a用于数值对换 a=b,b=c,c=a
- int max; //max 用于判定
- if(n<=1)max=3; //显示长条或正方形时矩阵旋转需要a[4][4]
- else max=2; //其他则为a[3][3]
-
- while(q!=0) //开始旋转
- { a=q->a1;
- q->a1=max-q->a2;
- q->a2=a;
- if(p->a[q->a1+q->x][q->a2+q->y]==1||(q->a1+q->x<0)||(q->a2+q->y>kuan))e++;
- /*旋转判定,是否越界或者与存储空间重合,是则判定+1
- 边界宽度宏定义为kuan*/
- q=q->next;
- }
- if(e!=0) //若显示上面的任意一项,则开始反向旋转
- { q=head; //重置
- while(q!=0)
- {
- a=q->a1;
- q->a1=q->a2;
- q->a2=max-a;
- q=q->next;
- }
-
- }
- }
- //方向开始
- void left(space *p,h *head)
- {
- h *q;
- int e=1;
- q=head;
- while(q!=NULL)
- {
- if((q->a1+q->x)<=0||p->a[q->a1+q->x-1][q->a2+q->y]==1) //判定是否碰到边界或本身就存在的方块
- { e=0;break; }
- else q=q->next;
- }
- q=head;
- while(e==1&&q!=NULL)
- {
- q->x=q->x-1;
- q=q->next;
- }
-
- }
- void right(space *p,h *head)
- {
- h *q;
- int e=1; //e为判定条件
- q=head;
- while(q!=NULL)
- {
- if((q->a1+q->x)>=kuan-1||p->a[q->a1+q->x+1][q->a2+q->y]==1) //判定是否碰到边界或本身就存在的方块
- { e=0;break; }
- else q=q->next;
- }
- q=head;
- while(e==1&&q!=NULL)
- {
- q->x=q->x+1;
- q=q->next;
- }
-
- }
- void down(h *head)
- {
- h *p;
- int e=0;
- p=head;
- while(p!=NULL)
- {
- p->y=p->y+1;
- if(p->a2+p->y==gao)e++;
- p=p->next;
- }
- if(e!=0)
- {
- while(p!=NULL)
- {
- p->y=p->y-1;
- p=p->next;
- }
- }
- }
- //方向结束
- int judge(space *p,h *head) //判定方块是否到底,交接存储,将方块的横纵坐标存入存储空间space中
- {
- int e=0,n=0;
- h *q;
- q=head;
- while(q!=NULL)
- {
- if(p->a[q->a1+q->x][q->a2+(q->y)+1]==1||(q->a2+q->y)==gao-1) //直接y的下一个已经有值或者到底了
- {
- e=1;
- if(q->a2+q->y==gao)n=1; //到底的话另外在判断
- }
- q=q->next;
-
- }
- if(e==1&&n==0) //碰边
- {
- q=head;
- while(q!=NULL)
- {
- p->a[q->a1+q->x][q->a2+q->y]=1;
-
- q=q->next;
- }
- }
- if(e==1&&n==1) //到底
- {
- q=head;
- while(q!=NULL)
- {
- p->a[q->a1+q->x][q->a2+q->y-1]=1;
-
- q=q->next;
- }
- }
- return e;
- }
- void man(space *p) //满层判定 函数p包含的是一个二维数组p[x][y],x表示宽度,y表示高度,当a[x][y]为1时,显示
- {
- int x,y,z,k; //z为计数器,k用于存储当前y值
- z=0;
- for(y=gao-1;y>=0;y--,z=0) //从底层开始判定,每次计数器清零,循环一次之后
- {
- for(x=0;x<kuan;x++) //每层判定,当前行为z=15时满值
- {
- if(p->a[x][y]==1)
- {
- z=z+1;
- }
- else break; //不为满值则直接跳出进行下一循环
- }
- if(z==kuan) //开始清除
- {
- for(k=y;k>0;k--)
- {
- for(x=0;x<kuan;x++)
- p->a[x][k]=p->a[x][k-1];
- }
- y=y+1; //过后重新运行当前行,因为当前行已经改变
-
- }
- }
-
- }
- void main()
- {
- int e=0;
- int n;
- int time=0;
- n=rand()%5;
- n=rand()%5;
- space *p;
- p=creatspace();
- h *head; //初始化开始
- initgraph(kuan*10,gao*10); //建立图像
- head=creat(n); // 创建新的方块
- while(1)
- { xian(head);
- out(p); //显示当前存储空间
- Sleep(100);
- xiao(head);
- time++;
- if(time==8)
- {
- down(head);
- time=0;
- }
- if(!kbhit())
- {
-
- }
- else
- {
- switch(getch()) //可以在这里直接增加判定,当向左或右或旋转时如果碰边则无效或返回前一个值
- { case 'w':xuan(n,p,head); break; //可以加个计时器,让旋转等操作与向下平行
- case 'a':left(p,head);break;
- case 'd':right(p,head);break;
- case 's':down(head);break;
- default :break;
- }
- }
-
-
- e=judge(p,head);
- if(e==1)
- {
- n=rand()%5;
- head=creat(n);
- e=0;
- }
- outxiao(p); //消除上一次的存储空间
- man(p); //满层判定
-
-
- } //while结束
- closegraph();
- }
复制代码 |
|