【C++】附录:魔兽世界大作业

总述

        面向对象的程序设计方法,在编写大程序的时候,优势才能体现。要让初学者在实践中应用 C++ 的各种面向对象的特性,考虑如何设计多个类并且处理它们之间的关系,从而领悟到面向对象程序设计的优越性,掌握面向对象程序设计的基本思想,没有一个足够大的编程任务作为作业,是很困难的。然而,真正大一点有点工程实践感觉的程序,往往就会牵涉图形界面的设计,这
对 C++ 的初学者来说,是不可能完成的任务。所以,如何设计一个足够大、有意思,能充分体现面向对象程序设计方法相对结构化程序设计方法的优势,而且 C++ 的初学者有能力完成的大作业,是C++教学中需要解决的重要问题。

        为此,“魔兽世界” 系列作业应运而生。这个作业以游戏为背景,特别适合运用面向对象的程序设计方法,而且不牵涉图形界面的处理。该作业分 3 个阶段,每个阶段一个程序,由简单到复杂,循序渐进完成,逐步扩充。在完成作业的过程中能够体会到面向对象的程序设计方法在提高程序可扩充性方面的作用。第三阶段的程序一般需要编写千行左右,从规模来说已足够大。这样的程序确实需要用面向对象的程序设计方法来编写,否则不但在程序设计时思路难以理清。要修改时更是会非常麻烦。可以说起到了让完成者体会面向对象程序设计优势。掌握面向对象程序设计的基本思路的作用。

        这个作业的描述篇幅很长,而且如果没有测试数据,也没法完成。因此这里只介绍此作业的概貌,读者可以到 OpenJudge - OpenJudge 下载该作业的描述和测试数据。作业如下:

        魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两者之间是若干城市,如下所示:

红司令部City 1City2...City n蓝司令部

        两军的司令部都有些生命元,都会制造武士,制造武士需要消耗生命元。武士有不同种类,每个武士都有编号、生命值、攻击力、拥有的武器等这些属性。武器也有不同的种类,如弓箭、炸弹等,所起的作用也不同。

        在不同的时间点会发生不同的事件,例如在整点,双方司令部会有武土降生;每个小时的第 10 分钟,武士会向对方的司令部前进一步(即走到下一个城市);在每个小时第 20分钟,城市里面双方的武士会发生战斗;战斗结束后的某个时刻。战胜者会夺取战利品,以及获得司令部的奖励。等等。不同种武士在战斗中的行为有所不同;战斗有一定判断生死的规则;武器在战斗中的作用也有一定的规则。最终有一方的司令部被敌人占领,游戏就结束。作业的要求就是给一个时间段,要求按先后次序输出在这个时间段内发生的所有事件。每种事件都要求按一定的格式输出。下面就是三行可能的输出:

                000:00 blue lion 1 born.
                000:10 blue lion1 marched to city 1 with 10 elements and force 5.
                000:30 blue lion 1 earned 10 elements for his headquarter.


作业描述及测试数据

魔兽世界之一:备战        OpenJudge - 013:魔兽世界之一:备战

魔兽世界之二:装备        OpenJudge - 022:魔兽世界之二:装备

魔兽世界之三:开战        OpenJudge - 045:魔兽世界三(开战)


参考代码

魔兽世界之一:备战

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define WARRIOR_NUM 5
/*
char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
红方司令部按照 iceman、lion、wolf、ninja、dragon 的顺序制造武士。
蓝方司令部按照 lion、dragon、ninja、iceman、wolf 的顺序制造武士。
*/
class CHeadquarter;
class CWarrior
{
	private:
		CHeadquarter * pHeadquarter;
		int nKindNo; //武士的种类编号 0 dragon 1 ninja 2 iceman 3 lion 4 wolf
		int nNo;
	public:
		static char * Names[WARRIOR_NUM];
		static int InitialLifeValue [WARRIOR_NUM];
		CWarrior( CHeadquarter * p,int nNo_,int nKindNo_ );
		void PrintResult(int nTime);
};
class CHeadquarter
{
	private:
		int nTotalLifeValue;
		bool bStopped;
		int nTotalWarriorNum;
		int nColor;
		int nCurMakingSeqIdx; //当前要制造的武士是制造序列中的第几个
		int anWarriorNum[WARRIOR_NUM]; //存放每种武士的数量
		CWarrior * pWarriors[1000];
	public:
		friend class CWarrior;
		static int MakingSeq[2][WARRIOR_NUM]; //武士的制作顺序序列
		void Init(int nColor_, int lv);
		~CHeadquarter () ;
		int Produce(int nTime);
		void GetColor( char * szColor);
};
CWarrior::CWarrior( CHeadquarter * p,int nNo_,int nKindNo_ ) {
	nNo = nNo_;
	nKindNo = nKindNo_;
	pHeadquarter = p;
}
void CWarrior::PrintResult(int nTime)
{
	char szColor[20];
	pHeadquarter->GetColor(szColor);
	printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n" ,
	nTime, szColor, Names[nKindNo], nNo,
	InitialLifeValue[nKindNo],
	pHeadquarter->anWarriorNum[nKindNo],Names[nKindNo],szColor);
}
void CHeadquarter::Init(int nColor_, int lv)
{
	nColor = nColor_;
	nTotalLifeValue = lv;
	nTotalWarriorNum = 0;
	bStopped = false;
	nCurMakingSeqIdx = 0;
	for( int i = 0;i < WARRIOR_NUM;i ++ )
		anWarriorNum[i] = 0;
}
CHeadquarter::~CHeadquarter () {
	for( int i = 0;i < nTotalWarriorNum;i ++ )
	delete pWarriors[i];
}
int CHeadquarter::Produce(int nTime)
{
	if( bStopped )
	return 0;
	int nSearchingTimes = 0;
	while( CWarrior::InitialLifeValue[MakingSeq[nColor][nCurMakingSeqIdx]] >
	nTotalLifeValue &&
	nSearchingTimes < WARRIOR_NUM ) {
		nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
		nSearchingTimes ++;
	}
	int nKindNo = MakingSeq[nColor][nCurMakingSeqIdx];
	if( CWarrior::InitialLifeValue[nKindNo] > nTotalLifeValue ) {
		bStopped = true;
		if( nColor == 0)
			printf("%03d red headquarter stops making warriors\n",nTime);
		else
			printf("%03d blue headquarter stops making warriors\n",nTime);
	return 0;
	}
	nTotalLifeValue -= CWarrior::InitialLifeValue[nKindNo];
	nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
	pWarriors[nTotalWarriorNum] = new CWarrior( this,nTotalWarriorNum+1,nKindNo);
	anWarriorNum[nKindNo]++;
	pWarriors[nTotalWarriorNum]->PrintResult(nTime);
	nTotalWarriorNum ++;
	return 1;
}
void CHeadquarter::GetColor( char * szColor)
{
	if( nColor == 0)
		strcpy(szColor,"red");
	else
		strcpy(szColor,"blue");
}
char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
int CWarrior::InitialLifeValue [WARRIOR_NUM];
int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} }; //两个司令部武士的制作顺序序列
int main()
{
	int t;
	int m;
	CHeadquarter RedHead,BlueHead;
	scanf("%d",&t);
	int nCaseNo = 1;
	while ( t -- ) {
		printf("Case:%d\n",nCaseNo++);
		scanf("%d",&m);
		for( int i = 0;i < WARRIOR_NUM;i ++ )
			scanf("%d", & CWarrior::InitialLifeValue[i]);
		RedHead.Init(0,m);
		BlueHead.Init(1,m);
		int nTime = 0;
		while( true) {
			int tmp1 = RedHead.Produce(nTime);
			int tmp2 = BlueHead.Produce(nTime);
			if( tmp1 == 0 && tmp2 == 0)
				break;
			nTime ++;
		}
	}
	return 0;
}

