北大程设 魔兽终极版总结

几个坑:
1.已经走到对方基地但是此时还没有赢的武士,仍需要报告工作
2.dragon的yell条件是自己没有死(对方是被弓射死会yell)
3.在有敌人的城市被射死会影响旗帜更换
4.奖励,获得生命源,插旗子等事情要一起做。

表述不清的地方
两个表述不清的问题:①双方可否知道对方是否有剑?可以②如果双方都判断要用炸弹,怎么输出?红的先判断并使用,如果红的确定要用,蓝的就不输出了

都被射死了不算平局

对方被弓射死dragon士气也变

魔兽3-终极版之间的变化
1.武士降生:需要多输出dragon的士气。如果获得攻击力=0的sword则视为没有武器。函数需要修一修,跟1.2里面规则完全不一样了
2.lion逃走
3.放arrow:发生在放箭城市。死人也可以放箭(表征同时放箭把对方射死)
4.战斗前使用bomb:不算是战斗,双方均不拿走生命源,不影响旗帜。使用bomb后把(双方)死人的指针给置为NULL。

5.战斗:
1)如果只有一个指针:生命值是否>0,如果没血了就给他擦去为NULL
2)如果有两个指针:
先看是否双方都有血
①都没血了,都擦去为NULL。不影响旗子
②只有一方有血,直接进行胜利后的各种操作
③双方都有血:只有一个人主动进攻一次。“被攻击者生命值会减去进攻者的攻击力值和进攻者手中sword的攻击力值。被进攻者若没死,就会发起反击,被反击者的生命值要减去反击者攻击力值的一半(去尾取整)和反击者手中sword的攻击力值。反击可能致敌人于死地。”
Attack_enemy,attack_back和 ninja的Attack_back都得写(写成空)
吸取生命源和战斗胜利在同一时间发生,要写

6.奖励和收取生命源:从远离自己司令部的城市开始奖励杀死敌人的武士。奖励完了再依次从胜利城市拿走生命源
7.插旗子:连续两场战斗都是一方胜利插旗子(中间没有战斗算,平局不算连续)
8.dragon的yell:一场战斗结束之后①士气增加:敌人被杀死,士气+0.2;敌人没被杀死,士气-0.2。
②进行yell:在主动攻击的战斗中没有战死且当前士气>0.8,欢呼。
9.战后需要做的:yell,wolf_rob,loyal_decrease,life_get

1.ninja没有还手。
2.iceman的self_hurt:前进的第二步结束的时候生命值减少9,攻击力增加20.如果将至0以下则置为1.
3.lion的loyal降低:没经过一场没有杀死敌人的战斗,loyal就降低K。如果lion战死,就在40分时的生命值传给对手
4.wolf_rob函数大改:
5.get_weapon函数不需要了
5.占领:同时出现两个敌人
6.武士移动函数里面:移动后检测双方基地对方指针,如果有一个,则将其置为空,并给占领进度+1

City 类:
新增: string 当前旗帜:“red”,“blue”,“none”。
本次战斗情况:+1代表红方胜利;-1代表蓝方胜利,0代表平局
占领进度,init为0。+2代表红方占领,-2代表蓝方占领
生命源数量

Weapon类要大改

--------------2020.07.04更新源代码--------------------
提交地址:http://cxsjsxmooc2.openjudge.cn/warcraft/

提醒:仅供学习交流,抄袭后果自负

【魔兽1】

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

string warrior_seq[2][5]={{"iceman","lion","wolf","ninja","dragon"},{"lion","dragon","ninja","iceman","wolf"}};//第一行→红方产生武士顺序;第二行→蓝方
int health_seq[5]={0,0,0,0,0};//全局变量,保存该case下各武士的生命值

int return_seq(string type){//返回武士在health_seq中的编号
    if (type=="dragon")
        return 0;
    if (type=="ninja")
        return 1;
    if (type=="iceman")
        return 2;
    if (type=="lion")
        return 3;
    if (type=="wolf")
        return 4;
}

string modify_time(int time){//修正输出的时间格式
    char ctime[10]={0},return_ctime[10]={0};
    sprintf(ctime,"%d",time);
    if (time==0)
        return "000";
    if (strlen(ctime)==1){
        return_ctime[0]='0';
        return_ctime[1]='0';
        strcat(return_ctime,ctime);
    }
    if (strlen(ctime)==2){
        return_ctime[0]='0';
        strcat(return_ctime,ctime);
    }
    if(strlen(ctime)==3)
        return ctime;
    return return_ctime;
}
/*
@此处整数变字符串不能用itoa,因为这不是标准的c函数,要使用sprintf!!!
@Runtime error 经常的原因是字符串操作的时候数组越界了
@字符串的各种函数都不支持string,都要用char*
@见如上方式给字符串全设为0!!!!!
*/

class warrior{
private:
    int tribe;
    string stribe;//0代表红方,1代表蓝方
    int number;//武士编号
    string type;//武士类型
    int health;//该武士的生命值
/*
@注意,在class的成员变量定义中不可以赋值!不然会出错,
@一切的赋值应该在成员函数中进行!!
*/
public:
    void init(int itribe,int inumber,int iplus){//初始化武士的各种信息
        tribe=itribe;
        number=inumber;
        stribe=(tribe==0)?"red":"blue";//0代表红方,1代表蓝方
        type=warrior_seq[tribe][(number+iplus-1)%5];//武士类型
        health=health_seq[return_seq(type)];//该武士的生命值
        }
    void print_born(int time,int*warrior_storge){//输出武士降生
        cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" born with strength "<<health_seq[return_seq(type)]<<","<<warrior_storge[return_seq(type)]<<" "<<type<<" in "<<stribe<<" headquarter"<<endl;;
    }
};

bool born_stop(int min_strength,int* stop_done,int ti,int time,int* pstrength,int* number_rb,int*plus_rb,int* health_seq,int* warrior_storge){
    if (stop_done[ti]==1)//stop_done 看是否已经做过了
        return false;
    if(*pstrength<min_strength){//用stop看是否要进行结束动作
        string stribe_=(ti==0)?"red":"blue";//0代表红方,1代表蓝方
        cout<<modify_time(time)<<" "<<stribe_<<" headquarter stops making warriors"<<endl;
        stop_done[ti]=1;
        return false;
    }
    string type=warrior_seq[ti][(number_rb[ti]+plus_rb[ti]-1)%5];
    int seq=return_seq(type);
    if (*pstrength>=health_seq[seq]){//如果本次可以直接按顺序创造
        warrior_storge[seq]+=1;
        *pstrength-=health_seq[seq];
        warrior W;
        W.init(ti,number_rb[ti],plus_rb[ti]);
        W.print_born(time,warrior_storge);
        number_rb[ti]+=1;
        return true;
    }
    else{
        plus_rb[ti]+=1;
        born_stop(min_strength,stop_done,ti,time,pstrength,number_rb,plus_rb,health_seq,warrior_storge);
    }
}

void onecase(){
	int strength,min_strength=10001;//生命源总量
	cin>>strength;
	for(int i=0;i<5;++i){
        cin>>health_seq[i];//读入了这个case生产每个武士需要耗费多少生命源
        if (health_seq[i]<min_strength)
            min_strength=health_seq[i];
	}
    int time=0,strength_rb[2]={strength,strength};//当前时间,红方生命源,蓝方生命源
    int number_rb[2]={1,1},plus_rb[2]={0,0};
    //number_rb记录红蓝双方目前的编号;plus用于生产不了的时候同时向后加一个
    int warrior_storge_rd[2][5]={{0,0,0,0,0},{0,0,0,0,0}};//库存多少武士
    int stop_done[2]={0,0};
    while (true){
        int ti=0;
        for(ti=0;ti<=1;++ti){//依次执行红蓝部落
            born_stop(min_strength,stop_done,ti,time,&strength_rb[ti],number_rb,plus_rb,health_seq,warrior_storge_rd[ti]);
        }
        ++time;
        if (stop_done[0]&&stop_done[1])
            break;
    }
}

int main(){
    int case_n;
    cin>>case_n;
    for(int i=0;i<case_n;++i){
        cout<<"Case:"<<i+1<<endl;
        onecase();
    }
    return 0;
}

【魔兽2】

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

string warrior_seq[2][5]={{"iceman","lion","wolf","ninja","dragon"},{"lion","dragon","ninja","iceman","wolf"}};//第一行→红方产生武士顺序;第二行→蓝方
int health_seq[5]={0,0,0,0,0};//全局变量,保存该case下各武士的生命值

int return_seq(string type){//返回武士在health_seq中的编号
    if (type=="dragon")
        return 0;
    if (type=="ninja")
        return 1;
    if (type=="iceman")
        return 2;
    if (type=="lion")
        return 3;
    if (type=="wolf")
        return 4;
}

string return_weapon_type(int i){
    if(i==0)
        return "sword";
    if(i==1)
        return "bomb";
    if(i==2)
        return "arrow";
}

string modify_time(int time){//修正输出的时间格式
    char ctime[10]={0},return_ctime[10]={0};
    sprintf(ctime,"%d",time);
    if (time==0)
        return "000";
    if (strlen(ctime)==1){
        return_ctime[0]='0';
        return_ctime[1]='0';
        strcat(return_ctime,ctime);
    }
    if (strlen(ctime)==2){
        return_ctime[0]='0';
        strcat(return_ctime,ctime);
    }
    if(strlen(ctime)==3)
        return ctime;
    return return_ctime;
}

class warrior{
protected:
    int tribe;
    string stribe;//0代表红方,1代表蓝方
    int number;//武士编号
    string type;//武士类型
    int health;//该武士的生命值
public:
    void init_basicinfo(int itribe,int inumber,int iplus){//初始化武士的基本信息
        tribe=itribe;
        number=inumber;
        stribe=(tribe==0)?"red":"blue";//0代表红方,1代表蓝方
        type=warrior_seq[tribe][(number+iplus-1)%5];//武士类型
        health=health_seq[return_seq(type)];//该武士的生命值
        }
    virtual void init_otherinfo(int strength,int strength_need){}//虚函数接口,表示能做什么
    //注意,strength是其降生后剩余的生命源数量↑
    void print_born(int time,int*warrior_storge){//输出武士降生
        cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" born with strength "<<health_seq[return_seq(type)]<<","<<warrior_storge[return_seq(type)]<<" "<<type<<" in "<<stribe<<" headquarter"<<endl;;
    }
    virtual void print_specialinfo(){}
    virtual ~warrior(){}// 析构函数里面不需要写delete,在对象自动销毁的时候会自动调用析构函数,然后delete
};

class dragon:public warrior{
private :
    int weapon;
    string sweapon_type;
    double morale;
public :
    virtual void init_otherinfo(int strength,int strength_need){
        weapon=number%3;
        morale=double(strength)/double(strength_need);
        sweapon_type=return_weapon_type(weapon);
    }
    virtual void print_specialinfo(){
    cout<<"It has a "<<sweapon_type<<",and it's morale is ";
    printf("%.2lf\n",morale);
    }
};

