红色警戒终极版

Description

在一局红色警戒游戏中,你代表的是英国势力,此时你迫切需要生产坦克来应对敌人的进攻,坦克分为灰熊坦克、幻影坦克、光棱坦克、天启坦克四种,价格分别为600、1000、1200、1750,生产时间分别为1、2、4、6单位时间,灰熊坦克为基础坦克无特殊属性,只有普通攻击、防御、血量三种属性,其余坦克除基础属性外,幻影坦克有变形属性,可幻化成为树木,光棱坦克有光棱攻击属性,不采用普通攻击属性,天启坦克有更强的防御能力。目前你手中共有m金币,坦克建造顺序为灰熊、幻影、光棱、天启作为循环,注意一个例子剩余金钱不够用于生产天启坦克,那么将开始下一循环,尝试生产灰熊,如果任何坦克都不能开始生产,立刻中断生产。

下面是不同坦克所具有的属性。每次攻击造成的伤害计算公式为:己方坦克攻击力减去敌方防御属性。坦克每次受到的伤害将从其血量中扣去,坦克受到某次伤害后血量小于等于0时,坦克被消灭。

其中幻影具有变形属性,它每次被击中后,同一回合内下次被攻击必定可以躲避而不受伤害(普通攻击、光棱攻击都可以躲避);光棱坦克攻击坦克使用光棱攻击属性,可以无视对方防御属性;天启具配备有更强的装甲,进行伤害计算时,还可以再减免掉即将所受20%的伤害。例如灰熊攻击天启,每次攻击将造成(30-20)×(1-0.2)=8点伤害。光棱攻击天启,无视天启防御值,但天启伤害减免仍有效,每次攻击将造成50×(1-0.2)= 40点伤害。

由于敌人的间谍在x单位时间后入侵了你的发电厂,你的坦克生产在x单位时间后将会停止生产,这时双方共同从基地派出坦克,向对方发起进攻。

会战的地点在一处狭窄峡谷,所以两方每次只能从基地派出一辆坦克进行作战,坦克派出顺序按照建造顺序,两方坦克从各自基地出发抵达峡谷都需要5个单位时间,到达峡谷在中间相遇时,开始这一回合的对战,双方将同时发起进攻互相攻击,双方坦克将同时受到伤害,坦克攻击完一次后,1个单位时间后再进行下一次攻击(例如灰熊对战灰熊,每次攻击将对敌方造成30-15=15点伤害,因此经过7个单位时间后,双方将同归于尽)。直到其中一方坦克爆炸被消灭或者双方坦克同归于尽,将结束这一回合的对战。本回合胜方坦克将返回基地进行修理,从峡谷中央返回基地也需要5个单位时间,(如果目前队伍只剩余最后这一辆坦克,将不再返回基地维修,停留在峡谷中央,原地等待对方坦克到达后,开始下一回合的对战)在胜方坦克掉头返回基地的同一时刻,双方军队的下一个坦克单位也开始从各自基地出发前往峡谷(也需5个单位时间),双方坦克都抵达峡谷中央后,下一回合的对战开始,以此持续下去,直到一方坦克数量为零,比赛结束。

下图为峡谷对战示意图。被击败报废的坦克将自动从战场上移除。

每回合对战胜利的坦克到达它的基地后将开始维修,维修速度是每单位时间回复4点生命值,回复到满血量或轮到该坦克再次出战离开基地时则立即停止维修,每辆回来维修的坦克都自动补到当前出战顺序的队尾,以备下次出战(基地可以同时维修多辆坦克,不设上限,坦克只要回到基地都可以进行维修)。如某回合双方对战坦克同归于尽,则没有坦克返回基地维修。

当你被敌方间谍入侵电厂的同时,你拥有的间谍也将出发渗入敌方的战车工厂,你能派出间谍类型可能有三种,3星间谍会乘坐直升机前往,将在5个单位时间后抵达敌方基地,2星间谍将乘车前往需要20个单位时间到达,1星间谍步行前往需要40个单位时间到达。当间谍抵达敌方基地后,还需要再经过0.5个单位时间破获敌方的战车工厂的坦克制造细节并发送回资料,此时你的所有仍在基地的坦克将会提高一个星级(注意,已经出发在路上或在返回途中而不在基地的坦克不会升星,而已经返回到基地维修的坦克会升星),升星的坦克攻击、防御值将提高5点。

