zoukankan      html  css  js  c++  java
  • C++实现俄罗斯方块

    写在卸载之前

    一个蒟蒻无力的挣扎

    如果你是在阅读本人的博文来实现俄罗斯方块

    在实现俄罗斯方块之前 本人建议先左转贪吃蛇

    正式开始

    本来还是想秉持拿来主义 像贪吃蛇一样从网上随随便便找一个拿来写写

    但是由于网上的俄罗斯方块 实在是要么看不懂要么运行不了这话好像已经说过了

    所以没有办法 只好自己手写一个轻描淡写的一句话 背后是逝去的头发

    同时由于我所使用的是exe显示 所以为了舒适看着顺眼 最好手动调节一下显示exe的比例和字体大小

    捕获.PNG

    捕获2.PNG

    大致写出来就是这样

    捕获2.PNG

    这里添加了黑暗模式也就是盲打俄罗斯方块 如果有想玩但是网上找不到的朋友可以试试

    并且理解代码之后 你发现你甚至可以通过修改参数来在开头生成残块

    tmp1.gif

    tmp1.gif

    俄罗斯方块的写法跟贪吃蛇硬件类似 软件不同

    这里的我有很多都用到了贪吃蛇里面的代码 例如Windows API

    1.初始化游戏设置

    跟贪吃蛇类似

    class GameSetting
    {
      public:
        static const int window_height=22;
        static const int window_width=28;
      public:
        static void GameInit()
        {//调节屏幕尺寸
          char buffer[32];
          sprintf(buffer,"mode con cols=%d lines=%d",window_width,window_height);
          system(buffer);
         //隐藏光标
          HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
          CONSOLE_CURSOR_INFO cursor;
          GetConsoleCursorInfo(handle,&cursor);
          cursor.bVisible=false;
          SetConsoleCursorInfo(handle,&cursor);
         //随机种子
          srand((unsigned int)time((int)(998244353==19260817)));
        }	
        static void GameStart()
        {//开始游戏界面
          system("cls");
          for(int i=1;i<=window_width;++i) putchar('#');
          putchar('\n');
          for(int i=2;i<window_height;++i)
          {
            for(int j=1;j<=window_width;++j)
            if(j==1||j==window_width) putchar('#');
            else putchar(' ');
            putchar('\n');
          }
          for(int i=1;i<=window_width;++i) putchar('#');
          gotoxy(7,9);printf("俄罗斯方块");
          gotoxy(7,11);printf("方向键控制");
          gotoxy(7,13);printf("请选择模式:");
          gotoxy(4,15);printf("↑:正常    ↓:黑暗"); 
        }
        static void GameOver(int score)
        {//游戏结束界面
          for(int i=3;i<=17;++i)
          for(int j=7;j<=13;++j)
          gotoxy(i,j),putchar(' ');
          gotoxy(7,9);printf("游戏结束!");
          gotoxy(5,11);printf("当前分数为:%03d",score);
        }
    };
    

    2.打印相关的游戏信息

    /* 
    
    1
    ****
    2 
    **
    **
    3
    *
    ***
    4
    *
    ***
    5
    *
    ***
    6
    **
    **
    7
    **
    **
    
    */ 
    class PrintInfo
    {
      public:
        static void DrawMap()
        {//打印初始版面
          system("cls");
          for(int i=1;i<=GameSetting::window_width;++i) putchar('#');
          putchar('\n');
          for(int i=2;i<GameSetting::window_height;++i)
          {
          for(int j=1;j<=GameSetting::window_width;++j)
          if(i==11&&j>=12) putchar('#');
          else if(j==1||j==GameSetting::window_width||j==12) putchar('#');
          else putchar(' ');
          putchar('\n');
          }
          for(int i=1;i<=GameSetting::window_width;++i) putchar('#');	
          for(int i=1;i<=20;++i) {gotoxy(i,21);nowhave[i][21]=1;} 
        }
        static void DrawNext(int knd)
        {//俄罗斯方块需要有下一个的提示 所以我们需要在右上角显示下一个方块的信息
          gotoxy(13,2);printf("Next:");
          switch(knd)
          {//具体为什么会这么打印 跟上面的对应吧
            case 1:
              gotoxy(14+2,3+2);putchar('*');
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(16+2,3+2);putchar('*');
              gotoxy(17+2,3+2);putchar('*');
              break;	
            case 2:
              gotoxy(14+2,3+2);putchar('*');
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              break;	
            case 3:
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              gotoxy(16+2,4+2);putchar('*');
              break;
            case 4:
              gotoxy(14+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              gotoxy(16+2,4+2);putchar('*');
              break;	
            case 5:
              gotoxy(16+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              gotoxy(16+2,4+2);putchar('*');
              break;	
            case 6:
              gotoxy(14+2,3+2);putchar('*');
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              gotoxy(16+2,4+2);putchar('*');
              break;	
            case 7:
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(16+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              break;					
          }
        }
        static void ClearNext()
        {//每一次打印完之后为了防止覆盖下一个 我们需要清理
          gotoxy(14+2,3+2);putchar(' ');
          gotoxy(15+2,3+2);putchar(' ');
          gotoxy(16+2,3+2);putchar(' ');
          gotoxy(17+2,3+2);putchar(' ');
          gotoxy(14+2,4+2);putchar(' ');
          gotoxy(15+2,4+2);putchar(' ');
          gotoxy(16+2,4+2);putchar(' ');
        }
        static void DrawScore(int hard,int line,int score)
        {//显示当前游戏信息
          gotoxy(13,13);printf("游戏等级:%02d\n",hard);
          gotoxy(13,15);printf("消灭行数:%03d\n",line);
          gotoxy(13,17);printf("玩家分数:%03d\n",score);
          gotoxy(13,19);printf("作者:破晓晨光");
        }
        static void DrawNowHave()
        {//打印下方已经存在还没有消去的块
          for(int i=1;i<=20;++i)
          for(int j=1;j<=10;++j)
          {
            gotoxy(j,i);
            putchar(nowhave[j][i] ? '*':' ');
          }
        }
    };
    

    3.关于方块

    class Square
    {
      private:
        vector<Node> NowL,tmp;//存储当前下降方块的坐标 以及用于临时存储的vector
        int NowKnd,nowdir;//当前方框的种类和朝向
        int NextKnd;//下一个方块的种类
      public:
        Square()
        {//初始构造函数
          NowKnd=rand()%7+1;nowdir=0;
          NextKnd=rand()%7+1;
          NowL.clear();
          switch(NowKnd)
          {//初始的方块所在显示屏幕的位置
            case 1:
              NowL.push_back((Node){4,0});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 2:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              break;
            case 3:
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 4:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 5:
              NowL.push_back((Node){7,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 6:
              NowL.push_back((Node){4,-1});
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              break;
            case 7:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){4,0});
              NowL.push_back((Node){5,0});
              break;						
          } 
        }	
        void getNew()
        {//获取新的下降方块 其种类就是当前的下一个的种类
          NowKnd=NextKnd;nowdir=0;NowL.clear();
          NextKnd=rand()%7+1; 
          switch(NowKnd)
          {
            case 1:
              NowL.push_back((Node){4,0});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 2:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              break;
            case 3:
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 4:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 5:
              NowL.push_back((Node){7,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 6:
              NowL.push_back((Node){4,-1});
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              break;
            case 7:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){4,0});
              NowL.push_back((Node){5,0});
              break;						
          } 
        }
        void listen_keyboard()
        {//监听键盘 
          char ch;
          if(_kbhit())
          {
            ch=_getch(); 
            ch=_getch();//72向上 80向下 75向左 77向右 
            int maxn=-1,minn=35;
            bool okay=1;
            for(int i=0;i<4;++i)
            {//我们分别判断左移 右移 加速下降是否合法
              minn=min(minn,NowL[i].xx),maxn=max(maxn,NowL[i].xx);
              for(int j=1;j<=3;++j)
              if(NowL[i].yy+j>20||nowhave[NowL[i].xx][NowL[i].yy+j]) okay=0;
            } 
            if(ch==75&&minn>1) 
            {
              for(int i=0;i<4;++i) NowL[i].xx--;
            }
            if(ch==77&&maxn<10)
            {
              for(int i=0;i<4;++i) NowL[i].xx++;
            }
            if(ch==80&&okay)
            {
              for(int i=0;i<4;++i) NowL[i].yy+=3;
            }
            if(ch==72)
            {//最复杂的旋转操作 建议看代码的同时自己手动模拟 以便理解
              tmp.clear();
              switch(NowKnd)
              {
                case 1:
                  if(nowdir==0)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy+2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else 
                  {
                  int nowx=NowL[1].xx,nowy=NowL[1].yy;
                  bool flag=1;
                  tmp.push_back((Node){nowx-1,nowy});
                  tmp.push_back((Node){nowx,nowy});
                  tmp.push_back((Node){nowx+1,nowy});
                  tmp.push_back((Node){nowx+2,nowy});
                  for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                  if(flag)
                  {
                  	NowL.clear();
                  	for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                  }
                  } 
                  nowdir=(nowdir+1)%2;
                  break;
                case 2:
                break;
                case 3:
                  if(nowdir==0)
                  {
                    int nowx=NowL[2].xx,nowy=NowL[2].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                    }
                  else if(nowdir==1)
                  {
                    int nowx=NowL[2].xx,nowy=NowL[2].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                        NowL.clear();
                        for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==2)
                  {
                    int nowx=NowL[2].xx,nowy=NowL[2].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==3)
                  {
                    int nowx=NowL[2].xx,nowy=NowL[2].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy-1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                        NowL.clear();
                        for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  nowdir=(nowdir+1)%4;
                  break;
                case 4:
                  if(nowdir==0)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy+2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                         NowL.clear();
                          for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==1)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx-2,nowy});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                       NowL.clear();
                       for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==2)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy-2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                        NowL.clear();
                        for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==3)
                  {
                  int nowx=NowL[1].xx,nowy=NowL[1].yy;
                  bool flag=1;
                  tmp.push_back((Node){nowx,nowy-1});
                  tmp.push_back((Node){nowx,nowy});
                  tmp.push_back((Node){nowx+1,nowy});
                  tmp.push_back((Node){nowx+2,nowy});
                  for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                  if(flag)
                  {
                  	NowL.clear();
                  	for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                  }
                  }
                  nowdir=(nowdir+1)%4;
                  break;
                case 5:
                  if(nowdir==0)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy-2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==1)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx+2,nowy});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==2)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy+2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==3)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx-2,nowy});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  nowdir=(nowdir+1)%4;
                  break;
                case 6:
                  if(nowdir==0)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx-1,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else 
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx+1,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  } 
                  nowdir=(nowdir+1)%2;
                  break;
                case 7:
                if(nowdir==0)
                {
                  int nowx=NowL[0].xx,nowy=NowL[0].yy;
                  bool flag=1;
                  tmp.push_back((Node){nowx,nowy});
                  tmp.push_back((Node){nowx,nowy+1});
                  tmp.push_back((Node){nowx-1,nowy});
                  tmp.push_back((Node){nowx-1,nowy-1});
                  for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                  if(flag)
                  {
                  	NowL.clear();
                  	for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                  }
                }
                else 
                {
                  int nowx=NowL[0].xx,nowy=NowL[0].yy;
                  bool flag=1;
                  tmp.push_back((Node){nowx,nowy});
                  tmp.push_back((Node){nowx+1,nowy});
                  tmp.push_back((Node){nowx-1,nowy+1});
                  tmp.push_back((Node){nowx,nowy+1});
                  for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                  if(flag)
                  {
                  	NowL.clear();
                  	for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                  }
                } 
                nowdir=(nowdir+1)%2;
                break;
              }
            }
          }
        }
        int getNext(){return NextKnd;}//获取下一个方块的种类
        bool CanMove()
        {//判断当前下降方块是否可以下降
          for(int i=0;i<4;++i)
          {
            int nowx=NowL[i].xx,nowy=NowL[i].yy;
            if(nowhave[nowx][nowy+1]||nowy+1>20) return 0; 
          }
          return 1;
        }
        void Move()
        {//向下移动
          listen_keyboard();
          if(CanMove())
          for(int i=0;i<4;++i) ++NowL[i].yy;
        }
        void MapChange()
        {//更新下方存在没有消去的方块
          for(int i=0;i<4;++i) nowhave[NowL[i].xx][NowL[i].yy]=1;
        }
        void Draw()
        {//打印下方存在没有消去的方块
          for(int i=0;i<4;++i)
          {
            if(NowL[i].xx>=1&&NowL[i].xx<=10&&NowL[i].yy>=1&&NowL[i].yy<=20)
            {
              gotoxy(NowL[i].xx,NowL[i].yy);putchar('*');
            }
          }
        }
        void print()
        {//打印下降方块的二维坐标
          for(int i=0;i<4;++i) printf("%d %d\n",NowL[i].xx,NowL[i].yy);
        }
        void ClearL()
        {//在显示屏幕上消除下降方块
          for(int i=0;i<4;++i)
          {
            if(NowL[i].xx>=1&&NowL[i].xx<=10&&NowL[i].yy>=1&&NowL[i].yy<=20)
            {
              gotoxy(NowL[i].xx,NowL[i].yy);putchar(' ');
            }
          }
        }
        bool HaveBeenOver()
        {//如果当前下降方块还没有开始下降便已经无法下降 就代表游戏结束
          for(int i=0;i<4;++i) if(NowL[i].yy<=0) return 1;
          return 0;
        }
    };
    

    4.消去方块

    int Speed=500,Score,cnt=1,tot,resline;
    void CheckScore()
    {
      bool flag=0;int tottmp=0;
    
      for(int j=20;j;--j)
      {
        flag=1;
        for(int i=1;i<=10;++i) if(nowhave[i][j]==0) {flag=0;break;}
        if(flag) solo[++tottmp]=j;//存在可以消去的整行
      }
      if(tottmp==0) return;//如果没有可以消去的整行
      memset(nowtmp,0,sizeof nowtmp);
      for(int j=20,x=1,y=20;j;--j)
      {//这里的话 使用了一个移动指针法来让没有被消去的重新积累在一起
        if(x<=tottmp&&j==solo[x]) ++x;
        else
        {
        for(int i=1;i<=10;++i) nowtmp[i][y]=nowhave[i][j];
        --y;
        }
    
      }
      if(eyeflag)
      {//正常模式下先删除过去的
        for(int j=20;j;--j)
        for(int i=1;i<=10;++i)
        {gotoxy(i,j);putchar(' ');}	
      }
      for(int j=20;j;--j)
      for(int i=1;i<=10;++i)
      nowhave[i][j]=nowtmp[i][j];
      if(eyeflag)
      {//然后在打印出新的
        for(int j=20;j;--j)
        for(int i=1;i<=10;++i)
        {gotoxy(i,j);putchar(nowhave[i][j] ? '*':' ');}  
      }	
      tot+=tottmp;resline+=tottmp;//这里也是我自定义的计分制度 不适应的可以自定义
      if(resline>=50) ++cnt,resline%=50,Speed=Speed*4/5;
      if(tottmp==1) Score+=tottmp*cnt;
      if(tottmp==2) Score+=(tottmp*cnt)*5/4;
      if(tottmp==3) Score+=(tottmp*cnt)*4/3;
      if(tottmp==4) Score+=(tottmp*cnt)*3/2;
    
    }
    

    5.主函数

    我们把上面的拼在一起

    bool Choice()
    {
      char ch;
      ch=_getch(); 
      ch=_getch();
      if(ch==72) return 1;
      else return 0;
    }
    int main()
    {
      GameSetting newset;
      PrintInfo print_info;
      Square nowL;
      newset.GameInit();newset.GameStart();//游戏初始化,载入开始界面
      eyeflag=Choice();//上下键选择模式(可视化还是不可视)
      print_info.DrawMap();//打印初始版面
      while(true)
      {
        print_info.DrawScore(cnt,tot,Score);//打印游戏信息
        print_info.ClearNext();//先清理旧的下一个块
        print_info.DrawNext(nowL.getNext());//再打印当前的下一个块
        if(eyeflag) print_info.DrawNowHave();//如果正常 打印已经存在且没有被消去的块
        if(nowL.CanMove()==0)
        {//如果不可以移动的话
          if(nowL.HaveBeenOver())
          {//判断游戏是否结束
            newset.GameOver(Score);
            break;
          } 
          nowL.MapChange();//更新已经存在且没有被消去的块
          CheckScore();//更新成绩
          nowL.getNew();//更新下降的块
          continue;
        } 
        nowL.Move();nowL.Draw();//下降的块的移动和打印
        Sleep(Speed);
        nowL.ClearL();//再在显示屏幕上删除下降的块
      }
      return 0;
    }
    

    其实从这里 我们可以发现 算法在现实中也是具有较大作用的

    完整代码CODE:

    #include<bits/stdc++.h>
    #include<windows.h>
    #include<conio.h>
    using namespace std;
    int Speed=500,Score,cnt=1,tot,resline;
    bool nowhave[30][30],nowtmp[30][30];
    int solo[40];
    bool eyeflag;
    struct Node
    {
      int xx,yy;
    };
    void gotoxy(short x, short y) 
    {
      COORD coord={x, y}; 
      //COORD是Windows API中定义的一种结构体类型,表示控制台屏幕上的坐标。
      //上面语句是定义了COORD类型的变量coord,并以形参x和y进行初始化。
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
      //GetStdHandle(STD_OUTPUT_HANDLE); 获取控制台输出句柄
      //然后用SetConsoleCursorPosition设置控制台(cmd)光标位置
    }
    class GameSetting
    {
      public:
        static const int window_height=22;
        static const int window_width=28;
      public:
        static void GameInit()
        {//调节屏幕尺寸
          char buffer[32];
          sprintf(buffer,"mode con cols=%d lines=%d",window_width,window_height);
          system(buffer);
         //隐藏光标
          HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
          CONSOLE_CURSOR_INFO cursor;
          GetConsoleCursorInfo(handle,&cursor);
          cursor.bVisible=false;
          SetConsoleCursorInfo(handle,&cursor);
         //随机种子
          srand((unsigned int)time((int)(998244353==19260817)));
        }	
        static void GameStart()
        {//开始游戏界面
          system("cls");
          for(int i=1;i<=window_width;++i) putchar('#');
          putchar('\n');
          for(int i=2;i<window_height;++i)
          {
            for(int j=1;j<=window_width;++j)
            if(j==1||j==window_width) putchar('#');
            else putchar(' ');
            putchar('\n');
          }
          for(int i=1;i<=window_width;++i) putchar('#');
          gotoxy(7,9);printf("俄罗斯方块");
          gotoxy(7,11);printf("方向键控制");
          gotoxy(7,13);printf("请选择模式:");
          gotoxy(4,15);printf("↑:正常    ↓:黑暗"); 
        }
        static void GameOver(int score)
        {//游戏结束界面
          for(int i=3;i<=17;++i)
          for(int j=7;j<=13;++j)
          gotoxy(i,j),putchar(' ');
          gotoxy(7,9);printf("游戏结束!");
          gotoxy(5,11);printf("当前分数为:%03d",score);
        }
    };
    /* 
    1
    ****
    2 
    **
    **
    3
    *
    ***
    4
    *
    ***
    5
    *
    ***
    6
    **
    **
    7
    **
    **
    */ 
    class PrintInfo
    {
      public:
        static void DrawMap()
        {//打印初始版面
          system("cls");
          for(int i=1;i<=GameSetting::window_width;++i) putchar('#');
          putchar('\n');
          for(int i=2;i<GameSetting::window_height;++i)
          {
          for(int j=1;j<=GameSetting::window_width;++j)
          if(i==11&&j>=12) putchar('#');
          else if(j==1||j==GameSetting::window_width||j==12) putchar('#');
          else putchar(' ');
          putchar('\n');
          }
          for(int i=1;i<=GameSetting::window_width;++i) putchar('#');	
          for(int i=1;i<=20;++i) {gotoxy(i,21);nowhave[i][21]=1;} 
        }
        static void DrawNext(int knd)
        {//俄罗斯方块需要有下一个的提示 所以我们需要在右上角显示下一个方块的信息
          gotoxy(13,2);printf("Next:");
          switch(knd)
          {//具体为什么会这么打印 跟上面的对应吧
            case 1:
              gotoxy(14+2,3+2);putchar('*');
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(16+2,3+2);putchar('*');
              gotoxy(17+2,3+2);putchar('*');
              break;	
            case 2:
              gotoxy(14+2,3+2);putchar('*');
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              break;	
            case 3:
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              gotoxy(16+2,4+2);putchar('*');
              break;
            case 4:
              gotoxy(14+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              gotoxy(16+2,4+2);putchar('*');
              break;	
            case 5:
              gotoxy(16+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              gotoxy(16+2,4+2);putchar('*');
              break;	
            case 6:
              gotoxy(14+2,3+2);putchar('*');
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              gotoxy(16+2,4+2);putchar('*');
              break;	
            case 7:
              gotoxy(15+2,3+2);putchar('*');
              gotoxy(16+2,3+2);putchar('*');
              gotoxy(14+2,4+2);putchar('*');
              gotoxy(15+2,4+2);putchar('*');
              break;					
          }
        }
        static void ClearNext()
        {//每一次打印完之后为了防止覆盖下一个 我们需要清理
          gotoxy(14+2,3+2);putchar(' ');
          gotoxy(15+2,3+2);putchar(' ');
          gotoxy(16+2,3+2);putchar(' ');
          gotoxy(17+2,3+2);putchar(' ');
          gotoxy(14+2,4+2);putchar(' ');
          gotoxy(15+2,4+2);putchar(' ');
          gotoxy(16+2,4+2);putchar(' ');
        }
        static void DrawScore(int hard,int line,int score)
        {//显示当前游戏信息
          gotoxy(13,13);printf("游戏等级:%02d\n",hard);
          gotoxy(13,15);printf("消灭行数:%03d\n",line);
          gotoxy(13,17);printf("玩家分数:%03d\n",score);
          gotoxy(13,19);printf("作者:破晓晨光");
        }
        static void DrawNowHave()
        {//打印下方已经存在还没有消去的块
          for(int i=1;i<=20;++i)
          for(int j=1;j<=10;++j)
          {
            gotoxy(j,i);
            putchar(nowhave[j][i] ? '*':' ');
          }
        }
    };
    class Square
    {
      private:
        vector<Node> NowL,tmp;//存储当前下降方块的坐标 以及用于临时存储的vector
        int NowKnd,nowdir;//当前方框的种类和朝向
        int NextKnd;//下一个方块的种类
      public:
        Square()
        {//初始构造函数
          NowKnd=rand()%7+1;nowdir=0;
          NextKnd=rand()%7+1;
          NowL.clear();
          switch(NowKnd)
          {//初始的方块所在显示屏幕的位置
            case 1:
              NowL.push_back((Node){4,0});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 2:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              break;
            case 3:
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 4:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 5:
              NowL.push_back((Node){7,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 6:
              NowL.push_back((Node){4,-1});
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              break;
            case 7:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){4,0});
              NowL.push_back((Node){5,0});
              break;						
          } 
        }	
        void getNew()
        {//获取新的下降方块 其种类就是当前的下一个的种类
          NowKnd=NextKnd;nowdir=0;NowL.clear();
          NextKnd=rand()%7+1; 
          switch(NowKnd)
          {
            case 1:
              NowL.push_back((Node){4,0});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 2:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              break;
            case 3:
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 4:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 5:
              NowL.push_back((Node){7,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              NowL.push_back((Node){7,0});
              break;
            case 6:
              NowL.push_back((Node){4,-1});
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){5,0});
              NowL.push_back((Node){6,0});
              break;
            case 7:
              NowL.push_back((Node){5,-1});
              NowL.push_back((Node){6,-1});
              NowL.push_back((Node){4,0});
              NowL.push_back((Node){5,0});
              break;						
          } 
        }
        void listen_keyboard()
        {//监听键盘 
          char ch;
          if(_kbhit())
          {
            ch=_getch(); 
            ch=_getch();//72向上 80向下 75向左 77向右 
            int maxn=-1,minn=35;
            bool okay=1;
            for(int i=0;i<4;++i)
            {//我们分别判断左移 右移 加速下降是否合法
              minn=min(minn,NowL[i].xx),maxn=max(maxn,NowL[i].xx);
              for(int j=1;j<=3;++j)
              if(NowL[i].yy+j>20||nowhave[NowL[i].xx][NowL[i].yy+j]) okay=0;
            } 
            if(ch==75&&minn>1) 
            {
              for(int i=0;i<4;++i) NowL[i].xx--;
            }
            if(ch==77&&maxn<10)
            {
              for(int i=0;i<4;++i) NowL[i].xx++;
            }
            if(ch==80&&okay)
            {
              for(int i=0;i<4;++i) NowL[i].yy+=3;
            }
            if(ch==72)
            {//最复杂的旋转操作 建议看代码的同时自己手动模拟 以便理解
              tmp.clear();
              switch(NowKnd)
              {
                case 1:
                  if(nowdir==0)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy+2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else 
                  {
                  int nowx=NowL[1].xx,nowy=NowL[1].yy;
                  bool flag=1;
                  tmp.push_back((Node){nowx-1,nowy});
                  tmp.push_back((Node){nowx,nowy});
                  tmp.push_back((Node){nowx+1,nowy});
                  tmp.push_back((Node){nowx+2,nowy});
                  for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                  if(flag)
                  {
                  	NowL.clear();
                  	for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                  }
                  } 
                  nowdir=(nowdir+1)%2;
                  break;
                case 2:
                break;
                case 3:
                  if(nowdir==0)
                  {
                    int nowx=NowL[2].xx,nowy=NowL[2].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                    }
                  else if(nowdir==1)
                  {
                    int nowx=NowL[2].xx,nowy=NowL[2].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                        NowL.clear();
                        for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==2)
                  {
                    int nowx=NowL[2].xx,nowy=NowL[2].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==3)
                  {
                    int nowx=NowL[2].xx,nowy=NowL[2].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy-1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                        NowL.clear();
                        for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  nowdir=(nowdir+1)%4;
                  break;
                case 4:
                  if(nowdir==0)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy+2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                         NowL.clear();
                          for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==1)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx-2,nowy});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                       NowL.clear();
                       for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==2)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy-2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                        NowL.clear();
                        for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==3)
                  {
                  int nowx=NowL[1].xx,nowy=NowL[1].yy;
                  bool flag=1;
                  tmp.push_back((Node){nowx,nowy-1});
                  tmp.push_back((Node){nowx,nowy});
                  tmp.push_back((Node){nowx+1,nowy});
                  tmp.push_back((Node){nowx+2,nowy});
                  for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                  if(flag)
                  {
                  	NowL.clear();
                  	for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                  }
                  }
                  nowdir=(nowdir+1)%4;
                  break;
                case 5:
                  if(nowdir==0)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy-2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==1)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx+1,nowy});
                    tmp.push_back((Node){nowx+2,nowy});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==2)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx,nowy+2});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else if(nowdir==3)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx-2,nowy});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  nowdir=(nowdir+1)%4;
                  break;
                case 6:
                  if(nowdir==0)
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx,nowy-1});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx-1,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  }
                  else 
                  {
                    int nowx=NowL[1].xx,nowy=NowL[1].yy;
                    bool flag=1;
                    tmp.push_back((Node){nowx-1,nowy});
                    tmp.push_back((Node){nowx,nowy});
                    tmp.push_back((Node){nowx,nowy+1});
                    tmp.push_back((Node){nowx+1,nowy+1});
                    for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                    if(flag)
                    {
                      NowL.clear();
                      for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                    }
                  } 
                  nowdir=(nowdir+1)%2;
                  break;
                case 7:
                if(nowdir==0)
                {
                  int nowx=NowL[0].xx,nowy=NowL[0].yy;
                  bool flag=1;
                  tmp.push_back((Node){nowx,nowy});
                  tmp.push_back((Node){nowx,nowy+1});
                  tmp.push_back((Node){nowx-1,nowy});
                  tmp.push_back((Node){nowx-1,nowy-1});
                  for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                  if(flag)
                  {
                  	NowL.clear();
                  	for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                  }
                }
                else 
                {
                  int nowx=NowL[0].xx,nowy=NowL[0].yy;
                  bool flag=1;
                  tmp.push_back((Node){nowx,nowy});
                  tmp.push_back((Node){nowx+1,nowy});
                  tmp.push_back((Node){nowx-1,nowy+1});
                  tmp.push_back((Node){nowx,nowy+1});
                  for(int i=0;i<4;++i) if(tmp[i].xx<1||tmp[i].xx>10||tmp[i].yy<1||tmp[i].yy>20||nowhave[tmp[i].xx][tmp[i].yy]) {flag=0;break;}
                  if(flag)
                  {
                  	NowL.clear();
                  	for(int i=0;i<4;++i) NowL.push_back((Node){tmp[i].xx,tmp[i].yy});
                  }
                } 
                nowdir=(nowdir+1)%2;
                break;
              }
            }
          }
        }
        int getNext(){return NextKnd;}//获取下一个方块的种类
        bool CanMove()
        {//判断当前下降方块是否可以下降
          for(int i=0;i<4;++i)
          {
            int nowx=NowL[i].xx,nowy=NowL[i].yy;
            if(nowhave[nowx][nowy+1]||nowy+1>20) return 0; 
          }
          return 1;
        }
        void Move()
        {//向下移动
          listen_keyboard();
          if(CanMove())
          for(int i=0;i<4;++i) ++NowL[i].yy;
        }
        void MapChange()
        {//更新下方存在没有消去的方块
          for(int i=0;i<4;++i) nowhave[NowL[i].xx][NowL[i].yy]=1;
        }
        void Draw()
        {//打印下方存在没有消去的方块
          for(int i=0;i<4;++i)
          {
            if(NowL[i].xx>=1&&NowL[i].xx<=10&&NowL[i].yy>=1&&NowL[i].yy<=20)
            {
              gotoxy(NowL[i].xx,NowL[i].yy);putchar('*');
            }
          }
        }
        void print()
        {//打印下降方块的二维坐标
          for(int i=0;i<4;++i) printf("%d %d\n",NowL[i].xx,NowL[i].yy);
        }
        void ClearL()
        {//在显示屏幕上消除下降方块
          for(int i=0;i<4;++i)
          {
            if(NowL[i].xx>=1&&NowL[i].xx<=10&&NowL[i].yy>=1&&NowL[i].yy<=20)
            {
              gotoxy(NowL[i].xx,NowL[i].yy);putchar(' ');
            }
          }
        }
        bool HaveBeenOver()
        {//如果当前下降方块还没有开始下降便已经无法下降 就代表游戏结束
          for(int i=0;i<4;++i) if(NowL[i].yy<=0) return 1;
          return 0;
        }
    };
    void CheckScore()
    {
      bool flag=0;int tottmp=0;
    
      for(int j=20;j;--j)
      {
        flag=1;
        for(int i=1;i<=10;++i) if(nowhave[i][j]==0) {flag=0;break;}
        if(flag) solo[++tottmp]=j;//存在可以消去的整行
      }
      if(tottmp==0) return;//如果没有可以消去的整行
      memset(nowtmp,0,sizeof nowtmp);
      for(int j=20,x=1,y=20;j;--j)
      {//这里的话 使用了一个移动指针法来让没有被消去的重新积累在一起
        if(x<=tottmp&&j==solo[x]) ++x;
        else
        {
        for(int i=1;i<=10;++i) nowtmp[i][y]=nowhave[i][j];
        --y;
        }
    
      }
      if(eyeflag)
      {//正常模式下先删除过去的
        for(int j=20;j;--j)
        for(int i=1;i<=10;++i)
        {gotoxy(i,j);putchar(' ');}	
      }
      for(int j=20;j;--j)
      for(int i=1;i<=10;++i)
      nowhave[i][j]=nowtmp[i][j];
      if(eyeflag)
      {//然后在打印出新的
        for(int j=20;j;--j)
        for(int i=1;i<=10;++i)
        {gotoxy(i,j);putchar(nowhave[i][j] ? '*':' ');}  
      }	
      tot+=tottmp;resline+=tottmp;//这里也是我自定义的计分制度 不适应的可以自定义
      if(resline>=50) ++cnt,resline%=50,Speed=Speed*4/5;
      if(tottmp==1) Score+=tottmp*cnt;
      if(tottmp==2) Score+=(tottmp*cnt)*5/4;
      if(tottmp==3) Score+=(tottmp*cnt)*4/3;
      if(tottmp==4) Score+=(tottmp*cnt)*3/2;
    
    }
    bool Choice()
    {
      char ch;
      ch=_getch(); 
      ch=_getch();
      if(ch==72) return 1;
      else return 0;
    }
    int main()
    {
      GameSetting newset;
      PrintInfo print_info;
      Square nowL;
      newset.GameInit();newset.GameStart();//游戏初始化,载入开始界面
      eyeflag=Choice();//上下键选择模式(可视化还是不可视)
      print_info.DrawMap();//打印初始版面
      while(true)
      {
        print_info.DrawScore(cnt,tot,Score);//打印游戏信息
        print_info.ClearNext();//先清理旧的下一个块
        print_info.DrawNext(nowL.getNext());//再打印当前的下一个块
        if(eyeflag) print_info.DrawNowHave();//如果正常 打印已经存在且没有被消去的块
        if(nowL.CanMove()==0)
        {//如果不可以移动的话
          if(nowL.HaveBeenOver())
          {//判断游戏是否结束
            newset.GameOver(Score);
            break;
          } 
          nowL.MapChange();//更新已经存在且没有被消去的块
          CheckScore();//更新成绩
          nowL.getNew();//更新下降的块
          continue;
        } 
        nowL.Move();nowL.Draw();//下降的块的移动和打印
        Sleep(Speed);
        nowL.ClearL();//再在显示屏幕上删除下降的块
      }
      return 0;
    }
    
  • 相关阅读:
    kafka consumer防止数据丢失(转)
    Cglib源码分析 invoke和invokeSuper的差别(转)
    如何查看k8s存在etcd中的数据(转)
    k8s Nodeport方式下service访问,iptables处理逻辑(转)
    项目演化系列--验证体系
    项目演化系列--路由解析
    项目演化系列--开篇
    基于SWFUpload的angular上传组件
    Query Object--查询对象模式(下)
    Query Object--查询对象模式(上)
  • 原文地址:https://www.cnblogs.com/tcswuzb/p/14513524.html
Copyright © 2011-2022 走看看