我的第一个系统化高标准(标准:完成度100%+设计模式全面封装)C++程序【文字游戏:暂未命名】

0.文件 _class_declaration_father.h

//
// Created by Administrator on 2018/1/7.
//

//头文件保护符
#ifndef CPP_PROJECTS_CLASS_DECLARATION_H
#define CPP_PROJECTS_CLASS_DECLARATION_H
//
//

#include <iostream>
#include <vector>

using namespace std;


/**
 * 用于存放不同的模块
 */
class ManagerConst;


/**
 * 场景的基类。
 * 内部类——场景Item类。
 * 静态场景名列表。
 */
class BaseScene {

    //内部类
    /**
    * 内部的场景Item类。
    * 构造(地名)。
    */
    struct Scene {
        string address;

        Scene(string scene_name) : address(scene_name) {}
    };

    //变量
public:
    /**
    * 静态全局变量:所有场景名的列表。
    */
    static vector<Scene> scenes;
    //TODO 需要在implementation中进行定义。形式如下:vector<BaseScene::Scene> BaseScene::scenes = { }



    int cur_choice;     //用户目前做出的选项。



    //方法
public:

    /**
     * 内部的抽象方法的声明。(仅在此声明。)
     */


    /**
     * 主要方法就是。wholeLogic( )
     * wholeLogic里面,包含了 updateStatus(初始化成员变量)、check(检查英雄状态)、一个循环(包含了  sayHello(介绍:背景文字和选项文字)、goSwitch(用户输入选项))。
     */

    virtual bool whole_logic() final {

        updateStatus();


        do {

            if (false == checkAlive_orCompleted()) {
                return false;
            };

            describe_scene();

            if (false == continue_switch_action()) {

                return false;
            }


        } while (true);

    };

    virtual void updateStatus()=0;

    virtual bool checkAlive_orCompleted()=0;

    virtual void describe_scene() =0;                    //由子类,进行继承Override重写。

    virtual bool continue_switch_action()=0;            //提供可选择的移动项目,由用后输入选项编号,选择。


};


/**
 * 用于过渡的【和平城镇场景】基类。
 * 目前拥有的子类:Square广场。
 */

class BasePeacePosition : public BaseScene {


    //内部类
    /**
     * 此处内部类,SpecialEvent,用于将来拓展。
     * 比如,在广场,遇到了某个特殊事件(比如精灵小妹子搭讪)。
     */
    struct SpecialEvent {
        //一个特殊的游戏事件
    };


    //变量
public:
    vector<SpecialEvent> surprises;


    //方法
public:

};


/**
 * 用于购买Item的【商店Shop】的基类。
 * 目前拥有的子类:Weapon武器店,Drug药品店。
 */
class BaseShop : public BaseScene {


    //内部类
    /**
     * 单个Item商品的类。
     * 商品Item所含属性:商品名标签、商品单价、商品效果值。
     */
public:
    struct Item {
        int index;
        string label;
        int price;
        int power;

        Item(int t_index, string t_label,
             int t_price, int t_power) : index(t_index), label(t_label),
                                         price(t_price), power(t_power) {}
    };





    //变量
public:
    vector<Item> goods;          //声明一个内含的【待售商品列表】的内部变量。




    //方法
public:

    //virtual void buyItem()= 0;      //购买物品的纯虚函数声明。                //BaseHero已声明这个方法。
    //virtual void sayGoodBye() =0;           //TODO 独属于Shop的店主招呼客人的方法。



    /**
     * 注意:
     * 此处,可以把checkMoney,比拟成一个函数变量。
     * C++,面向函数,闭包。
     */

    /**
     * TODO 检查客户身上的钱。
     */
    //virtual void checkMoney() =0;   //TODO 这个方法,注意一下,可以随时,在购买、出售等环节,都可以调用的。建议做成实方法,然后pirvate。
};


/**
 * BaseMonster在BaseBattleScene中有用到。
 */
class BaseMonster;

/**
 * 新附加的战斗场景类。
 * 变量:Monster实例列表。
 */
class BaseBattleScene : public BaseScene {

    //变量
public:
    int rounds;            //代表现在鏖战的回合数。
    vector<BaseMonster> monsters;

    //方法
public:

};

/**
 * 英雄基类。
 * 基本属性:生命值、攻击力、防御力、金钱。
 * 动作:攻击、逃跑、检查当前数值状态。
 * 数值增减:加减血、加减攻击、加减防御、加减金钱。
 */
class BaseHero {

    //内部类
public:
    /**
     * 购买时,商店的类型
     */
    enum Buy_Shop_Type {
        Buy_In_Weapon_Shop = 1, Buy_In_Drug_Shop = 2,
    };

    /**
     * 购买时,商品所属的功用类型
     */
    enum Buy_Item_Type {
        item_health = 1, item_atk = 2, item_def = 3,
    };

    //变量
public:
    int *health = nullptr;
    int *attack_ability = nullptr;
    int *defence_ability = nullptr;
    int *money = nullptr;

