C++程序设计 第6周 魔兽终极版

完全没有想到一个单元作业就会如此的复杂,可以说是一个小型模拟游戏。写了整整4天的代码,外加1天调试,要不是对编程有满腔的热情,绝对是坚持不下来的,毕竟这道题有很多人放弃了。虽然最终的代码很丑,不仅啰嗦而且迭代性差,但是对于现阶段的我来说还是很有纪念意义的。

回顾了一下代码,觉得有以下几点是日后要注意的:

1. 动作虽然是Warrior完成,但事件的激活都源于city,所以在city类里面应该有相关的成员函数,而非通过主函数访问city的成员变量。

2. 编写类之前,要充分归纳对象之间的相同点。原本headquarter是可以从city类里面派生出来的,这样后期调用可以减少很多的麻烦。

3. 少用指针调用。全屏的箭头看的好难过,乱七八糟的。

以下是我编程前,用来梳理思路和架构的草稿图,纪念一下~

--------------------------------------------------------分隔,以下是题目--------------------------------------------------------

描述

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为1,2,3 .... N ( N <= 20 )。红魔军的司令部算作编号为0的城市,蓝魔军的司令部算作编号为N+1的城市。司令部有生命元,用于制造武士。

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

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

武士在刚降生的时候有一个初始的生命值,生命值在战斗中会发生变化,如果生命值减少到0(生命值变为负数时应当做变为0处理),则武士死亡(消失)。

有的武士可以拥有武器。武器有三种,sword, bomb,和arrow,编号分别为0,1,2。

武士降生后就朝对方司令部走,在经过的城市如果遇到敌人(同一时刻每个城市最多只可能有1个蓝武士和一个红武士),就会发生战斗。每次战斗只有一方发起主动进攻一次。被攻击者生命值会减去进攻者的攻击力值和进攻者手中sword的攻击力值。被进攻者若没死,就会发起反击,被反击者的生命值要减去反击者攻击力值的一半(去尾取整)和反击者手中sword的攻击力值。反击可能致敌人于死地。

如果武士在战斗中杀死敌人(不论是主动进攻杀死还是反击杀死),则其司令部会立即向其发送8个生命元作为奖励,使其生命值增加8。当然前提是司令部得有8个生命元。如果司令部的生命元不足以奖励所有的武士,则优先奖励距离敌方司令部近的武士。

如果某武士在某城市的战斗中杀死了敌人,则该武士的司令部立即取得该城市中所有的生命元。注意,司令部总是先完成全部奖励工作,然后才开始从各个打了胜仗的城市回收生命元。对于因司令部生命元不足而领不到奖励的武士,司令部也不会在取得战利品生命元后为其补发奖励。

如果一次战斗的结果是双方都幸存(平局),则双方都不能拿走发生战斗的城市的生命元。

城市可以插旗子,一开始所有城市都没有旗子。在插红旗的城市,以及编号为奇数的无旗城市,由红武士主动发起进攻。在插蓝旗的城市,以及编号为偶数的无旗城市,由蓝武士主动发起进攻。

当某个城市有连续两场战斗都是同一方的武士杀死敌人(两场战斗之间如果有若干个战斗时刻并没有发生战斗,则这两场战斗仍然算是连续的;但如果中间有平局的战斗,就不算连续了) ,那么该城市就会插上胜方的旗帜,若原来插着败方的旗帜,则败方旗帜落下。旗帜一旦插上,就一直插着,直到被敌人更换。一个城市最多只能插一面旗帜,旗帜没被敌人更换前,也不会再次插同颜色的旗。

各种武器有其特点:

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

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

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

武士使用bomb和敌人同归于尽的情况下,不算是一场战斗,双方都不能拿走城市的生命元,也不影响城市的旗帜。

不同的武士有不同的特点。

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

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

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

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

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

以下是不同时间会发生的不同事件:

在每个整点,即每个小时的第0分, 双方的司令部中各有一个武士降生。

红方司令部按照 iceman、lion、wolf、ninja、dragon 的顺序制造武士。

蓝方司令部按照 lion、dragon、ninja、iceman、wolf 的顺序制造武士。

制造武士需要生命元。

制造一个初始生命值为 m 的武士,司令部中的生命元就要减少 m 个。

如果司令部中的生命元不足以制造某武士,那么司令部就等待,直到获得足够生命元后的第一个整点,才制造该武士。例如,在2:00,红方司令部本该制造一个 wolf ,如果此时生命元不足,那么就会等待,直到生命元足够后的下一个整点,才制造一个 wolf。

在每个小时的第5分,该逃跑的lion就在这一时刻逃跑了。

在每个小时的第10分:所有的武士朝敌人司令部方向前进一步。即从己方司令部走到相邻城市,或从一个城市走到下一个城市。或从和敌军司令部相邻的城市到达敌军司令部。

在每个小时的第20分:每个城市产出10个生命元。生命元留在城市,直到被武士取走。

在每个小时的第30分:如果某个城市中只有一个武士,那么该武士取走该城市中的所有生命元,并立即将这些生命元传送到其所属的司令部。

在每个小时的第35分,拥有arrow的武士放箭,对敌人造成伤害。放箭事件应算发生在箭发出的城市。注意,放箭不算是战斗,因此放箭的武士不会得到任何好处。武士在没有敌人的城市被箭射死也不影响其所在城市的旗帜更换情况。

在每个小时的第38分,拥有bomb的武士评估是否应该使用bomb。如果是,就用bomb和敌人同归于尽。

