021:魔兽世界之二:装备

题目:

http://cxsjsxmooc.openjudge.cn/2021t3springall2/021/

分析:

本题主要是在 “ 魔兽世界之一 ” 的基础上增加了装备系统,需要新增一个武器类(包括基类和派生类),然后由于需要对每个武士的装备和状态进行输出,所以需要用到多态(virtual)。

下面给我写的代码以及郭炜老师的代码以供参考(我觉得参考他人特别是高手的代码不仅可以学习到其思想,还能学习到他人优秀的编码风格)。

参考代码(我的):

#include<iostream>
using namespace std;

#define WarriorNum 5
#define WarriorsMax 10000 //武士数量上限
#define WeaponNum 3


int WarriorLife[WarriorNum] ={};
char colors[2][5] = {"red", "blue"};
char WarriorsName[WarriorNum][10] ={"dragon" ,"ninja","iceman","lion","wolf"};
char WeaponName[WeaponNum][10] = {"sword", "bomb","arrow"};

class Headquarters;
class Warrior;
class Dragon;
class Ninja;
class Iceman;
class Lion;
class Wolf;
class Weapon;
class sword;
class bomb;
class arrow;

class Weapon{
private:
    int attack;
    int defend;
    int Type;
public:
    void Init(int _Type){
        Type = _Type;
    }
    int GetWeapon(){ return Type;}
};


class Warrior{
protected:
    int Life;
    int Type; //武士类别,分别是dragon 、ninja、iceman、lion、wolf
    int ArrayNum; //武士队列编号
    Headquarters * team; //指针指回Head,省下很多参数
public:
    Warrior(Headquarters * p,int _ArrayNum):team(p),ArrayNum(_ArrayNum){}
    virtual void PrintProduce(int time) = 0;
    void PrintProduce(int time,int) ;
    virtual ~Warrior(){};
};


class Headquarters{
private:
    int Life;
    int Color; //0是红,1是蓝。
    Warrior * WarriorsArray[WarriorsMax]; //武士队列
    int WarriorsArrayNum;
    int Warrior_MakeSeq[WarriorNum];//该司令部生产序列
    int MakeNum; //当前生产序列编号
    bool ProduceState;
    int WarriorsNums[WarriorNum]; //对应武士数量
public:
    Headquarters(int _Color, int _Life, int * _Warrior_MakeSeq):Color(_Color),Life(_Life){
        for(int i = 0; i < WarriorNum ;i++){
            Warrior_MakeSeq[i] = _Warrior_MakeSeq[i];
            WarriorsNums[i] = 0;
        }
        WarriorsArrayNum = 0;
        MakeNum = 0;
        ProduceState = true;
    }
    ~Headquarters(){
        for(int i = 0; i < WarriorsArrayNum; i++) delete WarriorsArray[i];
    }

    bool produce(int time);
    int GetLife() { return Life; }
    int GetColor(){ return Color; }
    int GetWarriorsNums(int Type){ return WarriorsNums[Type]; }
};

void Warrior::PrintProduce(int time,int) {
    int color = team->GetColor();
    printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n",
           time,colors[color],WarriorsName[Type],ArrayNum,
           Life,team->GetWarriorsNums(Type),WarriorsName[Type],colors[color]);
};

class Dragon:public Warrior{
private:
    Weapon wp;
    float Morale;
public:
    Dragon(Headquarters * p,int _ArrayNum):Warrior(p,_ArrayNum){
        Type = 0;
        Life = WarriorLife[Type];
        wp.Init(ArrayNum % WeaponNum);
        Morale = team->GetLife() * 1.0 / Life;
    }
    virtual void PrintProduce(int time){
        Warrior::PrintProduce(time,0);
        printf("It has a %s,and it's morale is %.02f\n",WeaponName[wp.GetWeapon()],Morale);
    }
//    virtual ~Dragon();
};

class Ninja:public Warrior{
private:
    Weapon wp[2];
public:
    Ninja(Headquarters * p,int _ArrayNum):Warrior(p,_ArrayNum){
        Type = 1;
        Life = WarriorLife[Type];
        wp[0].Init(ArrayNum % WeaponNum);
        wp[1].Init((ArrayNum + 1) % WeaponNum);
    }
    virtual void PrintProduce(int time){
        Warrior::PrintProduce(time,0);
        printf("It has a %s and a %s\n",WeaponName[wp[0].GetWeapon()],WeaponName[wp[1].GetWeapon()]);
    }
   // virtual ~Ninja();
};

