魔兽世界-开战

/*
这里是从网上找的参考代码,有点迷迷糊糊的
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define WARRIOR_NUM 5
#define WEAPON_NUM 3

#define COLOR_RED 0
#define COLOR_BLUE 1
#define COLOR_NONE 3

enum{DRAGON,NINJA,ICEMAN,LION,WOLF};
enum{WEAPON_SWORD,WEAPON_BOMB,WEAPON_ARROW};
enum EEventType{EVENT_BORN,EVENT_LION_RUN,EVENT_MARCH,EVENT_ARROW,EVENT_BOMB,EVENT_ATTACK,EVENT_FIGHTBACK,
        EVENT_KILLED,EVENT_YELL,EVENT_EARNMONEY,EVENT_FLAG,EVENT_REACH,EVENT_CITYTAKEN,EVENT_PRINTMONEY,
        EVENT_WARRIOR_REPORT};


class CHeadquarter;
class CKingdom;
class CWarrior;
class CCity;
class CWeapon;
typedef  CWarrior* PWARRIOR;

string MyIntToStr(int n)
{
    /*
    将int转化为string
    */
    char szTmp[300];
    sprintf(szTmp,"%d",n);
    return szTmp;
}

//武器类CWeapon
class CWeapon
{
public:
    int nKindNo;//武器的种类编号 n代表为整数值
    int nForce;//sword的攻击力或者代表武器的使用次数arrow和bomb的使用次数
    static const char* Names[WEAPON_NUM];//武器的名称
    static int nArrowForce;//弓箭的攻击力
    bool operator<(const CWeapon& w)//????????????????????????????????????????????????????????????????????
    {
        return w.nKindNo<nKindNo;//武器种类从大到排序2,1,0
    }
};
//战士类CWarrior
class CWarrior
{
    friend class CHeadquarter;
    friend bool MyCompare(const PWARRIOR& p1,const PWARRIOR& p2);//奖励按照距离地方阵营比较近排序
protected:
    int nId;//编号
    int nStrength;//生命值
    int nForce;//攻击力
    int nCityNo;//所在城市编号
    bool bShotToDeath;//表示是由弓箭射死
    CHeadquarter* pHeadquarter;//复合关系,
public:
    static int InitialForce[WARRIOR_NUM];//和当前类关系紧密的全局变量声明为static
    static int InitialLifeValue[WARRIOR_NUM];
    static const char* Names[WARRIOR_NUM];

    CWarrior(int nId_,int nStrength_,int nForce_,int nCityNo_,CHeadquarter* pHeadquarter_);//构造函数
    virtual ~CWarrior();//析构函数
    virtual bool Runaway();//lion逃跑
    virtual bool HasBomb();//拥有炸弹
    virtual int GetSwordForce();//获得sword的攻击力
    virtual int UseSword();//使用sword,会进行磨损度
    virtual void AddMorale(double a);//dragon添加士气
    virtual void EarnWeapons(CWarrior* pEnemy);//wolf获得武器
    virtual string ReportWeapons();//战士报告武器情况

    virtual bool VirtualAttack(CWarrior *pEnemy);//判断是否战斗能将攻击将敌人杀死,并不修改变量
    virtual bool VirtualFightback(CWarrior* pEnemy);//判断是否战斗能将反击将敌人杀死

    virtual int Attack(CWarrior* pEnemy);//攻击操作杀死敌人返回1,被敌人反击杀死返回-1,否则返回0,判断killed

    virtual int HurtedBy(CWarrior *pEnemy);//返回被攻击武士的生命值,判断killed
    virtual void FightBack(CWarrior* pEnemy);//反击不判断死亡
    virtual void Killed();//死亡,并没有将死亡的武士去除,仅保存事件
    virtual string GetName() = 0;//需要重写
    virtual void March();//iceman前进


    virtual int ShootArrow();

    int AttackedByArrow(int nArrowForce);
    string GetColorStr();//获得武士阵营颜色
    int GetColor();//获得武士阵营颜色
    int GetStrength();//获取武士生命值
    int GetForce();//获取武士攻击力
    void SetStrength(int n);//设置武士生命值
    void SetForce(int n);//设置武士攻击力
    int GetPosition();//获取武士所在的城市编号
};
bool MyCompare(  const PWARRIOR & p1, const PWARRIOR & p2)
{
    /*
    给奖励的时候进行排序,距离地方近的优先奖励
    */
	if( p1->GetColor() == COLOR_RED)
		return p1->nCityNo > p2->nCityNo;
	else
		return p1->nCityNo < p2->nCityNo;
}
//武器战士类CWeaponWarrior
class CWeaponWarrior:public CWarrior
{
public:
    vector<CWeapon> vwp;
public:
    CWeaponWarrior(int nId_,int nStrength_,int nForce_,int nCityNo_,CHeadquarter* pHeadquarter_,int nWeaponNum);//构造函数
    bool HasBomb();//是否拥有炸弹
    int GetSwordForce();//获取sword的值
    int UseSword();//使用sword,将会修改磨损度,返回的也是sword的值
    int ShootArrow();//使用arrow,将会修改弓箭的使用次数,返回arrow的攻击力
    string ReportWeapons();//报告武器

};
//CDragon
class CDragon:public CWeaponWarrior
{
    friend class CHeadquarter;
private:
    double fMorale;//士气值
public:
    CDragon(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_);//构造函数初始化
    virtual int Attack( CWarrior * p) ;//调用父类的Attack重写
	void FightBack(CWarrior * pEnemy);//调用父类的FightBack重写
	void AddMorale(double a);//?????????????????????/
	virtual string GetName();//返回  color + 武士种类 + nId
};
//CNinja
class CNinja:public CWeaponWarrior
{
    friend class CHeadquarter;
public:
    CNinja(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_);//构造函数
    virtual int  HurtedBy(CWarrior * pEnemy);//收到攻击不还手,反击是在Hurted中调用的
	virtual string GetName();;//返回  color + 武士种类 + nId
	bool VirtualFightback( CWarrior * pEnemy);
};
//CIceman
class CIceman:public CWeaponWarrior
{
    friend class CHeadquarter;
private:
    int nSteps;
public:
    CIceman(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_);
    virtual void March() ;//行军
	virtual string GetName() ;;//返回  color + 武士种类 + nId
};
//CLion
class CLion:public CWarrior
{
    friend class CHeadquarter;
private:
    int nLoyalty;//狮子的忠诚度
public:
    static int nLoyaltyDec;//未能杀死敌人下降K
	CLion(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_);//构造函数
    int HurtedBy(CWarrior * pEnemy);//实现将血量加到别人身上
	void FightBack(CWarrior * pEnemy);//实现忠诚度
	int Attack( CWarrior * pEnemy) ;//攻击
	virtual string GetName();//获得名字
	bool Runaway ();//判断是否逃跑
};
//CWolf
class CWolf:public CWeaponWarrior
{
    friend class CHeadquarter;
private:
    int nEnemyKilled;
public:
    CWolf(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_);
    virtual int Attack( CWarrior * pEnemy);
	virtual string GetName();
	void EarnWeapons( CWarrior * pEnemy);
};
//class CHeadquarter
class CHeadquarter
{