在每个小时的第40分:在有两个武士的城市,会发生战斗。 如果敌人在5分钟前已经被飞来的arrow射死,那么仍然视为发生了一场战斗,而且存活者视为获得了战斗的胜利。此情况下不会有“武士主动攻击”,“武士反击”,“武士战死”的事件发生,但战斗胜利后应该发生的事情都会发生。如Wolf一样能缴获武器,旗帜也可能更换,等等。在此情况下,Dragon同样会通过判断是否应该轮到自己主动攻击来决定是否欢呼。

在每个小时的第50分,司令部报告它拥有的生命元数量。

在每个小时的第55分,每个武士报告其拥有的武器情况。

武士到达对方司令部后就算完成任务了,从此就呆在那里无所事事。

任何一方的司令部里若是出现了2个敌人,则认为该司令部已被敌人占领。

任何一方的司令部被敌人占领,则战争结束。战争结束之后就不会发生任何事情了。

给定一个时间,要求你将从0点0分开始到此时间为止的所有事件按顺序输出。事件及其对应的输出样例如下:

1) 武士降生

输出样例: 000:00 blue lion 1 born

表示在 0点0分,编号为1的蓝魔lion武士降生

如果造出的是dragon,那么还要多输出一行,例:

000:00 blue dragon 1 born

Its morale is 23.34

表示该该dragon降生时士气是23. 34(四舍五入到小数点后两位)

如果造出的是lion,那么还要多输出一行,例:

000:00 blue lion 1 born

Its loyalty is 24

表示该lion降生时的忠诚度是24

2) lion逃跑

输出样例: 000:05 blue lion 1 ran away

表示在 0点5分,编号为1的蓝魔lion武士逃走

3) 武士前进到某一城市

输出样例: 000:10 red iceman 1 marched to city 1 with 20 elements and force 30

表示在 0点10分,红魔1号武士iceman前进到1号城市,此时他生命值为20,攻击力为30

对于iceman,输出的生命值和攻击力应该是变化后的数值

4)武士放箭

输出样例: 000:35 blue dragon 1 shot

表示在 0点35分,编号为1的蓝魔dragon武士射出一支箭。如果射出的箭杀死了敌人,则应如下输出:

000:35 blue dragon 1 shot and killed red lion 4

表示在 0点35分,编号为1的蓝魔dragon武士射出一支箭,杀死了编号为4的红魔lion。

5)武士使用bomb

输出样例: 000:38 blue dragon 1 used a bomb and killed red lion 7

表示在 0点38分,编号为1的蓝魔dragon武士用炸弹和编号为7的红魔lion同归于尽。

6) 武士主动进攻

输出样例:000:40 red iceman 1 attacked blue lion 1 in city 1 with 20 elements and force 30

表示在0点40分,1号城市中,红魔1号武士iceman 进攻蓝魔1号武士lion,在发起进攻前,红魔1号武士iceman生命值为20,攻击力为 30

7) 武士反击

输出样例:001:40 blue dragon 2 fought back against red lion 2 in city 1

表示在1点40分,1号城市中,蓝魔2号武士dragon反击红魔2号武士lion

8) 武士战死

输出样例:001:40 red lion 2 was killed in city 1

被箭射死的武士就不会有这一条输出。

9) 武士欢呼

输出样例:003:40 blue dragon 2 yelled in city 4

10) 武士获取生命元( elements )

输出样例:001:40 blue dragon 2 earned 10 elements for his headquarter

11) 旗帜升起

输出样例:004:40 blue flag raised in city 4

12) 武士抵达敌军司令部

输出样例:001:10 red iceman 1 reached blue headquarter with 20 elements and force 30

(此时他生命值为20,攻击力为30)对于iceman,输出的生命值和攻击力应该是变化后的数值

13) 司令部被占领

输出样例:003:10 blue headquarter was taken

14)司令部报告生命元数量

000:50 100 elements in red headquarter

000:50 120 elements in blue headquarter

表示在0点50分,红方司令部有100个生命元,蓝方有120个

15)武士报告武器情况

000:55 blue wolf 2 has arrow(2),bomb,sword(23)

000:55 blue wolf 4 has no weapon

000:55 blue wolf 5 has sword(20)

表示在0点55分,蓝魔2号武士wolf有一支arrow(这支arrow还可以用2次),一个bomb,还有一支攻击力为23的sword。

蓝魔4号武士wolf没武器。

蓝魔5号武士wolf有一支攻击力为20的sword。

交代武器情况时,次序依次是:arrow,bomb,sword。如果没有某种武器,某种武器就不用提。报告时,先按从西向东的顺序所有的红武士报告,然后再从西向东所有的蓝武士报告。

输出事件时:

首先按时间顺序输出;

同一时间发生的事件,按发生地点从西向东依次输出. 武士前进的事件, 算是发生在目的地。

在一次战斗中有可能发生上面的 6 至 11 号事件。这些事件都算同时发生,其时间就是战斗开始时间。一次战斗中的这些事件,序号小的应该先输出。

两个武士同时抵达同一城市,则先输出红武士的前进事件,后输出蓝武士的。

显然,13号事件发生之前的一瞬间一定发生了12号事件。输出时,这两件事算同一时间发生,但是应先输出12号事件

虽然任何一方的司令部被占领之后,就不会有任何事情发生了。但和司令部被占领同时发生的事件,全都要输出。

输入

第一行是t,代表测试数据组数

每组样例共三行。

第一行,五个整数 M,N,R,K, T。其含义为:

