045:魔兽世界三(开战) + 自己思路及代码

北大mooc,程序设计与算法(三)

题目

描述
魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为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个蓝武士和一个红武士),就会发生战斗。战斗的规则是:

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

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

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

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

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

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

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

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

编号为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为止发生的所有事件。每个事件都以事件发生的时间开头,时间格式是“时: 分”,“时”有三位,“分”有两位。

样例输入
1
20 1 10 400
20 20 30 10 20
5 5 5 5 5
样例输出
Case 1:
000:00 blue lion 1 born
Its loyalty is 10
000:10 blue lion 1 marched to city 1 with 10 elements and force 5
000:50 20 elements in red headquarter
000:50 10 elements in blue headquarter
000:55 blue lion 1 has 0 sword 1 bomb 0 arrow and 10 elements
001:05 blue lion 1 ran away
001:50 20 elements in red headquarter
001:50 10 elements in blue headquarter
002:50 20 elements in red headquarter
002:50 10 elements in blue headquarter
003:50 20 elements in red headquarter
003:50 10 elements in blue headquarter
004:50 20 elements in red headquarter
004:50 10 elements in blue headquarter
005:50 20 elements in red headquarter
005:50 10 elements in blue headquarter

自己代码

分别有武器类、士兵类、阵营类和战斗系统单独成一类;
类别不同的武器继承武器类,类别不同的士兵继承士兵类;
武器用指针数组进行存放,作为士兵类的成员对象。士兵用指针数组进行存放,作为阵营类的成员对象;
士兵前进后统计每个士兵的位置,打包成数组放进阵营里;
设置战斗结束标志位。

#include <iostream>
#include <cstring>
#include <iomanip>
#include <algorithm>
using namespace std;

#define endl '\n'

class Weapon{ 
public:
    int weaponId, ad, available; 
	string typeName;
    
    Weapon(int weaponId_, int ad_, int available_, string typeName_): weaponId(weaponId_), ad(ad_), available(available_), typeName(typeName_) {}
};

class Sword: public Weapon{
public:
	Sword(int weaponId_, int ad_): Weapon(weaponId_, ad_, 999, "sword") {}
};

class Bomb: public Weapon{
public:
	Bomb(int weaponId_, int ad_): Weapon(weaponId_, ad_, 1, "bomb") {}
};

class Arrow: public Weapon{
public:
	Arrow(int weaponId_, int ad_): Weapon(weaponId_, ad_, 2, "arrow") {}
};

class Soldier{ 
public:
	//所属阵营,武士编号,生命,攻击,武器数量,武士类型,武士位置,忠诚度
    int headId, soldierId, hp, ad, weaponNumber, type, location, loyalty;
	//各类别的武器数量
    int weaponClass[3]; 
    string typeName;
	Weapon* weaponList[10]; 

    Soldier(int headId_, int soldierId_, int hp_, int ad_, int location_, int type_, string typeName_, int loyalty_ = 999): headId(headId_), soldierId(soldierId_), hp(hp_), ad(ad_), type(type_), typeName(typeName_), location(location_), loyalty(loyalty_), weaponNumber(0) {
		for(int i = 0; i < 10; ++i)
			weaponList[i] = nullptr; 
		memset(weaponClass, 0, sizeof(weaponClass));
	}
	
	void ChooseWeapon (int n) {
		switch(n) {
			case 0: weaponList[weaponNumber++] = new Sword(0, ad * 2 / 10);
					++weaponClass[0];
					break;
			case 1: weaponList[weaponNumber++] = new Bomb(1, ad * 4 / 10);
					++weaponClass[1];
					break;
			case 2: weaponList[weaponNumber++] = new Arrow(2, ad * 3 / 10);
					++weaponClass[2];
					break;
			default: cout << "!!武器选择错误" << endl; 
		}
		return;
	}
	
	~Soldier() {
		for(int i = 0; i < 10; ++i)
			delete weaponList[i]; 
	}
};

class Dragon: public Soldier{ 
public:
    Dragon(int headId_, int soldierId_, int hp_, int ad_, int location_): Soldier(headId_, soldierId_, hp_, ad_, location_, 0, "dragon") { 
		ChooseWeapon(soldierId % 3);
	}

};