Input

输入为:你拥有的金币值,敌方坦克及派出顺序,敌方间谍入侵你电厂的时间,你拥有的间谍的星级。

在输入、输出敌方坦克名称或者己方坦克名称时,用Bear代表灰熊,Phantom代表幻影,Prism代表光棱,Apocalypse代表天启,当坦克升星后,统一在名称后添加一个*

Output

你需要输出的是:当坦克停止生产时(不止一种情况),你需要输出此时时间,停止生产的原因(如果同时发生则都输出,见样例一)和你坦克的派出顺序(例:Money is empty或 Invaded by enemy spies and production stalled, Bear Phantom.)。当被敌方间谍入侵,需要输出此时间。当每回合对战开始时,你要输出当前时间和对战双方坦克类型,每回合对战决出胜负后,你要输出当前时间和战斗结果(You won the encounter! You lost the encounter!Deadlock!)和在基地里将要派出的坦克顺序(如基地中没有坦克能再派出,则不输出),当你的间谍成功渗入敌方战车工厂窃取到资料时,你需要按派出顺序输出此时有哪些坦克升星(例如,Spy successfullysteal enemy tank technology, Phantom Prism Bear will be upgraded!如果基地中没有坦克可以升星,则只输出Spy successfullysteal enemy tank technology.)。当对方或者我方坦克数量为零时,战争结束,你需要输出战争结果(You won the war! You lost the war!It ended in a draw!)。

Sample Input 1 

2500 Bear Bear Phantom 4 3

Sample Output 1

Time:4 Money is empty, Invaded by enemy spies and production stalled, Bear Phantom Bear.
Time:9 Round 1 Start, Bear vs Bear.
Time:9.5 Spy successfully steal enemy tank technology, Phantom Bear will be upgraded!
Time:16 Round 1 End, Deadlock! Phantom* Bear*.
Time:21 Round 2 Start, Phantom* vs Bear.
Time:25 Round 2 End, You won the encounter! Bear*.
Time:30 Round 3 Start, Bear* vs Phantom.
Time:35 Round 3 End, You lost the encounter! Phantom*.
Time:40 Round 4 Start, Phantom* vs Phantom.
Time:43 Round 4 End, You won the encounter! You won the war!

Sample Input 2 

0 Bear Bear Phantom 5 3

Sample Output 2

Time:0 You lost the war!

Sample Input 3 

1600 Bear Phantom 5 1

Sample Output 3

Time:3 Money is empty and production stalled, Bear Phantom.
Time:5 Invaded by enemy spies.
Time:10 Round 1 Start, Bear vs Bear.
Time:17 Round 1 End, Deadlock! Phantom.
Time:22 Round 2 Start, Phantom vs Phantom.
Time:29 Round 2 End, Deadlock! It ended in a draw!

Sample Input 4 

3500 Bear Phantom Phantom Bear 10 3

Sample Output 4

Time:8 Money is empty and production stalled, Bear Phantom Prism Bear.
Time:10 Invaded by enemy spies.
Time:15 Round 1 Start, Bear vs Bear.
Time:15.5 Spy successfully steal enemy tank technology, Phantom Prism Bear will be upgraded!
Time:22 Round 1 End, Deadlock! Phantom* Prism* Bear*.
Time:27 Round 2 Start, Phantom* vs Phantom.
Time:34 Round 2 End, You won the encounter! Prism* Bear*.
Time:39 Round 3 Start, Prism* vs Phantom.
Time:42 Round 3 End, You won the encounter! Bear* Phantom*.
Time:47 Round 4 Start, Bear* vs Bear.
Time:52 Round 4 End, You won the encounter! Phantom* Prism*. You won the war!

Hint

