魔獸世界小遊戲(基於C++)

前言

這個項目的需求還是挺複雜的,作爲檢驗c++學習成果還是挺不錯的,做完這個項目,感覺自己的水平又更上一層樓了,哈哈

下面是整個項目的需求,和我寫的代碼原碼,全部代碼(不包括測試代碼)大概在1000行左右。

源碼、需求說明、校驗數據可以在我的百度雲下載
鏈接:https://pan.baidu.com/s/17Ybq3s1bkdrjSbnJXj9frQ 提取碼:jbli

整個架構、流程完全獨立構思完成的,沒有參考任何其它人的代碼,雖然裏面還有一點點小BUG,但是目前來說影響不大,如果哪位大牛能看出來問題在哪,有償求教!

項目需求

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

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

源碼

main.cpp

#include <iostream>
#include "game.h"


using namespace std;
	
int main(void){
	gameInfo_t gInfo;
	cin>>gInfo.testCase;
	cin>>gInfo.initElements>>gInfo.totalCities>>gInfo.decLoyalty>>gInfo.totalTime;
	cin>>gInfo.warrior[0].element>>gInfo.warrior[1].element>>gInfo.warrior[2].element>>gInfo.warrior[3].element>>gInfo.warrior[4].element;
	cin>>gInfo.warrior[0].force>>gInfo.warrior[1].force>>gInfo.warrior[2].force>>gInfo.warrior[3].force>>gInfo.warrior[4].force;
	gInfo.warrior[0].name = "dragon";
	gInfo.warrior[1].name = "ninja";
	gInfo.warrior[2].name = "iceman";
	gInfo.warrior[3].name = "lion";
	gInfo.warrior[4].name = "wolf";

	cout<<"Case "<<gInfo.testCase<<":"<<endl;
	Game game(gInfo.initElements, gInfo.totalCities, gInfo.decLoyalty, gInfo.totalTime, gInfo.warrior);
	game.begin();
	return 0;
}

game.cpp

#include <iomanip>
#include "game.h"

#define DEBUG 0

using namespace std;

int Game::curTime = 0;