魔兽世界之二:装备

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
//下面这些东西都是常量,而且不止一个类都要用到,就声明为全局的较为简单
#define WARRIOR_NUM 5 
#define WEAPON_NUM 3
enum { DRAGON,NINJA,ICEMAN,LION,WOLF };
/*
char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
红方司令部按照 iceman、lion、wolf、ninja、dragon 的顺序制造武士。
蓝方司令部按照 lion、dragon、ninja、iceman、wolf 的顺序制造武士。
*/
class CHeadquarter;
class CDragon;
class CNinja;
class CIceman;
class CLion;
class CWolf;
class CWeapon;
class CWarrior; 
class CWeapon
{
	public:
		int nKindNo;
		int nForce;
		static int InitialForce[WEAPON_NUM];
		static const char * Names[WEAPON_NUM];
};
class CWarrior
{
	protected:
		CHeadquarter * pHeadquarter;
		int nNo;
	public:
		static const char * Names[WARRIOR_NUM];
		static int InitialLifeValue [WARRIOR_NUM];
		CWarrior( CHeadquarter * p,int nNo_):
		pHeadquarter(p),nNo(nNo_) { }
		virtual void PrintResult(int nTime,int nKindNo); 
		virtual void PrintResult(int nTime) = 0;
		virtual ~CWarrior() { }
};
class CHeadquarter
{
	private:
		static const int MAX_WARRIORS = 1000;
		int nTotalLifeValue;
		bool bStopped;
		int nColor;
		int nCurMakingSeqIdx;
		int anWarriorNum[WARRIOR_NUM];
		int nTotalWarriorNum;
		CWarrior * pWarriors[MAX_WARRIORS];
	public:
		friend class CWarrior;
		static int MakingSeq[2][WARRIOR_NUM];
		void Init(int nColor_, int lv);
		~CHeadquarter () ;
		int Produce(int nTime);
		void GetColor( char * szColor);
		int GetTotalLifeValue() { return nTotalLifeValue; }
};
void CWarrior::PrintResult(int nTime,int nKindNo) 
{
	char szColor[20];
	pHeadquarter->GetColor(szColor);
	printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n" ,
	nTime, szColor, Names[nKindNo], nNo, InitialLifeValue[nKindNo],
	pHeadquarter->anWarriorNum[nKindNo],Names[nKindNo],szColor);
}
class CDragon:public CWarrior
{
	private:
		CWeapon wp;
		double fmorale;
	public:
		void Countmorale()
		{
			fmorale = pHeadquarter -> GetTotalLifeValue() /(double)CWarrior::InitialLifeValue [0];
		}
		CDragon( CHeadquarter * p,int nNo_):
		CWarrior(p,nNo_) { 
			wp.nKindNo = nNo % WEAPON_NUM;
			wp.nForce = CWeapon::InitialForce[wp.nKindNo ];
			Countmorale();
		}
		void PrintResult(int nTime) 
		{
			CWarrior::PrintResult(nTime,DRAGON);
			printf("It has a %s,and it's morale is %.2f\n", 
			CWeapon::Names[wp.nKindNo], fmorale);
		}
};
class CNinja:public CWarrior
{
	private:
		CWeapon wps[2];
	public:
		CNinja( CHeadquarter * p,int nNo_):
		CWarrior(p,nNo_) { 
			wps[0].nKindNo = nNo % WEAPON_NUM;
			wps[0].nForce = CWeapon::InitialForce[wps[0].nKindNo];
			wps[1].nKindNo = ( nNo + 1) % WEAPON_NUM;
			wps[1].nForce = CWeapon::InitialForce[wps[1].nKindNo];
		}
		void PrintResult(int nTime)
		{
			CWarrior::PrintResult(nTime,NINJA);
			printf("It has a %s and a %s\n", 
			CWeapon::Names[wps[0].nKindNo],
			CWeapon::Names[wps[1].nKindNo]);
		}
};
class CIceman:public CWarrior
{
	private:
		CWeapon wp;
	public:
		CIceman( CHeadquarter * p,int nNo_):
		CWarrior(p,nNo_) 
		{ 
			wp.nKindNo = nNo % WEAPON_NUM;
			wp.nForce = CWeapon::InitialForce[ wp.nKindNo ];
		}
		void PrintResult(int nTime) 
		{
			CWarrior::PrintResult(nTime,ICEMAN);
			printf("It has a %s\n", 
			CWeapon::Names[wp.nKindNo]);
		}
};
class CLion:public CWarrior
{
	private:
		int nLoyalty;
	public:
		void CountLoyalty()
		{
			nLoyalty = pHeadquarter ->GetTotalLifeValue();
		}
		CLion( CHeadquarter * p,int nNo_):CWarrior(p,nNo_) { 
			CountLoyalty();
		}
		void PrintResult(int nTime)
		{
			CWarrior::PrintResult(nTime,LION);
			CountLoyalty();
			printf("It's loyalty is %d\n",nLoyalty);
		}
};
class CWolf:public CWarrior
{
	public:
		CWolf( CHeadquarter * p,int nNo_):
		CWarrior(p,nNo_) { }
		void PrintResult(int nTime)
		{
			CWarrior::PrintResult(nTime,WOLF);
		}
};
void CHeadquarter::Init(int nColor_, int lv)
{
	nColor = nColor_;
	nTotalLifeValue = lv;
	bStopped = false;
	nCurMakingSeqIdx = 0;
	nTotalWarriorNum = 0;
	for( int i = 0;i < WARRIOR_NUM;i ++ )
		anWarriorNum[i] = 0;
}
CHeadquarter::~CHeadquarter () {
	int i;
	for( i = 0;i < nTotalWarriorNum; i ++ )
	delete pWarriors[i];
}
int CHeadquarter::Produce(int nTime)
{
	int nSearchingTimes = 0;
	if( bStopped )
		return 0;
	while( CWarrior::InitialLifeValue[MakingSeq[nColor][nCurMakingSeqIdx]] > nTotalLifeValue && 
	nSearchingTimes < WARRIOR_NUM ) {
		nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
		nSearchingTimes ++;
	}
	int nKindNo = MakingSeq[nColor][nCurMakingSeqIdx];
	if( CWarrior::InitialLifeValue[nKindNo] > nTotalLifeValue ) {
		bStopped = true;
		if( nColor == 0)
			printf("%03d red headquarter stops making warriors\n",nTime);
		else
			printf("%03d blue headquarter stops making warriors\n",nTime);
		return 0;
	}
	nTotalLifeValue -= CWarrior::InitialLifeValue[nKindNo];
	nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
	int nTmp = anWarriorNum[nKindNo]; 
	anWarriorNum[nKindNo] ++;
	switch( nKindNo ) {
		case DRAGON:
			pWarriors[nTotalWarriorNum] = new CDragon( this,nTotalWarriorNum+1);
			break;
		case NINJA:
			pWarriors[nTotalWarriorNum] = new CNinja( this,nTotalWarriorNum+1);
			break;
		case ICEMAN:
			pWarriors[nTotalWarriorNum] = new CIceman( this,nTotalWarriorNum+1);
			break;
		case LION:
			pWarriors[nTotalWarriorNum] = new CLion( this,nTotalWarriorNum+1);
			break;
		case WOLF:
			pWarriors[nTotalWarriorNum] = new CWolf( this,nTotalWarriorNum+1);
			break;
	}
	pWarriors[nTotalWarriorNum]->PrintResult(nTime);
	nTotalWarriorNum ++;
	return 1;
}
void CHeadquarter::GetColor( char * szColor)
{
	if( nColor == 0)
		strcpy(szColor,"red");
	else
		strcpy(szColor,"blue");
}
const char * CWeapon::Names[WEAPON_NUM] = {"sword","bomb","arrow" };
int CWeapon::InitialForce[WEAPON_NUM];
const char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
int CWarrior::InitialLifeValue [WARRIOR_NUM];
int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} };
int main()
{
	int t;
	int m;
	//freopen("war2.in","r",stdin);
	CHeadquarter RedHead,BlueHead;
	scanf("%d",&t);
	int nCaseNo = 1;
	while ( t -- ) {
		printf("Case:%d\n",nCaseNo++);
		scanf("%d",&m);
		int i;
		for(i = 0;i < WARRIOR_NUM;i ++ )
		scanf("%d", & CWarrior::InitialLifeValue[i]); 
		// for(i = 0;i < WEAPON_NUM;i ++ )
		// scanf("%d", & CWeapon::InitialForce[i]); 
		RedHead.Init(0,m);
		BlueHead.Init(1,m);
		int nTime = 0;
		while( true) {
			int tmp1 = RedHead.Produce(nTime); 
			int tmp2 = BlueHead.Produce(nTime);
			if( tmp1 == 0 && tmp2 == 0)
				break;
			nTime ++;
		}
	}
	return 0;
}

