【OpenJudge】魔兽世界终极版

描述

首先对问题进行描述。

城市

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 .... N ( N <= 20 )。红魔军的司令部算作编号为0的城市,蓝魔军的司令部算作编号为N+1的城市。
每个城市中有生命元,得胜的一方可以取得用于补充。
每个城市产出10个生命元。生命元留在城市,直到被武士取走。
城市可以插旗子,一开始所有城市都没有旗子。在插红旗的城市,以及编号为奇数的无旗城市,由红武士主动发起进攻。在插蓝旗的城市,以及编号为偶数的无旗城市,由蓝武士主动发起进攻。
当某个城市有连续两场战斗都是同一方的武士杀死敌人(两场战斗之间如果有若干个战斗时刻并没有发生战斗,则这两场战斗仍然算是连续的;但如果中间有平局的战斗,就不算连续了) ,那么该城市就会插上胜方的旗帜,若原来插着败方的旗帜,则败方旗帜落下。旗帜一旦插上,就一直插着,直到被敌人更换。一个城市最多只能插一面旗帜,旗帜没被敌人更换前,也不会再次插同颜色的旗。

武器

武器有三种,sword, bomb,和arrow,编号分别为0,1,2。

Sword

sword武器的初始攻击力为拥有它的武士的攻击力的20%(去尾取整)。但是sword每经过一次战斗(不论是主动攻击还是反击),就会变钝,攻击力变为本次战斗前的80% (去尾取整)。sword攻击力变为0时,视为武士失去了sword。如果武士降生时得到了一个初始攻击力为0的sword,则视为武士没有sword.

Bomb

拥有bomb的武士,在战斗开始前如果判断自己将被杀死(不论主动攻击敌人,或者被敌人主动攻击都可能导致自己被杀死,而且假设武士可以知道敌人的攻击力和生命值),那么就会使用bomb和敌人同归于尽。武士不预测对方是否会使用bomb。
武士使用bomb和敌人同归于尽的情况下,不算是一场战斗,双方都不能拿走城市的生命元,也不影响城市的旗帜。

Arrow

arrow有一个攻击力值R。如果下一步要走到的城市有敌人,那么拥有arrow的武士就会放箭攻击下一个城市的敌人(不能攻击对方司令部里的敌人)而不被还击。arrow使敌人的生命值减少R,若减至小于等于0,则敌人被杀死。arrow使用3次后即被耗尽,武士失去arrow。两个相邻的武士可能同时放箭把对方射死。

武士

两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值、攻击力这三种属性。
红方司令部按 iceman、lion、wolf、ninja、dragon 的顺序制造武士。
蓝方司令部按 lion、dragon、ninja、iceman、wolf 的顺序制造武士。

编号

双方的武士编号都是从1开始计算。红方制造出来的第 n 个武士,编号就是n。同样,蓝方制造出来的第 n 个武士,编号也是n。

生命值

司令部有生命元,用于制造武士。制造武士需要生命元。制造一个初始生命值为 m 的武士,司令部中的生命元就要减少 m 个。
如果司令部中的生命元不足以制造某武士,那么司令部就等待,直到获得足够生命元后的第一个整点,才制造该武士。例如,在2:00,红方司令部本该制造一个 wolf ,如果此时生命元不足,那么就会等待,直到生命元足够后的下一个整点,才制造一个 wolf。
武士在刚降生的时候有一个初始的生命值,生命值在战斗中会发生变化,如果生命值减少到0(生命值变为负数时应当做变为0处理),则武士死亡(消失)。

Dragon

dragon可以拥有一件武器。编号为n的dragon降生时即获得编号为 n%3 的武器。
dragon还有“士气”这个属性,是个浮点数,其值为它降生后其司令部剩余生命元的数量除以造dragon所需的生命元数量。
dragon 在一次在它主动进攻的战斗结束后,如果还没有战死,而且士气值大于0.8,就会欢呼。
dragon每取得一次战斗的胜利(敌人被杀死),士气就会增加0.2,每经历一次未能获胜的战斗,士气值就会减少0.2。士气增减发生在欢呼之前。

Ninja

ninja可以拥有两件武器。编号为n的ninja降生时即获得编号为 n%3 和 (n+1)%3的武器。
ninja 挨打了也从不反击敌人。

Iceman

iceman有一件武器。编号为n的iceman降生时即获得编号为 n%3 的武器。
iceman 每前进两步,在第2步完成的时候,生命值会减少9,攻击力会增加20。但是若生命值减9后会小于等于0,则生命值不减9,而是变为1。即iceman不会因走多了而死。

Lion

lion 有“忠诚度”这个属性,其初始值等于它降生之后其司令部剩余生命元的数目。每经过一场未能杀死敌人的战斗,忠诚度就降低K。忠诚度降至0或0以下,则该lion逃离战场,永远消失。但是已经到达敌人司令部的lion不会逃跑。Lion在己方司令部可能逃跑。lion 若是战死,则其战斗前的生命值就会转移到对手身上。所谓“战斗前”,就是每个小时的40分前的一瞬间。

Wolf

wolf降生时没有武器,但是在战斗中如果获胜(杀死敌人),就会缴获敌人的武器,但自己已有的武器就不缴获了。被缴获的武器当然不能算新的,已经被用到什么样了,就是什么样的。

战斗