class Ninja: public Soldier{ 
public:
    Ninja(int headId_, int soldierId_, int hp_, int ad_, int location_): Soldier(headId_, soldierId_, hp_, ad_, location_, 1, "ninja") { 
		ChooseWeapon(soldierId % 3);
		ChooseWeapon((soldierId+1) % 3);
	}

};

class Iceman: public Soldier{ 
public:
    Iceman(int headId_, int soldierId_, int hp_, int ad_, int location_): Soldier(headId_, soldierId_, hp_, ad_, location_, 2, "iceman") { 
		ChooseWeapon(soldierId % 3);
	}
};

class Lion: public Soldier{ 
public:
    Lion(int headId_, int soldierId_, int hp_, int ad_, int loyalty_, int location_): Soldier(headId_, soldierId_, hp_, ad_, location_, 3, "lion", loyalty_) { 
		ChooseWeapon(soldierId % 3);
	}
};

class Wolf: public Soldier{ 
public:
    Wolf(int headId_, int soldierId_, int hp_, int ad_, int location_): Soldier(headId_, soldierId_, hp_, ad_, location_, 4, "wolf") { }

};

class Headquarter{ 
public:
    int hp, number, headId;
    int whereSoldier[24];
	//造兵顺序
    int* order;	
    int* p = order;
	
    Soldier* soldierList[110];
    
    Headquarter(int hp_, int headId_, int* order_): hp(hp_), headId(headId_), order(order_), number(0) {
		for(int i = 0; i < 110; ++i)
			soldierList[i] = nullptr; 
		memset(whereSoldier, 0, sizeof(whereSoldier));
	}
    
    void MakeSoldier(int* hpSoldier, int* adSoldier, int cityNumber, int times) {
    	if(hp > hpSoldier[*p]) {
    		switch(*p) {
	    		case 0: hp -= hpSoldier[0];
	    				++number;
						soldierList[number-1] = new Dragon(headId, number, hpSoldier[0], adSoldier[0], headId*(cityNumber+1));
						whereSoldier[headId*(cityNumber+1)] = number;
	    				break;
				case 1: hp -= hpSoldier[1];
						++number;
						soldierList[number-1] = new Ninja(headId, number, hpSoldier[1], adSoldier[1], headId*(cityNumber+1));
						whereSoldier[headId*(cityNumber+1)] = number;
						break;
				case 2: hp -= hpSoldier[2];
						++number;
						soldierList[number-1] = new Iceman(headId, number, hpSoldier[2], adSoldier[2], headId*(cityNumber+1));
						whereSoldier[headId*(cityNumber+1)] = number;
						break;
				case 3: hp -= hpSoldier[3];
						++number;
						soldierList[number-1] = new Lion(headId, number, hpSoldier[3], adSoldier[3], hp, headId*(cityNumber+1));
						whereSoldier[headId*(cityNumber+1)] = number;
						break;
				case 4: hp -= hpSoldier[4];
						++number;
						soldierList[number-1] = new Wolf(headId, number, hpSoldier[4], adSoldier[4], headId*(cityNumber+1));
						whereSoldier[headId*(cityNumber+1)] = number;
						break;
				default: p = order;
						cout << "!!武士选择错误" << endl; 
			}
			if(headId == 0) {
				cout << setw(3) << setfill('0') << times/60 << ':' << setw(2) << setfill('0') << times%60 << " red " << soldierList[number-1]->typeName << ' ' << number << " born" << endl;
				if(*p == 3)
					cout << "Its loyalty is " << soldierList[number-1]->loyalty << endl;
			}
			else if(headId == 1) {
				cout << setw(3) << setfill('0') << times/60 << ':' << setw(2) << setfill('0') << times%60 << " blue " << soldierList[number-1]->typeName << ' ' << number << " born" << endl;
				if(*p == 3)
					cout << "Its loyalty is " << soldierList[number-1]->loyalty << endl;
			}
			
			if(p == order + 4)
				p = order;
			else
				++p;
		}	
		return;
	}
	
	~Headquarter() {
		for(int i = 0; i < 110; ++i)
			delete soldierList[i];
	}
};

//战斗系统 
class CombatSystem {
public:
	int times = 0;
	