魔兽世界之三:开战 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>

const int WARRIOR_NUM = 5;//五种武士
const int WEAPON_NUM = 3;//三种武器
const int WEAPON_MAX = 10;//一个武士最多10把武器
enum {DRAGON, NINJA, ICEMAN, LION, WOLF};
enum {SWORD, BOMB, ARROW};

using namespace std;

class Headquarter;
class Dragon;
class Ninja;
class Iceman;
class Lion;
class Wolf;
class Warrior;
class City;

class Weapon
{
    protected:
        int WeaponKind;
        int WeaponForce;
        static char *WeaponName[WEAPON_NUM];
        Warrior *pWarrior;//该武器属于哪个武士
        bool Used; //为arrow准备的,标志arrow是否用过。
        Weapon(int kind, Warrior *p);
        friend int compareWeapon (const void *p, const void *q);//qsort函数的比较函数,用过的arrow排前面
        friend int compareWeapon2 (const void *p, const void *q);//qsort函数的比较函数,没用过的arrow排前面
        friend class Warrior;
        friend class Dragon;
        friend class Ninja;
        friend class Iceman;
        friend class Lion;
        friend class Wolf;
};

class Warrior
{
    protected:
        Headquarter *pHeadquarter; //武士属于红还是蓝司令部
        City *pCity;//武士目前在哪个City
        int OrderInMaking;//武士的种类
        int OrderInTotal;//武士是红/蓝司令部制造的第几个武士
        Weapon *Weaponptr[WEAPON_MAX];//武士拥有的武器数组
        int SumWeap;//武器总数
        int UsedArrow;//用过的Arrow的数量
        int NumOfWeapon[WEAPON_NUM];//各种武器有多少把
        int Life;
    public:
        friend class Weapon;
        friend class Headquarter;
        friend class City;
        friend class Dragon;
        friend class Ninja;
        friend class Iceman;
        friend class Lion;
        friend class Wolf;
        friend void RedWarriorMove(City * leftCity, City *rightCity, int Time, char * RedMoveString[]);
        friend void BlueWarriorMove(City *rightCity, City * leftCity, int Time, char * BlueMoveString[]);
        static char *WarriorName[WARRIOR_NUM];//存武士名字的全局字符串数组
        static int InitLifeValue[WARRIOR_NUM];//存武士初始生命值的全局数组
        static int AttackForce[WARRIOR_NUM];//存武士攻击力的全局数组
        Warrior(Headquarter *_p, int _oim, int _oit): pHeadquarter(_p),
                                                      OrderInMaking(_oim),
                                                      OrderInTotal(_oit),
                                                      SumWeap(0),
                                                      UsedArrow(0),
                                                      Life(InitLifeValue[OrderInMaking])
        {
            for (int i = 0; i < WEAPON_NUM; ++i)
                NumOfWeapon[i] = 0;
            for (int i = 0; i < WEAPON_MAX; ++i)
                Weaponptr[i] = NULL;
        }
        virtual ~Warrior()
        {
            for (int i = 0; i < SumWeap; i++)
                if (Weaponptr[i])
                    delete Weaponptr[i];
        }
        virtual void PrintResult(int Time);//武士降生时报告情况
        virtual void IcemanMove() {}
        virtual bool LionEscape(int Time)
        {
            return 0;
        }
        virtual void LionMove() {}
        virtual void Rob(Warrior *enemy, int Time) {}
        void CaptureWeapon(Warrior *another);//击败对方武士后抢夺武器
        void ArrangeWeapon();//战斗之前把武器排好序
        void WarriorAnnounce(int Time);//每小时55钟的时候报告情况
        void OneTimeAttack(Warrior *another, int OrderInWeaponptr);//攻击对方
        int WarriorKind() {return OrderInMaking;}
        int WarriorOrderInTotal() {return OrderInTotal;}
};

class City
{
    public:
        int Cityname;
        Warrior *redwarrior;
        Warrior *bluewarrior;
        bool ishead;//该City是否为司令部
        friend void RedWarriorMove(City * leftCity, City *rightCity, int Time, char * RedMoveString[]);
        friend void BlueWarriorMove(City *rightCity, City * leftCity, int Time, char * BlueMoveString[]);
        bool attackResult(int Time, Headquarter * Red, Headquarter * Blue);//每小时的40分报告战斗情况
        void Battling(int Time, Headquarter * Red, Headquarter * Blue);//City发生战斗
        void RedInit(Headquarter *p);//红司令部成为最左的City
        void BlueInit(Headquarter *p);//蓝司令部成为最右的City
};