    friend class CWarrior;
    friend class CWolf;
    friend class CDragon;
    friend class CIceman;
    friend class CLion;
    friend class CNinja;
private:
    int nBloodMoney ; //记录战争之后赢得的生命元
	int nMoney;//司令部的生命元
	int nEnemys;//到达对方司令部的武士数目
	int nWarriorNo;//武士的编号
	list<CWarrior * > lstWarrior;//复合关系,拥有的武士
	int nColor;//红方还是蓝方
	CKingdom * pKingdom;//战场
	int nCityNo; //red: 0 ,blue nCitynum + 1
	CHeadquarter * pEnemyheadquarter;//敌方司令部
	vector<CWarrior *> vAwardList;//战斗胜利之后需要奖励的武士
public:
    static int MakingSeq[2][WARRIOR_NUM];//生产战士的序列
    CHeadquarter(int nColor_, int nMoney_,int nCityNo_ );//构造函数
    ~CHeadquarter();//析构函数,释放所有的武士
    void SetEnemy( CHeadquarter * p);//设置敌方阵营
    void SetKingdom( CKingdom * p);//设置战场
    void AddEvent( EEventType eType, int nCityNo, int nColor,const string & sEventString);//向战场中添加事件
    void PrintMoney();//报告生命元
    string GetColorStr();//获得阵营的颜色
    int GetColor();//获得阵营的颜色
    void LionRunaway();//狮子逃跑
	void Bomb();//使用炸弹
	void ShootArrow();//射箭攻击
	void WarriorBorn();//生产战士
	void AddToAwardList( CWarrior * pWarrior);//战争胜利添加到奖励列表
	void GiveAward();//给奖励
	void WarriorsMarch(int nEnemyHeadquterCityNo );//武士前进
	void WarriorsAttack();//武士攻击
	void WarriorsReport();//士兵公布武器,并删除死亡的武士
	void EnemyReach();//敌军到达阵营,有2个武士之后,占领
	void WarriorsGetFreeMoney(int);//某一时刻,city中没有敌人,直接获取生命元
	CWarrior * QueryCityWarrior( int nCityNo);//查询所在城市是否有敌人
	void EarnBloodMoney( CWarrior * p, int nCityNo);//战争胜利之后获得生命元
	void AddBloodMoney();
};

//城市类CCity
class CCity
{
private:
    int nFlagColor;//当前城市旗帜的颜色
    int nNo;//当前城市旗帜的编号
    int nLastWinWarriorColor;//最近一次胜利方的颜色
public:
    int nMoney;
    CCity();
    void SetNo(int nNo_);//设置城市的编号
    void AddMoney();//城市产生 生命元
    int MoneyTaken();//取走城市的金钱
    void SetFlagColor(int nColor);//设置城市的旗帜颜色
    int GetFlagColor();//获得该城市的旗帜颜色
    int GetTotalMoney();//获得城市的金钱数目
    bool CWarriorWin(int nColor);//返回是否需要更换旗子
    void WarDraw();//战争平局
};
//事件类CEvent
class CEvent
{
private:
    EEventType eEventType;//事件的类型
    int nTime;//事件发生的时间
    int nCityNo;//事件发生的城市
    int nColor;//红方还是蓝方
    string sDescribe;//事件的描述
public:
    CEvent(EEventType eEventType_,int nTime_,int nCity_,int nColor_,const string &s);
    void Output();//输出一个事件
    bool operator<(const CEvent &e2) const//排序事件
    {
        if(nTime<e2.nTime)//时间从小到大排序
            return true;
        else if(nTime>e2.nTime)
            return false;


        if(eEventType == e2.eEventType && eEventType == EVENT_WARRIOR_REPORT)//报告武器情况时,单独处理
        {
            if(nColor < e2.nColor)
                return true;
            else if(nColor == e2.nColor)
                return nCityNo<e2.nCityNo;
            else
                return false;
        }

        if(nCityNo < e2.nCityNo)//然后按照城市的编号从小到大
            return true;
        else if(nCityNo > e2.nCityNo)
            return false;

        if(eEventType < e2.eEventType)//事件发生的时间相同,城市相同
            return true;
        else if(eEventType > e2.eEventType)
            return false;

        if(nColor<e2.nColor)
            return true;
        else
            return false;
    }
};