	//lion忠诚度判断
	void IfLoyalty(Headquarter& red, Headquarter& blue, int cityNumber) {
		for(int i = 0; i <= cityNumber+1; ++i) {
			int idr = red.whereSoldier[i]-1;
			int idb = blue.whereSoldier[i]-1;
			if(red.whereSoldier[i] != 0 && red.soldierList[idr]->type == 3 && red.soldierList[idr]->loyalty <= 0) {
				red.whereSoldier[i] = 0;
				cout << setw(3) << setfill('0') << times/60 << ':' << setw(2) << setfill('0') << times%60 << " red lion " << idr+1 << " ran away" << endl;
				delete red.soldierList[idr];
				red.soldierList[idr] = nullptr;
			}
			if(blue.whereSoldier[i] != 0 && blue.soldierList[idb]->type == 3 && blue.soldierList[idb]->loyalty <= 0) {
				blue.whereSoldier[i] = 0;
				cout << setw(3) << setfill('0') << times/60 << ':' << setw(2) << setfill('0') << times%60 << " blue lion " << idb+1 << " ran away" << endl;
				delete blue.soldierList[idb];
				blue.soldierList[idb] = nullptr;
			}
		}
	}
	
	//武器排序比较函数
	static int WeaponCmp(Weapon*& w1, Weapon*& w2) {
		if(w1->available == 0)
			return 0;
		else if(w2->available == 0)
			return 1;
		else if(w1->weaponId < w2->weaponId)
			return 1;
		else if(w1->weaponId > w2->weaponId)
			return 0;
		else if(w1->weaponId == 2)
			return w1->available < w2->available;
		else
			return 0;
	}
	
	//武器排序并统计该武士各类武器数量及武器总数
	void CountWeaponNumber(Soldier*& s) {
		sort(s->weaponList, s->weaponList + s->weaponNumber, WeaponCmp);
		int weaponNum = 0;
		int weaponClassNum[3] = {0, 0, 0};
		for(int i = 0; i < s->weaponNumber; ++i) {
			if(s->weaponList[i] != nullptr && s->weaponList[i]->available != 0) {
				weaponNum += 1;
				weaponClassNum[s->weaponList[i]->weaponId] += 1;
			}	
		}
		s->weaponNumber = weaponNum;
		s->weaponClass[0] = weaponClassNum[0];
		s->weaponClass[1] = weaponClassNum[1];
		s->weaponClass[2] = weaponClassNum[2];
		if(s->weaponClass[0] + s->weaponClass[1] + s->weaponClass[2] != s->weaponNumber)
			cout << "!!武器统计错误" << endl; 
		return;
	}
	
	//统计各武士位置
	void CountSoldier(Headquarter& h) {
		memset(h.whereSoldier, 0, sizeof(h.whereSoldier));
		for(int i = 0; i < h.number; ++i) {
			if(h.soldierList[i] != nullptr) {
				CountWeaponNumber(h.soldierList[i]);
				h.whereSoldier[h.soldierList[i]->location] = h.soldierList[i]->soldierId;
			}
		}
		return;
	}
	 
	//武士前进
	int SoldierGo(Headquarter& red, Headquarter& blue, int k, int cityNumber) {
		int headWinFlag = 0;
		for(int i = 0; i <= cityNumber+1; ++i) {
			if(red.whereSoldier[i] != 0) {
				int idr = red.whereSoldier[i]-1;
				red.soldierList[idr]->location++;
				if(red.soldierList[idr]->type == 3 && red.soldierList[idr]->location != (1-red.headId)*(cityNumber+1))
					red.soldierList[idr]->loyalty -= k;
				else if(red.soldierList[idr]->type == 2) 
					red.soldierList[idr]->hp -= red.soldierList[idr]->hp / 10;
			}
			if(blue.whereSoldier[i] != 0) {
				int idb = blue.whereSoldier[i]-1;
				blue.soldierList[idb]->location--;
				if(blue.soldierList[idb]->type == 3 && blue.soldierList[idb] -> location != (1-blue.headId)*(cityNumber+1))
					blue.soldierList[idb]->loyalty -= k;
				else if(blue.soldierList[idb]->type == 2) 
					blue.soldierList[idb]->hp -= blue.soldierList[idb]->hp / 10;
			}
		}
		CountSoldier(red);
		CountSoldier(blue);
		for(int i = 0; i <= cityNumber+1; ++i) {
			if(red.whereSoldier[i] != 0) {
				int idr = red.whereSoldier[i]-1;
				//判断是否到达敌方司令部
				if(red.soldierList[idr]->location >= cityNumber+1) {
					cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " red " << red.soldierList[idr]->typeName << ' ' << idr+1 << " reached blue headquarter with " << red.soldierList[idr]->hp << " elements and force " << red.soldierList[idr]->ad << endl;
					cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " blue headquarter was taken" << endl;
					headWinFlag = 1;
				}
				else
					cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " red " << red.soldierList[idr]->typeName << ' ' << idr+1 << " marched to city " << red.soldierList[idr]->location << " with " << red.soldierList[idr]->hp << " elements and force " << red.soldierList[idr]->ad << endl;
			}
			if(blue.whereSoldier[i] != 0) {
				int idb = blue.whereSoldier[i]-1;
				//判断是否到达敌方司令部
				if(blue.soldierList[idb]->location <= 0) {
					cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " reached red headquarter with " << blue.soldierList[idb]->hp << " elements and force " << blue.soldierList[idb]->ad << endl;
					cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " red headquarter was taken" << endl;
					headWinFlag = 1;
				}
				else
					cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " marched to city " << blue.soldierList[idb]->location << " with " << blue.soldierList[idb]->hp << " elements and force " << blue.soldierList[idb]->ad << endl;
			}
		}
		return headWinFlag;
	}
	