    //方法
public:
    virtual void
    buyItem(BaseHero::Buy_Shop_Type shop_type,
            BaseHero::Buy_Item_Type item_category,
            BaseShop::Item good
    ) = 0;                     //购买商店物品。
    virtual void attack() = 0;              //攻击
    virtual void run_away()= 0;            //逃跑
    virtual void check_battle()= 0;             //检查在战斗中,健康数值是否会导致已经被打死。
    virtual void health_add(int num) = 0;           //吃药加血。
    virtual void atk_add(int num) = 0;              //买武器加攻。
    virtual void def_add(int num)=0;              //买防具加防。
    virtual void money_add(int num) = 0;            //打怪加钱。
    virtual void health_deduce(int num) =0;            //被怪物打减血。
    virtual void money_deduce(int num) = 0;             //买物品减钱。
};


/**
 * 用于描述怪兽的基类。
 * 内部类:【难度调整类】。
 * 构造函数:传入一个已填充值的【难度调整类】。
 * 基本属性:攻击力、防御值、掉落金钱、生命健康值。
 * 动作:
 */
class BaseMonster {


    //内部类
public:
    /**
     * 用于调整四维的成长比例。
     * 根据四维的长短,来定制出非常有个人突出优点和薄弱缺点的怪物。
     * (攻高血少【刺客怪】——攻高防高血少【强化版】——攻低防高血高【血牛】——攻高防高血高金钱高【Boss怪或精英怪】)
     */
    struct Hardness_Ratio {
        int atk_ratio;              //攻击倍率
        int def_ratio;              //防御倍率
        int money_ratio;            //金钱掉率
        int health_ratio;           //生命健康值倍率

        Hardness_Ratio(int atk_r, int def_r, int money_r, int health_r) :
                atk_ratio(atk_r),
                def_ratio(def_r),
                money_ratio(money_r),
                health_ratio(health_r) {};

    };


    //变量
public:
    string label;                           //Monster的学名。
    int attack_ability;             //攻击力。
    int defence_ability;           //防御值。
    int money_remaining;           //掉落金钱。
    int health;                    //生命健康值。


    //方法
public:
    /**
     * 构造函数。需要传入一个【难度调整类】。
     *
     * 这里设置为抽象,是为了使BaseMonster成为抽象类,是为了避免,直接创建BaseMonster实例。
     */
    BaseMonster(string t_label, Hardness_Ratio ratio_obj) {

        this->label = t_label;

        attack_ability *= ratio_obj.atk_ratio;
        defence_ability *= ratio_obj.def_ratio;
        money_remaining *= ratio_obj.money_ratio;
        health *= ratio_obj.health_ratio;
    };

    //BaseMonster() {};     //其实熟练的话,就会理解。其实子类写无参构造,是不需要写父类的无参构造的。调用父类的有参构造就好。


    virtual void makeItVirtual() {};           //仅仅是把BaseMonster,设置为一个抽象类。makeItVirtual方法没有别的意义<>

};











//
//
//头文件保护符
#endif //CPP_PROJECTS_CLASS_DECLARATION_H

1.文件 _class_implementation_son.h

//
// Created by Administrator on 2018/1/7.
//

//头文件保护符
#ifndef CPP_PROJECTS_CLASS_IMPLEMENTATION_H
#define CPP_PROJECTS_CLASS_IMPLEMENTATION_H
//
//

#include <iostream>
#include <vector>

#include "_class_declaration_father.h"

using namespace std;


/**
 * 0.存放不同的游戏模块。
 */
class ManagerConst {
    //变量
public:
    static vector<BaseHero *> heroList;
    static vector<BaseScene *> sceneList;
    static vector<BaseMonster *> monsterList;

    //方法
public:
    explicit ManagerConst(bool needInit);

    explicit ManagerConst();

private:
    void initConstManager();
};


/**
 * 1.为主角准备的英雄子类。
 */
class LeadingHero : public BaseHero {

    //变量
public:


    int health = 100;
    int attack_ability = 10;
    int defence_ability = 5;
    int money = 50;


    //方法
public:

    void buyItem(BaseHero::Buy_Shop_Type shop_type,
                 BaseHero::Buy_Item_Type item_category,
                 BaseShop::Item good) override;

    void attack() override {

    }

    void run_away() override {

    }

    void check_battle() override {

    }

    void health_add(int num) override {

    }

    void atk_add(int num) override {

    }

    void def_add(int num) override {

    }

    void money_add(int num) override {

    }

    void health_deduce(int num) override {

    }

    void money_deduce(int num) override {

    }

};


/**
 * 2.静态全局变量:所有场景名的列表————>的定义。(声明和定义分离)
 */
//TODO 基于不把全局变量定义在 .h 文件的最佳实践,已移至  "version1_func_implementation.cpp" 里。


/**
 * 3.出生广场类的定义。
 */
class Birth_TownSquare : public BasePeacePosition {