样例一的具体时间点分析:

Time 1 完成灰熊生产。

Time 3 完成幻影生产。

Time 4 完成灰熊生产,同时钱不足,被敌方间谍入侵停止生产,我方拥有灰熊、幻影、灰熊(为派出顺序)三辆坦克。同时第一辆坦克灰熊从基地派出前往峡谷,我方三星间谍派出前往敌方基地。敌方灰熊也从敌方基地出发前往峡谷。

Time 9 我方灰熊与敌方灰熊都抵达峡谷(5个单位时间路程),开始第一回合对战。我方三星间谍同时抵达敌方基地。

Time 9.5 间谍破获敌方坦克细节,在我军基地的幻影,灰熊完成升星。

Time 16 第一回合双方同归于尽(战斗经过7个单位时间,每单位时间互相造成30-15=15点伤害),同时我方一星幻影坦克出发前往峡谷。敌方灰熊也从基地出发前往峡谷。

Time 21 我方一星幻影与敌方灰熊抵达峡谷,开始第二回合对战。

Time 25 第二回合结束,我方一星幻影击败敌方灰熊(一星幻影每次攻击造成45-15=30伤害,4个单位时间击败灰熊,同时灰熊对一星幻影造成10+0+10+0=20点伤害,一星幻影还剩80生命值),一星幻影此时将从峡谷返回基地维修,我方一星灰熊从基地出发前往峡谷。敌方幻影也出发。

Time 30 我方一星灰熊与敌方幻影抵达峡谷,开始第三回合对战。同时我方一星幻影抵达基地,开始维修。

Time 35 第三回合结束,我方一星灰熊被敌方幻影击败(一星灰熊对敌方幻影造成20+0+20+0+20=60伤害),我方一星幻影将立刻结束维修,从基地出发前往峡谷(一星幻影在基地维修了5个单位时间,总共回复5×4=20点生命值,一星幻影目前状态为80+20=100生命值),敌方幻影仅剩自己一辆坦克,无法返回基地维修(只剩40生命值),留在峡谷等待,继续战斗。

Time 40 我方一星幻影抵达峡谷,开始第四回合对战。

Time 43 第四回合结束,我方一星幻影击败地方幻影(敌方幻影只剩40生命值,我方一星幻影对敌方造成30+0+30=60伤害,三个单位时间消灭地方幻影),敌方全军覆没,我军胜利

我一开始写了很久答案一直不对,总是有各种小错误,在用了学长的正确代码进行答案对比后,终于找出了所有的错误,给大家借鉴借鉴

答案:

#include <iostream>
#include <string>
#include<list>
#include<sstream>
using namespace std;
class tank
{
private:
	int maxlife = 0;//生命值上限
	int attack=0;//攻击力,光凌的光凌攻击也算在这里
	int defense=0;//防御
	int life=0;//生命值
	string name;//名字
	bool transform = false;//是否变形
	string plus;//升级的后缀
public:
	void renew()
	{
		transform = false;
	}//回合取消变形
	void attacked(int x,string attacker)
	{
		if (name == "Bear")life -= x-defense;
		if (name == "Phantom")
		{
			if (transform)
			{
				transform = false; return;
			}
			else {
				transform = true;
				life -= x-defense;
			}
		}
		if (name == "Prism")life -= x-defense;
		if (name == "Apocalypse")
		{
			if (attacker == "Prism")
			{
				life -= x  * 8 / 10;
				return;
			}
			else
			{
				life -= (x - defense) * 8 / 10;
				return;
			}
		}
		if (attacker == "Prism")life -= defense;
	}//被攻击,输入值为攻击力以及攻击者名字用来判断如何扣血
	int attackk()
	{
		return attack;
	}//返回攻击力
	tank(int a, int b, int c, string d)
	{
		maxlife = c;
		attack = a;
		defense = b;
		life = c;
		name = d;
	}//坦克的构造函数
	bool alive()
	{
		if (life <= 0)return false;
		else return true;
	}//坦克是否还活着
	string nam()
	{
		return name;
	}//读取名字
	string andplus()
	{
		return plus;
	}//加上升星后缀
	void cure()
	{
		if (life < maxlife)
		{
			life += 4;
		}
		if (life >= maxlife)
		{
			life = maxlife;
		}
	}//每个单位时间回4点血
	void addplus()
	{
		plus = "*";
		attack += 5;
		defense += 5;
	}//可以升星了
};