//class CKingdom
class CKingdom
{
    friend class CHeadquarter;
private:
    CHeadquarter Red,Blue;//红蓝双方
    int nTimeInMinutes;//当前运行到的时间
    vector<CEvent> vEvent;//所有的事件
    vector<CCity> vCity;//所有的城市
    int nEndTime;//终止时间
    int nCityNum;//城市的数目
public:
    CKingdom(int nCityNum_,int nInitMoney);//构造函数
    void Run(int T);//时间计时,事件发生
    int TimePass(int nMinutes) ;//每一个时刻可能发生的时间
    string SystemTimeStr();//返回当前的规范的时间
    void WarDraw( int nCityNo);//战斗平局,战场类处理--》调用CCity类中的函数
    void KWarriorWin( CWarrior * pWarrior);//战争胜利
    int GetTime();//获得时间
	void WarEnd();//战争结束
	void OutputResult();//输出结果
	void AddEvent( EEventType eType, int nCityNo, int nColor, const string & sEventString);//添加事件
	int GetCityFlagColor( int nCityNo);//返回城市旗帜颜色
	int QueryCityMoney( int nNo);//返回该城市的生命元
	void TakeCityMoney( int nNo);//取走生命元
};



//CCity function
CCity::CCity():nFlagColor(COLOR_NONE),nMoney(0),nLastWinWarriorColor(COLOR_NONE){}
void CCity::SetNo(int nNo_)
{
    nNo = nNo_;
}
void CCity::AddMoney()
{
    nMoney += 10;
}
int CCity::MoneyTaken()
{
    int nTemp = nMoney;
    nMoney = 0;
    return nTemp;
}
void CCity::SetFlagColor(int nColor)
{
    nFlagColor = nColor;
}
int CCity::GetFlagColor()
{
    return nFlagColor;
}
int CCity::GetTotalMoney()
{
    return nMoney;
}
bool CCity::CWarriorWin(int nColor)
{
    if(nColor == nLastWinWarriorColor)
    {
        if(nFlagColor != nColor)
        {
            SetFlagColor(nColor);
            return true;
        }
        else
            return false;
    }
    nLastWinWarriorColor = nColor;
    return false;
}
void CCity::WarDraw()
{
    nLastWinWarriorColor = COLOR_NONE;
}

//CEvetn function
CEvent::CEvent(EEventType eEventType_,int nTime_,int nCityNo_,int nColor_,const string &s):
    eEventType(eEventType_),nTime(nTime_),nCityNo(nCityNo_),nColor(nColor_),sDescribe(s){}
void CEvent::Output()
{
    char szTime[20];
    sprintf(szTime,"%03d:%02d",nTime/60,nTime%60);
    cout<<szTime<<" "<<sDescribe<<endl;
}


//CWarrior function
CWarrior::CWarrior(int nId_,int nStrength_,int nForce_,int nCityNo_,CHeadquarter* pHeadquarter_):
    nId(nId_),nStrength(nStrength_),nForce(nForce_),nCityNo(nCityNo_),bShotToDeath(false),
    pHeadquarter(pHeadquarter_){}

CWarrior::~CWarrior(){}
bool CWarrior::Runaway() { return false; }
bool CWarrior::HasBomb() { return false; }
int CWarrior::GetSwordForce() { return 0;}
int CWarrior::UseSword(){ return 0; }
void CWarrior::AddMorale(double a) { };
void CWarrior::EarnWeapons( CWarrior * pEnemy) { }
string CWarrior::ReportWeapons() { return "";}
bool CWarrior::VirtualAttack(CWarrior *pEnemy)
{
    if(nStrength>0 && nForce + GetSwordForce() >= pEnemy->nStrength)
        return true;
    else
        return false;
}
bool CWarrior::VirtualFightback(CWarrior* pEnemy)
{
    if(nStrength>0 && nForce/2 + GetStrength() >= pEnemy->nStrength)
        return true;
    else
        return false;
}
int CWarrior::AttackedByArrow(int nArrowForce)
{
		nStrength -= nArrowForce;
		if( nStrength <= 0 ) {
			nStrength = 0;
			bShotToDeath = true;
		}
		return nStrength;
}
int CWarrior::Attack(CWarrior* pEnemy)
{
    if(pEnemy->GetStrength()<=0)
    {
        return 1;
    }

    char szTmp[200];
    sprintf(szTmp," with %d elements and force %d",nStrength,nForce);
    string sEventString = GetName() + "attacked " + pEnemy->GetName() + string(" in city ") + MyIntToStr(nCityNo) + szTmp;
    pHeadquarter->AddEvent(EVENT_ATTACK,nCityNo,GetColor(),sEventString);

    if(pEnemy->HurtedBy(this)<=0)
        return 1;
    if(nStrength<=0)
    {
        Killed();//判断死亡
        return -1;
    }
    return 0;
}
int CWarrior::HurtedBy(CWarrior* pEnemy)
{
    int nSwordForce = pEnemy->UseSword();
    nStrength -= pEnemy->GetForce() + nSwordForce;
    if(nStrength<=0)
    {
        Killed();//判断死亡
        return -1;
    }
    else
    {
        //此处可以调整一下
        string sEventString = GetName() + " fought back against " + pEnemy->GetName() + " in city " + MyIntToStr(nCityNo);
        pHeadquarter->AddEvent(EVENT_FIGHTBACK,nCityNo,GetColor(),sEventString);
        FightBack(pEnemy);
        return nStrength;
    }
}
void CWarrior::FightBack(CWarrior* pEnemy)
{
    int nSwordForce = UseSword();
    pEnemy->nStrength -= nForce/2 + nSwordForce;//反击的时候不会判断是否死亡
}
void CWarrior::Killed()
{
    string sEventString = GetName() + " was killed in city " + MyIntToStr(nCityNo);
    pHeadquarter->AddEvent(EVENT_KILLED,nCityNo,GetColor(),sEventString);
}
void CWarrior::March()
{
    if(GetColor() == COLOR_RED)
        nCityNo++;
    else
        nCityNo--;
}
int CWarrior::GetColor()
{
    return pHeadquarter->GetColor();
}
string CWarrior::GetColorStr()
{
    return pHeadquarter->GetColorStr();
}
int CWarrior::GetStrength()
{
    return nStrength;
}
int CWarrior::GetForce()
{
    return nForce;
}
void CWarrior::SetStrength(int n)
{
    nStrength = n;
}
void CWarrior::SetForce(int n)
{
    nForce = n;
}
int CWarrior::GetPosition()
{
    return nCityNo;
}
int CWarrior::ShootArrow()
{
    return 0;
}
//CWeaponWarrior function
CWeaponWarrior::CWeaponWarrior(int nId_,int nStrength_,int nForce_,int nCityNo_,CHeadquarter* pHeadquarter_,int nWeaponNum):
        CWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_),vwp(nWeaponNum)
        {
        }