    //变量
public:

    //方法
public:

    void updateStatus() override;

    bool checkAlive_orCompleted() override;

    void describe_scene() override;

    bool continue_switch_action() override;

};


/**
 * 4.实体武器店的定义。
 */
class Weapon_Shop : public BaseShop {


    //变量
public:
    /**
     * 正数,代表武器。
     * 负数,代表防具。
     */
    vector<Item> goods = {
            BaseShop::Item(0, "什么都不买", 0, 0),
            BaseShop::Item(1, "小刀", 10, 2),
            BaseShop::Item(2, "短剑", 80, 20),
            BaseShop::Item(3, "大砍刀", 140, 40),
            BaseShop::Item(4, "双节棍", 200, 60),
            BaseShop::Item(5, "盾牌", 60, -30),
            BaseShop::Item(6, "铠甲", 100, -60),
            BaseShop::Item(7, "离开武器店", 0, 0),
    };

    //方法
public:
    void describe_scene() override;

    void updateStatus() override;

    bool checkAlive_orCompleted() override;

    bool continue_switch_action() override;
};


/**
 * 5.实体药品店的定义。
 */
class Drug_Shop : public BaseShop {

    //变量
public:
    vector<Item> goods = {
            BaseShop::Item(0, "什么都不买", 0, 0),
            BaseShop::Item(1, "1号补血药", 10, 200),
            BaseShop::Item(2, "2号补血药", 50, 1200),
            BaseShop::Item(3, "3号补血药", 100, 2500),
            BaseShop::Item(4, "离开药品店", 0, 0),

    };

    //方法
public:
    void updateStatus() override;

    bool checkAlive_orCompleted() override;

    void describe_scene() override;

    bool continue_switch_action() override;

};


/**
 * 6.小型怪物:多钩猫。
 *
 */

class HookMoreCat : public BaseMonster {
    //变量
public:
//    string label = "多钩猫";
//    int attack_ability = 10;             //攻击力。
//    int defence_ability = 10;           //防御值。
//    int money_remaining = 10;           //掉落金钱。
//    int health = 50;                    //生命健康值。

    //方法
public:
    /**
     * 构造函数。至于为什么这样写……(目前还不得而知,先做笔记记上)
     * 写&引用。可能是为了排除指针类型。
     */
    explicit HookMoreCat(string t_label, const Hardness_Ratio &ratio_obj) : BaseMonster(t_label, ratio_obj) {
        this->label = t_label;
        this->attack_ability *= ratio_obj.atk_ratio;
        this->defence_ability *= ratio_obj.def_ratio;
        this->money_remaining *= ratio_obj.money_ratio;
        this->health *= ratio_obj.health_ratio;
    }

public:
    /**
     * 与上面的有参构造大体类似。
     * 这里添加了一个默认的内置Hardness_Ratio类。
     */
    explicit HookMoreCat() : HookMoreCat("多钩猫", Hardness_Ratio(1, 1, 1, 1)) {
        //构造函数,复用的最新正确写法。
    }

};


/**
 * 7.中型怪物:森林雪人。
 */

class ForestSnowman : public BaseMonster {
    //变量
public:
//    string label = "森林雪人";
//    int attack_ability = 10;             //攻击力。
//    int defence_ability = 10;           //防御值。
//    int money_remaining = 10;           //掉落金钱。
//    int health = 50;                    //生命健康值。

    //方法
public:
    /**
     * 构造函数。至于为什么这样写……(目前还不得而知,先做笔记记上)
     * 写&引用。可能是为了排除指针类型。
     */
    explicit ForestSnowman(string t_label, const Hardness_Ratio &ratio_obj) : BaseMonster(t_label, ratio_obj) {
        this->label = t_label;
        this->attack_ability *= ratio_obj.atk_ratio;
        this->defence_ability *= ratio_obj.def_ratio;
        this->money_remaining *= ratio_obj.money_ratio;
        this->health *= ratio_obj.health_ratio;
    }

public:
    /**
     * 与上面的有参构造大体类似。
     * 这里添加了一个默认的内置Hardness_Ratio类。
     */
    explicit ForestSnowman() : ForestSnowman("森林雪人", Hardness_Ratio(3, 2, 10, 2)) {
        //构造函数,复用的最新正确写法。
    }

};

/**
 * 8.基本战斗场景:比奇镇。
 */
class BiQiTown : public BaseBattleScene {

    //变量
public:

    enum BattleType {
        Cat_Small = 1, Snowman_Large = 2
    };

    BattleType battleType;                          //战斗类型:(火球术小猫。追至村口雪人。)



    bool faceMonster;              //最开始处在寻怪,是否已经遇怪。
    vector<BaseMonster *> monsters = vector<BaseMonster *>();
    vector<LeadingHero *> heros = vector<LeadingHero *>();


    //方法
public:

    BiQiTown(BattleType t_type);

    BiQiTown(BaseMonster *t_monster, BattleType t_type);