class Headquarter
{
    public:
        friend class Warrior;
        friend class City;
        int Color;
        int TotalLifeValue;//总共有多少生命元
        int CurOrderInMaking;//接下来准备产生哪种武士
        int TotalWarriorNum;//总共有多少活着的武士
        int NumOfWarrior[WARRIOR_NUM];//每种武士有多少个
        Warrior *Wptr[1000];//武士数组
        bool Stop;//该司令部是否有足够生命元继续生产武士
        static bool MainFlag;//全局量,标志是否被占领
        static int MakingOrder[2][WARRIOR_NUM];//存放武士制造顺序的数组
        Headquarter(bool _color, int _lifevalue): Color(_color),
                                                  TotalLifeValue(_lifevalue),
                                                  CurOrderInMaking(0),
                                                  TotalWarriorNum(0),
                                                  Stop(false)
        {
            for (int i = 0; i < WARRIOR_NUM; i++)
                NumOfWarrior[i] = 0;
            for (int i = 0; i < 1000; ++i)
                Wptr[i] = NULL;
        }
        ~Headquarter()
        {
            for (int i = 0; i < TotalWarriorNum; i++)
                if (Wptr[i])
                    delete Wptr[i];
        }
        void Produce(int Time);//武士降生
        void GetColor(char *HeadquarterName);//get “red” or “blue”
        void HeadAnnounce(int Time);//每小时的50分司令部报告生命元数量
        int GetTotalLifeValue() { return TotalLifeValue; }
        void DestroyWarrior(int number) {
            Wptr[number] = NULL;
        }
};

class Dragon: public Warrior
{
        friend class Headquarter;
        friend class City;
        friend class Ninja;
        friend class Iceman;
        friend class Lion;
        friend class Wolf;
    public:
        Dragon(Headquarter *_p, int _oim, int _oit): Warrior(_p, _oim, _oit)
        {
            int kind = OrderInTotal % WEAPON_NUM;
            Weaponptr[SumWeap] = new Weapon(kind, this);
            NumOfWeapon[kind]++;
            SumWeap++;
        }
        void PrintResult(int Time)
        {
            Warrior::PrintResult(Time);
        }
};

class Ninja: public Warrior
{
        friend class Headquarter;
        friend class City;
        friend class Dragon;
        friend class Iceman;
        friend class Lion;
        friend class Wolf;
    public:
        Ninja(Headquarter *_p, int _oim, int _oit): Warrior(_p, _oim, _oit)
        {
            int kind = OrderInTotal % WEAPON_NUM;
            Weaponptr[SumWeap] = new Weapon(kind,this);
            NumOfWeapon[kind]++;
            SumWeap++;
            kind = (OrderInTotal + 1) % WEAPON_NUM;
            Weaponptr[SumWeap] = new Weapon(kind,this);
            NumOfWeapon[kind]++;
            SumWeap++;
        }
        void PrintResult(int Time)
        {
            Warrior::PrintResult(Time);
        }
};

class Iceman: public Warrior
{
        friend class Headquarter;
        friend class City;
        friend class Dragon;
        friend class Lion;
        friend class Wolf;
        friend class Ninja;
    public:
        Iceman(Headquarter *_p, int _oim, int _oit): Warrior(_p, _oim, _oit)
        {
            int kind = OrderInTotal % WEAPON_NUM;
            Weaponptr[SumWeap] = new Weapon(kind,this);
            NumOfWeapon[kind]++;
            SumWeap++;
        }
        void PrintResult(int Time)
        {
            Warrior::PrintResult(Time);
        }
        void IcemanMove()
        {
            Life -= Life / 10;
        }
};

class Lion: public Warrior
{
        friend class Headquarter;
        friend class City;
        friend class Dragon;
        friend class Iceman;
        friend class Wolf;
        friend class Ninja;
    protected:
        int Loyalty;
    public:
        static int LoyaltyDecrease;//每前进一步忠诚度降低值
        void GetLoyalty()
        {
            Loyalty = pHeadquarter->GetTotalLifeValue();
        }
        Lion(Headquarter *_p, int _oim, int _oit): Warrior(_p, _oim, _oit)
        {
            GetLoyalty();
            int kind = OrderInTotal % WEAPON_NUM;
            Weaponptr[SumWeap] = new Weapon(kind,this);
            NumOfWeapon[kind]++;
            SumWeap++;
        }
        void PrintResult(int Time)
        {
            Warrior::PrintResult(Time);
            printf("It's loyalty is %d\n", Loyalty);
        }
        bool LionEscape(int Time) {
            if (Loyalty>0) return 0;
            char HeadquarterName[20];
            pHeadquarter->GetColor(HeadquarterName);
            printf("%.3d:05 %s lion %d ran away\n", Time, HeadquarterName, OrderInTotal);
            return 1;
        } //judge whether the lion escapes
        void LionMove() {
            Loyalty-=LoyaltyDecrease;
        }
};

class Wolf: public Warrior
{
        friend class Headquarter;
        friend class City;
        friend class Dragon;
        friend class Iceman;
        friend class Lion;
        friend class Ninja;
    public:
        Wolf(Headquarter *_p, int _oim, int _oit): Warrior(_p, _oim, _oit) {}
        void PrintResult(int Time)
        {
            Warrior::PrintResult(Time);
        }
        void Rob(Warrior *enemy, int Time);
};

int compareWeapon (const void *p, const void *q) //usedarrow排前面
{
    const Weapon ** p1 = (const Weapon **)p;
    const Weapon ** q1 = (const Weapon **)q;
    if ((*p1)->WeaponKind < (*q1)->WeaponKind) return -1;
    else if ((*p1)->WeaponKind == ARROW && (*q1)->WeaponKind == ARROW) {
        if ((*p1)->Used == (*q1)->Used) return 0;
        else if ((*p1)->Used > (*q1)->Used) return -1;
        else return 1;
    }
    else if ((*p1)->WeaponKind ==  (*q1)->WeaponKind) return 0;
    else return 1;
}

int compareWeapon2 (const void *p, const void *q) //usedarrow排后面
{
    const Weapon ** p1 = (const Weapon **)p;
    const Weapon ** q1 = (const Weapon **)q;
    if ((*p1)->WeaponKind < (*q1)->WeaponKind) return -1;
    else if ((*p1)->WeaponKind == ARROW && (*q1)->WeaponKind == ARROW) {
        if ((*p1)->Used == (*q1)->Used) return 0;
        else if ((*p1)->Used < (*q1)->Used) return -1;
        else return 1;
    }
    else if ((*p1)->WeaponKind ==  (*q1)->WeaponKind) return 0;
    else return 1;
}