每个司令部一开始都有M个生命元( 1 <= M <= 10000)

两个司令部之间一共有N个城市( 1 <= N <= 20 )

arrow的攻击力是R

lion每经过一场未能杀死敌人的战斗,忠诚度就降低K。

要求输出从0时0分开始,到时间T为止(包括T) 的所有事件。T以分钟为单位,0 <= T <= 5000

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

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

输出

对每组数据,先输出一行:

Case n:

如对第一组数据就输出 Case1:

然后按恰当的顺序和格式输出到时间T为止发生的所有事件。每个事件都以事件发生的时间开头,时间格式是“时: 分”,“时”有三位,“分”有两位。

#include<iostream>
#include<iomanip>
#include<string>
#include <cstring> 
using namespace std;
 
const int num = 5, testdata = 100;//定义武士类型的数量,预定义测试数据的组数,方便日后修改。
string weaponName[3] = { "sword","bomb","arrow" };
//存放测试数据
int iniElem_Wr[testdata][num] = { 0 }, iniForce_Wr[testdata][num] = { 0 },arrowForce[testdata] = { 0 };
int lionLoyl[testdata] = { 0 };
int stop;//是否有阵营被占领

class CWarrior; class CDragon; class CNinjia; class CIceman; class CLion; class CWolf;

class CHeadquarter {
	int color;
	string colorName;
	int index = 0;
	int round;
	int site;//所在坐标
	int countEnemy = 0; int record = 0;//record用来记录抵达本阵营的enemy数字有没有改变
	CWarrior *army[200] = { NULL };
	int warriorCode = 0;
	static int warriorCreatSqueue[2][5];
public:
	int element;
	CWarrior *enemyWr[2] = { NULL };//入侵的敌军
	CWarrior *wp=NULL;//我方刚出生的武士
	CHeadquarter(int color_, int elem_, int round_, int site_, string colorNm) :color(color_), element(elem_), round(round_), site(site_), colorName(colorNm) {}
	~CHeadquarter();
	friend class CWarrior; friend class CCity; friend class CLion;
	void printCommanSituation(int time);//输出生产出来的武士信息,不包括特殊情况
	void produceWr(int time_);//生产武士
	void pritenemy(int time);//输出敌军入侵的情况
	void pritElem(int time)//输出阵营的生命元
	{
		cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
		cout << element << " elements in " << colorName << " headquarter" << endl;
	}
}; 
class CCity {
public:
	
