• C++之《连连看》


    简介

    使用c++实现经典小游戏《连连看》

    背景

    1. 《连连看》的算法逻辑并不复杂,主要是游戏界面如何显式。目前只能用终端显示,所以,写完后,测试了两局,玩的我头昏脑涨的。
    2. 除了显示,另一个比较复杂的就是如何判断两张牌是否可以消除。鉴于受限于屏幕的大小,所以牌数不会很多,可以采用暴力枚举的方式来判断。

    实现效果

    1. 效果展示图
      在这里插入图片描述
    2. x代表纵坐标,y代表横坐标
    3. 目前只添加了3种图形,后续可以直接在map中随意添加。

    关键算法

    1. bool Game::isAllowedToErase():判断两个位置的牌是否可以消除
      • 根据判断两牌相邻时,牌的移动方向和剩余转向次数,可以判断两牌是否可以消除

        bool Game::isAllowedToErase(const int &_x1, const int &_y1, const int &_x2,
                                    const int &_y2, Dir _dir, int _times) const {
          // 在上面
          if (_x1 == _x2 - 1 && _y1 == _y2 &&
              (_dir == Dir::Down || _dir == Dir::Unknown || _times > 0)) {
            return true;
          }
          // 在下面
          if (_x1 == _x2 + 1 && _y1 == _y2 &&
              (_dir == Dir::Up || _dir == Dir::Unknown || _times > 0)) {
            return true;
          }
          // 在左边
          if (_x1 == _x2 && _y1 == _y2 - 1 &&
              (_dir == Dir::Right || _dir == Dir::Unknown || _times > 0)) {
            return true;
          }
          // 在右边
          if (_x1 == _x2 && _y1 == _y2 + 1 &&
              (_dir == Dir::Left || _dir == Dir::Unknown || _times > 0)) {
            return true;
          }
        
          std::vector<Dir> dirs = getAllowedDirs(_x1,_y1,_dir,_times);
          for(auto dir:dirs){
            switch (dir)
            {
            case Dir::Up:
                if(_dir==Dir::Left||_dir==Dir::Right){
                    if(isAllowedToErase(_x1-1,_y1,_x2,_y2,Dir::Up,_times-1)){
                        return true;
                    }
                }else{
                    if(isAllowedToErase(_x1-1,_y1,_x2,_y2,Dir::Up,_times)){
                        return true;
                    }
                }
                break;
            case Dir::Down:
                if(_dir==Dir::Left||_dir==Dir::Right){
                    if(isAllowedToErase(_x1+1,_y1,_x2,_y2,Dir::Down,_times-1)){
                        return true;
                    }
                }else{
                    if(isAllowedToErase(_x1+1,_y1,_x2,_y2,Dir::Down,_times)){
                        return true;
                    }
                }
                break;
            case Dir::Left:
                if(_dir==Dir::Up||_dir==Dir::Down){
                    if(isAllowedToErase(_x1,_y1-1,_x2,_y2,Dir::Left,_times-1)){
                        return true;
                    }
                }else{
                    if(isAllowedToErase(_x1,_y1-1,_x2,_y2,Dir::Left,_times)){
                        return true;
                    }
                }
                break;
            case Dir::Right:
                if(_dir==Dir::Up||_dir==Dir::Down){
                    if(isAllowedToErase(_x1,_y1+1,_x2,_y2,Dir::Right,_times-1)){
                        return true;
                    }
                }else{
                    if(isAllowedToErase(_x1,_y1+1,_x2,_y2,Dir::Right,_times)){
                        return true;
                    }
                }
                break;
            default:
                break;
            }
          }
        
          return false;
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43
        • 44
        • 45
        • 46
        • 47
        • 48
        • 49
        • 50
        • 51
        • 52
        • 53
        • 54
        • 55
        • 56
        • 57
        • 58
        • 59
        • 60
        • 61
        • 62
        • 63
        • 64
        • 65
        • 66
        • 67
        • 68
        • 69
        • 70
        • 71
        • 72
        • 73
        • 74
        • 75
        • 76
        • 77
        • 78
    2. std::vector Game::getAllowedDirs():获取牌可以移动的方向
      • 通过当前移动方向和剩余转向次数,获取当前牌下一步可选择的移动方向
        std::vector<Dir> Game::getAllowedDirs(const int& _x,const int& _y,Dir _dir, int _times) const{
            std::vector<Dir> res;
            switch (_dir)
            {
            case Dir::Unknown:
                if(isValid(_x-1,_y)){
                    res.push_back(Dir::Up);
                }
                if(isValid(_x+1,_y)){
                    res.push_back(Dir::Down);
                }
                if(isValid(_x,_y-1)){
                    res.push_back(Dir::Left);
                }
                if(isValid(_x,_y+1)){
                    res.push_back(Dir::Right);
                }
                break;
            case Dir::Up:
                if(isValid(_x-1,_y)){
                    res.push_back(Dir::Up);
                }
                if(_times<=0){
                    break;
                }
                if(isValid(_x,_y-1)){
                    res.push_back(Dir::Left);
                }
                if(isValid(_x,_y+1)){
                    res.push_back(Dir::Right);
                }
                break;
            case Dir::Down:
                if(isValid(_x+1,_y)){
                    res.push_back(Dir::Down);
                }
                if(_times<=0){
                    break;
                }
                if(isValid(_x,_y-1)){
                    res.push_back(Dir::Left);
                }
                if(isValid(_x,_y+1)){
                    res.push_back(Dir::Right);
                }
                break;
            case Dir::Left:
                if(isValid(_x,_y-1)){
                    res.push_back(Dir::Left);
                }
                if(_times<=0){
                    break;
                }
                if(isValid(_x-1,_y)){
                    res.push_back(Dir::Up);
                }
                if(isValid(_x+1,_y)){
                    res.push_back(Dir::Down);
                }
                break;
            case Dir::Right:
                if(isValid(_x,_y+1)){
                    res.push_back(Dir::Right);
                }
                if(_times<=0){
                    break;
                }
                if(isValid(_x-1,_y)){
                    res.push_back(Dir::Up);
                }
                if(isValid(_x+1,_y)){
                    res.push_back(Dir::Down);
                }
                break;
            default:
                break;
            }
            return res;
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43
        • 44
        • 45
        • 46
        • 47
        • 48
        • 49
        • 50
        • 51
        • 52
        • 53
        • 54
        • 55
        • 56
        • 57
        • 58
        • 59
        • 60
        • 61
        • 62
        • 63
        • 64
        • 65
        • 66
        • 67
        • 68
        • 69
        • 70
        • 71
        • 72
        • 73
        • 74
        • 75
        • 76
        • 77
        • 78
        • 79

    结语

           用c++写小游戏,最痛苦的便是游戏画面显示,本来打算这个游戏想想怎么用可视化的方法写出来,但是为了亲自体验一把cmake,还是选择用终端显示了。可以说,是为了cmake这点醋,包了《连连看》这顿饺子。


    (想要源码的可以私信我)

  • 相关阅读:
    如何确认串口波特率
    UG\NX二次开发 连接曲线、连结曲线 UF_CURVE_auto_join_curves
    第14章:垃圾回收概述
    B树的插入和删除
    第4关:书籍排序
    Ubuntu 安装redis数据库,并设置开机自启动
    数据结构——线性表:栈、队列
    LeetCode 1142.过去30天的用户活动2
    开发Qt上位机获取阿里云IOT设备数据(开发上位机对接阿里云IOT平台)
    数据结构与算法_排序算法_四个基础排序算法性能对比
  • 原文地址:https://blog.csdn.net/weixin_50749380/article/details/126214093