	//缴获武器
	void GrabWeapon(Soldier*& s1, Soldier*& s2) {
		for(int w1 = s1->weaponNumber, w2 = 0; w1 < 10, w2 < s2->weaponNumber; ++w1, ++w2) {
			if(s2->weaponList[w2]->available > 0) {
				s1->ChooseWeapon(s2->weaponList[w2]->weaponId);
				s1->weaponList[s1->weaponNumber-1]->available = s2->weaponList[w2]->available;
				s2->weaponList[w2]->available = 0;
			}
		}
		CountWeaponNumber(s1);
		CountWeaponNumber(s2);
		return;
	}
	
	//wolf抢武器
	void WolfGrabWeapon(Headquarter& red, Headquarter& blue, int cityNumber) {
		for(int i = 0; i <= cityNumber+1; ++i) {
			int idr = red.whereSoldier[i]-1, idb = blue.whereSoldier[i]-1;
			if(red.whereSoldier[i] != 0 && red.soldierList[idr]->type == 4 && blue.whereSoldier[i] != 0 && blue.soldierList[idb]->type != 4) {
				//被抢方从第一件武器开始找,可用便依次放在wolf的武器列表后面 
				for(int w1 = red.soldierList[idr]->weaponNumber, w2 = 0; w1 < 10, w2 < blue.soldierList[idb]->weaponNumber; ++w1, ++w2) {
					//wolf得到对应武器
					red.soldierList[idr]->ChooseWeapon(blue.soldierList[idb]->weaponList[w2]->weaponId);
					//被抢方的武器可用次数赋值给wolf得到的武器可用次数
					red.soldierList[idr]->weaponList[red.soldierList[idr]->weaponNumber - 1]->available = blue.soldierList[idb]->weaponList[w2]->available;
					//清空被抢方的武器可用次数
					blue.soldierList[idb]->weaponList[w2]->available = 0;
					//wolf只抢一类武器,判断若下一件武器为另一类武器 或没有下一件武器或 wolf自身武器已满10 则结束抢夺,跳出循环并输出抢夺信息
					if(w1 >= 10 || w2 >= blue.soldierList[idb]->weaponNumber || blue.soldierList[idb]->weaponList[w2+1] == nullptr || blue.soldierList[idb]->weaponList[w2+1]->available <= 0 || blue.soldierList[idb]->weaponList[w2]->weaponId != blue.soldierList[idb]->weaponList[w2+1]->weaponId) {
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " red wolf " << idr+1 << " took " << w2+1 << ' ' << blue.soldierList[idb]->weaponList[w2]->typeName << " from blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " in city " << i << endl;
						break;
					}
				}
				//抢夺后,重新武器排序并统计数量
				CountWeaponNumber(red.soldierList[idr]);
			}
				
			else if(blue.whereSoldier[i] != 0 && blue.soldierList[idb]->type == 4 && red.whereSoldier[i] != 0 && red.soldierList[idr]->type != 4) {
				for(int w1 = blue.soldierList[idb]->weaponNumber, w2 = 0; w1 < 10, w2 < red.soldierList[idr]->weaponNumber; ++w1, ++w2) {
					blue.soldierList[idb]->ChooseWeapon(red.soldierList[idr]->weaponList[w2]->weaponId);
					blue.soldierList[idb]->weaponList[blue.soldierList[idb]->weaponNumber - 1]->available = red.soldierList[idr]->weaponList[w2]->available;
					red.soldierList[idr]->weaponList[w2]->available = 0;
					if(w1 >= 10 || w2 >= red.soldierList[idr]->weaponNumber || red.soldierList[idr]->weaponList[w2+1] == nullptr || red.soldierList[idr]->weaponList[w2+1]->available <= 0 || red.soldierList[idr]->weaponList[w2]->weaponId != red.soldierList[idr]->weaponList[w2+1]->weaponId) {
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " blue wolf " << idb+1 << " took " << w2+1 << ' ' << red.soldierList[idr]->weaponList[w2]->typeName << " from red " << red.soldierList[idr]->typeName << ' ' << idr+1 << " in city " << i << endl;
						break;
					}
				}
				CountWeaponNumber(blue.soldierList[idb]);
			}
		}
		return;
	}
	