	int site;
	int element;
	int flag; 
	int last_winner = 2;//上次战斗胜利的阵营,0代表红,1代表蓝,2代表中立
	int num_warrior;
	CWarrior *victorWr=NULL;//本城市胜者
	CWarrior *wr[2] = {NULL};//本城市的武士
	CCity(int code_, int flag_, int elem_=0, int num_=0) :site(code_), flag(flag_),element(elem_), num_warrior(num_)
	{
		
		CWarrior *wr[2] = { NULL };
		victorWr = NULL;
	}
	void elementPlus() { element += 10; victorWr = NULL; }
	void transferElem(CHeadquarter & headquarter, int time,int color = 0);
	void pritWarrior(int time_);
	void shootWr(int time_, CCity *nextCity, int color);
	void bomb(int time);
	friend class CWarrior; friend class CDragon; friend class CNinjia; friend class CIceman; friend class CLion; friend class CWolf;
};
class CWeapon {
	string name;
	int force;
	int useTime = 3;
public:
	CWeapon(string name_, int force_ = 0) :name(name_), force(force_) {}
	friend class CWarrior; friend class CDragon; friend class CNinjia; friend class CIceman; friend class CLion; friend class CWolf;
};
class CWarrior {
public:
	string name;
	int color;
	string colorName;
	int force;
	int element;
	int code;
	int site;//所在城市编号
	int tmpElem;//记录开战前的生命元,用于lion
	CWeapon *wp[3] = { NULL };
	CWarrior(string name_, int force_, int elem_, int color_, int code_, int site_, string colorNm) :force(force_), element(elem_), color(color_), code(code_), site(site_), colorName(colorNm)
	{
		name=name_;
	}
	virtual ~CWarrior()
	{
		for (int i = 0; i < 3; i++)
		{
			if (wp[i])
				delete wp[i];
		}
	}
	virtual void attack(CWarrior & enemy, CCity & city, int time);
	virtual void fightback(CWarrior & enemy, CCity & city, int time);
	void rewardElem(CHeadquarter & headquarter)//本阵营奖励获胜武士
	{
		if (headquarter.element >= 8)
		{
			element += 8;
			headquarter.element -= 8;
		}
		else
		{
			element += headquarter.element;
			headquarter.element = 0;
		}
	}
	virtual void victor(CCity & city, int time);
	virtual void defeat(CCity & city);//双方都存活的事件
	virtual void death(CWarrior & enemy, CCity &city, int time);
	virtual void moveforward(CCity *city[], int N, CHeadquarter *headquarter[], int time);//前进动作
	virtual void shoot(CWarrior *enemy, int time);
	virtual int escape(int time_,CHeadquarter &headquarter,CCity &city) { return 0; }//用于lion的逃跑
	int calDamage();//使用sword的情况
	int estimateForce();//预计伤害值
	void pritAttack(CWarrior & enemy, CCity & city, int time);
	void pritWeapon(int time);
	virtual void getWeapon(CWarrior & enemy) {}//用于wolf缴获武器
};
class CDragon :public CWarrior {
	double morale;
	
public:
	CDragon(string name_, int force_, int elem_, int color_, int code_, double morale_, int arrowforce_, int site_, string colorname) :CWarrior(name_, force_, elem_, color_, code_, site_, colorname)
	{
		morale = morale_;
		switch (code % 3)
		{
		case 0:if ((force/5) != 0) wp[0] = new CWeapon("sword", force/5); break;
		case 1:wp[1] = new CWeapon("bomb"); break;
		case 2:wp[2] = new CWeapon("arrow", arrowforce_); break;
		}
	}
	void attack(CWarrior & enemy, CCity & city, int time);
	void fightback(CWarrior & enemy, CCity & city, int time);
	void defeat(CCity & city) { city.last_winner=2;  };
	void victor(CCity & city, int time);
	void pritYell(CCity & city, int time);
};
class CNinjia :public CWarrior {
public:
	CNinjia(string name_, int force_, int elem_, int color_, int code_, int arrowforce_, int site_, string colorname) :CWarrior(name_, force_, elem_, color_, code_, site_, colorname)
	{
		switch (code % 3)
		{
		case 0: {if ((force/5) != 0) wp[0] = new CWeapon("sword", force/5); wp[1] = new CWeapon("bomb"); break; }
		case 1: {wp[1] = new CWeapon("bomb"); wp[2] = new CWeapon("arrow", arrowforce_); break; }
		case 2: {wp[2] = new CWeapon("arrow", arrowforce_); if (force / 5 != 0) wp[0] = new CWeapon("sword", force/5);  break; }
		}
	}
	void fightback(CWarrior & enemy, CCity & city,int time)
	{
		defeat(city);
		enemy.defeat(city);
	}
};
class CIceman :public CWarrior {
	int countStep = 0;
public:
	CIceman(string name_, int force_, int elem_, int color_, int code_, int arrowforce_, int site_, string colorname) :CWarrior(name_, force_, elem_, color_, code_, site_, colorname)
	{
		switch (code % 3)
		{
		case 0:if ((force/5) != 0) wp[0] = new CWeapon("sword", force/5); break;
		case 1:wp[1] = new CWeapon("bomb"); break;
		case 2:wp[2] = new CWeapon("arrow", arrowforce_); break;
		}
	}
	void moveforward(CCity *city[], int N, CHeadquarter *headquarter[], int time);
};
class CLion :public CWarrior {
	int loyalty;
	int K;//每次下降的忠诚
public:
	CLion(string name_, int force_, int elem_, int color_, int code_, int arrowforce_, int loyalty_, int K_, int site_, string colorname) :CWarrior(name_, force_, elem_, color_, code_, site_, colorname)
	{
		loyalty = loyalty_;
		K = K_;
	}
	void attack(CWarrior & enemy, CCity & city, int time);
	void fightback(CWarrior & enemy, CCity & city, int time);
	void death(CWarrior & enemy, CCity & city, int time);
	int escape(int time_, CHeadquarter &headquarter,CCity & city);
};
class CWolf :public CWarrior {
public:
	CWolf(string name_, int force_, int elem_, int color_, int code_, int arrowforce_, int site_, string colorname) :CWarrior(name_, force_, elem_, color_, code_, site_, colorname) {}
	void getWeapon(CWarrior & enemy);
};

CHeadquarter::~CHeadquarter()
{
	for (int i = 0; i < warriorCode; i++)
		if (army[i])
			delete army[i];
}
void CHeadquarter::printCommanSituation(int time)
{
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << colorName << " " << army[warriorCode]->name << " " << warriorCode + 1 << " born" << endl;
}
void CHeadquarter::produceWr(int time_)
{
	switch (warriorCreatSqueue[color][index])
	{
	case 0:
	{
		if (iniElem_Wr[round][0] <= element)
		{
			element -= iniElem_Wr[round][0];
			army[warriorCode] = new CDragon("dragon", iniForce_Wr[round][0], iniElem_Wr[round][0], color, warriorCode + 1, double(element)/ iniElem_Wr[round][0], arrowForce[round], site, colorName);
			wp = army[warriorCode];
			printCommanSituation(time_);
			cout << "Its morale is " << setiosflags(ios::fixed) << setprecision(2) << double(element) / iniElem_Wr[round][0] << endl;
			warriorCode++; index++; 
			if (index == 5) index = 0;
		}
		break;
	}
	case 1:
	{
		if (iniElem_Wr[round][1] <= element)
		{
			element -= iniElem_Wr[round][1];
			army[warriorCode] = new CNinjia("ninja", iniForce_Wr[round][1], iniElem_Wr[round][1], color, warriorCode + 1, arrowForce[round], site, colorName);
			wp = army[warriorCode];
			printCommanSituation(time_);
			warriorCode++; index++; 
			if (index == 5) index = 0;
		}
		break;
	}
	case 2:
	{
		if (iniElem_Wr[round][2] <= element)
		{
			element -= iniElem_Wr[round][2];
			army[warriorCode] = new CIceman("iceman", iniForce_Wr[round][2], iniElem_Wr[round][2], color, warriorCode + 1, arrowForce[round], site, colorName);
			wp = army[warriorCode];
			printCommanSituation(time_);
			warriorCode++; index++; 
			if (index == 5) index = 0;
		}
		break;
	}
	case 3:
	{
		if (iniElem_Wr[round][3] <= element)
		{
			element -= iniElem_Wr[round][3];
			army[warriorCode] = new CLion("lion", iniForce_Wr[round][3], iniElem_Wr[round][3], color, warriorCode + 1, arrowForce[round], element, lionLoyl[round], site, colorName);
			wp = army[warriorCode];
			printCommanSituation(time_);
			cout << "Its loyalty is " << element << endl;
			warriorCode++; index++; 
			if (index == 5) index = 0;
		}
		break;
	}
	case 4:
	{
		if (iniElem_Wr[round][4] <= element)
		{
			element -= iniElem_Wr[round][4];
			army[warriorCode] = new CWolf("wolf", iniForce_Wr[round][4], iniElem_Wr[round][4], color, warriorCode + 1, arrowForce[round], site, colorName);
			wp = army[warriorCode];
			printCommanSituation(time_);
			warriorCode++; index++; 
			if (index == 5) index = 0;
		}
		break;
	}
	}
}
void CHeadquarter::pritenemy(int time)
{
	if (record == countEnemy)
		return;
	else
	{
		switch (countEnemy)
		{
		case 0: break;
		case 1: {
			cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
			cout << enemyWr[0]->colorName << " " << enemyWr[0]->name << " " << enemyWr[0]->code << " reached " << colorName << " headquarter with " << enemyWr[0]->element << " elements and force " << enemyWr[0]->force << endl;
			record = 1; break;
		}
		case 2:
		{
			cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
			cout << enemyWr[1]->colorName << " " << enemyWr[1]->name << " " << enemyWr[1]->code << " reached " << colorName << " headquarter with " << enemyWr[1]->element << " elements and force " << enemyWr[1]->force << endl;
			cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
			cout << colorName << " headquarter was taken" << endl;
			stop = 1; record = 2; break;
		}
		}
	}
}
int CHeadquarter::warriorCreatSqueue[2][5] = { { 2,3,4,1,0 },{ 3,0,1,2,4 } };