武士降生后就朝对方司令部走,在经过的城市如果遇到敌人(同一时刻每个城市最多只可能有1个蓝武士和一个红武士),就会发生战斗。每次战斗只有一方发起主动进攻一次。被攻击者生命值会减去进攻者的攻击力值和进攻者手中sword的攻击力值。被进攻者若没死,就会发起反击,被反击者的生命值要减去反击者攻击力值的一半(去尾取整)和反击者手中sword的攻击力值。反击可能致敌人于死地。
如果武士在战斗中杀死敌人(不论是主动进攻杀死还是反击杀死),则其司令部会立即向其发送8个生命元作为奖励,使其生命值增加8。当然前提是司令部得有8个生命元。如果司令部的生命元不足以奖励所有的武士,则优先奖励距离敌方司令部近的武士。
如果某武士在某城市的战斗中杀死了敌人,则该武士的司令部立即取得该城市中所有的生命元。注意,司令部总是先完成全部奖励工作,然后才开始从各个打了胜仗的城市回收生命元。对于因司令部生命元不足而领不到奖励的武士,司令部也不会在取得战利品生命元后为其补发奖励。

时间线

以下是不同时间会发生的不同事件:
在每个整点,即每个小时的第0分, 双方的司令部中各有一个武士降生。
在每个小时的第5分,该逃跑的lion就在这一时刻逃跑了。
在每个小时的第10分:所有的武士朝敌人司令部方向前进一步。即从己方司令部走到相邻城市,或从一个城市走到下一个城市。或从和敌军司令部相邻的城市到达敌军司令部。
在每个小时的第20分:每个城市产出10个生命元。生命元留在城市,直到被武士取走。
在每个小时的第30分:如果某个城市中只有一个武士,那么该武士取走该城市中的所有生命元,并立即将这些生命元传送到其所属的司令部。
在每个小时的第35分,拥有arrow的武士放箭,对敌人造成伤害。放箭事件应算发生在箭发出的城市。注意,放箭不算是战斗,因此放箭的武士不会得到任何好处。武士在没有敌人的城市被箭射死也不影响其所在城市的旗帜更换情况。
在每个小时的第38分,拥有bomb的武士评估是否应该使用bomb。如果是,就用bomb和敌人同归于尽。
在每个小时的第40分:在有两个武士的城市,会发生战斗。 如果敌人在5分钟前已经被飞来的arrow射死,那么仍然视为发生了一场战斗,而且存活者视为获得了战斗的胜利。此情况下不会有“武士主动攻击”,“武士反击”,“武士战死”的事件发生,但战斗胜利后应该发生的事情都会发生。如Wolf一样能缴获武器,旗帜也可能更换,等等。在此情况下,Dragon同样会通过判断是否应该轮到自己主动攻击来决定是否欢呼。
在每个小时的第50分,司令部报告它拥有的生命元数量。
在每个小时的第55分,每个武士报告其拥有的武器情况。
武士到达对方司令部后就算完成任务了,从此就呆在那里无所事事。
任何一方的司令部里若是出现了2个敌人,则认为该司令部已被敌人占领。
任何一方的司令部被敌人占领,则战争结束。战争结束之后就不会发生任何事情了。
给定一个时间,要求你将从0点0分开始到此时间为止的所有事件按顺序输出。事件及其对应的输出样例如下:

1)武士降生
输出样例: 000:00 blue lion 1 born
表示在 0点0分,编号为1的蓝魔lion武士降生
如果造出的是dragon,那么还要多输出一行,例:
000:00 blue dragon 1 born
Its morale is 23.34

表示该该dragon降生时士气是23. 34(四舍五入到小数点后两位)
如果造出的是lion,那么还要多输出一行,例:
000:00 blue lion 1 born
Its loyalty is 24

表示该lion降生时的忠诚度是24
2) lion逃跑
输出样例:
000:05 blue lion 1 ran away
表示在 0点5分,编号为1的蓝魔lion武士逃走
3) 武士前进到某一城市
输出样例:
000:10 red iceman 1 marched to city 1 with 20 elements and force 30
表示在 0点10分,红魔1号武士iceman前进到1号城市,此时他生命值为20,攻击力为30
对于iceman,输出的生命值和攻击力应该是变化后的数值
4)武士放箭
输出样例:
000:35 blue dragon 1 shot
表示在 0点35分,编号为1的蓝魔dragon武士射出一支箭。如果射出的箭杀死了敌人,则应如下输出:
000:35 blue dragon 1 shot and killed red lion 4
表示在 0点35分,编号为1的蓝魔dragon武士射出一支箭,杀死了编号为4的红魔lion。
5)武士使用bomb
输出样例:
000:38 blue dragon 1 used a bomb and killed red lion 7
表示在 0点38分,编号为1的蓝魔dragon武士用炸弹和编号为7的红魔lion同归于尽。
6) 武士主动进攻
输出样例:
000:40 red iceman 1 attacked blue lion 1 in city 1 with 20 elements and force 30
表示在0点40分,1号城市中,红魔1号武士iceman 进攻蓝魔1号武士lion,在发起进攻前,红魔1号武士iceman生命值为20,攻击力为 30
7) 武士反击
输出样例:
001:40 blue dragon 2 fought back against red lion 2 in city 1
表示在1点40分,1号城市中,蓝魔2号武士dragon反击红魔2号武士lion
8) 武士战死
输出样例:001:40 red lion 2 was killed in city 1
被箭射死的武士就不会有这一条输出。
9) 武士欢呼
输出样例:003:40 blue dragon 2 yelled in city 4
10) 武士获取生命元( elements )
输出样例:
001:40 blue dragon 2 earned 10 elements for his headquarter
输出不包括在30分不是通过战斗获取的elements
11) 旗帜升起
输出样例:004:40 blue flag raised in city 4
12) 武士抵达敌军司令部
输出样例:
001:10 red iceman 1 reached blue headquarter with 20 elements and force 30
(此时他生命值为20,攻击力为30)对于iceman,输出的生命值和攻击力应该是变化后的数值
13) 司令部被占领
输出样例:003:10 blue headquarter was taken
14)司令部报告生命元数量
000:50 100 elements in red headquarter
000:50 120 elements in blue headquarter
表示在0点50分,红方司令部有100个生命元,蓝方有120个
15)武士报告武器情况
000:55 blue wolf 2 has arrow(2),bomb,sword(23)
000:55 blue wolf 4 has no weapon
000:55 blue wolf 5 has sword(20)
表示在0点55分,蓝魔2号武士wolf有一支arrow(这支arrow还可以用2次),一个bomb,还有一支攻击力为23的sword。
蓝魔4号武士wolf没武器。
蓝魔5号武士wolf有一支攻击力为20的sword。
交代武器情况时,次序依次是:arrow,bomb,sword。如果没有某种武器,某种武器就不用提。
报告时,先按从西向东的顺序所有的红武士报告,然后再从西向东所有的蓝武士报告。
输出事件时:
首先按时间顺序输出;
同一时间发生的事件,按发生地点从西向东依次输出. 武士前进的事件, 算是发生在目的地。
在一次战斗中有可能发生上面的 6 至 11 号事件。这些事件都算同时发生,其时间就是战斗开始时间。一次战斗中的这些事件,序号小的应该先输出。
两个武士同时抵达同一城市,则先输出红武士的前进事件,后输出蓝武士的。
显然,13号事件发生之前的一瞬间一定发生了12号事件。输出时,这两件事算同一时间发生,但是应先输出12号事件
虽然任何一方的司令部被占领之后,就不会有任何事情发生了。但和司令部被占领同时发生的事件,全都要输出。

