C++之《小货兵摆大炮》

背景

     记得小时候经常和爷爷在水泥地上,随手抓来两颗石子,一边口里念叨“小货兵摆大炮”,一边在地上划下横竖各6条道,然后在从旁边的土地上捡一些小石子和两个大石块,小石子代表小兵,大石块代表大炮。


游戏规则

  1. 小兵每次可移动一步,方向为前后左右。
  2. 大炮每次可移动一步,方向为前后左右。当大炮与小兵中间有一个空位,大炮可以选择吃掉小兵。
  3. 大炮与小兵的移动范围不能超过棋盘边界。

胜利规则

  1. 当大炮无法移动时,小兵获胜,即小兵把大炮逼到游戏边界处。
  2. 当小兵被大炮全部干掉时,大炮获胜。

代码实现

  1. Bing.h:代表小兵

    #ifndef BING_H_
    #define BING_H_
    #include <iostream>
    enum class Dir{
        Up = 0,
        Down,
        Left,
        Right
    };
    class Bing
    {
    private:
        int x;
        int y;
    
        int length;
        int width;
    
    public:
        Bing(int _x,int _y);
        bool Move(Dir dir);
        std::pair<int,int> getPosition();
        ~Bing();
    };
    
    #endif
    
  2. Pao.h:炮

    #ifndef PAO_H_
    #define PAO_H_
    #include "Bing.h"
    class Pao:public Bing
    {
    private:
        
    public:
        Pao(int _x,int _y);
        ~Pao();
    };
    #endif
    
  3. Game.h:游戏类

    	#include "Bing.h"
    	#include "Pao.h"
    	#include <vector>
    	class Game
    	{
    	private:
    	    int length;
    	    int width;
    	    int bingRows;
    	    int paoNum;
    	    int **sence;
    	
    	    std::vector<Bing*> bings;
    	    std::vector<Bing*> delBings;
    	    
    	    std::vector<Pao*> paos;
    	    
    	public:
    	
    	    Game();
    	   
    	    void updateSence();
    	    void show();
    	
    	    bool isBingsWin();
    	    bool isPaosWin();
    	    
    	    bool MovePao();
    	    bool MoveBing();
    	    void run();
    	
    	    ~Game();
    	};
    
  4. Game.cpp游戏类的实现

    #include <iostream>
    #include "Game.h"
    
    using namespace std;
    
    Game::Game()
    {
        length = 6;
        width = 6;
        bingRows = 3;
        paoNum = 2;
        sence = new int*[length];
        for(int i=0;i<length;++i){
            sence[i] = new int[width];
        }
    
        for(int i=0;i<bingRows;++i){
            for(int j=0;j<width;++j){
                Bing* bing = new Bing(i,j);
                bings.push_back(bing);
            }
        }
    
        int row = bingRows-1+2;
        int col = width/2-1;
        for(int i=0;i<paoNum;++i){
            Pao* pao = new Pao(row,col+i);
            paos.push_back(pao);
        }
    
    }
    
    void Game::updateSence(){
        for(int i=0;i<length;++i){
            for(int j=0;j<width;++j){
                sence[i][j] = 0;
            }
        }
        for(int i=0;i<bings.size();++i){
            for(auto bing:bings){
                auto pos = bing->getPosition();
                sence[pos.first][pos.second] = 1;
            }
        }
        for(auto pao:paos){
            auto pos = pao->getPosition();
            sence[pos.first][pos.second] = 2;
        }
    }
    
    void Game::show(){
        updateSence();
        for(int i=0;i<length;++i){
            for(int j=0;j<width;++j){
                if(sence[i][j] == 1){
                    printf("* ");
                }else if(sence[i][j] == 2){
                    printf("+ ");
                }else{
                    printf("  ");
                }
            }
            printf("\n");
        }
    }
    
    bool Game::isBingsWin(){
        bool flag = true;
        for(auto pao:paos){
            auto pos = pao->getPosition();
    
            auto up = std::make_pair(pos.first-1,pos.second);
            if(up.first>=0&&up.first<length&&up.second>=0&&up.second<width){
                if(sence[up.first][up.second] == 0){
                    flag = false;
                }
            }
    
            up = std::make_pair(pos.first+1,pos.second);
            if(up.first>=0&&up.first<length&&up.second>=0&&up.second<width){
                if(sence[up.first][up.second] == 0){
                    flag = false;
                }
            }
            up = std::make_pair(pos.first,pos.second-1);
            if(up.first>=0&&up.first<length&&up.second>=0&&up.second<width){
                if(sence[up.first][up.second] == 0){
                    flag = false;
                }
            }
            up = std::make_pair(pos.first,pos.second+1);
            if(up.first>=0&&up.first<length&&up.second>=0&&up.second<width){
                if(sence[up.first][up.second] == 0){
                    flag = false;
                }
            }
    
        }
        return flag;
    }
    
    bool Game::isPaosWin(){ 
        if(bings.size()<4){
            return true;
        }
        return false;
    }
    
    bool Game::MovePao(){
        Pao* pao;
        printf("请选择你要移动的炮(1/2):");
        int x;
        
        cin>>x;
        if(x != 1 && x != 2){
            printf("你选择的炮无效,请重新选择!\n");
            return false;
        }
        
    
        pao = paos[x-1];
        auto pos = pao->getPosition();
    
        printf("请选择你要进行的操作(移动:1 / 吃兵:2):");
        
        cin>>x;
        if(x != 1 && x != 2){
            printf("你选择的操作无效,请重新选择!\n");
            return false;
        }
    
        if(x == 1){
            printf("请选择你要移动的方向(上:w /下:s /左:a /右:d):");
            char ch;
            bool flag = false;
           
            cin>>ch;
            if(ch == 'w' || ch == 's' ||ch == 'a' ||ch == 'd'){
                switch (ch)
                {
                case 'w':
                    if(pos.first > 0 && sence[pos.first-1][pos.second] == 0){
                        pao->Move(Dir::Up);
                        flag = true;
                    }
                    break;
                case 's':
                    if(pos.first < length-1 && sence[pos.first+1][pos.second] == 0){
                        pao->Move(Dir::Down);
                        flag = true;
                    }
                    break;
                case 'a':
                    if(pos.second > 0 && sence[pos.first][pos.second-1] == 0){
                        pao->Move(Dir::Left);
                        flag = true;
                    }
                    break;
                case 'd':
                    if(pos.second < width-1 && sence[pos.first][pos.second+1] == 0){
                        pao->Move(Dir::Right);
                        flag = true;
                    }
                    break;
                default:
                    break;
                }
            }
            if(flag){
                return true;
            }
            else{
                printf("你选择的方向无效,请重新选择!\n");
                return false;
            }
           
        }else if(x == 2){
            printf("请选择你要移动的方向(上:w /下:s /左:a /右:d):");
            char ch;
            bool flag = false;
           
            cin>>ch;
            if(ch == 'w' || ch == 's' ||ch == 'a' ||ch == 'd'){
                switch (ch)
                {
                case 'w':
                    if(pos.first > 1 && sence[pos.first-2][pos.second] == 1 && sence[pos.first-1][pos.second] == 0){
                        pao->Move(Dir::Up);
                        pao->Move(Dir::Up);
                        pos = pao->getPosition();
                        auto begin = bings.begin();
                        while (begin != bings.end())
                        {
                            if(pos == (*begin)->getPosition()){
                                delBings.push_back(*begin);
                                bings.erase(begin);
                                break;
                            }
                            begin++;
                        }
                        flag = true;
                    }
                    break;
                case 's':
                    if(pos.first < length-2 && sence[pos.first+2][pos.second] == 1 && sence[pos.first+1][pos.second] == 0){
                        pao->Move(Dir::Down);
                        pao->Move(Dir::Down);
                        pos = pao->getPosition();
                        auto begin = bings.begin();
                        while (begin != bings.end())
                        {
                            if(pos == (*begin)->getPosition()){
                                delBings.push_back(*begin);
                                bings.erase(begin);
                                break;
                            }
                            begin++;
                        }
                        flag = true;
                    }
                    break;
                case 'a':
                    if(pos.second > 1 && sence[pos.first][pos.second-2] == 1 && sence[pos.first][pos.second-1] == 0){
                        pao->Move(Dir::Left);
                        pao->Move(Dir::Left);
                        pos = pao->getPosition();
                        auto begin = bings.begin();
                        while (begin != bings.end())
                        {
                            if(pos == (*begin)->getPosition()){
                                delBings.push_back(*begin);
                                bings.erase(begin);
                                break;
                            }
                            begin++;
                        }
                        flag = true;
                    }
                    break;
                case 'd':
                    if(pos.second < width-2 && sence[pos.first][pos.second+2] == 1 && sence[pos.first][pos.second+1] == 0){
                        pao->Move(Dir::Right);
                        pao->Move(Dir::Right);
                        pos = pao->getPosition();
                        auto begin = bings.begin();
                        while (begin != bings.end())
                        {
                            if(pos == (*begin)->getPosition()){
                                delBings.push_back(*begin);
                                bings.erase(begin);
                                break;
                            }
                            begin++;
                        }
                        flag = true;
                    }
                    break;
                default:
                    break;
                }
            }
            if(flag){
                return true;
            }
            else{
                printf("你选择的方向无效,请重新选择!\n");
                return false;
            }
    
        }
    
    }
    
    bool Game::MoveBing(){
        printf("请选择你要移动的兵的位置(x,y):");
        int x,y;
        
        cin>>x>>y;
        if(x>0&&x<=length&&y>0&&y<=width&&sence[x-1][y-1]==1){
            
        }else{
            printf("你选择的位置无效,请重新选择!\n");
            return false;
        }
    
        std::pair<int,int> pos(x-1,y-1);
        Bing* b;
        for(auto bing:bings){
            if(pos == bing->getPosition()){
                b = bing;
                break;
            }
        }
    
        printf("请选择你要移动的方向(上:w /下:s /左:a /右:d):");
        char ch;
        cin>>ch;
        bool flag = false;
        switch (ch)
        {
        case 'w':
            if(pos.first>0&&sence[pos.first-1][pos.second] == 0){
                b->Move(Dir::Up);
                flag = true;
            }
            break;
        case 's':
            if(pos.first<length-1&&sence[pos.first+1][pos.second] == 0){
                b->Move(Dir::Down);
                flag = true;
            }
            break;
        case 'a':
            if(pos.second>0&&sence[pos.first][pos.second-1] == 0){
                b->Move(Dir::Left);
                flag = true;
            }
            break;
        case 'd':
            if(pos.second<width-1&&sence[pos.first][pos.second+1] == 0){
                b->Move(Dir::Right);
                flag = true;
            }
            break;
        default:
            break;
        }
        if(!flag){
            printf("你选择的方向无效,请重新选择!\n");
        }
        return flag;
    }
    
    void Game::run(){
        while(true){
            system("clear");
            show();
            if(isBingsWin()){
                printf("小兵获胜!\n");
                break;
            }
            while (!MovePao()){}
            system("clear");
            show();
            if(isPaosWin()){
                printf("大炮获胜!\n");
                break;
            }
            while (!MoveBing()){}
        }
    }
    
    
    
    Game::~Game()
    {
        for(auto bing:bings){
            delete bing;
        }
        for(auto bing:delBings){
            delete bing;
        }
        for(auto pao:paos){
            delete pao;
        }
    }
    
  5. main.cpp

    #include <iostream>
    
    #include "Game.h"
    
    using namespace std;
    
    int main(){
        
        Game* g = new Game();
        
        g->run(); 
    
        g->~Game();
    
        return 0;
    }
    

实现效果

  1. 游戏开始界面,炮先行
    在这里插入图片描述

  2. 当炮吃掉一个小兵后的游戏场景
    在这里插入图片描述

  3. 小兵移动的方式
    在这里插入图片描述


后记

这个小游戏做完后,和朋友试玩了一下,发现有个bug,然后修正了。又试玩了一局,I win!
下一个小游戏做连连看吧!


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

5436649486

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值