void CCity::pritWarrior(int time_)
{
	
	if (wr[0])
	{
		cout << setfill('0') << setw(3) << time_ / 60 << ":" << setfill('0') << setw(2) << time_ % 60 << " ";
		cout << "red " << wr[0]->name << " " << wr[0]->code << " marched to city " << site  << " with " << wr[0]->element << " elements and force " << wr[0]->force << endl;
	}
	if (wr[1])
	{
		cout << setfill('0') << setw(3) << time_ / 60 << ":" << setfill('0') << setw(2) << time_ % 60 << " ";
		cout << "blue " << wr[1]->name << " " << wr[1]->code << " marched to city " << site << " with " << wr[1]->element << " elements and force " << wr[1]->force << endl;
	}
}
void CCity::bomb(int time)
{
	if (num_warrior == 2)
	{
		if ((wr[0]->element > 0)&(wr[1]->element > 0))
		{
			for (int i = 0; i < 2; i++)
			{
				if (wr[i]->wp[1] != NULL)
				{
					if ((flag == i) || ((flag == 2)&(site % 2 == 1 - i)))
					{
						if (wr[1 - i]->element > (wr[i]->force + wr[i]->estimateForce()))
						{
							if (wr[1 - i]->name != "ninja")
							{
								if (wr[i]->element <= (wr[1 - i]->force / 2 + wr[1 - i]->estimateForce()))
								{
									cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
									cout << wr[i]->colorName << " " << wr[i]->name << " " << wr[i]->code << " used a bomb and killed " << wr[1 - i]->colorName << " " << wr[1 - i]->name << " " << wr[1 - i]->code << endl;
									wr[1 - i] = NULL; wr[i] = NULL;
									
									num_warrior = 0;
									break;
								}
							}
						}
					}
					else
					{
						if (wr[i]->element <= (wr[1 - i]->force + wr[1 - i]->estimateForce()))
						{
							cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
							cout << wr[i]->colorName << " " << wr[i]->name << " " << wr[i]->code << " used a bomb and killed " << wr[1 - i]->colorName << " " << wr[1 - i]->name << " " << wr[1 - i]->code << endl;
							wr[1 - i] = NULL; wr[i] = NULL;
							num_warrior = 0; break;
						}
					}
				}
			}
		}
	}
}
void  CCity::shootWr(int time_, CCity *nextCity, int color)
{
	if ((wr[color] != NULL)&(nextCity->wr[1 - color] != NULL))
	{
		wr[color]->shoot(nextCity->wr[1 - color], time_);
	}
}
void CCity::transferElem(CHeadquarter & headquarter, int time,int color)
{
	headquarter.element += element;
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << wr[color]->colorName << " " << wr[color]->name << " " << wr[color]->code << " earned " << element << " elements for his headquarter" << endl;
	element = 0;
}