Game::Game(int initElements, int totalCities, int decLoyalty, int totalTime, warriorInfo_t *warrior){
	this->initElements 	= initElements;
	this->totalCities  	= totalCities;
	this->decLoyalty   	= decLoyalty;
	this->totalTime   	= totalTime;
	this->warrior 		= warrior;
}
void Game::printGameTime(void){
	cout<<setw(3)<<setfill('0')<<curTime/60<<":"<<setw(2)<<setfill('0')<<curTime%60<<" ";
}
bool Game::checkGameTime(void){
	//totalTime = 500;			//測試用,限制遊戲時間 
	if(curTime >= totalTime)	//到達時間時,退出遊戲
		return true;
	else
		return false;
}
void Game::begin(void){
	Warrior *tmp, *tmpRed, *tmpBlue;
	string redName, blueName;
	int ret=0, retRed=0, retBlue=0;
	bool redWin = false;
	bool blueWin = false;
	
	//創建所有城市
	NormalCity city[totalCities];
	for(int i=0;i<totalCities; i++){
		city[i].setCityNum(i+1);
		//cout<<"create normal city, "<<"Number="<<city[i].number<<endl;
	} 

	//創建紅藍基地
	Headquarter *red = new Headquarter(0, "red", initElements, decLoyalty);
	Headquarter *blue = new Headquarter(totalCities+1, "blue", initElements, decLoyalty);
	//red->showCity();
	//blue->showCity();
	
	//遊戲正式開始
	while(true){
		//第一階段,雙方基地製造武士
		if(0 == curTime%60){
			redName = red->getWarriorName();		//先獲取要製造的武士的名字 
			blueName = blue->getWarriorName();
			//cout<<"redname="<<redName<<",bluename="<<blueName<<endl;
			for(int i=0; i<WARRIOR_KIND; i++){		//按照指定順序製造武士 
				if(0 == warrior[i].name.compare(redName)){
					red->makeWarrior(warrior[i].element, warrior[i].force, totalCities);
				}
			}
			for(int i=0; i<WARRIOR_KIND; i++){
				if(0 == warrior[i].name.compare(blueName)){
					blue->makeWarrior(warrior[i].element, warrior[i].force, totalCities);
				}	
			} 
			if(checkGameTime())	break;
		}
		
		//第二階段,5min判斷獅子是否逃跑
		curTime += 5;
		if(5 == curTime%60){
			//遍歷所有的城市,找出獅子對象 
			for(int i=0; i<totalCities; i++){
				if(city[i].redWarrior){
					tmp = city[i].redWarrior;
					//如果武士是獅子,判斷忠誠度,是否會逃跑
					if(0 == tmp->name.compare("lion")){
						Lion *lion = dynamic_cast<Lion *>(tmp);
						if(lion->loyalty <= 0){
							lion->escape();
							red->eraseWarrior(tmp);
							city[i].redWarrior = NULL;
						}	
					} 
				}	
				if(city[i].blueWarrior){
					tmp = city[i].blueWarrior;
					//如果武士是獅子,判斷忠誠度,是否會逃跑
					if(0 == tmp->name.compare("lion")){
						Lion *lion = dynamic_cast<Lion *>(tmp);
						if(lion->loyalty <= 0){
							lion->escape();
							blue->eraseWarrior(tmp);
							city[i].blueWarrior = NULL;
						}
					}
				}
			}
			if(checkGameTime())	break; 
		}
		
		//第三階段,10min武士前進
		curTime += 5;
		if(10 == curTime%60){
			//所以武士完成前進後,再按城市順序進行彙報
			//如果已經在敵方基地,則無需前進,返回-1
			//如果前進後,到達敵方基地,則返回0,到達常規城市,返回1  
			for(vector<Warrior *>::const_iterator  i=red->warriorVec.begin(); i!=red->warriorVec.end(); ++i){
				retRed = (*i)->march(city);
				if(0 == retRed){
					tmpRed = (*i);	//該武士佔領了敵方基地 
					redWin = true;
				}	
			}
			for(vector<Warrior *>::const_iterator  i=blue->warriorVec.begin(); i!=blue->warriorVec.end(); ++i){
				retBlue = (*i)->march(city);
				if(0 == retBlue){
					tmpBlue = (*i);	//該武士佔領了敵方基地
					blueWin = true; 	
				}
			}
			//檢查紅方基地是否被佔領 
			if(blueWin){
				//001:10 red iceman 1 reached blue headquarter with 20 elements and force 30
				//003:10 blue headquarter was taken
				printGameTime();
				cout<<"blue "<<tmpBlue->name<<" "<<tmpBlue->number<<" reached red headquarter with "<<tmpBlue->elements<<" elements and force "<<tmpBlue->force<<endl;
				printGameTime();
				cout<<"red headquarter was taken"<<endl;
			}
			//打印普通城市前進信息 
			for(int i=0; i<totalCities; i++){
				if(city[i].redWarrior){
					tmp = city[i].redWarrior;
					Game::printGameTime(); 
					cout<<tmp->team<<" "<<tmp->name<<" "<<tmp->number<<" marched to city "<<city[i].number<<" with "<<tmp->elements<<" elements and force "<<tmp->force<<endl;	
				}
				if(city[i].blueWarrior){
					tmp = city[i].blueWarrior;
					Game::printGameTime(); 
					cout<<tmp->team<<" "<<tmp->name<<" "<<tmp->number<<" marched to city "<<city[i].number<<" with "<<tmp->elements<<" elements and force "<<tmp->force<<endl;
				}
			}
			//檢查藍方基地是否被佔領
			if(redWin){
				//001:10 red iceman 1 reached blue headquarter with 20 elements and force 30
				//003:10 blue headquarter was taken
				printGameTime();
				cout<<"red "<<tmpRed->name<<" "<<tmpRed->number<<" reached blue headquarter with "<<tmpRed->elements<<" elements and force "<<tmpRed->force<<endl;
				printGameTime();
				cout<<"blue headquarter was taken"<<endl;
			}
			 
			if(redWin || blueWin)			//有一方到達敵方基地,則遊戲結束 
				break;
			if(checkGameTime())	break; 
		}
		
		//第四階段,35min狼搶奪武器 
		curTime += 25;
		if(35 == curTime%60){
			for(int i=0; i<totalCities; i++){
				//同一城市有兩個武士 
				if(city[i].redWarrior && city[i].blueWarrior){
					tmp = city[i].redWarrior; 
					if(0 == tmp->name.compare("wolf")){
						Wolf *wolf = dynamic_cast<Wolf *>(tmp);
						wolf->rob(city[i].blueWarrior);
					}
					tmp = city[i].blueWarrior; 
					if(0 == tmp->name.compare("wolf")){
						Wolf *wolf = dynamic_cast<Wolf *>(tmp);
						wolf->rob(city[i].redWarrior);
					}
				}		
			}
			if(checkGameTime())	break; 
		}

		//第五階段,40min發生戰鬥 
		curTime += 5;
		if(40 == curTime%60){
			for(int i=0; i<totalCities; i++){
				tmpRed = city[i].redWarrior;
				tmpBlue = city[i].blueWarrior;

				//同一城市有兩個武士則開戰,一定要先對武器排序 
				if(tmpRed && tmpBlue){
					ret = city[i].fight(tmpRed, tmpBlue);
					
					if(ret == -2){		//都死了 
						//000:40 both red iceman 1 and blue lion 12 died in city 2
						Game::printGameTime(); 
						cout<<"both red "<<tmpRed->name<<" "<<tmpRed->number<<" and blue "<<tmpBlue->name<<" "<<tmpBlue->number<<" died in city "<<city[i].number<<endl;
					}
					else if(ret == -1){	//藍方活着 
						//008:40 red iceman 6 killed blue ninja 3 in city 4 remaining 85 elements
						Game::printGameTime(); 
						cout<<"blue "<<tmpBlue->name<<" "<<tmpBlue->number<<" killed red "<<tmpRed->name<<" "<<tmpRed->number<<" in city "<<city[i].number<<" remaining "<<tmpBlue->elements<<" elements"<<endl;
						tmpBlue->getEnemyWeapon(tmpRed);
					}
					else if(ret == 1){	//紅方活着 
						Game::printGameTime(); 
						cout<<"red "<<tmpRed->name<<" "<<tmpRed->number<<" killed blue "<<tmpBlue->name<<" "<<tmpBlue->number<<" in city "<<city[i].number<<" remaining "<<tmpRed->elements<<" elements"<<endl;
						tmpRed->getEnemyWeapon(tmpBlue);
					}
					else if(ret == 0){	//都活着 
						//008:40 both red lion 7 and blue dragon 2 were alive in city 3
						Game::printGameTime(); 
						cout<<"both red "<<tmpRed->name<<" "<<tmpRed->number<<" and blue "<<tmpBlue->name<<" "<<tmpBlue->number<<" were alive in city "<<city[i].number<<endl;
					}
					//活着的龍,歡呼 
					if(tmpRed->alive() && (0 == tmpRed->name.compare("dragon"))){
						Dragon *dragon = dynamic_cast<Dragon *>(tmpRed);
						dragon->yelled(); 
					}
					if(tmpBlue->alive() && (0 == tmpBlue->name.compare("dragon"))){
						Dragon *dragon = dynamic_cast<Dragon *>(tmpBlue);
						dragon->yelled(); 
					}
					//刪除死去的武士對象
					if(!tmpRed->alive()) {
						red->eraseWarrior(tmpRed);
						city[i].redWarrior = NULL;
					}	
					if(!tmpBlue->alive()){
						blue->eraseWarrior(tmpBlue);
						city[i].blueWarrior = NULL; 
					}
				}
			}
			if(checkGameTime())	break; 
		}
		//第六階段,50min司令部報告剩餘生命元 
		curTime += 10;
		if(50 == curTime%60){
			red->report();
			blue->report();
			if(checkGameTime())	break; 
		}
		
		//第七階段,55min武士報告擁有武器情況 
		curTime += 5;
		if(55 == curTime%60){
			for(int i=0; i<totalCities; i++){
				tmpRed = city[i].redWarrior;
				tmpBlue = city[i].blueWarrior;
				if(tmpRed)	tmpRed->showInfo();
				if(tmpBlue)	tmpBlue->showInfo();
			}
			if(checkGameTime())	break; 
		}
		
		//第八階段,60min 
		curTime += 5;
	} 
}


#if DEBUG
int main(){
	// case 1
	gameInfo_t gInfo = {
		.testCase = 1,
		.initElements = 6000,
		.totalCities = 10,
		.decLoyalty = 10,
		.totalTime = 4000,
		.warrior ={
			{"dragon",	120,	50},
			{"ninja",	20,		50},
			{"iceman",	130,	50},
			{"lion",	10,		50},
			{"wolf",	20,		150}
		}
	};
	cout<<"Case "<<gInfo.testCase<<":"<<endl;
	Game game(gInfo.initElements, gInfo.totalCities, gInfo.decLoyalty, gInfo.totalTime, gInfo.warrior);
	game.begin();	
}

#endif

game.h

#ifndef __GAME__H
#define __GAME__H

#include <iostream>
#include <map>
#include "city.h" 

#define WARRIOR_KIND	5 
     
typedef struct WARRIOR_INFO{
	string name;
	int element;
	int force;
}warriorInfo_t;

typedef struct GAME_INFO{
	int testCase;
	int initElements;
	int totalCities;
	int decLoyalty;
	int totalTime;
	warriorInfo_t warrior[WARRIOR_KIND];
}gameInfo_t;

class Game{
public:
	int initElements;			//基地初始生命元
	int decLoyalty;				//獅子每次遞減的忠誠度 
	int totalCities;			//城市總數量(不算紅藍軍基地)
	int totalTime;				//總的遊戲時長,到時間後遊戲結束 
	static int curTime;			//當前遊戲時間
	warriorInfo_t *warrior;		//保存武士的初始化信息
public:
	Game(int initElements, int totalCities, int decLoyalty, int totalTime, warriorInfo_t *warrior); 	//創建遊戲對象,遊戲初始化 
	void begin(void);			//遊戲正式開始 
	static void printGameTime(void);		//打印當前遊戲時間
	bool checkGameTime(void); 				//檢查遊戲時間,確認是否應該結束遊戲 
};