	//检验状态是否改变
	int CheckState(Soldier*& s1, Soldier*& s2) {
		int s1WeaponNum = 0, s2WeaponNum = 0, s1TotalAd = 0, s2TotalAd = 0;
		int s1WeaponClassNum[3] = {0, 0, 0}, s2WeaponClassNum[3] = {0, 0, 0};
		for(int i = 0; i < s1->weaponNumber; ++i) {
			if(s1->weaponList[i] != nullptr && s1->weaponList[i]->available != 0) {
				s1WeaponNum += 1;
				s1WeaponClassNum[s1->weaponList[i]->weaponId] += 1;
				if(s1->weaponList[i]->weaponId == 0)
					s1TotalAd += s1->weaponList[i]->ad;
			}
		}
		for(int j = 0; j < s2->weaponNumber; ++j) {
			if(s2->weaponList[j] != nullptr && s2->weaponList[j]->available != 0) {
				s2WeaponNum += 1;
				s2WeaponClassNum[s2->weaponList[j]->weaponId] += 1;
				if(s2->weaponList[j]->weaponId == 0)
					s2TotalAd += s2->weaponList[j]->ad;
			}
		}
		if((s1WeaponNum == 0 && s2WeaponNum == 0) || (s1TotalAd == 0 && s2TotalAd == 0 && s1WeaponClassNum[1] == 0 && s2WeaponClassNum[1] == 0 && s1WeaponClassNum[2] == 0 && s2WeaponClassNum[2] == 0))
			return 1;
		else
			return 0;
	}

	//战斗
	int Combat(Soldier*& s1, Soldier*& s2) {
		int i1 = 0, i2 = 0, winflag = 0;
		while(winflag == 0) {
			//round一次回合中找武器的次数,找遍了都没有说明他没有可用武器了
			int round1 = 0, round2 = 0;
			//判断该武器是否可用,若不可用,找到可用次数大于0的武器
			while(round1 < s1->weaponNumber && s1->weaponList[i1]->available == 0) {
				++i1;
				if(i1 >= s1->weaponNumber) 
					i1 = 0;
				++round1;
			}
			//s1攻击s2 
			if(round1 < s1->weaponNumber) {
				s2->hp -= s1->weaponList[i1]->ad;
				//炸弹反伤
				if(s1->weaponList[i1]->weaponId == 1 && s1->type != 1) {
					s1->hp -= (s1->weaponList[i1]->ad / 2);
				}	
				if(s1->weaponList[i1]->weaponId != 0) {
					--s1->weaponList[i1]->available;
				}
				//使用后换武器
				++i1;
				if(i1 >= s1->weaponNumber) 
					i1 = 0;
			}
			//战斗结果判断
			if(s2->hp <= 0 && s1->hp <= 0) {
				winflag = 3; //两败俱伤
				break;
			}	
			else if(s2->hp <= 0 && s1->hp > 0) {
				winflag = 1; //第一个人赢
				break;
			}
			else if(s2->hp > 0 && s1->hp <= 0) {
				winflag = 2; //第二个人赢
				break;
			}		
			
			while(round2 < s2->weaponNumber && s2->weaponList[i2]->available == 0) {
				++i2;
				if(i2 >= s2->weaponNumber) 
					i2 = 0;
				++round2;
			}
			//s2攻击s1 
			if(round2 < s2->weaponNumber) {
				s1->hp -= s2->weaponList[i2]->ad;
				if(s2->weaponList[i2]->weaponId == 1 && s2->type != 1) {
					s2->hp -= (s2->weaponList[i2]->ad/2);
				}
				if(s2->weaponList[i2]->weaponId != 0) {
					--s2->weaponList[i2]->available;
				}
				//使用后换武器
				++i2;
				if(i2 >= s2->weaponNumber) 
					i2 = 0;
			}
			
			if(s2->hp <= 0 && s1->hp <= 0) {
				winflag = 3; //两败俱伤
				break;
			}	
			else if(s2->hp <= 0 && s1->hp > 0) {
				winflag = 1; //第一个人赢
				break;
			}
			else if(s2->hp > 0 && s1->hp <= 0) {
				winflag = 2; //第二个人赢
				break;
			}
			else if(round1 >= s1->weaponNumber && round2 >= s2->weaponNumber) {
				winflag = 4; //两边都无可用武器,平局
				break;
			}
			else if(CheckState(s1, s2) == 1) {
				winflag = 4; //双方无交手,状态不变,平局 
				break;
			}
		}
		return winflag;
	}
	