class ninja:public warrior{
private:
    int weapon_l,weapon_r;//左右手武器
    string sweapon_type_l,sweapon_type_r;
public:
    virtual void init_otherinfo(int strength,int strength_need){
        weapon_l=number%3;
        weapon_r=(number+1)%3;
        sweapon_type_l=return_weapon_type(weapon_l);
        sweapon_type_r=return_weapon_type(weapon_r);
    }
    virtual void print_specialinfo(){
    cout<<"It has a "<<sweapon_type_l<<" and a "<<sweapon_type_r<<endl;
    }
};

class iceman:public warrior{
private:
    int weapon;
    string sweapon_type;
public:
    virtual void init_otherinfo(int strength,int strength_need){
        weapon=number%3;
        sweapon_type=return_weapon_type(weapon);
    }
    virtual void print_specialinfo(){
    cout<<"It has a "<<sweapon_type<<endl;
    }

};

class lion:public warrior{
private:
    int loyal;
public:
    virtual void init_otherinfo(int strength,int strength_need){
        loyal=strength;
    }
    virtual void print_specialinfo(){
    cout<<"It's loyalty is "<<loyal<<endl;
    }
};

class wolf:public warrior{
public:
    virtual void init_otherinfo(int strength,int strength_need){}
    virtual void print_specialinfo(){}
};

warrior* type_point(int seq){//可以根据seq这个序数返回对映派生武士类的指针,赋值给一个基类的指针
    if(seq==0){
        dragon* pd=new dragon;
        return pd;
    }
    if(seq==1){
        ninja* pn=new ninja;
        return pn;
    }
    if(seq==2){
        iceman* pi=new iceman;
        return pi;
    }
    if(seq==3){
        lion* pl=new lion;
        return pl;
    }
    if(seq==4){}
        wolf* pw=new wolf;
        return pw;

}
/*
注意此处要用指针new一块地址出来,否则每一次调用该函数给的地址可能会重复,发生0xC0000005错误!!!
*/

bool born_or_stop(int min_strength,int* stop_done,int ti,int time,int* strength,int* number_rb,int*plus_rb,int* health_seq,int* warrior_storge){
    //执行出生或停止操作
    //如果为false则停止,为true则继续
    if (stop_done[ti]==1)//stop_done 看是否已经停止过了,防止重复打印停止语句
        return false;
    if(strength[ti]<min_strength){//用stop看是否要进行结束动作
        string stribe_=(ti==0)?"red":"blue";//0代表红方,1代表蓝方
        cout<<modify_time(time)<<" "<<stribe_<<" headquarter stops making warriors"<<endl;
        stop_done[ti]=1;
        return false;
    }
    string type=warrior_seq[ti][(number_rb[ti]+plus_rb[ti]-1)%5];//找出当前在创建的武士类型
    int seq=return_seq(type);///从这个地方可以插入返回指针的函数
    if (strength[ti]>=health_seq[seq]){//如果本次可以直接按顺序创造
        warrior_storge[seq]+=1;
        strength[ti]-=health_seq[seq];
        warrior* pW;
        pW=type_point(seq);
        pW->init_basicinfo(ti,number_rb[ti],plus_rb[ti]);
        pW->init_otherinfo(strength[ti],health_seq[seq]);
        pW->print_born(time,warrior_storge);
        pW->print_specialinfo();
        number_rb[ti]+=1;
        return true;
    }
    else{
        plus_rb[ti]+=1;
        born_or_stop(min_strength,stop_done,ti,time,strength,number_rb,plus_rb,health_seq,warrior_storge);
    }
}

void onecase(){
	int strength,min_strength=10001;//生命源总量,min_strength作用是判断是否停止生产
	cin>>strength;
	for(int i=0;i<5;++i){
        cin>>health_seq[i];//读入了这个case生产每个武士需要耗费多少生命源
        if (health_seq[i]<min_strength)
            min_strength=health_seq[i];
	}
    int time=0,strength_rb[2]={strength,strength};//当前时间,红方生命源,蓝方生命源
    int number_rb[2]={1,1},plus_rb[2]={0,0};
    //number_rb记录红蓝双方目前的编号;plus用于生产不了的时候同时向后加一个
    int warrior_storge_rd[2][5]={{0,0,0,0,0},{0,0,0,0,0}};//库存多少武士
    int stop_done[2]={0,0};
    while (true){
        int ti=0;
        for(ti=0;ti<=1;++ti){//依次执行红蓝部落
            born_or_stop(min_strength,stop_done,ti,time,strength_rb,number_rb,plus_rb,health_seq,warrior_storge_rd[ti]);
        }
        ++time;
        if (stop_done[0]&&stop_done[1])
            break;
    }
}

int main(){
    int case_n;
    cin>>case_n;
    cout.precision(3);
    for(int i=0;i<case_n;++i){
        cout<<"Case:"<<i+1<<endl;
        onecase();
    }
    return 0;
}

【魔兽3】

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;

string warrior_seq[2][5]={{"iceman","lion","wolf","ninja","dragon"},{"lion","dragon","ninja","iceman","wolf"}};//第一行→红方产生武士顺序;第二行→蓝方
int health_seq[5]={0,0,0,0,0};//全局变量,保存该case下各武士的生命值
int attack_seq[5]={0,0,0,0,0};//全局变量,保存该case下各武士的攻击力
int loyal_decrease=0,city_num=0;


int return_seq(string type){//返回武士在health_seq,attack_seq中的编号
    if (type=="dragon")
        return 0;
    if (type=="ninja")
        return 1;
    if (type=="iceman")
        return 2;
    if (type=="lion")
        return 3;
    if (type=="wolf")
        return 4;
}

string return_weapon_type(int i){
    if(i==0)
        return "sword";
    if(i==1)
        return "bomb";
    if(i==2)
        return "arrow";
}

string modify_time(int time){//已修正输出的时间格式,oj上只有atoi,没有itoa(用sprintf替代)
    int hour=time/60,minutes=time%60;
    char chour[7]="000:",cminutes[3]="00";
    if(hour>0&&hour<10)
        sprintf(chour+2,"%d",hour);
    else if(10<=hour&&hour<100)
        sprintf(chour+1,"%d",hour);
    else if(100<=hour)
        sprintf(chour,"%d",hour);
    chour[3]=':';//使用sprintf的时候末尾会自动粘贴一个\0过去,覆盖了原本的冒号
    if(minutes>0&&minutes<10)
        sprintf(cminutes+1,"%d",minutes);
    else if(10<=minutes)
        sprintf(cminutes,"%d",minutes);
    strcat(chour,cminutes);
    return chour;
}


class weapon{
public:
    int attack;
    int attack_self;
    int wnumber;
    int life;
    string type;
    virtual void init(int seq_self){}
    virtual ~weapon(){}
};

class sword:public weapon{
public:
    virtual void init(int seq_self){
        type="sword";
        wnumber=0;
        attack=2*attack_seq[seq_self]/10;
        life=100000;
        attack_self=0;
    }
};

class bomb:public weapon{
public:
    virtual void init(int seq_self){
        type="bomb";
        wnumber=1;
        attack=4*attack_seq[seq_self]/10;
        attack_self=attack/2;
        life=1;
        if (seq_self==1) //ninja使用炸弹不会受伤
            attack_self=0;
    }
};

class arrow:public weapon{
public:
    virtual void init(int seq_self){
        type="arrow";
        wnumber=2;
        attack=3*attack_seq[seq_self]/10;
        life=2;
        attack_self=0;
    }
};


template<class T>//记录对方丢失一个武器;使用时此处要写weapon*
void erase_move(T* arr,int pi,int& s){//抹除位置pi的元素,数组的类型为T,抹除前有s个元素
    if(pi==s-1){
        arr[pi]=NULL;
        s--;
    }
    else{
        for(int i=pi;i<s-1;++i){
            arr[i]=arr[i+1];
        }
        arr[s-1]=NULL;
        s--;
    }
}


weapon* weapon_point(int wnumber){//可以根据seq这个序数返回对映派生武士类的指针,赋值给一个基类的指针
    if(wnumber==0){
        sword* sp=new sword;
        return sp;
    }
    if(wnumber==1){
        bomb* bp=new bomb;
        return bp;
    }
    if(wnumber==2){
        arrow* ap=new arrow;
        return ap;
    }

}

int desend_compare(const void* s1,const void* s2){//按照序号升序,序号相同按照寿命降序(没用过的排在前面,wolf——rob用)
    weapon **s_1;
    weapon **s_2;
    s_1=(weapon**)(s1);
    s_2=(weapon**)(s2);
    if ((*s_1)->wnumber<(*s_2)->wnumber)
        return -1;
    else if((*s_1)->wnumber>(*s_2)->wnumber)
        return 1;
    else{
        if ((*s_1)->life>(*s_2)->life)
            return -1;
        else if((*s_1)->life<(*s_2)->life)
            return 1;
        else
            return 0;
    }
}

int asend_compare(const void* s1,const void* s2){//按照序号升序,序号相同按照寿命升序(用过的排在前面,战前排武器)
    weapon **s_1;
    weapon **s_2;
    s_1=(weapon**)(s1);
    s_2=(weapon**)(s2);
    if ((*s_1)->wnumber<(*s_2)->wnumber)
        return -1;
    else if((*s_1)->wnumber>(*s_2)->wnumber)
        return 1;
    else{
        if ((*s_1)->life>(*s_2)->life)
            return 1;
        else if((*s_1)->life<(*s_2)->life)
            return -1;
        else
            return 0;
    }
}


