C++編程練習 045:魔獸世界三(開戰)

Dreaming_shao

描述

魔獸世界的西面是紅魔軍的司令部,東面是藍魔軍的司令部。兩個司令部之間是依次排列的若干城市,城市從西向東依次編號爲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

  1. lion逃跑

輸出樣例:000:05 blue lion 1 ran away

表示在0點5分,編號爲1的藍魔lion武士逃走

  1. 武士前進到某一城市

輸出樣例:

000:10 red iceman 1 marched to city 1 with 20 elements and force 30

表示在0點10分,紅魔1號武士iceman前進到1號城市,此時他生命值爲20,攻擊力爲30

對於iceman,輸出的生命值應該是變化後的數值

  1. 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。爲簡單起見,武器不寫複數形式

  1. 報告戰鬥情況

戰鬥只有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

注意,把紅武士寫前面

  1. 武士歡呼

輸出樣例:003:40 blue dragon 2 yelled in city 4

  1. 武士抵達敵軍司令部

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

(此時他生命值爲20,攻擊力爲30)對於iceman,輸出的生命值和攻擊力應該是變化後的數值

  1. 司令部被佔領

輸出樣例:003:10 blue headquarter was taken

  1. 司令部報告生命元數量

000:50 100 elements in red headquarter

000:50 120 elements in blue headquarter

表示在0點50分,紅方司令部有100個生命元,藍方有120個

  1. 武士報告情況

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

提示
請注意浮點數精度誤差問題。OJ上的編譯器編譯出來的可執行程序,在這方面和你電腦上執行的程序很可能會不一致。5 * 0.3 的結果,有的機器上可能是 15.00000001,去尾取整得到15,有的機器上可能是14.9999999,去尾取整後就變成14。因此,本題不要寫 5 * 0.3,要寫 5 * 3 / 10。

來源
Guo Wei


思路分析

  1. 首先明白類的定義,定義武士類和戰場類最好
  2. 武士類肯定是有繼承的,先是基礎warrior類型的定義,後是各種武士類型的派生,最好找到武士共有的變量,便於定義與調用。
  3. 戰場類的定義,在前兩個程序的基礎上,只需要增加移動,戰鬥,搶奪武器等函數的實現。

代碼解析

#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<typeinfo>
using namespace std;
 
int soldier_HP[5];
char soldier_name[5][20] = {"iceman", "lion", "wolf", "ninja", "dragon"};
char weapon_name[3][20] = {"sword", "bomb", "arrow"};
int soldier_force[5];
int city_number, time_limited;
 
//different soldier class
//model class
class csoldier
{
public:
    int HP, force, locate, id;
	int weapon[4];
	int weapen_amount;
	csoldier() { memset(weapon, 0, sizeof(weapon)); }
    virtual ~csoldier(){}
 
//第n次交手應該使用的武器,n已經考慮過經過循環處理
	int getweapon(int &n)
	{
	    bool flag = false;
	    if (weapen_amount <= n) flag = true;
		if (n <= weapon[0])
		{
			++n;
			if(flag) n = 1;
			return 0;
		}
		else if (n <= weapon[0] + weapon[1])
		{
			weapon[1]--;
			weapen_amount--;
			if(flag) n = 1;
			return 1;
		}
		else if (n <= weapon[3] + weapon[0] + weapon[1])
		{
			weapon[3]--;
			weapen_amount--;
			if(flag) n = 1;
			return 2;
		}
		else if (n <= weapen_amount)
		{
 
			weapon[2]--;
			weapon[3]++;
			++n;
			if(flag) n = 1;
			return 2;
		}
		cout << "wrong!" << endl;
	}
	virtual void out_name() = 0;
    friend class battlefield;
};
 
class dragon:public csoldier
{
private:
    friend class battlefield;
    //constructor
    dragon(int n, int color):csoldier()
    {
        weapon[n % 3] = 1;
		weapen_amount = 1;
		force = soldier_force[4];
		locate = ((color == 0)? 0 : city_number + 1);
		HP = soldier_HP[4];
		id = n;
    }
    //destructor
    ~dragon(){}
	virtual void out_name()
	{
		cout << "dragon " << id;
	}
};
 