    BiQiTown(BaseMonster *t_monster, LeadingHero *t_hero, BattleType t_type);


    void updateStatus() override;

    bool checkAlive_orCompleted() override;

    void describe_scene() override;

    bool continue_switch_action() override;

};



//
//
//头文件保护符
#endif //CPP_PROJECTS_CLASS_DECLARATION_H

2.文件 BaseScene.cpp

#include "_class_declaration_father.h"
#include "_class_implementation_son.h"

#include <iostream>
#include <vector>

using namespace std;

vector <BaseScene::Scene> BaseScene::scenes = {
        BaseScene::Scene("weapon_shop"),
        BaseScene::Scene("drug_shop"),
};

3.文件 LeadingHero.cpp

#include "_class_declaration_father.h"
#include "_class_implementation_son.h"

#include <iostream>
#include <vector>

using namespace std;



void LeadingHero::buyItem(BaseHero::Buy_Shop_Type shop_type,
                          BaseHero::Buy_Item_Type item_category,
                          BaseShop::Item good) {

    //先分支——购物商店的类型。【武器店】【药品店】。
    switch (shop_type) {

        //【武器店】
        case BaseHero::Buy_Shop_Type::Buy_In_Weapon_Shop: {

            //再分支——武器店内商品的具体类型。【武器】【盔甲】。
            switch (item_category) {


                //【武器】
                case BaseHero::Buy_Item_Type::item_atk: {

                    //判断当前金钱是否足够

                    if (good.price <= this->money) {
                        //金钱足够,可以进行购买【武器】
                        this->money -= good.price;           //消耗金钱。
                        this->attack_ability += good.power;        //增加攻击力。

                        printf("已购买%s,攻击力增加%d。当前攻击为%d。当前背包还剩%dG金钱。",
                               good.label.c_str(), good.power, this->attack_ability, this->money);

                    } else {
                        //金钱不够,不能进行购买【武器】
                        printf("购买的金钱不够。%s需要%dG,当前背包仅剩%dG。请继续努力,攒够钱再回来。", good.label.c_str(), good.price, this->money);
                    };
                    break;
                }

                    //【盔甲】
                case BaseHero::Buy_Item_Type::item_def: {

                    //判断当前金钱是否足够

                    if (good.price <= this->money) {
                        //金钱足够,可以进行购买【盔甲】
                        this->money -= good.price;           //消耗金钱。
                        this->defence_ability += (0 - good.power);        //增加防御力。(防御力是用负值表示的。所以取反。)

                        printf("已购买%s,防御力增加%d。当前防御为%d。当前背包还剩%dG金钱。",
                               good.label.c_str(), (0 - good.power), this->defence_ability, this->money);
                    } else {
                        //金钱不够,不能进行购买【盔甲】
                        printf("购买的金钱不够。%s需要%dG,当前背包仅剩%dG。请继续努力,攒够钱再回来。", good.label.c_str(), good.price, this->money);
                    };

                    break;
                }

            }

            break;
        }

            //【药品店】
        case BaseHero::Buy_Shop_Type::Buy_In_Drug_Shop: {

            //再分支——药品店内商品的具体类型。【小】【中】【大】
            switch (item_category) {
                case BaseHero::Buy_Item_Type::item_health: {
                    //【药品】


                    //判断当前金钱是否足够
                    if (good.price <= this->money) {
                        //金钱足够,可以进行购买【药品】
                        this->money -= good.price;           //消耗金钱。
                        this->health += good.power;          //增加生命健康值。

                        printf("已购买%s,生命值增加%d。当前生命为%d。当前背包还剩%dG金钱。",
                               good.label.c_str(), good.power, this->health, this->money);

                    } else {
                        //金钱不够,不能进行购买【药品】
                        printf("购买的金钱不够。%s需要%dG,当前背包仅剩%dG。请继续努力,攒够钱再回来。", good.label.c_str(), good.price, this->money);
                    };

                    break;
                }

            }

            break;
        }

    }

}

4.文件 Birth_TownSquare.cpp

#include "_class_declaration_father.h"
#include "_class_implementation_son.h"

#include <iostream>
#include <vector>

using namespace std;


void Birth_TownSquare::updateStatus() {
    cur_choice = 0;
}


bool Birth_TownSquare::checkAlive_orCompleted() {

    LeadingHero *hero = (LeadingHero *) (ManagerConst().heroList[0]);

    /**
     * 检测英雄的基本状态:存活或者过关状态。
     */
    if (0 >= hero->health)                       //主角生命力小于等于0时游戏结束
    {
        cout << "英雄生命值不足,已经被世界树召回!" << endl;
        return false;
    }


    if (hero->attack_ability > 9999) {                                //触发了过关的条件,则游戏自动进阶
        cout << "可以穿戴战神盔甲。" << endl;
        cout << "恭喜你,完成了终极任务,终于过关了!" << endl;
        return false;
    }

    return true;
};