class warrior{//做一个武器库这样的weapon 数组
public:
    int tribe;
    string stribe;//0代表红方,1代表蓝方
    int number;//武士编号
    string type;//武士类型
    int attack;
    int health;//该武士的生命值
    weapon *p_pweapon_storge[10];//每个士兵最多十个武器,数组里存了每个武器的指针
    int weapon_numbers,now_city,weapon_num_type[3];//weapon_numbers武士现在共有多少武器;now_city武士现在在第几号城市;
    //weapon_num_type每一个type的武器各有多少(出生+;wolf夺+;战斗损失减;战胜拿对面+)
    void init_basicinfo(int itribe,int inumber,int iplus){//初始化武士的基本信息
        tribe=itribe;
        number=inumber;
        stribe=(tribe==0)?"red":"blue";//0代表红方,1代表蓝方
        type=warrior_seq[tribe][(number+iplus-1)%5];//武士类型
        health=health_seq[return_seq(type)];//该武士的生命值
        attack=attack_seq[return_seq(type)];
        weapon_numbers=0;//初始武器数=0
        memset(p_pweapon_storge,NULL,sizeof(weapon*)*10);//new出一块存放武器指针的内存空间
        memset(weapon_num_type,0,sizeof(int)*3);
        if(tribe==0)
            now_city=0;
        else
            now_city=city_num+1;
        }
    virtual void init_otherinfo(int strength,int strength_need){}//虚函数接口,表示能做什么
    //注意,strength是其降生后剩余的生命源数量↑
    void print_born(int time){//输出武士降生
        cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" born"<<endl;
    }
    virtual void print_specialinfo(){}
    virtual void yell(int time){}
    virtual void self_hurt(){}
    virtual bool run_away_test(int time){return false;}
    virtual void loyal_decrease_(){}
    void weapon_get(warrior* penemy){//获胜后拿对方的武器
        if(penemy->weapon_numbers>0){
            qsort(penemy->p_pweapon_storge,penemy->weapon_numbers,sizeof(weapon*),desend_compare);
            while(weapon_numbers<10){
                if(penemy->p_pweapon_storge[0]==NULL)
                    break;
                weapon* ptemp=penemy->p_pweapon_storge[0];
                int life_remain=ptemp->life;
                erase_move<weapon*>(penemy->p_pweapon_storge,0,penemy->weapon_numbers);//这个函数使得对方的weapon_numbers自动减少
                ptemp->init(return_seq(type));//改写武器攻击力等
                ptemp->life=life_remain;
                p_pweapon_storge[weapon_numbers]=ptemp;
                weapon_numbers++;
                weapon_num_type[ptemp->wnumber]+=1;
                penemy->weapon_num_type[ptemp->wnumber]-=1;
                }
        }
    }
    virtual void wolf_rob(warrior* penemy,int time){}
    void arrive_city(int time){//前进一步之后要先给iceman减血再arrive——city!!!!!!
        cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" marched to city "<<now_city<<" with "<<health<<" elements and force "<<attack<<endl;
    }
    void arrive_enemybase(int time){
        string enemy_stribe=(tribe==0)?"blue":"red";
        cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" reached "<<enemy_stribe<<" headquarter"<<" with "<<health<<" elements and force "<<attack<<endl;
    }
    bool death_test(){//true为战死
        if(health<=0)
            return true;
        else
            return false;
    }
    bool no_attack(){//true为该武士目前无法造成伤害了
        if(attack<=2)//攻击力<=2有什么都不行
            return true;
        if(attack<=3&&weapon_num_type[1]==0)//攻击力<=3,没有1号bomb不行
            return true;
        if(attack<=4&&weapon_num_type[1]==0&&weapon_num_type[2]==0)//攻击力<=4,既没有bomb也没有arrow不行
            return true;
        if(weapon_num_type[0]==0&&weapon_num_type[1]==0&&weapon_num_type[2]==0)
            return true;
        else
            return false;
    }
    void attack_enemy(warrior* penemy,int weapon_nowuse){//伤敌,自伤,武器磨损(但是还未清除)
        (penemy->health)-=(p_pweapon_storge[weapon_nowuse]->attack);
        health-=(p_pweapon_storge[weapon_nowuse]->attack_self);
        (p_pweapon_storge[weapon_nowuse]->life)-=1;
    }
    virtual ~warrior(){}// 析构函数里面不需要写delete,在对象自动销毁的时候会自动调用析构函数,然后delete
};

class dragon:public warrior{//已经改好吼叫
private :
    weapon* pW;//初始武器
    string sweapon_type;
    double morale;
public :
    virtual void init_otherinfo(int strength,int strength_need){
        pW=weapon_point(number%3);
        pW->init(0);
        morale=double(strength)/double(strength_need);
        sweapon_type=return_weapon_type(pW->wnumber);
        p_pweapon_storge[0]=pW;
        weapon_numbers=1;
        weapon_num_type[number%3]=1;
    }
    /*virtual void print_specialinfo(){
        cout<<"It has a "<<sweapon_type<<",and it's morale is ";
        printf("%.2lf\n",morale);
    }*/
    virtual void yell(int time){
        cout<<modify_time(time)<<" "<<stribe<<" dragon "<<number<<" yelled in city "<<now_city<<endl;
    }
};

class ninja:public warrior{//已经改好bomb无伤
private:
    weapon* pW_1,*pW_2;//初始化两件武器
    string sweapon_type_1,sweapon_type_2;
public:
    virtual void init_otherinfo(int strength,int strength_need){
        pW_1=weapon_point(number%3);
        pW_2=weapon_point((number+1)%3);
        pW_1->init(1);pW_2->init(1);//将两把初始武器按照ninja信息初始化
        sweapon_type_1=return_weapon_type(pW_1->wnumber);
        sweapon_type_2=return_weapon_type(pW_2->wnumber);
        p_pweapon_storge[0]=pW_1;
        p_pweapon_storge[1]=pW_2;
        weapon_numbers=2;
        weapon_num_type[number%3]=1;
        weapon_num_type[(number+1)%3]=1;
    }
    /*virtual void print_specialinfo(){
    cout<<"It has a "<<sweapon_type_1<<" and a "<<sweapon_type_2<<endl;
    }*/
};

class iceman:public warrior{//已经改好自伤
private:
    weapon* pW;
    string sweapon_type;
public:
    virtual void init_otherinfo(int strength,int strength_need){
        pW=weapon_point(number%3);
        pW->init(2);
        sweapon_type=return_weapon_type(pW->wnumber);
        p_pweapon_storge[0]=pW;
        weapon_numbers=1;
        weapon_num_type[number%3]=1;
    }
    /*virtual void print_specialinfo(){
    cout<<"It has a "<<sweapon_type<<endl;
    }*/
    virtual void self_hurt(){
        health-=int(health/10);
    }
};

class lion:public warrior{//已经增加逃跑设定和忠诚度降低设定
private:
    weapon* pW;
    string sweapon_type;
    int loyal;
public:
    virtual void init_otherinfo(int strength,int strength_need){
        pW=weapon_point(number%3);
        pW->init(3);
        sweapon_type=return_weapon_type(pW->wnumber);
        loyal=strength;
        p_pweapon_storge[0]=pW;
        weapon_numbers=1;
        weapon_num_type[number%3]=1;
    }
    virtual void print_specialinfo(){
    cout<<"Its loyalty is "<<loyal<<endl;
    }
    virtual void loyal_decrease_(){
        loyal-=loyal_decrease;
    }
    virtual bool run_away_test(int time){//1代表太跑了,0代表没逃跑
        if(loyal<=0){
            cout<<modify_time(time)<<" "<<stribe<<" lion "<<number<<" ran away"<<endl;
            return true;
        }
        else
            return false;
    }

};

class wolf:public warrior{//已经增加抢武器设定
public:
    virtual void wolf_rob(warrior* penemy,int time){
        if(penemy->weapon_numbers>0&&penemy->type!="wolf"){//对方有武器且对方不是狼
            qsort(penemy->p_pweapon_storge,penemy->weapon_numbers,sizeof(weapon*),desend_compare);
            int enemy_min_weapon=penemy->p_pweapon_storge[0]->wnumber,rob_num=0;
            while(weapon_numbers<10){
                if(penemy->p_pweapon_storge[0]==NULL)//对方没有武器了就不抢了
                    break;
                if(penemy->p_pweapon_storge[0]->wnumber!=enemy_min_weapon)//同一个编号抢完了就不抢了
                    break;
                weapon* ptemp=penemy->p_pweapon_storge[0];
                int life_remain=ptemp->life;
                erase_move<weapon*>(penemy->p_pweapon_storge,0,penemy->weapon_numbers);//这个函数会自动把对方的武器总数减少,不需要自己加
                ptemp->init(4);//改写武器攻击力等
                ptemp->life=life_remain;
                p_pweapon_storge[weapon_numbers]=ptemp;
                weapon_numbers++;
                rob_num++;
                }
            weapon_num_type[enemy_min_weapon]+=rob_num;
            penemy->weapon_num_type[enemy_min_weapon]-=rob_num;
            cout<<modify_time(time)<<" "<<stribe<<" wolf "<<number<<" took "<<rob_num<<" "<<return_weapon_type(enemy_min_weapon)<<" from "<<penemy->stribe<<" "<<penemy->type<<" "<<penemy->number<<" in city "<<now_city<<endl;
        }
    }
};



warrior* type_point(int seq){//可以根据seq这个序数返回对映派生武士类的指针,赋值给一个基类的指针
    if(seq==0){
        dragon* pd=new dragon;
        return pd;
    }
    if(seq==1){
        ninja* pn=new ninja;
        return pn;
    }
    if(seq==2){
        iceman* pi=new iceman;
        return pi;
    }
    if(seq==3){
        lion* pl=new lion;
        return pl;
    }
    if(seq==4){
        wolf* pw=new wolf;
        return pw;
    }
/*
注意此处要用指针new一块地址出来,否则每一次调用该函数给的地址可能会重复,发生0xC0000005错误!!!
*/
}