void CWarrior::attack(CWarrior & enemy,CCity & city,int time)//传入所在城市
{
	if (enemy.name == "lion")
		enemy.tmpElem = enemy.element;
	enemy.element = enemy.element - force - calDamage();
	pritAttack(enemy, city, time);
	if (enemy.element <= 0)
	{
		getWeapon(enemy);
		enemy.death(*this,city,time);
		city.victorWr= this;//城市标记胜者
		victor(city, time);
	}
	else
		enemy.fightback(* this, city,time);
	
}
void CWarrior::fightback(CWarrior & enemy, CCity & city,int time)
{
	enemy.element = enemy.element - force/2 - calDamage();
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout <<colorName<<" " << name << " " << code << " fought back against "<<enemy.colorName<<" "<< enemy.name << " " << enemy.code << " in city " << city.site << endl;
	if (enemy.element <= 0)
	{
		getWeapon(enemy);
		enemy.death(*this,city,time);
		city.victorWr = this;//城市标记胜者
		victor(city, time);
	}
	else
	{
		defeat(city);
		enemy.defeat(city);
	}
}
void CWarrior::victor(CCity & city,int time)//传入所在城市
{
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << colorName << " " << name << " " << code << " earned " << city.element << " elements for his headquarter" << endl;
	
	if ((city.flag!=color)&(city.last_winner == color))
	{
		city.flag = color;
		cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
		cout << colorName << " flag raised in city " << city.site << endl;
	}
	else
		city.last_winner = color;
}
void CWarrior::defeat(CCity & city)
{
	city.last_winner=2;
}
void CWarrior::death(CWarrior & enemy,CCity &city,int time)
{
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << colorName<<" " << name << " " << code << " was killed in city " << city.site << endl;
	
	city.num_warrior--;
	city.wr[color]=NULL;
}
void CWarrior::moveforward(CCity *city[],int N,CHeadquarter *headquarter[],int time)//传入城市数组,城市数量
{
	//将本座城市的武士数量减一,然后移动到下一座城市,并将下一座城市的武士数量加一,同时将城市中的武士指针指向自己。
	if (color == 0)
	{
		if(site!=0)
		{
			city[site]->num_warrior--;
			city[site]->wr[color] = NULL;
		}
		site++;
		if (site == N + 1)
		{
			headquarter[1]->enemyWr[headquarter[1]->countEnemy]=this;
			headquarter[1]->countEnemy++;
		}
		else
		{
			city[site]->num_warrior++;
			city[site]->wr[color] = this;
		}
	}
	if(color == 1)
	{
		
		if (site != N + 1)
		{
			city[site]->num_warrior--;
			city[site]->wr[color] = NULL;
		}
		site--;
		if (site ==0)
		{
			headquarter[0]->enemyWr[headquarter[0]->countEnemy] = this;
			headquarter[0]->countEnemy++;
		}
		else
		{
			city[site]->num_warrior++;
			city[site]->wr[color] = this;
		}
	}
}
void CWarrior::shoot(CWarrior *enemy, int time)
{
	if(wp[2])
	{
		enemy->element -= wp[2]->force;
		cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
		
		if (enemy->element <= 0)
			cout << colorName << " " << name << " "<<code<<" shot and killed " << enemy->colorName << " " << enemy->name << " " << enemy->code << endl;
		else
			cout << colorName << " " << name << " " << code << " shot" << endl;
		wp[2]->useTime--;
		if (wp[2]->useTime == 0)
		{
			delete wp[2]; wp[2] = NULL;
		}
	}
}
int  CWarrior::calDamage()
{
	if (wp[0])
	{
		int tmp = wp[0]->force;
		wp[0]->force = int(wp[0]->force* 0.8);
		if (wp[0]->force == 0)
		{
			delete wp[0]; wp[0] = NULL;
		}
		return tmp;
	}
	else
		return 0;
}
void CWarrior::pritAttack(CWarrior & enemy, CCity & city, int time)
{
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << colorName<<" " << name << " " << code << " attacked " <<enemy.colorName<<" "<< enemy.name << " " << enemy.code << " in city " << city.site<< " with " << element << " elements and force " << force << endl;
}
void CWarrior::pritWeapon(int time)
{
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << colorName << " " << name << " " << code << " has ";
	if (wp[2])
	{
		cout << "arrow(" << wp[2]->useTime << ")";
		if (wp[1] || wp[0])
			cout << ",";
		else cout << endl;
	}
	if (wp[1])
	{
		cout << "bomb";
		if (wp[0]) cout << ",";
		else cout << endl;
	}
	if (wp[0])
		cout << "sword(" << wp[0]->force << ")" << endl;
	else if((wp[0]==NULL)&(wp[1]==NULL)&(wp[2]==NULL))
		cout << "no weapon" << endl;
}
int CWarrior::estimateForce()
{
	if (wp[0])
		return wp[0]->force;
	else return 0;
}

void CDragon::attack(CWarrior & enemy, CCity & city,int time)
{
	
	if (enemy.name == "lion")
		enemy.tmpElem = enemy.element;
	enemy.element = enemy.element - force - calDamage();
	pritAttack(enemy, city, time);
	if (enemy.element <= 0)
	{
		enemy.death(*this,city,time);
		city.victorWr = this;//城市标记胜者
		victor(city, time);
	}
	else
	{
		morale -= 0.2;
		enemy.fightback(*this, city, time);
		if ((morale > 0.8)&(element > 0))
			pritYell(city, time);
	}
}
void CDragon::fightback(CWarrior & enemy, CCity & city,int time)
{
	enemy.element = enemy.element - force/2- calDamage();
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << colorName << " " << name << " " << code << " fought back against " << enemy.colorName << " " << enemy.name << " " << enemy.code << " in city " << city.site << endl;
	if (enemy.element <= 0)
	{
		enemy.death(*this,city,time);
		city.victorWr = this;//城市标记胜者
		victor(city, time);
	}
	else
	{
		morale -= 0.2;
		defeat(city);
		enemy.defeat(city);
	}
}
void CDragon::victor(CCity & city, int time)
{
	morale += 0.2;
	if((city.flag==color)||(city.site%2==(1-color)&(city.flag==2)))
		if (morale > 0.8)
			pritYell(city, time);
	CWarrior::victor(city, time);
}
void  CDragon::pritYell(CCity & city, int time)
{
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout<<colorName<<" dragon "<<code<< " yelled in city " << city.site << endl;
}