#endif

city.cpp

#include <iomanip>
#include "city.h"
#include "game.h"

#define DEBUG 0 

using namespace std;

City::City(){
}
City::City(int number){
	if(number < 0)	this->number = 0;
	else			this->number = number;
}
void City::setCityNum(int number){
	if(number < 0)	this->number = 0;
	else			this->number = number;
}



NormalCity::NormalCity(void){
	redWarrior = NULL;
	blueWarrior = NULL;
}
int NormalCity::fight(Warrior *red, Warrior *blue){
	int ret1=0,ret2=0;
	Warrior *first,*last;	 
	if(number % 2){
		first = red;							//奇數城市,紅方先出手 
		last = blue;
	}else{
		first = blue;
		last = red;
	}
	first->weaponSort();
	last->weaponSort();

	//當某一方只剩武器 劍 時,且它的劍攻擊力爲0,attack函數也返回0,退出循環 
	while(true){
		ret1 = first->attack(last);
		if(!first->alive() || !last->alive())	//出現死人的情況,則退出循環  	
			break;
		if(ret1 && ret2)						//雙方都沒有武器,則返回0
			return 0;
		ret2 = last->attack(first);
		if(!first->alive() || !last->alive())	//出現死人的情況,則退出循環 
			break;
		if(ret1 && ret2)						//雙方都沒有武器,則返回0
			return 0;
	}
	if(red->alive() && blue->alive())			//都或者,返回0 
		return 0;
	if(red->alive())	{						//紅方活着返回1 
		//cout<<"red alive"<<endl;
		return 1;	
	}
	else if(blue->alive())	{					//藍方活着返回-1 
		//cout<<"blue alive"<<endl;
		return -1;	
	}
	else										//都死了返回 -2 
		return -2;
}


Headquarter::Headquarter(int number, string team, int elements, int loyaltyDec):City(number){
	this->team = team;
	this->elements = elements;
	this->warriorNum = 0;
	this->setWarriorOrder(team);
	this->loyaltyDec = loyaltyDec;
	this->warrior = NULL;
}
void Headquarter::setWarriorOrder(string team){
	if(0 == team.compare("blue")){
		warriorOrder[0] = "lion";
		warriorOrder[1] = "dragon";
		warriorOrder[2] = "ninja";
		warriorOrder[3] = "iceman";
		warriorOrder[4] = "wolf";
	}else if(0 == team.compare("red")){
		warriorOrder[0] = "iceman";
		warriorOrder[1] = "lion";
		warriorOrder[2] = "wolf";
		warriorOrder[3] = "ninja";
		warriorOrder[4] = "dragon";
	}
}
string Headquarter::getWarriorName(void){
	return warriorOrder[warriorNum%5];
} 
int Headquarter::decElements(int elements){
	if(this->elements >= elements){
		this->elements -= elements;
		return 0;
	}
	else
		return -1;
}
Warrior * Headquarter::makeWarrior(int elements, int force, int totalCities){
	bool direction;
	if(this->elements < elements)							//基地生命元過低時,無法生產武士 
		return NULL;

	if(0 == team.compare("red"))	direction = true;	 
	else							direction = false;

	if(0 == warriorOrder[warriorNum%5].compare("dragon")){
		warrior = new Dragon(team, ++warriorNum, elements, force, number, totalCities, direction);
	}	
	else if(0 == warriorOrder[warriorNum%5].compare("ninja")){
		warrior = new Ninja(team, ++warriorNum, elements, force, number, totalCities, direction);
	}	
	else if(0 == warriorOrder[warriorNum%5].compare("iceman")){
		warrior = new Iceman(team, ++warriorNum, elements, force, number, totalCities, direction);
	}
	else if(0 == warriorOrder[warriorNum%5].compare("lion")){
		warrior = new Lion(team, ++warriorNum, elements, force, number, totalCities, direction, this->elements-elements, loyaltyDec);
		Lion *lion = dynamic_cast<Lion *>(warrior);
		if(lion->loyalty <= 0){		//如果剛好創建獅子後,基地血量爲0,則獅子忠誠度也爲0,獅子逃跑 
			lion->escape();
			delete warrior;
			warrior = NULL;
		}	
	}
	else if(0 == warriorOrder[warriorNum%5].compare("wolf")){
		warrior = new Wolf(team, ++warriorNum, elements, force, number, totalCities, direction);
	}
	decElements(elements);				//製造武士後,基地生命元降低 
	if(warrior)
		warriorVec.push_back(warrior);	//如果獅子沒有逃跑,則加入該陣營的武士容器 
	return warrior;	
}
int Headquarter::eraseWarrior(Warrior *warrior){
	for(vector<Warrior *>::iterator  i=warriorVec.begin(); i!=warriorVec.end(); ++i){
		if((*i) == warrior){
			warriorVec.erase(i);
			//delete warrior;			//目前加上去會有BUG,暫時還不清楚什麼原因 
			return 0;
		}
	}
	return -1;
}
void Headquarter::report(void){
	//008:50 5520 elements in red headquarter 
	Game::printGameTime(); 
	cout<<elements<<" elements in "<<team<<" headquarter"<<endl;
} 
void Headquarter::showWarrior(void){
	for(vector<Warrior *>::const_iterator i=warriorVec.begin(); i!=warriorVec.end(); ++i){
		cout<<"team="<<(*i)->team<<",name="<<(*i)->name<<",number="<<(*i)->number<<",elements="\
		<<(*i)->elements<<",force="<<(*i)->force<<",city="<<(*i)->city<<",totalCities="<<(*i)->totalCities<<",direction="<<(*i)->direction<<endl;
	
		if(0 == (*i)->name.compare("lion")){
			Lion *lion = dynamic_cast<Lion *>(*i);
			cout<<" Loyalty="<<lion->loyalty<<" loyaltyDec="<<loyaltyDec;
		}
		cout<<endl;
	}
}	
void Headquarter::showCity(){
	cout<<team<<", cityNumber="<<number<<", baseName="<<team<<", elements="<<elements<<", warriorTotalNum="<<warriorNum<<endl;
} 