class city{///fight 函数写在这里面,还没写
private:
    int NO;
public:
    warrior *pwarrior_red,*pwarrior_blue;
    city(){
        pwarrior_red=NULL;
        pwarrior_blue=NULL;
    }
    void init(int i){
        NO=i;
    }
    void fight(int time){//使用时应先保证两个指针均不为空
        warrior *w_1=NULL,*w_2=NULL;//记录先手、后手。!!!!!!败方要从cities中删去!!!!!!!
        //双方整理武器
        qsort(pwarrior_red->p_pweapon_storge,pwarrior_red->weapon_numbers,sizeof(weapon*),asend_compare);
        qsort(pwarrior_blue->p_pweapon_storge,pwarrior_blue->weapon_numbers,sizeof(weapon*),asend_compare);
        //双方决定先后手
        if(NO%2==1){//奇数城市红方先动手
            w_1=pwarrior_red;
            w_2=pwarrior_blue;
        }
        else if(NO%2==0){//偶数城市蓝方先动手
            w_1=pwarrior_blue;
            w_2=pwarrior_red;
        }
        int weapon1_use=0,weapon2_use=0;//记录双方当前所用武器
        //开始战斗
        while(true){
            if(w_1->no_attack()==true&&w_2->no_attack()==true&&w_1->weapon_num_type[1]==0&&w_1->weapon_num_type[2]==0&&w_2->weapon_num_type[1]==0&&w_2->weapon_num_type[2]==0){//以均活下来的平局结束
                //注意,武器没有变化的要求是把生命值有限的武器都用完了
                cout<<modify_time(time)<<" both red "<<pwarrior_red->type<<" "<<pwarrior_red->number<<" and blue "<<pwarrior_blue->type<<" "<<pwarrior_blue->number<<" were alive in city "<<NO<<endl;
                pwarrior_red->yell(time);
                pwarrior_blue->yell(time);
                break;
            }
/*            //确定先后手本轮使用的武器
            if(w_1->weapon_numbers>0){//确定w_1本轮武器
                if(weapon1_use<w_1->weapon_numbers-1)
                    weapon1_use++;
                else
                    weapon1_use=0;
            }
            if(w_2->weapon_numbers>0){//确定w_2本轮武器
                if(weapon2_use<w_2->weapon_numbers-1)
                    weapon2_use++;
                else
                    weapon2_use=0;
            }*/
            //先手攻击后手,并删除没有耐久的武器
            if(w_1->weapon_numbers>0){
                w_1->attack_enemy(w_2,weapon1_use);//攻击并减少了武器的生命值
                if(w_1->p_pweapon_storge[weapon1_use]->life<=0){//如果现在用的这把没有生命值了
                    int weapon_damage_typenumber=w_1->p_pweapon_storge[weapon1_use]->wnumber;//现在用坏的这把武器的类型是什么
                    w_1->weapon_num_type[weapon_damage_typenumber]--;//该武器类型数目减少
                    erase_move<weapon*>(w_1->p_pweapon_storge,weapon1_use,w_1->weapon_numbers);//擦除此损坏武器,并将总数-1
                    weapon1_use--;//调整现在用的武器的状态
                }
                }
            //判断死亡情况,死掉的要擦除,赢得龙吼叫
            if (w_1->death_test()==true && w_2->death_test()==true){//两者都死了
                cout<<modify_time(time)<<" both red "<<pwarrior_red->type<<" "<<pwarrior_red->number<<" and blue "<<pwarrior_blue->type<<" "<<pwarrior_blue->number<<" died in city "<<NO<<endl;
                pwarrior_blue=NULL;
                pwarrior_red=NULL;
                break;
            }
            else if(w_1->death_test()==false && w_2->death_test()==true){//先手的没死,后手的死了
                cout<<modify_time(time)<<" "<<w_1->stribe<<" "<<w_1->type<<" "<<w_1->number<<" killed "<<w_2->stribe<<" "<<w_2->type<<" "<<w_2->number<<" in city "<<NO<<" remaining "<<w_1->health<<" elements"<<endl;
                w_1->weapon_get(w_2);
                if(w_2==pwarrior_blue)
                    pwarrior_blue=NULL;
                else if(w_2==pwarrior_red)
                    pwarrior_red=NULL;
                w_1->yell(time);
                break;
            }
            else if(w_1->death_test()==true && w_2->death_test()==false){//先手的死了,后手的没死
                cout<<modify_time(time)<<" "<<w_2->stribe<<" "<<w_2->type<<" "<<w_2->number<<" killed "<<w_1->stribe<<" "<<w_1->type<<" "<<w_1->number<<" in city "<<NO<<" remaining "<<w_2->health<<" elements"<<endl;
                w_2->weapon_get(w_1);
                if(w_1==pwarrior_blue)
                    pwarrior_blue=NULL;
                else if(w_1==pwarrior_red)
                    pwarrior_red=NULL;
                w_2->yell(time);
                break;
            }
            //后手攻击先手,并删除没有耐久的武器
            if(w_2->weapon_numbers>0){
                w_2->attack_enemy(w_1,weapon2_use);//攻击并减少了武器的生命值
                if(w_2->p_pweapon_storge[weapon2_use]->life<=0){//如果现在用的这把没有生命值了
                    int weapon_damage_typenumber=w_2->p_pweapon_storge[weapon2_use]->wnumber;//现在用坏的这把武器的类型是什么
                    w_2->weapon_num_type[weapon_damage_typenumber]--;//该武器类型数目减少
                    erase_move<weapon*>(w_2->p_pweapon_storge,weapon2_use,w_2->weapon_numbers);//擦除此损坏武器,并将总数-1
                    weapon2_use--;//调整现在用的武器的状态
                }
                }
            //再次判断死亡情况
            if (w_1->death_test()==true && w_2->death_test()==true){//两者都死了
                cout<<modify_time(time)<<" both red "<<pwarrior_red->type<<" "<<pwarrior_red->number<<" and blue "<<pwarrior_blue->type<<" "<<pwarrior_blue->number<<" died in city "<<NO<<endl;
                pwarrior_blue=NULL;
                pwarrior_red=NULL;
                break;
            }
            else if(w_1->death_test()==false && w_2->death_test()==true){//先手的没死,后手的死了
                cout<<modify_time(time)<<" "<<w_1->stribe<<" "<<w_1->type<<" "<<w_1->number<<" killed "<<w_2->stribe<<" "<<w_2->type<<" "<<w_2->number<<" in city "<<NO<<" remaining "<<w_1->health<<" elements"<<endl;
                w_1->weapon_get(w_2);
                if(w_2==pwarrior_blue)
                    pwarrior_blue=NULL;
                else if(w_2==pwarrior_red)
                    pwarrior_red=NULL;
                w_1->yell(time);
                break;
            }
            else if(w_1->death_test()==true && w_2->death_test()==false){//先手的死了,后手的没死
                cout<<modify_time(time)<<" "<<w_2->stribe<<" "<<w_2->type<<" "<<w_2->number<<" killed "<<w_1->stribe<<" "<<w_1->type<<" "<<w_1->number<<" in city "<<NO<<" remaining "<<w_2->health<<" elements"<<endl;
                w_2->weapon_get(w_1);
                if(w_1==pwarrior_blue)
                    pwarrior_blue=NULL;
                else if(w_1==pwarrior_red)
                    pwarrior_red=NULL;
                w_2->yell(time);
                break;
            }
        //开始新的一轮
            //确定先后手下一轮轮使用的武器
            if(w_1->weapon_numbers>0){//确定w_1本轮武器
                if(weapon1_use<w_1->weapon_numbers-1)
                    weapon1_use++;
                else
                    weapon1_use=0;
            }
            if(w_2->weapon_numbers>0){//确定w_2本轮武器
                if(weapon2_use<w_2->weapon_numbers-1)
                    weapon2_use++;
                else
                    weapon2_use=0;
            }
            }
        }
};



bool born_or_stop(city* cities,const int& min_strength,int* stop_done,const int& ti,const int& time,int* strength,int* number_rb,int*plus_rb,int* health_seq,int& warrior_storge,warrior** pwarrior){
    //执行出生或停止操作
    //如果为false则停止,为true则继续
    if (stop_done[ti]==1)//stop_done 看是否已经停止过了,防止重复打印停止语句
        return false;
    if(strength[ti]<min_strength){//用stop看是否要进行结束动作
        //string stribe_=(ti==0)?"red":"blue";//0代表红方,1代表蓝方
        //cout<<modify_time(time)<<" "<<stribe_<<" headquarter stops making warriors"<<endl;
        stop_done[ti]=1;
        return false;
    }
    string type=warrior_seq[ti][(number_rb[ti]+plus_rb[ti]-1)%5];//找出当前想要创建的武士类型
    int seq=return_seq(type);
    if (strength[ti]>=health_seq[seq]){//如果本次可以直接按顺序创造
        warrior_storge+=1;
        strength[ti]-=health_seq[seq];
        warrior* pW;
        pW=type_point(seq);
        pW->init_basicinfo(ti,number_rb[ti],plus_rb[ti]);
        pW->init_otherinfo(strength[ti],health_seq[seq]);
        pW->print_born(time);
        pW->print_specialinfo();
        pwarrior[warrior_storge-1]=pW;///这行可以考虑删了
        number_rb[ti]+=1;
        if(ti==0)//如果红方出生,记在红司令部
            cities[0].pwarrior_red=pW;
        if(ti==1)//如果蓝方出生,记在蓝司令部
            cities[city_num+1].pwarrior_blue=pW;
        return true;
    }
    else{//在魔兽1/2中需要进行递归,此处由于规则有变化,进行了修改
        stop_done[ti]=1;
        return false;
    }
}


bool onehour(city* cities,int& hours,bool& red_win,bool& blue_win,int& strength,int& min_strength,int& T,int* strength_rb,int* number_rb,int* plus_rb,int* warrior_storge_rb,warrior** pwarrior_r,warrior** pwarrior_b,int* stop_done){
//只要能进这个循环,就说明还没有人获胜

    //1) 武士降生,完成
    int time=60*hours+0;
    born_or_stop(cities,min_strength,stop_done,0,time,strength_rb,number_rb,plus_rb,health_seq,warrior_storge_rb[0],pwarrior_r);//红方降生
    born_or_stop(cities,min_strength,stop_done,1,time,strength_rb,number_rb,plus_rb,health_seq,warrior_storge_rb[1],pwarrior_b);//蓝方降生

    //2) lion逃跑,完成
    time=60*hours+5;
    if(time>T)
        return false;
    for(int i=0;i<=city_num+1;++i){
        if(cities[i].pwarrior_red!=NULL){
            bool test;
            test=cities[i].pwarrior_red->run_away_test(time);
            if(test==true){
                warrior_storge_rb[0]-=1;
                cities[i].pwarrior_red=NULL;
            }
        }
        if(cities[i].pwarrior_blue!=NULL){
            bool test;
            test=cities[i].pwarrior_blue->run_away_test(time);
            if(test==true){
                warrior_storge_rb[1]-=1;
                cities[i].pwarrior_blue=NULL;
            }
        }
    }

    //3) 武士前进到某一城市 && 7) 武士抵达敌军司令部 && 8) 司令部被占领
    time=60*hours+10;
    if(time>T)
        return false;
    for(int i=0;i<=city_num;++i){//双方移动并进行自伤、忠诚降低
        if (cities[i+1].pwarrior_blue!=NULL){
            cities[i].pwarrior_blue=cities[i+1].pwarrior_blue;//蓝方前进
            cities[i].pwarrior_blue->now_city=i;
            cities[i].pwarrior_blue->self_hurt();//iceman自伤
            cities[i].pwarrior_blue->loyal_decrease_();//lion忠诚减少
        }
        else
            cities[i].pwarrior_blue=NULL;
        int j=city_num+1-i;//以下红方前进
        if (cities[j-1].pwarrior_red!=NULL){
            cities[j].pwarrior_red=cities[j-1].pwarrior_red;
            cities[j].pwarrior_red->now_city=j;
            cities[j].pwarrior_red->self_hurt();
            cities[j].pwarrior_red->loyal_decrease_();
        }
        else
            cities[j].pwarrior_red=NULL;
    }
    cities[0].pwarrior_red=NULL;
    cities[city_num+1].pwarrior_blue=NULL;//移动全部完成
    if(cities[0].pwarrior_blue!=NULL){///红方基地被蓝方占领
        blue_win=true;
        cities[0].pwarrior_blue->arrive_enemybase(time);
        cout<<modify_time(time)<<" red headquarter was taken"<<endl;
    }
    for(int ii=1;ii<=city_num;++ii){
        if(cities[ii].pwarrior_red!=NULL)
            cities[ii].pwarrior_red->arrive_city(time);
        if(cities[ii].pwarrior_blue!=NULL)
            cities[ii].pwarrior_blue->arrive_city(time);
    }
    if(cities[city_num+1].pwarrior_red!=NULL){///蓝方基地被红方占领
        red_win=true;
        cities[city_num+1].pwarrior_red->arrive_enemybase(time);
        cout<<modify_time(time)<<" blue headquarter was taken"<<endl;
    }
    if(red_win==true||blue_win==true)//如果有人占领了对方司令部就全部结束
        return true;

    //4) wolf抢敌人的武器
    time=60*hours+35;
    if(time>T)
        return false;
    for(int i=1;i<=city_num;++i){
        if(cities[i].pwarrior_red!=NULL&&cities[i].pwarrior_blue!=NULL){
            cities[i].pwarrior_red->wolf_rob(cities[i].pwarrior_blue,time);
            cities[i].pwarrior_blue->wolf_rob(cities[i].pwarrior_red,time);
        }
    }



    //4.5) 战斗+捡武器 && 5) 报告战斗情况 && 6) 武士欢呼
    time=60*hours+40;
    if(time>T)
        return false;
    for(int i=1;i<=city_num;++i){
        if(cities[i].pwarrior_red!=NULL&&cities[i].pwarrior_blue!=NULL)
            cities[i].fight(time);
    }

    //9)司令部报告生命元数量
    time=60*hours+50;
    if(time>T)
        return false;
    cout<<modify_time(time)<<" "<<strength_rb[0]<<" elements in red headquarter"<<endl;
    cout<<modify_time(time)<<" "<<strength_rb[1]<<" elements in blue headquarter"<<endl;
    //10)武士报告情况
    time=60*hours+55;
    if(time>T)
        return false;
    for(int i=0;i<=city_num+1;++i){
        if(cities[i].pwarrior_red!=NULL){
            warrior* pw;
            pw=cities[i].pwarrior_red;
            cout<<modify_time(time)<<" red "<<pw->type<<" "<<pw->number<<" has "<<pw->weapon_num_type[0]<<" sword "<<pw->weapon_num_type[1]<<" bomb "<<pw->weapon_num_type[2]<<" arrow and "<<pw->health<<" elements"<<endl;
        }
        if(cities[i].pwarrior_blue!=NULL){
            warrior* pw;
            pw=cities[i].pwarrior_blue;
            cout<<modify_time(time)<<" blue "<<pw->type<<" "<<pw->number<<" has "<<pw->weapon_num_type[0]<<" sword "<<pw->weapon_num_type[1]<<" bomb "<<pw->weapon_num_type[2]<<" arrow and "<<pw->health<<" elements"<<endl;
        }
}
}