void Birth_TownSquare::describe_scene() {
    //TODO 基本场景描述。(为选项做铺垫。写给玩家看的环境背景和选项分支)。【背景】+【选项】
    //进行最基本的,【场景】【上下文】介绍。


    cout << "经过了片刻时间后,你来到了:" << endl;
    cout << "小镇\n" << endl;
    cout << "一个1000年的小镇。周围有一条河,有一片树林,很多房子和很多人。\n有一家药店" << endl;
    cout << "和一家武器店。\n" << endl;

    /**
     * 前情选项提醒。在每次循环的最前面(甚至在输入选项指令之前。)
     */

    cout << "1.去武器店" << endl;
    cout << "2.去药品店" << endl;
    cout << "3.去打小怪物" << endl;
    cout << "4.去打大怪物" << endl;
    cout << "5.显示你的状态" << endl;
    cout << "6.退出游戏" << endl;
}


bool Birth_TownSquare::continue_switch_action() {

    LeadingHero *hero = (LeadingHero *) (ManagerConst().heroList[0]);

    cin >> cur_choice;

    if (cur_choice == 6) {
        //如果是输入了  分支6  的话,则自动结束该游戏。(可以考虑加入先存盘再退出系统。)
        return false;                                                       //原意,是让whole_logic里的循环,中止。
    };


    switch (cur_choice) {
        case 1:
            //去武器店。
            ((Weapon_Shop *) (ManagerConst().sceneList[1]))->whole_logic();
            break;

        case 2:
            //去药品店。
            ((Drug_Shop *) (ManagerConst().sceneList[2]))->whole_logic();
            break;

        case 3:
            //去打多钩猫。
            ((BiQiTown *) (ManagerConst().sceneList[3]))->whole_logic();
            break;

        case 4:
            //去打森林雪人。
            ((BiQiTown *) (ManagerConst().sceneList[4]))->whole_logic();
            break;

        case 5:
            //检查自身状态。
            printf("\n");
            printf("当前状态:   \n生命健康值:%d   \n攻击力:%d   \n防御力:%d   \n背包金钱:%d   ",
                   hero->health, hero->attack_ability, hero->defence_ability, hero->money);
            printf("\n");
            printf("\n");
            break;

        default:
            cout << "你输入的选项编号,暂无法识别";
            break;


    }

    return true;

}


5.文件 Weapon_Shop.cpp

#include "_class_declaration_father.h"
#include "_class_implementation_son.h"

#include <iostream>
#include <vector>

using namespace std;


/**
    * 正数,代表武器。
    * 负数,代表防具。
    */
//vector<BaseShop::Item> Weapon_Shop::goods = {
//        BaseShop::Item(0, "什么都不买", 0, 0),
//        BaseShop::Item(1, "小刀", 10, 2),
//        BaseShop::Item(2, "短剑", 80, 20),
//        BaseShop::Item(3, "大砍刀", 140, 40),
//        BaseShop::Item(4, "双节棍", 200, 60),
//        BaseShop::Item(5, "盾牌", 60, -30),
//        BaseShop::Item(6, "铠甲", 100, -60),
//        BaseShop::Item(7, "离开武器店", 0, 0),
//};


void Weapon_Shop::updateStatus() {

    /**
    * 准备初始值。
    */
    cur_choice = 0;

}

bool Weapon_Shop::checkAlive_orCompleted() {
    LeadingHero *hero = (LeadingHero *) (ManagerConst().heroList[0]);

    /**
     * 检测英雄的基本状态:存活或者过关状态。
     */
    if (0 >= hero->health)                       //主角生命力小于等于0时游戏结束
    {
        cout << "英雄生命值不足,已经被世界树召回!" << endl;
        return false;
    }


    if (hero->attack_ability > 9999) {                                //触发了过关的条件,则游戏自动进阶
        cout << "可以穿戴战神盔甲。" << endl;
        cout << "恭喜你,完成了终极任务,终于过关了!" << endl;
        return false;
    }

    return true;
}

void Weapon_Shop::describe_scene() {


    /**
     * 先进行,商店的自我介绍。和提供的各个购买选项介绍。
     */

    cout << "欢迎来到武器店!\n" << endl;
    for (int i = 1; i < goods.size(); ++i) {
        if (goods[i].power > 0) {
            //cout << goods[i].index << "、买" << goods[i].label << "(" << goods[i].price << "G加" << goods[i].power
            //     << "攻击力)" << endl;
            printf("%d、买%s(%dG加%d攻击力)", goods[i].index, goods[i].label.c_str(), goods[i].price, goods[i].power);
        }
        if (goods[i].power < 0) {
            //cout << goods[i].index << "、买" << goods[i].label << "(" << goods[i].price << "G加" << goods[i].power
            //     << "防御力)" << endl;
            printf("%d、买%s(%dG加%d防御力)", goods[i].index, goods[i].label.c_str(), goods[i].price, (0 - goods[i].power));
        }
        if (goods[i].power == 0) {
            //cout << goods[i].index << "、" << goods[i].label << endl;
            printf("%d、%s", goods[i].index, goods[i].label.c_str());
        }
        printf("\n");
    };

}


