鱼C论坛

 找回密码
 立即注册
查看: 2970|回复: 18

卡在俄罗斯方块旋转上了,错在哪里了求指点,谢谢

[复制链接]
发表于 2014-11-15 12:09:11 | 显示全部楼层 |阅读模式
50鱼币
本帖最后由 漠水 于 2014-11-15 14:02 编辑
  1. void xuan(int n,space *p,h *head)
  2. /*
  3. 旋转
  4. n是显示方块的形状 0为长条,1为正方形,2。。。。
  5. space *p指向一个二维数组a[][]作为存储空间,储存已落地的方块,
  6. h *head存储方块在矩阵中的位置,如何在矩阵中(a1,a2),控制位移x,y;
  7. h *head 利用链表存储,遍历旋转
  8. 通过计算x+a1的坐标判定是否超越左边界,通过判定y+a2-1的坐标来判定是否超越右边界
  9. 通过判定旋转之后的坐标是否与当前存储空间的位置上冲突(判定当前空间p->a[x+a1][y+a2]是否为1)
  10. 是则反向旋转,令h *head 重新遍历,反向旋转,回到原位置。
  11. */
  12. {

  13. h*q; //定义一个指针,代替head指针遍历旋转
  14. q=head;
  15. int e=0; //判定指针,当需要回到原坐标时的判定
  16. int a; //a用于数值对换 a=b,b=c,c=a
  17. int max; //max 用于判定
  18. if(n<=1)max=3; //显示长条或正方形时矩阵旋转需要a[4][4]
  19. else max=2; //其他则为a[3][3]

  20. while(q!=0) //开始旋转
  21. { a=q->a1;
  22. q->a1=max-q->a2;
  23. q->a2=a;
  24. if(p->a[q->a1+q->x][q->a2+q->y]==1||(q->a1+q->x<0)||(q->a2+q->y>kuan-1))e++;
  25. /*旋转判定,是否越界或者与存储空间重合,是则判定+1
  26. 边界宽度宏定义为kuan*/
  27. q=q->next;
  28. }
  29. if(e!=0) //若越界或重合,则开始反向旋转
  30. { q=head; //重置
  31. while(q!=0)
  32. {
  33. a=q->a1;
  34. q->a1=q->a2;
  35. q->a2=max-a;
  36. q=q->next;
  37. }

  38. }
  39. }
复制代码

最佳答案

查看完整内容