int main(){//真正的main函数
    //freopen("datapub.in","r",stdin);
    //freopen("myout.out","w",stdout);
    int case_n;
    cin>>case_n;
    for(int i_i=0;i_i<case_n;++i_i){
        cout<<"Case "<<i_i+1<<":"<<endl;
        int hours=0;
        bool red_win=false,blue_win=false;
        int strength,min_strength=10001,T;//生命源总量,min_strength作用是判断是否停止生产
        cin>>strength>>city_num>>loyal_decrease>>T;
        for(int j=0;j<5;++j){//读入了这个case生产每个武士需要耗费多少生命源
            cin>>health_seq[j];
            if (health_seq[j]<min_strength)
                min_strength=health_seq[j];
        }
        for(int j=0;j<5;++j){//读入了这个case每个武士的攻击力
            cin>>attack_seq[j];
        }
        int strength_rb[2]={strength,strength};//当前时间,红方生命源,蓝方生命源
        int number_rb[2]={1,1},plus_rb[2]={0,0};
        //number_rb记录红蓝双方目前的编号;plus用于生产不了的时候同时向后加一个
        int warrior_storge_rb[2]={0,0};//库存多少武士
        warrior *pwarrior_r[int(T/60)+5],*pwarrior_b[int(T/60)+5];///按照顺序产生的各个士兵们,考虑后续把这个删掉也可以
        memset(pwarrior_r,NULL,(int(T/60)+5)*sizeof(warrior*));
        memset(pwarrior_b,NULL,(int(T/60)+5)*sizeof(warrior*));
        int stop_done[2]={0,0};
        city cities[city_num+2];
        for(int j=0;j<=city_num+1;++j)
            cities[j].init(j);
        for(hours=0;hours<=int(T/60);++hours){
            onehour(cities,hours,red_win,blue_win,strength,min_strength,T,strength_rb,number_rb,plus_rb,warrior_storge_rb,pwarrior_r,pwarrior_b,stop_done);
            if(red_win==true||blue_win==true)
                break;
            }
    }
    return 0;
}

【魔兽终极版】

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;

char stemp[100];

string warrior_seq[2][5]={{"iceman","lion","wolf","ninja","dragon"},{"lion","dragon","ninja","iceman","wolf"}};//第一行→红方产生武士顺序;第二行→蓝方
int health_seq[5]={0,0,0,0,0};//全局变量,保存该case下各武士的生命值
int attack_seq[5]={0,0,0,0,0};//全局变量,保存该case下各武士的攻击力
int loyal_decrease=0,city_num=0,arrow_attack=0;//全局变量,保存该case下lion每次降低多少loyal,一共多少城市,弓箭的攻击力


int return_seq(string type){//返回武士在health_seq,attack_seq中的编号
    if (type=="dragon")
        return 0;
    if (type=="ninja")
        return 1;
    if (type=="iceman")
        return 2;
    if (type=="lion")
        return 3;
    if (type=="wolf")
        return 4;
}

string return_weapon_type(int i){
    if(i==0)
        return "sword";
    if(i==1)
        return "bomb";
    if(i==2)
        return "arrow";
}

string modify_time(int time){//修正输出的时间格式    ***oj上只有atoi,没有itoa(用sprintf替代)
    int hour=time/60,minutes=time%60;
    char chour[7]="000:",cminutes[3]="00";
    if(hour>0&&hour<10)
        sprintf(chour+2,"%d",hour);
    else if(10<=hour&&hour<100)
        sprintf(chour+1,"%d",hour);
    else if(100<=hour)
        sprintf(chour,"%d",hour);
    chour[3]=':';//使用sprintf的时候末尾会自动粘贴一个\0过去,覆盖了原本的冒号
    if(minutes>0&&minutes<10)
        sprintf(cminutes+1,"%d",minutes);
    else if(10<=minutes)
        sprintf(cminutes,"%d",minutes);
    strcat(chour,cminutes);
    return chour;
}




class weapon{
public:
    int wnumber;
    string type;
    int attack,life;
    weapon(){life=3;}
    virtual void init(int user_attack=0){}
    virtual void weapon_damage(){}//将剑的攻击乘数修改,弓的生命降低
    virtual ~weapon(){}
};

class sword:public weapon{
public:
    virtual void init(int user_attack=0){
        type="sword";
        wnumber=0;
        attack=int(0.2*user_attack);
        life=100000;
    }
    virtual void weapon_damage(){
        attack=int(0.8*attack);
    }
};

class bomb:public weapon{
public:
    virtual void init(int user_attack=0){
        type="bomb";
        wnumber=1;
        attack=0;
        life=100000;
    }
};

class arrow:public weapon{
public:
    virtual void init(int user_attack=0){
        type="arrow";
        wnumber=2;
        attack=arrow_attack;
        life=3;
    }
    virtual void weapon_damage(){
        life--;
    }
};

weapon* weapon_point(int wnumber){//可以根据seq这个序数返回对映派生武士类的指针,赋值给一个基类的指针
    if(wnumber==0){
        sword* sp=new sword;
        return sp;
    }
    if(wnumber==1){
        bomb* bp=new bomb;
        return bp;
    }
    if(wnumber==2){
        arrow* ap=new arrow;
        return ap;
    }

}




class warrior{
public:
    int tribe;
    string stribe;//0代表红方,1代表蓝方
    int number;//武士编号
    string type;//武士类型
    int attack;
    int health;//该武士的生命值
    int now_city,weapon_num_type[3],war_acquire;//now_city武士现在在第几号城市;每种武器是否有;war_acquire记录每次作战能获得什么
    weapon* weapon_store[3];//三种武器的库
    void init_basicinfo(int itribe,int inumber){//初始化武士的基本信息
        tribe=itribe;
        number=inumber;
        stribe=(tribe==0)?"red":"blue";//0代表红方,1代表蓝方
        type=warrior_seq[tribe][(number-1)%5];//武士类型
        health=health_seq[return_seq(type)];//该武士的生命值
        attack=attack_seq[return_seq(type)];
        memset(weapon_num_type,0,sizeof(int)*3);
        memset(weapon_store,NULL,sizeof(weapon*)*3);
        war_acquire=(tribe==0)?1:(-1);//红色胜利一次记+1,蓝色胜利一次记-1
        if(tribe==0)
            now_city=0;
        else
            now_city=city_num+1;
        }
    virtual void init_otherinfo(int strength,int strength_need){}//注意,strength是其降生后剩余的生命源数量↑
    void print_born(int time){//输出武士降生
        cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" born"<<endl;
    }
    virtual void print_specialinfo(){}
    virtual void yell(int time,string& rep){}
    virtual void self_hurt(){}
    virtual bool run_away_test(int time){return false;}
    virtual void loyal_decrease_(){}
    virtual void morale_change(bool win){}
    virtual void wolf_rob(warrior* penemy){}
    void arrive_city(int time){//前进一步之后要先给iceman减血再arrive——city!!!!!!
        cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" marched to city "<<now_city<<" with "<<health<<" elements and force "<<attack<<endl;
    }
    void arrive_enemybase(int time){
        string enemy_stribe=(tribe==0)?"blue":"red";
        cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" reached "<<enemy_stribe<<" headquarter"<<" with "<<health<<" elements and force "<<attack<<endl;
    }
    bool death_test(){//true为战死
        if(health<=0)
            return true;
        else
            return false;
    }
    void attack_enemy(int time,warrior* penemy,int NO,string& rep){//伤敌
        int all_attack=attack;
        if(weapon_num_type[0]>0){
            all_attack+=weapon_store[0]->attack;
            weapon_store[0]->weapon_damage();//剑的损伤,如果坏的太严重就扔了
            if((weapon_store[0]->attack)<=0){
                weapon_num_type[0]=0;
                delete weapon_store[0];
                weapon_store[0]=NULL;
            }
        }
        penemy->health-=all_attack;
        rep+=modify_time(time);rep+=" ";rep+=stribe;rep+=" ";rep+=type;rep+=" ";sprintf(stemp,"%d",number);rep+=stemp;memset(stemp,'\0',100);
        rep+=" attacked ";rep+=penemy->stribe;rep+=" ";rep+=penemy->type;rep+=" ";sprintf(stemp,"%d",penemy->number);rep+=stemp;memset(stemp,'\0',100);
        rep+=" in city ";sprintf(stemp,"%d",NO);rep+=stemp;memset(stemp,'\0',100);rep+=" with ";sprintf(stemp,"%d",health);rep+=stemp;memset(stemp,'\0',100);
        rep+=" elements and force ";sprintf(stemp,"%d",attack);rep+=stemp;memset(stemp,'\0',100);rep+="\n";
    }
    virtual void attack_back(int time,warrior* penemy,int NO,string& rep){//反击,对于ninja要改为空
        int all_attack=int(attack/2);
        if(weapon_num_type[0]>0){
            all_attack+=weapon_store[0]->attack;
            weapon_store[0]->weapon_damage();//剑的损伤,如果坏的太严重就扔了
            if((weapon_store[0]->attack)<=0){
                weapon_num_type[0]=0;
                delete weapon_store[0];
                weapon_store[0]=NULL;
            }
        }
        penemy->health-=all_attack;
        rep+=modify_time(time);rep+=" ";rep+=stribe;rep+=" ";rep+=type;rep+=" ";sprintf(stemp,"%d",number);rep+=stemp;memset(stemp,'\0',100);
        rep+=" fought back against ";rep+=penemy->stribe;rep+=" ";rep+=penemy->type;rep+=" ";sprintf(stemp,"%d",penemy->number);rep+=stemp;memset(stemp,'\0',100);
        rep+=" in city ";sprintf(stemp,"%d",NO);rep+=stemp;memset(stemp,'\0',100);rep+="\n";
    }
    void shot(warrior* penemy,int time){
        if(weapon_num_type[2]>0 && penemy!=NULL){
            penemy->health-=arrow_attack;
            weapon_store[2]->weapon_damage();
            if(penemy->health<=0)//如果打死了
                cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" shot and killed "<<penemy->stribe<<" "<<penemy->type<<" "<<penemy->number<<endl;
            else//如果没打死
                cout<<modify_time(time)<<" "<<stribe<<" "<<type<<" "<<number<<" shot"<<endl;
            if(weapon_store[2]->life<=0){//如果弓打坏了就delete
                delete weapon_store[2];
                weapon_store[2]=NULL;
                weapon_num_type[2]=0;
            }
        }
    }
    bool usebomb(warrior* penemy,bool first_attack){//first_attack 为是否先手攻击的判断
        if(weapon_num_type[1]>0){//如果有炸弹
            int self_actual_attack=0,enemy_actual_attack=0;
            if(first_attack==true){//如果先手攻击
                self_actual_attack+=attack;
                enemy_actual_attack+=int((penemy->attack)/2);
            }
            else if(first_attack==false){//如果后手攻击
                self_actual_attack+=int(attack/2);
                enemy_actual_attack+=penemy->attack;
            }
            if(weapon_num_type[0]>0)
                self_actual_attack+=weapon_store[0]->attack;
            if(penemy->weapon_num_type[0]>0)
                enemy_actual_attack+=penemy->weapon_store[0]->attack;
            if(penemy->type=="ninja" && first_attack==1)//ninja不反击
                enemy_actual_attack=0;
            if((first_attack==true && penemy->health>self_actual_attack && health<=enemy_actual_attack)||(first_attack==false && health<=enemy_actual_attack))//先手攻击且打不死对方且对方会反击死自己||后手攻击且对方会杀死自己
                return true;
        }
        return false;
    }
    virtual ~warrior(){}// 析构函数里面不需要写delete,在对象自动销毁的时候会自动调用析构函数,然后delete
};