bool CWeaponWarrior::HasBomb()
{
    for(int i = 0;i<vwp.size();i++)
    {
        if(vwp[i].nKindNo == WEAPON_BOMB)
            return true;
    }
    return false;
}
int CWeaponWarrior::GetSwordForce()
{
    for(int i = 0;i<vwp.size();i++)
    {
        if(vwp[i].nKindNo == WEAPON_SWORD)
            return vwp[i].nForce;
    }
    return 0;
}
int CWeaponWarrior::UseSword()
{
    for(int i = 0;i<vwp.size();i++)
    {
        if(vwp[i].nKindNo == WEAPON_SWORD)
        {
            int nTmp = vwp[i].nForce;
            vwp[i].nForce *= 0.8;
            if(vwp[i].nForce == 0)
                vwp.erase(vwp.begin() + i);
            return nTmp;
        }
    }
    return 0;
}
int CWeaponWarrior::ShootArrow()
{
    for(int i = 0;i<vwp.size();i++)//?????????????????????????????????????????
    {
        if(vwp[i].nKindNo == WEAPON_ARROW)
        {
            vwp[i].nForce--;
            if(vwp[i].nForce == 0)
                vwp.erase(vwp.begin() + i);
            return CWeapon::nArrowForce;
        }
    }
    return 0;
}
string CWeaponWarrior::ReportWeapons()
{
    if(vwp.size() == 0)
        return "";
    string rs = " has ";
    sort(vwp.begin(),vwp.end());
    bool bFirst = true;
    for(int i = 0;i<vwp.size();i++)
    {
        if(!bFirst)
            rs+=",";
        else
            bFirst = false;

        rs+=CWeapon::Names[vwp[i].nKindNo];
        if(vwp[i].nKindNo != WEAPON_BOMB)
            rs+=string("(") + MyIntToStr(vwp[i].nForce) + string(")");
    }
    return rs;
}
//CDragon function
CDragon::CDragon(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
	CWeaponWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_,1)
{
	vwp[0].nKindNo = nId_%WEAPON_NUM;
	if(vwp[0].nKindNo == WEAPON_SWORD)
    {
        vwp[0].nForce == nForce_*0.2;
        if(vwp[0].nForce == 0)
            vwp.clear();
    }
    else if(vwp[0].nKindNo == WEAPON_ARROW)
        vwp[0].nForce = 3;
    fMorale = pHeadquarter->nMoney/(double)CWarrior::InitialLifeValue[0];
}
int CDragon::Attack( CWarrior * p)
{
	int nRetVal = CWarrior::Attack(p);

	if( nRetVal != -1 && fMorale > 0.8) { //没有战死
		string sEventString = GetName() + " yelled in city " + MyIntToStr(nCityNo);
		pHeadquarter->AddEvent( EVENT_YELL, nCityNo, GetColor(), sEventString);
		if( nRetVal == 0) //平局
			fMorale -= 0.2;
		else
			fMorale += 0.2;
	}
	return nRetVal;
}
void CDragon::FightBack(CWarrior * pEnemy)
{
	CWarrior::FightBack (pEnemy);
	if( pEnemy->GetStrength() > 0 )
		fMorale -= 0.2;
	else
		fMorale += 0.2;
}

void CDragon::AddMorale(double a)
{
    fMorale += a;
};
string CDragon::GetName()
{
	return pHeadquarter->GetColorStr() + " dragon " + MyIntToStr(nId);
}
//CNinja function
CNinja::CNinja(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
		CWeaponWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_,2)
{
    bool bDeleteSword = false;
    vector<CWeapon>::iterator p;
    for( int i = 0;i < 2;i ++) {
        vwp[i].nKindNo =( nId_ + i )% WEAPON_NUM;
        if( vwp[i].nKindNo == WEAPON_SWORD ) {
            vwp[i].nForce = nForce_ * 0.2;
            if(vwp[i].nForce == 0) {
                bDeleteSword = true;
                p = vwp.begin() + i;
            }
        }
        else if( vwp[i].nKindNo == WEAPON_ARROW )
            vwp[i].nForce = 3;
    }
    if( bDeleteSword)//只可能有一件sword
        vwp.erase (p);
}
int CNinja::HurtedBy(CWarrior * pEnemy)
{
	int nSwordForce = pEnemy->UseSword();
	nStrength -= pEnemy->GetForce() + nSwordForce;
	if( nStrength <= 0 ) {
		Killed();
		return -1;
	}

	return nStrength;
}
bool CNinja::VirtualFightback( CWarrior * pEnemy)
{
    return false;
}
string CNinja::GetName()
{
	return pHeadquarter->GetColorStr() + " ninja " + MyIntToStr(nId);
}
//CIceman function
CIceman::CIceman(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
		CWeaponWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_,1),nSteps(0)
	{
		vwp[0].nKindNo = nId % WEAPON_NUM;
		if( vwp[0].nKindNo == WEAPON_SWORD ) {
			vwp[0].nForce = nForce_ * 0.2;
			if(  vwp[0].nForce == 0)
				vwp.clear();
		}
		else if( vwp[0].nKindNo == WEAPON_ARROW )
			vwp[0].nForce = 3;
	}