#if DEBUG
int main(){
	//測試1 創建普通城市
//	int MAX = 10;
//	NormalCity city[MAX];
//	for(int i=0;i<MAX; i++){
//		city[i].setCityNum(i+1);
//		cout<<"create normal city, "<<"Number="<<city[i].number<<endl;
//	} 

	//測試2 創建紅藍基地
//	Headquarter *red = new Headquarter(0, "red", 1000, 100);
//	Headquarter *blue = new Headquarter(11, "blue", 2000, 70);
//	red->showCity();
//	blue->showCity();
//
//	//測試3 生產武士
//	Warrior *w1 = red->makeWarrior(100, 20);
//	Warrior *w2 = red->makeWarrior(200, 50);
//	Warrior *w3 = red->makeWarrior(150, 32);
//	
////	red->makeWarrior(147, 21);
////	red->makeWarrior(23, 501);
////	red->makeWarrior(44, 10);
////	red->makeWarrior(30, 88);	
//
//	red->showWarrior();
//	cout<<"after"<<endl;
////	//red->showCity();
//	int ret = red->eraseWarrior(w1);
////
//	if(ret == 0){
//		cout<<w1->team<<" "<<w1->name<<" "<<w1->number <<" elements="<<w1->elements<<" force="<<w1->force;
//		delete w1;
//	}
////		
//	
//	red->showWarrior();
	
	
	//測試4 兩個武士戰鬥
//	int ret=0;
//	city[0].redWarrior = red->makeWarrior(100, 20);
//	city[0].blueWarrior = blue->makeWarrior(200, 50);
//	
//	city[0].redWarrior->showWeaponInfo();
//	city[0].redWarrior->showTestInfo();
//	city[0].blueWarrior->showWeaponInfo();
//	city[0].blueWarrior->showTestInfo();
//
//	ret = city[0].fight(city[0].redWarrior, city[0].blueWarrior);
//	if(ret == -2)
//		cout<<"both died"<<endl;
//	else if(ret == -1)
//		cout<<"blue died"<<endl;
//	else if(ret == 1)
//		cout<<"red died"<<endl;
//	else if(ret == 0)
//		cout<<"both alive"<<endl;
}
#endif

city.h

#ifndef __CITY__H
#define __CITY__H

#include <iostream>
#include <vector>
#include "warrior.h"
using namespace std;

//基類:城市 
class City{
public:
	int number;								//每個城市都有編號
public:
	City();
	City(int number);
	void setCityNum(int number);		 
};

//司令部 
class Headquarter : public City{
public:
	string team;							//陣營名字
	int elements;							//基地剩餘生命元
	int warriorNum; 						//武士最大編號
	int initLoyalty;						//獅子的初始化忠誠度 
	int loyaltyDec;							//獅子的忠誠度遞減數 
	string warriorOrder[5];					//製造順序  
	vector<Warrior *> warriorVec;			//用以存儲的武士對象的指針
	Warrior *warrior;
public:
	Headquarter(int number, string team, int elements, int loyaltyDec);
	void setWarriorOrder(string team);		//設置陣容製造武士的順序
	string getWarriorName(void);			//獲取當前需要製造的武士名字 
	int decElements(int elements);			//剩餘生命源數量減少
	Warrior * makeWarrior(int elements, int force, int totalCities);	//製造武士
	int eraseWarrior(Warrior *warrior);		//刪除死去的武士 
	void report(void);						//司令部報告剩餘生命元 
	void showWarrior(void);					//顯示目前陣營所有活着的武士,僅供測試用
	void showCity(void);					//顯示城市信息 ,僅供測試用
};

//普通城市類 
class NormalCity : public City{
public:
	Warrior *redWarrior;
	Warrior *blueWarrior;
public:
	NormalCity();
	int fight(Warrior *red, Warrior *blue);
};




#endif

warrior.cpp

#include <iomanip>
#include "warrior.h" 
#include "game.h"
#define DEBUG 0

using namespace std;

//武器進行排序時的算法 
bool mySort(const WEAPON_PAIR& lhs, const WEAPON_PAIR& rhs)
{
	if(lhs.first != rhs.first)				//編號不相同的武器,根據編號排序 
    	return lhs.first < rhs.first;
    else									//編號相同的武器,根據剩餘使用次數排序	
    	return lhs.second->times < rhs.second->times;
}
 
Warrior::Warrior(){
	this->name 		= "default";
	this->team  	= "default";
	this->number 	= 0;
	this->elements 	= 0;
	this->force 	= 0;
	this->city 		= 0;
	this->totalCities= 0; 
	this->direction	= false;
	Game::printGameTime();
	printBornInfo();
}
	