class dragon:public warrior{//已经改好吼叫
private :
    double morale;
public :
    virtual void init_otherinfo(int strength,int strength_need){
        morale=double(strength)/double(strength_need);
        if(number%3==0 && int(0.2*attack)==0)//如果是废剑,就不做了
            return;
        weapon_store[number%3]=weapon_point(number%3);
        weapon_store[number%3]->init(attack);
        weapon_num_type[number%3]=1;
    }
    virtual void print_specialinfo(){
        printf("Its morale is %.2lf\n",morale);
    }
    virtual void morale_change(bool win){
        if(win==true)
            morale+=0.2;
        else
            morale-=0.2;
    }
    virtual void yell(int time,string& rep){
        if(morale>0.8){
            rep+=modify_time(time);rep+=" ";rep+=stribe;rep+=" dragon ";sprintf(stemp,"%d",number);rep+=stemp;memset(stemp,'\0',100);
            rep+=" yelled in city ";sprintf(stemp,"%d",now_city);rep+=stemp;memset(stemp,'\0',100);rep+="\n";}
    }
};

class ninja:public warrior{
private:
    bool do1=true,do2=true;//测试两件武器是否是废剑,false代表为废
public:
    virtual void init_otherinfo(int strength,int strength_need){
        if(number%3==0 && int(0.2*attack)==0)
            do1=false;
        if((number+1)%3==0 && int(0.2*attack)==0)
            do2=false;
        if(do1==true){
            weapon_store[number%3]=weapon_point(number%3);
            weapon_store[number%3]->init(attack);
            weapon_num_type[number%3]=1;
        }
        if(do2==true){
            weapon_store[(number+1)%3]=weapon_point((number+1)%3);
            weapon_store[(number+1)%3]->init(attack);
            weapon_num_type[(number+1)%3]=1;
        }
    }
    virtual void attack_back(int time,warrior* penemy,int NO,string& rep){}
};

class iceman:public warrior{//已经改好自伤
public:
    virtual void init_otherinfo(int strength,int strength_need){
        if(number%3==0 && int(0.2*attack)==0)//如果是废剑,就不做了
            return;
        weapon_store[number%3]=weapon_point(number%3);
        weapon_store[number%3]->init(attack);
        weapon_num_type[number%3]=1;
    }
    virtual void self_hurt(){
        health-=9;
        attack+=20;
        if(health<=0)
            health=1;
    }
};

class lion:public warrior{//已经增加逃跑设定和忠诚度降低设定
private:
    int loyal;
public:
    virtual void init_otherinfo(int strength,int strength_need){
/*        if(number%3==0 && int(0.2*attack)==0)//如果是废剑,就不做了
            return;
        weapon_store[number%3]=weapon_point(number%3);
        weapon_store[number%3]->init(attack);
        weapon_num_type[number%3]=1;*/
        loyal=strength;
    }
    virtual void print_specialinfo(){
    cout<<"Its loyalty is "<<loyal<<endl;
    }
    virtual void loyal_decrease_(){
        loyal-=loyal_decrease;
    }
    virtual bool run_away_test(int time){//1代表太跑了,0代表没逃跑
        if(loyal<=0){
            cout<<modify_time(time)<<" "<<stribe<<" lion "<<number<<" ran away"<<endl;
            return true;
        }
        else
            return false;
    }

};

class wolf:public warrior{//已经增加抢武器设定
public:
    virtual void wolf_rob(warrior* penemy){
        for(int i=0;i<=2;++i){
            if(penemy->weapon_store[i]!=NULL && weapon_store[i]==NULL){
                weapon_store[i]=penemy->weapon_store[i];
                weapon_num_type[i]=1;
            }
        }
    }
};

warrior* type_point(int seq){//可以根据seq这个序数返回对映派生武士类的指针,赋值给一个基类的指针
    if(seq==0){
        dragon* pd=new dragon;
        return pd;
    }
    if(seq==1){
        ninja* pn=new ninja;
        return pn;
    }
    if(seq==2){
        iceman* pi=new iceman;
        return pi;
    }
    if(seq==3){
        lion* pl=new lion;
        return pl;
    }
    if(seq==4){
        wolf* pw=new wolf;
        return pw;
    }
/*
注意此处要用指针new一块地址出来,否则每一次调用该函数给的地址可能会重复,发生0xC0000005错误!!!
*/
}




class city{
public:
    int this_war,war;//this_war记录本次战斗结果,war记录总体战况
    string flag;//当前旗帜
    int NO,strength,process;//NO记录城市编号,该城市生命源,precess为基地占领进度
    int just_rise;//为1表示旗子刚刚升起
    warrior *pwarrior_red,*pwarrior_blue;
    void init(int i){
        NO=i;
        pwarrior_red=NULL;
        pwarrior_blue=NULL;
        this_war=0;//本次战况
        war=0;//总战况
        process=0;
        strength=0;
        just_rise=0;
        flag="none";
    }
    void fight(int time,warrior* &pwinner,string& rep){
        this_war=0;
        just_rise=0;
        pwinner=NULL;
        //以下判断先后手
            warrior *w_1=NULL,*w_2=NULL;
            if(NO%2==1){
                w_1=pwarrior_red;
                w_2=pwarrior_blue;
            }
            else{
                w_1=pwarrior_blue;
                w_2=pwarrior_red;
            }
            if(flag=="red"){
                w_1=pwarrior_red;
                w_2=pwarrior_blue;
            }
            else if(flag=="blue"){
                w_1=pwarrior_blue;
                w_2=pwarrior_red;
            }
        //以上判断先后手
        if(pwarrior_blue->health<=0 && pwarrior_red->health<=0){//两者都是被射死的,不算平局
            delete pwarrior_blue;
            delete pwarrior_red;
            pwarrior_blue=NULL;
            pwarrior_red=NULL;
        }
        else if(pwarrior_blue->health<=0 && pwarrior_red->health>0){//只有红方存活
            this_war=1;
            pwarrior_red->morale_change(true);
            pwinner=pwarrior_red;
            pwarrior_red->wolf_rob(pwarrior_blue);//狼抢尸体
            if(w_1->health>0)
                w_1->yell(time,rep);//龙吼
            delete pwarrior_blue;
            pwarrior_blue=NULL;
            if(war==0){
                war+=this_war;
            }
            else if(war==1){
                war+=this_war;
                if(flag!="red"){
                    just_rise=1;//旗子刚刚升起
                    flag="red";
                }
            }
            else if(war>=2){
                war+=this_war;
            }
            else if(war<=-1){
                war=0;
                war+=this_war;
            }
        }
        else if(pwarrior_blue->health>0 && pwarrior_red->health<=0){//只有蓝方存活
            this_war=-1;
            pwarrior_blue->morale_change(true);
            pwinner=pwarrior_blue;
            pwarrior_blue->wolf_rob(pwarrior_red);//狼抢尸体
            if(w_1->health>0)
                w_1->yell(time,rep);//龙吼
            delete pwarrior_red;
            pwarrior_red=NULL;
            if(war==0){
                war+=this_war;
            }
            else if(war==-1){
                war+=this_war;
                if(flag!="blue"){
                    just_rise=1;//旗子刚刚升起
                    flag="blue";
                }
            }
            else if(war<=-2){
                war+=this_war;
            }
            else if(war>=1){
                war=0;
                war+=this_war;
            }
        }
        else if(pwarrior_blue->health>0 && pwarrior_red->health>0){//两者都有血,正常开战
            int lion_1_life=(w_1->type=="lion")?(w_1->health):0;
            int lion_2_life=(w_2->type=="lion")?(w_2->health):0;
            w_1->attack_enemy(time,w_2,NO,rep);
            if(w_2->death_test()==true){//w2死了,胜者为w1
                pwinner=w_1;
                rep+=modify_time(time);rep+=" ";rep+=w_2->stribe;rep+=" ";rep+=w_2->type;rep+=" ";sprintf(stemp,"%d",w_2->number);rep+=stemp;memset(stemp,'\0',100);
                rep+=" was killed in city ";sprintf(stemp,"%d",NO);rep+=stemp;memset(stemp,'\0',100);rep+="\n";
                w_1->morale_change(true);
                w_1->yell(time,rep);//龙吼
                w_1->health+=lion_2_life;
                w_1->wolf_rob(w_2);
                this_war=w_1->war_acquire;
                if(war==0){
                    war+=this_war;
                }
                else if(war*this_war<0){//两者异号
                    war=0;
                    war+=this_war;
                }
                else if(war*this_war>0 && war==this_war){//两者同号且刚升起来
                    war+=this_war;
                    if(flag!=w_1->stribe){
                        just_rise=1;//刚刚升起
                        flag=w_1->stribe;
                    }
                }
                else if(war*this_war>0 && war*war>this_war*this_war){
                    war+=this_war;
                }
                if(pwarrior_blue==w_2){
                    delete pwarrior_blue;
                    pwarrior_blue=NULL;
                }
                else if(pwarrior_red==w_2){
                    delete pwarrior_red;
                    pwarrior_red=NULL;
                }
            }
            else{//w2没死,发起反击
                w_2->attack_back(time,w_1,NO,rep);
                if(w_1->death_test()==true){//w1死了,胜者为w2
                    pwinner=w_2;
                    rep+=modify_time(time);rep+=" ";rep+=w_1->stribe;rep+=" ";rep+=w_1->type;rep+=" ";sprintf(stemp,"%d",w_1->number);rep+=stemp;memset(stemp,'\0',100);
                    rep+=" was killed in city ";sprintf(stemp,"%d",NO);rep+=stemp;memset(stemp,'\0',100);rep+="\n";
                    w_2->morale_change(true);//还击不吼
                    w_2->health+=lion_1_life;
                    w_2->wolf_rob(w_1);
                    this_war=w_2->war_acquire;
                    if(war==0){
                        war+=this_war;
                    }
                    else if(war*this_war<0){//两者异号
                        war=0;
                        war+=this_war;
                    }
                    else if(war*this_war>0 && war==this_war){//两者同号
                        war+=this_war;
                        if(flag!=w_2->stribe){
                            just_rise=1;
                            flag=w_2->stribe;
                        }
                    }
                    else if(war*this_war>0 && war*war>this_war*this_war){
                        war+=this_war;
                    }
                    if(pwarrior_blue==w_1){
                        delete pwarrior_blue;
                        pwarrior_blue=NULL;
                    }
                    else if(pwarrior_red==w_1){
                        delete pwarrior_red;
                        pwarrior_red=NULL;
                    }
                }
                else{//两者都没死,成为平局
                    this_war=0;
                    war=0;
                    w_1->loyal_decrease_();
                    w_1->morale_change(false);
                    w_2->loyal_decrease_();
                    w_2->morale_change(false);
                    w_1->yell(time,rep);//龙吼
                }
            }
        }
    }
};