输入

第一行是t,代表测试数据组数
每组样例共三行。

第一行,五个整数 M,N,R,K, T。其含义为:
每个司令部一开始都有M个生命元( 1 <= M <= 10000)
两个司令部之间一共有N个城市( 1 <= N <= 20 )
arrow的攻击力是R
lion每经过一场未能杀死敌人的战斗,忠诚度就降低K。
要求输出从0时0分开始,到时间T为止(包括T) 的所有事件。T以分钟为单位,0 <= T <= 5000

第二行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它们都大于0小于等于10000

第三行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的攻击力。它们都大于0小于等于10000

输出

对每组数据,先输出一行:
Case n:
如对第一组数据就输出 Case1:
然后按恰当的顺序和格式输出到时间T为止发生的所有事件。每个事件都以事件发生的时间开头,时间格式是“时: 分”,“时”有三位,“分”有两位。

样例输入

1
20 1 10 10 1000
20 20 30 10 20
5 5 5 5 5

样例输出

Case 1:
000:00 blue lion 1 born
Its loyalty is 10
000:10 blue lion 1 marched to city 1 with 10 elements and force 5
000:30 blue lion 1 earned 10 elements for his headquarter
000:50 20 elements in red headquarter
000:50 20 elements in blue headquarter
000:55 blue lion 1 has no weapon
001:00 blue dragon 2 born
Its morale is 0.00
001:10 blue lion 1 reached red headquarter with 10 elements and force 5
001:10 blue dragon 2 marched to city 1 with 20 elements and force 5
001:30 blue dragon 2 earned 10 elements for his headquarter
001:50 20 elements in red headquarter
001:50 10 elements in blue headquarter
001:55 blue lion 1 has no weapon
001:55 blue dragon 2 has arrow(3)
002:10 blue dragon 2 reached red headquarter with 20 elements and force 5
002:10 red headquarter was taken

模块代码

全局量

#include<iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<list>
#include<string>
using namespace std;
/*
全局量
*/
const int RED=0,BLUE=1;//兵营编号
const char* SIDE[2]={"red","blue"};
const int SWORD=0,BOMB=1,ARROW=2;//武器编号
const char* ITEM[3]={"sword","bomb","arrow"};
const int DRAGON=0,NINJIA=1,ICEMAN=2,LION=3,WOLF=4;//士兵编号
const char* KIND[5]={"dragon","ninja","iceman","lion","wolf"};
const int CREAT[2][5]={{2,3,4,1,0},{3,0,1,2,4}};//造兵顺序
int KIND_HP[5];//建造所需生命元
int KIND_ATK[5];//兵种攻击力
int HEAD_HP[2];//司令部生命元
int ID[2];//士兵编号
int TIME;//现在时间
int TIME_LIM;//最多时间
int ARROW_ATK;//箭的攻击力
int LOYALTY_DEC;//忠诚度下降
int CITY_NUM;//城市数量
bool WIN[2];//是否胜利

武器类

/*
武器类
*/
class sword{
private:
    int atk;//攻击力
public:
    sword(int _atk):atk(_atk) {}
    int Atk() {return atk;}
    void BeUsed() {atk=atk*4/5;}
    bool Desert() {return atk==0;}
};

class arrow{
private:
    int atk;//攻击力
    int used;//使用次数
public:
    arrow(int _atk,int _used):atk(_atk),used(_used) {}
    int Atk() {return atk;}
    int Used() {return used;}
    void BeUsed() {used--;}
    bool Desert() {return used==0;}
};

typedef bool bomb;//bomb使用bool来操作

武士类

/*
武士类
*/
class warriors{
public:
    int kind;//兵种
    int side;//部落所属
    int id;//编号
    int hp;//生命元
    int atk;//攻击力
    sword* _sword;
    arrow* _arrow;
    bomb _bomb;
    warriors(int _kind,int _side,int _id);
    ~warriors();
    void GainHp(int _hp) {hp+=_hp;}
    virtual void MoraleChange(bool win){};//士气改变
    virtual void Yell(int city_id){};//dragon欢呼
    virtual bool Melt() {return false;}//iceman融化
    virtual void LoyaltyDec(){};//忠诚度下降
    virtual bool Escape() {return false;}//逃跑
    virtual int Attack(warriors* enemy,int city_id,bool predict);//攻击
    virtual int ReAttack(warriors* enemy,int city_id,bool predict);//反击
    virtual void Rob(warriors* enemy){};//缴获
    void Bugcheck(){}//检查bug用
};

