编程作业--魔兽世界三(开战)

魔兽世界三(开战)

描述

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为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。

sword的攻击力是使用者当前攻击力的20%(去尾取整)。

bomb的攻击力是使用者当前攻击力的40%(去尾取整),但是也会导致使用者受到攻击,对使用者的攻击力是对敌人取整后的攻击力的1/2(去尾取整)。Bomb一旦使用就没了。

arrow的攻击力是使用者当前攻击力的30%(去尾取整)。一个arrow用两次就没了。

武士降生后就朝对方司令部走,在经过的城市如果遇到敌人(同一时刻每个城市最多只可能有1个蓝武士和一个红武士),就会发生战斗。战斗的规则是:

  1. 在奇数编号城市,红武士先发起攻击

  2. 在偶数编号城市,蓝武士先发起攻击

  3. 战斗开始前,双方先对自己的武器排好使用顺序,然后再一件一件地按顺序使用。编号小的武器,排在前面。若有多支arrow,用过的排在前面。排好序后,攻击者按此排序依次对敌人一件一件地使用武器。如果一种武器有多件,那就都要用上。每使用一件武器,被攻击者生命值要减去武器攻击力。如果任何一方生命值减为0或小于0即为死去。有一方死去,则战斗结束。

  4. 双方轮流使用武器,甲用过一件,就轮到乙用。某一方把自己所有的武器都用过一轮后,就从头开始再用一轮。如果某一方没有武器了,那就挨打直到死去或敌人武器用完。武器排序只在战斗前进行,战斗中不会重新排序。

  5. 如果双方武器都用完且都还活着,则战斗以平局结束。如果双方都死了,也算平局。

  6. 有可能由于武士自身攻击力太低,而导致武器攻击力为0。攻击力为0的武器也要使用。如果战斗中双方的生命值和武器的状态都不再发生变化,则战斗结束,算平局。

  7. 战斗的胜方获得对方手里的武器。武士手里武器总数不超过10件。缴获武器时,按照武器种类编号从小到大缴获。如果有多件arrow,优先缴获没用过的。

  8. 如果战斗开始前双方都没有武器,则战斗视为平局。如果先攻击方没有武器,则由后攻击方攻击。

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

编号为n的dragon降生时即获得编号为n%3 的武器。dragon在战斗结束后,如果还没有战死,就会欢呼。

编号为n的ninjia降生时即获得编号为n%3 和(n+1)%3的武器。ninja 使用bomb不会让自己受伤。

编号为n的iceman降生时即获得编号为n%3 的武器。iceman每前进一步,生命值减少10%(减少的量要去尾取整)。

编号为n的lion降生时即获得编号为n%3 的武器。lion 有“忠诚度”这个属性,其初始值等于它降生之后其司令部剩余生命元的数目。每前进一步忠诚度就降低K。忠诚度降至0或0以下,则该lion逃离战场,永远消失。但是已经到达敌人司令部的lion不会逃跑。lion在己方司令部可能逃跑。

wolf降生时没有武器,但是在战斗开始前会抢到敌人编号最小的那种武器。如果敌人有多件这样的武器,则全部抢来。Wolf手里武器也不能超过10件。如果敌人arrow太多没法都抢来,那就先抢没用过的。如果敌人也是wolf,则不抢武器。

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

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

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

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

制造武士需要生命元。

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

如果司令部中的生命元不足以制造某本该造的武士,那就从此停止制造武士。

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

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

在每个小时的第35分:在有wolf及其敌人的城市,wolf要抢夺对方的武器。

在每个小时的第40分:在有两个武士的城市,会发生战斗。

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

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

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

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

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

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

1) 武士降生

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

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

如果造出的是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) wolf抢敌人的武器

000:35 blue wolf 2 took 3 bomb from red dragon 2 in city 4

表示在0点35分,4号城市中,红魔1号武士wolf 抢走蓝魔2号武士dragon 3个bomb。为简单起见,武器不写复数形式

5) 报告战斗情况

战斗只有3种可能的输出结果:

000:40 red iceman 1 killed blue lion 12 in city 2 remaining 20 elements

表示在0点40分,1号城市中,红魔1号武士iceman 杀死蓝魔12号武士lion后,剩下生命值20

000:40 both red iceman 1 and blue lion 12 died in city 2

注意,把红武士写前面

000:40 both red iceman 1 and blue lion 12 were alive in city 2

注意,把红武士写前面

6) 武士欢呼

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

7) 武士抵达敌军司令部

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

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

8) 司令部被占领

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

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

000:50 100 elements in red headquarter

000:50 120 elements in blue headquarter

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

10)武士报告情况

000:55 blue wolf 2 has 2 sword 3 bomb 0 arrow and 7 elements

为简单起见,武器都不写复数形式。elements一律写复数,哪怕只有1个

