C++課作業 魔獸世界Part 1

URNOTJANET發表於2017-12-13

據說是去年的大作業,結果變成了今年的小實驗題,給老師一個大寫的微笑:) 題目描述:

【魔獸世界】

魔獸世界的西面是紅魔軍的司令部,東面是藍魔軍的司令部。兩個司令部之間是依次排列的若干城市。

紅司令部,City 1,City 2,……,City n,藍司令部

兩軍的司令部都會製造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五種。每種武士都有編號、生命值這兩種屬性。雙方的武士編號都是從1開始計算。紅方製造出來的第 n 個武士,編號就是n。同樣,藍方製造出來的第 n 個武士,編號也是n。武士在剛降生的時候有一個生命值。

有的武士可以擁有武器。武器有三種,sword, bomb和arrow,編號分別為0,1,2。不同的武士有不同的特點:

  • dragon 可以擁有一件武器。編號為n的dragon降生時即獲得編號為n%3的武器。dragon還有“士氣”這個屬性,是個浮點數,其值為它降生後其司令部剩餘生命元的數量除以製造dragon所需的生命元數量。

  • ninja可以擁有兩件武器。編號為n的ninja降生時即獲得編號為n%3和(n+1)%3的武器。

  • iceman有一件武器。編號為n的iceman降生時即獲得編號為n%3的武器。

  • lion 有“忠誠度”這個屬性,其值等於它降生後其司令部剩餘生命元的數目。

  • wolf沒特點。

請注意,在以後的題目裡,武士的士氣,生命值,忠誠度在其生存期間都可能發生變化,都有作用,武士手中的武器隨著使用攻擊力也會發生變化。

在每個整點,雙方的司令部中各有一個武士降生。紅方司令部按照 iceman、lion、wolf、ninja、dragon 的順序迴圈制造武士。藍方司令部按照 lion、dragon、ninja、iceman、wolf 的順序迴圈制造武士。製造武士需要生命元。製造一個初始生命值為 m 的武士,司令部中的生命元就要減少 m 個。如果司令部中的生命元不足以製造某個按順序應該製造的武士,那麼司令部就試圖製造下一個。如果所有武士都不能製造了,則司令部停止製造武士。

給定一個時間,和雙方司令部的初始生命元數目,要求你將從0點0分開始到雙方司令部停止製造武士為止的所有事件按順序輸出。一共有兩種事件,其對應的輸出樣例如下:

(1)武士降生

輸出樣例:

004 blue lion 5 born with strength 5, 2 lion in red headquarter

表示在 4點整,編號為5的藍魔lion武士降生,它降生時生命值為5,降生後藍魔司令部裡共有2個lion武士。(為簡單起見,不考慮單詞的複數形式)注意,每製造出一個新的武士,都要輸出此時司令部裡共有多少個該種武士。

如果造出的是dragon,那麼還要輸出一行,例:

It has a arrow, and its morale is 23.34

表示該dragon降生時得到了arrow,其士氣是23.34(為簡單起見,本題中arrow前面的冠詞用a,不用an,士氣精確到小數點後面2位,四捨五入)

如果造出的是ninja,那麼還要輸出一行,例:

It has a bomb and a arrow

表示該ninja降生時得到了bomb和arrow。

如果造出的是iceman,那麼還要輸出一行,例:

It has a sword

表示該iceman降生時得到了sword。

如果造出的是lion,那麼還要輸出一行,例:

Its loyalty is 24

表示該lion降生時的忠誠度是24。

(2)司令部停止製造武士

輸出樣例:

010 red headquarter stops making warriors

表示在 10點整,紅方司令部停止製造武士。

輸出事件時,首先按時間順序輸出;同一時間發生的事件,先輸出紅司令部的,再輸出藍司令部的。

【輸入】

第一行是一個整數,代表測試資料組數。

每組測試資料共兩行。

第一行:一個整數M。其含義為: 每個司令部一開始都有M個生命元(1 <= M <= 10000)

第二行:五個整數,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它們都大於0且小於等於10000。

【輸出】

對每組測試資料,要求輸出從0時0分開始,到雙方司令部都停止製造武士為止的所有事件。

對每組測試資料,首先輸出“Case:n”,n是測試資料的編號,從1開始,接下來按恰當的順序和格式輸出所有事件。每個事件都以事件發生的時間開頭,時間以小時為單位,有三位。

【樣例輸入】

1

20

3 4 5 6 7

【樣例輸出】

Case:1

000 red iceman 1 born with strength 5, 1 iceman in red headquarter

It has a bomb

000 blue lion 1 born with strength 6, 1 lion in blue headquarter