void Wolf::Rob(Warrior *enemy, int Time)
{
    if (enemy->OrderInMaking == WOLF) return;
    if (SumWeap == 10 || enemy->SumWeap == 0) return;

    int i_ = 0, used_change = 0;//used-change是抢的用过的arrow的数量
    for (; i_ < WEAPON_NUM; ++i_)
        if (enemy->NumOfWeapon[i_] > 0) break;
    int robNum = min(enemy->NumOfWeapon[i_], WEAPON_MAX - SumWeap);
    if (i_ == ARROW) {
        if (enemy->NumOfWeapon[ARROW] - enemy->UsedArrow < robNum) {
            used_change =  robNum - (enemy->NumOfWeapon[ARROW] - enemy->UsedArrow);
            enemy->UsedArrow -= used_change;
            UsedArrow += used_change;
        }
    }
    for (int i = 0; i < robNum; ++i)
        Weaponptr[SumWeap+i] = new Weapon(i_,this);
    if (i_ == ARROW) {
        for (int i = 0; i < used_change; i++)
            Weaponptr[SumWeap+i]->Used = true;
    }
    SumWeap += robNum;
    NumOfWeapon[i_] += robNum;
    if (i_ != ARROW) {
    for (int i = 0, cnt = 0; i < enemy->SumWeap && cnt < robNum; ++i)
        if (enemy->Weaponptr[i]->WeaponKind == i_) {
            delete enemy->Weaponptr[i];
            enemy->Weaponptr[i] = NULL;
            ++cnt;
        }
    }
    else {
        for (int i = 0, cnt = 0; i < enemy->SumWeap && cnt < (robNum - used_change); ++i)
            if (enemy->Weaponptr[i]->WeaponKind == i_) {
                if (!(enemy->Weaponptr[i]->Used)) {
                    delete enemy->Weaponptr[i];
                    enemy->Weaponptr[i] = NULL;
                    ++cnt;
                }
            }
        for (int i = 0, cnt = 0; i < enemy->SumWeap && cnt < used_change; ++i)
            if (enemy->Weaponptr[i]->WeaponKind == i_) {
                if (enemy->Weaponptr[i]->Used) {
                    delete enemy->Weaponptr[i];
                    enemy->Weaponptr[i] = NULL;
                    ++cnt;
                }
            }
    }
    //抢完之后要给武器数组进行及时排好序:
    Weapon *Weaponptr_tmp[WEAPON_MAX];
    for (int i = 0; i < WEAPON_MAX; i++)
        Weaponptr_tmp[i] = NULL;
    for (int i = 0, k = 0; i < WEAPON_MAX; ++i)
    if (enemy->Weaponptr[i]) {
        Weaponptr_tmp[k] = enemy->Weaponptr[i];
        k++;
    }
    for (int i = 0; i < WEAPON_MAX; ++i)
        enemy->Weaponptr[i] = Weaponptr_tmp[i];
    for (int i = 0; i < WEAPON_MAX; ++i)
        Weaponptr_tmp[i] = NULL;

    enemy->SumWeap -= robNum;
    enemy->NumOfWeapon[i_] -= robNum;
    if (enemy->SumWeap > 0) qsort(enemy->Weaponptr, enemy->SumWeap, sizeof(Weapon *), compareWeapon);
    qsort(Weaponptr, SumWeap, sizeof(Weapon *), compareWeapon);
            //000:35 blue wolf 2 took 3 bomb from red dragon 2 in city 4
    char HeadquarterName1[20];
    pHeadquarter->GetColor(HeadquarterName1);
    char HeadquarterName2[20];
    enemy->pHeadquarter->GetColor(HeadquarterName2);
    printf("%.3d:35 %s wolf %d took %d %s from %s %s %d in city %d\n", Time, HeadquarterName1, OrderInTotal,
                                                                        robNum, Weapon::WeaponName[i_], HeadquarterName2,
                                                                        WarriorName[enemy->OrderInMaking], enemy->OrderInTotal,
                                                                        pCity->Cityname);
}

Weapon::Weapon(int kind, Warrior *p): WeaponKind(kind), pWarrior(p), Used(false)
{
    switch (kind) {
        case SWORD: WeaponForce = p->AttackForce[pWarrior->OrderInMaking] / 5;
                    break;
        case BOMB : WeaponForce = p->AttackForce[pWarrior->OrderInMaking] * 2 / 5;
                    break;
        case ARROW: WeaponForce = p->AttackForce[pWarrior->OrderInMaking] * 3 / 10;
                    break;
    }
}

void City::RedInit(Headquarter *p)
{
    redwarrior = p->Wptr[p->TotalWarriorNum-1];
    redwarrior->pCity = this;
}

void City::BlueInit(Headquarter *p)
{
    bluewarrior = p->Wptr[p->TotalWarriorNum-1];
    bluewarrior->pCity = this;
}

void Warrior::PrintResult(int Time)
{
    char HeadquarterName[20];
    pHeadquarter->GetColor(HeadquarterName);
    printf("%.3d:00 %s %s %d born\n", Time, HeadquarterName, WarriorName[OrderInMaking], OrderInTotal);
}

void Headquarter::Produce(int Time)
{
    if (Stop) return;

    if (Warrior::InitLifeValue[MakingOrder[Color][CurOrderInMaking]] > TotalLifeValue) {
        Stop = true;
        return;
    }

    int Kind = MakingOrder[Color][CurOrderInMaking];
    TotalLifeValue -= Warrior::InitLifeValue[Kind];
    CurOrderInMaking = (CurOrderInMaking + 1) % WARRIOR_NUM;
    switch (Kind) {
        case DRAGON: Wptr[TotalWarriorNum] = new Dragon(this, Kind, TotalWarriorNum+1);
                     break;
        case NINJA : Wptr[TotalWarriorNum] = new Ninja(this, Kind, TotalWarriorNum+1);
                     break;
        case ICEMAN: Wptr[TotalWarriorNum] = new Iceman(this, Kind, TotalWarriorNum+1);
                     break;
        case LION  : Wptr[TotalWarriorNum] = new Lion(this, Kind, TotalWarriorNum+1);
                     break;
        case WOLF  : Wptr[TotalWarriorNum] = new Wolf(this, Kind, TotalWarriorNum+1);
                     break;
    }
    NumOfWarrior[Kind]++;
    Wptr[TotalWarriorNum]->PrintResult(Time);
    TotalWarriorNum++;
}

void Headquarter::GetColor(char *HeadquarterName)
{
    if (Color == 0)
        strcpy(HeadquarterName, "red");
    else
        strcpy(HeadquarterName, "blue");
}

void RedWarriorMove(City * leftCity, City *rightCity, int Time, char * RedMoveString [])//从左往右
{
    if (leftCity->redwarrior) {
        if (leftCity->redwarrior->OrderInMaking == ICEMAN) leftCity->redwarrior->IcemanMove();
        if (leftCity->redwarrior->OrderInMaking == LION) leftCity->redwarrior->LionMove();
        char HeadquarterName[20];
        leftCity->redwarrior->pHeadquarter->GetColor(HeadquarterName);
        RedMoveString[rightCity->Cityname] = new char[150];
        if (!RedMoveString[rightCity->Cityname]) {perror("cannot malloc\n"); exit(1);}
        if (!rightCity->ishead)
        //000:10 red iceman 1 marched to city 1 with 20 elements and force 30
            sprintf(RedMoveString[rightCity->Cityname], "%.3d:10 %s %s %d marched to city %d with %d elements and force %d\n",
                                                                                          Time, HeadquarterName, Warrior::WarriorName[leftCity->redwarrior->OrderInMaking],
                                                                                          leftCity->redwarrior->OrderInTotal, rightCity->Cityname, leftCity->redwarrior->Life,
                                                                                          Warrior::AttackForce[leftCity->redwarrior->OrderInMaking]);
        else if (rightCity->ishead) {
        //001:10 red iceman 1 reached blue headquarter with 20 elements and force 30 004:10 blue headquarter was taken
            sprintf(RedMoveString[rightCity->Cityname], "%.3d:10 %s %s %d reached blue headquarter with %d elements and force %d\n%.3d:10 blue headquarter was taken\n",
                                                                                            Time, HeadquarterName, Warrior::WarriorName[leftCity->redwarrior->OrderInMaking],
                                                                                            leftCity->redwarrior->OrderInTotal, leftCity->redwarrior->Life,
                                                                                            Warrior::AttackForce[leftCity->redwarrior->OrderInMaking], Time);
            Headquarter::MainFlag = 0;
        }
        rightCity->redwarrior = leftCity->redwarrior;
        leftCity->redwarrior = NULL;
        rightCity->redwarrior->pCity = rightCity;
    }
}