void CIceman::moveforward(CCity *city[], int N, CHeadquarter *headquarter[],int time)
{
	countStep++;
	if (countStep == 2)
	{
		if (element > 9)
			element -= 9;
		else
			element = 1;
		force += 20;
		countStep = 0;
	}
	CWarrior::moveforward(city, N, headquarter,time);
}

void CLion::attack(CWarrior & enemy, CCity & city,int time)
{
	tmpElem = element;
	if (enemy.name == "lion")
		enemy.tmpElem = enemy.element;
	enemy.element -= force;
	pritAttack(enemy, city, time);
	if (enemy.element <= 0)
	{
		enemy.death(*this,city,time);
		city.victorWr = this;//城市标记胜者
		victor(city, time);
	}
	else
	{
		loyalty -= K;
		enemy.fightback(*this, city,time);
	}
}
void CLion::fightback(CWarrior & enemy, CCity & city, int time)
{
	enemy.element = enemy.element - force / 2 - calDamage();
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << colorName << " " << name << " " << code << " fought back against " << enemy.colorName << " " << enemy.name << " " << enemy.code << " in city " << city.site << endl;
	if (enemy.element <= 0)
	{
		getWeapon(enemy);
		enemy.death(*this, city, time);
		city.victorWr = this;//城市标记胜者
		victor(city, time);
	}
	else
	{
		loyalty -= K;
		defeat(city);
		enemy.defeat(city);
	}
}
void CLion::death(CWarrior & enemy,CCity& city,int time)
{
	cout << setfill('0') << setw(3) << time / 60 << ":" << setfill('0') << setw(2) << time % 60 << " ";
	cout << colorName << " lion "<< code << " was killed in city " << city.site << endl;
	enemy.element += tmpElem; city.num_warrior--;
	city.wr[color]=NULL;
}
int CLion::escape(int time_, CHeadquarter &headquarter,CCity & city)
{
	if (loyalty <= 0)
	{
		cout << setfill('0') << setw(3) << time_ / 60 << ":" << setfill('0') << setw(2) << time_ % 60 << " ";
		cout << colorName<<" lion "  << code << " ran away" << endl;
	
		return 1;
	}
	else return 0;
}

void CWolf::getWeapon(CWarrior & enemy)
{
	for (int i = 0; i < 3; i++)
		if ((wp[i] == NULL)&(enemy.wp[i] != NULL))
			wp[i] = new CWeapon(*enemy.wp[i]);
}

