俄罗斯方块代码解析

  1 #include<stdio.h>  
  2  #include<stdlib.h>  
  3 #include<windows.h>  
  4 #include<time.h>  
  5 #include<conio.h>     
  6  #define MOD 28  //28种模式
  7 #define SIZE_N 19  //设置高度和宽度
  8 #define SIZE_M 12     
  9 int cur_x,cur_y;  
 10 int score,mark,next,map[SIZE_N][SIZE_M],Gamespeed=3000; //设置下落速度
 11  int shape[28][6]=//一共7种方法,加上旋转4种形状,28种,另外坐标本是8位,因总有小方块坐标在原点,故省去
 12  {
 13 
 14      {0,-1,0,-2,1,0}, {0,1,1,0,2,0}, {-1,0,0,1,0,2}, {0,-1,-1,0,-2,0},  
 15 
 16      {0,-1,0,1,-1,0}, {0,1,1,0,-1,0}, {1,0,0,-1,0,1}, {1,0,-1,0,0,-1},  
 17 
 18      {-1,1,0,1,1,0}, {0,-1,1,0,1,1}, {-1,0,0,-1,1,-1}, {-1,-1,-1,0,0,1},  
 19 
 20     {-1,0,0,1,1,1}, {0,1,1,-1,1,0}, {-1,0,0,1,1,1}, {0,1,1,-1,1,0},  
 21 
 22     {-1,0,0,-1,0,-2}, {-1,0,-2,0,0,1}, {0,1,0,2,1,0}, {0,-1,1,0,2,0},  
 23 
 24     {0,1,1,0,1,1}, {0,-1,1,0,1,-1}, {-1,0,0,-1,-1,-1}, {-1,0,-1,1,0,1},  
 25 
 26      {0,1,0,2,0,3}, {1,0,2,0,3,0}, {0,-1,0,-2,0,-3}, {-1,0,-2,0,-3,0}  
 27 
 28  };  
 29     
 30  void gotoxy(int x,int y)//gotoxy本是TC中system.h库文件里的一个函数,但在VC不可直接用,故需如此定义,直接跳转到某个坐标
 31  {
 32      COORD c;  
 33      c.X=x-1; c.Y=y-1;  
 34      SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c); 
 35  }  
 36 
 37  void Gameover()//对游戏结束进行判断
 38  {
 39     int i,j,flag=0;  
 40      for(j=1;j<SIZE_M-1;j++)
 41      {  
 42          if(map[1][j]!=0)
 43          {  
 44             flag=1;
 45             break;  //跳出整个for循环
 46         }  
 47      }  
 48      if(flag==1)
 49      {  
 50          for(i=1;i<SIZE_N-1;i++)
 51          {  
 52              gotoxy(2,i+1);  
 53              for(j=1;j<SIZE_M-1;j++)
 54              {  
 55                  printf("");  
 56             }
 57              puts("");  
 58          }  
 59          gotoxy(7,9);  
 60          printf("GAME OVER!");  
 61          gotoxy(1,SIZE_N+1);  
 62          exit(0);  
 63      }  
 64 
 65  }  
 66 
 67  void ShowMap(int id)//设置整个方块的活动区域
 68  {  
 69      int i,j;  
 70      gotoxy(1,1);  
 71      if(id!=-1)
 72      {  
 73          for(i=0;i<SIZE_N;i++)
 74          {  
 75              for(j=0;j<SIZE_M;j++)
 76              {  
 77                  if(i==0&&j==0 || i==0&&j==SIZE_M-1 || j==0&&i==SIZE_N-1 || j==SIZE_M-1&&i==SIZE_N-1)
 78                      printf(" "); 
 79                  else 
 80                      if(i==0 || i==SIZE_N-1)
 81                          printf("--"); 
 82                  else 
 83                      if(j==0 || j==SIZE_M-1)
 84                          printf("|");  
 85                  else 
 86                      if(map[i][j]==2)
 87                          printf("");  
 88                  else // cur_x=0; cur_y=5;
 89                      if(i==cur_x+shape[id][0] && j==cur_y+shape[id][1] ||  
 90                         i==cur_x+shape[id][2] && j==cur_y+shape[id][3] ||  
 91                         i==cur_x+shape[id][4] && j==cur_y+shape[id][5] ||  
 92                         i==cur_x && j==cur_y)  
 93                      printf("");  
 94                  else 
 95                      if(map[i][j]==0) 
 96                          printf("  ");   
 97              }  
 98              if(i==1)printf("   next:");  
 99              if(i==11)printf("   score :   %d",score);  
100              if(i==14)printf("   speed :   %d",score/100+1);  
101              puts("");  
102          }  
103      }  
104      else {  
105          mark=1;  
106          for(i=0;i<SIZE_N;i++)
107          {  
108              for(j=0;j<SIZE_M;j++)
109              {  
110                  if(i==0&&j==0 || i==0&&j==SIZE_M-1 || j==0&&i==SIZE_N-1 || j==SIZE_M-1&&i==SIZE_N-1)
111                      printf(" ");  
112                  else 
113                     if(i==0 || i==SIZE_N-1)
114                      printf("--");  
115                 else 
116                     if(j==0 || j==SIZE_M-1)
117                         printf("|");  
118                  else 
119                     if(map[i][j]==2) 
120                          printf("");  
121                 else 
122                     if(map[i][j]==0) 
123                         printf("  ");   
124             }  
125              if(i==1)
126                  printf("   next:");  
127              if(i==11)
128                  printf("   score :   %d",score);  
129             if(i==14)
130                 printf("   speed :   %d",score/100+1);  
131             puts("");  
132          }  
133      }  
134 
135      /*对于 next 方块的处理,先擦除再画图*/ 
136      gotoxy(30,6);
137      printf("  ");  
138     for(i=0;i<6;i=i+2)
139     {  
140          gotoxy(30+2*shape[id][i+1],6+shape[id][i]);
141          printf("  ");  
142     }  
143      gotoxy(30,6);
144      printf("");  
145      for(i=0;i<6;i=i+2)
146      {  
147          gotoxy(30+2*shape[next][i+1],6+shape[next][i]);
148          printf(""); 
149      }  
150      Sleep(Gamespeed); //Sleep()定时停顿时间
151  }  
152 
153     
154 
155  void init(int id)//初始化函数,cur_x,cur_y是全局变量,标记了移动方块的位置
156  {
157  int i,j;  
158      memset(map,0,sizeof(map));//将map元素全部初始化为0
159      for( i=0;i<SIZE_N;i++)
160      {  
161          for( j=0;j<SIZE_M;j++)  
162              if(i==SIZE_N-1 || j==0 || j==SIZE_M-1) //靠近最顶端设置为-1 
163                  map[i][j]=-1;  
164      }  
165      cur_x=0; cur_y=5; //初始化 
166      ShowMap(id);  
167  }  
168 
169     
170 
171  int judge_in(int x,int y,int id){/*/判断是否出界,或者说是否合法*/ 
172 
173      int i;  
174      if(map[x][y]!=0)
175         return 0;  
176      for( i=0;i<6;i=i+2)
177      {  
178          if(map[ x+shape[id][i] ][ y+shape[id][i+1] ]!=0)
179              return 0;  
180      }
181      return 1;  
182  }  
183 
184     
185 
186  void fun_score()
187  {
188      //得分,擦除行的闪烁,还有图形的向下平移
189  int i,j,flag=0;  
190  int k,ii,jj;  
191      for( i=1;i<SIZE_N-1;i++)
192      {  
193       flag=0;  
194          for(j=1;j<SIZE_M-1;j++)
195          {  
196              if(map[i][j]!=2)
197              { 
198                  flag=1;
199                  break; 
200              }  
201          }  
202          if(flag==0)
203          {  
204               k=3;  
205              while(k--)
206             {  
207                 gotoxy(2,i+1);  
208                 for( ii=1;ii<SIZE_M-1;ii++)
209                 {  
210                     if(map[i][ii]==2)
211                     {  
212                          if(k%2==1)
213                          printf("  ");  
214                          else printf("");  
215                      }  
216                  }
217                 Sleep(100);  
218             }  
219              for( ii=i;ii>1;ii--)
220              {  
221 
222                  for(jj=1;jj<SIZE_M-1;jj++)
223                      map[ii][jj]=map[ii-1][jj];  
224              }  
225              ShowMap(-1);  
226             score+=10;  
227             if(score%100==0 && score!=0)
228                 Gamespeed-=50;  
229          }  
230 
231      }  
232 
233  }  
234 
235     
236 
237  int main(){  
238 
239      int i,id,set=1;  
240      srand(time(NULL)); //srand((unsigned)time(NULL))设置随机种子
241      id=rand()%MOD; //分配随机数id值
242      next=rand()%MOD; //next值
243      init(id);  //id
244      while(1)
245      {  
246  Here:   mark=0; //进行goto语句的使用,分数设置为0
247          if(set==0)
248          {  
249             id=next;  
250              next=rand()%MOD; 
251              next=(next+MOD)%MOD; 
252              cur_x=0;cur_y=5;  
253              set=1;  
254         }  
255         while(!kbhit())//kbhit默认为0
256         {  
257             Gameover(); //调用Gameover()函数 
258              if(judge_in(cur_x+1,cur_y,id)==1)
259                  cur_x++;  
260              else 
261              {  
262                  map[cur_x][cur_y]=2;  
263                  for(i=0;i<6;i=i+2)  
264                      map[ cur_x+shape[id][i] ][ cur_y+shape[id][i+1] ]=2;  
265                 fun_score();  
266                  set=0;  
267              }  
268             if(mark!=1)
269                 ShowMap(id);  
270             goto Here;  
271 
272          }/*/end of while(!kbhit())*/ 
273          char key;  
274          key=getch();  
275          if(key==72){  
276             int tmp=id;  
277             id++;  
278              if( id%4==0 && id!=0 )
279                  id=id-4;  
280             if(judge_in(cur_x,cur_y,id)!=1)
281                 id=tmp;  
282          }  
283          else if(key==80 && judge_in(cur_x+1,cur_y,id)==1)
284              cur_x++; 
285          else if(key==75 && judge_in(cur_x,cur_y-1,id)==1)
286              cur_y--;  
287         else if(key==77 && judge_in(cur_x,cur_y+1,id)==1)
288             cur_y++;  
289         else if(key==27)
290         {
291             gotoxy(1,SIZE_N+1);
292             exit(0);
293         }  
294      }  
295      return 0;   
296  } 

         
         
   

(0,2)

   
   

(0,1)

   

(-2,0)

(-1,0)

(0,0)

(1,0)

(2,0)

   

(0,-1)

   
   

(0,-2)

   
         
         
         
    1. 每个坐标代表一个方块样式,一共有28组坐标,代表28个方块式样。

      2.由于在控制台下,光标的初始位置一般是在左上角,所以这里以左上角为原点(0,0),向下为X轴正方向,向右为Y轴正方向。

      3.每组坐标有6个数字,实际上有8个数字,只是因为第一位和第二位恒为0,故省略。这样,从第一位开始,每相邻的两个数字为一组,一共得到4组坐标,即为俄罗斯方块中的小方块坐标(常规俄罗斯方块一共有4个小方块)。

      4.你可以动手画一画。例如:{-1,0,0,1,0,2},细分为:(x1=0,y1=0),(x2=-1,y2=0),(x3=0,y3=1),(x4=0,y4=2).如图:
原文地址:https://www.cnblogs.com/Zblogs/p/zblogs.html