void BlueWarriorMove(City *rightCity, City * leftCity, int Time, char * BlueMoveString [])
{//从you往zuo
    if (rightCity->bluewarrior) {
        if (rightCity->bluewarrior->OrderInMaking == ICEMAN) rightCity->bluewarrior->IcemanMove();
        if (rightCity->bluewarrior->OrderInMaking == LION) rightCity->bluewarrior->LionMove();
        char HeadquarterName[20];
        rightCity->bluewarrior->pHeadquarter->GetColor(HeadquarterName);
        BlueMoveString[leftCity->Cityname] = new char[150];
        if (!BlueMoveString[leftCity->Cityname]) {perror("cannot malloc\n"); exit(1);}
        if (!leftCity->ishead)
        //000:10 red iceman 1 marched to city 1 with 20 elements and force 30
            sprintf(BlueMoveString[leftCity->Cityname], "%.3d:10 %s %s %d marched to city %d with %d elements and force %d\n",
                                                                                          Time, HeadquarterName, Warrior::WarriorName[rightCity->bluewarrior->OrderInMaking],
                                                                                          rightCity->bluewarrior->OrderInTotal, leftCity->Cityname, rightCity->bluewarrior->Life,
                                                                                          Warrior::AttackForce[rightCity->bluewarrior->OrderInMaking]);
        else if (leftCity->ishead) {
        //001:10 red iceman 1 reached blue headquarter with 20 elements and force 30 004:10 blue headquarter was taken
            sprintf(BlueMoveString[leftCity->Cityname], "%.3d:10 %s %s %d reached red headquarter with %d elements and force %d\n%.3d:10 red headquarter was taken\n",
                                                                                            Time, HeadquarterName, Warrior::WarriorName[rightCity->bluewarrior->OrderInMaking],
                                                                                            rightCity->bluewarrior->OrderInTotal, rightCity->bluewarrior->Life,
                                                                                            Warrior::AttackForce[rightCity->bluewarrior->OrderInMaking], Time);
            Headquarter::MainFlag = 0;
        }
        leftCity->bluewarrior = rightCity->bluewarrior;
        rightCity->bluewarrior = NULL;
        leftCity->bluewarrior->pCity = leftCity;
    }
}

void Warrior::OneTimeAttack(Warrior *another, int OrderInWeaponptr)
{
    int usingKind = Weaponptr[OrderInWeaponptr]->WeaponKind;
    switch (usingKind) {
        case SWORD: another->Life -= Weaponptr[OrderInWeaponptr]->WeaponForce;
                    break;
        case BOMB : another->Life -= Weaponptr[OrderInWeaponptr]->WeaponForce;
                    if (OrderInMaking != NINJA) {
                        Life -= Weaponptr[OrderInWeaponptr]->WeaponForce / 2;
                    }
                    delete Weaponptr[OrderInWeaponptr];
                    Weaponptr[OrderInWeaponptr] = NULL;
                    NumOfWeapon[usingKind]--;
                    break;
        case ARROW: another->Life -= Weaponptr[OrderInWeaponptr]->WeaponForce;
                    if (Weaponptr[OrderInWeaponptr]->Used) {
                        delete Weaponptr[OrderInWeaponptr];
                        Weaponptr[OrderInWeaponptr] = NULL;
                        NumOfWeapon[usingKind]--;
                        UsedArrow--;
                    }
                    else{
                        UsedArrow++;
                        Weaponptr[OrderInWeaponptr]->Used = true;
                    }
                    break;
    }
}

void Warrior::ArrangeWeapon()
{
    SumWeap = NumOfWeapon[0] +  NumOfWeapon[1] + NumOfWeapon[2];

    Weapon *Weaponptr_tmp[WEAPON_MAX];
    for (int i = 0; i < WEAPON_MAX; i++)
        Weaponptr_tmp[i] = NULL;
    for (int i = 0, k = 0; i < WEAPON_MAX; ++i)
    if (Weaponptr[i]) {
        Weaponptr_tmp[k] = Weaponptr[i];
        k++;
    }
    for (int i = 0; i < WEAPON_MAX; ++i)
        Weaponptr[i] = Weaponptr_tmp[i];
    for (int i = 0; i < WEAPON_MAX; ++i)
        Weaponptr_tmp[i] = NULL;

    if (SumWeap > 0) qsort(Weaponptr, SumWeap, sizeof(Weapon *), compareWeapon);
}

void Warrior::CaptureWeapon(Warrior *another)
{
    if ((WEAPON_MAX - SumWeap) > 0 && another->SumWeap > 0) {//自己武器没满,且对方还有武器,才要拿
        int add;
        if ((WEAPON_MAX - SumWeap) >= another->SumWeap) {
            add = another->SumWeap;
            Weapon *Weaponptr_tmp[add];
            for (int i = 0; i < add; i++) {
                int kind = another->Weaponptr[i]->WeaponKind;
                bool used = another->Weaponptr[i]->Used;
                Weaponptr_tmp[i] = new Weapon(kind, this);
                if (kind == ARROW && used)
                    Weaponptr_tmp[i]->Used = true;
            }
            for (int i = 0; i < add; i++)
                Weaponptr[SumWeap+i] = Weaponptr_tmp[i];
            SumWeap += add;
            NumOfWeapon[SWORD] += another->NumOfWeapon[SWORD];
            NumOfWeapon[BOMB] += another->NumOfWeapon[BOMB];
            NumOfWeapon[ARROW] += another->NumOfWeapon[ARROW];
        }
        else {
            qsort(another->Weaponptr, another->SumWeap, sizeof(Weapon *), compareWeapon2);//把another没用过的排在前面

            add = WEAPON_MAX - SumWeap;
            Weapon *Weaponptr_tmp[add];
            for (int i = 0; i < add; ++i) {
                int kind = another->Weaponptr[i]->WeaponKind;
                bool used = another->Weaponptr[i]->Used;
                Weaponptr_tmp[i] = new Weapon(kind, this);
                if (kind == ARROW && used)
                    Weaponptr_tmp[i]->Used = true;
                if (kind == SWORD) NumOfWeapon[SWORD]++;
                if (kind == BOMB) NumOfWeapon[BOMB]++;
                if (kind == ARROW) NumOfWeapon[ARROW]++;
            }
            for (int i = 0; i < add; i++)
                Weaponptr[SumWeap+i] = Weaponptr_tmp[i];
            SumWeap += add;
        }
    }
}