class Iceman:public Warrior{
private:
    Weapon wp;
public:
    Iceman(Headquarters * p,int _ArrayNum):Warrior(p,_ArrayNum){
        Type = 2;
        Life = WarriorLife[Type];
        wp.Init(ArrayNum % WeaponNum);
    }
    virtual void PrintProduce(int time){
        Warrior::PrintProduce(time,0);
        printf("It has a %s\n",WeaponName[wp.GetWeapon()]);
    }
    //virtual ~Iceman();
};

class Lion:public Warrior{
private:
    int loyalty;
public:
    Lion(Headquarters * p,int _ArrayNum):Warrior(p,_ArrayNum){
        Type = 3;
        Life = WarriorLife[Type];
        loyalty = team->GetLife();
    }
    virtual void PrintProduce(int time){
        Warrior::PrintProduce(time,0);
        printf("It's loyalty is %d\n",loyalty);
    }
    //virtual ~Lion();
};

class Wolf:public Warrior{
public:
    Wolf(Headquarters * p,int _ArrayNum):Warrior(p,_ArrayNum){
        Type = 4;
        Life = WarriorLife[Type];
    }
    virtual void PrintProduce(int time){
        Warrior::PrintProduce(time,0);
    }
//    virtual ~Wolf();
};

bool Headquarters::produce(int time){
    if(ProduceState == false) return false;
    for(int i = 0; i < WarriorNum ; i++){
        if(Life >= WarriorLife[Warrior_MakeSeq[(MakeNum + i) % WarriorNum]]){
            MakeNum = (MakeNum + i) % WarriorNum;
            ProduceState = true;
            Life -= WarriorLife[Warrior_MakeSeq[MakeNum]];
            switch (Warrior_MakeSeq[MakeNum]) { //{"dragon" ,"ninja","iceman","lion","wolf"};
                case 0:
                    WarriorsArray[WarriorsArrayNum] = new Dragon(this,WarriorsArrayNum + 1);
                    break;
                case 1:
                    WarriorsArray[WarriorsArrayNum] = new Ninja(this,WarriorsArrayNum + 1);
                    break;
                case 2:
                    WarriorsArray[WarriorsArrayNum] = new Iceman(this,WarriorsArrayNum + 1);
                    break;
                case 3:
                    WarriorsArray[WarriorsArrayNum] = new Lion(this,WarriorsArrayNum + 1);
                    break;
                case 4:
                    WarriorsArray[WarriorsArrayNum] = new Wolf(this,WarriorsArrayNum + 1);
                    break;
            }
            WarriorsNums[Warrior_MakeSeq[MakeNum]] ++;
            WarriorsArray[WarriorsArrayNum++]->PrintProduce(time);
            MakeNum = (MakeNum + 1) % WarriorNum;
            return true;
        }
    }
    //上面没有return true则说明已经无法制造士兵了
    ProduceState = false;
    printf("%03d %s headquarter stops making warriors\n",time,colors[Color]);
    return false;

}


int main(){
    int n,m;
    cin >> n;
    for(int i = 1 ;i <= n ;i++){
        cout << "Case:" << i <<endl;
        cin >> m;
        for(int i = 0; i < WarriorNum ; i++){
            cin >> WarriorLife[i];
        }
        int Head_Red_Warrior_MakeSeq[WarriorNum] = {2,3,4,1,0};
        int Head_Blue_Warrior_MakeSeq[WarriorNum] = {3,0,1,2,4};
        Headquarters Head_Red(0,m,Head_Red_Warrior_MakeSeq);
        Headquarters Head_Blue(1,m,Head_Blue_Warrior_MakeSeq);
        bool Red_flag = true , Blue_flag = true; //
        int time = 0;
        while(Red_flag == true || Blue_flag == true){
            Red_flag = Head_Red.produce(time);
            Blue_flag= Head_Blue.produce(time);
            time ++;
        }
    }
    return 0;
}

参考代码(郭炜老师):


// by Guo Wei
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

