|  | 
 
 
 楼主|
发表于 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();
}
 | 
 |