俄罗斯方块

      上学期看到学长写了一个贪吃蛇,就一直想要做一个不同的游戏,当时觉得写出来并不是不可能,可还是因为能力有限,很多东西都不懂,就放弃了这个想法。这学期还没开始,就一直心想着编一个俄罗斯方块出来,可是当我真正开始的时候,才发现没有那么简单,什么头绪也没有就开始凭着感觉去写。大干花了两个晚上的时间写了大概有100~200行代码,再回过头来去看那个贪吃蛇的代码,发现自己写的完全什么用也没有。没办法只有全部删掉,先研究研究再从头开始。

      在中途也碰到过很多问题,有一段时间就干脆不去管它,搁置了大概有一两周的时间,之后开始写才一点一点理清思路,写各种函数(由于对c++还算是没入门,只能用c语言写下去了),再考虑各种情况,再一点一点拼凑起来,总算是把他给摆平了。不过到现在也还是有各种BUG,还希望多多见谅。(实在是不好找错了)。没事了可以拿去玩一玩。还希望各位指出其中的BUG,容小菜再去改一改。。。

      从这500行的代码中,其实感觉自己也没用到什么新东西,不懂得直接调用别人的,其他的基本上都是FOR循环以及IF和ELSE,所以这不算什么学到很多新知识,但是有一点,就是从这么长的代码中明白一点,就是如何去管理这样长的代码:用容易理解的函数名以及变量名;各种函数的功能明确;如何去安排每个细节;然后就是一点一点耐心的调试,一边调试一边编写。。。。还是很有收获的!!!

游戏图片:(高手勿喷!!!)

 

 