bool City::attackResult(int Time, Headquarter * Red, Headquarter * Blue)
{
    if (redwarrior->Life <= 0 && bluewarrior->Life <= 0) {
            //000:40 both red iceman 1 and blue lion 12 died in city 2
        printf("%.3d:40 both red %s %d and blue %s %d died in city %d\n", Time, Warrior::WarriorName[redwarrior->OrderInMaking], redwarrior->OrderInTotal,
                                                                          Warrior::WarriorName[bluewarrior->OrderInMaking], bluewarrior->OrderInTotal, Cityname);
        Red->DestroyWarrior(redwarrior->OrderInTotal-1);
        delete redwarrior;
        redwarrior = NULL;
        Blue->DestroyWarrior(bluewarrior->OrderInTotal-1);
        delete bluewarrior;
        bluewarrior = NULL;
        return 1;
    }
    if (bluewarrior->Life <= 0) {
        redwarrior->ArrangeWeapon();  bluewarrior->ArrangeWeapon();
        redwarrior->CaptureWeapon(bluewarrior);
        redwarrior->ArrangeWeapon();
        //000:40 red iceman 1 killed blue lion 12 in city 2 remaining 20 elements
        printf("%.3d:40 red %s %d killed blue %s %d in city %d remaining %d elements\n", Time, Warrior::WarriorName[redwarrior->OrderInMaking], redwarrior->OrderInTotal,
                                                                                         Warrior::WarriorName[bluewarrior->OrderInMaking], bluewarrior->OrderInTotal, Cityname,
                                                                                         redwarrior->Life);
        Blue->DestroyWarrior(bluewarrior->OrderInTotal-1);
        delete bluewarrior;
        bluewarrior = NULL;
        if (redwarrior->OrderInMaking == DRAGON)
            //003:40 blue dragon 2 yelled in city 4
            printf("%.3d:40 red dragon %d yelled in city %d\n", Time, redwarrior->OrderInTotal, Cityname);
        return 1;
    }
    if (redwarrior->Life <= 0) {
        redwarrior->ArrangeWeapon();  bluewarrior->ArrangeWeapon();
        bluewarrior->CaptureWeapon(redwarrior);
        bluewarrior->ArrangeWeapon();
        //000:40 red iceman 1 killed blue lion 12 in city 2 remaining 20 elements
        printf("%.3d:40 blue %s %d killed red %s %d in city %d remaining %d elements\n", Time, Warrior::WarriorName[bluewarrior->OrderInMaking], bluewarrior->OrderInTotal,
                                                                                         Warrior::WarriorName[redwarrior->OrderInMaking], redwarrior->OrderInTotal, Cityname,
                                                                                         bluewarrior->Life);
        Red->DestroyWarrior(redwarrior->OrderInTotal-1);
        delete redwarrior;
        redwarrior = NULL;
        if (bluewarrior->OrderInMaking == DRAGON)
            //003:40 blue dragon 2 yelled in city 4
            printf("%.3d:40 blue dragon %d yelled in city %d\n", Time, bluewarrior->OrderInTotal, Cityname);
        return 1;
    }
    return 0;
}


void City::Battling(int Time, Headquarter * Red, Headquarter * Blue)
{
    if (!(redwarrior && bluewarrior)) return;//形不成战斗

    bool tempFlag = 0;//标志战斗状态是否不再发生变化,我这里认为如果双方生命值连续五轮不变,那就是平局
    int redlife = redwarrior->Life, bluelife = bluewarrior->Life;
    int i_red = 0, i_blue = 0;//使用的是武士拥有的武器数组中序号为i_red/i_blue的武器

    if (Cityname % 2 ==1) {
        if (redwarrior->SumWeap) {
           if (i_red == redwarrior->SumWeap) i_red = 0;
           if (redwarrior->Weaponptr[i_red]) {
             redwarrior->OneTimeAttack(bluewarrior, i_red);
             if (attackResult(Time, Red, Blue)) return;
             i_red++;
           }
           else {
             int i;
             for (i = i_red; i < redwarrior->SumWeap; i++)
                if (redwarrior->Weaponptr[i]) break;
             if (i < redwarrior->SumWeap) {
                i_red = i;
                redwarrior->OneTimeAttack(bluewarrior, i_red);
                if (attackResult(Time, Red, Blue)) return;
                i_red++;
             }
             else {
                i_red = 0;
                if (redwarrior->Weaponptr[i_red]) {
                   redwarrior->OneTimeAttack(bluewarrior, i_red);
                   if (attackResult(Time, Red, Blue)) return;
                   i_red++;
                }
             }
           }
        }
    }

    int tie_counter = 0;//回合制攻击轮数
    while (!tempFlag) {
        redlife = redwarrior->Life;
        bluelife = bluewarrior->Life;

        if (bluewarrior->SumWeap) {
            if (i_blue == bluewarrior->SumWeap) i_blue = 0;
            if (bluewarrior->Weaponptr[i_blue]) {
                bluewarrior->OneTimeAttack(redwarrior,i_blue);
                if (attackResult(Time, Red, Blue)) return;
                i_blue++;
            }
            else {
                int i;
                for (i = i_blue; i < bluewarrior->SumWeap; i++)
                    if (bluewarrior->Weaponptr[i]) break;
                if (i < bluewarrior->SumWeap) {
                    i_blue = i;
                    bluewarrior->OneTimeAttack(redwarrior,i_blue);
                    if (attackResult(Time, Red, Blue)) return;
                    i_blue++;
                }
                else {
                    i_blue = 0;
                    if (bluewarrior->Weaponptr[i_blue]) {
                        bluewarrior->OneTimeAttack(redwarrior,i_blue);
                        if (attackResult(Time, Red, Blue)) return;
                        i_blue++;
                    }
                }
            }
        }

        if (redwarrior->SumWeap) {
            if (i_red == redwarrior->SumWeap) i_red = 0;
            if (redwarrior->Weaponptr[i_red]) {
                redwarrior->OneTimeAttack(bluewarrior, i_red);
                if (attackResult(Time, Red, Blue)) return;
                i_red++;
            }
            else {
                int i;
                for (i = i_red; i < redwarrior->SumWeap; i++)
                    if (redwarrior->Weaponptr[i]) break;
                if (i < redwarrior->SumWeap) {
                    i_red = i;
                    redwarrior->OneTimeAttack(bluewarrior, i_red);
                    if (attackResult(Time, Red, Blue)) return;
                    i_red++;
                }
                else {
                    i_red = 0;
                    if (redwarrior->Weaponptr[i_red]) {
                        redwarrior->OneTimeAttack(bluewarrior, i_red);
                        if (attackResult(Time, Red, Blue)) return;
                        i_red++;
                    }
                }
            }
        }

        if (redlife == redwarrior->Life && bluelife == bluewarrior->Life)
            tie_counter++;
        else
            tie_counter = 0;

        if (tie_counter >= 5)
            tempFlag = 1;
    }

    if (tempFlag) {
        redwarrior->ArrangeWeapon();  bluewarrior->ArrangeWeapon();//打完了也要记得排个序
            //000:40 both red iceman 1 and blue lion 12 were alive in city 2
        printf("%.3d:40 both red %s %d and blue %s %d were alive in city %d\n", Time, Warrior::WarriorName[redwarrior->OrderInMaking], redwarrior->OrderInTotal,
                                                                                Warrior::WarriorName[bluewarrior->OrderInMaking], bluewarrior->OrderInTotal, Cityname);
        if (redwarrior->OrderInMaking == DRAGON)
            //003:40 blue dragon 2 yelled in city 4
            printf("%.3d:40 red dragon %d yelled in city %d\n", Time, redwarrior->OrderInTotal, Cityname);
        if (bluewarrior->OrderInMaking == DRAGON)
            //003:40 blue dragon 2 yelled in city 4
            printf("%.3d:40 blue dragon %d yelled in city %d\n", Time, bluewarrior->OrderInTotal, Cityname);
    }
}