Its loyalty is 14

001 red lion 2 born with strength 6, 1 lion in red headquarter

Its loyalty is 9

001 blue dragon 2 born with strength 3, 1 dragon in blue headquarter

It has a arrow, and its morale is 3.67

002 red wolf 3 born with strength 7, 1 wolf in red headquarter

002 blue ninja 3 born with strength 4, 1 ninja in blue headquarter

It has a sword and a bomb

003 red headquarter stops making warriors

003 blue iceman 4 born with strength 5, 1 iceman in blue headquarter

It has a bomb

004 blue headquarter stops making warriors

考點:類和物件 這題有兩種建類的方法,一種是對每一個戰士單獨建一個class,另外一個就是對red和blue陣營建一個類。

兩種方法都能夠解決這道題,但是程式碼量差別比較大。

五種戰士的很多特點是共有的,比如生命值,是否擁有武器等等,所以如果按照武士單獨建class,會有很多冗餘。【雖然我自己就是這麼做的】

這裡只說我的思路吧。全部思路建立在”對武士單獨建類的前提下】

由於題目的輸出是有單獨要求的,所以必須要建立一個函式輸出,接著由於每個武士擁有一些各自的特性,所以輸入的時候,在對所有武士的生命值賦值之後,就按照要求(特定順序)開始一個個嘗試造武士。

特別的,還需要判斷是否用盡該陣營的所有生命值,而且red和blue的判斷是分開的,哪個先用盡哪個先退出。因為當時實在懶得思考這個了,所以我在判斷的那邊偷了點懶,直接用了幾個flag判斷。

程式碼如下:(共243行)

#include<iostream>
#include<string>
#include<iomanip>
#include<vector>
using namespace std;
int M1=0,M2=0;
int order1[5]={2,3,4,1,0}; //red製造順序
int order2[5]={3,0,1,2,4}; //blue製造順序
/*--------武器的基本型別------*/
string Weapon[3]={"sword","bomb","arrow"};
/*--------武士的基本類----*/
class dragon {
public:
    dragon(){};
    dragon(const &d){};
    int give_d(int i,int& M);
    void print_d(int j,int who);
    int live;
private:
    int weapon; //武器個數和種類
    int number;  //編號
    float morale;//士氣
};
class ninja {
public:
    ninja(){};
    int give_n(int i,int &M);
    void print_n(int j,int who);
    int live;
private:
    int wep[2]; //武器種類
    int number;  //編號
};
class iceman {
public:
    iceman(){};
    int give_i(int i,int &M);
    void print_i(int j,int who);
    int live;
private:
    int weapon; //武器個數和種類
    int number;  //編號
};
class lion {
public:
    lion(){};
    int give_l(int i,int &M);
    void print_l(int j,int who);
    int live;
private:
    int number;  //編號
    int loyalty; //忠誠度
};
class wolf {
public:
    wolf(){};
    int give_w(int i,int &M);
    void print_w(int j,int who);
    int live;
private:
    int number;  //編號
};

