OpenJudge 百练 POJ 3750:魔兽世界代码
题目查看
毕业多年,当年被大作业支配的恐惧仍历历在目,最近突然心血来潮,便想着再做一遍题目,无奈终极版在百练中找不到,只能做做这个无装备版的,完全独立完成。话不多说,奉上AC代码,也算是记录一下自己的学习点滴。
#include<iostream>
#include <iomanip>
using namespace std;
int WE[5]/*WarriorElements*/, WF[5]/*WarriorForce*/;
void printT(int t);
void StartGame(int M, int N, int T);
class City;
class Warrior {
protected:
friend class City;
int elements;
int force;
int number;
string camp;
int nCamp;
int species;
int survived;
string name;
public:
Warrior(int camp, int num);
void PrintEvent_Produced(int t);
void PrintEvent_MoveForward(int t, int n);
void PrintEvent_ArriveHeadQuarter(int t);
void PrintEvent_EarnElements(int t, int n);
void AddElements(int n);
int Survied() { return survived; }
virtual void Move(int i, int n) {};
virtual void Double() {}
virtual int Attack(int t, Warrior* W, int n);
virtual void FightBack(int t, Warrior* W, int n);
virtual int RewardElements() { return 0; }
virtual void Yell(int t, int n) {}
};
class Dragon :public Warrior {
public:
Dragon(int camp, int num);
virtual void Yell(int t, int n);
};
class Ninja :public Warrior {
public:
Ninja(int camp, int num);
virtual void FightBack(int t, Warrior* W, int n) {}
};
class Iceman :public Warrior {
public:
Iceman(int camp, int num);
virtual void Move(int i, int N);
};
class Lion :public Warrior {
public:
Lion(int camp, int num);
virtual int RewardElements() { return this->elements; }
};
class Wolf :public Warrior {
int win;
public:
Wolf(int camp, int num);
virtual void Double();
};
class HeadQuarter {
protected:
int elements;
int round;
int numWarrior;
string camp;
Warrior* campWarrior;
public:
HeadQuarter(int n);
virtual void ProduceWarrior(int t) {}
virtual void WarriorForward(int t, City* c, int& g, int n) {}
virtual void RewardElement(City* c) {}
void AddElements(int e);
void ReportElements(int t);
~HeadQuarter();
};
class RedHeadQuarter :public HeadQuarter {
friend class City;
public:
RedHeadQuarter(int n) :HeadQuarter(n) { this->camp.assign("red"); }
virtual void ProduceWarrior(int t);
virtual void WarriorForward(int t, City* c, int& g, int n);
virtual void RewardElement(City* c);
};
class BlueHeadQuarter :public HeadQuarter {
friend class City;
public:
BlueHeadQuarter(int n) :HeadQuarter(n) { this->camp.assign("blue"); }
virtual void ProduceWarrior(int t);
virtual void WarriorForward(int t, City* c, int& g, int n);
void RewardElement(City* pCity);
};
class City {
friend class RedHeadQuarter;
friend class BlueHeadQuarter;
City* next;
City* prev;
int flag; // 0:None; 1:Red; 2:Blue
int number;
int elements;
int redWin;
int blueWin;
Warrior* warriorRed;
Warrior* warriorBlue;
Warrior* toNext;
Warrior* toLast;
public:
City(int n);
void SetNext(City* n);
void SetPrev(City* p);
City* GetNext();
void AddElements(int n);
void ForwardInit();
void WarriorForwardOnly1(int t, RedHeadQuarter* rd, BlueHeadQuarter* bd, int n);
void WarriorForward1(int t, RedHeadQuarter* rd, int n);
void WarriorForwardN(int t, BlueHeadQuarter* bd, int n);
void WarriorForward(int t, int n); // City 2 ~ (N-1)
void EarnElements(int t, RedHeadQuarter* rd, BlueHeadQuarter* bd);
void EarnElements2(int t, RedHeadQuarter* rd, BlueHeadQuarter* bd);
void Fight(int t);
void RaiseFlag(int t, int c);
void Delete();
~City();
};
int main() {
int n, i, j, M, N, T;
cin >> n;
for (i = 0; i < n; i++) {
cin >> M >> N >> T;
for (j = 0; j < 5; j++)
cin >> WE[j];
for (j = 0; j < 5; j++)
cin >> WF[j];
cout << "Case:" << i + 1 << endl;
StartGame(M, N, T);
}
return 0;
}
void printT(int t) {
cout << setw(3) << setfill('0') << t / 6 << ':' << t % 6 << '0' << ' ';
}
void StartGame(int M, int N, int T) {
int i, t, hour, minute, gameOn = 1, lionElements = 0;
T /= 10;
RedHeadQuarter* redHeadQuarter = new RedHeadQuarter(M);
BlueHeadQuarter* blueHeadQuarter = new BlueHeadQuarter(M);
City* firstCity = new City(1), * lastCity = firstCity;
if (N != 1)
lastCity = new City(N);
City* pCity = firstCity, * pTmpCity;
for (i = 2; i < N; i++) {
pTmpCity = new City(i);
pCity->SetNext(pTmpCity);
pTmpCity->SetPrev(pCity);
pCity = pTmpCity;
}
if (N != 1) {
pCity->SetNext(lastCity);
lastCity->SetPrev(pCity);
}
for (t = 0; t <= T && gameOn; t++) {
hour = t / 6;
minute = t % 6;
switch (minute) {
case 0:
redHeadQuarter->ProduceWarrior(t);
blueHeadQuarter->ProduceWarrior(t);
break;
case 1:
pCity = firstCity;
do {
pCity->ForwardInit();
pCity = pCity->GetNext();
} while (pCity);
// redHeadQuarter
redHeadQuarter->WarriorForward(t, firstCity, gameOn, N);
// 1~N
if (N == 1)
firstCity->WarriorForwardOnly1(t, redHeadQuarter, blueHeadQuarter, N);
else {
firstCity->WarriorForward1(t, redHeadQuarter, N);
pCity = firstCity->GetNext();
while (pCity != lastCity) {
pCity->WarriorForward(t, N);
pCity = pCity->GetNext();
}
lastCity->WarriorForwardN(t, blueHeadQuarter, N);
}
// blueHeadQuarter
blueHeadQuarter->WarriorForward(t, lastCity, gameOn, N);
break;
case 2:
pCity = firstCity;
do {
pCity->AddElements(10);
pCity = pCity->GetNext();
} while (pCity);
break;
case 3:
pCity = firstCity;
do {
pCity->EarnElements(t, redHeadQuarter, blueHeadQuarter);
pCity = pCity->GetNext();
} while (pCity);
break;
case 4:
pCity = firstCity;
do {
pCity->Fight(t);
pCity = pCity->GetNext();
} while (pCity);
redHeadQuarter->RewardElement(lastCity);
blueHeadQuarter->RewardElement(firstCity);
pCity = firstCity;
do {
pCity->EarnElements2(t, redHeadQuarter, blueHeadQuarter);
pCity = pCity->GetNext();
} while (pCity);
pCity = firstCity;
do {
pCity->Delete();
pCity = pCity->GetNext();
} while (pCity);
break;
case 5:
redHeadQuarter->ReportElements(t);
blueHeadQuarter->ReportElements(t);
break;
}
}
pCity = firstCity;
do {
pTmpCity = pCity;
pCity = pCity->GetNext();
delete pTmpCity;
} while (pCity);
delete redHeadQuarter;
delete blueHeadQuarter;
}
Warrior::Warrior(int camp, int num) {
this->elements = 0;
this->force = 0;
this->number = num;
if (camp)
this->camp = "blue";
else
this->camp = "red";
this->nCamp = camp;
this->species = 0;
this->survived = 1;
}
void Warrior::PrintEvent_Produced(int t) {
printT(t);
cout << this->camp << " " << this->name << " " << this->number << " born" << endl;
}
void Warrior::PrintEvent_MoveForward(int t, int n) {
printT(t);
cout << this->camp << " " << this->name << " " << this->number << " marched to city " << n << " with " << this->elements << " elements and force " << this->force << endl;
}
void Warrior::PrintEvent_ArriveHeadQuarter(int t) {
printT(t);
cout << this->camp << " " << this->name << " " << this->number;
if (this->nCamp)
cout << " reached red headquarter with ";
else
cout << " reached blue headquarter with ";
cout << this->elements << " elements and force " << this->force << endl;
}
void Warrior::PrintEvent_EarnElements(int t, int n) {
printT(t);
cout << this->camp << " " << this->name << " " << this->number << " earned " << n << " elements for his headquarter" << endl;
}
int Warrior::Attack(int t, Warrior* W, int n) {
int rewardElements = W->RewardElements();
printT(t);
cout << this->camp << " " << this->name << " " << this->number << " attacked " << W->camp << " " << W->name << " " << W->number << " in city " << n << " with " << this->elements << " elements and force " << this->force << endl;
W->elements -= this->force;
if (W->elements <= 0) {
printT(t);
cout << W->camp << " " << W->name << " " << W->number << " was killed in city " << n << endl;
this->Double();
this->AddElements(rewardElements);
W->survived = 0;
return 0;
}
return 1;
}
void Warrior::FightBack(int t, Warrior* W, int n)
{
int rewardElements = W->RewardElements();
printT(t);
cout << this->camp << " " << this->name << " " << this->number << " fought back against " << W->camp << " " << W->name << " " << W->number << " in city " << n << endl;
W->elements -= this->force / 2;
if (W->elements <= 0) {
printT(t);
cout << W->camp << " " << W->name << " " << W->number << " was killed in city " << n << endl;
this->AddElements(rewardElements);
W->survived = 0;
}
}
void Warrior::AddElements(int n) {
this->elements += n;
}
Wolf::Wolf(int camp, int num) :Warrior(camp, num) {
this->elements = WE[4];
this->force = WF[4];
this->name.assign("wolf");
this->win = 0;
}
void Wolf::Double() {
this->win++;
if ((win & 1) == 0) {
this->elements <<= 1;
this->force <<= 1;
}
}
Ninja::Ninja(int camp, int num) :Warrior(camp, num) {
this->elements = WE[1];
this->force = WF[1];
this->name.assign("ninja");
}
Lion::Lion(int camp, int num) : Warrior(camp, num) {
this->elements = WE[3];
this->force = WF[3];
this->name.assign("lion");
}
Dragon::Dragon(int camp, int num) : Warrior(camp, num) {
this->elements = WE[0];
this->force = WF[0];
this->name.assign("dragon");
}
void Dragon::Yell(int t, int n) {
printT(t);
cout << this->camp << " dragon " << this->number << " yelled in city " << n << endl;
}
Iceman::Iceman(int camp, int num) :Warrior(camp, num) {
this->elements = WE[2];
this->force = WF[2];
this->name.assign("iceman");
}
void Iceman::Move(int i, int N) {
if ((i & 1) && (!this->nCamp) || ((N - i) & 1) == 0 && this->nCamp)
return;
this->force += 20;
this->elements -= 9;
if (this->elements <= 0)
this->elements = 1;
}
HeadQuarter::HeadQuarter(int n) {
this->elements = n;
this->round = 0;
this->numWarrior = 0;
this->campWarrior = NULL;
}
void HeadQuarter::AddElements(int e) {
this->elements += e;
}
void HeadQuarter::ReportElements(int t) {
printT(t);
cout << this->elements << " elements in " << this->camp << " headquarter" << endl;
}
HeadQuarter::~HeadQuarter() {
if (this->campWarrior)
delete this->campWarrior;
}
void RedHeadQuarter::ProduceWarrior(int t) {
switch (this->round % 5) {
case 0: // iceman
if (WE[2] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Iceman(0, this->round + 1);
this->elements -= WE[2];
break;
case 1: // lion
if (WE[3] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Lion(0, this->round + 1);
this->elements -= WE[3];
break;
case 2: // wolf
if (WE[4] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Wolf(0, this->round + 1);
this->elements -= WE[4];
break;
case 3: // ninja
if (WE[1] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Ninja(0, this->round + 1);
this->elements -= WE[1];
break;
case 4: // dragon
if (WE[0] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Dragon(0, this->round + 1);
this->elements -= WE[0];
break;
}
this->campWarrior->PrintEvent_Produced(t);
this->round++;
}
void RedHeadQuarter::WarriorForward(int t, City* c, int& gameOn, int n) {
if (c->toLast) {
c->toLast->Move(0, n);
c->toLast->PrintEvent_ArriveHeadQuarter(t);
this->numWarrior++;
delete c->toLast;
if (this->numWarrior == 2) {
printT(t);
gameOn = 0;
cout << "red headquarter was taken" << endl;
}
}
}
void RedHeadQuarter::RewardElement(City* pCity) {
do {
if (this->elements < 8)
break;
if (pCity->warriorRed && pCity->warriorBlue) {
if (pCity->warriorRed->Survied() && !pCity->warriorBlue->Survied()) {
pCity->warriorRed->AddElements(8);
this->elements -= 8;
}
}
pCity = pCity->prev;
} while (pCity);
}
void BlueHeadQuarter::ProduceWarrior(int t) {
switch (this->round % 5) {
case 0: // lion
if (WE[3] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Lion(1, this->round + 1);
this->elements -= WE[3];
break;
case 1: // dragon
if (WE[0] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Dragon(1, this->round + 1);
this->elements -= WE[0];
break;
case 2: // ninja
if (WE[1] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Ninja(1, this->round + 1);
this->elements -= WE[1];
break;
case 3: // iceman
if (WE[2] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Iceman(1, this->round + 1);
this->elements -= WE[2];
break;
case 4: // wolf
if (WE[4] > this->elements) {
campWarrior = NULL;
return;
}
this->campWarrior = new Wolf(1, this->round + 1);
this->elements -= WE[4];
break;
}
this->campWarrior->PrintEvent_Produced(t);
this->round++;
}
void BlueHeadQuarter::WarriorForward(int t, City* c, int& gameOn, int n) {
if (c->toNext) {
c->toNext->Move(n + 1, n);
c->toNext->PrintEvent_ArriveHeadQuarter(t);
delete c->toNext;
this->numWarrior++;
if (this->numWarrior == 2) {
printT(t);
gameOn = 0;
cout << "blue headquarter was taken" << endl;
}
}
}
void BlueHeadQuarter::RewardElement(City* pCity) {
do {
if (this->elements < 8)
break;
if (pCity->warriorRed && pCity->warriorBlue) {
if (pCity->warriorBlue->Survied() && !pCity->warriorRed->Survied()) {
pCity->warriorBlue->AddElements(8);
this->elements -= 8;
}
}
pCity = pCity->next;
} while (pCity);
}
City::City(int n) {
this->next = NULL;
this->prev = NULL;
this->flag = 0;
this->number = n;
this->elements = 0;
this->redWin = 0;
this->blueWin = 0;
this->warriorRed = NULL;
this->warriorBlue = NULL;
this->toNext = NULL;
this->toLast = NULL;
}
void City::SetNext(City* n) {
this->next = n;
}
void City::SetPrev(City* p) {
this->prev = p;
}
City* City::GetNext() {
return this->next;
}
void City::AddElements(int n) {
this->elements += n;
}
void City::ForwardInit() {
if (this->warriorRed)
this->toNext = this->warriorRed;
else
this->toNext = NULL;
if (this->warriorBlue)
this->toLast = this->warriorBlue;
else
this->toLast = NULL;
}
void City::WarriorForwardOnly1(int t, RedHeadQuarter* rd, BlueHeadQuarter* bd, int n) {
// Red
if (rd->campWarrior) {
this->warriorRed = rd->campWarrior;
rd->campWarrior = NULL;
this->warriorRed->Move(this->number, n);
warriorRed->PrintEvent_MoveForward(t, this->number);
}
else
this->warriorRed = NULL;
// Blue
if (bd->campWarrior) {
this->warriorBlue = bd->campWarrior;
bd->campWarrior = NULL;
this->warriorBlue->Move(this->number, n);
warriorBlue->PrintEvent_MoveForward(t, this->number);
}
else
this->warriorBlue = NULL;
}
void City::WarriorForward1(int t, RedHeadQuarter* rd, int n) {
// Red
if (rd->campWarrior) {
this->warriorRed = rd->campWarrior;
rd->campWarrior = NULL;
this->warriorRed->Move(this->number, n);
warriorRed->PrintEvent_MoveForward(t, this->number);
}
else
this->warriorRed = NULL;
// Blue
if (this->next->toLast) {
this->warriorBlue = this->next->toLast;
this->warriorBlue->Move(this->number, n);
warriorBlue->PrintEvent_MoveForward(t, this->number);
}
else
this->warriorBlue = NULL;
}
void City::WarriorForwardN(int t, BlueHeadQuarter* bd, int n) {
// Red
if (this->prev->toNext) {
this->warriorRed = this->prev->toNext;
this->warriorRed->Move(this->number, n);
warriorRed->PrintEvent_MoveForward(t, this->number);
}
else
this->warriorRed = NULL;
// Blue
if (bd->campWarrior) {
this->warriorBlue = bd->campWarrior;
bd->campWarrior = NULL;
this->warriorBlue->Move(this->number, n);
warriorBlue->PrintEvent_MoveForward(t, this->number);
}
else
this->warriorBlue = NULL;
}
void City::WarriorForward(int t, int n) { // City 2 ~ (N-1)
// Red
if (this->prev->toNext) {
this->warriorRed = this->prev->toNext;
this->warriorRed->Move(this->number, n);
warriorRed->PrintEvent_MoveForward(t, this->number);
}
else
this->warriorRed = NULL;
// Blue
if (this->next->toLast) {
this->warriorBlue = this->next->toLast;
this->warriorBlue->Move(this->number, n);
warriorBlue->PrintEvent_MoveForward(t, this->number);
}
else
this->warriorBlue = NULL;
}
void City::EarnElements(int t, RedHeadQuarter* rd, BlueHeadQuarter* bd) {
if (!this->warriorBlue && this->warriorRed) {
printT(t);
cout << "red " << this->warriorRed->name << " " << this->warriorRed->number << " earned " << this->elements << " elements for his headquarter" << endl;
rd->AddElements(this->elements);
this->elements = 0;
}
else {
if (this->warriorBlue && !this->warriorRed) {
printT(t);
cout << "blue " << this->warriorBlue->name << " " << this->warriorBlue->number << " earned " << this->elements << " elements for his headquarter" << endl;
bd->AddElements(this->elements);
this->elements = 0;
}
}
}
void City::EarnElements2(int t, RedHeadQuarter* rd, BlueHeadQuarter* bd) {
if (this->warriorBlue && this->warriorRed) {
if (!this->warriorBlue->survived && this->warriorRed->survived) {
rd->AddElements(this->elements);
this->elements = 0;
}
else {
if (this->warriorBlue->survived && !this->warriorRed->survived) {
bd->AddElements(this->elements);
this->elements = 0;
}
}
}
}
void City::Fight(int t) {
if (!(this->warriorRed && this->warriorBlue))
return;
if (this->flag == 0 && (this->number & 1) || this->flag == 1) { // Red
if (this->warriorRed->Attack(t, this->warriorBlue, this->number))
this->warriorBlue->FightBack(t, this->warriorRed, this->number);
if (this->warriorRed->survived)
this->warriorRed->Yell(t, this->number);
}
else {
if (this->flag == 0 && (this->number & 1) == 0 || this->flag == 2) { // Blue
if (this->warriorBlue->Attack(t, this->warriorRed, this->number))
this->warriorRed->FightBack(t, this->warriorBlue, this->number);
if (this->warriorBlue->survived)
this->warriorBlue->Yell(t, this->number);
}
}
if (this->warriorRed->survived && !this->warriorBlue->survived) {
this->warriorRed->PrintEvent_EarnElements(t, this->elements);
this->redWin++;
this->blueWin = 0;
if (this->redWin >= 2 && this->flag != 1) {
this->RaiseFlag(t, 1);
this->blueWin = 0;
}
}
if (this->warriorBlue->survived && !this->warriorRed->survived) {
this->warriorBlue->PrintEvent_EarnElements(t, this->elements);
this->blueWin++;
this->redWin = 0;
if (this->blueWin >= 2 && this->flag != 2) {
this->RaiseFlag(t, 0);
this->redWin = 0;
}
}
if (this->warriorRed->survived && this->warriorBlue->survived) {
this->redWin = 0;
this->blueWin = 0;
}
}
void City::RaiseFlag(int t, int c) {
printT(t);
if (c) {
this->flag = 1;
cout << "red ";
}
else {
this->flag = 2;
cout << "blue ";
}
cout << "flag raised in city " << this->number << endl;
}
void City::Delete() {
if (this->warriorRed)
if (!this->warriorRed->survived) {
delete this->warriorRed;
this->warriorRed = NULL;
}
if (this->warriorBlue)
if (!this->warriorBlue->survived) {
delete this->warriorBlue;
this->warriorBlue = NULL;
}
}
City::~City() {
if (this->warriorRed)
delete this->warriorRed;
if (warriorBlue)
delete this->warriorBlue;
}