在魔兽三基础上改成,唯一优点是能过。
吸取了写三的经验教训,先用注释把需要改的地方全部标好怎么改才开始写,于是没有再出现前后不一致的痛苦情况——除了一处数组大小改前没改后,导致bebug模式能过、直接跑起来超时,让当时的我十分困惑。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
#define WARRIOR_NUM 5
#define WEAPON_NUM 3
#define MAX_WARRIORS 1000
enum { DRAGON,NINJA,ICEMAN,LION,WOLF };
/*
char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
红方司令部按照 iceman、lion、wolf、ninja、dragon 的顺序制造武士。
蓝方司令部按照 lion、dragon、ninja、iceman、wolf 的顺序制造武士。
*/
int n,k,r;//n cities,lion loses k loyalty per step,r ATK of arrows
bool warStopped=false;
bool redreach=false,bluereach=false;
bool redstop=false,bluestop=false;
class CHeadquarter;
class CWarrior;
CWarrior* city[25][2];
int cityflag[25];
int cityrecord[25][2];//the first one stores the previous record. the second one stores the record from this round
int citylife[25];
class CWeapon
{
public:
int nKindNo;//0sword 1bomb 2arrow
int nNo;//number in warriors hands
int nTimesLeft;
int ATK;
virtual int nForce(int userForce){return 0;};
virtual void useWeapon(CWarrior* user, CWarrior* taker){
}
static const char * Names[WEAPON_NUM];
CWeapon(int no_,int _atk){
nNo=no_;
ATK=_atk;
nTimesLeft=3;
}
};
bool compare(CWeapon* w1,CWeapon* w2){
if (w1->nKindNo<w2->nKindNo) return true;
else if(w1->nKindNo>w2->nKindNo) return false;
else if(w1->nKindNo==2&&w2->nKindNo==2){
if(w1->nTimesLeft<w2->nTimesLeft){
return true;
}
else{
return false;
}
}
return false;
}
bool recompare(CWeapon* w1,CWeapon* w2){
if (w1->nKindNo<w2->nKindNo) return true;
else if(w1->nKindNo>w2->nKindNo) return false;
else if(w1->nKindNo==2&&w2->nKindNo==2){
if(w1->nTimesLeft<w2->nTimesLeft){
return false;
}
else{
return true;
}
}
return false;
}
class CWarrior
{
public:
CHeadquarter * pHeadquarter;
int nNo;//"no."in its headquarter
int location;
static const char * Names[WARRIOR_NUM];
static int InitialLifeValue [WARRIOR_NUM];
static int Attack [WARRIOR_NUM];
int nLoyalty=100;
int lifeValue;
int attack;
double fmorale;
CWeapon* wp[4];
int weaponCount;
CWarrior( CHeadquarter * p,int nNo_);
virtual int getType()=0;
virtual void PrintResult(int nTime,int nKindNo);
virtual void PrintResult(int nTime) = 0;
~CWarrior(){
for(int i=0;i<4;i++){
if(wp[i]!=NULL){
//delete wp[i];
}
}
}
virtual void wMarch(int dir,int _time){
}
void takeBlow(CWeapon* w,CWarrior* user){
lifeValue-= (w->ATK);
}
void ditchWeapon(int n){
weaponCount--;
wp[n]=NULL;
}
void boostmorale(){
fmorale+=0.2;
}
void ggmorale(){
fmorale-=0.2;
}
void wReportWeapon(int _time);
//√DIFF
void rob(CWarrior* W){
for(int i=0;i<3;i++){
if(wp[i]==NULL&&W->wp[i]!=NULL){
wp[i]=W->wp[i];
}
}
}
};
//consider getting an ATK attribute,initialize when born, if ATK=0, ditch immediatly
//Gets blunt: after every use, ATK becomes 80%
//make that a method?
//when ATK becomse 0, ditch it
class CSword:public CWeapon{
public:
CSword(int no_, int atk):CWeapon(no_, atk*2/10){
CWeapon::nKindNo=0;};
void useWeapon(CWarrior* user, CWarrior* taker){
taker->takeBlow(this,user);
ATK=ATK*8/10;
if(ATK<=0){
user->ditchWeapon(0);
}
}
};
//probably should write usebomb after the nfight
//consider making the decision a version of the nfight func
class CBomb:public CWeapon{
public:
CBomb(int no_):CWeapon(no_,0){CWeapon::nKindNo=1;};
void useWeapon(CWarrior* user, CWarrior* taker){
/*taker->takeBlow(this,user);
if(user->getType()!=2)
user->takeBackfire(this);*/
//√ADD: they both die
user->lifeValue=0;
taker->lifeValue=0;
user->ditchWeapon(1);
}
};
//ATK R
//shoots to enemy in the next city to march to(not if it's headquarter)
class CArrow:public CWeapon{
public:
CArrow(int no_):CWeapon(no_,r){CWeapon::nKindNo=2;};
int nForce(int userForce){
return userForce*3/10;//not true anymore
}
void useWeapon(CWarrior* user,CWarrior* taker){
taker->takeBlow(this,user);
nTimesLeft--;
if(nTimesLeft<=0){
user->ditchWeapon(2);
}
}
};
class CDragon;
class CNinja;
class CIceman;
class CLion;
class CWolf;
class CHeadquarter
{
private:
int nTotalLifeValue;
bool bStopped;
int nCurMakingSeqIdx;
int anWarriorNum[WARRIOR_NUM];
int nTotalWarriorNum;
CWarrior * pWarriors[MAX_WARRIORS];
public:
int nColor;
friend class CWarrior;
static int MakingSeq[2][WARRIOR_NUM];
void Init(int nColor_, int lv);
~CHeadquarter () ;
int Produce(int nTime);
void GetColor( char * szColor);
int GetTotalLifeValue() { return nTotalLifeValue; }
void changeLifeValue(int _val){ nTotalLifeValue+=_val; }
void March(int dir,int _time){
for(int i=0;i<nTotalWarriorNum;i++){
if(pWarriors[i]!=NULL){
pWarriors[i]->wMarch(dir,_time);
}
}
}
void CheckRun(int _time){
for(int i=0;i<nTotalWarriorNum;i++){
if((pWarriors[i]!=NULL)&&(pWarriors[i]->getType()==4)&&(pWarriors[i]->nLoyalty<=0)&&(pWarriors[i]->location!=(((n+1)+(n+1)*pow(-1,nColor))/2))){
char szColor[20];
pWarriors[i]->pHeadquarter->GetColor(szColor);
int hour= _time/60,minute=_time%60;
printf("%03d:%02d %s lion %d ran away\n",hour,minute,szColor,pWarriors[i]->nNo);
//cout<<city[pWarriors[i]->location][nColor]->nNo<<endl;
city[pWarriors[i]->location][nColor]=NULL;
pWarriors[i]=NULL;
}
}
}
void loseWarrior(CWarrior* W){
pWarriors[W->nNo-1]=NULL;
}
void ReportLifeValue(int _time){
int hour=_time/60,minute=_time%60;
char szcolor[20];
GetColor(szcolor);
printf("%03d:%02d %d elements in %s headquarter\n",hour,minute,nTotalLifeValue,szcolor);
}
void reward(int i){
if(cityrecord[i][1]==1&&nColor==0&&nTotalLifeValue>=8){
nTotalLifeValue-=8;
city[i][0]->lifeValue+=8;
}
if(cityrecord[i][1]==-1&&nColor==1&&nTotalLifeValue>=8){
nTotalLifeValue-=8;
city[i][1]->lifeValue+=8;
}
}
void harvest(int i){
if(cityrecord[i][1]==1&&nColor==0){
nTotalLifeValue+=citylife[i];
citylife[i]=0;
}
if(cityrecord[i][1]==-1&&nColor==1){
nTotalLifeValue+=citylife[i];
citylife[i]=0;
}
}
};
//√boost morale(0.2) when kills, lose morale when tie.
//√make them methods
//changing morale precedes yelling
class CDragon:public CWarrior
{
private:
//int lifeValue;
//int attack;
//int location;
public:
int type=1;
void Countmorale()
{
fmorale = pHeadquarter -> GetTotalLifeValue() /(double)CWarrior::InitialLifeValue [0];
}
CDragon( CHeadquarter * p,int nNo_):
CWarrior(p,nNo_) {
weaponCount=1;
lifeValue=InitialLifeValue[DRAGON];
attack=Attack[DRAGON];
switch(nNo % WEAPON_NUM){
case 0:
wp[0]=new CSword(0,attack);
if(wp[0]->ATK<=0){
ditchWeapon(0);
}
break;
case 1:
wp[1]=new CBomb(1);
break;
case 2:
wp[2]=new CArrow(2);
break;
}
if(p->nColor==1){
location=n+1;
}
else{
location=0;
}
Countmorale();
}
//√ADD: Its morale is xx.xx
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,DRAGON);
printf("Its morale is %.2f\n",fmorale);
}
virtual void wMarch(int dir,int _time){
if(!((location==0&&dir==1)||(location==n+1&&dir==0))){
city[location][dir]=NULL;
location+=pow(-1,dir);
int hour=_time/60;
int minute=_time%60;
char szColor[20];
pHeadquarter->GetColor(szColor);
if((location==0&&dir==1)&&city[location][dir]!=NULL){
warStopped=true;
bluestop=true;
}
if((location==n+1&&dir==0)&&city[location][dir]!=NULL){
warStopped=true;
redstop=true;
}
city[location][dir]=this;
}
}
int getType(){
return type;
}
};
//ninjas don't fight back
//√NO MORE can't die from bomb
class CNinja:public CWarrior
{
private:
//int lifeValue;
//int attack;
//int location;
public:
int type=2;
CNinja( CHeadquarter * p,int nNo_):
CWarrior(p,nNo_) {
weaponCount=2;
lifeValue=InitialLifeValue[NINJA];
attack=Attack[NINJA];
switch(nNo % WEAPON_NUM){
case 0:
wp[0]=new CSword(0,attack);
wp[1]=new CBomb(1);
if(wp[0]->ATK<=0){
ditchWeapon(0);
}
break;
case 1:
wp[1]=new CBomb(1);
wp[2]=new CArrow(2);
break;
case 2:
wp[2]=new CArrow(2);
wp[0]=new CSword(0,attack);
if(wp[0]->ATK<=0){
ditchWeapon(0);
}
break;
}
if(p->nColor==1){
location=n+1;
}
else{
location=0;
}
}
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,NINJA);
}
virtual void wMarch(int dir,int _time){
if(!((location==0&&dir==1)||(location==n+1&&dir==0))){
city[location][dir]=NULL;
location+=pow(-1,dir);
int hour=_time/60;
int minute=_time%60;
char szColor[20];
pHeadquarter->GetColor(szColor);
if((location==0&&dir==1)&&city[location][dir]!=NULL){
bluestop=true;
warStopped=true;
}
if((location==n+1&&dir==0)&&city[location][dir]!=NULL){
redstop=true;
warStopped=true;
}
city[location][dir]=this;
}
}
int getType(){
return type;
}
};
//√wMarch needs to change: loses lifeValue(9) every two steps(count them with new attribute?)
//√...but also boosts ATK(20)
//√...also if walks lifeValue down to 0 or negative, returns to 1
class CIceman:public CWarrior
{
private:
int steps;
public:
int type=3;
CIceman( CHeadquarter * p,int nNo_):
CWarrior(p,nNo_)
{
weaponCount=1;
steps=0;
lifeValue=InitialLifeValue[ICEMAN];
attack=Attack[ICEMAN];
switch(nNo % WEAPON_NUM){
case 0:
wp[0]=new CSword(0,attack);
if(wp[0]->ATK<=0){
ditchWeapon(0);
}
break;
case 1:
wp[1]=new CBomb(1);
break;
case 2:
wp[2]=new CArrow(2);
break;
}
if(p->nColor==1){
location=n+1;
}
else{
location=0;
}
}
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,ICEMAN);
}
virtual void wMarch(int dir,int _time){
if(!((location==0&&dir==1)||(location==n+1&&dir==0))){
city[location][dir]=NULL;
location+=pow(-1,dir);
int hour=_time/60;
int minute=_time%60;
char szColor[20];
pHeadquarter->GetColor(szColor);
steps++;
if(steps==2){
steps=0;
attack+=20;
lifeValue-=9;
if(lifeValue<=0) lifeValue=1;
}
if((location==0&&dir==1)&&city[location][dir]!=NULL){
warStopped=true;
bluestop=true;
}
if((location==n+1&&dir==0)&&city[location][dir]!=NULL){
warStopped=true;
redstop=true;
}
city[location][dir]=this;
}
}
int getType(){
return type;
}
};
//√NO MORE loyalty loss from marching
//loyalty -K every tie
//if dies, adds lifevalue before the fight to the opponent
class CLion:public CWarrior
{
private:
//int lifeValue;
//int attack;
//int location;
public:
int type=4;
void CountLoyalty()
{
nLoyalty = pHeadquarter ->GetTotalLifeValue();
}
CLion( CHeadquarter * p,int nNo_):
CWarrior(p,nNo_) {
weaponCount=0;
CountLoyalty();
lifeValue=InitialLifeValue[LION];
attack=Attack[LION];
if(p->nColor==1){
location=n+1;
//cout<<"lion in red"<<endl;
}
else{
location=0;
//cout<<"in blue"<<endl;
}
//cout<<"location now "<<location<<endl;
}
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,LION);
CountLoyalty();
printf("Its loyalty is %d\n",nLoyalty);
//cout<<weaponCount<<endl;
}
virtual void wMarch(int dir,int _time){
if(!((location==0&&dir==1)||(location==n+1&&dir==0))){
city[location][dir]=NULL;
location+=pow(-1,dir);
int hour=_time/60;
int minute=_time%60;
char szColor[20];
pHeadquarter->GetColor(szColor);
if((location==0&&dir==1)&&city[location][dir]!=NULL){
warStopped=true;
bluestop=true;
}
if((location==n+1&&dir==0)&&city[location][dir]!=NULL){
warStopped=true;
redstop=true;
}
city[location][dir]=this;
}
}
int getType(){
return type;
}
};
//ONLY wolves get weapon from dead enemy now.
//ONLY 1 for each type
class CWolf:public CWarrior
{
private:
//int lifeValue;
//int attack;
//int location;
public:
int type=5;
CWolf( CHeadquarter * p,int nNo_):
CWarrior(p,nNo_) {
weaponCount=0;
lifeValue=InitialLifeValue[WOLF];
attack=Attack[WOLF];
if(p->nColor==1){
location=n+1;
}
else{
location=0;
}
}
void PrintResult(int nTime)
{
CWarrior::PrintResult(nTime,WOLF);
}
virtual void wMarch(int dir,int _time){
if(!((location==0&&dir==1)||(location==n+1&&dir==0))){
city[location][dir]=NULL;
location+=pow(-1,dir);
int hour=_time/60;
int minute=_time%60;
char szColor[20];
pHeadquarter->GetColor(szColor);
if((location==0&&dir==1)&&city[location][dir]!=NULL){
warStopped=true;
bluestop=true;
}
if((location==n+1&&dir==0)&&city[location][dir]!=NULL){
warStopped=true;
redstop=true;
}
city[location][dir]=this;
}
}
int getType(){
return type;
}
};
CWarrior::CWarrior( CHeadquarter * p,int nNo_) {
nNo = nNo_;
pHeadquarter = p;
for(int i=0;i<4;i++){
wp[i]=NULL;
}
}
void CWarrior::PrintResult(int nTime,int nKindNo)
{
char szColor[20];
pHeadquarter->GetColor(szColor);
int hour=nTime/60,minute=nTime%60;
printf("%03d:%02d %s %s %d born\n" ,
hour, minute, szColor, Names[nKindNo], nNo);
}
void CHeadquarter::Init(int nColor_, int lv)
{
nColor = nColor_;
nTotalLifeValue = lv;
bStopped = false;
nCurMakingSeqIdx = 0;
nTotalWarriorNum = 0;
for( int i = 0;i < WARRIOR_NUM;i ++ )
anWarriorNum[i] = 0;
for(int i=0;i<MAX_WARRIORS;i++){
pWarriors[i]=NULL;
}
}
CHeadquarter::~CHeadquarter () {
int i;
for( i = 0;i < nTotalWarriorNum; i ++ )
if(pWarriors[i]!=NULL){
//delete pWarriors[i];
}
}
int CHeadquarter::Produce(int nTime)
{
int nKindNo = MakingSeq[nColor][nCurMakingSeqIdx];
if( CWarrior::InitialLifeValue[nKindNo] > nTotalLifeValue ) {
return 0;
}
nTotalLifeValue -= CWarrior::InitialLifeValue[nKindNo];
nCurMakingSeqIdx = ( nCurMakingSeqIdx + 1 ) % WARRIOR_NUM ;
int nTmp = anWarriorNum[nKindNo];
anWarriorNum[nKindNo] ++;
switch( nKindNo ) {
case DRAGON:
pWarriors[nTotalWarriorNum] = new CDragon( this,nTotalWarriorNum+1);
break;
case NINJA:
pWarriors[nTotalWarriorNum] = new CNinja( this,nTotalWarriorNum+1);
break;
case ICEMAN:
pWarriors[nTotalWarriorNum] = new CIceman( this,nTotalWarriorNum+1);
break;
case LION:
pWarriors[nTotalWarriorNum] = new CLion( this,nTotalWarriorNum+1);
break;
case WOLF:
pWarriors[nTotalWarriorNum] = new CWolf( this,nTotalWarriorNum+1);
break;
}
pWarriors[nTotalWarriorNum]->PrintResult(nTime);
nTotalWarriorNum ++;
return 1;
}
void CHeadquarter::GetColor( char * szColor)
{
if( nColor == 0)
strcpy(szColor,"red");
else
strcpy(szColor,"blue");
}
void ReportWeapon(int i, int _time,int color){
if(city[i][color]!=NULL){
city[i][color]->wReportWeapon(_time);
}
}
//CHANGE arrow(times_left),bomb(),sword(ATK)
//don't mention what you don't have
void CWarrior::wReportWeapon(int _time){
char szname[20];
pHeadquarter->GetColor(szname);
int hour=_time/60,minute=_time%60;
printf("%03d:%02d %s %s %d has ",hour,minute,szname,Names[getType()-1],nNo);
bool hasweap=false;
if(wp[2]!=0){
hasweap=true;
cout<<"arrow("<<wp[2]->nTimesLeft<<')';
}
if(wp[1]!=0){
if(hasweap==true) cout<<',';
cout<<"bomb";
hasweap=true;
}
if(wp[0]!=0){
if(hasweap==true) cout<<',';
cout<<"sword("<<wp[0]->ATK<<')';
hasweap=true;
}
if(hasweap==false) cout<<"no weapon";
cout<<endl;
}
const char * CWeapon::Names[WEAPON_NUM] = {"sword","bomb","arrow" };
const char * CWarrior::Names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" };
int CWarrior::InitialLifeValue [WARRIOR_NUM];
int CWarrior::Attack[WARRIOR_NUM];
int CHeadquarter::MakingSeq[2][WARRIOR_NUM] = { { 2,3,4,1,0 },{3,0,1,2,4} };
void printMarch(int i,int _time){
int hour=_time/60,minute=_time%60;
if(i==0&&city[0][1]!=NULL){
if((bluestop==true)||(bluereach==false)){
bluereach=true;
printf("%03d:%02d blue %s %d reached red headquarter with %d elements and force %d\n",hour,minute,city[0][1]->Names[city[0][1]->getType()-1],city[0][1]->nNo,city[0][1]->lifeValue,city[0][1]->attack);
}
if(warStopped==true&&bluestop==true)
printf("%03d:%02d red headquarter was taken\n",hour,minute);
}
else if(i==n+1&&city[n+1][0]!=NULL){
if((redstop==true)||(redreach==false)){
redreach=true;
printf("%03d:%02d red %s %d reached blue headquarter with %d elements and force %d\n",hour,minute,city[n+1][0]->Names[city[n+1][0]->getType()-1],city[n+1][0]->nNo,city[n+1][0]->lifeValue,city[n+1][0]->attack);
}
if(warStopped==true&&redstop==true)
printf("%03d:%02d blue headquarter was taken\n",hour,minute);
}
else{
for(int j=0;j<2;j++){
if(city[i][j]!=NULL){
char szcolor[20];
city[i][j]->pHeadquarter->GetColor(szcolor);
printf("%03d:%02d %s %s %d marched to city %d with %d elements and force %d\n",hour,minute,szcolor,city[i][j]->Names[city[i][j]->getType()-1],city[i][j]->nNo,i,city[i][j]->lifeValue,city[i][j]->attack);
}
}
}
}
void GrowLife(int i,int _time){
citylife[i]+=10;
}
void CheckTakeLife(int i,int _time){
int h=_time/60,m=_time%60;
if(city[i][0]!=NULL&&city[i][1]==NULL){
printf("%03d:%02d red %s %d earned %d elements for his headquarter\n",h,m,city[i][0]->Names[city[i][0]->getType()-1],city[i][0]->nNo,citylife[i]);
city[i][0]->pHeadquarter->changeLifeValue(citylife[i]);
citylife[i]=0;
}
if(city[i][0]==NULL&&city[i][1]!=NULL){
printf("%03d:%02d blue %s %d earned %d elements for his headquarter\n",h,m,city[i][1]->Names[city[i][1]->getType()-1],city[i][1]->nNo,citylife[i]);
city[i][1]->pHeadquarter->changeLifeValue(citylife[i]);
citylife[i]=0;
}
}
void useArrow(int i,int _time){
int h=_time/60,m=_time%60;
if(city[i][0]!=NULL&&city[i+1][1]!=NULL&&city[i][0]->wp[2]!=NULL){
city[i][0]->wp[2]->useWeapon(city[i][0],city[i+1][1]);
printf("%03d:%02d red %s %d shot",h,m,city[i][0]->Names[city[i][0]->getType()-1],city[i][0]->nNo);
if(city[i+1][1]->lifeValue<=0){
printf(" and killed blue %s %d",city[i+1][1]->Names[city[i+1][1]->getType()-1],city[i+1][1]->nNo);
}
printf("\n");
}
if(city[i][1]!=NULL&&city[i-1][0]!=NULL&&city[i][1]->wp[2]!=NULL){
city[i][1]->wp[2]->useWeapon(city[i][1],city[i-1][0]);
printf("%03d:%02d blue %s %d shot",h,m,city[i][1]->Names[city[i][1]->getType()-1],city[i][1]->nNo);
if(city[i-1][0]->lifeValue<=0){
printf(" and killed red %s %d",city[i-1][0]->Names[city[i-1][0]->getType()-1],city[i-1][0]->nNo);
}
printf("\n");
}
}
void clearbodies(int i){
if(city[i][0]!=NULL&&city[i][0]->lifeValue<=0){
city[i][0]->pHeadquarter->loseWarrior(city[i][0]);
city[i][0]=NULL;
}
if(city[i][1]!=NULL&&city[i][1]->lifeValue<=0){
city[i][1]->pHeadquarter->loseWarrior(city[i][1]);
city[i][1]=NULL;
}
}
void useBomb(int i,int _time){
if(city[i][0]!=NULL&&city[i][1]!=NULL&&city[i][0]->lifeValue>0&&city[i][1]->lifeValue>0&&(city[i][0]->wp[1]!=NULL||city[i][1]->wp[1]!=NULL)){
int first,second;
int h=_time/60,m=_time%60;
if(cityflag[i]==1){
second=1;
}
else if(cityflag[i]==-1){
second=0;
}
else{
second=i%2;
}
first=1-second;
int life1=city[i][first]->lifeValue,life2=city[i][second]->lifeValue;
life2-=(city[i][first]->attack);
if(city[i][first]->wp[0]!=NULL){
life2-=(city[i][first]->wp[0]->ATK);
}
if(life2>0&&city[i][second]->getType()!=2){
life1-=((city[i][second]->attack)/2);
if(city[i][second]->wp[0]!=NULL){
life1-=(city[i][second]->wp[0]->ATK);
}
}
int lifer,lifeb;
if(first==0){
lifer=life1;
lifeb=life2;
}
else{
lifer=life2;
lifeb=life1;
}
if(lifer<=0&&city[i][0]->wp[1]!=NULL){
city[i][0]->wp[1]->useWeapon(city[i][0],city[i][1]);
printf("%03d:%02d red %s %d used a bomb and killed blue %s %d\n",h,m,city[i][0]->Names[city[i][0]->getType()-1],city[i][0]->nNo,city[i][1]->Names[city[i][1]->getType()-1],city[i][1]->nNo);
}
else if(lifeb<=0&&city[i][1]->wp[1]!=NULL){
city[i][1]->wp[1]->useWeapon(city[i][1],city[i][0]);
printf("%03d:%02d blue %s %d used a bomb and killed red %s %d\n",h,m,city[i][1]->Names[city[i][1]->getType()-1],city[i][1]->nNo,city[i][0]->Names[city[i][0]->getType()-1],city[i][0]->nNo);
}
}
}
//?WHAT IF THERE'S NO SWORD->still fights
//√IF KILLS, HQ gives out 8 in reward. warrior further has priority
//√IF KILLS, HQ takes all life in city. print this
//√if there were two kill from the same color, no ties in between(shoots don't count),
//√Flag it! Consider another array for each city to store flag status
//√Consider a 1_dim array for latest kill/tie record
//√ONLY wolves get weapons when kill
//√print flag rises
void nFight(int i, int _time){
cityrecord[i][1]=0;
int first,second;
int h=_time/60,m=_time%60;
int rlife=0,blife=0;
bool notbothshot=false;
if(cityflag[i]==1){
second=1;
}
else if(cityflag[i]==-1){
second=0;
}
else{
second=i%2;
}
first=1-second;
if(city[i][0]!=NULL&&city[i][1]!=NULL&&city[i][0]->lifeValue>0&&city[i][1]->lifeValue>0){
notbothshot=true;
rlife=city[i][0]->lifeValue,blife=city[i][1]->lifeValue;
char szcolor1[20],szcolor2[20];
city[i][first]->pHeadquarter->GetColor(szcolor1);
city[i][second]->pHeadquarter->GetColor(szcolor2);
city[i][second]->lifeValue-=(city[i][first]->attack);
if(city[i][first]->wp[0]!=NULL){
city[i][first]->wp[0]->useWeapon(city[i][first],city[i][second]);
}
printf("%03d:%02d %s %s %d attacked %s %s %d in city %d with %d elements and force %d\n",h,m,szcolor1,city[i][first]->Names[city[i][first]->getType()-1],city[i][first]->nNo,szcolor2,city[i][second]->Names[city[i][second]->getType()-1],city[i][second]->nNo,i,city[i][first]->lifeValue,city[i][first]->attack);
if(city[i][second]->lifeValue>0&&city[i][second]->getType()!=2){
city[i][first]->lifeValue-=((city[i][second]->attack)/2);
if(city[i][second]->wp[0]!=NULL){
city[i][second]->wp[0]->useWeapon(city[i][second],city[i][first]);
}
printf("%03d:%02d %s %s %d fought back against %s %s %d in city %d\n",h,m,szcolor2,city[i][second]->Names[city[i][second]->getType()-1],city[i][second]->nNo,szcolor1,city[i][first]->Names[city[i][first]->getType()-1],city[i][first]->nNo,i);
}
else if(city[i][second]->lifeValue<=0){
printf("%03d:%02d %s %s %d was killed in city %d\n",h,m,szcolor2,city[i][second]->Names[city[i][second]->getType()-1],city[i][second]->nNo,i);
}
if(city[i][first]->lifeValue<=0){
printf("%03d:%02d %s %s %d was killed in city %d\n",h,m,szcolor1,city[i][first]->Names[city[i][first]->getType()-1],city[i][first]->nNo,i);
}
}
if(city[i][0]!=NULL&&city[i][1]!=NULL){
CWarrior* rwarrior=city[i][0];
CWarrior* bwarrior=city[i][1];
//add condition: dragon initiated it & morale>0.8
if(rwarrior->lifeValue>0&&rwarrior->getType()==1){
if(bwarrior->lifeValue<=0)
rwarrior->boostmorale();
else if(bwarrior->lifeValue>0)
rwarrior->ggmorale();
if(first==0&&rwarrior->fmorale>0.8){
printf("%03d:%02d red dragon %d yelled in city %d\n",h,m,rwarrior->nNo,i);
}
}
if(bwarrior->lifeValue>0&&bwarrior->getType()==1){
if(rwarrior->lifeValue<=0)
bwarrior->boostmorale();
else if(rwarrior->lifeValue>0)
bwarrior->ggmorale();
if(first==1&&bwarrior->fmorale>0.8)
printf("%03d:%02d blue dragon %d yelled in city %d\n",h,m,bwarrior->nNo,i);
}
if(rwarrior->lifeValue>0&&bwarrior->lifeValue<=0){
if(bwarrior->getType()==4){
rwarrior->lifeValue+=blife;
}
if(rwarrior->getType()==5){
rwarrior->rob(bwarrior);
}
printf("%03d:%02d red %s %d earned %d elements for his headquarter\n",h,m,rwarrior->Names[rwarrior->getType()-1],rwarrior->nNo,citylife[i]);
if(cityrecord[i][0]==1){
if(cityflag[i]!=1){
printf("%03d:%02d red flag raised in city %d\n",h,m,i);
}
cityflag[i]=1;
}
cityrecord[i][0]=1;
cityrecord[i][1]=1;
}
else if(rwarrior->lifeValue<=0&&bwarrior->lifeValue>0){
if(rwarrior->getType()==4){
bwarrior->lifeValue+=rlife;
}
if(bwarrior->getType()==5){
bwarrior->rob(rwarrior);
}
printf("%03d:%02d blue %s %d earned %d elements for his headquarter\n",h,m,bwarrior->Names[bwarrior->getType()-1],bwarrior->nNo,citylife[i]);
if(cityrecord[i][0]==-1){
if(cityflag[i]!=-1){
printf("%03d:%02d blue flag raised in city %d\n",h,m,i);
}
cityflag[i]=-1;
}
cityrecord[i][1]=-1;
cityrecord[i][0]=-1;
}
else if(rwarrior->lifeValue>0&&bwarrior->lifeValue>0){
if(rwarrior->getType()==4){
rwarrior->nLoyalty-=k;
}
if(bwarrior->getType()==4){
bwarrior->nLoyalty-=k;
}
cityrecord[i][1]=0;
cityrecord[i][0]=0;
}
else if(rwarrior->lifeValue<=0&&bwarrior->lifeValue<=0&¬bothshot==true){
cityrecord[i][0]=0;
cityrecord[i][1]=0;
}
}
}
int main()
{
int t;
int m;//totalLifeValue for each headquarter
int T;//T minutes
CHeadquarter RedHead,BlueHead;
scanf("%d",&t);
int nCaseNo = 1;
while ( t -- ) {
warStopped=false;
redreach=false;
redstop=false;
bluereach=false;
bluestop=false;
for(int i=0;i<25;i++){
city[i][0]=NULL;
city[i][1]=NULL;
cityflag[i]=0;
cityrecord[i][0]=0;
cityrecord[i][1]=0;
citylife[i]=0;
}
printf("Case %d:\n",nCaseNo++);
scanf("%d",&m);//totalLifeValue
cin>>n>>r>>k>>T;
int i;
for(i = 0;i < WARRIOR_NUM;i ++ )
scanf("%d", & CWarrior::InitialLifeValue[i]);
for(i = 0;i < WARRIOR_NUM;i ++ )
scanf("%d", & CWarrior::Attack[i]);
RedHead.Init(0,m);
BlueHead.Init(1,m);
int nTime = 0;
while( nTime<=T && warStopped==false) {
switch(nTime%60){
case 0:
//Produce warriors.
//√DIFF: waits till life values are enough
RedHead.Produce(nTime);
BlueHead.Produce(nTime);
break;
case 5:
RedHead.CheckRun(nTime);
BlueHead.CheckRun(nTime);
break;
case 10:
RedHead.March(0,nTime);
BlueHead.March(1,nTime);
for(int i=0;i<=n+1;i++){
printMarch(i,nTime);
}
break;
case 20:
for(int i=1;i<=n;i++){
GrowLife(i,nTime);
//√every city produces 10
//√make a new array!! each filled with lifevalues for them cities
}
break;
case 30:
for(int i=1;i<=n;i++){
CheckTakeLife(i,nTime);
//√if there's only one warrior in a city,all the lifevalues there moves to the warrior's headquarter
//√might consider making a method for headquarter to take lifevalues from cities
//?will headqs take from other places?
}
break;
case 35:
for(int i=1;i<=n;i++){
useArrow(i,nTime);
//warriors won't get benefits
//if die alone, doesn't count as fight
}
break;
case 38:
for(int i=1;i<=n;i++){
useBomb(i,nTime);
//predict the outcome die together
}
break;
case 40:
for(int i=1;i<=n;i++){
nFight(i,nTime);
}
for(int i=n;i>0;i--){
RedHead.reward(i);
}
for(int i=1;i<=n;i++){
BlueHead.reward(i);
}
for(int i=1;i<=n;i++){
BlueHead.harvest(i);
RedHead.harvest(i);
clearbodies(i);
}
break;
case 50:
RedHead.ReportLifeValue(nTime);
BlueHead.ReportLifeValue(nTime);
break;
case 55:
//√Different order: west->east red -> west->east blue
for(int i=0;i<=n+1;i++){
ReportWeapon(i,nTime,0);
}
for(int i=0;i<=n+1;i++){
ReportWeapon(i,nTime,1);
}
default:
break;
}
nTime +=1;
}
}
return 0;
}