	//寻找战场
	void FindCombat(Headquarter& red, Headquarter& blue, int cityNumber) {
		for(int i = 0; i <= cityNumber+1; ++i) {
			if(red.whereSoldier[i] != 0 && blue.whereSoldier[i] != 0) {
				int idr = red.whereSoldier[i]-1;
				int idb = blue.whereSoldier[i]-1;
				int winflag = 0; //战斗结果标记,1第一个人赢,2第二个人赢,3两败俱伤,4都活着
				if(i % 2 == 1) {
					winflag = Combat(red.soldierList[idr], blue.soldierList[idb]);
					if(winflag == 1) {
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " red " <<  red.soldierList[idr]->typeName << ' ' << idr+1 << " killed blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " in city " << i << " remaining " << red.soldierList[idr]->hp << " elements" <<endl;
						GrabWeapon(red.soldierList[idr], blue.soldierList[idb]);
						blue.whereSoldier[i] = 0;
						delete blue.soldierList[idb];
						blue.soldierList[idb] = nullptr;
					}
					else if(winflag == 2) {
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " blue " <<  blue.soldierList[idb]->typeName << ' ' << idb+1 << " killed red " << red.soldierList[idr]->typeName << ' ' << idr+1 << " in city " << i << " remaining " << blue.soldierList[idb]->hp << " elements" <<endl;
						GrabWeapon(blue.soldierList[idb], red.soldierList[idr]);
						red.whereSoldier[i] = 0;
						delete red.soldierList[idr];
						red.soldierList[idr] = nullptr;
					}
					else if(winflag == 3) {
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " both red " <<  red.soldierList[idr]->typeName << ' ' << idr+1 << " and blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " died in city " << i <<endl;
						red.whereSoldier[i] = 0;
						delete red.soldierList[idr];
						red.soldierList[idr] = nullptr;
						blue.whereSoldier[i] = 0;
						delete blue.soldierList[idb];
						blue.soldierList[idb] = nullptr;
					}
					else {
						CountWeaponNumber(red.soldierList[idr]);
						CountWeaponNumber(blue.soldierList[idb]);
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " both red " <<  red.soldierList[idr]->typeName << ' ' << idr+1 << " and blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " were alive in city " << i <<endl;
					}
				}
				else {
					winflag = Combat(blue.soldierList[idb], red.soldierList[idr]);
					if(winflag == 2) {
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " red " <<  red.soldierList[idr]->typeName << ' ' << idr+1 << " killed blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " in city " << i << " remaining " << red.soldierList[idr]->hp << " elements" <<endl;
						GrabWeapon(red.soldierList[idr], blue.soldierList[idb]);
						blue.whereSoldier[i] = 0;
						delete blue.soldierList[idb];
						blue.soldierList[idb] = nullptr;
					}
					else if(winflag == 1) {
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " blue " <<  blue.soldierList[idb]->typeName << ' ' << idb+1 << " killed red " << red.soldierList[idr]->typeName << ' ' << idr+1 << " in city " << i << " remaining " << blue.soldierList[idb]->hp << " elements" <<endl;
						GrabWeapon(blue.soldierList[idb], red.soldierList[idr]);
						red.whereSoldier[i] = 0;
						delete red.soldierList[idr];
						red.soldierList[idr] = nullptr;
					}
					else if(winflag == 3) {
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " both red " <<  red.soldierList[idr]->typeName << ' ' << idr+1 << " and blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " died in city " << i <<endl;
						red.whereSoldier[i] = 0;
						delete red.soldierList[idr];
						red.soldierList[idr] = nullptr;
						blue.whereSoldier[i] = 0;
						delete blue.soldierList[idb];
						blue.soldierList[idb] = nullptr;
					}
					else {
						CountWeaponNumber(red.soldierList[idr]);
						CountWeaponNumber(blue.soldierList[idb]);
						cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " both red " <<  red.soldierList[idr]->typeName << ' ' << idr+1 << " and blue " << blue.soldierList[idb]->typeName << ' ' << idb+1 << " were alive in city " << i <<endl;
					}
				}
				//dragon欢呼
				if(red.soldierList[idr] != nullptr && red.soldierList[idr]->type == 0 && red.soldierList[idr]->hp > 0)
					cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " red dragon " << idr+1 << " yelled in city " << i << endl;
				if(blue.soldierList[idb] != nullptr && blue.soldierList[idb]->type == 0 && blue.soldierList[idb]->hp > 0)
					cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " blue dragon " << idb+1 << " yelled in city " << i << endl;
			}
		}
		return;
	}
	