Warrior::Warrior(string name, string team, int number, int elements, int force, int city, int totalCities, bool direction){
	if(name.empty())	this->name 		= "default";
	else				this->name 		= name;

	if(team.empty())	this->team 		= "default";
	else				this->team 		= team;
	
	if(number < 0)		this->number 	= 0;
	else				this->number 	= number;
	
	if(elements < 0)	this->elements 	= 0;
	else				this->elements 	= elements;
	
	if(force < 0)		this->force 	= 0;
	else				this->force 	= force;

	if(city < 0)		this->city 		= 0;
	else				this->city 		= city;
	
	if(totalCities < 0)	this->totalCities	= 0;
	else				this->totalCities	= totalCities;
	
	this->direction = direction;
	Game::printGameTime(); 
	printBornInfo();
}
/*
一般情況下,武士消亡時,武器會被敵人繳獲
但是當敵人武器數量等於10時,武器並不會被全部繳獲,因此需要手動刪除 
*/
Warrior::~Warrior(){				//武士消亡時,武器庫也要清空 
	//cout<<"~Warrior call"<<endl;
	for(WEAPON_VEC::iterator i=weaponVec.begin(); i!=weaponVec.end(); ++i){
		delete ((*i).second);		//刪除武器庫的武器對象 
	} 
	weaponVec.clear(); 				//清空容器
}
int Warrior::decElements(int force){
	if(force <= 0)
		return -2; 			//攻擊爲負,或者攻擊爲0,返回-2
	if(elements > 0){
		elements -= force;	//正常攻擊,減血,返回0 
		return 0;
	}
	return -1;				//血量已經不大於0,返回-1 
}
bool Warrior::alive(void){
	if(elements > 0)
		return true;
	else
		return false;
}
int Warrior::march(NormalCity* iCity){
	int enemyCity = 0; 
	if(0 == team.compare("red")){
		enemyCity = totalCities+1;
	}else if(0 == team.compare("blue")){
		enemyCity = 0;
	}else{
		return -2;			//未知錯誤 
	}
	if(city == enemyCity)	//如果當前已經在敵方基地,則無需前進,返回-1
		return -1;
	//前進一個城市 
	if(direction)	city += 1;		
	else			city -= 1;
	//cout<<team<<" "<<name<<", number="<<number<<" march city = "<<city<<", enemyCity = "<<enemyCity<<endl;
	setCity(iCity); 
	//到達敵方基地,返回0, 到達常規城市,返回1 
	if(city == enemyCity)		return 0;
	else						return 1;					
}
void Warrior::setCity(NormalCity* iCity){		//武士前進後,需要將之前和當前的城市對象中的武士指針重新賦值 
	if(totalCities < 0 || NULL == iCity)		//參數不對直接退出 
		return;
	if(0 == team.compare("red")){
		if((city - 1) > 0){
			iCity[city - 2].redWarrior = NULL;	//武士前進後,上一個城市不爲基地,則賦值爲NULL
		}else{
			//cout<<"no null "<<team<<" "<<name<<" number="<<number<<" city="<<city<<endl;
		}
		if(city != (totalCities+1)){				//武士前進後,所在城市不是敵方基地 				
			iCity[city - 1].redWarrior = this;	//將武士的指針賦值給城市對象 
		}else{
			//cout<<"no this "<<team<<" "<<name<<" number="<<number<<" city="<<city<<endl;
		}
	}else if(0 == team.compare("blue")){
		if((city + 1) < (totalCities+1)){
			iCity[city].blueWarrior = NULL;		//武士前進後,上一個城市不爲基地,則賦值爲NULL
		}
		if(city != 0){							//武士前進後,所在城市不是敵方基地 
			iCity[city-1].blueWarrior = this;	//將武士的指針賦值給城市對象
		}
	}
}
int Warrior::attack(Warrior * enemy){
	if((NULL == enemy) || (enemy == this))
		return -1;										//傳入錯誤參數,直接返回-1 
	if(weaponVec.empty())
		return 1;										//沒有武器時,直接返回1
	if(checkWeaponNoForce())							//武器爲劍,且沒有傷害時,返回 
		return 1;
	int number = (*iweapon).second->number;				//獲取當前武器的編號 
	int force  = (*iweapon).second->force;				//獲取當前武器的攻擊力
	int times  = (*iweapon).second->useWeapon();		//使用武器,獲取剩餘可使用次數 
	enemy->decElements(force);							//敵人血量降低 
	//cout<<team<<" "<<name<<" attack "<<enemy->team<<" "<<enemy->name<<" with weapon number "<<number<<", enemy elements dec "<<force<<", now elements is "<<elements<<" enemy elements is "<<enemy->elements<<endl;
	if(1 == number){ 									//使用炸彈時 
		this->decElements(force/2);						//自己受到傷害的一半
		//cout<<team<<" "<<name<<"get hurt form bomb, elements dec "<<force/2<<endl; 
	} 
	if(times > 0)										//如果武器還能用 
		iweapon++;										//則指向下一個武器 
	else{
		delete (*iweapon).second;						//刪除武器對象
		weaponVec.erase(iweapon);						//從容器中移除 
	} 
	if(iweapon == weaponVec.end())
		iweapon = weaponVec.begin();					//武器用完一遍又回到開頭
	return 0;
}
void Warrior::weaponSort(void){
	sort(weaponVec.begin(), weaponVec.end(), mySort);
	iweapon = weaponVec.begin();						//指針指向武器庫的開頭 
}
void Warrior::getEnemyWeapon(Warrior * enemy){
	if((NULL == enemy) || (enemy == this))
		return;											//傳入錯誤參數,直接返回 	
	if(enemy->weaponVec.empty())						//如果敵人沒有武器,則直接返回 
		return;
	for(WEAPON_VEC::iterator i=enemy->weaponVec.begin(); i!=enemy->weaponVec.end(); ){
		if(weaponVec.size() < 10){						//武器少於10個,才繳獲 
			if(0 == (*i).first){						//攻擊力重新計算 
				(*i).second->force = force*2/10;
			}else if(1 == (*i).first){
				(*i).second->force = force*4/10;
			}else if(2 == (*i).first){
				(*i).second->force = force*3/10;
			}
			weaponVec.push_back(*i);					//放入武器容器中 
			enemy->weaponVec.erase(i);					//移除原先武士的對應武器
		}else
			break;										//武器達到10個,直接退出 
	}
	weaponSort();										//繳獲武器後,進行排序
}
bool Warrior::checkWeaponNoForce(void){
	for(WEAPON_VEC::const_iterator i=weaponVec.begin(); i!=weaponVec.end(); ++i){
		if((*i).second->force > 0){			//武器有攻擊力,則武器正常使用	
			return false;
		} 				 	
		if((*i).first != 0){				//攻擊力爲0的炸彈和弓箭,也要使用
			return false;
		}		
	}
	return true;
}
void Warrior::showInfo(void){
	int swordNum = 0;
	int bombNum = 0;
	int arrowNum = 0;
	for(WEAPON_VEC::const_iterator i=weaponVec.begin(); i!=weaponVec.end(); ++i){
		if(0 == (*i).first)
			swordNum++;
		else if(1 == (*i).first)
			bombNum++;
		else if(2 == (*i).first)
			arrowNum++;
	}
	Game::printGameTime(); 
	cout<<team<<" "<<name<<" "<<number <<" has "<<swordNum<<" sword "<<bombNum<<" bomb "<<arrowNum<<" arrow and "<<elements<<" elements"<<endl;
} 
void Warrior::showWeaponInfo(void){
	cout<<team<<" "<<name<<" "<<number<<" has "<<endl;
	for(WEAPON_VEC::const_iterator i=weaponVec.begin(); i!=weaponVec.end(); ++i){
		cout<<"number="<<(*i).second->number<<", force="<<(*i).second->force<<",times="<<(*i).second->times<<endl;
	}
	if(weaponVec.empty())
		cout<<"nothing"<<endl;
}

void Warrior::showTestInfo(void){
	cout<<"name="<<name<<",team="<<team<<",number="<<number<<",elements="\
		<<elements<<",force="<<force<<",city="<<city<<",totalCities="<<totalCities<<",direction="<<direction<<endl;
}
void Warrior::printBornInfo(void){
	cout<<team<<" "<<name<<" "<<number<<" born"<<endl;
}



Dragon::Dragon(string team, int number, int elements, int force, int city, int totalCities, bool direction):Warrior("dragon", team, number, elements, force, city, totalCities, direction){
	//龍誕生時,獲得武器 
	if(0 == number%3)
		weaponVec.push_back(make_pair(0, new Sword(force*2/10)));
	else if(1 == number%3)
		weaponVec.push_back(make_pair(1, new Bomb(force*4/10)));	
	else
		weaponVec.push_back(make_pair(2, new Arrow(force*3/10)));	
}
Dragon::~Dragon(){
	cout<<"Dragon call"<<endl; 
}
void Dragon::yelled(void){
	//red dragon 5 yelled in city 7
	Game::printGameTime(); 
	cout<<team<<" "<<name<<" "<<number<<" yelled in city "<<city<<endl;
}




Ninja::Ninja(string team, int number, int elements, int force, int city, int totalCities, bool direction):Warrior("ninja", team, number, elements, force, city, totalCities, direction){
	if(0 == number%3){
		weaponVec.push_back(make_pair(0, new Sword(force*2/10)));
		weaponVec.push_back(make_pair(1, new Bomb(force*4/10)));
	}
	else if(1 == number%3){
		weaponVec.push_back(make_pair(1, new Bomb(force*4/10)));
		weaponVec.push_back(make_pair(2, new Arrow(force*3/10)));		
	}	
	else{
		weaponVec.push_back(make_pair(2, new Arrow(force*3/10)));
		weaponVec.push_back(make_pair(0, new Sword(force*2/10)));	
	}	
}
Ninja::~Ninja(){
	cout<<"Ninja call"<<endl; 
}
int Ninja::attack(Warrior * enemy){
	if((NULL == enemy) || (enemy == this))
		return -1;										//傳入錯誤參數,直接返回-1 
	if(weaponVec.empty())
		return 1;										//沒有武器時,直接返回1
	if(checkWeaponNoForce())							//武器爲劍,且沒有傷害時,返回 
		return 1;

	int number = (*iweapon).second->number;				//獲取當前武器的編號 
	int force  = (*iweapon).second->force;				//獲取當前武器的攻擊力
	int times  = (*iweapon).second->useWeapon();		//使用武器,獲取剩餘可使用次數 

	enemy->decElements(force);							//敵人血量降低 
	//cout<<name<<" attack "<<enemy->name<<" with weapon number "<<number<<", enemy elements dec "<<force<<endl;

	//忍者使用炸彈不受傷害 
	if(1 == number){ 									//使用炸彈時 
		//this->decElements(force/2);						//自己受到傷害的一半
		//cout<<name<<"get hurt form bomb, elements dec "<<force/2<<endl; 
		//cout<<"Ninja protected himself from being hurt by bomb"<<endl;
	} 

	if(times > 0)										//如果武器還能用 
		iweapon++;										//則指向下一個武器 
	else{
		delete (*iweapon).second;						//刪除武器對象
		weaponVec.erase(iweapon);						//從容器中移除 
	} 
	
	if(iweapon == weaponVec.end())
		iweapon = weaponVec.begin();					//武器用完一遍又回到開頭
	return 0;
}