class dragon: public warriors{
private:
    double morale;
public:
    dragon(int _kind,int _side,int _id);
    void MoraleChange(bool win) {morale+= (win? 0.2:-0.2);}
    void Yell(int city_id);
};

class ninjia: public warriors{
public:
    ninjia(int _kind,int _side,int _id);
    void ReAttack(warriors* enemy,int city_id);
};

class iceman: public warriors{
private:
    bool walked;
public:
    iceman(int _kind,int _side,int _id);
    bool Melt() {walked=!walked; return !walked;}
};

class lion: public warriors{
private:
    int loyalty;
public:
    lion(int _kind,int _side,int _id);
    void LoyaltyDec() {loyalty-=LOYALTY_DEC;}
    bool Escape() {return loyalty<=0;}
};

class wolf: public warriors{
public:
    wolf(int _kind,int _side,int _id);
    void Rob(warriors* enemy);
};

warriors::warriors(int _kind,int _side,int _id){
    kind=_kind;//初始化各种参数
    side=_side;
    id=_id;
    hp=KIND_HP[kind];
    atk=KIND_ATK[kind];
    _sword=NULL;
    _arrow=NULL;
    _bomb=false;
    switch (kind){
        case DRAGON: case ICEMAN:{
            switch (id%3){
                case SWORD:{
                    if (atk/5!=0) {_sword=new sword(atk/5);}
                    break;
                }
                case BOMB:{
                    _bomb=true;
                    break;
                }
                case ARROW:{
                    _arrow=new arrow(ARROW_ATK,3);
                    break;
                }
            }
            break;
        }//多个case匹配相同情况
        case NINJIA:{
            switch (id%3){
                case SWORD:{
                    if (atk/5!=0) {_sword=new sword(atk/5);}
                    _bomb=true;
                    break;
                }
                case BOMB:{
                    _bomb=true;
                    _arrow=new arrow(ARROW_ATK,3);
                    break;
                }
                case ARROW:{
                    _arrow=new arrow(ARROW_ATK,3);
                    if (atk/5!=0) {_sword=new sword(atk/5);}
                    break;
                }
            }
            break;
        }
    }//获得武器
    printf("%03d:00 %s %s %d born\n",TIME,SIDE[side],KIND[kind],ID[side]);
    //输出
}
warriors::~warriors(){
    if (_sword) {delete _sword;}
    if (_arrow) {delete _arrow;}
}
int warriors::Attack(warriors* enemy,int city_id,bool predict){
    if (!predict){//不是预测
        enemy->hp-=atk;//减去攻击力
        if (_sword){
            enemy->hp-=_sword->Atk();
            _sword->BeUsed();
            if (_sword->Desert()) {delete _sword; _sword=NULL;}
        }//减去剑的攻击力
        printf("%03d:40 %s %s %d attacked %s %s %d in city %d with %d elements and force %d\n",
            TIME,
            SIDE[side],KIND[kind],id,
            SIDE[enemy->side],KIND[enemy->kind],enemy->id,
            city_id,hp,atk);
        if (enemy->hp<=0){
            printf("%03d:40 %s %s %d was killed in city %d\n",
                TIME,
                SIDE[enemy->side],KIND[enemy->kind],enemy->id,
                city_id);
        }//敌方死了
        return enemy->hp;
    }else{//只预测结果
        int pre_hp=enemy->hp;
        pre_hp-=atk;
        if (_sword){
            pre_hp-=_sword->Atk();
        }
        //if (pre_hp>0) {enemy->ReAttack(this,city_id,predict);}
        return pre_hp;
    }
}
int warriors::ReAttack(warriors* enemy,int city_id,bool predict){
    if (!predict){//不是预测
        enemy->hp-=atk/2;//减去攻击力一半
        if (_sword){
            enemy->hp-=_sword->Atk();
            _sword->BeUsed();
            if (_sword->Desert()) {delete _sword; _sword=NULL;}
        }
        printf("%03d:40 %s %s %d fought back against %s %s %d in city %d\n",
            TIME,
            SIDE[side],KIND[kind],id,
            SIDE[enemy->side],KIND[enemy->kind],enemy->id,
            city_id);
        if (enemy->hp<=0){
            printf("%03d:40 %s %s %d was killed in city %d\n",
                TIME,
                SIDE[enemy->side],KIND[enemy->kind],enemy->id,
                city_id);
        }//敌方死了
        return enemy->hp;
    }else{//只预测结果
        int pre_hp=enemy->hp;
        pre_hp-=atk/2;
        if (_sword){
            pre_hp-=_sword->Atk();
        }
        return pre_hp;
    }
}

dragon::dragon(int _kind,int _side,int _id):warriors(_kind,_side,_id){
    morale=(double)(HEAD_HP[side]-KIND_HP[DRAGON])/KIND_HP[DRAGON];
    printf("Its morale is %.2lf\n",morale);
}
void dragon::Yell(int city_id){
    if(morale>0.8){
        printf("%03d:40 %s dragon %d yelled in city %d\n",TIME,SIDE[side],id,city_id);
    }
}

ninjia::ninjia(int _kind,int _side,int _id):warriors(_kind,_side,_id){}
void ninjia::ReAttack(warriors* enemy,int city_id){}

iceman::iceman(int _kind,int _side,int _id):warriors(_kind,_side,_id){
    walked=false;
}

lion::lion(int _kind,int _side,int _id):warriors(_kind,_side,_id){
    loyalty=HEAD_HP[side]-KIND_HP[LION];
    printf("Its loyalty is %d\n",loyalty);
}