int main()
{
	int test;
	cin >> test;
	int iniElem_Hedqr[testdata] = { 0 }, num_City[testdata] = { 0 }, T[testdata] = { 0 };
	for (int i = 0; i < test; i++)//输入所有测试数据
	{
		cin >> iniElem_Hedqr[i] >> num_City[i] >> arrowForce[i] >> lionLoyl[i] >> T[i];
		for (int j = 0; j < num; j++)
			cin >> iniElem_Wr[i][j];
		for (int j = 0; j < num; j++)
			cin >> iniForce_Wr[i][j];
	}
	for (int i = 0; i < test; i++)//开始游戏
	{
		int time = 0;
		CHeadquarter *headquater[2];
		CCity*city[25] = {NULL};
		headquater[0] = new CHeadquarter(0, iniElem_Hedqr[i], i, 0, "red");
		headquater[1] = new CHeadquarter(1, iniElem_Hedqr[i], i, num_City[i] + 1, "blue");
for (int j = 1; j < num_City[i] + 1; j++)
{
	city[j] = new CCity(j, 2);
	city[j]->site = j;
}
cout << "Case " << i + 1 << ":" << endl;
while (stop != 1)
{
	//制造武士
	headquater[0]->produceWr(time);
	headquater[1]->produceWr(time);
	time += 5; if (time > T[i]) break;//第5分钟,自西向东,判定lion是否逃走
	if (headquater[0]->wp)
		if (headquater[0]->wp->escape(time, *headquater[0], *city[1]) == 1)
			headquater[0]->wp = NULL;
	for (int j = 1; j < num_City[i] + 1; j++)
	{
		for (int k = 0; k < 2; k++)
		{
			if (city[j]->wr[k])
			{
				if (city[j]->wr[k]->escape(time, *headquater[k], *city[j]) == 1)
				{
					city[j]->wr[k] = NULL;
					city[j]->num_warrior--;
				}
			}
		}
	}
	if (headquater[1]->wp)
		if (headquater[1]->wp->escape(time, *headquater[1], *city[1]) == 1)
			headquater[1]->wp = NULL;
	time += 5; if (time > T[i]) break;//第10分钟,如果指针不为空,那么指针指向的武士前进
	for (int j = num_City[i]; j > 0; j--)
		if (city[j]->wr[0])
			city[j]->wr[0]->moveforward(city, num_City[i], headquater, time);
	if (headquater[0]->wp)
	{
		headquater[0]->wp->moveforward(city, num_City[i], headquater, time);
		headquater[0]->wp = NULL;
	}
	for (int j = 1; j < num_City[i] + 1; j++)
		if (city[j]->wr[1])
			city[j]->wr[1]->moveforward(city, num_City[i], headquater, time);
	if (headquater[1]->wp)
	{
		headquater[1]->wp->moveforward(city, num_City[i], headquater, time);
		headquater[1]->wp = NULL;
	}
	headquater[0]->pritenemy(time);//打印武士前进的情况
	for (int j = 1; j < num_City[i] + 1; j++)
		city[j]->pritWarrior(time);
	headquater[1]->pritenemy(time);
	if (stop != 1)
	{
		time += 10; if (time > T[i]) break;//第20分钟,城市增加10个element
		for (int j = 1; j < num_City[i] + 1; j++)
			city[j]->elementPlus();
		time += 10; if (time > T[i]) break;//第30分钟,如果城市只有一个武士,那么武士取走element
		for (int j = 1; j < num_City[i] + 1; j++)
		{
			if ((city[j]->wr[0] == NULL)&(city[j]->wr[1] != NULL))
				city[j]->transferElem(*headquater[1], time, 1);
			if ((city[j]->wr[0] != NULL)&(city[j]->wr[1] == NULL))
				city[j]->transferElem(*headquater[0], time, 0);
		}
		time += 5; if (time > T[i]) break;//第35分钟,判断是否有arrow,并且邻近城市是否有敌人
		if (num_City[i] != 1)
		{
			city[1]->shootWr(time, city[2], 0);
			for (int j = 2; j < num_City[i]; j++)
			{
				city[j]->shootWr(time, city[j + 1], 0);
				city[j]->shootWr(time, city[j - 1], 1);
			}
			city[num_City[i]]->shootWr(time, city[num_City[i] - 1], 1);
		}
		time += 3; if (time > T[i]) break;//第38分钟,拥有bomb的武士行动
		for (int j = 1; j < num_City[i] + 1; j++)
			city[j]->bomb(time);
		time += 2; if (time > T[i]) break;//第40分钟,自西向东,战斗开始
		for (int j = 1; j < num_City[i] + 1; j++)
		{
			if (city[j]->num_warrior == 2)
			{
				if ((city[j]->wr[0]->element > 0)&(city[j]->wr[1]->element > 0))
				{
					if ((city[j]->flag == 0) || ((city[j]->flag == 2)&(city[j]->site % 2 == 1)))
						city[j]->wr[0]->attack(*city[j]->wr[1], *city[j], time);
					else
						city[j]->wr[1]->attack(*city[j]->wr[0], *city[j], time);
				}
				else if ((city[j]->wr[1]->element <= 0)&(city[j]->wr[0]->element <=0))
				{
					city[j]->victorWr = NULL;
					city[j]->num_warrior = 0;
					city[j]->wr[0] = NULL; city[j]->wr[1] = NULL;
				}
				else if ((city[j]->wr[0]->element > 0)&(city[j]->wr[1]->element <= 0))
				{
					city[j]->wr[0]->getWeapon(*city[j]->wr[1]);
					city[j]->wr[0]->victor(*city[j], time);
					city[j]->victorWr = city[j]->wr[0];
					city[j]->wr[1] = NULL; city[j]->num_warrior--;
				}
				else if ((city[j]->wr[0]->element <= 0)&(city[j]->wr[1]->element>0))
				{
					city[j]->wr[1]->getWeapon(*city[j]->wr[0]);
					city[j]->victorWr = city[j]->wr[1];
					city[j]->wr[1]->victor(*city[j], time);
					city[j]->wr[0] = NULL; city[j]->num_warrior--;
				}		
			}
			else if (city[j]->num_warrior == 1)
			{
				if (city[j]->wr[0])
				{
					if (city[j]->wr[0]->element <= 0)
					{
						city[j]->wr[0] = NULL;
						city[j]->num_warrior = 0;
					}
				}
				else if (city[j]->wr[1])
				{
					if (city[j]->wr[1]->element <= 0)
					{
						city[j]->wr[1] = NULL;
						city[j]->num_warrior = 0;
					}
				}
			}
		}
					for (int j = 1; j < num_City[i] + 1; j++)//自西向东,蓝阵营奖励获胜武士
					{
						if (city[j]->victorWr)
							if (city[j]->victorWr->color == 1)
								city[j]->victorWr->rewardElem(*headquater[1]);
					}
					for (int j = num_City[i]; j > 0; j--)//自东向西,红阵营奖励获胜武士
					{
						if (city[j]->victorWr)
							if (city[j]->victorWr->color == 0)
								city[j]->victorWr->rewardElem(*headquater[0]);
					}
					for (int j = 1; j < num_City[i] + 1; j++)//胜者回收城市element
						if (city[j]->victorWr)
						{
								headquater[city[j]->victorWr->color]->element += city[j]->element;
								city[j]->element = 0;
						}
					time += 10; if (time > T[i]) break;//第50分钟,阵营报告element
					headquater[0]->pritElem(time);
					headquater[1]->pritElem(time);
					time += 5; if (time > T[i]) break;//第55分钟,武士报告武器情况
					for (int j = 1; j < num_City[i] + 1; j++)
						if (city[j]->wr[0])
							city[j]->wr[0]->pritWeapon(time);
					if (headquater[1]->enemyWr[0])
						headquater[1]->enemyWr[0]->pritWeapon(time);
					if (headquater[0]->enemyWr[0])
						headquater[0]->enemyWr[0]->pritWeapon(time);
					for (int j = 1; j < num_City[i] + 1; j++)
						if (city[j]->wr[1])
							city[j]->wr[1]->pritWeapon(time);
					
				}
				time += 5;
			}
		delete headquater[0]; delete headquater[1];
		for (int i = 0; i < 25; i++)
			if (city[i])
				delete city[i];
		stop = 0;
	}
	return 0;
}


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值