1. 程式人生 > >俄羅斯方塊c/c++語言程式碼

俄羅斯方塊c/c++語言程式碼

/*******************************/
   /******Writer:   GJ      *******/
   /******Language: C       *******/
   /******Date:   2013 3 23 *******/
   /*******************************/
   #include<iostream>
   #include<stdio.h>
   //#include<conio.h>
   #include<string.h>
   #include<time.h>
   #include<stdlib.h>
   #include<windows.h>
   using namespace std;
   #define me(a) memset(a,0,sizeof(a))
   #define judge(bl,ok) for(i=0;i<5;i++)if(bl[i].x&&map[bl[i].x][bl[i].y])ok=0
   #define is_pure(node,ok) if(map[node.x][node.y])ok=0
   const int HEIGHT=24,LENGTH=40,SIDE=22;
 
   char INIT_MAP[HEIGHT+1][LENGTH+1];
   int map[HEIGHT][SIDE];
   struct node{int x,y;int color;};
   const int TIME_DWELL=1000;
   int state=0;
 
   /**********獲取控制代碼**********/
   HANDLE Output=GetStdHandle(STD_OUTPUT_HANDLE);
   HANDLE Input=GetStdHandle(STD_INPUT_HANDLE);
 
   /**********設定游標位置**********/
   void SetCursor(int x,int y){
       COORD cd={x,y};
       SetConsoleCursorPosition(Output,cd);
   }
 
   /**************初始化圖**************/
   void INITMAP()
   {
       for(int i=0;i<HEIGHT;i++)
           for(int j=0;j<SIDE;j++){
               if(i==0||i==HEIGHT-1||j==0||j==SIDE-1)map[i][j]=1;
               else map[i][j]=0;
           }
   }
 
   /********右上方提前顯示方塊******/
   node bl[5];
   void Former_Print_block(int n)
   {
       int i;
       for(i=0;i<5;i++){bl[i].x=bl[i].y=0;}
       if(n==0){
           bl[0].x=3,bl[0].y=28;  bl[1].x=3,bl[1].y=30;
           bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=32;
       }
       if(n==1){
           bl[0].x=3,bl[0].y=32;  bl[1].x=3,bl[1].y=30;
           bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=28;
       }
       if(n==2){
           bl[0].x=3,bl[0].y=30;  bl[1].x=4,bl[1].y=28;
           bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=32;
       }
       if(n==3){
           bl[0].x=3,bl[0].y=27;   bl[1].x=3,bl[1].y=29;
           bl[2].x=3,bl[2].y=31;  bl[3].x=3,bl[3].y=33;
       }
       if(n==4){
           bl[0].x=3,bl[0].y=29;  bl[1].x=3,bl[1].y=31;
           bl[2].x=4,bl[2].y=29;  bl[3].x=4,bl[3].y=31;
       }
       if(n==5){
           bl[0].x=3,bl[0].y=28;  bl[1].x=4,bl[1].y=28;
           bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=32;
       }
       if(n==6){
           bl[0].x=3,bl[0].y=32;  bl[1].x=4,bl[1].y=28;
           bl[2].x=4,bl[2].y=30;  bl[3].x=4,bl[3].y=32;
       }
       for(i=0;i<5;i++){
           SetCursor(bl[i].y,bl[i].x);
           printf("■");
       }
   }
 
   /*********獲取不同的方塊,出現在中間***********/
   node block[5];//全域性使用的核心!!!
   void print_block(int n)
   {int i;
       for(i=0;i<5;i++){block[i].x=block[i].y=0;}
       if(n==0){
           block[0].x=1,block[0].y=7;   block[1].x=1,block[1].y=9;
           block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
       }
       if(n==1){
           block[0].x=1,block[0].y=11;  block[1].x=1,block[1].y=9;
           block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=7;
       }
       if(n==2){
           block[0].x=1,block[0].y=9;  block[1].x=2,block[1].y=7;
           block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
       }
       if(n==3){
           block[0].x=1,block[0].y=7;   block[1].x=1,block[1].y=9;
           block[2].x=1,block[2].y=11;  block[3].x=1,block[3].y=13;
       }
       if(n==4){
           block[0].x=1,block[0].y=9;  block[1].x=1,block[1].y=11;
           block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
       }
       if(n==5){
           block[0].x=1,block[0].y=7;  block[1].x=2,block[1].y=7;
           block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
       }
       if(n==6){
           block[0].x=1,block[0].y=11;  block[1].x=2,block[1].y=7;
           block[2].x=2,block[2].y=9;  block[3].x=2,block[3].y=11;
       }
       for(i=0;i<5;i++){
           SetCursor(block[i].y,block[i].x);
           printf("■");
       }
   }
 
 
   /*************按 上 鍵 旋轉*************/
   void Exchange(int m)
   {
       int i,ok=1;
       node blo[5];
       for(i=0;i<5;i++)blo[i]=block[i];
       if(m==0){
           if(state==0){
               blo[0].x+=1;blo[0].y+=2;blo[2].x-=1;blo[2].y+=2;blo[3].x-=2;
               judge(blo,ok);
               if(map[blo[0].x][blo[0].y-2])ok=0;
               if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=1;}
           }
           else{
               blo[0].x-=1;blo[0].y-=2;blo[2].x+=1;blo[2].y-=2;blo[3].x+=2;
               judge(blo,ok);
               if(map[blo[1].x-1][blo[1].y])ok=0;
               if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=0;}
           }
       }
       else if(m==1){
           if(state==0){
               blo[0].x-=1;blo[0].y-=2;blo[2].x-=1;blo[2].y+=2;blo[3].y+=4;
               judge(blo,ok);
               if(map[blo[1].x][blo[1].y-2])ok=0;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;}
           }
           else {
               blo[0].x+=1;blo[0].y+=2;blo[2].x+=1;blo[2].y-=2;blo[3].y-=4;
               judge(blo,ok);
               if(map[blo[0].x-1][blo[0].y])ok=0;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;}
           }
       }
       else if(m==2)
       {
           if(state==0)
           {
               blo[0].x+=1;blo[0].y-=2; blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2;
               judge(blo,ok);
               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;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;}
           }
           else if(state==1)
           {
               blo[0].x+=1;blo[0].y+=2; blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2;
               judge(blo,ok);
               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;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=2;}
           }
           else if(state==2)
           {
               blo[0].x-=1;blo[0].y+=2; blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2;
               judge(blo,ok);
               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;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=3;}
           }
           else{
               blo[0].x-=1;blo[0].y-=2; blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2;
               judge(blo,ok);
               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;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;}
           }
       }
       else if(m==3)
       {
           if(state==0){
               blo[0].x+=1;blo[0].y+=2;blo[2].x-=1;blo[2].y-=2;blo[3].x-=2;blo[3].y-=4;
               judge(blo,ok);
               if(map[blo[0].x][blo[0].y-2]||map[blo[2].x][blo[2].y+2])ok=0;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;}
           }
           else {
               blo[0].x-=1;blo[0].y-=2;blo[2].x+=1;blo[2].y+=2;blo[3].x+=2;blo[3].y+=4;
               judge(blo,ok);
               if(map[blo[0].x+1][blo[0].y]||map[blo[2].x-1][blo[2].y])ok=0;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;}
           }
       }
       else if(m==5)
       {
           if(state==0)
           {
               blo[0].x+=2;blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2;
               judge(blo,ok);
               if(map[blo[3].x][blo[3].y+2])ok=0;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=1;}
           }
           else if(state==1)
           {
               blo[0].y+=4;blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2;
               judge(blo,ok);
               if(map[blo[3].x-1][blo[3].y])ok=0;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=2;}
           }
           else if(state==2)
           {
               blo[0].x-=2;blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2;
               judge(blo,ok);
               if(map[blo[3].x][blo[3].y-2])ok=0;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=3;}
           }
           else{
               blo[0].y-=4;blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2;
               judge(blo,ok);
               if(map[blo[3].x+1][blo[3].y])ok=0;
               if(ok)for(i=0;i<5;i++){block[i]=blo[i];state=0;}
           }
       }
       else if(m==6)
       {
           if(state==0)
           {
               blo[0].y-=4;blo[1].x+=1;blo[1].y+=2;blo[3].x-=1;blo[3].y-=2;
               judge(blo,ok);
               if(map[blo[1].x][blo[1].y-2])ok=0;
               if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=1;}
           }
           else if(state==1)
           {
               blo[0].x+=2;blo[1].x-=1;blo[1].y+=2;blo[3].x+=1;blo[3].y-=2;
               judge(blo,ok);
               if(map[blo[1].x+1][blo[1].y])ok=0;
               if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=2;}
           }
           else if(state==2)
           {
               blo[0].y+=4;blo[1].x-=1;blo[1].y-=2;blo[3].x+=1;blo[3].y+=2;
               judge(blo,ok);
               if(map[blo[1].x][blo[1].y+2])ok=0;
               if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=3;}
           }
           else{
               blo[0].x-=2;blo[1].x+=1;blo[1].y-=2;blo[3].x-=1;blo[3].y+=2;
               judge(blo,ok);
               if(map[blo[1].x-1][blo[1].y])ok=0;
               if(ok){for(i=0;i<5;i++)block[i]=blo[i];state=0;}
           }
       }
   }
 
   /*********清除當前方塊**********/
   void clear_cube(node* block)
   {
       for(int i=0;i<5;i++){
           if(block[i].x){
           SetCursor(block[i].y,block[i].x);
           printf("  ");}
       }
   }
 
   /*******列印當前方塊*********/
   void printt_cube(node* block)
   {
       for(int i=0;i<5;i++){
           if(block[i].x){
               SetCursor(block[i].y,block[i].x);
               printf("■");
           }
       }
   }
 
   /**********按鍵***********/
   void Move(int m,int n){
       int i;
       if(n==0){//左
           for(i=0;i<5&&block[i].x;i++)if(block[i].y)block[i].y-=2;
       }
       if(n==1){//右
           for(i=0;i<5&&block[i].x;i++)if(block[i].y)block[i].y+=2;
       }
       if(n==2)//上
       {
           Exchange(m);
       }
       if(n==3)//下
       {
           int ok=1;
           while(ok){
               for(i=0;i<5;i++)if(block[i].x)
                   if(map[block[i].x+1][block[i].y])ok=0;
               if(ok)for(i=0;i<5;i++)if(block[i].x)
                   block[i].x+=1;
           }
       }
   }
 
   /******判斷是否可以向左移動*****/
   int If_Can_Left(node* block)
   {
       int ok=1,i;
       int min=22;
       for(i=0;i<5&&block[i].x;i++)if(block[i].y<min)min=block[i].y;
       if(min-2<1)ok=0;
       for(i=0;i<5&&block[i].x;i++)if(block[i].x)
           if(map[block[i].x][block[i].y-2])ok=0;
       return ok;
   }
 
   /******判斷是否可以向右移動********/
   int If_Can_Right(node* block)
   {
       int ok=1,i;
       int max=0;
       for(i=0;i<5&&block[i].x;i++)if(block[i].y>max)max=block[i].y;
       if(max+2>19)ok=0;
       for(i=0;i<5&&block[i].x;i++)if(block[i].x)
           if(map[block[i].x][block[i].y+2])ok=0;
       return ok;
   }
 
   /*********列印圖**********/
   void print_map()
   {
       int i,j;
       me(INIT_MAP);
       for(i=0;i<HEIGHT;i++)
       {
           if(i==0||i==23){
               for(j=0;j<LENGTH;j++)printf("%c",INIT_MAP[i][j]='-');
           }
           else{
               printf("%c",INIT_MAP[i][0]='|');
               for(j=1;j<SIDE-1;j++)printf("%c",INIT_MAP[i][j]=' ');
               printf("%c%c",INIT_MAP[i][j++]='|',INIT_MAP[i][j++]='|');
               for(;j<LENGTH-1;j++)printf("%c",INIT_MAP[i][j]=' ');
               printf("%c",INIT_MAP[i][j]='|');
           }
           cout<<endl;
       }
       SetCursor(SIDE+1,10);
       printf("================");
       SetCursor(SIDE+1,11);
       printf("Speed");
       SetCursor(SIDE+1,13);
       printf("================");
       SetCursor(SIDE+1,14);
       printf("Score");
       SetCursor(SIDE+1,16);
       printf("================");
       SetCursor(SIDE+1,19);
       printf("   Created By   ");
       SetCursor(SIDE+1,20);
       printf("   Gong Jing    ");
   }
 
   /*******下降一格*******/
   void cube_drop(node *block)
   {
       int i;
       for(i=0;i<5;i++)if(block[i].x)
           block[i].x+=1;
   }
 
   /*****到達底部返回1*******/
   int is_at_botton(node* block)
   {
       for(int i=0;i<5;i++)
           if(block[i].x&&map[block[i].x+1][block[i].y])return 1;
       return 0;
   }
 
   /******到達底部map賦值為1*****/
   void print_map(node *block)
   {
       int i;
       for(i=0;i<5;i++){
           if(block[i].x){
               map[block[i].x][block[i].y]=1;
               SetCursor(block[i].y,block[i].x);
               printf("■");
           }
       }
   }
 
   /******是否可以消去並消去**********/
   int Can_It_Cut()
   {
       int i,j;
       int cut=0;
       for(i=HEIGHT-2;i>1;i--){
           int ok=1;
           for(j=1;j<SIDE-1;j+=2)
               if(map[i][j]==0){ok=0;break;}
           if(ok){
               for(j=i;j>1;j--)for(int k=1;k<SIDE-1;k+=2)
                   map[j][k]=map[j-1][k];
               cut++;i++;
           }
       }
       for(i=HEIGHT-2;i>1;i--)
           for(int j=1;j<SIDE-1;j+=2)
           {
               SetCursor(j,i);
               if(map[i][j])printf("■");
               else printf("  ");
           }
       return cut;
   }
 
 
   /********是否GameOver********/
   int is_gameover(int num)
   {
       int i,j,ok=1;
       print_block(num);
       for(i=0;i<5;i++)if(block[i].x&&map[block[i].x][block[i].y])ok=0;
       if(!ok){
           char aa[20]={"Game Over!!!"};
           for(i=9;i<12;i++)
           {
               if(i==10){
                   int t=0;
                   for(int j=4;j<18;j++){
                       SetCursor(j,i);
                       if(j>=5&&j<17)printf("%c",aa[t++]);
                       else printf(" ");
                   }
               }
               else for(j=4;j<18;j++){
                       SetCursor(j,i);
                       printf(" ");
               }
           }
           SetCursor(1,12);printf(" Enter To Continue. ");
           SetCursor(1,13);printf("    Esc To Escape.  ");
           SetCursor(1,14);printf("                    ");
       }
       return ok;
   }
 
   /*******遊戲結束,再來一局,清理螢幕******/
   void Clear_map()
   {
       for(int i=22;i>0;i--)
           for(int j=1;j<SIDE-1;j+=2)
           {
               map[i][j]=0;
               SetCursor(j,i);
               printf("  ");
           }
   }
 
   int main()
   {
       srand(time(NULL));
       print_map();
       INITMAP();
       int gameover=1;
       int ok=1;//用於判斷遊戲是否結束
       while(gameover){
           int Score=0;
           int Speed=0;
            int numm=(rand()%7)*(rand()%7)%7;
            Sleep(TIME_DWELL);
           while(ok)
           {
               SetCursor(SIDE+4+Speed,12);
               printf("     ");
               SetCursor(SIDE+4,15);
               printf("     ");
               SetCursor(SIDE+4+Speed,12);
               printf("*");
               SetCursor(SIDE+4,15);
               printf("%d",Score);
               Sleep(200);
               int num=numm;        //第num個方塊,初始時為0這個狀態
               numm=(rand()%7)*(rand()%7)%7;               //提前顯示的方塊
               clear_cube(bl);
               Former_Print_block(numm);    //列印提前顯示的方塊
               print_block(num);             //列印要落下的方塊初始位置
               state=0;
               int botton=1;//用於判斷是否已經落到底部
               while(botton)
               {
                   clear_cube(block);
                    /**********鍵位響應**********/
                    if(GetAsyncKeyState(VK_LEFT)&&If_Can_Left(block))Move(num,0);
                    else if(GetAsyncKeyState(VK_RIGHT)&&If_Can_Right(block))Move(num,1);
                    else if(GetAsyncKeyState(VK_UP))Move(num,2);
                    else if(GetAsyncKeyState(VK_DOWN)){Move(num,3);botton=0;}
 
                   if(!is_at_botton(block))cube_drop(block);
                   else botton=0;
                   printt_cube(block);//列印當前方塊
                   if(!botton)print_map( block);
                   Sleep(100*(4-Score/80));
               }
               int cut=Can_It_Cut();
               if(cut){
                   Score+=cut*10;
                   Speed=Score/80;
               }
               ok=is_gameover(numm);
           }
           if(GetAsyncKeyState(VK_ESCAPE))gameover=0;
           else if(GetAsyncKeyState(VK_RETURN)){Clear_map();ok=1;}
       }
       return 0;
   }