class ninja:public csoldier
{
private:
    friend class battlefield;
	ninja(int n, int color) :csoldier()
	{
		weapon[n % 3] = 1;
		weapon[(n + 1) % 3] = 1;
		weapen_amount = 2;
		force = soldier_force[3];
		locate = ((color == 0) ? 0 : city_number + 1);
		HP = soldier_HP[3];
		id = n;
	}
    ~ninja(){}
	virtual void out_name()
	{
		cout << "ninja " << id;
	}
};
 
class iceman:public csoldier
{
private:
    friend class battlefield;
	iceman(int n, int color) :csoldier()
	{
		weapon[(n % 3)] = 1;
		weapen_amount = 1;
		force = soldier_force[0];
		locate = ((color == 0) ? 0 : city_number + 1);
		HP = soldier_HP[0];
		id = n;
	}
	virtual void out_name()
	{
		cout << "iceman " << id;
	}
};
 
class lion:public csoldier
{
private:
    friend class battlefield;
    int loyalty;
	lion(int n, int color, int hp) :csoldier(), loyalty(hp)
	{
		weapon[n % 3] = 1;
		weapen_amount = 1;
		force = soldier_force[1];
		locate = ((color == 0) ? 0 : city_number + 1);
		HP = soldier_HP[1];
		id = n;
		cout << "Its loyalty is " << loyalty << endl;
	}
	virtual void out_name()
	{
		cout << "lion " << id;
	}
public:
	static int K;
};
int lion::K = 0;
 
class wolf:public csoldier
{
	wolf(int n, int color) :csoldier()
	{
		weapen_amount = 0;
		force = soldier_force[2];
		locate = ((color == 0) ? 0 : city_number + 1);
		HP = soldier_HP[2];
		id = n;
	}
	virtual void out_name()
	{
		cout << "wolf " << id;
	}
private:
    friend class battlefield;
};
 
class battlefield
{
private:
    int hour, minute, soldier_total[2], cur[2];
    int HP[2];
    char name[2][20];
    bool produce_end[2];//if production is carrying on, it is false, if else it is true
    csoldier ***head;
    int soldier[5];//in the order of iceman¡¢lion¡¢wolf¡¢ninja¡¢dragon
public:
	int arr[2][5] = { {0, 1, 2, 3, 4} ,{1, 4, 3, 0, 2} };
    //int arr[5] = {1, 4, 3, 0, 2};
	battlefield(int n) :HP{ n, n}, hour(0), minute(0), produce_end{ true,true }
    {
		soldier_total[0] = soldier_total[1] = 0;
		cur[0] = cur[1] = -1;
		strcpy(name[0], "red");
		strcpy(name[1], "blue");
        memset(soldier, 0, sizeof(soldier));
		head = new csoldier** [city_number + 2];
		for (int i = 0; i < city_number + 2; ++i)
		{
			head[i] = new csoldier*[4];
			memset(head[i], NULL, sizeof(csoldier*) * 4);
		}
    }
	//輸出當前時間
    void out_time()
    {
        cout << setfill('0') << setw(3) << hour << ':' << setfill('0') << setw(2) << minute;
		return;
    }
 
	//base produce soldiers. if base produce soldier sucessfully, return true;if else return false;
    bool produce(int color)
    {
        if(produce_end[color] == false)
            return false;
        cur[color] = (cur[color] + 1) % 5;
        int t = arr[color][cur[color]];
        if(HP[color] >= soldier_HP[t])
        {
            HP[color] -= soldier_HP[t];
            soldier[t]++;
            soldier_total[color]++;
			out_time();
			cout << ' ' << name[color] << ' ' << soldier_name[t] << ' ' << soldier_total[color] << " born"<< endl;
			int pos = ((color == 0) ? 0 : city_number + 1);
            switch(t)
            {
                case 0: head[pos][color] = new iceman(soldier_total[color], color);break;
                case 1: head[pos][color] = new lion(soldier_total[color], color, HP[color]);break;
                case 2: head[pos][color] = new wolf(soldier_total[color], color);break;
                case 3: head[pos][color] = new ninja(soldier_total[color], color);break;
                case 4: head[pos][color] = new dragon(soldier_total[color], color);break;
            }
            return true;
        }
        else
        {
			produce_end[color] = false;
			return false;
        }
    }
	//renew location
	void clear()
	{
		for (int i = 0; i <= city_number + 1; ++i)
		{
			head[i][0] = head[i][2];
			head[i][1] = head[i][3];
			head[i][2] = head[i][3] = NULL;
		}
		return;
	}
 