wolf::wolf(int _kind,int _side,int _id):warriors(_kind,_side,_id){}
void wolf::Rob(warriors* enemy){
    if (!_sword&&enemy->_sword){
        _sword=enemy->_sword;
        enemy->_sword=NULL;
    }
    if (!_arrow&&enemy->_arrow){
        _arrow=enemy->_arrow;
        enemy->_arrow=NULL;
    }
    if (!_bomb&&enemy->_bomb){
        _bomb=true;
        enemy->_bomb=false;
    }//抢夺三种武器
}

城市类

/*
城市类
*/
class city{
public:
    int id;
    int hp;
    int flag;
    int last_fight;
    bool headquarter[2];//[0]是否为司令部,[1]是否被占领过
    warriors* Soldier[2];//红蓝方士兵
    void initial(int _id,bool _headquarter);//初始化
    void Escape();//lion逃跑
    void Produce() {hp+=10;}//产出生命元
    void Rob();//只有一个武士 取走生命元
    void Bomb();//炸弹的使用
    int Fight(bool predict);//战斗(是否为预测),返回战斗结果
    void Bugcheck(){}//检查bug用
};//最多22座城市
city City[22];

void city::initial(int _id,bool _headquarter){
    id=_id;
    hp=0;
    flag=-1;//表示无旗
    last_fight=-1;//表示还没有发生过战斗
    headquarter[0]=_headquarter;
    headquarter[1]=false;//未被占领过
    Soldier[0]=NULL;
    Soldier[1]=NULL;
}

降生

/*
降生
双方的司令部中各有一个武士降生。
*/
warriors* _Soldier;
void born_side(int side){
    if (_Soldier) {_Soldier=NULL;}
    switch (CREAT[side][ID[side]%5]){
        case DRAGON: if (HEAD_HP[side]>=KIND_HP[DRAGON]){
            _Soldier=new dragon(DRAGON,side,++ID[side]);
            HEAD_HP[side]-=KIND_HP[DRAGON];} break;
        case NINJIA: if (HEAD_HP[side]>=KIND_HP[NINJIA]){
            _Soldier=new ninjia(NINJIA,side,++ID[side]);
            HEAD_HP[side]-=KIND_HP[NINJIA];} break;
        case ICEMAN: if (HEAD_HP[side]>=KIND_HP[ICEMAN]){
            _Soldier=new iceman(ICEMAN,side,++ID[side]);
            HEAD_HP[side]-=KIND_HP[ICEMAN];} break;
        case LION:   if (HEAD_HP[side]>=KIND_HP[LION]){
            _Soldier=new lion(LION,side,++ID[side]);
            HEAD_HP[side]-=KIND_HP[LION];} break;
        case WOLF:   if (HEAD_HP[side]>=KIND_HP[WOLF]){
            _Soldier=new wolf(WOLF,side,++ID[side]);
            HEAD_HP[side]-=KIND_HP[WOLF];} break;
    }
}
void born(){
    born_side(RED);
    City[0].Soldier[RED]=_Soldier;
    born_side(BLUE);
    City[CITY_NUM+1].Soldier[BLUE]=_Soldier;
}

逃跑

/*
逃跑
该逃跑的lion就在这一时刻逃跑了。
*/
void city::Escape(){
    for (int i=0;i<2;i++){
        if (Soldier[i]&&Soldier[i]->Escape()){
            printf("%03d:05 %s lion %d ran away\n",TIME,SIDE[i],Soldier[i]->id);
            delete Soldier[i];//逃跑
            Soldier[i]=NULL;
        }
    }
}
void Escape(){
    for (int i=0;i<=CITY_NUM+1;i++){
        City[i].Escape();
    }
}

行军

/*
行军
所有的武士朝敌人司令部方向前进一步。
即从己方司令部走到相邻城市,或从一个城市走到下一个城市。
或从和敌军司令部相邻的城市到达敌军司令部。
*/
void March(){
    warriors* march[22][2];
    warriors* temp[2];//记录溢出的部分
    for (int i=0;i<=CITY_NUM+1;i++){
        for (int j=0;j<2;j++){
            march[i][j]=NULL;
        }
    }

    for (int i=0;i<=CITY_NUM;i++){
        march[i+1][RED]=City[i].Soldier[RED];//红方右移
    }temp[RED]=City[CITY_NUM+1].Soldier[RED];
    for (int i=CITY_NUM+1;i>=1;i--){
        march[i-1][BLUE]=City[i].Soldier[BLUE];//蓝方左移
    }temp[BLUE]=City[0].Soldier[BLUE];

    for (int i=0;i<=CITY_NUM+1;i++){
        for (int j=0;j<2;j++){
            if (march[i][j]&&march[i][j]->Melt()){
                march[i][j]->hp= march[i][j]->hp>9? march[i][j]->hp-9:1;
                march[i][j]->atk+=20;
            }
        }
    }//iceman融化

    if (march[0][BLUE]){
        printf("%03d:10 blue %s %d reached red headquarter with %d elements and force %d\n",
            TIME,
            KIND[march[0][BLUE]->kind],
            march[0][BLUE]->id,
            march[0][BLUE]->hp,
            march[0][BLUE]->atk);
        if (City[0].headquarter[1]){
            WIN[BLUE]=true;
            printf("%03d:10 red headquarter was taken\n",TIME);
        }else {City[0].headquarter[1]=true;}//红方被占领
    }

    for (int i=1;i<=CITY_NUM;i++){
        if (march[i][RED]){
            printf("%03d:10 red %s %d marched to city %d with %d elements and force %d\n",
                TIME,
                KIND[march[i][RED]->kind],
                march[i][RED]->id,i,
                march[i][RED]->hp,
                march[i][RED]->atk);
        }
        if (march[i][BLUE]){
            printf("%03d:10 blue %s %d marched to city %d with %d elements and force %d\n",
                TIME,
                KIND[march[i][BLUE]->kind],
                march[i][BLUE]->id,i,
                march[i][BLUE]->hp,
                march[i][BLUE]->atk);
        }
    }//报告行军

    if (march[CITY_NUM+1][RED]){
        printf("%03d:10 red %s %d reached blue headquarter with %d elements and force %d\n",
            TIME,
            KIND[march[CITY_NUM+1][RED]->kind],
            march[CITY_NUM+1][RED]->id,
            march[CITY_NUM+1][RED]->hp,
            march[CITY_NUM+1][RED]->atk);
        if (City[CITY_NUM+1].headquarter[1]){
            WIN[RED]=true;
            printf("%03d:10 blue headquarter was taken\n",TIME);
        }else {City[CITY_NUM+1].headquarter[1]=true;}//蓝方被占领
    }
    for (int i=0;i<=CITY_NUM+1;i++){
        for (int j=0;j<2;j++){
            City[i].Soldier[j]=march[i][j];
        }
    }//行军
    if (temp[RED]){City[CITY_NUM+1].Soldier[RED]=temp[RED];}
    if (temp[BLUE]){City[0].Soldier[BLUE]=temp[BLUE];}
}