void CIceman::March()
{
	CWarrior::March();
	nSteps = ( nSteps + 1 ) %2;
	if( nSteps ==  0) {
		if( nStrength - 9 > 1 )
			nStrength -= 9;
		else
			nStrength = 1;
		nForce += 20;
	}
}
string CIceman::GetName()
{
	return pHeadquarter->GetColorStr() + " iceman " + MyIntToStr(nId);
}
//CLion function
CLion::CLion(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):CWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_)
{
    //???????????????pHeadquarter_->nMoney;
    nLoyalty = pHeadquarter->nMoney;
}
int CLion::Attack(CWarrior *pEnemy)
{
    int nTmp = nStrength;
    int nRetVal = CWarrior::Attack(pEnemy);
    if(nRetVal == -1)
        pEnemy->SetStrength(pEnemy->GetStrength() + nTmp);
    else if(nRetVal != 1)
        nLoyalty-=CLion::nLoyaltyDec;
    return nRetVal;
}
int CLion::HurtedBy(CWarrior * pEnemy)
{
    int nSwordForce = pEnemy->UseSword();
	if( nStrength - pEnemy->GetForce() - nSwordForce <= 0 ) {
		pEnemy->SetStrength( pEnemy->GetStrength() + nStrength );
		nStrength = 0;
		Killed();
		return -1;
	}
	nStrength -= pEnemy->GetForce() + nSwordForce;
	string sEventString = GetName() + " fought back against " + pEnemy->GetName() + " in city "  + MyIntToStr(nCityNo);
	FightBack(pEnemy);
	pHeadquarter->AddEvent(EVENT_FIGHTBACK,nCityNo, GetColor(),sEventString);
	return nStrength;
}
void CLion::FightBack(CWarrior * pEnemy)
{
    CWarrior::FightBack(pEnemy);
    if(pEnemy->GetStrength()>0)
        nLoyalty -= CLion::nLoyaltyDec;
}
bool CLion::Runaway ()
{
    return nLoyalty <= 0;
}
string CLion::GetName()
{
	return pHeadquarter->GetColorStr() + " lion " + MyIntToStr(nId);
}
//CWolf function
CWolf::CWolf(int nId_,int nStrength_,int nForce_,int nCityNo_, CHeadquarter * pHeadquarter_):
    CWeaponWarrior(nId_,nStrength_,nForce_,nCityNo_,pHeadquarter_,0),nEnemyKilled(0)
    {

    }