int dragon::give_d(int i,int& M){
    i=i+1;
    if(M-live>=0) {
        number=i;
        weapon=i%3;   //獲得1個武器,名字為Weapon[i%3]
        morale=(M-live)/(live);
        M=M-live;
        return 1;
    }
    return 0;
}
int ninja::give_n(int i,int &M){
    i=i+1;
    if(M-live>=0){
        number=i;
        wep[0]=i%3;   //獲得2個武器
        wep[1]=(i+1)%3;
        M=M-live;
        return 1;
    }
    return 0;
}
int iceman::give_i(int i,int &M) {
    i=i+1;
    if(M-live>=0){
        number=i;
        weapon=i%3;   //獲得1個武器,名字為Weapon[i%3]
        M=M-live;
        return 1;
    }
    return 0;
}
int lion::give_l(int i,int &M){
    i=i+1;
    if(M-live>=0){
        number=i;
        loyalty=M-live;
        M=M-live;
        return 1;
    }
    return 0;
}
int wolf::give_w(int i,int &M){
    i=i+1;
    if(M-live>=0){
        number=i;
        M=M-live;
        return 1;
    }
    return 0;
}
dragon d;
ninja ni;
iceman ic;
lion l;
wolf w;
vector<dragon> dra;  //用以儲存武士
vector<ninja> nin;
vector<iceman> ice;
vector<lion>li;
vector<wolf>wol;
/*-------控制輸出語句--------*/
void dragon::print_d(int j,int who) {
    cout<<setfill('0')<<setw(3)<<j;
    if(who){
        cout<<" red dragon "<<number<<" born with strength "<<live<<", ";
        cout<<dra.size()<<" dragon in red headquarter"<<endl;
    }
    else{
        cout<<" blue dragon "<<number<<" born with strength "<<live<<", ";
        cout<<dra.size()<<" dragon in blue headquarter"<<endl;
    }
    cout<<"It has a "<<Weapon[weapon]<<", and its morale is "<<morale<<endl;
}
void ninja::print_n(int j,int who) {
    cout<<setfill('0')<<setw(3)<<j;
    if(who){
        cout<<" red ninja "<<number<<" born with strength "<<live<<", ";
        cout<<" ninja in red headquarter"<<'\n';
    }
    else{
        cout<<" blue ninja "<<number<<" born with strength "<<live<<", ";
        cout<<nin.size()<<" ninja in blue headquarter"<<'\n';
    }
    cout<<"It has a "<<Weapon[wep[0]]<<" and a "<<Weapon[wep[1]]<<endl;
}
void iceman::print_i(int j,int who) {
    cout<<setfill('0')<<setw(3)<<j;
    if(who){
        cout<<" red iceman "<<number<<" born with strength "<<live<<", ";
        cout<<ice.size()<<" iceman in red headquarter"<<endl;
    }
    else{
        cout<<" blue iceman "<<number<<" born with strength "<<live<<", ";
        cout<<ice.size()<<" iceman in blue headquarter"<<endl;
    }
    cout<<"It has a "<<Weapon[weapon]<<endl;
}
void lion::print_l(int j,int who) {
    cout<<setfill('0')<<setw(3)<<j;
    if(who){
        cout<<" red lion "<<number<<" born with strength "<<live<<", ";
        cout<<li.size()<<" lion in red headquarter"<<endl;
    }
    else{
        cout<<" blue lion "<<number<<" born with strength "<<live<<", ";
        cout<<li.size()<<" lion in blue headquarter"<<endl;
    }
    cout<<"Its loyalty is "<<loyalty<<endl;
}
void wolf::print_w(int j,int who) {
    cout<<setfill('0')<<setw(3)<<j;
    if(who){
        cout<<" red wolf "<<number<<" born with strength "<<live<<", ";
        cout<<wol.size()<<" wolf in red headquarter"<<endl;
    }
    else{
        cout<<" blue wolf "<<number<<" born with strength "<<live<<", ";
        cout<<wol.size()<<" wolf in blue headquarter"<<endl;
    }
}

/*-------控制製造順序-------*/
int create(int k,int j,int &M,int who) {
    int flag=0;
    switch(k){
    case 0:if(d.give_d(j,M)){dra.push_back(d);flag=1;d.print_d(j,who);}
            break;
    case 1:if(ni.give_n(j,M)){nin.push_back(ni);flag=1;ni.print_n(j,who);}
            break;
    case 2:if(ic.give_i(j,M)){ice.push_back(ic);flag=1;ic.print_i(j,who);}
            break;
    case 3:if(l.give_l(j,M)){li.push_back(l);flag=1;l.print_l(j,who);}
            break;
    case 4:if(w.give_w(j,M)){wol.push_back(w);flag=1;w.print_w(j,who);}
            break;
    default:break;
    }
    return flag;
}

int main(){
    int i,j,k1=0,k2=0,n,tmp=0,mark1=0,mark2=0;
    int red=1,blue=0;

    cin>>n;
    for(i=1;i<n+1;i++){
        cin>>M1;
        M2=M1;
        cin>>d.live>>ni.live>>ic.live>>l.live>>w.live;
        cout<<"Case:"<<i<<endl;
        for(j=0;M1>=0||M2>=0;j++){
            while(M1>0&&tmp<5){
                if(create(order1[k1],j,M1,red)){k1++;break;}
                k1++;tmp++;
                if(k1==5)k1=0;
            }
            if((M1<=0&&!mark1)||(tmp>4&&!mark1)){
                mark1=1;
                cout<<setfill('0')<<setw(3)<<j<<" red headquarter stops making warriors"<<endl;
            }
            tmp=0;
            while(M2>0&&tmp<5) {
                if(create(order2[k2],j,M2,blue)){k2++;break;}
                k2++;tmp++;
                if(k2==5)k2=0;
            }
            if((M2<=0&&!mark2)||(tmp>4&&!mark2)){
                mark2=1;
                cout<<setfill('0')<<setw(3)<<j<<" blue headquarter stops making warriors"<<endl;
            }
            if(k1==5)k1=0;
            if(k2==5)k2=0;
        }
    }
    return 0;
}
 ```
複製程式碼

相關文章