用C++实现2048小游戏(暂无图形化界面)

前言:这次面向对象程序设计(object oriented programming)的小lab是做一个2048小游戏,我很激动,因为平时无聊的时候最喜欢玩getFudan,觉得自己是2048高手,可以自己写一个2048小游戏觉得很有意思。要是用Java写的话,我觉得文件结构和逻辑都是比较显而易见的, 但是用到的是新学的语言C++,也要求用到封装,所以还是花了一点时间
github地址:https://github.com/Panpanmojue/game_2048

首先定义了一个名为game2048的类,它的属性都是私有的,不可被外部访问的,公共的是我们定义的一些方法与构造方法

//game2048.h
#pragma once

#define Size 4

class game2048
{
    
    
private:
    int chessMap[4][4];
    int count1;//用来记录连消值(以后可以用来实现随机生成4) 
    bool flag;//判断是否能消除 
public:
    game2048();//构造函数 
    void add();//在棋盘上增加2的函数 
    //四个移动操作 
    void up();
    void down();
    void left();
    void right();
    void showMap();//打印棋盘 
    bool over();//判断游戏是否结束 
};

void delay_time(double t);

然后在main.cpp里重写这些方法
我觉得这里难以实现的主要是移动的方法,我也在网上参考了很多别人的思路,但是感觉各种循环之间的嵌套特别不好理解,于是自己思考的时候想到了一个思路,最终也靠这个思路成功实现了游戏的逻辑。(笑死,一拿到这个lab就跟室友说要是我的话就怎么这么尝试,后来自己都不记得这个思路了,还是在室友的提示下想起来原来自己是这么想的)
以向上移动up()为例子
先不考虑数字之间能否结合,把数字全部上移,集中在4*4方格的上部分,再从上往下依次检验数字和它下一个数字之间两两能否结合,若能结合,当前数字变为原来的两倍,它的下一个数字清零,且从当前数字的下两个开始检查;若不能结合,数字不变,从它下一个数字开始检查起。第三步,由于结合之后可能产生空位,再进行数字全部上移操作即可。

void game2048::up(){
    
    
   int count = 0;//用来记录每一列有几个数字
   //先全部上移
   for (int j = 0;j < 4;j++){
    
    //j代表列,一列一列地检查
       for (int i = 0;i < 4;i++){
    
    
           if (chessMap[i][j] != 0){
    
    找到第count个非零值就放在第count位上
               chessMap[count][j] = chessMap[i][j];
               count++;
           }
       }
       //这个for循环是对棋盘没有数字的下部分清零
       for (count;count < 4;count++){
    
    
           	chessMap[count][j] = 0;
		}
		count = 0;
    }
   //再合并
   for (int j = 0;j < 4;j++){
    
    
       for (int i = 0;i < 3;){
    
    
           if (chessMap[i][j] != 0 && chessMap[i][j] == chessMap[i+1][j]){
    
    //当前数字与下一个数字能匹配
               chessMap[i][j] *= 2;
               chessMap[i+1][j] = 0;
               i = i + 2;//从当前数字的下两个开始
            } else{
    
    
                i = i + 1;//不能匹配
           }
       }
   }
	//再上移,同时清零 
    count = 0;
	for (int j = 0;j < 4;j++){
    
    
       for (int i = 0;i < 4;i++){
    
    
            if (chessMap[i][j] != 0){
    
    
               chessMap[count][j] = chessMap[i][j];
               count++;
           }
       }
       for (count;count < 4;count++){
    
    
           	chessMap[count][j] = 0;
		}
		count = 0;
   }
   count = 0;
}

向左向右向下同理。
最后说一下我判断游戏结束的顺序:

  1. 先判断是否产生了2048,若有,游戏胜利,结束;否则,进行第二步
  2. 不满足第一个条件的话,检测棋盘上是否有空位,若有,游戏继续;否则,进行第三步
  3. 判断能否已满的棋盘上是否存在两两可消除的数字,若是,游戏继续;若否,游戏失败,结束

这样就可以做到不重不漏
键盘实时响应获取事件参考:
https://www.runoob.com/w3cnote/c-get-keycode.html

猜你喜欢

转载自blog.csdn.net/weixin_45784337/article/details/115152565
今日推荐