大大维的游戏机计划2--一个自制的类似2048的小游戏

来源:互联网 发布:分体式集成灶 品牌知乎 编辑:程序博客网 时间:2024/05/21 12:44

承接上篇,这几日,笔者本来打算写一个2048的,但写着写着,突然有个想法,能不能搞一个将2048和消消乐结合起来的游戏,于是,笔者便写出了如下这个小游戏。

值得一提的是,整个游戏完全由笔者独自写成,并没有参考任何网上的代码,这跟上次写贪吃蛇前学了老半天网上已有代码就显得独立了很多。看来贪食蛇的书写还是让笔者受益匪浅

定义的游戏规则如下:

1.采用类似2048的游戏规则合成数字

2.加入消消乐的点选作用(类似于在PC端模拟了一下触摸屏)

3.加入地图压缩规则

4.由于游戏像2048,就叫他NEW2048吧

虽然笔者将游戏按照所想做了出来,但笔者玩了一下,可玩性并不高。甚至十分枯燥!!!

尽管如此,这个游戏还是笔者完全独立书写的第一个游戏,意义还是蛮大的,因此笔者还是在此记录一笔。日后再翻出来改改,说不定能更好玩些。

大家可以试试这个游戏,并提提意见,可能有些bug,也请指正。

以后还是接着计划写剩余的游戏,加油。

  1 #include<iostream>  2 #include<string>  3 #include<cmath>  4 #include<ctime>  5 #include<cstdlib>  6 #include<conio.h>  7 using namespace std;  8 constexpr unsigned HIGH=4;  9 constexpr unsigned LENG=4; 10 ///当前地图状态:READY,即(),可以进行moveAndAddData()操作;WAIT,即[],可以进行chooseMapSpace()操作 11 enum state {READY,WAIT}; 12 ///当前操作块的移动方向及操作:UP,上;DOWN,下;LEFT,左;RIGHT,右;CHANGE,改变状态;DEFAULT,其他 13 enum dir {UP,DOWN,LEFT,RIGHT,CHANGE,DEFAULT}; 14 class MapNew2048 15 { 16 public: 17     MapNew2048();///构造函数,初始化数据 18     void printMap();///地图打印 19     void chooseMapSpace();///操作块移动,选择想要处理的地图块 20     void moveAndAddData();///移动和相加选中块的数据 21     ///压缩地图,将有意义的数值向左(上)角靠拢 22     void mapSortToUp(); 23     void mapSortToLeft(); 24     ///当一行(一列)完全为空时,随机生成一个数加入地图(这个数不能大于当前所合成的最大数的一半) 25     void dataCreate(); 26     void stateChange();///状态切换函数 27     bool isLive();///是否存活判断 28     state getState();///获取当前地图状态 29     dir setDir();///输入操作块的移动方向 30     unsigned getMaxData(); 31     string dataToPrintData(int n);///data到printData的转换函数 32 private: 33     unsigned data[HIGH][LENG];///设要显示数据为x,data=log2(x),空白时,data=0 34     string printData[HIGH][LENG];///存储规范化的输出数据 35     int nowX;///记录当前操作块的位置 36     int nowY; 37     state sta;///记录当前地图状态,确定执行chooseMapSpace()还是moveAndAddData() 38     bool flag;///记录上次moveAndAddData()操作是否成功 39 }; 40  41 MapNew2048::MapNew2048() 42 { 43     for(int i=0; i<HIGH; i++) 44         for(int j=0; j<LENG; j++) 45         { 46             data[i][j]=1; 47             srand((unsigned)time(NULL)+(2*i+3*j));///确保每一次,地图的每一格生成的data都是随机的 48             unsigned p=rand()%5; 49             if(p!=0) 50                 data[i][j]=p; 51         } 52     for(int i=0; i<HIGH; i++) 53         for(int j=0; j<LENG; j++) 54             printData[i][j]=dataToPrintData(data[i][j]); 55     nowX=nowY=0; 56     printData[nowX][nowY][0]='['; 57     printData[nowX][nowY][7]=']'; 58     sta=WAIT; 59 } 60  61 state MapNew2048::getState() 62 { 63     return sta; 64 } 65  66 dir MapNew2048::setDir() 67 { 68     char keydown=getch();///读取按键 69     switch(keydown) 70     { 71     case 'w': 72         return UP; 73         break; 74     case 'W': 75         return UP; 76         break; 77     case 's': 78         return DOWN; 79         break; 80     case 'S': 81         return DOWN; 82         break; 83     case 'a': 84         return LEFT; 85         break; 86     case 'A': 87         return LEFT; 88         break; 89     case 'd': 90         return RIGHT; 91         break; 92     case 'D': 93         return RIGHT; 94         break; 95     case ' ': 96         return CHANGE; 97         break; 98     default: 99         return DEFAULT;100         break;101     }102 }103 unsigned MapNew2048::getMaxData()104 {105     unsigned temp=data[0][0];106     for(int i=0; i<HIGH; i++)107         for(int j=0; j<LENG; j++)108         {109             temp=temp>data[i][j]?temp:data[i][j];110         }111     return temp;112 }113 void MapNew2048::printMap()114 {115     cout<<"            NEW   2    0    4    8"<<endl;116     cout<<"-----------------------------------------------------"<<endl;117     for(int i=0; i<HIGH; i++)118     {119         for(int j=0; j<LENG; j++)120         {121             if(data[i][j]!=0)122                 cout<<"|  "<<printData[i][j]<<"  ";123             else124                 cout<<"|  "<<printData[i][j][0]<<"      "<<printData[i][j][7]<<"  ";125         }126         cout<<"|"<<endl<<"-----------------------------------------------------"<<endl;127     }128 }129 130 string MapNew2048::dataToPrintData(int n)131 {132 133     int count=0;134     int m=pow(2,n);135     ///str的初始化基于如下数学关系:4*4的地图下,2048游戏能合成数,理论上最大值131072(2^17),即data最大为17136     string str {' ',m/100000+48,(m/10000)%10+48,(m/1000)%10+48,(m/100)%10+48,(m/10)%10+48,m%10+48,' '};137     ///对冗余0的处理138     for(int i=1; i<7; i++)139     {140         if(str[i]=='0')141         {142             count++;143             str[i]=' ';144         }145         else146             break;147     }148     switch(count)///格式调整149     {150     case 2:///不加break会在执行完第一条语句后自动执行break151     {152         str[2]=str[3];153         str[3]=str[4];154         str[4]=str[5];155         str[5]=str[6];156         str[6]=' ';157         break;158     }159     case 3:160     {161         str[3]=str[4];162         str[4]=str[5];163         str[5]=str[6];164         str[6]=' ';165         break;166     }167     case 4:168     {169         str[3]=str[5];170         str[4]=str[6];171         str[5]=' ';172         str[6]=' ';173         break;174     }175     case 5:176     {177         str[4]=str[6];178         str[6]=' ';179         break;180     }181     }182     return str;183 }184 void MapNew2048::chooseMapSpace()185 {186 187     if(sta==WAIT)188     {189         printData[nowX][nowY][0]=printData[nowX][nowY][7]=' ';190         dir DIR=setDir();191         switch(DIR)192         {193         case LEFT:194         {195             nowY--;196             if(nowY<0)197                 nowY=LENG-1;198             printData[nowX][nowY][0]='[';199             printData[nowX][nowY][7]=']';200             break;201         }202         case RIGHT:203         {204             nowY++;205             if(nowY>LENG-1)206                 nowY=0;207             printData[nowX][nowY][0]='[';208             printData[nowX][nowY][7]=']';209             break;210         }211         case UP:212         {213             nowX--;214             if(nowX<0)215                 nowX=HIGH-1;216             printData[nowX][nowY][0]='[';217             printData[nowX][nowY][7]=']';218             break;219         }220         case DOWN:221         {222             nowX++;223             if(nowX>HIGH-1)224                 nowX=0;225             printData[nowX][nowY][0]='[';226             printData[nowX][nowY][7]=']';227             break;228         }229         case CHANGE:230             stateChange();231             break;232         case DEFAULT:233         {234             printData[nowX][nowY][0]='[';235             printData[nowX][nowY][7]=']';236             break;237         }238         }239     }240 }241 void MapNew2048::moveAndAddData()242 {243     if(sta==READY)244     {245         printData[nowX][nowY][0]=printData[nowX][nowY][7]=' ';246         dir DIR=setDir();247         switch(DIR)248         {249         case LEFT:250         {251             if((data[nowX][nowY]==data[nowX][nowY-1])&&(nowY>0)&&(data[nowX][nowY-1]>0))252             {253                 data[nowX][nowY]=0;254                 nowY--;255                 data[nowX][nowY]++;256                 printData[nowX][nowY]=dataToPrintData(data[nowX][nowY]);257                 printData[nowX][nowY][0]='(';258                 printData[nowX][nowY][7]=')';259             }260             else261             {262                 printData[nowX][nowY][0]='(';263                 printData[nowX][nowY][7]=')';264             }265             mapSortToLeft();266             mapSortToUp();267             break;268         }269         case RIGHT:270         {271             if((data[nowX][nowY]==data[nowX][nowY+1])&&(nowY<LENG-1)&&(data[nowX][nowY+1]>0))272             {273                 data[nowX][nowY]=0;274                 nowY++;275                 data[nowX][nowY]++;276                 printData[nowX][nowY]=dataToPrintData(data[nowX][nowY]);277                 printData[nowX][nowY][0]='(';278                 printData[nowX][nowY][7]=')';279             }280             else281             {282                 printData[nowX][nowY][0]='(';283                 printData[nowX][nowY][7]=')';284             }285             mapSortToLeft();286             mapSortToUp();287             break;288         }289         case UP:290         {291             if((data[nowX][nowY]==data[nowX-1][nowY])&&(nowX>0)&&(data[nowX-1][nowY]>0))292             {293                 data[nowX][nowY]=0;294                 nowX--;295                 data[nowX][nowY]++;296                 printData[nowX][nowY]=dataToPrintData(data[nowX][nowY]);297                 printData[nowX][nowY][0]='(';298                 printData[nowX][nowY][7]=')';299             }300             else301             {302                 printData[nowX][nowY][0]='(';303                 printData[nowX][nowY][7]=')';304             }305             mapSortToUp();306             mapSortToLeft();307             break;308         }309         case DOWN:310         {311             if((data[nowX][nowY]==data[nowX+1][nowY])&&(nowX<HIGH-1)&&(data[nowX+1][nowY]>0))312             {313                 data[nowX][nowY]=0;314                 nowX++;315                 data[nowX][nowY]++;316                 printData[nowX][nowY]=dataToPrintData(data[nowX][nowY]);317                 printData[nowX][nowY][0]='(';318                 printData[nowX][nowY][7]=')';319             }320             else321             {322                 printData[nowX][nowY][0]='(';323                 printData[nowX][nowY][7]=')';324             }325             mapSortToUp();326             mapSortToLeft();327             break;328         }329         case CHANGE:330             stateChange();331             break;332         case DEFAULT:333         {334             printData[nowX][nowY][0]='(';335             printData[nowX][nowY][7]=')';336             break;337         }338         }339     }340 }341 342 void MapNew2048::stateChange()343 {344     if(sta==WAIT)345     {346         sta=READY;347         printData[nowX][nowY][0]='(';348         printData[nowX][nowY][7]=')';349     }350     else351     {352         sta=WAIT;353         printData[nowX][nowY][0]='[';354         printData[nowX][nowY][7]=']';355     }356 }357 358 void MapNew2048::mapSortToUp()///地图向上压缩359 {360     for(int n=0; n<LENG; n++)361     {362         for(int m=0; m<HIGH; m++)363         {364             if(data[m][n]==0&&m<HIGH-1)365             {366                 for(int k=m; k<HIGH-1; k++)367                 {368                     data[k][n]=data[k+1][n];369                     printData[k][n]=dataToPrintData(data[k][n]);370                 }371                 data[HIGH-1][n]=0;372             }373         }374     }375     ///调整时,会将printData[nowX][nowY]的标志冲掉,需要恢复一步376     printData[nowX][nowY][0]='(';377     printData[nowX][nowY][7]=')';378 }379 void MapNew2048::mapSortToLeft()///地图向左压缩380 {381     for(int m=0; m<HIGH; m++)382     {383         for(int n=0; n<LENG; n++)384         {385             if(data[m][n]==0&&n<LENG-1)386             {387                 for(int k=n; k<LENG-1; k++)388                 {389                     data[m][k]=data[m][k+1];390                     printData[m][k]=dataToPrintData(data[m][k]);391                 }392                 data[m][LENG-1]=0;393             }394         }395     }396     printData[nowX][nowY][0]='(';397     printData[nowX][nowY][7]=')';398 }399 400 //void MapNew2048::dataCreate()401 //{402 //    bool dataCreateFlag1=true;///列向生成newData标志403 //    bool dataCreateFlag2=true;///横向生成newData标志404 //    for(int i=0; i<HIGH; i++)405 //        if(data[i][LENG-1]!=0)406 //        {407 //            dataCreateFlag1=false;408 //            break;409 //        }410 //    for(int i=0; i<LENG; i++)411 //        if(data[HIGH-1][i]!=0)412 //        {413 //            dataCreateFlag2=false;414 //            break;415 //        }416 //    if(!dataCreateFlag1&&!dataCreateFlag2);///不用生成newData417 //    else418 //    {419 //        unsigned max=getMaxData();420 //        ///创建的数不大于当前地图显示的合成的最大数的一半,newData最大为max-1421 //        srand((unsigned int)time(NULL));422 //        unsigned newData=rand()%max;423 //        if(newData==0)424 //            newData++;425 //        /**经过上述的newData生成算法,P(newData=1)=2/(max-1),P(newData=other)=1/(max-1)**/426 //427 //        /**下面的几行语句用于确定newData在地图中的位置**/428 //        if(dataCreateFlag1&&!dataCreateFlag2)429 //        {430 //            srand((unsigned int)time(NULL));431 //            int a=rand()%HIGH;432 //            data[a][LENG-1]=newData;433 //            printData[a][LENG-1]=dataToPrintData(data[a][LENG-1]);434 //            mapSortToLeft();///地图压缩435 //        }436 //        else if(!dataCreateFlag1&&dataCreateFlag2)437 //        {438 //            srand((unsigned int)time(NULL));439 //            int b=rand()%LENG;440 //            data[HIGH-1][b]=newData;441 //            printData[HIGH-1][b]=dataToPrintData(data[HIGH-1][b]);442 //            mapSortToUp();///地图压缩443 //        }444 //        else if(dataCreateFlag1&&dataCreateFlag2)445 //        {446 //            srand((unsigned int)time(NULL));447 //            int a=rand()%HIGH;448 //            data[a][LENG-1]=newData;449 //            printData[a][LENG-1]=dataToPrintData(data[a][LENG-1]);450 //            if(a==HIGH-1)451 //            {452 //                mapSortToLeft();///地图压缩453 //                mapSortToUp();454 //            }455 //            else456 //                mapSortToLeft();457 //        }458 //    }459 //}460 461 462 bool MapNew2048::isLive()463 {464     ///isLive函数基于如下数学关系:反复使用向右,向下查询(最右行只向下),465     ///最底行只向右,可以将他的所有邻居遍历一次466     bool liveFlag=false;467     for(int i=0; i<HIGH; i++)468     {469         for(int j=0; j<LENG; j++)470         {471             if(i!=HIGH-1&&j!=LENG-1&&data[i][j]!=0)472             {473                 if(data[i][j]==data[i+1][j]||data[i][j]==data[i][j+1])474                 {475                     liveFlag=true;476                     return liveFlag;477                 }478             }479             else if(i==HIGH-1&&j!=LENG-1&&data[i][j]!=0)480             {481                 if(data[i][j]=data[i+1][j])482                 {483                     liveFlag=true;484                     return liveFlag;485                 }486             }487             else if(i!=HIGH-1&&j==LENG-1&&data[i][j]!=0)488             {489                 if(data[i][j]=data[i][j+1])490                 {491                     liveFlag=true;492                     return liveFlag;493                 }494             }495         }496     }497     return liveFlag;498 }499 500 int main()501 {502     bool gameOverFlag=false;503     MapNew2048 map;504     map.printMap();505     while(!gameOverFlag)506     {507         while(kbhit())508         {509             system("cls");510         if(map.getState()==WAIT)511             map.chooseMapSpace();512         else513         {514             map.moveAndAddData();515 //            map.dataCreate();516         }517         if(!map.isLive())518             gameOverFlag=true;519         map.printMap();520         }521 522     }523     cout<<endl<<"The Max is:  "<<pow(2,map.getMaxData())<<endl;524 }
View Code

付几张游戏截图:

 

0 0
原创粉丝点击