	//soldiers start moving
	bool march()
	{
		bool flag = true;
 
		if (head[1][1] != NULL)
		{
			if (typeid(*head[1][1]) == typeid(iceman))
				head[1][1]->HP -= head[1][1]->HP / 10;
			out_time();
			cout << " blue "; head[1][1]->out_name();
			printf(" reached red headquarter with %d elements and force %d\n", head[1][1]->HP, head[1][1]->force);
			head[0][3] = head[1][1];
			out_time();
			cout << " red headquarter was taken" << endl;
			flag = false;
		}
		for (int i = 1; i <= city_number; ++i)
		{
			if (head[i - 1][0] != NULL)
			{
				if (typeid(*head[i - 1][0]) == typeid(iceman))
					head[i - 1][0]->HP -= head[i - 1][0]->HP / 10;
				out_time();
				cout << " red "; head[i - 1][0]->out_name();
				printf(" marched to city %d with %d elements and force %d\n",i, head[i-1][0]->HP, head[i-1][0]->force);
				head[i][2] = head[i - 1][0];
			}
			if (head[i + 1][1] != NULL)
			{
				if (typeid(*head[i + 1][1]) == typeid(iceman))
					head[i + 1][1]->HP -= head[i + 1][1]->HP / 10;
				out_time();
				cout << " blue "; head[i + 1][1]->out_name();
				printf(" marched to city %d with %d elements and force %d\n", i, head[i + 1][1]->HP, head[i + 1][1]->force);
				head[i][3] = head[i + 1][1];
			}
		}
		if (head[city_number][0] != NULL)
		{
			if (typeid(*head[city_number][0]) == typeid(iceman))
				head[city_number][0]->HP -= head[city_number][0]->HP / 10;
			out_time();
			cout << " red "; head[city_number][0]->out_name();
			printf(" reached blue headquarter with %d elements and force %d\n", head[city_number][0]->HP, head[city_number][0]->force);
			head[city_number + 1][2] = head[city_number][0];
			out_time();
			cout << " blue headquarter was taken" << endl;
			flag = false;
		}
		clear();
		return flag;
	}
 
	//judge whether lion run away
	void run_away()
	{
		for (int i = 0; i <= city_number + 1; ++i)
		{
			for (int t = 0; t < 2; ++t)
			{
				if (head[i][t] != NULL && typeid(*head[i][t]) == typeid(lion))
				{
					auto p = (lion *)head[i][t];
					if (p->loyalty <= 0)
					{
						out_time();
						cout << ' ' << name[t];
						cout << " lion " << head[i][t]->id << " ran away" << endl;
						delete head[i][t];
						head[i][t] = NULL;
						continue;
					}
					p->loyalty -= lion::K;
				}
			}
 
		}
		return;
	}
 
	//winner snatch loser's weapon
	void snatch_weapon(csoldier *p, csoldier *q)
	{
		for (int i = 0; i < 4; ++i)
		{
			while (q->weapon[i] > 0 && p->weapen_amount < 10)
			{
				p->weapon[i]++;
				q->weapon[i]--;
				p->weapen_amount++;
			}
		}
		return;
	}
    void out_weapen(int t)
    {
        switch(t)
        {
            case 0: cout << weapon_name[0];break;
            case 1: cout << weapon_name[1];break;
            case 2: cout << weapon_name[2];break;
            case 3: cout << weapon_name[2];break;
        }
        return;
    }
	//wolf snatch enemy's weapon
	void w_snatch_weapon(csoldier *p, csoldier *q)
	{
		//bool flag = true;
 
		int t = 0, s = 0;
		while (q->weapon[t] == 0)++t;
		if (10 - p->weapen_amount <= q->weapon[t])
		{
			p->weapon[t] += 10 - p->weapen_amount;
			s += 10 - p->weapen_amount;
			p->weapen_amount = 10;
			q->weapen_amount -= s;
			q->weapon[t] -= s;
			return;
		}
		else
		{
			p->weapon[t] += q->weapon[t];
			s += q->weapon[t];
			p->weapen_amount += q->weapon[t];
			q->weapon[t] -= s;
			q->weapen_amount -= s;
			if (t == 2 && q->weapon[3] > 0)
			{
				t = 3;
				if (10 - p->weapen_amount <= q->weapon[t])
				{
					p->weapon[t] += 10 - p->weapen_amount;
					s += 10 - p->weapen_amount;
					p->weapon[t] -= 10 - p->weapen_amount;
					p->weapen_amount -= 10 - p->weapen_amount;
					p->weapen_amount = 10;
				}
				else
				{
					p->weapon[t] += q->weapon[t];
					s += q->weapon[t];
					q->weapen_amount -= q->weapon[t];
					p->weapen_amount += q->weapon[t];
					q->weapon[t] = 0;
				}
			}
			cout << s << ' ';
            out_weapen(t);
			return;
		}
	}
 