class center {
	int money=0;//总经济
	list<tank> fighter;
	int time = 0;//计算制造时间,后面输出到主函数中
	int invaded = 0;//预计被侵入时间
	int star = 0;//间谍星级
	int plustime = 0;//预计间谍进入地方大本营时间
public:
	int thept()
	{
		return plustime;
	}//输出预计间谍进入敌方大本营时间
	int thestar()
	{
		return star;
	}//输出星级
	void addplus()
	{
		list<tank>::iterator p = fighter.begin();
		for (; p != fighter.end(); p++)
		{
			p->addplus();
		}
	}//所有在基地内的都升级
	void cure()
	{
		list<tank>::iterator p = fighter.begin();
		for (; p != fighter.end(); p++)
		{
			p->cure();
		}
	}//所有在基地内的都治疗4点血
	void outcount1()
	{
		outcount2();
		if (fighter.size() != 0)
		{
			cout << '.';
		}
	}//可作为结尾,输出基地内所有坦克
	void outcount2()
	{
		list<tank>::iterator p = fighter.begin();
		for (int x = 0; x < fighter.size(); x++, p++)
		{
			cout << " ";
			cout << p->nam() << p->andplus();
		}
	}//输出基地内所有坦克
	void add(tank &a)
	{
		fighter.push_back(a);
	}//插到队尾
	tank fight()
	{
			tank temper = *fighter.begin();
			fighter.pop_front();
			return temper;
	}//坦克出发
	int outtime()
	{
		return time;
	}//将初步计算后的时间输出
	bool exist()
	{
		return (fighter.size() > 0);
	}//基地内还有坦克吗
	void create()
	{
		int turn = 1;
		while(money>=600&&(invaded-time)>=1)
		{ 
			if (turn == 1)
			{
				if (money >= 600)
				{
					fighter.push_back(tank(30, 15, 100, "Bear"));
					money -= 600;
					turn++;
					time += 1;
					continue;
				}
				else return;
			}
			if (turn == 2)
			{
				if (money >= 1000)
				{
					if ((invaded - time) < 2)
					{
						return;
					}
					fighter.push_back(tank(40, 15, 100, "Phantom"));
					money -= 1000;
					turn++;
					time += 2;
					continue;
				}
			    else { turn = 1; continue; }
			}
			if (turn == 3)
			{
				if (money >= 1200)
				{
					if ((invaded - time) < 4)
					{
						return;
					}
					fighter.push_back(tank(50, 10, 100, "Prism"));
					money -= 1200;
					turn++;
					time += 4;
					continue;
				}
				else { turn = 1; continue; }
			}
			if (turn == 4)
			{
				if (money >= 1750)
				{
					if ((invaded - time) < 6)
					{
						return;
					}
					fighter.push_back(tank(60, 20, 120, "Apocalypse"));
					money -= 1750;
					turn = 1;
					time += 6;
					continue;
				}
				else { turn = 1; continue; }
			}
		}
	}//开始制造,造不下去直接停止
	center(int x,int c,int s) 
	{
		star = s;
		if (star == 3)
		{
			plustime = c + 5;
		}
		else if (star == 2)
		{
			plustime = c + 20;
		}
		else if (star == 1)
		{
			plustime = c + 40;
		}
		invaded = c;
		money = x;
		if (money >= 600)
		{
			create();
		}
		else return;
		if (money >= 600)
		{
			if (time <= invaded)
			{
				time = invaded;
				cout << "Time:" << time << " Invaded by enemy spies ";
			}
		}
		if (money < 600)
		{
			if (time < invaded)
			{
				cout << "Time:" << time << " Money is empty ";
			}
			if (time ==invaded)
			{
				cout << "Time:" << time << " Money is empty, Invaded by enemy spies ";
			}
		}
		cout << "and production stalled,";
		list<tank>::iterator p = fighter.begin();
		for (;p!=fighter.end();p++)
		{
			cout << ' ' << p->nam();
		}
		cout<<'.' << endl;
		if (money < 600)
		{
			if (time < invaded)
			{
				time = invaded;
				cout << "Time:" << time;
				cout << " Invaded by enemy spies." << endl;
				return;
			}
		}
		time = invaded;
	}//确定定义的一系列数值,包括对先没钱还是先被侵入的判断
};