bool Weapon_Shop::continue_switch_action() {
    LeadingHero *hero = ((LeadingHero *) (ManagerConst().heroList[0]));     //取到当前英雄的指针。


    /**
     * 等待用户输入选项键。
     *
     * (通过return方式,返回false给whole_logic。然后whole_logic,因为收到false,所以走whole_logic的return分支。)跳出这个循环,就等于离开了武器店。
     */


    cin >> cur_choice;

    //判断choice的值。

    if (cur_choice == goods.size() - 1) {
        return false;              //选择了最后一个选项的话,则退出当前武器店的界面。回到中心广场。
    };


    //选择了武器购买。
    if (goods[cur_choice].power > 0) {

        //武器类。增加攻击力。

        hero->buyItem(BaseHero::Buy_Shop_Type::Buy_In_Weapon_Shop,
                      BaseHero::Buy_Item_Type::item_atk,
                      goods[cur_choice]
        );


    }
        //选择了盔甲购买。
    else if (goods[cur_choice].power < 0) {

        //防具类。增加防御力。

        hero->buyItem(BaseHero::Buy_Shop_Type::Buy_In_Weapon_Shop,
                      BaseHero::Buy_Item_Type::item_def,
                      goods[cur_choice]
        );

    }
        //选择了其它。
    else if (goods[cur_choice].power == 0) {

        //什么都不买选项。
        cout << "你选择了什么都不买选项" << "," << "下面我将为你讲一个故事:从前有座山" << endl;

    };

    return true;

}

6. 文件 Drug_Shop.cpp

#include "_class_declaration_father.h"
#include "_class_implementation_son.h"

#include <iostream>
#include <vector>

using namespace std;


//vector<BaseShop::Item> Drug_Shop::goods = {
//        BaseShop::Item(0, "什么都不买", 0, 0),
//        BaseShop::Item(1, "1号补血药", 10, 200),
//        BaseShop::Item(2, "2号补血药", 50, 1200),
//        BaseShop::Item(3, "3号补血药", 100, 2500),
//        BaseShop::Item(4, "离开药品店", 0, 0),
//
//};


void Drug_Shop::updateStatus() {
    /**
    * 准备初始值。
    */
    cur_choice = 0;

}

bool Drug_Shop::checkAlive_orCompleted() {
    LeadingHero *hero = (LeadingHero *) (ManagerConst().heroList[0]);

    /**
     * 检测英雄的基本状态:存活或者过关状态。
     */
    if (0 >= hero->health)                       //主角生命力小于等于0时游戏结束
    {
        cout << "英雄生命值不足,已经被世界树召回!" << endl;
        return false;
    }


    if (hero->attack_ability > 9999) {                                //触发了过关的条件,则游戏自动进阶
        cout << "可以穿戴战神盔甲。" << endl;
        cout << "恭喜你,完成了终极任务,终于过关了!" << endl;
        return false;
    }

    return true;
}

void Drug_Shop::describe_scene() {

    /**
     * 先进行,商店的自我介绍。和提供的各个购买选项介绍。
     */

    cout << "欢迎来到药品店!\n" << endl;
    for (int i = 1; i < goods.size(); ++i) {
        printf("%d、买%s(%dG加%d生命健康值)", goods[i].index, goods[i].label.c_str(), goods[i].price, goods[i].power);
        printf("\n");
    };


}

bool Drug_Shop::continue_switch_action() {
    LeadingHero *hero = ((LeadingHero *) (ManagerConst().heroList[0]));     //取到当前英雄的指针。


    /**
     * 等待用户输入选项键。
     *
     * (通过return方式,返回false给whole_logic。然后whole_logic,因为收到false,所以走whole_logic的return分支。)跳出这个循环,就等于离开了武器店。
     */


    cin >> cur_choice;

    //判断choice的值。

    if (cur_choice == goods.size() - 1) {
        return false;              //选择了最后一个选项的话,则退出当前武器店的界面。回到中心广场。
    };


    //选择了药品购买。
    if (goods[cur_choice].power > 0) {
        //药品类。增加生命健康值。
        hero->buyItem(BaseHero::Buy_Shop_Type::Buy_In_Drug_Shop,
                      BaseHero::Buy_Item_Type::item_health,
                      goods[cur_choice]
        );
    }
        //选择了其它。
    else if (goods[cur_choice].power == 0) {

        //什么都不买选项。
        cout << "你选择了什么都不买选项" << "," << "下面我将为你讲一个故事:山里有座庙" << endl;

    };

    return true;
}

7. BiQiTown.cpp

#include "_class_declaration_father.h"
#include "_class_implementation_son.h"

#include <iostream>
#include <vector>

using namespace std;


//vector<BaseMonster> BiQiTown::monsters = vector();