	//wolf snatch enemy's weapon
	void snatch()
	{
		for (int i = 1; i <= city_number; ++i)
		{
			csoldier *p[2] = { head[i][0], head[i][1] };
			if (p[0] != NULL && p[1] != NULL)
			{
 
				if (typeid(*p[0]) != typeid(wolf) && typeid(*p[1]) != typeid(wolf))
					continue;
				else if (typeid(*p[0]) != typeid(wolf))
				{
				    if(p[0]->weapen_amount == 0 || p[1]->weapen_amount == 10)
                        continue;
					out_time(); cout << " blue ";p[1]->out_name();
					cout << " took ";
					w_snatch_weapon(p[1], p[0]);
					cout << " from red ";
					p[0]->out_name();cout << " in city " << i << endl;
				}
				else if (typeid(*p[1]) != typeid(wolf))
				{
				    if(p[1]->weapen_amount == 0 || p[0]->weapen_amount == 10)
                        continue;
					out_time(); cout << " red ";p[0]->out_name();
					cout << " took ";
					w_snatch_weapon(p[0], p[1]);
					cout << " from blue ";
					p[1]->out_name();cout << " in city " << i << endl;
				}
				else
					continue;
 
			}
		}
	}
 
	//fight
	void fight()
	{
		for (int i = 1; i <= city_number; ++i)
		{
			if (head[i][0] == NULL || head[i][1] == NULL)
				continue;
			int r = i % 2, L = r ^ 1, n[2] = {1, 1}, w, flag = 5, check[4] = {0}, cnt = 0;
			while (true)
			{
				//判斷是否局勢改變,若不改變則爲平局
				r = r ^ 1;
				L = L ^ 1;
				if (cnt == 0)
				{
					if (check[0] == head[i][0]->HP && check[1] == head[i][1]->HP && check[2] == head[i][0]->weapen_amount && check[3] == head[i][1]->weapen_amount)
					{
						flag = 0;//all alive
						break;
					}
					check[0] = head[i][0]->HP;
					check[1] = head[i][1]->HP;
					check[2] = head[i][0]->weapen_amount;
					check[3] = head[i][1]->weapen_amount;
					cnt = 10;
				}
				cnt--;
 
				if (head[i][L]->weapen_amount == 0 && head[i][r]->weapen_amount == 0)
				{
					flag = 0;//alive
					break;
				}
				if(head[i][r]->weapen_amount == 0)
                    continue;
				w = head[i][r]->getweapon(n[r]);
//				if(head[i][1]->id == 10)
//				cout << r << ' ' << "use weapen " << w << " in city " << i <<n[r] << endl;
				int h;
				switch (w)
				{
				case 0:
					head[i][L]->HP -= head[i][r]->force / 5; break;
				case 1:
					h = head[i][r]->force * 2 / 5;
					head[i][L]->HP -= h;
					if(typeid(*head[i][r]) != typeid(ninja))
                        head[i][r]->HP -= h / 2;
					break;
				case 2:
					head[i][L]->HP -= head[i][r]->force * 3 / 10; break;
				default:
					break;
				}
				if (head[i][L]->HP <= 0 && head[i][r]->HP <= 0)
				{
					flag = 3;//all died
					break;
				}
				else if (head[i][L]->HP <= 0)
				{
					if (L == 0)
					{
						flag = 2; //blue win
						break;
					}
					else
					{
						flag = 1; //red win
						break;
					}
				}
				else if (head[i][r]->HP <= 0)
				{
					if (r == 0)
					{
						flag = 2; //blue win
						break;
					}
					else
					{
						flag = 1; //red win
						break;
					}
				}
			}
			out_time();
			switch (flag)
			{
			case 0:
				cout << " both red ";
				head[i][0]->out_name();
				cout << " and blue ";
				head[i][1]->out_name();
				cout << " were alive in city " << i << endl;
				break;
			case 3:
				cout << " both red ";
				head[i][0]->out_name();
				cout << " and blue ";
				head[i][1]->out_name();
				cout << " died in city " << i << endl;
				delete head[i][0];
				delete head[i][1];
				head[i][0] = NULL;
				head[i][1] = NULL;
				break;
			case 1:
				cout << " red ";
				head[i][0]->out_name();
				cout << " killed blue ";
				head[i][1]->out_name();
				printf(" in city %d remaining %d elements\n", i, head[i][0]->HP);
				snatch_weapon(head[i][0], head[i][1]);
				delete head[i][1];
				head[i][1] = NULL;
				break;
			case 2:
				cout << " blue ";
				head[i][1]->out_name();
				cout << " killed red ";
				head[i][0]->out_name();
				printf(" in city %d remaining %d elements\n", i, head[i][1]->HP);
				snatch_weapon(head[i][1], head[i][0]);
				delete head[i][0];
				head[i][0] = NULL;
				break;
			default:
				break;
			}
			for (int t = 0; t < 2; ++t)
			{
				if (head[i][t] != NULL && typeid(*head[i][t]) == typeid(dragon))
				{
					out_time(); cout << ' ' << name[t] << ' ';
					head[i][t]->out_name();
					cout << " yelled in city " << i << endl;
				}
			}
 
		}
 
	}
 
