魔兽世界 大模拟 思路+代码 [山东大学 高级程序设计]
先来看看问题描述(要不还是别看了)
描述
魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为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分开始到此时间为止的所有事件按顺序输出。事件及其对应的输出样例如下:
武士降生
输出样例:000:00 blue dragon 1 born
表示在0点0分,编号为1的蓝魔dragon武士降生
如果造出的是lion,那么还要多输出一行,例:
000:00 blue lion 1 born
Its loyalty is 24
表示该lion降生时的忠诚度是24lion逃跑
输出样例:000:05 blue lion 1 ran away
表示在0点5分,编号为1的蓝魔lion武士逃走武士前进到某一城市
输出样例:
000:10 red iceman 1 marched to city 1 with 20 elements and force 30
表示在0点10分,红魔1号武士iceman前进到1号城市,此时他生命值为20,攻击力为30
对于iceman,输出的生命值应该是变化后的数值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。为简单起见,武器不写复数形式报告战斗情况
战斗只有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
注意,把红武士写前面武士欢呼
输出样例:003:40 blue dragon 2 yelled in city 4武士抵达敌军司令部
输出样例:001:10 red iceman 1 reached blue headquarter with 20 elements and force 30
(此时他生命值为20,攻击力为30)对于iceman,输出的生命值和攻击力应该是变化后的数值司令部被占领
输出样例:003:10 blue headquarter was taken司令部报告生命元数量
000:50 100 elements in red headquarter
000:50 120 elements in blue headquarter
表示在0点50分,红方司令部有100个生命元,蓝方有120个武士报告情况
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。
思路
什么?想让我写面向对象是吧?对不起,做不到。
一开始想的是,司令部抽象成一个类,武士抽象统合成一个类,武器抽象统合成一个类。但是时间有限(指一直摆烂没开始写),能力更有限,于是一开始写的类比类本身还抽象,然后到后面才发现输出的顺序是同一时间下从西向东,这样直接就推翻了一开始把一些事件绑定到两个司令部的做法,然后就一不做二不休,把成员函数全拆了(除了武士降生),扔到外面,嫌麻烦就直接把类的成员变量公开,允许外部调用,然后就把类的作用被降到了可有可无的地步(毫无存在意义)。
司令部内最少应该有的量为:生命元、武士总数、武士类的对象、记录每个城市中有哪个己方武士的数组、降生顺序、
此外,我把司令部的名字(方便调用输出)、武士生产花费、lion的忠诚度衰减值、武士攻击力也加到了司令部类中(没有绑定的必要,但是方便析构时清零)。
武士类内应该有的量为:武士种类、生命值、攻击力、位置、忠诚度、武器类的对象。
武器类内应该有的量为:记录每个武器可用次数的数组(或者只记arrow类型的武器)、每种武器数量、武器总数。
将武士名字和武器名字定义为全局变量,方便调用。
武器的获得、失去、抢夺、排序、使用都可以放到武器类中(但是我写的太麻烦了,统合一下比较好)。
缴械与wolf的抢武器有重叠部分,同一时空的事件顺序先红后蓝也会导致许多的复制粘贴,有不少地方可以独立出来写的再简略一些,但是因为时间原因(我懒得改)就直接复制粘贴带过了。
从每个事件开始捋一下:
-
武士降生:
可以作为司令部的成员函数,因为是为司令部生产新武士。赋好初值并注意好每种武士的不同之处即可。 -
lion逃跑:
自律的lion连逃跑都要统一时间按位置扫一遍,有忠诚度掉没了的狮子就输出一下并删了它。 -
武士前进:
先分别让两方的武士前进一格,再按规定顺序输出,注意有武士到达敌方司令部的时候的输出顺序(踩坑1)即可,另外还要注意iceman的自伤和lion的掉忠。(踩坑2) -
wolf抢敌人的武器:
按位置扫一遍,存在一个位置有一方的wolf和另一方的其它兵种且另一方的武士有武器的话,就让它抢,注意wolf只能抢一种武器,但不限数量(除非自己身上的武器满了)。 -
报告战斗情况:
还是按位置扫一遍,存在一个位置上有双方的武士时开打,需要注意武器使用次序(踩坑3)与胜负平手的判定(踩坑4),另外还要注意战斗出现胜负时的缴械(踩坑5)。输出时记得先红后蓝。 -
武士欢呼:
只有dragon会在战斗结束后存活的情况下进行一次欢呼。 -
武士抵达敌军司令部:
可以和和武士前进合在一起写,毕竟抵达事件发生时一定是武士前进时。 -
司令部被占领:
和7合在一起。 -
司令部报告生命元:
直接输出。 -
武士报告情况:
依然是按位置扫一遍,有武士的话就让它报告一下,注意先红后蓝。
代码
/****************************/
/**/ #define author QAS /**/
/****************************/
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAXN 101
using namespace std;
string Samurai_Name[6] = { "\0", "dragon", "ninja", "iceman", "lion", "wolf" }; //兵种名字
string Weapon_Name[3] = { "sword", "bomb", "arrow" }; //武器名字
int t, M, N, K, T, Hour, Minute, If_Win;
class Weapon { //武器类
public:
int wea[3][10] = {{0}, {0}, {0}}; //行为武器种类,列为该类每个武器,数值代表使用次数
int num[3] = {0}; //每种武器数量
int useable[3] = {-1, 1, 2}; //可用次数,-1代表无限次
int cnt = 0; //总数
void gain(int n) { wea[n][num[n]++] = useable[n]; cnt++; } //获取,加到后面
void seize(int n, int m) { wea[n][num[n]++] = m; cnt++; } //抢夺,针对wolf
void lose(int n) { wea[n][--num[n]] = 0; cnt--; } //失去,从后面
void use(int n); //使用,针对arrow
void Weapon_Sort(); //排序,使用次数少的在前,多的在后
};
void Weapon::use(int n) {
for(int i=0; i<10; i++) {
if(wea[n][i]) {
wea[n][i]--;
if(wea[n][i] == 0) cnt--, num[n]--;
break;
}
}
}
void Weapon::Weapon_Sort() { //武器排序
for(int i=0; i<3; i++)
for(int j=0; j<10; j++)
if(wea[i][j] == 0) wea[i][j] = 3;
for(int i=0; i<3; i++) sort(wea[i], wea[i]+10);
for(int i=0; i<3; i++)
for(int j=0; j<10; j++)
if(wea[i][j] == 3) wea[i][j] = 0;
}
class Samurai { //统一为武士类
public:
int Name = 0; //种类
int Strength = 0; //生命值
int Force = 0; //攻击
int Position = 0; //位置
int Loyalty = 0; //忠诚度(Lion)
Weapon weapon; //武器(Dragon1 iceman1 ninja2)
};
class HeadQuarter { //司令部类
public:
string HQName; //名字
int HP = 0; //总生命值
Samurai Member[MAXN]; //武士
int Total = 0; //总数
int Now = 0; //循环制造时记录位置用
int Queue[22]; //记录各点的士兵
int SamuraiCost[6]; //武士花费(初始生命值
int Lyt_Reduce; //忠诚度衰减值
int Sequence[6] = { 0, 3, 4, 5, 2, 1 }; //制造顺序
int Samurai_Force[6];
bool Produce(int n); //制造函数,n是位置
};
bool HeadQuarter::Produce(int n) { //生产士兵
int x = Sequence[Now%5+1]; //x记录当前为顺序表里哪个兵种
if(SamuraiCost[x] <= HP) { //HP大于当前兵种花费
HP -= SamuraiCost[x]; //减去HP
Member[Total].Name = x; //新武士的名字
Member[Total].Strength = SamuraiCost[x]; //新武士的生命值
Member[Total].Position = n; //位置
Queue[n] = Total; //记录哪个位置有什么士兵
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<HQName<<" "<<Samurai_Name[Member[Total].Name]<<" "<<Total+1<<" born\n";
switch (Member[Total].Name) {
case 1: { //dragon
Member[Total].Force = Samurai_Force[1];
Member[Total].weapon.gain((Total+1)%3);
break;
}
case 2: { //ninja
Member[Total].Force = Samurai_Force[2];
Member[Total].weapon.gain((Total+1)%3);
Member[Total].weapon.gain((Total+2)%3);
break;
}
case 3: { //iceman
Member[Total].Force = Samurai_Force[3];
Member[Total].weapon.gain((Total+1)%3);
break;
}
case 4: { //lion
Member[Total].Force = Samurai_Force[4];
Member[Total].weapon.gain((Total+1)%3);
Member[Total].Loyalty = HP;
cout<<"Its loyalty is "<<HP<<"\n";
break;
}
case 5: { //wolf
Member[Total].Force = Samurai_Force[5];
break;
}
}
Total++; Now++;
return false; //成功制造返回 0
}
return true; //制造失败返回 1
}
void Run(HeadQuarter &X, HeadQuarter &Y) { //lion逃跑
for(int i=0; i<=N+1; i++) {
if(X.Queue[i] != -1) {
if(Samurai_Name[X.Member[X.Queue[i]].Name] == "lion" && X.Member[X.Queue[i]].Loyalty <= 0) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<X.HQName<<" lion "<<X.Queue[i]+1<<" ran away\n";
X.Queue[i] = -1; //从位置上清除
}
}
if(Y.Queue[i] != -1) {
if(Samurai_Name[Y.Member[Y.Queue[i]].Name] == "lion" && Y.Member[Y.Queue[i]].Loyalty <= 0) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<Y.HQName<<" lion "<<Y.Queue[i]+1<<" ran away\n";
Y.Queue[i] = -1; //从位置上清除
}
}
}
}
bool Move(HeadQuarter &X, HeadQuarter &Y) { //前进
for(int i=N; i>=0; i--) {
if(X.Queue[i] != -1) {
X.Queue[i+1] = X.Queue[i];
X.Member[X.Queue[i]].Position++;
if(Samurai_Name[X.Member[X.Queue[i]].Name] == "iceman") X.Member[X.Queue[i]].Strength -= X.Member[X.Queue[i]].Strength/10;
//冰人自伤
if(Samurai_Name[X.Member[X.Queue[i]].Name] == "lion") X.Member[X.Queue[i]].Loyalty -= X.Lyt_Reduce;
//狮子掉忠
X.Queue[i] = -1;
}
}
for(int i=1; i<=N+1; i++) {
if(Y.Queue[i] != -1) {
Y.Queue[i-1] = Y.Queue[i];
Y.Member[Y.Queue[i]].Position--;
if(Samurai_Name[Y.Member[Y.Queue[i]].Name] == "iceman") Y.Member[Y.Queue[i]].Strength -= Y.Member[Y.Queue[i]].Strength/10;
if(Samurai_Name[Y.Member[Y.Queue[i]].Name] == "lion") Y.Member[Y.Queue[i]].Loyalty -= Y.Lyt_Reduce;
Y.Queue[i] = -1;
}
}
if(Y.Queue[0] != -1) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<Y.HQName<<" "<<Samurai_Name[Y.Member[Y.Queue[0]].Name]<<" "<<Y.Queue[0]+1<<" reached red headquarter with "
<<Y.Member[Y.Queue[0]].Strength<<" elements and force "<<Y.Member[Y.Queue[0]].Force<<"\n";
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" red headquarter was taken\n";
If_Win = 1;
}
for(int i=1; i<=N; i++) {
if(X.Queue[i] != -1) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<X.HQName<<" "<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1<<" marched to city "
<<X.Member[X.Queue[i]].Position<<" with "<<X.Member[X.Queue[i]].Strength<<" elements and force "<<X.Member[X.Queue[i]].Force<<"\n";
}
if(Y.Queue[i] != -1) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<Y.HQName<<" "<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" marched to city "
<<Y.Member[Y.Queue[i]].Position<<" with "<<Y.Member[Y.Queue[i]].Strength<<" elements and force "<<Y.Member[Y.Queue[i]].Force<<"\n";
}
}
if(X.Queue[N+1] != -1) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<X.HQName<<" "<<Samurai_Name[X.Member[X.Queue[N+1]].Name]<<" "<<X.Queue[N+1]+1<<" reached blue headquarter with "
<<X.Member[X.Queue[N+1]].Strength<<" elements and force "<<X.Member[X.Queue[N+1]].Force<<"\n";
If_Win = 1;
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" blue headquarter was taken\n";
}
if(If_Win) return true;
else return false;
}
void Report_S(HeadQuarter &X, HeadQuarter &Y) { //士兵报告
for(int i=0; i<=N+1; i++) {
if(X.Queue[i] != -1) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<X.HQName<<" "<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1<<" has "
<<X.Member[X.Queue[i]].weapon.num[0]<<" sword "<<X.Member[X.Queue[i]].weapon.num[1]<<" bomb "
<<X.Member[X.Queue[i]].weapon.num[2]<<" arrow and "<<X.Member[X.Queue[i]].Strength<<" elements\n";
}
if(Y.Queue[i] != -1) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<Y.HQName<<" "<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" has "
<<Y.Member[Y.Queue[i]].weapon.num[0]<<" sword "<<Y.Member[Y.Queue[i]].weapon.num[1]<<" bomb "
<<Y.Member[Y.Queue[i]].weapon.num[2]<<" arrow and "<<Y.Member[Y.Queue[i]].Strength<<" elements\n";
}
}
}
void Grab(Samurai &X, Samurai &Y, int &sum, int &sign, int &xlog) { //X拿走Y的武器,带走了sum件xlog
for(int j=0; j<3; j++) {
while(Y.weapon.num[j]) {
if(X.weapon.cnt == 10) break;
X.weapon.seize(j, Y.weapon.wea[j][Y.weapon.num[j]]);
//位于i位置的X的武士获得j类型的可用次数为在i位置的Y的武士的j类型的武器的最末一件武器的可用次数的武器
Y.weapon.lose(j);
//Y失去 j 类型的最末一件武器
sum++; sign=1; xlog=j;
}
if(sign) break;
}
X.weapon.Weapon_Sort();
Y.weapon.Weapon_Sort();
}
void Snatch(HeadQuarter &X, HeadQuarter &Y) { //wolf抢夺
for(int i=1; i<=N; i++) {
int sum = 0, sign = 0, xlog = 0; //sum记录抢走多少件,sign标记抢没抢走,xlog记录抢走什么
if(X.Queue[i]<0 || Y.Queue[i]<0) continue;
if(Samurai_Name[X.Member[X.Queue[i]].Name] == "wolf" && Samurai_Name[Y.Member[Y.Queue[i]].Name] != "wolf")
Grab(X.Member[X.Queue[i]], Y.Member[Y.Queue[i]], sum, sign, xlog);
if(sign) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<X.HQName<<" wolf "<<X.Queue[i]+1<<" took "<<sum<<" "<<Weapon_Name[xlog]<<" from "
<<Y.HQName<<" "<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" in city "<<i<<"\n";
}
sum=0, sign=0, xlog=0;
if(Samurai_Name[Y.Member[Y.Queue[i]].Name] == "wolf" && Samurai_Name[X.Member[X.Queue[i]].Name] != "wolf")
Grab(Y.Member[Y.Queue[i]], X.Member[X.Queue[i]], sum, sign, xlog);
if(sign) {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<Y.HQName<<" wolf "<<Y.Queue[i]+1<<" took "<<sum<<" "<<Weapon_Name[xlog]<<" from "
<<X.HQName<<" "<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1<<" in city "<<i<<"\n";
}
}
}
void Yelled(HeadQuarter &X, int i) { //dragon欢呼
if(Samurai_Name[X.Member[X.Queue[i]].Name] == "dragon") {
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<X.HQName<<" dragon "<<X.Queue[i]+1<<" yelled in city "<<i<<"\n";
}
}
void Atk(HeadQuarter &X, HeadQuarter &Y, int i, int &a, int &ua) { //攻击
if(X.Member[X.Queue[i]].weapon.cnt) {
while(ua == X.Member[X.Queue[i]].weapon.num[a] || X.Member[X.Queue[i]].weapon.num[a] == 0) {
ua=0; a=(a+1)%3;
}
if(a == 0 && ua<X.Member[X.Queue[i]].weapon.num[0]) {
ua++;
Y.Member[Y.Queue[i]].Strength -= (X.Member[X.Queue[i]].Force*2/10);
}
else if(a == 1 && ua<X.Member[X.Queue[i]].weapon.num[a]) {
ua++;
Y.Member[Y.Queue[i]].Strength -= (X.Member[X.Queue[i]].Force*4/10);
if(Samurai_Name[X.Member[X.Queue[i]].Name] != "ninja")
X.Member[X.Queue[i]].Strength -= (X.Member[X.Queue[i]].Force*4/20);
X.Member[X.Queue[i]].weapon.lose(1);
X.Member[X.Queue[i]].weapon.Weapon_Sort();
}
else if(a ==2 && ua<X.Member[X.Queue[i]].weapon.num[a]) {
ua++;
Y.Member[Y.Queue[i]].Strength -= (X.Member[X.Queue[i]].Force*3/10);
X.Member[X.Queue[i]].weapon.use(2);
X.Member[X.Queue[i]].weapon.Weapon_Sort();
}
}
if(Y.Member[Y.Queue[i]].Strength <= 0 && X.Member[X.Queue[i]].Strength >0) { //胜利
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<X.HQName<<" "<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1<<" killed "
<<Y.HQName<<" "<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" in city "
<<i<<" remaining "<<X.Member[X.Queue[i]].Strength<<" elements\n";
Yelled(X, i); //dragon欢呼
while(X.Member[X.Queue[i]].weapon.cnt<10 && Y.Member[Y.Queue[i]].weapon.cnt>0) {
int sum=0, sign=0, xlog=0;
Grab(X.Member[X.Queue[i]], Y.Member[Y.Queue[i]], sum, sign, xlog); //缴械
}
Y.Queue[i] = -1;
}
else if(Y.Member[Y.Queue[i]].Strength > 0 && X.Member[X.Queue[i]].Strength <=0) { //失败
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" ";
cout<<Y.HQName<<" "<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" killed "
<<X.HQName<<" "<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1<<" in city "
<<i<<" remaining "<<Y.Member[Y.Queue[i]].Strength<<" elements\n";
Yelled(Y, i); //dragon欢呼
while(Y.Member[Y.Queue[i]].weapon.cnt<10 && X.Member[X.Queue[i]].weapon.cnt>0) {
int sum=0, sign=0, xlog=0;
Grab(Y.Member[Y.Queue[i]], X.Member[X.Queue[i]], sum, sign, xlog);
}
X.Queue[i] = -1;
}
else if(X.Member[X.Queue[i]].Strength <= 0 && Y.Member[Y.Queue[i]].Strength <= 0) { //同归于尽
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" both red ";
if(X.HQName == "red") {
cout<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1<<" and blue "
<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" died in city "<<i<<"\n";
}
else {
cout<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" and blue "
<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1<<" died in city "<<i<<"\n";
}
X.Queue[i] = -1; Y.Queue[i] = -1;
}
}
void Fight(HeadQuarter &X, HeadQuarter &Y) { //交战
for(int i=1; i<=N; i++) {
if(X.Queue[i] != -1 && Y.Queue[i] != -1) {
int a=0, ua=0, b=0, ub=0;
if(i&1) { //奇数城市红先手
while(1) {
int X_pre = X.Member[X.Queue[i]].Strength;
int Y_pre = Y.Member[Y.Queue[i]].Strength;
Atk(X, Y, i, a, ua);
if(X.Queue[i] == -1 || Y.Queue[i]== -1) break;
Atk(Y, X, i, b, ub);
if(X.Member[X.Queue[i]].Strength == X_pre && Y.Member[Y.Queue[i]].Strength == Y_pre
&& X.Member[X.Queue[i]].weapon.num[1] == 0 && X.Member[X.Queue[i]].weapon.num[2] == 0
&& Y.Member[Y.Queue[i]].weapon.num[1] == 0 && Y.Member[Y.Queue[i]].weapon.num[2] == 0) { //平局
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" both ";
cout<<"red "<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1
<<" and blue "<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" were alive in city "<<i<<"\n";
Yelled(X, i); Yelled(Y, i);
break;
}
if(X.Queue[i] == -1 || Y.Queue[i]== -1) break;
}
}
else {
while(1) {
int X_pre = X.Member[X.Queue[i]].Strength;
int Y_pre = Y.Member[Y.Queue[i]].Strength;
Atk(Y, X, i, b, ub);
if(X.Queue[i] == -1 || Y.Queue[i]== -1) break;
Atk(X, Y, i, a, ua);
if(X.Member[X.Queue[i]].Strength == X_pre && Y.Member[Y.Queue[i]].Strength == Y_pre
&& X.Member[X.Queue[i]].weapon.num[1] == 0 && X.Member[X.Queue[i]].weapon.num[2] == 0
&& Y.Member[Y.Queue[i]].weapon.num[1] == 0 && Y.Member[Y.Queue[i]].weapon.num[2] == 0) { //平局
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" both ";
if(X.HQName == "red")
cout<<"red "<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1
<<" and blue "<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1<<" were alive in city "<<i<<"\n";
else
cout<<"red "<<Samurai_Name[Y.Member[Y.Queue[i]].Name]<<" "<<Y.Queue[i]+1
<<" and blue "<<Samurai_Name[X.Member[X.Queue[i]].Name]<<" "<<X.Queue[i]+1<<" were alive in city "<<i<<"\n";
Yelled(X, i); Yelled(Y, i);
break;
}
if(X.Queue[i] == -1 || Y.Queue[i]== -1) break;
}
}
}
}
}
bool check() { if(Hour*60 + Minute > T) return true; else return false; } //判断停止
int main(int argc, char** argv) {
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
cin>>t;
for(int Q=1; Q<=t; Q++) {
If_Win = 0;
HeadQuarter Red, Blue;
memset(Red.Queue, -1, sizeof(Red.Queue));
memset(Blue.Queue, -1, sizeof(Blue.Queue));
Red.HQName = "red"; Blue.HQName = "blue";
Blue.Sequence[1] = 4; Blue.Sequence[2] = 1; Blue.Sequence[3] = 2; Blue.Sequence[4] = 3; Blue.Sequence[5] = 5;
cin >> M >> N >> K >> T;
Red.HP = M; Red.Lyt_Reduce = K;
Blue.HP = M; Blue.Lyt_Reduce = K;
Hour = 0; Minute = 0;
for(int i=1; i<=5; i++) { cin >> Red.SamuraiCost[i]; }
for(int i=1; i<=5; i++) { cin >> Red.Samurai_Force[i]; }
for(int i=1; i<=5; i++) { Blue.SamuraiCost[i] = Red.SamuraiCost[i]; Blue.Samurai_Force[i] = Red.Samurai_Force[i];}
cout<<"Case "<<Q<<":\n";
bool sr = false, sb = false;
while(Hour*60 + Minute <= T) {
//第0分,降生
if(check()) break;
if(!sr) { sr = Red.Produce(0); }
if(!sb) { sb = Blue.Produce(N+1); }
//第5分,逃跑
Minute = 5;
if(check()) break;
Run(Red, Blue);
//第10分,前进
Minute = 10;
if(check()) break;
if(Move(Red, Blue)) break;
//第35分,抢夺 ---
Minute = 35;
if(check()) break;
Snatch(Red, Blue);
//第40分,战斗
Minute = 40;
if(check()) break;
Fight(Red, Blue);
//第50分,司令部报告
Minute = 50;
if(check()) break;
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" "<<Red.HP<<" elements in red headquarter\n";
cout<<setw(3)<<setfill('0')<<Hour<<":"<<setw(2)<<Minute<<" "<<Blue.HP<<" elements in blue headquarter\n";
//第55分,武士报告
Minute = 55;
if(check()) break;
Report_S(Red, Blue);
Minute = 0; Hour++;//下一个小时
}
}
fclose(stdin);
fclose(stdout);
return 0;
}
后记
上课没听或者压根没去上课导致讲的东西一点不会,但是大作业还是要写的,怎么办呢。反正能实现效果就行了对吧?当时对类这个东西还一点都不熟,然后又因为摆烂,好像是最后一周才想起来做,但是哪怕最后一周还是三天打鱼两天晒网,最后阶段三花了最后一两天才调完了着急交上去了。写的什么东西我也忘了总之很烂,该用的一点没用,单纯大力出奇迹了属于是。虽然本来就是大模拟也用不着什么。虽然这么说,但是想来当时思路并不混乱,然后加上我打了那么一丢丢的注释应该也不算难理解,码风是不太好,变量使用有些夸张但也算是为了方便理解。以上