/**
 * 注:
 * BiQiTown这样的战斗场景类中,全部使用成员变量的 monster 和 hero 。
 */

//【单人战斗情况下1】
BiQiTown::BiQiTown(BattleType t_type) {}


//【单人战斗情况下2】
BiQiTown::BiQiTown(BaseMonster *t_monster, BattleType t_type) : battleType(t_type) {
    monsters.push_back(t_monster);

    LeadingHero *battle_hero = ((LeadingHero *) (ManagerConst().heroList[0]));
    heros.push_back(battle_hero);                       //这是世界管理类中的主角英雄。
}

//【多人战斗情况下】
BiQiTown::BiQiTown(BaseMonster *t_monster, LeadingHero *t_hero, BattleType t_type) : battleType(t_type) {
    monsters.push_back(t_monster);
    heros.push_back(t_hero);                //这里的英雄,可以自己指定。(用引用方式。)
}


void BiQiTown::updateStatus() {
    cur_choice = 0;

    rounds = 0;             //每次重新回到这个场景,回合数清零。

    faceMonster = false;

    /**
     * 每次都创建new一个新的,然后放入vector。
     */
    switch (battleType) {
        case BattleType::Cat_Small: {
            monsters[0] = new HookMoreCat();
            break;
        }
        case BattleType::Snowman_Large: {
            monsters[0] = new ForestSnowman();
            break;
        }
    }

}

bool BiQiTown::checkAlive_orCompleted() {

    LeadingHero *hero = (LeadingHero *) (ManagerConst().heroList[0]);

    /**
     * 检测英雄的基本状态:存活或者过关状态。
     */
    if (0 >= hero->health)                       //主角生命力小于等于0时游戏结束
    {
        cout << "英雄生命值不足,已经被世界树召回!" << endl;
        return false;
    }


    if (hero->attack_ability > 9999) {                                //触发了过关的条件,则游戏自动进阶
        cout << "可以穿戴战神盔甲。" << endl;
        cout << "恭喜你,完成了终极任务,终于过关了!" << endl;
        return false;
    }

    return true;
}

void BiQiTown::describe_scene() {


    LeadingHero *hero = (LeadingHero *) (ManagerConst().heroList[0]);       //此处没有用到ManagerConst().monsterList[0]


    /**
     * 比奇小镇的野外场景描述。
     */

    if (false == faceMonster) {                                         //如果此时还没有遇到怪物,弹出【遇怪提示】

        cout << "现在处于比奇镇周边的树林之中。希望你没有迷路……" << endl;
        cout << "树丛中发出一股窸窸窣窣的声音,遭遇怪物!" << endl;

        printf("开始与%s战斗!!!\n", monsters[0]->label.c_str());
        printf("你现在的状态为:\n");
        printf("生命健康值:%d   \n攻击力:%d   \n防御力:%d   \n背包金钱:%d   \n",
               hero->health, hero->attack_ability, hero->defence_ability, hero->money);

        faceMonster = true;                                             //【遇怪提示】显示完毕后,标记为已经遇怪
    }





    /**
     * 战斗开始之后的场景描述
     */



    //现在是第几回合。
    //请选择你的动作
    //1.攻击。2.逃跑。


    rounds++;

    printf("现在是第%d回合\n", rounds);
    cout << "请选择你的动作" << endl;
    cout << "1.攻击。" << endl;
    cout << "2.逃跑。" << endl;


}