Iceman::Iceman(string team, int number, int elements, int force, int city, int totalCities, bool direction):Warrior("iceman", team, number, elements, force, city, totalCities, direction){
	if(0 == number%3)
		weaponVec.push_back(make_pair(0, new Sword(force*2/10)));
	else if(1 == number%3)
		weaponVec.push_back(make_pair(1, new Bomb(force*4/10)));	
	else
		weaponVec.push_back(make_pair(2, new Arrow(force*3/10)));		
}
Iceman::~Iceman(){
	cout<<"Iceman call"<<endl; 
}
int Iceman::march(NormalCity* iCity){
	int enemyCity = 0; 
	if(0 == team.compare("red")){
		enemyCity = totalCities+1;
	}else if(0 == team.compare("blue")){
		enemyCity = 0;
	}else{
		return -2;			//未知錯誤 
	}
	
	if(city == enemyCity)	//如果當前已經在敵方基地,則無需前進,返回-1
		return -1;
	
	//前進一個城市 
	if(direction)	city += 1;		
	else			city -= 1;
	//cout<<team<<" "<<name<<", number="<<number<<" march city = "<<city<<", enemyCity = "<<enemyCity<<endl;
	setCity(iCity); 
	elements -= elements/10;		//每前進一個城市,血量減少1/10
	//到達敵方基地,返回0, 到達常規城市,返回1 
	if(city == enemyCity)		return 0;
	else						return 1;	
}




Lion::Lion(string team, int number, int elements, int force, int city, int totalCities, bool direction, int loyalty, int loyaltyDec):Warrior("lion", team, number, elements, force, city, totalCities, direction){
	if(0 == number%3)
		weaponVec.push_back(make_pair(0, new Sword(force*2/10)));
	else if(1 == number%3)
		weaponVec.push_back(make_pair(1, new Bomb(force*4/10)));	
	else
		weaponVec.push_back(make_pair(2, new Arrow(force*3/10)));
	this->loyalty = loyalty;		
	this->loyaltyDec = loyaltyDec;		
	printLoyalty();
}
Lion::~Lion(){
	cout<<"Lion call"<<endl; 
}
int Lion::march(NormalCity* iCity){
	int enemyCity = 0; 
	if(0 == team.compare("red")){
		enemyCity = totalCities+1;
	}else if(0 == team.compare("blue")){
		enemyCity = 0;
	}else{
		return -2;			//未知錯誤 
	}
	
	if(city == enemyCity)	//如果當前已經在敵方基地,則無需前進,返回-1
		return -1;
	
	//前進一個城市 
	if(direction)	city += 1;		
	else			city -= 1;
	//cout<<team<<" "<<name<<", number="<<number<<" march city = "<<city<<", enemyCity = "<<enemyCity<<endl;
	setCity(iCity); 
	loyalty -= loyaltyDec;		//每前進一個城市,忠誠度降低 
	//到達敵方基地,返回0, 到達常規城市,返回1 
	if(city == enemyCity)		return 0;
	else						return 1;	
}
void Lion::escape(void){
	//002:05 blue lion 1 ran away
	Game::printGameTime(); 
	cout<<team<<" "<<name<<" "<<number<<" ran away"<<endl; 
}
void Lion::showTestInfo(void){
	cout<<"name="<<name<<",team="<<team<<",number="<<number<<",elements="\
		<<elements<<",force="<<force<<",city="<<city<<",direction="<<direction<<",loyalty="<<loyalty<<",loyaltyDec="<<loyaltyDec<<endl;
}
void Lion::printLoyalty(void){
	cout<<"Its loyalty is "<<loyalty<<endl;
}