代码

  1 /*******************************/
  2    /******Writer:   GJ      *******/
  3    /******Language: C       *******/
  4    /******Date:   2013 3 23 *******/
  5    /*******************************/
  6    #include<iostream>
  7    #include<stdio.h>
  8    //#include<conio.h>
  9    #include<string.h>
 10    #include<time.h>
 11    #include<stdlib.h>
 12    #include<windows.h>
 13    using namespace std;
 14    #define me(a) memset(a,0,sizeof(a))
 15    #define judge(bl,ok) for(i=0;i<5;i++)if(bl[i].x&&map[bl[i].x][bl[i].y])ok=0
 16    #define is_pure(node,ok) if(map[node.x][node.y])ok=0
 17    const int HEIGHT=24,LENGTH=40,SIDE=22;
 18  
 19    char INIT_MAP[HEIGHT+1][LENGTH+1];
 20    int map[HEIGHT][SIDE];
 21    struct node{int x,y;int color;};
 22    const int TIME_DWELL=1000;
 23    int state=0;
 24  
 25    /**********获取句柄**********/
 26    HANDLE Output=GetStdHandle(STD_OUTPUT_HANDLE);
 27    HANDLE Input=GetStdHandle(STD_INPUT_HANDLE);
 28  
 29    /**********设置光标位置**********/
 30    void SetCursor(int x,int y){
 31        COORD cd={x,y};
 32        SetConsoleCursorPosition(Output,cd);
 33    }
 34  
 35    /**************初始化图**************/
 36    void INITMAP()
 37    {
 38        for(int i=0;i<HEIGHT;i++)
 39            for(int j=0;j<SIDE;j++){
 40                if(i==0||i==HEIGHT-1||j==0||j==SIDE-1)map[i][j]=1;
 41                else map[i][j]=0;
 42            }
 43    }
 44  
 45    /********右上方提前显示方块******/
 46    node bl[5];
 47    void Former_Print_block(int n)
 48    {
 49        int i;
 50        for(i=0;i<5;i++){bl[i].x=bl[i].y=0;}
 51        if(n==0){
 52            bl[0].x=3,bl[0].y=28;  bl[1].x=3,bl[1].y=30;
 53            bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=32;
 54        }
 55        if(n==1){
 56            bl[0].x=3,bl[0].y=32;  bl[1].x=3,bl[1].y=30;
 57            bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=28;
 58        }
 59        if(n==2){
 60            bl[0].x=3,bl[0].y=30;  bl[1].x=4,bl[1].y=28;
 61            bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=32;
 62        }
 63        if(n==3){
 64            bl[0].x=3,bl[0].y=27;   bl[1].x=3,bl[1].y=29;
 65            bl[2].x=3,bl[2].y=31;  bl[3].x=3,bl[3].y=33;
 66        }
 67        if(n==4){
 68            bl[0].x=3,bl[0].y=29;  bl[1].x=3,bl[1].y=31;
 69            bl[2].x=4,bl[2].y=29;  bl[3].x=4,bl[3].y=31;
 70        }
 71        if(n==5){
 72            bl[0].x=3,bl[0].y=28;  bl[1].x=4,bl[1].y=28;
 73            bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=32;
 74        }
 75        if(n==6){
 76            bl[0].x=3,bl[0].y=32;  bl[1].x=4,bl[1].y=28;
 77            bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=32;
 78        }
 79        for(i=0;i<5;i++){
 80            SetCursor(bl[i].y,bl[i].x);
 81            printf("");
 82        }
 83    }
 84  
 85    /*********获取不同的方块,出现在中间***********/
 86    node block[5];//全局使用的核心!!!
 87    void print_block(int n)
 88    {int i;
 89        for(i=0;i<5;i++){block[i].x=block[i].y=0;}
 90        if(n==0){
 91            block[0].x=1,block[0].y=7;   block[1].x=1,block[1].y=9;
 92            block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
 93        }
 94        if(n==1){
 95            block[0].x=1,block[0].y=11;  block[1].x=1,block[1].y=9;
 96            block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=7;
 97        }
 98        if(n==2){
 99            block[0].x=1,block[0].y=9;  block[1].x=2,block[1].y=7;
100            block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
101        }
102        if(n==3){
103            block[0].x=1,block[0].y=7;   block[1].x=1,block[1].y=9;
104            block[2].x=1,block[2].y=11;  block[3].x=1,block[3].y=13;
105        }
106        if(n==4){
107            block[0].x=1,block[0].y=9;  block[1].x=1,block[1].y=11;
108            block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
109        }
110        if(n==5){
111            block[0].x=1,block[0].y=7;  block[1].x=2,block[1].y=7;
112            block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
113        }
114        if(n==6){
115            block[0].x=1,block[0].y=11;  block[1].x=2,block[1].y=7;
116            block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
117        }
118        for(i=0;i<5;i++){
119            SetCursor(block[i].y,block[i].x);
120            printf("");
121        }
122    }
123  
124  
125    /*************按 上 键 旋转*************/
126    void Exchange(int m)
127    {
128        int i,ok=1;
129        node blo[5];
130        for(i=0;i<5;i++)blo[i]=block[i];
131        if(m==0){
132            if(state==0){
133                blo[0].x+=1;blo[0].y+=2;blo[2].x-=1;blo[2].y+=2;blo[3].x-=2;
134                judge(blo,ok);
135                if(map[blo[0].x][blo[0].y-2])ok=0;
136                if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=1;}
137            }
138            else{
139                blo[0].x-=1;blo[0].y-=2;blo[2].x+=1;blo[2].y-=2;blo[3].x+=2;
140                judge(blo,ok);
141                if(map[blo[1].x-1][blo[1].y])ok=0;
142                if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=0;}
143            }
144        }
145        else if(m==1){
146            if(state==0){
147                blo[0].x-=1;blo[0].y-=2;blo[2].x-=1;blo[2].y+=2;blo[3].y+=4;
148                judge(blo,ok);
149                if(map[blo[1].x][blo[1].y-2])ok=0;
150                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;}
151            }
152            else {
153                blo[0].x+=1;blo[0].y+=2;blo[2].x+=1;blo[2].y-=2;blo[3].y-=4;
154                judge(blo,ok);
155                if(map[blo[0].x-1][blo[0].y])ok=0;
156                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;}
157            }
158        }
159        else if(m==2)
160        {
161            if(state==0)
162            {
163                blo[0].x+=1;blo[0].y-=2; blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2;
164                judge(blo,ok);
165                if(map[blo[0].x+1][blo[0].y]||map[blo[0].x-1][block[0].y]||map[blo[3].x][blo[3].y+2])ok=0;
166                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;}
167            }
168            else if(state==1)
169            {
170                blo[0].x+=1;blo[0].y+=2; blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2;
171                judge(blo,ok);
172                if(map[blo[0].x][blo[0].y+2]||map[blo[0].x][blo[0].y-2]||map[blo[3].x-1][blo[3].y])ok=0;
173                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=2;}
174            }
175            else if(state==2)
176            {
177                blo[0].x-=1;blo[0].y+=2; blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2;
178                judge(blo,ok);
179                if(map[blo[0].x+1][blo[0].y]||map[blo[0].x-1][blo[0].y]||map[blo[3].x][blo[3].y-2])ok=0;
180                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=3;}
181            }
182            else{
183                blo[0].x-=1;blo[0].y-=2; blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2;
184                judge(blo,ok);
185                if(map[blo[0].x][blo[0].y+2]||map[blo[0].x][blo[0].y-2]||map[blo[3].x+1][blo[1].y])ok=0;
186                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;}
187            }
188        }
189        else if(m==3)
190        {
191            if(state==0){
192                blo[0].x+=1;blo[0].y+=2;blo[2].x-=1;blo[2].y-=2;blo[3].x-=2;blo[3].y-=4;
193                judge(blo,ok);
194                if(map[blo[0].x][blo[0].y-2]||map[blo[2].x][blo[2].y+2])ok=0;
195                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;}
196            }
197            else {
198                blo[0].x-=1;blo[0].y-=2;blo[2].x+=1;blo[2].y+=2;blo[3].x+=2;blo[3].y+=4;
199                judge(blo,ok);
200                if(map[blo[0].x+1][blo[0].y]||map[blo[2].x-1][blo[2].y])ok=0;
201                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;}
202            }
203        }
204        else if(m==5)
205        {
206            if(state==0)
207            {
208                blo[0].x+=2;blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2;
209                judge(blo,ok);
210                if(map[blo[3].x][blo[3].y+2])ok=0;
211                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;}
212            }
213            else if(state==1)
214            {
215                blo[0].y+=4;blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2;
216                judge(blo,ok);
217                if(map[blo[3].x-1][blo[3].y])ok=0;
218                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=2;}
219            }
220            else if(state==2)
221            {
222                blo[0].x-=2;blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2;
223                judge(blo,ok);
224                if(map[blo[3].x][blo[3].y-2])ok=0;
225                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=3;}
226            }
227            else{
228                blo[0].y-=4;blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2;
229                judge(blo,ok);
230                if(map[blo[3].x+1][blo[3].y])ok=0;
231                if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;}
232            }
233        }
234        else if(m==6)
235        {
236            if(state==0)
237            {
238                blo[0].y-=4;blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2;
239                judge(blo,ok);
240                if(map[blo[1].x][blo[1].y-2])ok=0;
241                if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=1;}
242            }
243            else if(state==1)
244            {
245                blo[0].x+=2;blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2;
246                judge(blo,ok);
247                if(map[blo[1].x+1][blo[1].y])ok=0;
248                if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=2;}
249            }
250            else if(state==2)
251            {
252                blo[0].y+=4;blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2;
253                judge(blo,ok);
254                if(map[blo[1].x][blo[1].y+2])ok=0;
255                if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=3;}
256            }
257            else{
258                blo[0].x-=2;blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2;
259                judge(blo,ok);
260                if(map[blo[1].x-1][blo[1].y])ok=0;
261                if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=0;}
262            }
263        }
264    }
265  
266    /*********清除当前方块**********/
267    void clear_cube(node* block)
268    {
269        for(int i=0;i<5;i++){
270            if(block[i].x){
271            SetCursor(block[i].y,block[i].x);
272            printf("  ");}
273        }
274    }
275  
276    /*******打印当前方块*********/
277    void printt_cube(node* block)
278    {
279        for(int i=0;i<5;i++){
280            if(block[i].x){
281                SetCursor(block[i].y,block[i].x);
282                printf("");
283            }
284        }
285    }
286  
287    /**********按键***********/
288    void Move(int m,int n){
289        int i;
290        if(n==0){//
291            for(i=0;i<5&&block[i].x;i++)if(block[i].y)block[i].y-=2;
292        }
293        if(n==1){//
294            for(i=0;i<5&&block[i].x;i++)if(block[i].y)block[i].y+=2;
295        }
296        if(n==2)//
297        {
298            Exchange(m);
299        }
300        if(n==3)//
301        {
302            int ok=1;
303            while(ok){
304                for(i=0;i<5;i++)if(block[i].x)
305                    if(map[block[i].x+1][block[i].y])ok=0;
306                if(ok)for(i=0;i<5;i++)if(block[i].x)
307                    block[i].x+=1;
308            }
309        }
310    }
311  
312    /******判断是否可以向左移动*****/
313    int If_Can_Left(node* block)
314    {
315        int ok=1,i;
316        int min=22;
317        for(i=0;i<5&&block[i].x;i++)if(block[i].y<min)min=block[i].y;
318        if(min-2<1)ok=0;
319        for(i=0;i<5&&block[i].x;i++)if(block[i].x)
320            if(map[block[i].x][block[i].y-2])ok=0;
321        return ok;
322    }
323  
324    /******判断是否可以向右移动********/
325    int If_Can_Right(node* block)
326    {
327        int ok=1,i;
328        int max=0;
329        for(i=0;i<5&&block[i].x;i++)if(block[i].y>max)max=block[i].y;
330        if(max+2>19)ok=0;
331        for(i=0;i<5&&block[i].x;i++)if(block[i].x)
332            if(map[block[i].x][block[i].y+2])ok=0;
333        return ok;
334    }
335  
336    /*********打印图**********/
337    void print_map()
338    {
339        int i,j;
340        me(INIT_MAP);
341        for(i=0;i<HEIGHT;i++)
342        {
343            if(i==0||i==23){
344                for(j=0;j<LENGTH;j++)printf("%c",INIT_MAP[i][j]='-');
345            }
346            else{
347                printf("%c",INIT_MAP[i][0]='|');
348                for(j=1;j<SIDE-1;j++)printf("%c",INIT_MAP[i][j]=' ');
349                printf("%c%c",INIT_MAP[i][j++]='|',INIT_MAP[i][j++]='|');
350                for(;j<LENGTH-1;j++)printf("%c",INIT_MAP[i][j]=' ');
351                printf("%c",INIT_MAP[i][j]='|');
352            }
353            cout<<endl;
354        }
355        SetCursor(SIDE+1,10);
356        printf("================");
357        SetCursor(SIDE+1,11);
358        printf("Speed");
359        SetCursor(SIDE+1,13);
360        printf("================");
361        SetCursor(SIDE+1,14);
362        printf("Score");
363        SetCursor(SIDE+1,16);
364        printf("================");
365        SetCursor(SIDE+1,19);
366        printf("   Created By   ");
367        SetCursor(SIDE+1,20);
368        printf("   Gong Jing    ");
369    }
370  
371    /*******下降一格*******/
372    void cube_drop(node *block)
373    {
374        int i;
375        for(i=0;i<5;i++)if(block[i].x)
376            block[i].x+=1;
377    }
378  
379    /*****到达底部返回1*******/
380    int is_at_botton(node* block)
381    {
382        for(int i=0;i<5;i++)
383            if(block[i].x&&map[block[i].x+1][block[i].y])return 1;
384        return 0;
385    }
386  
387    /******到达底部map赋值为1*****/
388    void print_map(node *block)
389    {
390        int i;
391        for(i=0;i<5;i++){
392            if(block[i].x){
393                map[block[i].x][block[i].y]=1;
394                SetCursor(block[i].y,block[i].x);
395                printf("");
396            }
397        }
398    }
399  
400    /******是否可以消去并消去**********/
401    int Can_It_Cut()
402    {
403        int i,j;
404        int cut=0;
405        for(i=HEIGHT-2;i>1;i--){
406            int ok=1;
407            for(j=1;j<SIDE-1;j+=2)
408                if(map[i][j]==0){ok=0;break;}
409            if(ok){
410                for(j=i;j>1;j--)for(int k=1;k<SIDE-1;k+=2)
411                    map[j][k]=map[j-1][k];
412                cut++;i++;
413            }
414        }
415        for(i=HEIGHT-2;i>1;i--)
416            for(int j=1;j<SIDE-1;j+=2)
417            {
418                SetCursor(j,i);
419                if(map[i][j])printf("");
420                else printf("  ");
421            }
422        return cut;
423    }
424  
425  
426    /********是否GameOver********/
427    int is_gameover(int num)
428    {
429        int i,j,ok=1;
430        print_block(num);
431        for(i=0;i<5;i++)if(block[i].x&&map[block[i].x][block[i].y])ok=0;
432        if(!ok){
433            char aa[20]={"Game Over!!!"};
434            for(i=9;i<12;i++)
435            {
436                if(i==10){
437                    int t=0;
438                    for(int j=4;j<18;j++){
439                        SetCursor(j,i);
440                        if(j>=5&&j<17)printf("%c",aa[t++]);
441                        else printf(" ");
442                    }
443                }
444                else for(j=4;j<18;j++){
445                        SetCursor(j,i);
446                        printf(" ");
447                }
448            }
449            SetCursor(1,12);printf(" Enter To Continue. ");
450            SetCursor(1,13);printf("    Esc To Escape.  ");
451            SetCursor(1,14);printf("                    ");
452        }
453        return ok;
454    }
455  
456    /*******游戏结束,再来一局,清理屏幕******/
457    void Clear_map()
458    {
459        for(int i=22;i>0;i--)
460            for(int j=1;j<SIDE-1;j+=2)
461            {
462                map[i][j]=0;
463                SetCursor(j,i);
464                printf("  ");
465            }
466    }
467  
468    int main()
469    {
470        srand(time(NULL));
471        print_map();
472        INITMAP();
473        int gameover=1;
474        int ok=1;//用于判断游戏是否结束
475        while(gameover){
476            int Score=0;
477            int Speed=0;
478             int numm=(rand()%7)*(rand()%7)%7;
479             Sleep(TIME_DWELL);
480            while(ok)
481            {
482                SetCursor(SIDE+4+Speed,12);
483                printf("     ");
484                SetCursor(SIDE+4,15);
485                printf("     ");
486                SetCursor(SIDE+4+Speed,12);
487                printf("*");
488                SetCursor(SIDE+4,15);
489                printf("%d",Score);
490                Sleep(200);
491                int num=numm;        //第num个方块,初始时为0这个状态
492                numm=(rand()%7)*(rand()%7)%7;               //提前显示的方块
493                clear_cube(bl);
494                Former_Print_block(numm);    //打印提前显示的方块
495                print_block(num);             //打印要落下的方块初始位置
496                state=0;
497                int botton=1;//用于判断是否已经落到底部
498                while(botton)
499                {
500                    clear_cube(block);
501                     /**********键位响应**********/
502                     if(GetAsyncKeyState(VK_LEFT)&&If_Can_Left(block))Move(num,0);
503                     else if(GetAsyncKeyState(VK_RIGHT)&&If_Can_Right(block))Move(num,1);
504                     else if(GetAsyncKeyState(VK_UP))Move(num,2);
505                     else if(GetAsyncKeyState(VK_DOWN)){Move(num,3);botton=0;}
506  
507                    if(!is_at_botton(block))cube_drop(block);
508                    else botton=0;
509                    printt_cube(block);//打印当前方块
510                    if(!botton)print_map( block);
511                    Sleep(100*(4-Score/80));
512                }
513                int cut=Can_It_Cut();
514                if(cut){
515                    Score+=cut*10;
516                    Speed=Score/80;
517                }
518                ok=is_gameover(numm);
519            }
520            if(GetAsyncKeyState(VK_ESCAPE))gameover=0;
521            else if(GetAsyncKeyState(VK_RETURN)){Clear_map();ok=1;}
522        }
523        return 0;
524    }

 

 

posted @ 2013-03-25 00:27  再见~雨泉  阅读(814)  评论(8)    收藏  举报