	//base report condition
	void base_report()
	{
		out_time();
		printf(" %d elements in red headquarter\n", HP[0]);
		out_time();
		printf(" %d elements in blue headquarter\n", HP[1]);
		return;
	}
 
	//soldier report
	void soldier_report()
	{
		for (int i = 0; i < city_number + 1; ++i)
		{
			for(int t = 0; t < 2; ++t)
				if (head[i][t] != NULL)
				{
					out_time();
					cout << ' ' << name[t] << ' ';
					head[i][t]->out_name();
					cout << " has " << head[i][t]->weapon[0] << " sword " << head[i][t]->weapon[1] << " bomb "
						<< head[i][t]->weapon[2] + head[i][t]->weapon[3] << " arrow and " << head[i][t]->HP << " elements" << endl;
				}
		}
		return;
	}
 
	//check whether time is legal
	bool check_time()
	{
		if (hour * 60 + minute > time_limited)
			return false;
		else
			return true;
	}
 
	bool run()
	{
		minute = 0;
		if (!check_time()) return false;
 
		produce(0);
		produce(1);
 
		minute = 5;
		if (!check_time()) return false;
 
		run_away();
 
		minute = 10;
		if (!check_time()) return false;
 
		if(!march())
			return false;
 
		minute = 35;
		if (!check_time()) return false;
 
		snatch();
 
		minute = 40;
		if (!check_time()) return false;
 
		fight();
 
		minute = 50;
		if (!check_time()) return false;
		base_report();
 
		minute = 55;
		if (!check_time()) return false;
		soldier_report();
 
		hour++;
		return true;
	}
};
int main()
{
    int n, hp, cnt = 0;
    cin >> n;
    while(n--)
    {
		cout << "Case " << ++cnt <<':'<< endl;
                cin >> hp >> city_number >> lion::K >> time_limited;
                battlefield Battle(hp);
                cin >> soldier_HP[4] >> soldier_HP[3] >> soldier_HP[0] >> soldier_HP[1] >> soldier_HP[2];
		cin >> soldier_force[4] >> soldier_force[3] >> soldier_force[0] >> soldier_force[1] >> soldier_force[2];
		while (Battle.run());
 
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章