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

承接上篇,这几日,笔者本来打算写一个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             else
124                 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最大为17
136     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         else
146             break;
147     }
148     switch(count)///格式调整
149     {
150     case 2:///不加break会在执行完第一条语句后自动执行break
151     {
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             else
261             {
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             else
281             {
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             else
301             {
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             else
321             {
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     else
351     {
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);///不用生成newData
417 //    else
418 //    {
419 //        unsigned max=getMaxData();
420 //        ///创建的数不大于当前地图显示的合成的最大数的一半,newData最大为max-1
421 //        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 //            else
456 //                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         else
513         {
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

付几张游戏截图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值