首页 > 代码库 > 大大维的游戏机计划3--2048v1

大大维的游戏机计划3--2048v1

前几天由于忙着过年串门,游戏机的计划搁置了几天。这两天终于空出了一块时间,抽空写了2048。

由于笔者前面自制了一个类似2048的游戏,所以写起来也算是轻车熟路,花了两个晚上也就差不多了。

废话少说,先将代码copy一份过来!

后续这几天,笔者想先写一个拼图小游戏,然后想办法将这几个游戏中共同存在的全屏刷新闪屏的问题给解决了。

另外,整个程序代码均为笔者原创,引用或转载请注明出处!

技术分享
  1 /**--------------------------------------------------------------**/  2 /**名称:大大维的2048v1                            日期:2017/2/1**/  3 /**描述:简单地实现了2048的基本功能                            **/  4 /**存在的问题:由于使用了全局刷新,游戏运行中会出现闪屏现象;  5 不能够存储玩家的游戏记录;由于不是图形化界面,用户界面较丑;  6 不能改变游戏的地图大小                                          **/  7 /**笔者会在后续版本逐步完善这些问题!!!                         **/  8 /**-------------------------------------------------------------**/  9 /**申明: 1.本程序由大大维独自编写,转载、引用请注明出处 10          2.本程序注释掉的部分,笔者认为理论上可以替代后续的代码, 11          但存在错误。笔者未发现错误原因,如有高手发现,请联系笔者 12          3.程序中若存在BUG请联系笔者 13          4.笔者联系方式   1329423134@qq.com                     **/ 14 /**-------------------------------------------------------------**/ 15 #include<iostream> 16 #include<string> 17 #include<vector> 18 #include<ctime> 19 #include<cstdlib> 20 #include<conio.h> 21 using namespace std; 22 constexpr unsigned HIGH=4; 23 constexpr unsigned LENG=4; 24 ///当前地图状态:READY,即(),可以进行moveAndAddData()操作;WAIT,即[],可以进行chooseMapSpace()操作 25 enum state {READY,WAIT}; 26 ///当前操作块的移动方向:UP,上;DOWN,下;LEFT,左;RIGHT,右;DEFAULT,其他 27 enum dir {UP,DOWN,LEFT,RIGHT,DEFAULT}; 28 class Map2048 29 { 30 public: 31     Map2048();///构造函数,初始化数据 32     void moveAndAddData();///移动和相加选中块的数据 33     ///地图压缩 34     void mapSortToUp(); 35     void mapSortToDown(); 36     void mapSortToLeft(); 37     void mapSortToRight(); 38     void dataCreate(unsigned persentOf2);///生成新data 39     bool isLive();///是否存活判断 40     void printMap();///地图打印 41     dir setDir();///输入操作块的移动方向 42     string dataToPrintData(int n);///data到printData的转换函数 43     unsigned getScore(); 44 private: 45     unsigned data[HIGH][LENG];///设要显示数据为x,data=http://www.mamicode.com/log2(x),空白时,data=0 46     string printData[HIGH][LENG];///存储规范化的输出数据 47     unsigned score; 48 }; 49  50 Map2048::Map2048() 51 { 52     for(int i=0; i<HIGH; i++) 53         for(int j=0; j<LENG; j++) 54         { 55             data[i][j]=0; 56         } 57     for(int i=0; i<HIGH; i++) 58         for(int j=0; j<LENG; j++) 59             printData[i][j]=dataToPrintData(data[i][j]); 60     bool initFlag=true; 61     while(initFlag) 62     { 63         srand((unsigned)time(NULL)); 64         int x1=rand()%HIGH,y1=rand()%LENG,x2=rand()%HIGH,y2=rand()%LENG; 65         if(x1!=x2&&y1!=y2) 66         { 67             initFlag=false; 68             data[x1][y1]=data[x2][y2]=2; 69             printData[x1][y1]=dataToPrintData(data[x1][y1]); 70             printData[x2][y2]=dataToPrintData(data[x2][y2]); 71         } 72     } 73     score=0; 74 } 75  76 void Map2048::moveAndAddData() 77 { 78     dir DIR=setDir(); 79     switch(DIR) 80     { 81     case UP: 82     { 83         mapSortToUp(); 84         for(int n=0; n<LENG; n++) 85             for(int m=1; m<HIGH; m++) 86                 if(data[m][n]==data[m-1][n]) 87                 { 88                     data[m-1][n]*=2; 89                     data[m][n]=0; 90                     printData[m-1][n]=dataToPrintData(data[m-1][n]); 91                     printData[m][n]=dataToPrintData(data[m][n]); 92                     score+=data[m-1][n]; 93                 } 94         mapSortToUp(); 95         break; 96     } 97     case DOWN: 98     { 99         mapSortToDown();100         for(int n=0; n<LENG; n++)101             for(int m=HIGH-2; m>=0; m--)102                 if(data[m][n]==data[m+1][n])103                 {104                     data[m+1][n]*=2;105                     data[m][n]=0;106                     printData[m+1][n]=dataToPrintData(data[m+1][n]);107                     printData[m][n]=dataToPrintData(data[m][n]);108                     score+=data[m+1][n];109                 }110         mapSortToDown();111         break;112     }113     case LEFT:114     {115         mapSortToLeft();116         for(int m=0; m<HIGH; m++)117             for(int n=1; n<LENG; n++)118                 if(data[m][n]==data[m][n-1])119                 {120                     data[m][n-1]*=2;121                     data[m][n]=0;122                     printData[m][n-1]=dataToPrintData(data[m][n-1]);123                     printData[m][n]=dataToPrintData(data[m][n]);124                     score+=data[m][n-1];125                 }126         mapSortToLeft();127         break;128     }129     case RIGHT:130     {131         mapSortToRight();132         for(int m=0; m<HIGH; m++)133             for(int n=LENG-2; n>=0; n--)134                 if(data[m][n]==data[m][n+1])135                 {136                     data[m][n+1]*=2;137                     data[m][n]=0;138                     printData[m][n+1]=dataToPrintData(data[m][n+1]);139                     printData[m][n]=dataToPrintData(data[m][n]);140                     score+=data[m][n+1];141                 }142         mapSortToRight();143         break;144     }145     case DEFAULT:146         break;147     }148 }149 150 void Map2048::mapSortToUp()///地图向上压缩151 {152     for(int n=0; n<LENG; n++)153         for(int m=0; m<HIGH; m++)154             if(data[m][n]==0)155                 for(int k=m; k<HIGH; k++)156                     if(data[k][n]!=0)157                     {158                         data[m][n]=data[k][n];159                         data[k][n]=0;160                         printData[m][n]=dataToPrintData(data[m][n]);161                         printData[k][n]=dataToPrintData(data[k][n]);162                         break;163                     }164 }165 166 void Map2048::mapSortToDown()///地图向下压缩167 {168     for(int n=LENG-1; n>=0; n--)169         for(int m=HIGH-1; m>=0; m--)170             if(data[m][n]==0)171                 for(int k=m; k>=0; k--)172                     if(data[k][n]!=0)173                     {174                         data[m][n]=data[k][n];175                         data[k][n]=0;176                         printData[m][n]=dataToPrintData(data[m][n]);177                         printData[k][n]=dataToPrintData(data[k][n]);178                         break;179                     }180 }181 182 void Map2048::mapSortToLeft()///地图向左压缩183 {184     for(int m=0; m<HIGH; m++)185         for(int n=0; n<LENG; n++)186             if(data[m][n]==0)187                 for(int k=n; k<LENG; k++)188                     if(data[m][k]!=0)189                     {190                         data[m][n]=data[m][k];191                         data[m][k]=0;192                         printData[m][n]=dataToPrintData(data[m][n]);193                         printData[m][k]=dataToPrintData(data[m][k]);194                         break;195                     }196 }197 198 void Map2048::mapSortToRight()///地图向右压缩199 {200     for(int m=HIGH-1; m>=0; m--)201         for(int n=LENG-1; n>=0; n--)202             if(data[m][n]==0)203                 for(int k=n; k>=0; k--)204                     if(data[m][k]!=0)205                     {206                         data[m][n]=data[m][k];207                         data[m][k]=0;208                         printData[m][n]=dataToPrintData(data[m][n]);209                         printData[m][k]=dataToPrintData(data[m][k]);210                         break;211                     }212 }213 214 void Map2048::dataCreate(unsigned persentOf2)215 {216     vector<int> dataVecX;///加入一个矢量,记录空位置的x坐标217     vector<int> dataVecY;///加入一个矢量,记录空位置的y坐标218     for(int i=0; i<HIGH; i++)219         for(int j=0; j<LENG; j++)220         {221             if(data[i][j]==0)222             {223                 dataVecX.push_back(i);224                 dataVecY.push_back(j);225             }226         }227     if(!dataVecX.empty())228     {229         srand((unsigned)time(NULL));230         auto k=rand()%dataVecX.size();///在空位中随机选择一个位置231         if(rand()%100<persentOf2)///根据2,4生成的比例随机生成新数据232             data[dataVecX[k]][dataVecY[k]]=2;233         else234             data[dataVecX[k]][dataVecY[k]]=4;235         printData[dataVecX[k]][dataVecY[k]]=dataToPrintData(data[dataVecX[k]][dataVecY[k]]);236     }237 }238 239 bool Map2048::isLive()240 {241     bool liveFlag=false;242     for(int m=0; m<HIGH; m++) ///确保没有空位置243         for(int n=0; n<LENG; n++)244             if(data[m][n]==0)245             {246                 liveFlag=true;247                 return liveFlag;248             }249 //    ///以下代码基于如下数学关系:反复使用向右,向下查询250 //    ///(最右行只向下,最底行只向右),可以遍历检查一遍元素自身是否与邻居相等251 //    for(int i=0; i<HIGH; i++)252 //    {253 //        for(int j=0; j<LENG; j++)254 //        {255 //            if(i!=HIGH-1&&j!=LENG-1)///非最右且非最下节点256 //            {257 //                if(data[i][j]==data[i][j+1]||data[i][j]==data[i+1][j])///向右,向下比较258 //                {259 //                    liveFlag=true;260 //                    return liveFlag;261 //                }262 //            }263 //            else if(i==HIGH-1&&j!=LENG-1)///非最右但是最下节点264 //            {265 //                if(data[i][j]=data[i][j+1])///向右比较266 //                {267 //                    liveFlag=true;268 //                    return liveFlag;269 //                }270 //            }271 //            else if(i!=HIGH-1&&j==LENG-1)///非最下但是最右节点272 //            {273 //                if(data[i][j]=data[i+1][j])///向下比较274 //                {275 //                    liveFlag=true;276 //                    return liveFlag;277 //                }278 //            }279 //            else///末尾节点,即最下且最右节点,无须比较,直接返回标志280 //                return liveFlag;281 //        }282 //    }283     for(int m=0; m<HIGH; m++) ///确保没有空位置284         for(int n=0; n<LENG; n++)285         {286             if((m==0)&&(n==0))287             {288                 if(data[m][n]==data[m+1][n]||data[m][n]==data[m][n+1])289                 {290                     liveFlag=true;291                     return liveFlag;292                 }293             }294             else if((m==HIGH-1)&&(n==LENG-1))295             {296                 if(data[m][n]==data[m-1][n]||data[m][n]==data[m][n-1])297                 {298                     liveFlag=true;299                     return liveFlag;300                 }301             }302             else if((m==0)&&(n==LENG-1))303             {304                 if(data[m][n]==data[m+1][n]||data[m][n]==data[m][n-1])305                 {306                     liveFlag=true;307                     return liveFlag;308                 }309             }310             else if((m==HIGH-1)&&(n==0))311             {312                 if(data[m][n]==data[m-1][n]||data[m][n]==data[m][n+1])313                 {314                     liveFlag=true;315                     return liveFlag;316                 }317             }318             else if((m==0)&&(n!=0)&&(n!=LENG-1))319             {320                 if(data[m][n]==data[m+1][n]||data[m][n]==data[m][n-1]||data[m][n]==data[m][n+1])321                 {322                     liveFlag=true;323                     return liveFlag;324                 }325             }326             else if((m=HIGH-1)&&(n!=0)&&(n!=LENG-1))327             {328                 if(data[m][n]==data[m-1][n]||data[m][n]==data[m][n-1]||data[m][n]==data[m][n+1])329                 {330                     liveFlag=true;331                     return liveFlag;332                 }333             }334             else if((n==0)&&(m!=0)&&(m!=HIGH-1))335             {336                 if(data[m][n]==data[m+1][n]||data[m][n]==data[m-1][n]||data[m][n]==data[m][n+1])337                 {338                     liveFlag=true;339                     return liveFlag;340                 }341             }342             else if((n==LENG-1)&&(m!=0)&&(m!=HIGH-1))343             {344                 if(data[m][n]==data[m+1][n]||data[m][n]==data[m-1][n]||data[m][n]==data[m][n-1])345                 {346                     liveFlag=true;347                     return liveFlag;348                 }349             }350             else351             {352                 if(data[m][n]==data[m+1][n]||data[m][n]==data[m-1][n]||data[m][n]==data[m][n-1]||data[m][n]==data[m][n+1])353                 {354                     liveFlag=true;355                     return liveFlag;356                 }357             }358         }359 }360 361 void Map2048::printMap()362 {363     cout<<"               2    0    4    8"<<endl;364     cout<<"---------------------------------------------"<<endl;365     for(int i=0; i<HIGH; i++)366     {367         for(int j=0; j<LENG; j++)368         {369             if(data[i][j]!=0)370                 cout<<"|  "<<printData[i][j]<<"  ";371             else372                 cout<<"|  "<<"      "<<"  ";373         }374         cout<<"|"<<endl;375         cout<<"---------------------------------------------"<<endl;376     }377     cout<<"SCORE= "<<score;378 }379 380 dir Map2048::setDir()381 {382     char keydown=getch();///读取按键383     switch(keydown)384     {385     case w:386         return UP;387         break;388     case W:389         return UP;390         break;391     case s:392         return DOWN;393         break;394     case S:395         return DOWN;396         break;397     case a:398         return LEFT;399         break;400     case A:401         return LEFT;402         break;403     case d:404         return RIGHT;405         break;406     case D:407         return RIGHT;408         break;409     default:410         return DEFAULT;411         break;412     }413 }414 415 string Map2048::dataToPrintData(int m)416 {417 418     int count=0;419     ///str的初始化基于如下数学关系:4*4的地图下,2048游戏能合成数,理论上最大值131072(2^17),即data最大为17420     string str {m/100000+48,(m/10000)%10+48,(m/1000)%10+48,(m/100)%10+48,(m/10)%10+48,m%10+48};421     ///对冗余0的处理422     for(int i=0; i<6; i++)423     {424         if(str[i]==0)425         {426             count++;427             str[i]= ;428         }429         else430             break;431     }432     switch(count)///格式调整433     {434     case 2:///不加break会在执行完第一条语句后自动执行break435     {436         str[1]=str[2];437         str[2]=str[3];438         str[3]=str[4];439         str[4]=str[5];440         str[5]= ;441         break;442     }443     case 3:444     {445         str[2]=str[3];446         str[3]=str[4];447         str[4]=str[5];448         str[5]= ;449         break;450     }451     case 4:452     {453         str[2]=str[4];454         str[3]=str[5];455         str[4]= ;456         str[5]= ;457         break;458     }459     case 5:460     {461         str[3]=str[5];462         str[5]= ;463         break;464     }465     }466     return str;467 }468 469 unsigned Map2048::getScore()470 {471     return score;472 }473 474 int main()475 {476     Map2048 map;477     bool gameOverFlag=false;478     map.printMap();479     while(!gameOverFlag)480     {481         while(kbhit())482         {483             system("cls");484             map.moveAndAddData();485             map.dataCreate(50);///以50%为2,50%为4的规则生成新数据486             map.printMap();487             if(!map.isLive())488                 gameOverFlag=true;489         }490     }491     cout<<endl<<"GAME OVER"<<endl;492     cout<<"The Final Score Is: "<<map.getScore()<<endl;493     getch();494 }
View Code

老规矩,上几张游戏截图:(在codeblocks下编译)

技术分享

技术分享

技术分享

技术分享

技术分享

 

大大维的游戏机计划3--2048v1