	//武士报告自己的情况
	void SoldierReport(Headquarter& red, Headquarter& blue, int cityNumber) {
		for(int i = 0; i <= cityNumber+1; ++i) {
			if(red.whereSoldier[i] != 0) {
				int idr = red.whereSoldier[i]-1;
				cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " red " << red.soldierList[idr]->typeName << " " << idr+1 << " has " << red.soldierList[idr]->weaponClass[0] << " sword " << red.soldierList[idr]->weaponClass[1] << " bomb " << red.soldierList[idr]->weaponClass[2] << " arrow and " << red.soldierList[idr]->hp << " elements" << endl;
			}
			if(blue.whereSoldier[i] != 0) {
				int idb = blue.whereSoldier[i]-1;
				cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << " blue " << blue.soldierList[idb]->typeName << " " << idb+1 << " has " << blue.soldierList[idb]->weaponClass[0] << " sword " << blue.soldierList[idb]->weaponClass[1] << " bomb " << blue.soldierList[idb]->weaponClass[2] << " arrow and " << blue.soldierList[idb]->hp << " elements" << endl;
			}
		}
		return;
	}
	
	//阵营双方开始交战
	void start() {
		int t = 0;
		cin >> t;
		for(int t0 = 1; t0 <= t; ++t0) {
			int M, N, K, T;	//司令部生命,城市数,忠诚度下降系数,截至时间
			cin >> M >> N >> K >> T;
			int hpSoldier[5];
			for(int i = 0; i < 5; cin >> hpSoldier[i++]);
			int adSoldier[5];
			for(int i = 0; i < 5; cin >> adSoldier[i++]);
			cout << "Case " << t0 << ":" << endl;
			int orderRed[5] = {2, 3, 4, 1, 0}, orderBlue[5] = {3, 0, 1, 2, 4};
			Headquarter red(M, 0, orderRed);
			Headquarter blue(M, 1, orderBlue);
			
			times = 0;
			while(times <= T) {
				red.MakeSoldier(hpSoldier,adSoldier, N, times);
				blue.MakeSoldier(hpSoldier,adSoldier, N, times);
				
				times += 5;
				if(times > T) break;
				IfLoyalty(red, blue, N);
					
				times += 5;
				if(times > T) break;
				if(SoldierGo(red, blue, K, N) == 1) break; //到达敌方司令部则跳出
				
				times += 25;
				if(times > T) break;
				WolfGrabWeapon(red, blue, N);
				
				times += 5;
				if(times > T) break;				
				FindCombat(red, blue, N);
				
				times += 10;
				if(times > T) break;				
				cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << ' ' << red.hp << " elements in red headquarter" << endl;
				cout << setw(3) << setfill('0') << times/60 << ':' << times%60 << ' ' << blue.hp << " elements in blue headquarter" << endl;
				
				times += 5;
				if(times > T) break;				
				SoldierReport(red, blue, N);
				
				times += 5;
				if(times > T) break;
			}
		}
		return;
	}
};

int main() {
	CombatSystem c;
	c.start();
	return 0;
} 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值