int CWolf::Attack( CWarrior * pEnemy)
{
    /*
	int nEnemyStrength = pEnemy->GetStrength();
	int nOriStrength = nStrength;
	*/
	int nRetVal = CWarrior::Attack(pEnemy);
	if( nRetVal > 0 )   //杀死敌人
		EarnWeapons( pEnemy);
	return nRetVal;
}
void CWolf::EarnWeapons( CWarrior * pEnemy)
{
    int i,j;
    if(pEnemy->ReportWeapons() != "")
    {
        CWeaponWarrior* p = (CWeaponWarrior*)pEnemy;
        for(i = 0;i<p->vwp.size();i++)
        {
            bool bAlreadyHas = false;
            for(j = 0;j<vwp.size();j++)
            {
                if(p->vwp[i].nKindNo == vwp[j].nKindNo)
                {
                    bAlreadyHas = true;
                    break;
                }
            }
            if(!bAlreadyHas)
                vwp.push_back(p->vwp[i]);
        }
    }
}
string CWolf::GetName()
{
	return pHeadquarter->GetColorStr() + " wolf " + MyIntToStr(nId);
}
//CHeadquarter function
CHeadquarter::CHeadquarter(int nColor_, int nMoney_,int nCityNo_ ) : nBloodMoney(0),nMoney(nMoney_), nEnemys(0),
    nWarriorNo(1),nColor(nColor_),nCityNo(nCityNo_)
{
}
CHeadquarter::~CHeadquarter()
{
    list<CWarrior*> ::iterator p;
    for( p = lstWarrior.begin(); p != lstWarrior.end(); p ++ )
        delete (* p);
    lstWarrior.clear();
}
void CHeadquarter::SetEnemy( CHeadquarter * p)
{
    pEnemyheadquarter = p;
}
void CHeadquarter::SetKingdom( CKingdom * p)
{
    pKingdom = p;
}
void CHeadquarter::AddEvent( EEventType eType, int nCityNo, int nColor, const string & sEventString)
{
	pKingdom->AddEvent( eType,nCityNo,nColor,sEventString);
}
void CHeadquarter::PrintMoney()
{
    char szTmp[100];

    sprintf(szTmp,"%d",nMoney);
    string sEventString = string(szTmp) + " elements in " + GetColorStr() + " headquarter";
    if( nColor == COLOR_RED)
        pKingdom->AddEvent( EVENT_PRINTMONEY, 0, nColor,sEventString);
    else
        pKingdom->AddEvent( EVENT_PRINTMONEY, pKingdom->vCity.size() + 1, nColor,sEventString);
}
string CHeadquarter::GetColorStr()
{
    if( nColor == COLOR_RED)
			return "red";
    else
        return "blue";
}
int CHeadquarter::GetColor()
{
    return nColor;
}
void CHeadquarter::LionRunaway()
{
	string sEventString;
	list<CWarrior * >::iterator i = lstWarrior.begin();
	while(i != lstWarrior.end() ) {
		if( (*i)->Runaway()) {
			int nCityNo = ( * i )->GetPosition();
			if( nColor == COLOR_RED &&  nCityNo == pKingdom->nCityNum + 1 ||
				nColor == COLOR_BLUE &&  nCityNo == 0 )
				continue;
			sEventString = (*i)->GetName() + " ran away";
			AddEvent( EVENT_LION_RUN, ( * i )-> nCityNo, nColor,sEventString);
			i = lstWarrior.erase (i); //指向被erased的元素的后一个
			continue;
		}
		i++;
	}
}
void CHeadquarter::Bomb()
{
	list<CWarrior * >::iterator i = lstWarrior.begin();
	while( i != lstWarrior.end() ) {
		int nCityNo = ( * i )->GetPosition();
		if( (*i)->GetStrength () > 0 ) {
			CWarrior * p = pEnemyheadquarter->QueryCityWarrior(nCityNo);
			if( p ) {
				bool bShouldAttack = false;
				if( pKingdom->GetCityFlagColor(nCityNo) == nColor )
					bShouldAttack = true;
				else if( pKingdom->GetCityFlagColor(nCityNo) == COLOR_NONE) {
					if( nColor == COLOR_RED && (nCityNo % 2 == 1))
						bShouldAttack = true;
					if( nColor == COLOR_BLUE && (nCityNo % 2 == 0))
						bShouldAttack = true;
				}
				bool r1 = false ,r2 = false;
				if( ( * i )->HasBomb()) {
					if( bShouldAttack) {
						if( (*i)->VirtualAttack(p) == false)
							r1 = p->VirtualFightback(*i);
						else
							r1 = false;
					}
					else
						r2 = p->VirtualAttack(*i);
					if( r1  || r2  ) {
						string sEventString = (*i)->GetName() + " used a bomb and killed " +
							p->GetName();
						AddEvent( EVENT_BOMB, nCityNo, GetColor(), sEventString);
						i = lstWarrior.erase (i); //指向被erased的元素的后一个
						p->SetStrength(0);
						continue;
					}
				}
			}
		}
		i ++;
	}
}
void CHeadquarter::ShootArrow()
{
	list<CWarrior * >::iterator i;
	for( i = lstWarrior.begin();i != lstWarrior.end();i ++ ) {
		int nCityNo = ( * i )->GetPosition();
		if( nColor == COLOR_RED ) {
			nCityNo ++;
			if( nCityNo == pKingdom->nCityNum + 1 )
				continue ;
		}
		else {
			nCityNo --;
			if( nCityNo == 0)
				continue;
		}
		CWarrior * p = pEnemyheadquarter->QueryCityWarrior(nCityNo);
		if( p ) {
			int nArrowForce = (*i)->ShootArrow();
			if( nArrowForce > 0) {
				string sEventString = (*i)->GetName() + " shot";
				if( p->AttackedByArrow(nArrowForce) <= 0 )
					sEventString += " and killed " + p->GetName();
				AddEvent( EVENT_ARROW,( * i )->GetPosition(), GetColor(), sEventString);
			}
		}
	}

}
void CHeadquarter::EnemyReach()
{
	nEnemys ++;
	if( nEnemys == 2 ) {
		if( nColor == COLOR_RED )
			AddEvent( EVENT_CITYTAKEN, nCityNo,	nColor,string("red headquarter was taken"));
		else
			AddEvent( EVENT_CITYTAKEN, nCityNo, nColor,string("blue headquarter was taken"));
		pKingdom->WarEnd();
	}
}
CWarrior * CHeadquarter::QueryCityWarrior( int nCityNo)
{
	list<CWarrior *>::iterator i;
	for( i = lstWarrior.begin();i != lstWarrior.end();i ++ ) {
		if( (* i )->GetPosition () == nCityNo)
			return ( * i );
	}
	return NULL;
}
void CHeadquarter::AddBloodMoney()
{
    nMoney += nBloodMoney;
    nBloodMoney = 0;
}
void CHeadquarter::WarriorsGetFreeMoney(int nEnemyheadquarterNo )
{
    //武士拿城市里的钱,在没有发生战斗的情况下
	list<CWarrior*>::iterator i;
	for( i = lstWarrior.begin(); i !=  lstWarrior.end();i ++ ) {
		int nCityno = ( * i )->GetPosition();
		if( nCityno != 0 && nCityno != nEnemyheadquarterNo) {
			CWarrior * p ;
			p = pEnemyheadquarter->QueryCityWarrior(nCityno);
			if( p == NULL ) {
				int nMoneyEarned;
				nMoneyEarned = pKingdom->QueryCityMoney(nCityno);
				if( nMoneyEarned > 0 ) {
					nMoney += nMoneyEarned;
					pKingdom->TakeCityMoney(nCityno);
					string sEventString = (*i)->GetName() + " earned " + MyIntToStr(nMoneyEarned) + " elements for his headquarter";
					AddEvent( EVENT_EARNMONEY, nCityno,nColor, sEventString);
				}
			}
		}
	}
}
void CHeadquarter::WarriorsMarch(int nEnemyHeadquterCityNo)
{
	list<CWarrior * >::iterator i;
	string sEventString;
	for( i = lstWarrior.begin();i != lstWarrior.end();i ++ ) {
		int nOldPos = ( * i ) ->nCityNo ;
		if( nColor == COLOR_RED ) {
			if( ( * i )-> nCityNo < nEnemyHeadquterCityNo)
				( *i )->March();
		}
		else {
			if( ( * i )-> nCityNo > nEnemyHeadquterCityNo)
				( *i )->March();
		}
		char szTmp[100];
		sprintf( szTmp," with %d elements and force %d",(*i)->nStrength,(*i)->nForce);

		if( nOldPos != nEnemyHeadquterCityNo) {
			if (( * i )-> nCityNo == nEnemyHeadquterCityNo ) {
				sEventString = (*i)->GetName() + " reached "+  pEnemyheadquarter->GetColorStr() + " headquarter" + szTmp;
				AddEvent( EVENT_REACH, ( * i )-> nCityNo, nColor,sEventString);
				pEnemyheadquarter->EnemyReach();
			}
			else {
				sEventString = (*i)->GetName() + " marched to city " + MyIntToStr(( * i )->GetPosition() ) + szTmp;
				AddEvent( EVENT_MARCH, ( * i )->GetPosition(), nColor,sEventString);
			}
		}
	}
}
void CHeadquarter::WarriorsAttack()
	{
	list<CWarrior * >::iterator i = lstWarrior.begin();
	for( i; i != lstWarrior.end();i ++) {
		if( (*i)->nStrength <= 0) //5分钟前已经被射杀
			continue;
		int nCityNo = ( * i )->GetPosition();
		if( nCityNo == 13 )
			cout << "";
		CWarrior * p = pEnemyheadquarter->QueryCityWarrior(nCityNo);
		if( p ) {
			bool bShouldAttack = false;
			if( pKingdom->GetCityFlagColor(nCityNo) == nColor )
				bShouldAttack = true;
			else if( pKingdom->GetCityFlagColor(nCityNo) == COLOR_NONE) {
				if( nColor == COLOR_RED && (nCityNo % 2 == 1))
					bShouldAttack = true;
				if( nColor == COLOR_BLUE && (nCityNo % 2 == 0))
					bShouldAttack = true;
			}
			if( bShouldAttack && ( p->GetStrength () > 0 || p->bShotToDeath )) {
				int nResult = ( * i )->Attack (p);
					if( nResult == 1 ) { //杀死敌人
					AddToAwardList(*i);
					pKingdom->KWarriorWin( * i ) ; //让kingdom处理城市变旗帜的事情
					EarnBloodMoney( (*i), nCityNo);
				}
				else if( nResult < 0 ) { //被敌人反击时杀死
					pEnemyheadquarter->AddToAwardList(p);
					pKingdom->KWarriorWin(p); //让kingdom处理城市变旗帜的事情
					pEnemyheadquarter->EarnBloodMoney(p,nCityNo);
					/*
					i = lstWarrior.erase (i); //指向被erased的元素的后一个
					continue;
					erase 统一在report时完成
					*/
				}
				else {
					pKingdom->WarDraw(nCityNo);
				}
			}
			else { //如果不是主动进攻,但是敌人已经被箭射杀,那么还算发生了战斗,而且会影响Dragon的fMorale
					//还会影响Wolf缴获武器
				if( p->bShotToDeath ) { //5分钟前被箭射杀
					AddToAwardList(*i);
					pKingdom->KWarriorWin( * i ) ; //让kingdom处理城市变旗帜的事情
					EarnBloodMoney( (*i), nCityNo);
					(*i) -> AddMorale(0.2);
					(*i) -> EarnWeapons(p);
				}
			}
		}
	}
}
void CHeadquarter::EarnBloodMoney( CWarrior * p, int nCityNo)
{
//获取杀死敌人以后的城市中的生命元
	int nMoneyEarned;
	nMoneyEarned = pKingdom->QueryCityMoney(nCityNo);
	if( nMoneyEarned > 0 ) {
		nBloodMoney += nMoneyEarned;
		pKingdom->TakeCityMoney(nCityNo);
		string sEventString = p->GetName() + " earned " + MyIntToStr(nMoneyEarned) + " elements for his headquarter";
		AddEvent( EVENT_EARNMONEY, nCityNo,nColor, sEventString);
	}
}
void CHeadquarter::AddToAwardList( CWarrior * pWarrior)
{
	vAwardList.push_back(pWarrior);
}