a[10][10]至于你说的旋转,我是这样认为的 比如 图中的 “土”字, 首先他们是1,我们就在数组里面循环把它的坐标换一下,如果换完后的坐标 a[10] 如果 i
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-11-15 12:09:12 | 显示全部楼层
a[10][10]至于你说的旋转,我是这样认为的 比如  图中的 “土”字, 首先他们是1,我们就在数组里面循环把它的坐标换一下,如果换完后的坐标 a[i][10]  如果 i<0 那么 就把4个方块的i坐标 +1  如果还有i<1 那么继续+1  如果 i>9那么久-1.不知道能听懂吗?   
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-11-15 13:58:45 | 显示全部楼层
全部代码如下,运行有bug ,旋转会直接卡到边界里面去了,而且有时旋转会失灵,求解释
  1. #include<stdio.h>
  2. #include<conio.h>
  3. #include<malloc.h>
  4. #include<graphics.h>
  5. #define kuan  12
  6. #define gao   20

  7. typedef struct h        //构建节点,a1,a2代表在矩阵中的坐标(a1,a2),x,y代表位移
  8. {
  9. int a1,a2,x,y;            
  10. struct h *next;
  11. }h;

  12. typedef struct space         //定义空间
  13. {
  14.         int        a[kuan][gao];
  15. }space;


  16. space *creatspace()               //创建初始化空间,a[30][15]=0
  17. {
  18.         int x,y;
  19.         space *p;
  20.         p=(space *)malloc(sizeof(space));
  21.         for(x=0;x<kuan;x++)
  22.         for(y=0;y<gao;y++)
  23.                 p->a[x][y]=0;
  24.         return p;
  25. }


  26. void out(space *p)          //空间输出
  27. {
  28.         int x,y;
  29.                 for(x=0;x<kuan;x++)
  30.                 for(y=0;y<gao;y++)
  31.                 if(p->a[x][y]==1)
  32.                 {
  33.                
  34.                         setcolor(YELLOW);
  35.                         bar(x*10,y*10,x*10+10,y*10+10);
  36.                 }
  37. }

  38. void outxiao(space *p)          //空间输出
  39. {
  40.         int x,y;
  41.                 for(x=0;x<kuan;x++)
  42.                 for(y=0;y<gao;y++)
  43.                 if(p->a[x][y]==1)
  44.                 {
  45.                
  46.                         setcolor(BLACK);
  47.                         bar(x*10,y*10,x*10+10,y*10+10);
  48.                 }
  49. }

  50. h *creat(int n)
  51. {
  52. h *head,*p1,*p2,*p3,*p4;
  53. head=(h*)malloc(sizeof(h));
  54. p2=(h*)malloc(sizeof(h));
  55. p3=(h*)malloc(sizeof(h));
  56. p4=(h*)malloc(sizeof(h));
  57. p1=head;
  58. p1->next=p2;
  59. p2->next=p3;
  60. p3->next=p4;
  61. p4->next=NULL;
  62. p1->x=p2->x=p3->x=p4->x=p1->y=p2->y=p3->y=p4->y=2;

  63.     if(n==0)
  64.         {
  65.         p1->a1=1;
  66.         p1->a2=1;
  67.         p2->a1=1;
  68.         p2->a2=2;
  69.         p3->a1=2;
  70.         p3->a2=1;
  71.         p4->a1=2;
  72.         p4->a2=2;
  73.        
  74.        
  75.        
  76.        
  77.         }
  78.         if(n==1)
  79.         {
  80.         p1->a1=0;
  81.         p1->a2=1;
  82.         p2->a1=1;
  83.         p2->a2=1;
  84.         p3->a1=2;
  85.         p3->a2=1;
  86.         p4->a1=3;
  87.         p4->a2=1;               
  88.         }

  89.         if(n==2)                //判定显示什么样的方块--|
  90.         {
  91.         p1->a1=0;
  92.         p1->a2=0;
  93.         p2->a1=0;
  94.         p2->a2=1;
  95.         p3->a1=0;
  96.         p3->a2=2;
  97.         p4->a1=1;
  98.         p4->a2=2;

  99.         }

  100.         if(n==3)
  101.                         {
  102.         p1->a1=0;
  103.         p1->a2=1;
  104.         p2->a1=1;
  105.         p2->a2=1;
  106.         p3->a1=1;
  107.         p3->a2=2;
  108.         p4->a1=2;
  109.         p4->a2=1;

  110.         }
  111.         if(n==4)
  112.                         {
  113.         p1->a1=0;
  114.         p1->a2=1;
  115.         p2->a1=1;
  116.         p2->a2=1;
  117.         p3->a1=1;
  118.         p3->a2=2;
  119.         p4->a1=2;
  120.         p4->a2=2;

  121.         }



  122. return head;
  123. }



  124. void xian(h *head)                      //显示
  125. {
  126.         h *p;
  127.         p=head;
  128.         while(p!=0)
  129.         {
  130.                 setfillcolor(GREEN);
  131.                 bar((p->a1+p->x)*10,(p->a2+p->y)*10,(p->a1+p->x)*10+10,(p->a2+p->y)*10+10);
  132.                 p=p->next;
  133.         }
  134. }


  135. void xiao(h *head)                      //消失
  136. {
  137.         h *p;
  138.         p=head;
  139.         while(p!=0)
  140.         {
  141.                 setfillcolor(BLACK);
  142.                 bar((p->a1+p->x)*1,(p->a2+p->y)*10,(p->a1+p->x)*10+10,(p->a2+p->y)*10+10);
  143.                 p=p->next;
  144.         }
  145. }


  146. void xuan(int n,space *p,h *head)                     
  147. /*
  148. 旋转
  149.   n是显示方块的形状 0为长条,1为正方形,2。。。。
  150.   space *p指向一个二维数组a[][]作为存储空间,储存已落地的方块,
  151. h *head存储方块在矩阵中的位置,如何在矩阵中(a1,a2),控制位移x,y;
  152. h *head 利用链表存储,遍历旋转
  153. 通过计算x+a1的坐标判定是否超越左边界,通过判定y+a2-1的坐标来判定是否超越右边界
  154. 通过判定旋转之后的坐标是否与当前存储空间的位置上冲突(判定当前空间p->a[x+a1][y+a2]是否为1)
  155.    是则反向旋转,令h *head 重新遍历,反向旋转,回到原位置。
  156.          */
  157. {
  158.   
  159.         h*q;              //定义一个指针,代替head指针遍历旋转
  160.         q=head;
  161.         int e=0;          //判定指针,当需要回到原坐标时的判定
  162.         int a;             //a用于数值对换 a=b,b=c,c=a
  163.         int max;            //max 用于判定
  164.         if(n<=1)max=3;      //显示长条或正方形时矩阵旋转需要a[4][4]
  165.         else max=2;                //其他则为a[3][3]
  166.        
  167.         while(q!=0)       //开始旋转
  168.         {        a=q->a1;
  169.                 q->a1=max-q->a2;
  170.                 q->a2=a;
  171.                 if(p->a[q->a1+q->x][q->a2+q->y]==1||(q->a1+q->x<0)||(q->a2+q->y>kuan))e++;           
  172.                 /*旋转判定,是否越界或者与存储空间重合,是则判定+1
  173.                 边界宽度宏定义为kuan*/
  174.                 q=q->next;               
  175.         }
  176.     if(e!=0)        //若显示上面的任意一项,则开始反向旋转
  177.         {        q=head;                            //重置
  178.           while(q!=0)
  179.           {
  180.                    a=q->a1;
  181.                 q->a1=q->a2;
  182.                 q->a2=max-a;
  183.                 q=q->next;
  184.           }
  185.          
  186.         }
  187. }

  188. //方向开始

  189. void left(space *p,h *head)
  190. {
  191.         h *q;
  192.         int e=1;
  193.         q=head;
  194.         while(q!=NULL)      
  195.         {       
  196.         if((q->a1+q->x)<=0||p->a[q->a1+q->x-1][q->a2+q->y]==1)      //判定是否碰到边界或本身就存在的方块   
  197.         {        e=0;break; }     
  198.     else  q=q->next;
  199.         }

  200.         q=head;
  201.         while(e==1&&q!=NULL)
  202.         {
  203.         q->x=q->x-1;
  204.         q=q->next;
  205. }
  206.        
  207. }

  208. void right(space *p,h *head)
  209. {
  210.         h *q;
  211.         int e=1;                                                         //e为判定条件
  212.         q=head;
  213.         while(q!=NULL)      
  214.         {       
  215.         if((q->a1+q->x)>=kuan-1||p->a[q->a1+q->x+1][q->a2+q->y]==1)    //判定是否碰到边界或本身就存在的方块   
  216.         {        e=0;break; }     
  217.     else  q=q->next;
  218.         }

  219.         q=head;
  220.         while(e==1&&q!=NULL)
  221.         {
  222.         q->x=q->x+1;
  223.         q=q->next;
  224. }
  225.        
  226. }


  227. void down(h *head)
  228. {
  229. h *p;
  230. int e=0;
  231. p=head;
  232.         while(p!=NULL)
  233.         {
  234.         p->y=p->y+1;
  235.         if(p->a2+p->y==gao)e++;
  236.         p=p->next;
  237.         }
  238. if(e!=0)
  239. {
  240.         while(p!=NULL)
  241.         {
  242.         p->y=p->y-1;
  243.         p=p->next;
  244.         }
  245. }
  246. }
  247. //方向结束


  248. int judge(space *p,h *head)                   //判定方块是否到底,交接存储,将方块的横纵坐标存入存储空间space中
  249. {
  250.         int e=0,n=0;
  251.         h *q;
  252.         q=head;
  253.         while(q!=NULL)
  254.                 {
  255.                         if(p->a[q->a1+q->x][q->a2+(q->y)+1]==1||(q->a2+q->y)==gao-1) //直接y的下一个已经有值或者到底了
  256.                         {   
  257.                                 e=1;                    
  258.                         if(q->a2+q->y==gao)n=1;                                    //到底的话另外在判断
  259.                         }                           
  260.                         q=q->next;

  261.                                                           
  262.                 }
  263.                 if(e==1&&n==0)                             //碰边
  264.                 {
  265.                         q=head;
  266.                         while(q!=NULL)
  267.                         {
  268.                                 p->a[q->a1+q->x][q->a2+q->y]=1;
  269.        
  270.                                 q=q->next;
  271.                         }
  272.                 }
  273.                 if(e==1&&n==1)                          //到底
  274.                 {
  275.                         q=head;
  276.                         while(q!=NULL)
  277.                         {
  278.                                 p->a[q->a1+q->x][q->a2+q->y-1]=1;
  279.                        
  280.                                 q=q->next;
  281.                         }
  282.                 }
  283.                 return e;
  284. }

  285. void man(space *p)                //满层判定  函数p包含的是一个二维数组p[x][y],x表示宽度,y表示高度,当a[x][y]为1时,显示
  286. {
  287.         int x,y,z,k;                 //z为计数器,k用于存储当前y值
  288.         z=0;       
  289.         for(y=gao-1;y>=0;y--,z=0)            //从底层开始判定,每次计数器清零,循环一次之后
  290.         {
  291.                 for(x=0;x<kuan;x++)                 //每层判定,当前行为z=15时满值
  292.                 {
  293.                         if(p->a[x][y]==1)
  294.                         {
  295.                         z=z+1;
  296.                         }
  297.                         else break;                      //不为满值则直接跳出进行下一循环
  298.                 }

  299.                 if(z==kuan)                            //开始清除
  300.                 {
  301.                         for(k=y;k>0;k--)               
  302.                         {
  303.                                 for(x=0;x<kuan;x++)
  304.                                 p->a[x][k]=p->a[x][k-1];        
  305.                         }
  306.                         y=y+1;                           //过后重新运行当前行,因为当前行已经改变
  307.                        
  308.                 }
  309.         }

  310.        
  311. }

  312. void main()
  313. {   
  314.         int e=0;
  315.         int n;
  316.         int time=0;
  317.         n=rand()%5;
  318.         n=rand()%5;
  319.         space *p;
  320.         p=creatspace();
  321.     h *head;                                                                //初始化开始
  322.         initgraph(kuan*10,gao*10);                                //建立图像
  323.         head=creat(n);                                                        //  创建新的方块
  324.         while(1)       
  325.         {        xian(head);
  326.                 out(p);                    //显示当前存储空间
  327.                 Sleep(100);
  328.                 xiao(head);
  329.                 time++;
  330.                   if(time==8)
  331.           {
  332.            down(head);
  333.            time=0;
  334.           }
  335.                 if(!kbhit())
  336.                 {
  337.                
  338.                 }
  339.                 else
  340.                 {
  341.                         switch(getch())                                                                         //可以在这里直接增加判定,当向左或右或旋转时如果碰边则无效或返回前一个值
  342.                         {        case 'w':xuan(n,p,head); break;               //可以加个计时器,让旋转等操作与向下平行
  343.                                 case 'a':left(p,head);break;
  344.                                 case 'd':right(p,head);break;
  345.                                 case 's':down(head);break;
  346.                                 default :break;       
  347.                         }
  348.                 }
  349.    
  350.        
  351.                 e=judge(p,head);
  352.                 if(e==1)
  353.                 {
  354.             n=rand()%5;
  355.                         head=creat(n);
  356.                         e=0;
  357.                 }
  358.                 outxiao(p);                 //消除上一次的存储空间
  359.                 man(p);                    //满层判定

  360.        
  361.             
  362.         }                                                        //while结束

  363.     closegraph();

  364. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

头像被屏蔽
发表于 2014-12-2 20:05:40 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-23 13:38:14 | 显示全部楼层
楼主 我看了你的问题我就写了个俄罗斯方块
Z]6F{NXSIL6~C`V1~[{G592.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-23 13:45:39 | 显示全部楼层
首先说下我的思路, 定义一个数组 初始化为0; 方块为1;落下后为2;
Z]6F{NXSIL6~C`V1~[{G592.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-12-23 16:18:28 | 显示全部楼层
735899422 发表于 2014-12-23 13:45
首先说下我的思路, 定义一个数组 初始化为0; 方块为1;落下后为2;

旋转的问题我已经解决了,还是有点其他的小毛病,这帖子感觉过去好久了,不过还是要谢谢你的解答。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-24 09:00:43 | 显示全部楼层
什么小毛病、
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-12-24 11:27:39 | 显示全部楼层
本帖最后由 漠水 于 2014-12-24 11:29 编辑

还是有点不懂,能不能把代码发一下,看看,谢谢哈
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-12-24 11:29:57 | 显示全部楼层

还是有点不懂,能不能把代码发一下,看看,谢谢哈
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-24 11:31:49 | 显示全部楼层
哪里不懂?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-24 11:32:53 | 显示全部楼层
我的代码只写了一半就不想写了 麻烦 你哪里不懂?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-24 11:36:59 | 显示全部楼层
漠水 发表于 2014-12-24 11:29
还是有点不懂,能不能把代码发一下,看看,谢谢哈

旋转越界不懂吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-12-24 11:39:38 | 显示全部楼层
735899422 发表于 2014-12-24 11:32
我的代码只写了一半就不想写了 麻烦 你哪里不懂?

就是一个反应的机制问题,是下降的时间的控制与按键操作的配合,主要就是一个时间差问题,比如我这个程序如果一直向右的话也会右下角而非右边。不过我已经不纠结这个了,还是非常感谢。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-12-24 11:41:49 | 显示全部楼层
本帖最后由 漠水 于 2014-12-24 11:44 编辑
735899422 发表于 2014-12-24 11:36
旋转越界不懂吗?


恩,我主要是看不出来程序中的旋转越界的操作错在了哪一个步骤上,哪一行,应该说我不怎么会试调,比较不是纯业余的。
具体点说就是:不知道在旋转的时候,判定条件按道理来说应该可以啊,怎么会越界出去呢?还是说存储空间的判定条件出错了?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-24 11:44:00 | 显示全部楼层
你用的是kbhit() 吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-24 11:44:39 | 显示全部楼层
漠水 发表于 2014-12-24 11:39
就是一个反应的机制问题,是下降的时间的控制与按键操作的配合,主要就是一个时间差问题,比如我这个程序 ...

你用的是kbhit() 吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-12-24 11:45:36 | 显示全部楼层
735899422 发表于 2014-12-24 11:44
你用的是kbhit() 吗?

呃,是啊,因为只会学到什么用什么,难道有什么问题吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-24 11:51:27 | 显示全部楼层
漠水 发表于 2014-12-24 11:45
呃,是啊,因为只会学到什么用什么,难道有什么问题吗?

没问题 我也是用的这个
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-18 11:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表