交代武器情况时,次序依次是:sword,bomb, arrow。

输出事件时:

首先按时间顺序输出;

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

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

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

对于同一城市,同一时间发生的事情,先输出红方的,后输出蓝方的。

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

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

输入

第一行是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

输出

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

Case n:

如对第一组数据就输出 Case 1:

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

样例输入

120 1 10 40020 20 30 10 205 5 5 5 5

样例输出

Case 1:000:00 blue lion 1 bornIts loyalty is 10000:10 blue lion 1 marched to city 1 with 10 elements and force 5000:50 20 elements in red headquarter000:50 10 elements in blue headquarter000:55 blue lion 1 has 0 sword 1 bomb 0 arrow and 10 elements001:05 blue lion 1 ran away001:50 20 elements in red headquarter001:50 10 elements in blue headquarter002:50 20 elements in red headquarter002:50 10 elements in blue headquarter003:50 20 elements in red headquarter003:50 10 elements in blue headquarter004:50 20 elements in red headquarter004:50 10 elements in blue headquarter005:50 20 elements in red headquarter005:50 10 elements in blue headquarter

提示

请注意浮点数精度误差问题。OJ上的编译器编译出来的可执行程序,在这方面和你电脑上执行的程序很可能会不一致。5 * 0.3 的结果,有的机器上可能是 15.00000001,去尾取整得到15,有的机器上可能是14.9999999,去尾取整后就变成14。因此,本题不要写 5 * 0.3,要写 5 * 3 / 10。

这题可以说是相当的nice了,感觉前两个版本白写了,完全重新coding了....

(程序里面加了很多调试)

代码:

#pragma warning(disable:4996)
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
string weapon[3] = { "sword","bomb","arrow" };
int m, citys, loyalty_d, deadline;//m:生命值
bool r_win = false, b_win = false;
class weapons {
public:
	int weapons_n;//武器的编号
	string name;//武器名称
	int w_atk;//武器的攻击力
	int n;//武器寿命(即所能使用的次数)
	bool w_ok;//武器是否还能用
	weapons(string name,int atk) {
		this->name = name;
		if (name == "sword") {
			this->n = 0xffff;
			this->w_atk = atk * 2/10;
			weapons_n = 0;
		}
		else if (name == "bomb") {
			this->n = 1;
			this->w_atk = atk * 4 / 10;
			weapons_n = 1;
		}
		else if (name == "arrow") {
			this->n = 2;
			this->w_atk = atk * 3 / 10;
			weapons_n = 2;
		}
		w_ok = true;
	}

	void update_w() {
		if (this->w_ok==true) {
			if (this->name != "sword") {
				if (this->n>0) this->n--;
				if (this->n <= 0) this->w_ok = false;
			}
		}

	}

};
struct w_rule_1 {
	bool operator()(const weapons &a, const weapons &b) const {//对象比较
		if (a.weapons_n < b.weapons_n) {
			return true;
		}
		else if (a.weapons_n == b.weapons_n) {//使用过的优先(n--)
			return a.n < b.n;
		}
		else {
			return false;
		}
	}
};

struct w_rule_2 {
	bool operator()(const weapons &a, const weapons &b) const {//对象比较
		if (a.weapons_n < b.weapons_n) {
			return true;
		}
		else if (a.weapons_n == b.weapons_n) {//没使用过的优先
			return a.n > b.n;
		}
		else {
			return false;
		}
	}
};

class warrior {//武士类
public:
	int n, hp, atk, flag,city_n,elements;//编号,生命值,攻击力,红蓝方标记,所在城市,剩余生命元
	bool alive;
	int loyalty, loyalty_d;
	bool isninja;//默认值是false
	bool isiceman;
	bool isdragon;
	bool islion;
	bool iswolf;
	vector<weapons> arms;
	bool exist;
	bool isescape;
	warrior() {
		exist = false;
	}
	warrior(int n, int hp, int atk, int flag,int elements) {
		this->n = n;
		this->hp = hp;
		this->atk = atk;
		this->flag = flag;
		this->elements = elements;
		alive = true;
		if (flag == 0) city_n = 0;//r初始所在城市编号
		else city_n = citys + 1;//b初始所在城市编号
		exist = true;
	}
	bool isalive() {
		return alive;
	}
	void update_s() {//更新武士存活的状态
		if (hp<=0) {
			alive = false;
		}
	}
	bool weapon_equal(vector<weapons> &v) {
		int cnt = 0;
		for (vector<weapons>::iterator iter = arms.begin(); iter != arms.end(); ++iter) {
			if (iter->n != v[cnt++].n) {//发现状态不一致
				return false;
			}
		}
		return true;
	}