Wolf::Wolf(string team, int number, int elements, int force, int city, int totalCities, bool direction):Warrior("wolf", team, number, elements, force, city, totalCities, direction){}
Wolf::~Wolf(){
	cout<<"Wolf call"<<endl; 
}
int Wolf::rob(Warrior * enemy){
	if((NULL == enemy) || (enemy == this))
		return -1;					//傳入錯誤參數,直接返回-1 
	if(enemy->weaponVec.empty() || (0 == enemy->name.compare("wolf")))
		return 1;					//敵人沒有武器或者敵人是狼時,直接返回1
		
	int swordNum = 0;
  	int bombNum = 0;
	int arrowNum = 0;
				
	enemy->weaponSort();			//將敵人武器分類後,從編號小的開始搶																		
	int  min = (*(enemy->weaponVec.begin())).first;		//記下敵人最小的武器編號 
	for(WEAPON_VEC::iterator i=enemy->weaponVec.begin(); i!=enemy->weaponVec.end(); ){
		if((*i).first != min)							//搶完所有最小編號的武最後就退出 
			break; 
		if(weaponVec.size() < 10){						//狼的武器少於10個,才搶 
			if(0 == (*i).first){						//攻擊力重新計算 
				swordNum++;
				(*i).second->force = force*2/10;
			}else if(1 == (*i).first){
				bombNum++;
				(*i).second->force = force*4/10;
			}else if(2 == (*i).first){
				arrowNum++;
				(*i).second->force = force*3/10;
			}
			weaponVec.push_back(*i);					//放入狼的武器容器中 
			enemy->weaponVec.erase(i);					//移除原先武士的對應武器
		}	
	}
	//008:35 red wolf 3 took 1 sword from blue lion 6 in city 7
	Game::printGameTime(); 
	cout<<team<<" "<<name<<" "<<number<<" took ";
	
	if(swordNum || bombNum || arrowNum){
		if(swordNum){
			cout<<swordNum<<" sword ";
		}
		if(bombNum){
			cout<<bombNum<<" bomb ";
		}
		if(arrowNum){
			cout<<arrowNum<<" arrow ";
		}
	}
	cout<<"from "<<enemy->team<<" "<<enemy->name<<" "<<enemy->number<<" in city "<<city<<endl;
	return 0;
}
#if DEBUG
int main(){
	//測試1 : 武士基類的構造函數和所有信息打印函數 
//	Warrior *w1 = new Warrior(); 
//	Warrior *w2 = new Warrior("pig", "blue", 10, 100, 120, 3, false); 
// 
//	w1->showInfo();
//	w2->showInfo();
//	
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();
//	
//	w1->showTestInfo();
//	w2->showTestInfo();
	
	//測試2 : 武士血量降低,判斷武士是否活着
//	Warrior *w2 = new Warrior("pig", "blue", 10, 100, 120, 3, false); 
//	if(w2->alive())
//		cout<<"before:alive"<<endl;
//	else
//		cout<<"before:died"<<endl;
	//血量降低爲0的測試 
//	w2->decElements(100);
//	if(w2->alive())
//		cout<<"after:alive"<<endl;
//	else
//		cout<<"after:died"<<endl; 
	//血量降低爲負數的測試 
//	w2->decElements(200);
//	if(w2->alive())
//		cout<<"after:alive"<<endl;
//	else
//		cout<<"after:died"<<endl;  
	
	//測試3 : 武士前進到下一個城市
//	int ret=1;
//	Warrior *w2 = new Warrior("pig", "blue", 10, 100, 120, 4, false); 
//	w2->showTestInfo(); 
//	while(ret > 0){				//返回值大於0,說明之前前進到一個普通城市,可以進行下一次前進 
//		ret = w2->march(0);	
//	}
	
	//測試4 :武器排序、攻擊、和繳獲測試 
//	Warrior *w1 = new Warrior("redBoy", "red",  10,  500, 120, 3, true); 
//	Warrior *w2 = new Warrior("blueGirl", "blue",  8,  200, 60,  0, false);
//	 
//	//創建武器對象 
//	Weapon *pSword1  = new Sword(10);
//	Weapon *pSword2  = new Sword(20);
//	Weapon *pSword3  = new Sword(30);
//	Weapon *pBomb1   = new Bomb(40);
//	Weapon *pBomb2   = new Bomb(50);
//	Weapon *pBomb3   = new Bomb(60);
//	Weapon *pArrow1  = new Arrow(70);
//	Weapon *pArrow2  = new Arrow(80);
//	Weapon *pArrow3  = new Arrow(90);
//	Weapon *pArrow4  = new Arrow(80);
//	Weapon *pArrow5  = new Arrow(70);
//	
//	//給雙方發武器
//	w1->weaponVec.push_back(make_pair(pArrow1->number, pArrow1));
//	w1->weaponVec.push_back(make_pair(pSword1->number, pSword1));
//	w1->weaponVec.push_back(make_pair(pBomb2->number, pBomb2));
//	w1->weaponVec.push_back(make_pair(pArrow2->number, pArrow2));
//	
//	w2->weaponVec.push_back(make_pair(pArrow3->number, pArrow3));
//	w2->weaponVec.push_back(make_pair(pSword2->number, pSword2));
//	w2->weaponVec.push_back(make_pair(pSword3->number, pSword3));
//	w2->weaponVec.push_back(make_pair(pBomb1->number, pBomb1));
//	w2->weaponVec.push_back(make_pair(pBomb3->number, pBomb3));
//	w2->weaponVec.push_back(make_pair(pArrow4->number, pArrow4));
//	w2->weaponVec.push_back(make_pair(pArrow5->number, pArrow5));
	
	//展示武器數量 
//	w1->showInfo();
//	w2->showInfo();
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();
//	
//	排序函數
//	pArrow2->useWeapon();	//使用一次,看排序是否正確 
//	pArrow4->useWeapon();	//使用一次,看排序是否正確 
//	w1->weaponSort();
//	w2->weaponSort();
//	cout<<"after sort"<<endl; 
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();

	//繳獲武器測試
//	cout<<"after take"<<endl; 
//	//w1->getEnemyWeapon(w2);
//	w2->getEnemyWeapon(w1);
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();


	//單步攻擊測試
//	w1->weaponSort();
//	w2->weaponSort();
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();
//	
//	w1->showTestInfo(); 
//	w2->showTestInfo();
//	w1->attack(w2);
//	cout<<"attack time 1"<<endl;
//	w1->showTestInfo(); 
//	w2->showTestInfo(); 
//	w1->attack(w2);
//	cout<<"attack time 2"<<endl;
//	w1->showTestInfo(); 
//	w2->showTestInfo(); 
	
	//致死攻擊測試
//	w1->weaponSort();
//	w2->weaponSort();
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();
//	w1->showTestInfo(); 
//	w2->showTestInfo(); 
//	cout<<"before attack test"<<endl;
//	int ret1=0,ret2=0;
//	while(true){
//		ret1 = w1->attack(w2);
//		if(!w1->alive() || !w2->alive())	//出現死人的情況,則退出循環 
//			break;
//		if(ret1 && ret1)					//雙方都沒有武器,則退出循環 
//			break;
//			
//		ret2 = w2->attack(w1);
//		if(!w1->alive() || !w2->alive())	//出現死人的情況,則退出循環 
//			break;
//		if(ret1 && ret1)					//雙方都沒有武器,則退出循環 
//			break;
//	} 
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();
//	w1->showTestInfo(); 
//	w2->showTestInfo(); 	



	//測試5 :子類龍的測試 
//	Dragon *w1 = new Dragon("red", 12, 500, 100, 3, true);
//	w1->showWeaponInfo();
//	w1->yelled();

	//測試6 :子類忍者的測試 
//	Dragon *w1 = new Dragon("red", 12, 500, 100, 3, true);
//	Warrior *w2 = new Ninja("blue", 12, 200, 200, 3, false);
//
//	w1->weaponSort();
//	w2->weaponSort();
//	
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();
//	
//	w1->showTestInfo();
//	w2->showTestInfo();
//	
//	int ret1=0,ret2=0;
//	while(true){
//		ret2 = w2->attack(w1);
//		if(!w1->alive() || !w2->alive())	//出現死人的情況,則退出循環 
//			break;
//		if(ret1 && ret2)					//雙方都沒有武器,則退出循環 
//			break;
//		ret1 = w1->attack(w2);
//		if(!w1->alive() || !w2->alive())	//出現死人的情況,則退出循環 
//			break;
//		if(ret1 && ret2)					//雙方都沒有武器,則退出循環 
//			break;
//	} 
//	cout<<"after attack"<<endl;
//	w1->showTestInfo();
//	w2->showTestInfo();

	//測試7 :子類冰人的測試 
//	Warrior *w1 = new Iceman("red", 12, 500, 100, 7, true);
//	w1->march(10);
//	w1->march(10);
//	w1->march(10);
//	w1->march(10);
	
	//測試8 :子類獅子的測試 
//	Lion *w1 = new Lion("red", 12, 500, 100, 3, true, 100, 40);
//	for(int i=0; i<10; i++){
//		w1->march(10);
//		if(w1->loyalty <= 0)
//			w1->escape();
//	}

	//測試9 :子類狼的測試 
//	Wolf *w3 = new Wolf("red", 12, 500, 100, 7, true);
//	
//	w1->showWeaponInfo();
//	w2->showWeaponInfo();
//	w3->rob(w1);
//	w1->showWeaponInfo(); 
//	w3->rob(w2);
//	w2->showWeaponInfo(); 
}
#endif 

warrior.h

#ifndef __WARRIOR__H
#define __WARRIOR__H

#include <iostream>
#include <algorithm>
#include <vector>
#include "weapon.h"

using namespace std;
class Warrior;
class NormalCity;

//pair對象的first爲武器編號,second爲武器對象指針 
typedef pair<int,Weapon*>			WEAPON_PAIR;
typedef vector<WEAPON_PAIR> 		WEAPON_VEC;