生产

/*
生产
每个城市产出10个生命元。生命元留在城市,直到被武士取走。
*/
void Produce(){
    for (int i=1;i<CITY_NUM+1;i++){
        City[i].Produce();
    }
}

获取生命元

/*
获取生命元
如果某个城市中只有一个武士,那么该武士取走该城市中的所有生命元,
并立即将这些生命元传送到其所属的司令部。
*/
void city::Rob(){
    if (Soldier[RED]&&!Soldier[BLUE]){
        HEAD_HP[RED]+=hp;
        printf("%03d:30 %s %s %d earned %d elements for his headquarter\n",TIME,
            SIDE[RED],
            KIND[Soldier[RED]->kind],
            Soldier[RED]->id,hp);
        hp=0;
    }
    if (Soldier[BLUE]&&!Soldier[RED]){
        HEAD_HP[BLUE]+=hp;
        printf("%03d:30 %s %s %d earned %d elements for his headquarter\n",TIME,
            SIDE[BLUE],
            KIND[Soldier[BLUE]->kind],
            Soldier[BLUE]->id,hp);
        hp=0;
    }
}
void Rob(){
    for (int i=1;i<=CITY_NUM;i++){
        City[i].Rob();
    }
}

放箭

/*
放箭
拥有arrow的武士放箭,对敌人造成伤害。
不能攻击对方司令部里的敌人!
*/
void Shoot_red(int i){
    if (City[i].Soldier[RED]&&City[i].Soldier[RED]->_arrow&&City[i+1].Soldier[BLUE]){
        City[i+1].Soldier[BLUE]->hp-=City[i].Soldier[RED]->_arrow->Atk();
        City[i].Soldier[RED]->_arrow->BeUsed();
        if (City[i].Soldier[RED]->_arrow->Desert()){//丢弃
            delete City[i].Soldier[RED]->_arrow;
            City[i].Soldier[RED]->_arrow=NULL;
        }
        printf("%03d:35 red %s %d shot",
            TIME,
            KIND[City[i].Soldier[RED]->kind],
            City[i].Soldier[RED]->id);
        if (City[i+1].Soldier[BLUE]->hp>0) {printf("\n");}
        else{
            printf(" and killed blue %s %d\n",
                KIND[City[i+1].Soldier[BLUE]->kind],
                City[i+1].Soldier[BLUE]->id);
        }
    }
}
void Shoot_blue(int i){
    if (City[i].Soldier[BLUE]&&City[i].Soldier[BLUE]->_arrow&&City[i-1].Soldier[RED]){
        City[i-1].Soldier[RED]->hp-=City[i].Soldier[BLUE]->_arrow->Atk();
        City[i].Soldier[BLUE]->_arrow->BeUsed();
        if (City[i].Soldier[BLUE]->_arrow->Desert()){
            delete City[i].Soldier[BLUE]->_arrow;
            City[i].Soldier[BLUE]->_arrow=NULL;
        }
        printf("%03d:35 blue %s %d shot",
            TIME,
            KIND[City[i].Soldier[BLUE]->kind],
            City[i].Soldier[BLUE]->id);
        if (City[i-1].Soldier[RED]->hp>0) {printf("\n");}
        else{
            printf(" and killed red %s %d\n",
                KIND[City[i-1].Soldier[RED]->kind],
                City[i-1].Soldier[RED]->id);
        }
    }
}
void Shoot(){
    Shoot_red(0);
    Shoot_red(1);
    for (int i=2;i<CITY_NUM;i++){
        Shoot_red(i);
        Shoot_blue(i);
    }
    Shoot_blue(CITY_NUM);
    Shoot_blue(CITY_NUM+1);
}

Bomb使用

/*
bomb使用
*/
void city::Bomb(){
    if (!Soldier[RED]||!Soldier[BLUE]) {return ;}//兵不齐全
    for (int i=0;i<2;i++){
        if (Soldier[i]->hp<=0) {return ;}//有人曾被射死
        int result=Fight(true);
        if (result!=-1&& Soldier[i]->_bomb&& result!=i){//不是平局,我方有炸弹且对方胜利
            printf("%03d:38 %s %s %d used a bomb and killed %s %s %d\n",
                TIME,
                SIDE[Soldier[i]->side],
                KIND[Soldier[i]->kind],
                Soldier[i]->id,
                SIDE[Soldier[(i+1)%2]->side],
                KIND[Soldier[(i+1)%2]->kind],
                Soldier[(i+1)%2]->id);
            delete Soldier[RED]; delete Soldier[BLUE];
            Soldier[RED]=NULL; Soldier[BLUE]=NULL;
            return ;
        }
    }
}
void Bomb(){
    for (int i=1;i<=CITY_NUM;i++){
        if (City[i].Soldier[RED]&&City[i].Soldier[BLUE]){
            if (City[i].Soldier[RED]->hp>0&&City[i].Soldier[BLUE]->hp>0){
                City[i].Bomb();
            }
        }
    }
}