bool BiQiTown::continue_switch_action() {

    //你对怪物发动了攻击。
    //你打掉了怪物多少的生命。
    //怪物还剩多少点生命。
    //怪物对你发动了攻击。
    //怪物打掉了你多少的生命。
    //你还剩多少点生命值。

    //你决定逃跑
    //逃跑成功。



    cin >> cur_choice;


    switch (battleType) {
        case BattleType::Cat_Small: {

            HookMoreCat *cur_monster = ((HookMoreCat *) (monsters[0]));

            switch (cur_choice) {

                case 1: {
                    printf("你对%s发动了攻击,", cur_monster->label.c_str());
                    int damage_to_monster = heros[0]->attack_ability - cur_monster->defence_ability;
                    printf("你打掉了%s%d的生命,",
                           cur_monster->label.c_str(), damage_to_monster);
                    cur_monster->health -= damage_to_monster;            //怪物扣血了。
                    printf("%s还剩%d点生命。\n", cur_monster->label.c_str(), cur_monster->health);

                    printf("%s对你发动了攻击,", cur_monster->label.c_str());
                    int damage_to_hero = cur_monster->attack_ability - heros[0]->defence_ability;
                    printf("%s打掉了你%d的生命,",
                           cur_monster->label.c_str(), damage_to_hero);
                    heros[0]->health -= damage_to_hero;            //主角英雄扣血了。
                    printf("你还剩%d点生命。\n\n", heros[0]->health);

                    if (0 >= cur_monster->health) {
                        //击杀了怪物
                        printf("%s被你杀死了!你真厉害!!!\n", cur_monster->label.c_str());
                        heros[0]->money += cur_monster->money_remaining;          //获得了怪物身上的金钱。【屠龙者会变成巨龙?】
                        printf("你搜索%s掉落的物品,得到了%dG。你现在拥有了%dG。",
                               cur_monster->label.c_str(), cur_monster->money_remaining, heros[0]->money);
                        return false;                   //战斗结束。
                    } else if (0 >= heros[0]->health) {
                        printf("你被%s杀死了,游戏结束。\n", cur_monster->label.c_str());                    //被怪物打至空血。回城复活。
                        return false;                   //战斗结束。
                    }

                    break;
                }
                case 2: {
                    cout << "你决定逃跑!" << endl;
                    cout << "逃跑成功!" << endl;
                    return false;                       //战斗结束
                    break;
                }
            }

            break;
        }
        case BattleType::Snowman_Large: {

            ForestSnowman *cur_monster = ((ForestSnowman *) (monsters[0]));

            switch (cur_choice) {

                case 1: {
                    printf("你对%s发动了攻击\n", cur_monster->label.c_str());
                    int damage_to_monster = heros[0]->attack_ability - cur_monster->defence_ability;
                    printf("你打掉了%s%d的生命\n",
                           cur_monster->label.c_str(), damage_to_monster);
                    cur_monster->health -= damage_to_monster;            //怪物扣血了。
                    printf("%s还剩%d点生命。\n", cur_monster->label.c_str(), cur_monster->health);

                    printf("%s对你发动了攻击\n", cur_monster->label.c_str());
                    int damage_to_hero = cur_monster->attack_ability - heros[0]->defence_ability;
                    printf("%s打掉了你%d的生命\n",
                           cur_monster->label.c_str(), damage_to_hero);
                    heros[0]->health -= damage_to_hero;            //主角英雄扣血了。
                    printf("你还剩%d点生命。\n", heros[0]->health);

                    if (0 >= cur_monster->health) {
                        //击杀了怪物
                        printf("%s被你杀死了!你真厉害!!!\n", cur_monster->label.c_str());
                        heros[0]->money += cur_monster->money_remaining;          //获得了怪物身上的金钱。【屠龙者会变成巨龙?】
                        printf("你搜索%s掉落的物品,得到了%dG。你现在拥有了%dG。",
                               cur_monster->label.c_str(), cur_monster->money_remaining, heros[0]->money);
                        return false;                   //战斗结束。
                    } else if (0 >= heros[0]->health) {
                        printf("你被%s杀死了,游戏结束。\n", cur_monster->label.c_str());                    //被怪物打至空血。回城复活。
                        return false;                   //战斗结束。
                    }

                    break;
                }
                case 2: {
                    cout << "你决定逃跑!" << endl;
                    cout << "逃跑成功!" << endl;
                    return false;                       //战斗结束
                    break;
                }
            }

            break;

        }
    }


    return true;

}

8.文件 ManagerConst.cpp

#include "_class_declaration_father.h"
#include "_class_implementation_son.h"

#include <iostream>
#include <vector>

using namespace std;


vector<BaseHero *> ManagerConst::heroList = vector<BaseHero *>();
vector<BaseScene *> ManagerConst::sceneList = vector<BaseScene *>();
vector<BaseMonster *> ManagerConst::monsterList = vector<BaseMonster *>();


ManagerConst::ManagerConst() {

}

ManagerConst::ManagerConst(bool needInit) {
    if (needInit) {
        initConstManager();         //初始化一下。每个向量,内容+1。
    } else {
        ManagerConst();             //什么都不执行。
    };
}

void ManagerConst::initConstManager() {                     //初始化管理类。
    this->heroList.push_back(new LeadingHero());

    this->sceneList.push_back(new Birth_TownSquare());
    this->sceneList.push_back(new Weapon_Shop());
    this->sceneList.push_back(new Drug_Shop());
    this->sceneList.push_back(new BiQiTown(new HookMoreCat(), BiQiTown::BattleType::Cat_Small));
    this->sceneList.push_back(new BiQiTown(new ForestSnowman(), BiQiTown::BattleType::Snowman_Large));

    this->monsterList.push_back(new HookMoreCat());
}

9.文件 game.cpp

#include "_class_implementation_son.h"             //数据类型
#include "_class_declaration_father.h"             //数据类型
#include "_logic_declaration.h"             //业务逻辑

/**
 * 原版创意地址  《用C++语言写游戏——打怪小游戏》
 *             http://blog.csdn.net/cnyali_ljf/article/details/51340317
 */

int main() {

    ManagerConst manager = ManagerConst(true);//世界管理类
    Birth_TownSquare *square = (Birth_TownSquare *) (manager.sceneList[0]);               //广场的实例。

    square->whole_logic();           //进入【广场】场景的主逻辑。

    return 0;
}


展开阅读全文

没有更多推荐了,返回首页