void CHeadquarter::GiveAward()
{

	int nSize = vAwardList.size();
	sort(vAwardList.begin(), vAwardList.end(),MyCompare);
	for( int i = 0;i < vAwardList.size();i ++ ) {
		if( nMoney >= 8 ) {
			vAwardList[i]->nStrength += 8;
			nMoney -= 8;
		}
		else
			break;
	}
	vAwardList.clear();
}
void CHeadquarter::WarriorsReport()
{
	list<CWarrior * >::iterator i = lstWarrior.begin();
	string sEventString;
	while(i != lstWarrior.end()) {
		if( (*i)->nStrength <= 0) { //在35分,或刚才的战斗中已经被杀了
			i = lstWarrior.erase (i);
			continue;
		}
		string sEventString = (*i)->GetName();
		string sWeaponStatus = (*i)->ReportWeapons();
		if( sWeaponStatus != "")
			sEventString += sWeaponStatus;
		else
			sEventString += " has no weapon";
		AddEvent( EVENT_WARRIOR_REPORT, ( * i )-> nCityNo, nColor,sEventString );
		i ++;
	}
}
void CHeadquarter::WarriorBorn()
{

	CWarrior * p = NULL;
	int nSeqIdx = (nWarriorNo - 1) % 5;
	if( nMoney <  CWarrior::InitialLifeValue[MakingSeq[nColor][nSeqIdx]])
		return ;
	nMoney -= CWarrior::InitialLifeValue[MakingSeq[nColor][nSeqIdx]];
	int nKindNo = MakingSeq[nColor][nSeqIdx];

	switch( nKindNo ) {
		case DRAGON:
			p = new CDragon(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitialForce[nKindNo],nCityNo, this);
			break;
		case NINJA:
			p = new CNinja(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitialForce[nKindNo],nCityNo, this);
			break;
		case ICEMAN:
			p = new CIceman(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitialForce[nKindNo],nCityNo, this);
			break;
		case LION:
			p = new CLion(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitialForce[nKindNo],nCityNo, this);
			break;
		case WOLF:
			p = new CWolf(nWarriorNo,CWarrior::InitialLifeValue[nKindNo],CWarrior::InitialForce[nKindNo],nCityNo, this);
			break;
	}

	lstWarrior.push_back(p);
	string sEventString = p->GetName () + " born";
	if( nKindNo == LION )
		sEventString += "\nIts loyalty is " + MyIntToStr(((CLion*)p)->nLoyalty);
	else if( nKindNo == DRAGON) {
		char szTmp[40];
		//old sprintf(szTmp,"%.2f",((CDragon*)p)->fMorale + EPS);
		sprintf(szTmp,"%.2f",((CDragon*)p)->fMorale );
		sEventString += "\nIts morale is " +string(szTmp);
	}

	pKingdom->AddEvent( EVENT_BORN, nCityNo, nColor,sEventString);
	nWarriorNo ++;
}
//CKingdom function
CKingdom::CKingdom(int nCityNum_,int nInitMoney):
		nTimeInMinutes(0),Red(COLOR_RED,nInitMoney,0),Blue(COLOR_BLUE,nInitMoney,nCityNum_ + 1),
			nCityNum(nCityNum_), vCity(nCityNum_ + 1)
	{
		for( int i = 1; i <= nCityNum;i ++ )
			vCity[i].SetNo(i);
		Red.SetKingdom(this);
		Red.SetEnemy( &Blue);
		Blue.SetKingdom(this);
		Blue.SetEnemy( &Red);
		nEndTime = 3000000;
	}