战斗

/*
战斗
*/
int city::Fight(bool predict){
    int result=2;//战斗结果
    if (Soldier[RED]&&Soldier[BLUE]){
        if (Soldier[RED]->hp<=0||Soldier[BLUE]->hp<=0) {return result;}//有人曾被箭射死,返回2
        int result_atk=1;
        int atk_side;//先攻方编号
        int result_reatk=1;
        int reatk_side;//反攻方编号
        if (flag==RED){//红方先攻
            atk_side=RED;
            reatk_side=BLUE;
            result_atk=Soldier[RED]->Attack(Soldier[BLUE],id,predict);
            if (result_atk>0&&Soldier[BLUE]->kind!=NINJIA) {result_reatk=Soldier[BLUE]->ReAttack(Soldier[RED],id,predict);}
        }
        if (flag==BLUE){//蓝方先攻
            atk_side=BLUE;
            reatk_side=RED;
            result_atk=Soldier[BLUE]->Attack(Soldier[RED],id,predict);
            if (result_atk>0&&Soldier[RED]->kind!=NINJIA) {result_reatk=Soldier[RED]->ReAttack(Soldier[BLUE],id,predict);}
        }
        if (flag==-1){//按奇数偶数攻击
            if (id%2==1){
                atk_side=RED;
                reatk_side=BLUE;
                result_atk=Soldier[RED]->Attack(Soldier[BLUE],id,predict);
                if (result_atk>0&&Soldier[BLUE]->kind!=NINJIA) {result_reatk=Soldier[BLUE]->ReAttack(Soldier[RED],id,predict);}
            }
            else{
                atk_side=BLUE;
                reatk_side=RED;
                result_atk=Soldier[BLUE]->Attack(Soldier[RED],id,predict);
                if (result_atk>0&&Soldier[RED]->kind!=NINJIA) {result_reatk=Soldier[RED]->ReAttack(Soldier[BLUE],id,predict);}
            }
        }
        if (result_atk<=0) {result=atk_side;}//先攻方胜利
        else if (result_atk>0&&result_reatk<=0) {result=reatk_side;}//反攻方胜利
        else {result=-1;}//平局
        /*if (last_fight!=result) {last_fight=result;}//与上一场结果比较
        else if (flag!=result){//与旗帜比较
            flag=result;
            if (flag!=-1){

            }
        }*/
    }
    return result;
}
void Fight(){
    int result;
    int hp_store[2]={0,0};//hp暂存处
    for (int i=1;i<=CITY_NUM;i++){
        result=-1;
        if (City[i].Soldier[RED]&& City[i].Soldier[BLUE]){
            int rec_hp[2];
            rec_hp[RED]=City[i].Soldier[RED]->hp;
            rec_hp[BLUE]=City[i].Soldier[BLUE]->hp;//保存hp副本
            if (City[i].Soldier[RED]->hp<=0 && City[i].Soldier[BLUE]->hp<=0){//都被射死了
                delete City[i].Soldier[RED];delete City[i].Soldier[BLUE];
                City[i].Soldier[RED]=NULL;City[i].Soldier[BLUE]=NULL;
                continue;
            }
            if (TIME==48){
                City[i].Soldier[RED]->Bugcheck();
                City[i].Soldier[BLUE]->Bugcheck();
            }
            if (City[i].Soldier[RED]->hp>0 && City[i].Soldier[BLUE]->hp<=0){//蓝方被射死了
                result=RED;
            }
            if (City[i].Soldier[BLUE]->hp>0 && City[i].Soldier[RED]->hp<=0){//红方被射死了
                result=BLUE;
            }
            if (City[i].Soldier[BLUE]->hp>0 && City[i].Soldier[RED]->hp>0){//都没死
                result=City[i].Fight(false);
            }

            if (result!=-1){//有胜有败
                if (HEAD_HP[result]>=8){
                    City[i].Soldier[result]->hp+=8;
                    HEAD_HP[result]-=8;
                }//派发生命元
                City[i].Soldier[result]->MoraleChange(true);
                City[i].Soldier[(result+1)%2]->MoraleChange(false);//士气改变

                if (City[i].flag==result) {City[i].Soldier[result]->Yell(i);}//欢呼
                if (City[i].flag==-1&&i%2!=result) {City[i].Soldier[result]->Yell(i);}//欢呼

                hp_store[result]+=City[i].hp;
                printf("%03d:40 %s %s %d earned %d elements for his headquarter\n",TIME,
                    SIDE[result],
                    KIND[City[i].Soldier[result]->kind],
                    City[i].Soldier[result]->id,City[i].hp);
                City[i].hp=0;//武士获取生命元

                if (City[i].Soldier[(result+1)%2]->kind==LION&&rec_hp[(result+1)%2]>0){
                    City[i].Soldier[result]->hp+=rec_hp[(result+1)%2];
                }//战败lion交出生命元

                City[i].Soldier[result]->Rob(City[i].Soldier[(result+1)%2]);//wolf缴获
            }
            else{//平局
                City[i].Soldier[RED]->MoraleChange(false);
                City[i].Soldier[BLUE]->MoraleChange(false);//士气改变
                City[i].Soldier[RED]->LoyaltyDec();
                City[i].Soldier[BLUE]->LoyaltyDec();//忠诚度改变
                for (int k=0;k<2;k++){
                    if (City[i].flag==k) {City[i].Soldier[k]->Yell(i);}//欢呼
                    if (City[i].flag==-1&&i%2!=k) {City[i].Soldier[k]->Yell(i);}//欢呼
                }
            }
            if (TIME==64&&i==12){
                City[i].Bugcheck();
            }

            if (City[i].last_fight!=result) {City[i].last_fight=result;}//与上一场结果比较
            else if (City[i].flag!=result){//若与上一场结果相同则与旗帜比较,当与旗帜不同时旗帜更换
                if (result!=-1){//如果更换的不是无旗帜
                    printf("%03d:40 %s flag raised in city %d\n",TIME,SIDE[result],i);//旗帜升起
                    City[i].flag=result;
                }
            }
        }
    }
    for (int i=1;i<=CITY_NUM;i++){
        for (int j=0;j<2;j++){
            if (City[i].Soldier[j]&& City[i].Soldier[j]->hp<=0){
                delete City[i].Soldier[j];
                City[i].Soldier[j]=NULL;
            }
        }
    }//清理战场
    HEAD_HP[RED]+=hp_store[RED];
    HEAD_HP[BLUE]+=hp_store[BLUE];//回收存储
}