void born_or_stop(city* cities,const int& ti,const int& time,int* strength_rb,int* number_rb,int* health_seq,int& warrior_storge){
    //执行出生或停止操作
    //如果为false则停止,为true则继续
    string type=warrior_seq[ti][(number_rb[ti]-1)%5];//找出当前想要创建的武士类型
    int seq=return_seq(type);
    if (strength_rb[ti]>=health_seq[seq]){//如果本次可以直接按顺序创造
        warrior_storge+=1;
        strength_rb[ti]-=health_seq[seq];
        warrior* pW;
        pW=type_point(seq);
        pW->init_basicinfo(ti,number_rb[ti]);
        pW->init_otherinfo(strength_rb[ti],health_seq[seq]);
        pW->print_born(time);
        pW->print_specialinfo();
        number_rb[ti]+=1;
        if(ti==0)//如果红方出生,记在红司令部
            cities[0].pwarrior_red=pW;
        if(ti==1)//如果蓝方出生,记在蓝司令部
            cities[city_num+1].pwarrior_blue=pW;
    }
}


void report(warrior* pw,int time){//武士汇报工作
    int a=pw->weapon_num_type[2],b=pw->weapon_num_type[1],s=pw->weapon_num_type[0];
    int s_attack=0,a_life=0;
    if(s>0)
        s_attack=pw->weapon_store[0]->attack;
    if(a>0)
        a_life=pw->weapon_store[2]->life;
    cout<<modify_time(time)<<" "<<pw->stribe<<" "<<pw->type<<" "<<pw->number<<" has ";
    if(a==0&&b==0&&s==0)
        cout<<"no weapon"<<endl;
    else if(a==1&&b==0&&s==0)
        cout<<"arrow("<<a_life<<")"<<endl;
    else if(a==0&&b==1&&s==0)
        cout<<"bomb"<<endl;
    else if(a==0&&b==0&&s==1)
        cout<<"sword("<<s_attack<<")"<<endl;
    else if(a==1&&b==1&&s==0)
        cout<<"arrow("<<a_life<<"),bomb"<<endl;
    else if(a==1&&b==0&&s==1)
        cout<<"arrow("<<a_life<<"),sword("<<s_attack<<")"<<endl;
    else if(a==0&&b==1&&s==1)
        cout<<"bomb,sword("<<s_attack<<")"<<endl;
    else if(a==1&&b==1&&s==1)
        cout<<"arrow("<<a_life<<"),bomb,sword("<<s_attack<<")"<<endl;
}

bool onehour(city* cities,int& hours,bool& red_win,bool& blue_win,int& T,int* strength_rb,int* number_rb,int* warrior_storge_rb,warrior** out_range_warrior){
//只要能进这个循环,就说明还没有人获胜

    //1) 武士降生 OK
    int time=60*hours+0;
    born_or_stop(cities,0,time,strength_rb,number_rb,health_seq,warrior_storge_rb[0]);//红方降生
    born_or_stop(cities,1,time,strength_rb,number_rb,health_seq,warrior_storge_rb[1]);//蓝方降生

    //2) lion逃跑 OK
    time=60*hours+5;
    if(time>T)
        return false;
    for(int i=0;i<=city_num+1;++i){
        if(cities[i].pwarrior_red!=NULL){
            bool test;
            test=cities[i].pwarrior_red->run_away_test(time);
            if(test==true){
                warrior_storge_rb[0]-=1;
                delete cities[i].pwarrior_red;
                cities[i].pwarrior_red=NULL;
            }
        }
        if(cities[i].pwarrior_blue!=NULL){
            bool test;
            test=cities[i].pwarrior_blue->run_away_test(time);
            if(test==true){
                warrior_storge_rb[1]-=1;
                delete cities[i].pwarrior_blue;
                cities[i].pwarrior_blue=NULL;
            }
        }
    }

    //3) 武士前进到某一城市 && 7) 武士抵达敌军司令部 && 8) 司令部被占领
    time=60*hours+10;
    if(time>T)
        return false;
    for(int i=0;i<=city_num;++i){//双方移动并进行自伤
        if (cities[i+1].pwarrior_blue!=NULL){
            cities[i].pwarrior_blue=cities[i+1].pwarrior_blue;//蓝方前进
            cities[i].pwarrior_blue->now_city=i;
            if((city_num+1-i)%2==0)//如果iceman前进了偶数步
                cities[i].pwarrior_blue->self_hurt();//iceman自伤
        }
        else
            cities[i].pwarrior_blue=NULL;
        int j=city_num+1-i;//以下红方前进
        if (cities[j-1].pwarrior_red!=NULL){
            cities[j].pwarrior_red=cities[j-1].pwarrior_red;
            cities[j].pwarrior_red->now_city=j;
            if(j%2==0)
                cities[j].pwarrior_red->self_hurt();
        }
        else
            cities[j].pwarrior_red=NULL;
    }
    cities[0].pwarrior_red=NULL;
    cities[city_num+1].pwarrior_blue=NULL;//移动全部完成
    if(cities[0].pwarrior_blue!=NULL){//红方基地被蓝方占领
        cities[0].process++;
        if(cities[0].process==2)
            blue_win=true;
        cities[0].pwarrior_blue->arrive_enemybase(time);
        out_range_warrior[0]=cities[0].pwarrior_blue;
        cities[0].pwarrior_blue=NULL;
        if(blue_win==true)
            cout<<modify_time(time)<<" red headquarter was taken"<<endl;
    }
    for(int ii=1;ii<=city_num;++ii){
        if(cities[ii].pwarrior_red!=NULL)
            cities[ii].pwarrior_red->arrive_city(time);
        if(cities[ii].pwarrior_blue!=NULL)
            cities[ii].pwarrior_blue->arrive_city(time);
    }
    if(cities[city_num+1].pwarrior_red!=NULL){//蓝方基地被红方占领
        cities[city_num+1].process++;
        if(cities[city_num+1].process==2)
            red_win=true;
        cities[city_num+1].pwarrior_red->arrive_enemybase(time);
        out_range_warrior[1]=cities[city_num+1].pwarrior_red;
        cities[city_num+1].pwarrior_red=NULL;
        if(red_win==true)
            cout<<modify_time(time)<<" blue headquarter was taken"<<endl;
    }
    if(red_win==true||blue_win==true)//如果有人占领了对方司令部就全部结束
        return true;

    //每个城市产生10个生命源
    time=60*hours+20;
    if(time>T)
        return false;
    for(int i=1;i<=city_num;++i)
        cities[i].strength+=10;

    //只有一个武士,取走该城市所有的生命源
    time=60*hours+30;
    if(time>T)
        return false;
    for(int i=1;i<=city_num;++i){
        if(cities[i].pwarrior_blue==NULL&&cities[i].pwarrior_red!=NULL){//只有红武士
            strength_rb[0]+=cities[i].strength;
            cout<<modify_time(time)<<" red "<<cities[i].pwarrior_red->type<<" "<<cities[i].pwarrior_red->number<<" earned "<<cities[i].strength<<" elements for his headquarter"<<endl;
            cities[i].strength=0;
        }
        else if(cities[i].pwarrior_blue!=NULL&&cities[i].pwarrior_red==NULL){//只有蓝武士
            strength_rb[1]+=cities[i].strength;
            cout<<modify_time(time)<<" blue "<<cities[i].pwarrior_blue->type<<" "<<cities[i].pwarrior_blue->number<<" earned "<<cities[i].strength<<" elements for his headquarter"<<endl;
            cities[i].strength=0;
        }
    }


    //4) 武士放箭
    time=60*hours+35;
    if(time>T)
        return false;
    for(int i=1;i<=city_num;++i){
        if(cities[i].pwarrior_red!=NULL){
            if(cities[i].pwarrior_red->weapon_num_type[2]>0 && cities[i+1].pwarrior_blue!=NULL)//本方有人且有箭,下一格有人
                cities[i].pwarrior_red->shot(cities[i+1].pwarrior_blue,time);
        }
        if(cities[i].pwarrior_blue!=NULL){
            if(cities[i].pwarrior_blue->weapon_num_type[2]>0 && cities[i-1].pwarrior_red!=NULL)
                cities[i].pwarrior_blue->shot(cities[i-1].pwarrior_red,time);
        }
    }

    //5)武士使用bomb
    time=60*hours+38;
    if(time>T)
        return false;
    for(int i=1;i<=city_num;++i){
        if(cities[i].pwarrior_red!=NULL && cities[i].pwarrior_blue!=NULL){
            if(cities[i].pwarrior_red->health>0 && cities[i].pwarrior_blue->health>0){//由于放箭不清除指针,所以本次必须要判断是不是双方还活着
                warrior *w_1=NULL,*w_2=NULL;
                if(i%2==1){
                    w_1=cities[i].pwarrior_red;
                    w_2=cities[i].pwarrior_blue;
                }
                else{
                    w_1=cities[i].pwarrior_blue;
                    w_2=cities[i].pwarrior_red;
                }
                if(cities[i].flag=="red"){
                    w_1=cities[i].pwarrior_red;
                    w_2=cities[i].pwarrior_blue;
                }
                else if(cities[i].flag=="blue"){
                    w_1=cities[i].pwarrior_blue;
                    w_2=cities[i].pwarrior_red;
                }
                //以上,按照规则完整地判断了先后手,可以在fight函数中复用
                if(cities[i].pwarrior_red->usebomb(cities[i].pwarrior_blue,w_1==cities[i].pwarrior_red)==true){
                    cout<<modify_time(time)<<" red "<<cities[i].pwarrior_red->type<<" "<<cities[i].pwarrior_red->number<<" used a bomb and killed blue "<<cities[i].pwarrior_blue->type<<" "<<cities[i].pwarrior_blue->number<<endl;
                    delete cities[i].pwarrior_red;
                    delete cities[i].pwarrior_blue;
                    cities[i].pwarrior_red=NULL;
                    cities[i].pwarrior_blue=NULL;
                }
                else if(cities[i].pwarrior_blue->usebomb(cities[i].pwarrior_red,w_1==cities[i].pwarrior_blue)==true){
                    cout<<modify_time(time)<<" blue "<<cities[i].pwarrior_blue->type<<" "<<cities[i].pwarrior_blue->number<<" used a bomb and killed red "<<cities[i].pwarrior_red->type<<" "<<cities[i].pwarrior_red->number<<endl;
                    delete cities[i].pwarrior_red;
                    delete cities[i].pwarrior_blue;
                    cities[i].pwarrior_red=NULL;
                    cities[i].pwarrior_blue=NULL;//看样例的输出,如果发现可以两者同时输出用炸弹,则修改此处的else if为if且删去上面的delete操作!!!
                }
            }
        }
    }



    //6) 武士主动进攻   7) 武士反击   8) 武士战死+lion送初始生命   lion减少loyal   狼抢武器   9) 武士欢呼    10) 武士获取生命元( elements ) +奖励+回收给基地   11) 旗帜升起
    time=60*hours+40;
    if(time>T)
        return false;
    warrior *pwinner[city_num];
    memset(pwinner,NULL,city_num*sizeof(weapon*));
    string rep[city_num+5];
    memset(rep,'\0',(city_num+5)*sizeof(rep[0]));
    for(int i=1;i<=city_num;++i){
        if(cities[i].pwarrior_blue==NULL && cities[i].pwarrior_red!=NULL){
            if(cities[i].pwarrior_red->health<=0){//只有红战士且被射死了
                delete cities[i].pwarrior_red;
                cities[i].pwarrior_red=NULL;
            }
        }
        else if(cities[i].pwarrior_blue!=NULL && cities[i].pwarrior_red==NULL){
            if(cities[i].pwarrior_blue->health<=0){//只有蓝武士且被射死了
                delete cities[i].pwarrior_blue;
                cities[i].pwarrior_blue=NULL;
            }
        }
        else if(cities[i].pwarrior_blue!=NULL && cities[i].pwarrior_red!=NULL)
            cities[i].fight(time,pwinner[i],rep[i]);//两者都有就开战吧
    }
    for(int i=1;i<=city_num;++i){//发放奖励
        int j=city_num+1-i;//j用给红色奖励,i用给蓝色奖励
        if(pwinner[j]!=NULL && pwinner[j]==cities[j].pwarrior_red && strength_rb[0]>=8){
            strength_rb[0]-=8;
            pwinner[j]->health+=8;
        }
        if(pwinner[i]!=NULL && pwinner[i]==cities[i].pwarrior_blue && strength_rb[1]>=8){
            strength_rb[1]-=8;
            pwinner[i]->health+=8;
        }
    }
    for(int i=1;i<=city_num;++i){//回收生命源
        if(pwinner[i]!=NULL && pwinner[i]==cities[i].pwarrior_red){
            strength_rb[0]+=cities[i].strength;
            //cout<<modify_time(time)<<" red "<<pwinner[i]->type<<" "<<pwinner[i]->number<<" earned "<<cities[i].strength<<" elements for his headquarter"<<endl;
            rep[i]+=modify_time(time);rep[i]+=" red ";rep[i]+=pwinner[i]->type;rep[i]+=" ";sprintf(stemp,"%d",pwinner[i]->number);rep[i]+=stemp;memset(stemp,'\0',100);
            rep[i]+=" earned ";sprintf(stemp,"%d",cities[i].strength);rep[i]+=stemp;memset(stemp,'\0',100);rep[i]+=" elements for his headquarter";rep[i]+="\n";
            cities[i].strength=0;
        }
        else if(pwinner[i]!=NULL && pwinner[i]==cities[i].pwarrior_blue){
            strength_rb[1]+=cities[i].strength;
            //cout<<modify_time(time)<<" blue "<<pwinner[i]->type<<" "<<pwinner[i]->number<<" earned "<<cities[i].strength<<" elements for his headquarter"<<endl;
            rep[i]+=modify_time(time);rep[i]+=" blue ";rep[i]+=pwinner[i]->type;rep[i]+=" ";sprintf(stemp,"%d",pwinner[i]->number);rep[i]+=stemp;memset(stemp,'\0',100);
            rep[i]+=" earned ";sprintf(stemp,"%d",cities[i].strength);rep[i]+=stemp;memset(stemp,'\0',100);rep[i]+=" elements for his headquarter";rep[i]+="\n";
            cities[i].strength=0;
        }
    }
    for(int i=1;i<=city_num;++i){//插旗子
        if(cities[i].just_rise==1){
            cities[i].just_rise=0;
            rep[i]+=modify_time(time);rep[i]+=" ";rep[i]+=cities[i].flag;rep[i]+=" flag raised in city ";sprintf(stemp,"%d",cities[i].NO);rep[i]+=stemp;memset(stemp,'\0',100);
            rep[i]+="\n";
        }
        cout<<rep[i];//rep[i]一定自带换行
    }

    //9)司令部报告生命元数量
    time=60*hours+50;
    if(time>T)
        return false;
    cout<<modify_time(time)<<" "<<strength_rb[0]<<" elements in red headquarter"<<endl;
    cout<<modify_time(time)<<" "<<strength_rb[1]<<" elements in blue headquarter"<<endl;

    //10)武士报告情况
    time=60*hours+55;
    if(time>T)
        return false;
    for(int i=0;i<=city_num+1;++i){
        if(cities[i].pwarrior_red!=NULL)
            report(cities[i].pwarrior_red,time);
    }
    if(out_range_warrior[1]!=NULL)
        report(out_range_warrior[1],time);//汇报之前走到终点的
    if(out_range_warrior[0]!=NULL)
        report(out_range_warrior[0],time);//汇报之前走到终点的
    for(int i=0;i<=city_num+1;++i){
        if(cities[i].pwarrior_blue!=NULL)
           report(cities[i].pwarrior_blue,time);
    }
}