class enemy
{
	list<tank> fighter;
public:
	void cure()
	{
		list<tank>::iterator p = fighter.begin();
		for (; p != fighter.end(); p++)
		{
			p->cure();
		}
	}
	void add(tank& a)
	{
		fighter.push_back(a);
	}
	tank fight()
	{
			tank temper = *fighter.begin();
			fighter.pop_front();
			return temper;
	}
	bool exist()
	{
		return (fighter.size() > 0);
	}
	void in(string x)
	{
		if (x == "Bear")
		{
			fighter.push_back(tank(30, 15, 100, "Bear"));
		}
		if (x == "Phantom")
		{
			fighter.push_back(tank(40, 15, 100, "Phantom"));
		}
		if (x == "Prism")
		{
			fighter.push_back(tank(50, 10, 100, "Prism"));
		}
		if (x == "Apocalypse")
		{
			fighter.push_back(tank(60, 20, 120, "Apocalypse"));
		}
	}
};//地方大本营,基本所有内容与center对应

void outime(double x)
{
	cout << "Time:" << x << " ";
}//输出时间

void instarwithoutendl(center& my, int time)
{
	if (my.thept() == time)
	{
		outime(time * 1.0 + 0.5);
		cout << "Spy successfully steal enemy tank technology";
		if (my.exist())
		{
			cout << ',';
			my.outcount2();
			cout << " will be upgraded!" << endl;
			my.addplus();
		}
		else
		{
			cout << '.' << endl;
		}
	}
}//一个不包含回车的升星

void instarwithendl(center& my, int time)
{
	if (my.thept() == time)
	{
		cout << endl;
		outime(time * 1.0 + 0.5);
		cout << "Spy successfully steal enemy tank technology";
		if (my.exist())
		{
			cout << ',';
			my.outcount2();
			cout << " will be upgraded!";
			my.addplus();
		}
		else
		{
			cout << '.';
		}
	}
}
//一个不包含回车的升星(回车问题确实是难题)
void service(center &my, enemy&enemy,int &time)
{
	for (int i = 0; i < 5; i++)
	{
		my.cure();
		enemy.cure();
		time++;
		if (i != 4)instarwithendl(my, time);
	}
}//不断回血五次,用于在路上的时间