void CKingdom::Run(int T) {
		for( int t = 0; t <= T; t ++ ) { //modifor 2010 old: t < T
			if( TimePass(t) == 0)
				return ;
		}
	}
int CKingdom::TimePass(int nMinutes) {
	int i;
	nTimeInMinutes = nMinutes;
	if( nTimeInMinutes > nEndTime )
		return 0;
	int nRemain = nTimeInMinutes % 60;
	switch( nRemain) {
		case 0: //生产怪物
			Red.WarriorBorn();
			Blue.WarriorBorn();
			break;
		case 5: //lion可能逃跑
			Red.LionRunaway();
			Blue.LionRunaway();
			break;
		case 10: //前进
			Red.WarriorsMarch(nCityNum + 1);
			Blue.WarriorsMarch(0);
			break;
		case 20: //城市出产生命元

			for( i = 0;i < vCity.size();i ++ ) {
				vCity[i].AddMoney();
			}
			break;
		case 30: //挣钱
			Red.WarriorsGetFreeMoney(nCityNum+1);
			Blue.WarriorsGetFreeMoney(nCityNum+1);

			break;
		case 35: //放箭
			Red.ShootArrow();
			Blue.ShootArrow();
			break;
		case 38:
			Red.Bomb();
			Blue.Bomb();
			break;
		case 40://发生战斗
			//addfor debug cccc
			if( nTimeInMinutes == 1720 )
				cout << "" ;
			//gwend

			Red.WarriorsAttack();
			Blue.WarriorsAttack();
			Red.GiveAward();
			Blue.GiveAward();
			Red.AddBloodMoney();
			Blue.AddBloodMoney();
			break;
		case 50:
			Red.PrintMoney(); //addfor 2010
			Blue.PrintMoney(); //addfor 2010
			break;
		case 55:
			Red.WarriorsReport();
			Blue.WarriorsReport();
	}
	return 1;
}
string CKingdom::SystemTimeStr()
{
    char szTime[20];
    sprintf(szTime,"%03d:%02d",nTimeInMinutes /60, nTimeInMinutes % 60);
    return szTime;
}
void CKingdom::WarDraw( int nCityNo)
	{
		vCity[nCityNo].WarDraw();
	}
void CKingdom::KWarriorWin( CWarrior * pWarrior)
	{
		int nCityNo = pWarrior->GetPosition();
		if( vCity[nCityNo].CWarriorWin( pWarrior->GetColor()) == true ) {
			//addfor 2010 要判断是否已经有同颜色的旗子,有则不升旗

			string sEventString = pWarrior->GetColorStr() + " flag raised in city " + MyIntToStr( nCityNo);
			AddEvent(EVENT_FLAG, nCityNo, pWarrior->GetColor(),sEventString);
		}
	}
int CKingdom::GetTime()
	{
		return nTimeInMinutes;
	}
void CKingdom::WarEnd()
	{
		if( nEndTime == 3000000)
			nEndTime = nTimeInMinutes;
	}
void CKingdom::OutputResult()
	{
		sort(vEvent.begin(),vEvent.end());
		for( int i = 0;i < vEvent.size();i ++ )
			vEvent[i].Output();
	}
void CKingdom::AddEvent( EEventType eType, int nCityNo,int nColor, const string & sEventString)
{
	CEvent tmp(eType, nTimeInMinutes, nCityNo,nColor,sEventString);
	vEvent.push_back(tmp);
}
int CKingdom::GetCityFlagColor( int nCityNo)
	{
		return vCity[nCityNo].GetFlagColor();
	}
int CKingdom::QueryCityMoney( int nNo)
{
    return vCity[nNo].GetTotalMoney();
}
void CKingdom::TakeCityMoney( int nNo)
{
	vCity[nNo].MoneyTaken();
}


//CWeapon中的static声明
const char* CWeapon::Names[WEAPON_NUM] = {"sword","bomb","arrow"};
int CWeapon::nArrowForce;
//CWarrior中的static声明
int CWarrior::InitialForce[WARRIOR_NUM];
int CWarrior::InitialLifeValue[WARRIOR_NUM];
const char* CWarrior::Names[WARRIOR_NUM] = {"dragon","ninja","iceman","lion","wolf"};
//Clion中的static声明
int CLion::nLoyaltyDec;
//CHeadquarter中的static声明
int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} };

int main()
{
    int nCases;
	int M,N,R,K,T;
	cin >> nCases;
	int nCaseNo = 1;
	while( nCases -- )  {
		cin >> M >> N >> R >> K >> T;
		CWeapon::nArrowForce = R;
		CLion::nLoyaltyDec = K;
		int i;
		for( i = 0;i < WARRIOR_NUM;i ++ )
			cin >> CWarrior::InitialLifeValue[i];
		for( i = 0;i < WARRIOR_NUM;i ++ )
			cin >> CWarrior::InitialForce[i];
		CKingdom MyKingdom(N,M);
		MyKingdom.Run(T);
		cout << "Case " << nCaseNo++ << ":" << endl;
		MyKingdom.OutputResult();
	}
    return 0;
}

你可能感兴趣的:(#,C++项目:魔兽世界)