int main(){
    //freopen("data.in","r",stdin);
    //freopen("myout.out","w",stdout);
    int case_n;//现在是第几个case
    cin>>case_n;
    for(int i=0;i<case_n;++i){
        memset(stemp,'\0',100);
        cout<<"Case "<<i+1<<":"<<endl;
        int hours=0;
        warrior* out_range_warrior[2]={NULL,NULL};//记录走到对方终点,但是还没赢的两个战士
        bool red_win=false,blue_win=false;
        int strength,T;//生命源总量,输出到第几个时间
        cin>>strength>>city_num>>arrow_attack>>loyal_decrease>>T;
        for(int j=0;j<5;++j)//读入了这个case生产每个武士需要耗费多少生命源
            cin>>health_seq[j];
        for(int j=0;j<5;++j)//读入了这个case每个武士的攻击力
            cin>>attack_seq[j];
        int strength_rb[2]={strength,strength},number_rb[2]={1,1},warrior_storge_rb[2]={0,0};//红蓝方生命源,红蓝方目前的需要,红蓝方的武士总数
        city cities[city_num+2];
        for(int j=0;j<=city_num+1;++j)
            cities[j].init(j);
        for(hours=0;hours<=int(T/60);++hours){
            onehour(cities,hours,red_win,blue_win,T,strength_rb,number_rb,warrior_storge_rb,out_range_warrior);
            if(red_win==true||blue_win==true)
                break;
            }
    }
    return 0;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
问题描述 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 …. N ( N <= 20 )。红魔军的司令部算作编号为0的城市,蓝魔军的司令部算作编号为N+1的城市。司令部有生命元,用于制造武士。 两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值、攻击力这三种属性。 双方的武士编号都是从1开始计算。红方制造出来的第 n 个武士,编号就是n。同样,蓝方制造出来的第 n 个武士,编号也是n。 武士在刚降生的时候有一个初始的生命值,生命值在战斗中会发生变化,如果生命值减少到0(生命值变为负数时应当做变为0处理),则武士死亡(消失)。 有的武士可以拥有武器。武器有三种,sword, bomb,和arrow,编号分别为0,1,2。 武士降生后就朝对方司令部走,在经过的城市如果遇到敌人(同一时刻每个城市最多只可能有1个蓝武士和一个红武士),就会发生战斗。每次战斗只有一方发起主动进攻一次。被攻击者生命值会减去进攻者的攻击力值和进攻者手中sword的攻击力值。被进攻者若没死,就会发起反击,被反击者的生命值要减去反击者攻击力值的一半(去尾取整)和反击者手中sword的攻击力值。反击可能致敌人于死地。 如果武士在战斗中杀死敌人(不论是主动进攻杀死还是反击杀死),则其司令部会立即向其发送8个生命元作为奖励,使其生命值增加8。当然前提是司令部得有8个生命元。如果司令部的生命元不足以奖励所有的武士,则优先奖励距离敌方司令部近的武士。 如果某武士在某城市的战斗中杀死了敌人,则该武士的司令部立即取得该城市中所有的生命元。注意,司令部总是先完成全部奖励工作,然后才开始从各个打了胜仗的城市回收生命元。对于因司令部生命元不足而领不到奖励的武士,司令部也不会在取得战利品生命元后为其补发奖励。 如果一次战斗的结果是双方都幸存(平局),则双方都不能拿走发生战斗的城市的生命元。 城市可以插旗子,一开始所有城市都没有旗子。在插红旗的城市,以及编号为奇数的无旗城市,由红武士主动发起进攻。在插蓝旗的城市,以及编号为偶数的无旗城市,由蓝武士主动发起进攻。 当某个城市有连续两场战斗都是同一方的武士杀死敌人(两场战斗之间如果有若干个战斗时刻并没有发生战斗,则这两场战斗仍然算是连续的;但如果中间有平局的战斗,就不算连续了) ,那么该城市就会插上胜方的旗帜,若原来插着败方的旗帜,则败方旗帜落下。旗帜一旦插上,就一直插着,直到被敌人更换。一个城市最多只能插一面旗帜,旗帜没被敌人更换前,也不会再次插同颜色的旗。 各种武器有其特点: sword武器的初始攻击力为拥有它的武士的攻击力的20%(去尾取整)。但是sword每经过一次战斗(不论是主动攻击还是反击),就会变钝,攻击力变为本次战斗前的80% (去尾取整)。sword攻击力变为0时,视为武士失去了sword。如果武士降生时得到了一个初始攻击力为0的sword,则视为武士没有sword. arrow有一个攻击力值R。如果下一步要走到的城市有敌人,那么拥有arrow的武士就会放箭攻击下一个城市的敌人(不能攻击对方司令部里的敌人)而不被还击。arrow使敌人的生命值减少R,若减至小于等于0,则敌人被杀死。arrow使用3次后即被耗尽,武士失去arrow。两个相邻的武士可能同时放箭把对方射死。 拥有bomb的武士,在战斗开始前如果判断自己将被杀死(不论主动攻击敌人,或者被敌人主动攻击都可能导致自己被杀死,而且假设武士可以知道敌人的攻击力和生命值),那么就会使用bomb和敌人同归于尽。武士不预测对方是否会使用bomb。 武士使用bomb和敌人同归于尽的情况下,不算是一场战斗,双方都不能拿走城市的生命元,也不影响城市的旗帜。 不同的武士有不同的特点。 dragon可以拥有一件武器。编号为n的dragon降生时即获得编号为 n%3 的武器。dragon还有“士气”这个属性,是个浮点数,其值为它降生后其司令部剩余生命元的数量除以造dragon所需的生命元数量。dragon 在一次在它主动进攻的战斗结束后,如果还没有战死,而且士气值大于0.8,就会欢呼。dragon每取得一次战斗的胜利(敌人被杀死),士气就会增加0.2,每经历一次未能获胜的战斗,士气值就会减少0.2。士气增减发生在欢呼之前。 ninjia可以拥有两件武器。编号为n的ninjia降生时即获得编号为 n%3 和 (n+1)%3的武器。ninja 挨打了也从不反击敌人。 iceman有一件武器。编号为n的iceman降生时即获得编号为 n%3 的武器。iceman 每前进两步,在第2步完成的时候,生命值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值