bool afterfight(center& my, enemy& enemy, int& time, int& round,tank& mytank,tank&youtank)
{
	if (mytank.alive())//己方胜利了吗
	{
		if (enemy.exist())//敌方还有吗
		{
			outime(time);
			cout << "Round " << round << " End, You won the encounter!";
			my.outcount1();
			if (my.exist())//己方还有吗
			{
				tank temp = mytank;
				mytank = my.fight(); youtank = enemy.fight();//都有就都派出新坦克
				instarwithendl(my, time);
				service(my, enemy, time);
				my.add(temp);//旧坦克最后时刻才到
			}
			else
			{
				youtank = enemy.fight();//己方没有只有对方派出
				instarwithendl(my, time);
				service(my, enemy, time);
			}
		}
		else
		{
			outime(time);
			cout << "Round " << round << " End, You won the encounter!";
			my.outcount1();
			cout << " You won the war!" << endl;;
			return true;
		}//敌方没坦克了我直接获胜
	}
	else
		if (youtank.alive())//对面赢了?
		{
			if (my.exist())//我还有吗
			{
				outime(time);
				cout << "Round " << round << " End, You lost the encounter!";
				my.outcount1();
				if (enemy.exist())
				{
					tank temp = youtank;
					mytank = my.fight(); youtank = enemy.fight();//双方都有坦克就都派出新的
					instarwithendl(my, time);
					service(my, enemy, time);
					enemy.add(temp);
				}
				else
				{
					mytank = my.fight();
					instarwithendl(my, time);
					service(my, enemy, time);
				}
			}
			else//己方没有坦克了直接失败
			{
				outime(time);
				cout << "Round " << round << " End, You lost the encounter!";
				my.outcount1();
				cout << " You lost the war!" << endl;;
				return true;
			}
		}
		else//同归于尽了
		{
			if (my.exist())
			{
				if (enemy.exist())
				{
					outime(time);
					cout << "Round " << round << " End, Deadlock!";
					my.outcount1();
					mytank = my.fight(); youtank = enemy.fight();//大家都有就派出新的
					instarwithendl(my, time);
					service(my, enemy, time);
				}
				else {
					outime(time);
					cout << "Round " << round << " End, Deadlock!";
					my.outcount1();
					cout << " You won the war!" << endl;;
					return true;
				}//我有对面没有直接获胜
			}
			else if (enemy.exist())//对面有我没有直接失败
			{
				outime(time);
				cout << "Round " << round << " End, Deadlock!";
				my.outcount1();
				cout << " You lose the war!" << endl; ;
				return true;
			}
			else {
				outime(time);
				cout << "Round " << round << " End, Deadlock!";
				my.outcount1();
				cout << " It ended in a draw!" << endl;;
				return true;
			}//大家都没了算平局
		}
	return false;
}//一个回合打完了判断一下战况,返回true战斗结束,在主函数中直接结束所有进程

int main()
{
	int n;//钱
	string a;//坦克名称
	int ctime=0;//侵入时间
	int star;//间谍星级
	cin >> n;
	enemy enemy;//敌方大本营
	while (cin >> a)
	{
		if (a == "Bear" || a == "Phantom" || a == "Prism" || a == "Apocalypse")enemy.in(a);
		else
		{
			istringstream is(a);//网上找的一个算法,把string转化为int
			is >> ctime;
			break;
		}
	}
	cin >> star;
	center my(n,ctime,star);//己方大本营
	int round = 1;//这是第几个回合?
	int time = my.outtime();//导出初步时间
	if (my.exist()) {}
	else
	{
		outime(time);
		cout << "You lost the war!" << endl;
		return 0;
	}//什么都没造出来直接认输
	time += 5;
	tank mytank = my.fight(), youtank = enemy.fight();//这两步没有写在while里,是将while完全认为是回合开始后的操作,也方便后续一些数值的处理(很大占比是本人水平受限)
	while (1)
	{
		outime(time);
		cout << "Round " << round << " Start, ";
		cout << mytank.nam() <<mytank.andplus()<< " vs " << youtank.nam()<<youtank.andplus()<< '.' << endl;//开始了
		instarwithoutendl(my, time);//升星的时间比较特殊,安排在每一个整数时间输出后,避免出现时间错误
		if (mytank.nam() == "Phantom")mytank.renew();
		if (youtank.nam() == "Phantom")youtank.renew();//phantom的变形在一个新的回合中不算数
		while (mytank.alive() && youtank.alive())//干起来
		{
			mytank.attacked(youtank.attackk(), youtank.nam());
			youtank.attacked(mytank.attackk(), mytank.nam());
			my.cure(); enemy.cure();
			time++;
			if (mytank.alive() && youtank.alive())instarwithoutendl(my, time);//新时间变化后查看是否到升星时间,同时最后一个回合打完后不输出,以免出现时间倒挂
		}
		bool judge=afterfight(my, enemy, time, round, mytank, youtank);
		if (judge)return 0;//战斗结束了直接return0;
		cout << endl;
		round++;//进入下一个回合
	}
	return 0;
}

其实可以更简洁,但是我也懒得在写一遍了,对于一个初学者来说不错了。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