报告

/*
报告
*/
void Report_head(){
    printf("%03d:50 %d elements in red headquarter\n",TIME,HEAD_HP[RED]);
    printf("%03d:50 %d elements in blue headquarter\n",TIME,HEAD_HP[BLUE]);
}
void Report_sold(){
    bool _arrow,_bomb,_sword;
    for (int i=0;i<=CITY_NUM+1;i++){
        if (City[i].Soldier[RED]){
            _arrow=(bool)City[i].Soldier[RED]->_arrow;
            _bomb=City[i].Soldier[RED]->_bomb;
            _sword=(bool)City[i].Soldier[RED]->_sword;
            printf("%03d:55 red %s %d has ",TIME,KIND[City[i].Soldier[RED]->kind],City[i].Soldier[RED]->id);
            if (_arrow) {printf("arrow(%d)",City[i].Soldier[RED]->_arrow->Used());}
            if (_arrow&&_bomb) {printf(",");}
            if (_bomb) {printf("bomb");}
            if ((_arrow||_bomb)&&_sword) {printf(",");}
            if (_sword) {printf("sword(%d)",City[i].Soldier[RED]->_sword->Atk());}
            if (!_arrow&&!_bomb&&!_sword) {printf("no weapon\n");}
            if (_arrow||_bomb||_sword) {printf("\n");}
        }
    }//红方报告
    for (int i=0;i<=CITY_NUM+1;i++){
        if (City[i].Soldier[BLUE]){
            _arrow=(bool)City[i].Soldier[BLUE]->_arrow;
            _bomb=City[i].Soldier[BLUE]->_bomb;
            _sword=(bool)City[i].Soldier[BLUE]->_sword;
            printf("%03d:55 blue %s %d has ",TIME,KIND[City[i].Soldier[BLUE]->kind],City[i].Soldier[BLUE]->id);
            if (_arrow) {printf("arrow(%d)",City[i].Soldier[BLUE]->_arrow->Used());}
            if (_arrow&&_bomb) {printf(",");}
            if (_bomb) {printf("bomb");}
            if ((_arrow||_bomb)&&_sword) {printf(",");}
            if (_sword) {printf("sword(%d)",City[i].Soldier[BLUE]->_sword->Atk());}
            if (!_arrow&&!_bomb&&!_sword) {printf("no weapon\n");}
            if (_arrow||_bomb||_sword) {printf("\n");}
        }
    }//蓝方报告
}

输入

/*
输入
*/
void Scan(){
    scanf("%d %d %d %d %d",&HEAD_HP[RED],&CITY_NUM,&ARROW_ATK,&LOYALTY_DEC,&TIME_LIM); HEAD_HP[BLUE]=HEAD_HP[RED];
    for (int i=0;i<5;i++){scanf("%d",&KIND_HP[i]);}
    for (int i=0;i<5;i++){scanf("%d",&KIND_ATK[i]);}
    for (int i=1;i<=CITY_NUM;i++){
        City[i].initial(i,false);
    }
    City[0].initial(0,true);
    City[CITY_NUM+1].initial(CITY_NUM+1,true);

    ID[RED]=0;ID[BLUE]=0;
    TIME=0;
    WIN[RED]=false;
    WIN[BLUE]=false;
}

停止检查

/*
检查停止时刻
*/
bool Check(int min) {return TIME_LIM>=TIME*60+min;}

输出

/*
输出
*/
void Print(){
    while (1){
        if (!Check(0)){break;}
        born();
        if (!Check(5)){break;}
        Escape();
        if (!Check(10)){break;}
        March();
        if (WIN[RED]||WIN[BLUE]){break;}
        if (!Check(20)){break;}
        Produce();
        if (!Check(30)){break;}
        Rob();
        if (!Check(35)){break;}
        Shoot();
        if (!Check(38)){break;}
        Bomb();
        if (!Check(40)){break;}
        Fight();
        if (!Check(50)){break;}
        Report_head();
        if (!Check(55)){break;}
        Report_sold();
        TIME++;
    }
}

主函数

/*
主函数
*/
int main(){
    /*
    freopen("Warcraft(3).in","r",stdin);
    freopen("my.txt","w",stdout);
    提交的时候忘记删除输出重定向了……怎么可以这么蠢
    */
    int n;
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        Scan();
        printf("Case %d:\n",i);
        Print();
    }
    return 0;
}

心得

  • 在类内部添加一个空函数bugcheck(),这样通过指针调用这个函数可以使VScode的调试访问这个指针的内存。
  • 记得删除输出重定向!QAQ
  • 模块化的编程对bug的调试真的很好用,出现的bug在输出中往往都集中在同一类型,很容易看出是哪一个模块的bug。
posted @ 2021-11-23 20:21  ParallelParadox  阅读(230)  评论(0编辑  收藏  举报