	void attack(warrior &w,int id) {//用当前武士手中总体编号为id的武器去攻击武士w
		if (this->isalive()&&w.isalive()) {	
			if (this->hp > 0) {
				if (this->isninja == true && this->arms[id].name == "bomb") ;//ninja使用bomb就不用减自己的生命力
				else if(this->arms[id].name=="bomb") this->hp -= this->arms[id].w_atk/2;//自己减去生命力
				w.hp -= this->arms[id].w_atk;//敌方减去生命力
				this->update_s();//更新武士存活的状态
				w.update_s();
				
				this->arms[id].update_w();//更新武器状态(只需更新攻击者的)
			}
		}
	}

	virtual void print() {}
	virtual void goahead(int hours) {}
	virtual string getname() { return string(NULL); }
	virtual void escape(int hours){}
};

class dragon :public warrior {
public:
	double morale;//士气

	dragon(int n_t, int hp_t, int atk_t, int flag_t, int elements_t) :warrior(n_t, hp_t, atk_t, flag_t,elements_t) {
		morale = double(elements_t) / hp_t;
		arms.push_back(*(new weapons(weapon[n_t % 3],atk_t)));
		isdragon = true;
	}
	virtual void print() {
		if (flag == 0)
			printf("%03d:00 red dragon %d born\n", n - 1, n);
		else
			printf("%03d:00 blue dragon %d born\n", n - 1, n);

	}
	virtual void goahead(int hours) {
		if (flag == 0)
			printf("%03d:10 red dragon %d marched to city %d with %d elements and force %d\n", hours, n, city_n,hp,atk);
		else
			printf("%03d:10 blue dragon %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
	}
	virtual string getname() {
		return string("dragon");
	}
};

class ninja :public warrior {
public:

	ninja(int n_t, int hp_t, int atk_t, int flag_t,int elements_t) :warrior(n_t, hp_t, atk_t, flag_t, elements_t) {
		arms.push_back(*(new weapons(weapon[n_t % 3], atk_t)));
		arms.push_back(*(new weapons(weapon[(n_t+1) % 3], atk_t)));
		isninja = true;
	}
	virtual void print() {
		if (flag == 0)
			printf("%03d:00 red ninja %d born\n", n - 1, n);
		else
			printf("%03d:00 blue ninja %d born\n", n - 1, n);
	}
	virtual void goahead(int hours) {
		if (flag == 0)
			printf("%03d:10 red ninja %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
		else
			printf("%03d:10 blue ninja %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
	}
	virtual string getname() {
		return string("ninja");
	}
};

class iceman :public warrior {
public:

	iceman(int n_t, int hp_t, int atk_t, int flag_t,int elements_t) :warrior(n_t, hp_t, atk_t, flag_t, elements_t) {
		flag = flag_t;
		arms.push_back(*(new weapons(weapon[n_t % 3], atk_t)));
		isiceman = true;
	}

	virtual void print() {
		if (flag == 0)
			printf("%03d:00 red iceman %d born\n", n - 1, n);
		else
			printf("%03d:00 blue iceman %d born\n", n - 1, n);
	}
	virtual void goahead(int hours) {
		hp -=(hp / 10);
		if (flag == 0)
			printf("%03d:10 red iceman %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
		else
			printf("%03d:10 blue iceman %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
	}
	virtual string getname() {
		return string("iceman");
	}
};

class lion :public warrior {
public:

	lion(int n_t, int hp_t, int atk_t, int flag_t,int loyalty_d,int elements_t) :warrior(n_t, hp_t, atk_t, flag_t, elements_t) {
		loyalty = elements_t;
		arms.push_back(*(new weapons(weapon[n_t % 3], atk_t)));
		islion = true;
		this->loyalty_d = loyalty_d;
	}
	virtual void print() {
		if (flag == 0)
			printf("%03d:00 red lion %d born\n", n - 1, n);
		else
			printf("%03d:00 blue lion %d born\n", n - 1, n);
		cout << "Its loyalty is " << loyalty << endl;
	}
	//lion逃跑05,此时还没前进一步
	virtual void escape(int hours) {
		if (loyalty <= 0) {
			if (flag == 0 && isalive()&& city_n != citys + 1) {//实际上在05时刻,还没前进一步,是不可能占领了司令部的(因为在那之前10时刻的gameover()会检测到并结束对战)
				printf("%03d:05 red lion %d ran away\n", hours, n);//lion逃跑后武器怎么办呢?
				alive = false;
				return;//跑了
			}
			else if (flag == 1 && isalive() && city_n != 0) {
				printf("%03d:05 blue lion %d ran away\n", hours, n);
				alive = false;
				return;//跑了
			}
		}
	}

	//10
	virtual void goahead(int hours) {
		loyalty -= loyalty_d;
		if (flag == 0)
			printf("%03d:10 red lion %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
		else
			printf("%03d:10 blue lion %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
	}
	virtual string getname() {
		return string("lion");
	}
};

class wolf :public warrior {
public:

	wolf(int n_t, int hp_t, int atk_t, int flag_t,int elements_t) :warrior(n_t, hp_t, atk_t, flag_t, elements_t) {
		flag = flag_t;
		iswolf = true;
	}
	virtual void print() {
		if (flag == 0)
			printf("%03d:00 red wolf %d born\n", n - 1, n);
		else
			printf("%03d:00 blue wolf %d born\n", n - 1, n);
	}
	virtual void goahead(int hours) {
		if (flag == 0)
			printf("%03d:10 red wolf %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
		else
			printf("%03d:10 blue wolf %d marched to city %d with %d elements and force %d\n", hours, n, city_n, hp, atk);
	}
	virtual string getname() {
		return string("wolf");
	}
};

//10
void gameover(warrior &r, warrior &b, int hours) {
	//抵达,占领司令部10,10之后的事情就不会再发生了
	if (r.exist&&b.exist) {//同时占领
		printf("%03d:10 red %s %d reached blue headquarter with %d elements and force %d\n", hours, r.getname().c_str(), r.n, r.hp, r.atk);
		printf("%03d:10 red headquarter was taken\n", hours);
		printf("%03d:10 blue %s %d reached red headquarter with %d elements and force %d\n", hours, b.getname().c_str(), b.n, b.hp, b.atk);
		printf("%03d:10 red headquarter was taken\n", hours);
		b_win = true;
		r_win = true;
	}else if (r.exist&&!b.exist) {//r占领b
		printf("%03d:10 red %s %d reached blue headquarter with %d elements and force %d\n", hours, r.getname().c_str(), r.n, r.hp, r.atk);
		printf("%03d:10 red headquarter was taken\n", hours);
		r_win = true;
	}else if (b.exist&&!r.exist) {//b占领r
		printf("%03d:10 blue %s %d reached red headquarter with %d elements and force %d\n", hours, b.getname().c_str(), b.n, b.hp, b.atk);
		printf("%03d:10 red headquarter was taken\n", hours);
		b_win = true;
	}
}

int get_weapon_atk(int atk, string name) {
	if (name == "sword") return atk * 2 / 10;
	if (name == "bomb") return atk * 4 / 10;
	if (name == "arrow") return atk * 3 / 10;
	return 0;
}

//35
void rob(warrior &r, warrior &b, int n, int hours) {
	//wolf的特性 35
	if (r.iswolf&&b.iswolf) return;
	if (r.iswolf && !b.iswolf) {//r抢b的武器
		if (b.arms.empty()) return;
		sort(b.arms.begin(), b.arms.end(), w_rule_2());//(r抢b)的武器排序(2)
		string name_t = b.arms[0].name;//抢的武器名
		int sum = 0;//抢的武器数目
		for (vector<weapons>::iterator iter = b.arms.begin(); iter != b.arms.end(); ++iter) {
			if (r.arms.size() >= 10) break;
			if (name_t != iter->name) break;//确保只抢编号最小的那种武器
			iter->w_atk = get_weapon_atk(r.atk, iter->name);
			r.arms.push_back(*iter);
			++sum;
		}
		//抢完了,汇报
		printf("%03d:35 red wolf %d took %d ", hours, r.n, sum);
		cout << name_t << " from blue " << b.getname();
		printf(" %d in city %d\n", b.n, n);
	}
	else if (!r.iswolf&&b.iswolf) {//b抢r的武器
		if (r.arms.empty()) return;
		sort(r.arms.begin(), r.arms.end(), w_rule_2());//(b抢r)的武器排序(2)
		string name_t = r.arms[0].name;//抢的武器名
		int sum = 0;//抢的武器数目
		for (vector<weapons>::iterator iter = r.arms.begin(); iter != r.arms.end(); ++iter) {
			if (b.arms.size() >= 10) break;
			if (name_t != iter->name) break;//确保只抢编号最小的那种武器
			iter->w_atk = get_weapon_atk(b.atk, iter->name);
			b.arms.push_back(*iter);
			++sum;
		}
		//抢完了,汇报
		printf("%03d:35 blue wolf %d took %d ", hours, b.n, sum);
		cout << name_t << " from red " << r.getname();
		printf(" %d in city %d\n", r.n, n);
	}
}

bool weapons_atk_ok(vector<weapons> &v) {//检测是否还有能产生伤害的武器
	for (vector<weapons>::iterator iter = v.begin(); iter != v.end(); ++iter) {
		if (iter->w_atk > 0) return true;
	}
	return false;
}

bool weapons_w_ok(vector<weapons> &v) {//检测是否还有武器能用
	for (vector<weapons>::iterator iter = v.begin(); iter != v.end(); ++iter) {
		if (iter->w_ok) return true;
	}
	return false;
}

//40
//调用前做好入口检查,当没有遇敌的时候只会发生武士降生,(lion逃跑)武士前进和武士报告情况(没交战也要报告),这种情况应另外考虑
void battle(warrior &r, warrior &b, int n,int hours) {//n:城市编号,hours:整点时刻,要确保r,b都活着才能传入参数

	bool flag = false;//平局的标记,false表示非平局
	if (r.arms.size() == 0 && b.arms.size() == 0) {//如果战斗开始时双方武器都没武器,则以平局结束
		flag = true;
	} 
	//if (!weapons_atk_ok(r.arms)  && !weapons_atk_ok(b.arms)) {//双方都没有能产生攻击力的武器了,则平局
	//	flag = true;
	//}
	sort(r.arms.begin(), r.arms.end(), w_rule_1());//武器排序(1)
	sort(b.arms.begin(), b.arms.end(), w_rule_1());
	int r_id = 0, b_id = 0;//红方,蓝方当前使用的武器编号
	while (flag==false&&r.alive && b.alive) {
		int r_hp_t = r.hp, b_hp_t = b.hp;
		vector<weapons> r_arms_t(r.arms), b_arms_t(b.arms);
		r_id %= r.arms.size();//轮换使用武器
		b_id %= b.arms.size();//轮换使用武器
		if (r.arms.size() > 0&& weapons_w_ok(r.arms)) {//不排除只有其中一方没武器
			while (r.arms[r_id].w_ok == false) {
				++r_id;
				r_id %= r.arms.size();//轮换使用武器
			}
		}
		if (b.arms.size() > 0 && weapons_w_ok(b.arms)) {//不排除只有其中一方没武器
			while (b.arms[b_id].w_ok == false) {
				++b_id;
				b_id %= b.arms.size();//轮换使用武器
			}
		}
		if (!weapons_w_ok(r.arms) && !weapons_w_ok(b.arms)) break;
		//if (!weapons_atk_ok(r.arms) && !weapons_atk_ok(b.arms)) break;
		if (n % 2 == 0) {//偶数城市,blue先攻击
			if (b.arms.size() > 0 && b.arms[b_id].w_ok) {
				b.attack(r, b_id);//不排除只有其中一方没武器
				++b_id;
			}
			if (r.arms.size() > 0 && r.arms[r_id].w_ok) {
				r.attack(b, r_id);//不排除只有其中一方没武器
				++r_id;
			}
		}
		else {
			if (r.arms.size() > 0 && r.arms[r_id].w_ok) {
				r.attack(b, r_id);//不排除只有其中一方没武器
				++r_id;
			}
			if (b.arms.size() > 0 && b.arms[b_id].w_ok) {
				b.attack(r, b_id);//不排除只有其中一方没武器
				++b_id;
			}
		}

		if (r.hp == r_hp_t && b.hp == b_hp_t) {
			if (r.weapon_equal(r_arms_t) && b.weapon_equal(b_arms_t)) {
				break;//生命值,武器状态不再发生改变了,以平局结束(可能是武器攻击力太低(只剩sword了)或者武器都用完了)
			}
		}

	}

	if (!r.alive && !b.alive) {//都死了的平局
		printf("%03d:40 both red ", hours);
		cout << r.getname() << " " << r.n << " and blue " << b.getname() << " " << b.n << " died in city " << n << endl;

	}
	if(!r.arms.empty())
		for (vector<weapons>::iterator iter = r.arms.begin(); iter != r.arms.end();) {//清理报废的武器
			if (iter->w_ok == false) {
				iter = r.arms.erase(iter);
			}
			else {
				++iter;
			}
		}
	if(!b.arms.empty())
		for (vector<weapons>::iterator iter = b.arms.begin(); iter != b.arms.end();) {//清理报废的武器
			if (iter->w_ok == false) {
				iter = b.arms.erase(iter);
			}
			else {
				++iter;
			}
		}

	//打完以后更新武器的状态并报告战斗情况 40
	//都活着的平局(可能是武器攻击力太低或者武器都用完了)
	if (r.alive && b.alive) {
		printf("%03d:40 both red ", hours);
		cout << r.getname() << " " << r.n << " and blue " << b.getname() << " " << b.n << " were alive in city " << n << endl;
	}

	//有胜负
	if (r.alive &&!b.alive) {//r赢
		printf("%03d:40 red ", hours);
		cout<<r.getname()<<" "<<r.n<<" killed blue "<<b.getname()<<" "<<b.n<<" in city "<<n<<" remaining "<<r.hp<<" elements"<<endl;
		//r缴获b的武器
		sort(b.arms.begin(), b.arms.end(), w_rule_2());
		for (vector<weapons>::iterator iter = b.arms.begin(); iter != b.arms.end(); ++iter) {
			if (r.arms.size() >= 10) break;
			iter->w_atk = get_weapon_atk(r.atk, iter->name);
			r.arms.push_back(*iter);
		}

	}
	if (b.alive &&!r.alive) {//b赢
		printf("%03d:40 blue ", hours);
		cout << b.getname() << " " << b.n << " killed red " << r.getname() << " " << r.n << " in city " << n << " remaining " << b.hp << " elements" << endl;
		//b缴获r的武器
		sort(r.arms.begin(), r.arms.end(), w_rule_2());
		for (vector<weapons>::iterator iter = r.arms.begin(); iter != r.arms.end(); ++iter) {
			if (b.arms.size() >= 10) break;
			iter->w_atk = get_weapon_atk(b.atk, iter->name);
			b.arms.push_back(*iter);
		}

	}

	//dragon的特性--欢呼 40
	if (r.alive && r.isdragon) {
		printf("%03d:40 red dragon %d yelled in city %d\n", hours, r.n, n);
	}
	if (b.alive && b.isdragon) {
		printf("%03d:40 blue dragon %d yelled in city %d\n", hours, b.n, n);
	}

}

//50
void showheadquarters(int hours,int r_elements,int b_elements) {
	printf("%03d:50 %d elements in red headquarter\n", hours, r_elements);
	printf("%03d:50 %d elements in blue headquarter\n", hours, b_elements);
}

void getweapons(vector<weapons> &v,int *a) {
	a[0] = 0;
	a[1] = 0;
	a[2] = 0;
	for (vector<weapons>::iterator iter = v.begin(); iter != v.end(); ++iter) {
		if (iter->name == "sword") ++a[0];
		if (iter->name == "bomb") ++a[1];
		if (iter->name == "arrow") ++a[2];
	}

}

//55 调用前做好入口检查
void showwarriors(warrior* r[], warrior* b[],int hours) {
	int a[3];
	for (int i = 1; i <= citys; ++i) {
		if (r[i]!=NULL&&r[i]->isalive()) {//只有存在的且活着的才报告情况
			getweapons(r[i]->arms, a);
			printf("%03d:55 red %s %d has %d sword %d bomb %d arrow and %d elements\n",
				hours, r[i]->getname().c_str(), r[i]->n,a[0],a[1],a[2],r[i]->hp);
		}
		if (b[i]!=NULL&&b[i]->isalive()) {
			getweapons(b[i]->arms, a);
			printf("%03d:55 blue %s %d has %d sword %d bomb %d arrow and %d elements\n",
				hours, b[i]->getname().c_str(), b[i]->n, a[0], a[1], a[2], b[i]->hp);
		}
	}
}

int main()
{
	//freopen("C:\\Users\\pc\\Desktop\\openjudge\\in.txt", "r", stdin);
	freopen("C:\\Users\\pc\\Desktop\\openjudge\\out.txt", "w", stdout);
	int N;
	scanf("%d", &N);
	int cnt = 0;//case的编号
	while (N--) {
		scanf("%d %d %d %d", &m, &citys, &loyalty_d, &deadline);
		int hour = deadline / 60;
		int minuter = deadline - hour * 60;
		warrior* battlefield[2][25];//战斗的场所
		for (int i = 0; i < 2; ++i) {//初始化
			for (int j = 0; j < 25; ++j) {
				battlefield[i][j] = NULL;
			}
		}
		int d, n, i, l, w;//武士们的所需生命值
		scanf("%d %d %d %d %d", &d, &n, &i, &l, &w);
		int min_hp = min(d, min(n, min(i, min(l, w))));
		int da, na, ia, la, wa;//武士们的攻击力
		scanf("%d %d %d %d %d", &da, &na, &ia, &la, &wa);
		printf("Case %d:\n", ++cnt);

		int r = m, b = m;//双方剩余生命值
		int cnt_r = 1, cnt_b = 1;//武士的编号,-1就是整点时刻
		vector<warrior*> r_army, b_army;
		int r_end = 0, b_end = 0;//等于1时,表示已经无法再生成了
		int r_i_ok = 0, r_l_ok = 0, r_w_ok = 0, r_n_ok = 0, r_d_ok = 0;//轮换生成,表明检测过
		int b_i_ok = 0, b_l_ok = 0, b_w_ok = 0, b_n_ok = 0, b_d_ok = 0;

		int r_ok = 0, b_ok = 0;//等于1时,说明已经生成了一个,等于0时说明还没生成,此时才可以生成
		while (1) {//生成武士
			//if (max(cnt_r, cnt_b) == hour + 2) break;//武士编号从1开始(1-hour+1),整点时刻从0开始(0-hour),因为有余数,所以可能要多保留一个状态
			if (r_end == 1 && b_end == 1) break;//只有当无法生成时才跳出循环 
			r_ok = 0;
			b_ok = 0;
			if (r_ok == 0 && r_end == 0) {
				if (r_i_ok == 1 && r_l_ok == 1 && r_w_ok == 1 && r_n_ok == 1 && r_d_ok == 1) {
					r_i_ok = 0;
					r_l_ok = 0;
					r_w_ok = 0;
					r_n_ok = 0;
					r_d_ok = 0;
				}
				if (r >= i && r_ok == 0 && r_i_ok == 0) {//iceman
					r -= i;
					r_army.push_back(new iceman(cnt_r++, i, ia, 0,r));
					r_ok = 1;//红方本轮生成了,本轮下面就不用再生成了
					r_i_ok = 1;
				}
				else if (r_i_ok == 0 && r < i) {//检测到,本该生成,但因为生命元不够而不能生成
					r_end = 1;
					r_ok = 1;//确保本轮下面也不生成了
				}
				if (r >= l && r_ok == 0 && r_l_ok == 0) {//lion
					r -= l;
					r_army.push_back(new lion(cnt_r++, l,la, 0, loyalty_d,r));
					r_ok = 1;
					r_l_ok = 1;
				}
				else if (r_l_ok == 0 && r < l) {
					r_end = 1;
					r_ok = 1;
				}
				if (r >= w && r_ok == 0 && r_w_ok == 0) {//wolf
					r -= w;
					r_army.push_back(new wolf(cnt_r++, w, wa, 0,r));
					r_ok = 1;
					r_w_ok = 1;
				}
				else if (r_w_ok == 0 && r < w) {
					r_end = 1;
					r_ok = 1;
				}
				if (r >= n && r_ok == 0 && r_n_ok == 0) {//ninja
					r -= n;
					r_army.push_back(new ninja(cnt_r++, n, na, 0,r));
					r_ok = 1;
					r_n_ok = 1;
				}
				else if (r_n_ok == 0 && r < n) {
					r_end = 1;
					r_ok = 1;
				}
				if (r >= d && r_ok == 0 && r_d_ok == 0) {//dragon
					r -= d;
					r_army.push_back(new dragon(cnt_r++, d, da, 0, r));
					r_ok = 1;
					r_d_ok = 1;
				}
				else if (r_d_ok == 0 && r < d) {
					r_end = 1;
					r_ok = 1;
				}
			}

			if (b_ok == 0 && b_end == 0) {
				//if (r_ok == 0 && r_end == 0) continue;//red一方没有生成,且还有足够的生命元的话,此时blue一方也不能生成,需要下一轮重新遍历
				if (b_i_ok == 1 && b_l_ok == 1 && b_w_ok == 1 && b_n_ok == 1 && b_d_ok == 1) {
					b_i_ok = 0;
					b_l_ok = 0;
					b_w_ok = 0;
					b_n_ok = 0;
					b_d_ok = 0;
				}
				if (b >= l && b_ok == 0 && b_l_ok == 0) {//lion
					b -= l;
					b_army.push_back(new lion(cnt_b++, l,la, 1, loyalty_d,b));
					b_ok = 1;
					b_l_ok = 1;
				}
				else if (b_l_ok == 0 && b < l) {
					b_end = 1;
					b_ok = 1;
				}
				if (b >= d && b_ok == 0 && b_d_ok == 0) {//dragon
					b -= d;
					b_army.push_back(new dragon(cnt_b++, d, da, 1, b));
					b_ok = 1;
					b_d_ok = 1;
				}
				else if (b_d_ok == 0 && b < d) {
					b_end = 1;
					b_ok = 1;
				}
				if (b >= n && b_ok == 0 && b_n_ok == 0) {//ninja
					b -= n;
					b_army.push_back(new ninja(cnt_b++, n, na, 1,b));
					b_ok = 1;
					b_n_ok = 1;
				}
				else if (b_n_ok == 0 && b < n) {
					b_end = 1;
					b_ok = 1;
				}
				if (b >= i && b_ok == 0 && b_i_ok == 0) {//iceman
					b -= i;
					b_army.push_back(new iceman(cnt_b++, i, ia, 1,b));
					b_ok = 1;
					b_i_ok = 1;
				}
				else if (b_i_ok == 0 && b < i) {
					b_end = 1;
					b_ok = 1;
				}
				if (b >= w && b_ok == 0 && b_w_ok == 0) {//wolf
					b -= w;
					b_army.push_back(new wolf(cnt_b++, w, wa, 1,b));
					b_ok = 1;
					b_w_ok = 1;
				}
				else if (b_w_ok == 0 && b < w) {
					b_end = 1;
					b_ok = 1;
				}
			}


		}

		int r_size = r_army.size(), b_size = b_army.size();
		//cout << r_size << " " << b_size <<" "<<hour<<endl;
		bool flag_0 = false, flag_05=false,flag_10 = false, flag_35 = false, flag_40 = false, flag_50 = false,flag_55=false;//余数时间控制
		if (minuter >= 0) flag_0 = true;
		if (minuter >= 5) flag_05 = true;
		if (minuter >= 10) flag_10 = true;
		if (minuter >= 35) flag_35 = true;
		if (minuter >= 40) flag_40 = true;
		if (minuter >= 50) flag_50 = true;
		if (minuter >= 55) flag_55 = true;
		for (int i = 0; i <= hour; ++i) {
			if (i == hour && flag_0 == false) break;
			//降生00
			if (i<r_size) r_army[i]->print();
			if (i<b_size) b_army[i]->print();

			//lion 逃跑 05
			if (i == hour && flag_05 == false) break;
			for (int j = 1; j <= citys; ++j) {
				if (battlefield[0][j] != NULL || battlefield[1][j] != NULL) {//战场上有战士																	
					if (battlefield[0][j]!=NULL&&battlefield[0][j]->islion) battlefield[0][j]->escape(i);
					if (battlefield[1][j]!=NULL&&battlefield[1][j]->islion) battlefield[1][j]->escape(i);
				}
			}

			//前进一步 10
			if (i == hour && flag_10 == false) break;
			//for (int j = 0; j <= i; ++j) {
			//	if (j<r_size&&r_army[j]->alive) r_army[j]->goahead(i);
			//	if (j<b_size&&b_army[j]->alive) b_army[j]->goahead(i);
			//}

			//分配到战场上(10)
			for (int j = 0; j <= i; ++j) {
				if (j<r_size&&r_army[j]->alive) battlefield[0][++r_army[j]->city_n] = r_army[j];//red: 1 ~ citys+1
				if (j<b_size&&b_army[j]->alive) battlefield[1][--b_army[j]->city_n] = b_army[j];//blue: citys ~ 0
			}

			//前进一步 10
			for (int j = 1; j <= citys; ++j) {
				if (battlefield[0][j] != NULL && battlefield[0][j]->alive) battlefield[0][j]->goahead(i);
				if (battlefield[1][j] != NULL && battlefield[1][j]->alive) battlefield[1][j]->goahead(i);
			}

			//占领司令部(10)
			if (!r_win && !b_win) { //gamover 10
				if (battlefield[1][citys + 1] != NULL || battlefield[0][0] != NULL) {
					if (battlefield[1][citys + 1] == NULL && battlefield[0][0] != NULL) {
						if(battlefield[0][0]->alive) gameover(*(new warrior()), *battlefield[0][0], i);
					}
					else if (battlefield[1][citys + 1] != NULL && battlefield[0][0] == NULL) {
						if(battlefield[1][citys + 1]->alive) gameover(*battlefield[1][citys + 1], *(new warrior()), i);
					}
					else {
						if (battlefield[1][citys + 1]->alive&&battlefield[0][0]->alive)
							gameover(*battlefield[1][citys + 1], *battlefield[0][0], i);//red占领blue(1)的citys+1号,blue占领red(0)的0号
					}
				}
			}

			//wolf 35,rob
			if (i == hour && flag_35 == false) break;
			if (r_win || b_win) break;
			for (int j = 1; j <= citys; ++j) {
				if (battlefield[0][j] != NULL && battlefield[1][j] != NULL) {//战场上双方都有战士																	
					if (battlefield[0][j]->alive && battlefield[1][j]->alive) {//且都活着
						if (battlefield[0][j]->iswolf || battlefield[1][j]->iswolf) rob(*battlefield[0][j], *battlefield[1][j], j, i);
					}
				}
			}

			//battle 40
			if (i == hour && flag_40 == false) break;
			for (int j = 1; j <= citys; ++j) {
				if (battlefield[0][j] != NULL && battlefield[1][j] != NULL) {//战场上双方都有战士																	
					if (battlefield[0][j]->alive && battlefield[1][j]->alive) {//且都活着
						battle(*battlefield[0][j], *battlefield[1][j], j, i);
					}

				}
			}

			//50 司令部报告生命元数量
			if (i == hour && flag_50 == false) break;
			showheadquarters(i, r_size == 0 ? m : battlefield[0][1]->elements, b_size == 0 ? m : battlefield[1][citys]->elements);
			//55 武士报告情况
			if (i == hour && flag_55 == false) break;
			showwarriors(battlefield[0], battlefield[1], i);
			
			//for (int i = 0; i < 2; ++i) {//初始化
			//	for (int j = 0; j < 25; ++j) {
			//		battlefield[i][j] = NULL;
			//	}
			//}
		}
	}

	//rob(*new iceman(1, 1, 1, 0, 10), *new wolf(2, 3, 4, 1, 10),5,20);
	//system("pause");
	return 0;
}


 
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值