//下面这些东西都是常量,而且不止一个类都要用到,就声明为全局的较为简单
#define WARRIOR_NUM 5
#define WEAPON_NUM 3
enum { DRAGON,NINJA,ICEMAN,LION,WOLF };

/*

char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };

红方司令部按照 iceman、lion、wolf、ninja、dragon 的顺序制造武士。
蓝方司令部按照 lion、dragon、ninja、iceman、wolf 的顺序制造武士。 */

class CHeadquarter;
class CDragon;
class CNinja;
class CIceman;
class CLion;
class CWolf;
class CWeapon;
class CWarrior;

class CWeapon {
public:
    int nKindNo;
    int nForce;
    static int InitialForce[WEAPON_NUM];
    static const char * Names[WEAPON_NUM];
};

class CWarrior {
protected:
    CHeadquarter * pHeadquarter;
    int nNo;
public:
    static const char * Names[WARRIOR_NUM];
    static int InitialLifeValue [WARRIOR_NUM];
    CWarrior( CHeadquarter * p,int nNo_):pHeadquarter(p),nNo(nNo_) { }
    virtual void PrintResult(int nTime,int nKindNo);
    virtual void PrintResult(int nTime) = 0;
    virtual ~CWarrior() { }

};

class CHeadquarter {
private:
    static const int MAX_WARRIORS = 1000;
    int nTotalLifeValue;
    bool bStopped;
    int nColor;
    int nCurMakingSeqIdx;
    int anWarriorNum[WARRIOR_NUM];
    int nTotalWarriorNum;
    CWarrior * pWarriors[MAX_WARRIORS];
public:
    friend class CWarrior;
    static int MakingSeq[2][WARRIOR_NUM];
    void Init(int nColor_, int lv);
    ~CHeadquarter () ;
    int Produce(int nTime);
    void GetColor( char * szColor);
    int GetTotalLifeValue() { return nTotalLifeValue; }
};

void CWarrior::PrintResult(int nTime,int nKindNo) {
    char szColor[20];
    pHeadquarter->GetColor(szColor);
    printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n"
            ,nTime, szColor, Names[nKindNo], nNo, InitialLifeValue[nKindNo],
           pHeadquarter->anWarriorNum[nKindNo],Names[nKindNo],szColor);

}

class CDragon:public CWarrior {
private:
    CWeapon wp;
    double fmorale;
public:
    void Countmorale(){
        fmorale = pHeadquarter -> GetTotalLifeValue() /(double)CWarrior::InitialLifeValue [0];
    }
    CDragon( CHeadquarter * p,int nNo_):CWarrior(p,nNo_) {
        wp.nKindNo = nNo % WEAPON_NUM;
        wp.nForce = CWeapon::InitialForce[wp.nKindNo ];
        Countmorale();
    }
    void PrintResult(int nTime) {
        CWarrior::PrintResult(nTime,DRAGON);
        printf("It has a %s,and it's morale is %.2f\n", CWeapon::Names[wp.nKindNo], fmorale); }
};

class CNinja:public CWarrior {
private:
    CWeapon wps[2];
public:
    CNinja( CHeadquarter * p,int nNo_):CWarrior(p,nNo_) {
        wps[0].nKindNo = nNo % WEAPON_NUM;
        wps[0].nForce = CWeapon::InitialForce[wps[0].nKindNo];
        wps[1].nKindNo = ( nNo + 1) % WEAPON_NUM;
        wps[1].nForce = CWeapon::InitialForce[wps[1].nKindNo];
    }
    void PrintResult(int nTime) {
        CWarrior::PrintResult(nTime,NINJA);
        printf("It has a %s and a %s\n",CWeapon::Names[wps[0].nKindNo],CWeapon::Names[wps[1].nKindNo]);
    }

};

class CIceman:public CWarrior {
private:
    CWeapon wp;
public:
    CIceman( CHeadquarter * p,int nNo_):CWarrior(p,nNo_) {
        wp.nKindNo = nNo % WEAPON_NUM;
        wp.nForce = CWeapon::InitialForce[ wp.nKindNo ];

    }

    void PrintResult(int nTime) {
        CWarrior::PrintResult(nTime,ICEMAN);
        printf("It has a %s\n",CWeapon::Names[wp.nKindNo]);
    }

};

