/*
这里是从网上找的参考代码,有点迷迷糊糊的
*/
#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
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;
}
魔兽世界-开战
最新推荐文章于 2023-03-23 23:12:31 发布