//基類:武士 
class Warrior{
public:
	string name;	//武士名稱			//"dragon", "ninja", "iceman", "lion", "wolf"
	string team;	//武士所屬陣營 		//red,blue 
	int number;		//編號 				//按出生順序編號 1-N 
	int elements;	//生命值
	int force;		//攻擊力 
	int city;		//所在城市編號		//武士會路過不同的城市 
	int totalCities;//總城市數量 
	bool direction;	//行進方向 			//向東爲true,向西爲false
	WEAPON_VEC weaponVec;				//武士擁有的武器 
	WEAPON_VEC::iterator iweapon;	   	//輪流攻擊時,依次遍歷,指向下一個使用的武器 
public:
	Warrior(); 
	Warrior(string name, string team, int number, int elements, int force, int city, int totalCities, bool direction);
	virtual ~Warrior();
	int decElements(int force);				//受到攻擊,減少生命值,若生命值已經不大於0,則返回-1 
	bool alive(void);						//返回武士是否存活的信息 
	virtual int march(NormalCity* iCity);	//前進,到下一個城市,參數是敵方基地的城市編號,否則不知道何時到達敵方基地
	void setCity(NormalCity* iCity);		//前進後,將自己的指針保存到城市對象中 
	virtual int attack(Warrior * enemy);	//攻擊敵人
	void weaponSort(void);					//發動攻擊前,對武器排序
	void getEnemyWeapon(Warrior * enemy);	//繳獲敵人的武器
	bool checkWeaponNoForce(void);			//檢查當前武器是不是無傷害,如果劍無傷害,則可能死循環 
	void showInfo(void);					//展示武器數量和血量 
	void showWeaponInfo(void);				//顯示武器的具體信息,僅供調試使用
	virtual void showTestInfo(void);		//顯示武士的具體信息,僅供調試使用
//	void printGameTime(int gameTime);		//打印當前遊戲時間 
	void printBornInfo(void);				//打印出生信息 
};

//派生類:龍 
class Dragon : public Warrior{
public:
	Dragon(string team, int number, int elements, int force, int city, int totalCities, bool direction);
	~Dragon();
	void yelled(void);				//戰勝後歡呼  
};

//派生類:忍者 
class Ninja : public Warrior{
public:
	Ninja(string team, int number, int elements, int force, int city, int totalCities, bool direction);
	~Ninja();
	int attack(Warrior * enemy);	//使用炸彈不受傷害 
};

//派生類:冰人 
class Iceman : public Warrior{
public:
	Iceman(string team, int number, int elements, int force, int city, int totalCities, bool direction);
	~Iceman();
	int march(NormalCity* iCity);
};

//派生類:獅子 
class Lion : public Warrior{
public:
	int loyalty;			//降生時的忠誠度 
	int loyaltyDec; 		//每次前進需要減少的忠誠度 
	Lion(string team, int number, int elements, int force, int city, int totalCities, bool direction, int loyalty, int loyaltyDec);
	~Lion();
	int march(NormalCity* iCity);
	void escape(void);		//獅子逃跑 
	void showTestInfo(void);
	void printLoyalty(void);
};

//派生類:狼
class Wolf : public Warrior{
public:
	Wolf(string team, int number, int elements, int force, int city, int totalCities, bool direction);
	~Wolf();
	int rob(Warrior * enemy);	//搶奪敵人最低編號的武器 
};

#endif

weapon.cpp

#include "weapon.h"
#define DEBUG 0

using namespace std;

//基類 
Weapon::Weapon(int number, int force){
	//判斷初始化數據是否合理 
	if(number < 0 || number > 2)  	this->number = 0;
	else							this->number = number;
	if(force < 0)	this->force = 0;
	else			this->force = force;
}
int Weapon::resetForce(int force){
	if(force < 0)	this->force = 0;
	else			this->force = force;
	
}
int Weapon::useWeapon(void){return times;}				//不降低可使用次數 

//劍 
Sword::Sword(int force):Weapon(0, force){times = 1;}	//劍的可使用次數初始化爲1

//炸彈 
Bomb::Bomb(int force):Weapon(1, force){times = 1;}		//炸彈的可使用次數初始化爲1 
int Bomb::useWeapon(void){								//使用炸彈,降低可使用次數,返回剩餘可使用次數 
	if(times > 0)		times--;
	return times;
}

//弓箭 
Arrow::Arrow(int force):Weapon(2, force){times = 2;}	//弓箭的可使用次數初始化爲2
int Arrow::useWeapon(void){								//使用弓箭,降低可使用次數,返回剩餘可使用次數	
	if(times > 0)		times--;
	return times;
} 

#if DEBUG 
int main(){
	//test1 測試構造函數 
	Sword b(35);
	Bomb  c(48);
	Arrow d(51);
	cout<<"b number="<<b.number<<",force="<<b.force<<",times="<<b.times<<endl;
	cout<<"c number="<<c.number<<",force="<<c.force<<",times="<<c.times<<endl;
	cout<<"d number="<<d.number<<",force="<<d.force<<",times="<<d.times<<endl;
	cout<<endl;

	//test2 測試其它函數
	b.resetForce(200);
	c.resetForce(300);
	d.resetForce(400);
	cout<<"b number="<<b.number<<",force="<<b.force<<",times="<<b.times<<endl;
	cout<<"c number="<<c.number<<",force="<<c.force<<",times="<<c.times<<endl;
	cout<<"d number="<<d.number<<",force="<<d.force<<",times="<<d.times<<endl;
	cout<<endl;
	
	int bt, ct, dt;
	bt = b.useWeapon();
	ct = c.useWeapon();
	dt = d.useWeapon();
	cout<<"b bt="<<bt<<",force="<<b.force<<",times="<<b.times<<endl;
	cout<<"c ct="<<ct<<",force="<<c.force<<",times="<<c.times<<endl;
	cout<<"d dt="<<dt<<",force="<<d.force<<",times="<<d.times<<endl;
	cout<<endl;
	bt = b.useWeapon();
	ct = c.useWeapon();
	dt = d.useWeapon();
	cout<<"b bt="<<bt<<",force="<<b.force<<",times="<<b.times<<endl;
	cout<<"c ct="<<ct<<",force="<<c.force<<",times="<<c.times<<endl;
	cout<<"d dt="<<dt<<",force="<<d.force<<",times="<<d.times<<endl;
}
#endif



weapon.h

#ifndef __WEAPON__H
#define __WEAPON__H

#include <iostream>

using namespace std;

//基類:武器
class Weapon{
public:
	int force;							//攻擊力
	int times;							//剩餘使用次數
	int number; 						//武器的編號 
public:
	Weapon(int number, int force);
	int resetForce(int force);			//武器更換主人,重新計算攻擊力
	virtual int useWeapon(void);
};

//派生類:劍
class Sword : public Weapon{
public:	
	Sword(int force);
};

//派生類:炸彈 
class Bomb : public Weapon{
public: 
	Bomb(int force);
	int useWeapon(void);			//使用武器後,返回剩餘可使用次數 
};

//派生類:弓箭 
class Arrow : public Weapon{
public: 	
	Arrow(int force);
	int useWeapon(void);			//使用武器後,返回剩餘可使用次數 
};

#endif

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章