class CLion:public CWarrior {
private:
    int nLoyalty;
public:
    void CountLoyalty() {
        nLoyalty = pHeadquarter ->GetTotalLifeValue();
    }
    CLion( CHeadquarter * p,int nNo_):CWarrior(p,nNo_) {CountLoyalty(); }
    void PrintResult(int nTime) {
        CWarrior::PrintResult(nTime,LION);
        CountLoyalty();
        printf("It's loyalty is %d\n",nLoyalty);
    }

};

class CWolf:public CWarrior {
public:
    CWolf( CHeadquarter * p,int nNo_):CWarrior(p,nNo_) { }
    void PrintResult(int nTime) {
        CWarrior::PrintResult(nTime,WOLF); }
};

void CHeadquarter::Init(int nColor_, int lv) {
    nColor = nColor_;
    nTotalLifeValue = lv;
    bStopped = false;
    nCurMakingSeqIdx = 0;
    nTotalWarriorNum = 0;

    for( int i = 0;i < WARRIOR_NUM;i ++ ) anWarriorNum[i] = 0;

}

CHeadquarter::~CHeadquarter () {
    int i;
    for( i = 0;i < nTotalWarriorNum; i ++ )  delete pWarriors[i];

}
int CHeadquarter::Produce(int nTime) {

    int nSearchingTimes = 0;
    if( bStopped )
        return 0;
    while( CWarrior::InitialLifeValue[MakingSeq[nColor][nCurMakingSeqIdx]]
           > nTotalLifeValue &&nSearchingTimes < WARRIOR_NUM )
    {
        nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
        nSearchingTimes ++;
    }

    int nKindNo = MakingSeq[nColor][nCurMakingSeqIdx];
    if( CWarrior::InitialLifeValue[nKindNo] > nTotalLifeValue ) {
        bStopped = true;
        if( nColor == 0)
            printf("%03d red headquarter stops making warriors\n",nTime);
        else
            printf("%03d blue headquarter stops making warriors\n",nTime);
        return 0;

    }
    nTotalLifeValue -= CWarrior::InitialLifeValue[nKindNo];
    nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
    int nTmp = anWarriorNum[nKindNo];
    anWarriorNum[nKindNo] ++;
    switch( nKindNo ) {
        case DRAGON:
            pWarriors[nTotalWarriorNum] = new CDragon( this,nTotalWarriorNum+1);
            break;
        case NINJA:
            pWarriors[nTotalWarriorNum] = new CNinja( this,nTotalWarriorNum+1);
            break;
        case ICEMAN:
            pWarriors[nTotalWarriorNum] = new CIceman( this,nTotalWarriorNum+1);
            break;
        case LION:
            pWarriors[nTotalWarriorNum] = new CLion( this,nTotalWarriorNum+1);
            break;
        case WOLF:
            pWarriors[nTotalWarriorNum] = new CWolf( this,nTotalWarriorNum+1);
            break;
    }

    pWarriors[nTotalWarriorNum]->PrintResult(nTime);
    nTotalWarriorNum ++;
    return 1;

}

void CHeadquarter::GetColor( char * szColor) {

    if( nColor == 0)
        strcpy(szColor,"red");
    else
        strcpy(szColor,"blue");
}

const char * CWeapon::Names[WEAPON_NUM] = {"sword","bomb","arrow" };
int CWeapon::InitialForce[WEAPON_NUM];
const char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
int CWarrior::InitialLifeValue [WARRIOR_NUM];

int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} };

int main() {

    int t;
    int m;
    //freopen("war2.in","r",stdin);
    CHeadquarter RedHead,BlueHead;
    scanf("%d",&t);
    int nCaseNo = 1;
    while ( t -- ) {
        printf("Case:%d\n",nCaseNo++);
        scanf("%d",&m);
        int i;
        for(i = 0;i < WARRIOR_NUM;i ++ )
            scanf("%d", & CWarrior::InitialLifeValue[i]);
        RedHead.Init(0,m);
        BlueHead.Init(1,m);
        int nTime = 0;
        while(true) {
            int tmp1 = RedHead.Produce(nTime);
            int tmp2 = BlueHead.Produce(nTime);
            if( tmp1 == 0 && tmp2 == 0) break;
            nTime ++;
        }
    }
    return 0;
}

 

 

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值