void Headquarter::HeadAnnounce(int Time)
{
   // 000:50 120 elements in blue headquarter
    char HeadquarterName[20];
    GetColor(HeadquarterName);
    printf("%.3d:50 %d elements in %s headquarter\n", Time, TotalLifeValue, HeadquarterName);
}

void Warrior::WarriorAnnounce(int Time)
{
    //000:55 blue wolf 2 has 2 sword 3 bomb 0 arrow and 7 elements
    char HeadquarterName[20];
    pHeadquarter->GetColor(HeadquarterName);
    printf("%.3d:55 %s %s %d has %d sword %d bomb %d arrow and %d elements\n", Time, HeadquarterName, Warrior::WarriorName[OrderInMaking], OrderInTotal,
                                                                               NumOfWeapon[SWORD], NumOfWeapon[BOMB], NumOfWeapon[ARROW], Life);
}

char * Weapon::WeaponName[WEAPON_NUM] = {"sword","bomb","arrow" };
int Warrior::AttackForce[WARRIOR_NUM];
char * Warrior::WarriorName[WARRIOR_NUM] = {"dragon","ninja","iceman","lion","wolf"};
int Warrior::InitLifeValue[WARRIOR_NUM];
int Headquarter::MakingOrder[2][WARRIOR_NUM] = {{ 2,3,4,1,0 } ,{ 3,0,1,2,4 }};
bool Headquarter::MainFlag = 1;
int Lion::LoyaltyDecrease;

int main()
{
/*第一行是t,代表测试数据组数
每组样例共三行。
第一行,4个整数 M,N,K, T。其含义为:
每个司令部一开始都有M个生命元( 1 <= M <= 100000)
两个司令部之间一共有N个城市( 1 <= N <= 20 )
lion每前进一步,忠诚度就降低K。(0<=K<=100)
要求输出从0时0分开始,到时间T为止(包括T) 的所有事件。T以分钟为单位,0 <= T <= 6000
第二行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它们都大于0小于等于200
第三行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的攻击力。它们都大于0小于等于200*/
    int t;
    scanf("%d", &t);
    int Case = 1;
    while (t--) {
        printf("%d\n", Case++);

        int lifeValue, CityNumber, TotalTime, Hour = 0; Headquarter::MainFlag = 1;

        scanf("%d%d%d%d", &lifeValue, &CityNumber, &Lion::LoyaltyDecrease, &TotalTime);
        for (int i = 0; i < WARRIOR_NUM; i++)
            scanf("%d", &Warrior::InitLifeValue[i]);
        for (int i = 0; i < WARRIOR_NUM; i++)
            scanf("%d", &Warrior::AttackForce[i]);

        Headquarter Red(0, lifeValue);
        Headquarter Blue(1, lifeValue);
        City *cities = new City[CityNumber+2];

        for (int i = 0; i < CityNumber+2; ++i) {
            cities[i].redwarrior = NULL;
            cities[i].bluewarrior = NULL;
            cities[i].Cityname = i;
            cities[i].ishead = 0;
        }
        cities[0].ishead = 1;
        cities[CityNumber+1].ishead = 1;

        while (Hour * 60 <= TotalTime) {
            if (!Red.Stop) {
                Red.Produce(Hour);
                if (!Red.Stop)//根据Produce()的写法,这里的两次判断是必须的
                    cities[0].RedInit(&Red);
            }
            if (!Blue.Stop) {
                Blue.Produce(Hour);
                if (!Blue.Stop)
                    cities[CityNumber+1].BlueInit(&Blue);
            }

            if (Hour * 60 + 5 <= TotalTime) {
                for (int i = 0; i <= CityNumber + 1; ++i) {
                    if (cities[i].redwarrior ) {
                        if ( cities[i].redwarrior->WarriorKind() == 3 ) {
                            if (cities[i].redwarrior->LionEscape(Hour)) {
                                Red.DestroyWarrior(cities[i].redwarrior->WarriorOrderInTotal() - 1);
                                delete cities[i].redwarrior;
                                cities[i].redwarrior = NULL;
                            }
                        }
                    }
                    if (cities[i].bluewarrior ) {
                        if( cities[i].bluewarrior->WarriorKind() == 3 ) {
                            if (cities[i].bluewarrior->LionEscape(Hour)) {
                                Blue.DestroyWarrior(cities[i].bluewarrior->WarriorOrderInTotal() - 1);
                                delete cities[i].bluewarrior;
                                cities[i].bluewarrior = NULL;
                            }
                        }
                    }
                }
            }

            if (Hour * 60 + 10 <= TotalTime) {
                int shangxian = CityNumber + 1;
                char * MoveString[2][CityNumber+2];//为了按答案顺序输出武士前进消息
                for (int row = 0; row < 2; row++)
                    for (int col = 0; col < CityNumber+2; col++)
                        MoveString[row][col]= NULL;

                for (int i = shangxian; i > 0; i--) {
                    RedWarriorMove(&cities[i-1], &cities[i], Hour, MoveString[0]);
                }
                for (int i = 0; i < shangxian; i++) {
                    BlueWarriorMove(&cities[i+1], &cities[i], Hour, MoveString[1]);
                }

                for (int i = 0; i < CityNumber+2; i++)
                    for (char* (*p)[CityNumber+2] = &MoveString[0]; p <= &MoveString[1]; p++)
                        if ((*p)[i]) printf("%s", (*p)[i]);
                for (int row = 0; row < 2; row++)
                    for (int col = 0; col < CityNumber+2; col++)
                        if (MoveString[row][col]) delete [] MoveString[row][col];

                if (!Headquarter::MainFlag) break;
            }

            if (Hour * 60 + 35 <= TotalTime) {
                for (int i = 1; i < CityNumber+1; ++i) {
                    if (cities[i].redwarrior && cities[i].bluewarrior) {
                        cities[i].redwarrior->Rob(cities[i].bluewarrior, Hour);
                        cities[i].bluewarrior->Rob(cities[i].redwarrior, Hour);
                    }
                }
            }

            if (Hour * 60 + 40 <= TotalTime) {
                for (int i = 1; i < CityNumber+1; ++i)
                    cities[i].Battling(Hour, &Red, &Blue);
            }

            if (Hour * 60 + 50 <= TotalTime) {
                Red.HeadAnnounce(Hour);
                Blue.HeadAnnounce(Hour);
            }

            if (Hour * 60 + 55 <= TotalTime) {
                for (int i = 1; i < CityNumber+1; ++i) {
                    if (cities[i].redwarrior) cities[i].redwarrior->WarriorAnnounce(Hour);
                    if (cities[i].bluewarrior) cities[i].bluewarrior->WarriorAnnounce(Hour);
                }
            }

            Hour++;
        }
    }

    return 0;
}
  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值