程序设计实习 MOOC Week 6(待補)

contents

  1. 1. 前提概要
  2. 2. A - 魔兽世界终极版
    1. 2.1. 題目
    2. 2.2. 失敗代碼

前提概要

這一道題目,照理來講是一版一版慢慢加強,但是突然接收到巨噁模擬題。在很有耐心看完後,看起來是不得度使用物件導向的多形來模擬,不然程式代碼會寫得非常難看,難看也倒還好,只是怕寫不出來。

不過礙於時間關係,寫到一半還是放棄了,於是附加的代碼是 失敗 的。

卡在 RE 狀態,明明本地端測試不會有噴出 RE 資訊,上傳卻發生了 RE,暫時沒有辦法去解決。
題目來源

A - 魔兽世界终极版

題目

总时间限制: 2000ms 内存限制: 65536kB

描述

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市,城市从西向东依次编号为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。

武士降生后就朝对方司令部走,在经过的城市如果遇到敌人(同一时刻每个城市最多只可能有1个蓝武士和一个红武士),就会发生战斗。每次战斗只有一方发起主动进攻一次。被攻击者生命值会减去进攻者的攻击力值和进攻者手中sword的攻击力值。被进攻者若没死,就会发起反击,被反击者的生命值要减去反击者攻击力值的一半(去尾取整)和反击者手中sword的攻击力值。反击可能致敌人于死地。

如果武士在战斗中杀死敌人(不论是主动进攻杀死还是反击杀死),则其司令部会立即向其发送8个生命元作为奖励,使其生命值增加8。当然前提是司令部得有8个生命元。如果司令部的生命元不足以奖励所有的武士,则优先奖励距离敌方司令部近的武士。

如果某武士在某城市的战斗中杀死了敌人,则该武士的司令部立即取得该城市中所有的生命元。注意,司令部总是先完成全部奖励工作,然后才开始从各个打了胜仗的城市回收生命元。对于因司令部生命元不足而领不到奖励的武士,司令部也不会在取得战利品生命元后为其补发奖励。

如果一次战斗的结果是双方都幸存(平局),则双方都不能拿走发生战斗的城市的生命元。

城市可以插旗子,一开始所有城市都没有旗子。在插红旗的城市,以及编号为奇数的无旗城市,由红武士主动发起进攻。在插蓝旗的城市,以及编号为偶数的无旗城市,由蓝武士主动发起进攻。

当某个城市有连续两场战斗都是同一方的武士杀死敌人(两场战斗之间如果有若干个战斗时刻并没有发生战斗,则这两场战斗仍然算是连续的;但如果中间有平局的战斗,就不算连续了) ,那么该城市就会插上胜方的旗帜,若原来插着败方的旗帜,则败方旗帜落下。旗帜一旦插上,就一直插着,直到被敌人更换。一个城市最多只能插一面旗帜,旗帜没被敌人更换前,也不会再次插同颜色的旗。

各种武器有其特点:

sword武器的初始攻击力为拥有它的武士的攻击力的20%(去尾取整)。但是sword每经过一次战斗(不论是主动攻击还是反击),就会变钝,攻击力变为本次战斗前的80% (去尾取整)。sword攻击力变为0时,视为武士失去了sword。如果武士降生时得到了一个初始攻击力为0的sword,则视为武士没有sword.

arrow有一个攻击力值R。如果下一步要走到的城市有敌人,那么拥有arrow的武士就会放箭攻击下一个城市的敌人(不能攻击对方司令部里的敌人)而不被还击。arrow使敌人的生命值减少R,若减至小于等于0,则敌人被杀死。arrow使用3次后即被耗尽,武士失去arrow。两个相邻的武士可能同时放箭把对方射死。

拥有bomb的武士,在战斗开始前如果判断自己将被杀死(不论主动攻击敌人,或者被敌人主动攻击都可能导致自己被杀死,而且假设武士可以知道敌人的攻击力和生命值),那么就会使用bomb和敌人同归于尽。武士不预测对方是否会使用bomb。

武士使用bomb和敌人同归于尽的情况下,不算是一场战斗,双方都不能拿走城市的生命元,也不影响城市的旗帜。

不同的武士有不同的特点。

dragon可以拥有一件武器。编号为n的dragon降生时即获得编号为 n%3 的武器。dragon还有“士气”这个属性,是个浮点数,其值为它降生后其司令部剩余生命元的数量除以造dragon所需的生命元数量。dragon 在一次在它主动进攻的战斗结束后,如果还没有战死,而且士气值大于0.8,就会欢呼。dragon每取得一次战斗的胜利(敌人被杀死),士气就会增加0.2,每经历一次未能获胜的战斗,士气值就会减少0.2。士气增减发生在欢呼之前。

ninjia可以拥有两件武器。编号为n的ninjia降生时即获得编号为 n%3 和 (n+1)%3的武器。ninja 挨打了也从不反击敌人。

iceman有一件武器。编号为n的iceman降生时即获得编号为 n%3 的武器。iceman 每前进两步,在第2步完成的时候,生命值会减少9,攻击力会增加20。但是若生命值减9后会小于等于0,则生命值不减9,而是变为1。即iceman不会因走多了而死。

lion 有“忠诚度”这个属性,其初始值等于它降生之后其司令部剩余生命元的数目。每经过一场未能杀死敌人的战斗,忠诚度就降低K。忠诚度降至0或0以下,则该lion逃离战场,永远消失。但是已经到达敌人司令部的lion不会逃跑。Lion在己方司令部可能逃跑。lion 若是战死,则其战斗前的生命值就会转移到对手身上。所谓“战斗前”,就是每个小时的40分前的一瞬间。

wolf降生时没有武器,但是在战斗中如果获胜(杀死敌人),就会缴获敌人的武器,但自己已有的武器就不缴获了。被缴获的武器当然不能算新的,已经被用到什么样了,就是什么样的。

以下是不同时间会发生的不同事件:

在每个整点,即每个小时的第0分, 双方的司令部中各有一个武士降生。

红方司令部按照 iceman、lion、wolf、ninja、dragon 的顺序制造武士。

蓝方司令部按照 lion、dragon、ninja、iceman、wolf 的顺序制造武士。

制造武士需要生命元。

制造一个初始生命值为 m 的武士,司令部中的生命元就要减少 m 个。

如果司令部中的生命元不足以制造某武士,那么司令部就等待,直到获得足够生命元后的第一个整点,才制造该武士。例如,在2:00,红方司令部本该制造一个 wolf ,如果此时生命元不足,那么就会等待,直到生命元足够后的下一个整点,才制造一个 wolf。

在每个小时的第5分,该逃跑的lion就在这一时刻逃跑了。

在每个小时的第10分:所有的武士朝敌人司令部方向前进一步。即从己方司令部走到相邻城市,或从一个城市走到下一个城市。或从和敌军司令部相邻的城市到达敌军司令部。

在每个小时的第20分:每个城市产出10个生命元。生命元留在城市,直到被武士取走。

在每个小时的第30分:如果某个城市中只有一个武士,那么该武士取走该城市中的所有生命元,并立即将这些生命元传送到其所属的司令部。

在每个小时的第35分,拥有arrow的武士放箭,对敌人造成伤害。放箭事件应算发生在箭发出的城市。注意,放箭不算是战斗,因此放箭的武士不会得到任何好处。武士在没有敌人的城市被箭射死也不影响其所在城市的旗帜更换情况。

在每个小时的第38分,拥有bomb的武士评估是否应该使用bomb。如果是,就用bomb和敌人同归于尽。

在每个小时的第40分:在有两个武士的城市,会发生战斗。 如果敌人在5分钟前已经被飞来的arrow射死,那么仍然视为发生了一场战斗,而且存活者视为获得了战斗的胜利。此情况下不会有“武士主动攻击”,“武士反击”,“武士战死”的事件发生,但战斗胜利后应该发生的事情都会发生。如Wolf一样能缴获武器,旗帜也可能更换,等等。在此情况下,Dragon同样会通过判断是否应该轮到自己主动攻击来决定是否欢呼。

在每个小时的第50分,司令部报告它拥有的生命元数量。

在每个小时的第55分,每个武士报告其拥有的武器情况。

武士到达对方司令部后就算完成任务了,从此就呆在那里无所事事。

任何一方的司令部里若是出现了2个敌人,则认为该司令部已被敌人占领。

任何一方的司令部被敌人占领,则战争结束。战争结束之后就不会发生任何事情了。

给定一个时间,要求你将从0点0分开始到此时间为止的所有事件按顺序输出。事件及其对应的输出样例如下:

1) 武士降生

输出样例: 000:00 blue lion 1 born

表示在 0点0分,编号为1的蓝魔lion武士降生
如果造出的是dragon,那么还要多输出一行,例:

000:00 blue dragon 1 born
Its morale is 23.34

表示该该dragon降生时士气是23. 34(四舍五入到小数点后两位)

如果造出的是lion,那么还要多输出一行,例:
000:00 blue lion 1 born
Its loyalty is 24

表示该lion降生时的忠诚度是24

2) lion逃跑

输出样例: 000:05 blue lion 1 ran away
表示在 0点5分,编号为1的蓝魔lion武士逃走

3) 武士前进到某一城市

输出样例: 000:10 red iceman 1 marched to city 1 with 20 elements and force 30
表示在 0点10分,红魔1号武士iceman前进到1号城市,此时他生命值为20,攻击力为30
对于iceman,输出的生命值和攻击力应该是变化后的数值

4)武士放箭

输出样例: 000:35 blue dragon 1 shot
表示在 0点35分,编号为1的蓝魔dragon武士射出一支箭。如果射出的箭杀死了敌人,则应如下输出:
000:35 blue dragon 1 shot and killed red lion 4
表示在 0点35分,编号为1的蓝魔dragon武士射出一支箭,杀死了编号为4的红魔lion。

5)武士使用bomb

输出样例: 000:38 blue dragon 1 used a bomb and killed red lion 7
表示在 0点38分,编号为1的蓝魔dragon武士用炸弹和编号为7的红魔lion同归于尽。

6) 武士主动进攻

输出样例:000:40 red iceman 1 attacked blue lion 1 in city 1 with 20 elements and force 30
表示在0点40分,1号城市中,红魔1号武士iceman 进攻蓝魔1号武士lion,在发起进攻前,红魔1号武士iceman生命值为20,攻击力为 30

7) 武士反击

输出样例:001:40 blue dragon 2 fought back against red lion 2 in city 1
表示在1点40分,1号城市中,蓝魔2号武士dragon反击红魔2号武士lion

8) 武士战死

输出样例:001:40 red lion 2 was killed in city 1
被箭射死的武士就不会有这一条输出。

9) 武士欢呼

输出样例:003:40 blue dragon 2 yelled in city 4

10) 武士获取生命元( elements )

输出样例:001:40 blue dragon 2 earned 10 elements for his headquarter

11) 旗帜升起

输出样例:004:40 blue flag raised in city 4

12) 武士抵达敌军司令部

输出样例:001:10 red iceman 1 reached blue headquarter with 20 elements and force 30
(此时他生命值为20,攻击力为30)对于iceman,输出的生命值和攻击力应该是变化后的数值

13) 司令部被占领

输出样例:003:10 blue headquarter was taken

14)司令部报告生命元数量

000:50 100 elements in red headquarter
000:50 120 elements in blue headquarter
表示在0点50分,红方司令部有100个生命元,蓝方有120个

15)武士报告武器情况

000:55 blue wolf 2 has arrow(2),bomb,sword(23)
000:55 blue wolf 4 has no weapon
000:55 blue wolf 5 has sword(20)
表示在0点55分,蓝魔2号武士wolf有一支arrow(这支arrow还可以用2次),一个bomb,还有一支攻击力为23的sword。
蓝魔4号武士wolf没武器。
蓝魔5号武士wolf有一支攻击力为20的sword。
交代武器情况时,次序依次是:arrow,bomb,sword。如果没有某种武器,某种武器就不用提。报告时,先按从西向东的顺序所有的红武士报告,然后再从西向东所有的蓝武士报告。

输出事件时:

首先按时间顺序输出;

同一时间发生的事件,按发生地点从西向东依次输出. 武士前进的事件, 算是发生在目的地。

在一次战斗中有可能发生上面的 6 至 11 号事件。这些事件都算同时发生,其时间就是战斗开始时间。一次战斗中的这些事件,序号小的应该先输出。

两个武士同时抵达同一城市,则先输出红武士的前进事件,后输出蓝武士的。

显然,13号事件发生之前的一瞬间一定发生了12号事件。输出时,这两件事算同一时间发生,但是应先输出12号事件

虽然任何一方的司令部被占领之后,就不会有任何事情发生了。但和司令部被占领同时发生的事件,全都要输出。

输入

第一行是t,代表测试数据组数
每组样例共三行。
第一行,五个整数 M,N,R,K, T。其含义为:

每个司令部一开始都有M个生命元( 1 <= M <= 10000)
两个司令部之间一共有N个城市( 1 <= N <= 20 )
arrow的攻击力是R
lion每经过一场未能杀死敌人的战斗,忠诚度就降低K。
要求输出从0时0分开始,到时间T为止(包括T) 的所有事件。T以分钟为单位,0 <= T <= 5000

第二行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它们都大于0小于等于10000

第三行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的攻击力。它们都大于0小于等于10000

输出

对每组数据,先输出一行:
Case n:
如对第一组数据就输出 Case1:
然后按恰当的顺序和格式输出到时间T为止发生的所有事件。每个事件都以事件发生的时间开头,时间格式是“时: 分”,“时”有三位,“分”有两位。

样例输入

1
20 1 10 10 1000
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:30 blue lion 1 earned 10 elements for his headquarter
000:50 20 elements in red headquarter
000:50 20 elements in blue headquarter
000:55 blue lion 1 has no weapon
001:00 blue dragon 2 born
Its morale is 0.00
001:10 blue lion 1 reached red headquarter with 10 elements and force 5
001:10 blue dragon 2 marched to city 1 with 20 elements and force 5
001:30 blue dragon 2 earned 10 elements for his headquarter
001:50 20 elements in red headquarter
001:50 10 elements in blue headquarter
001:55 blue lion 1 has no weapon
001:55 blue dragon 2 has arrow(3)
002:10 blue dragon 2 reached red headquarter with 20 elements and force 5
002:10 red headquarter was taken

失敗代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
#include <stdio.h>
#include <algorithm>
#include <map>
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
class Info {
public:
static int M, N, R, K, T;
static map<string, int> HP, ATK;
static string Mkind[];
static string Rkind[];
static string Bkind[];
};
int Info::M = 0, Info::N = 0, Info::R = 0, Info::K = 0, Info::T = 0;
map<string, int> Info::HP, Info::ATK;
string Info::Mkind[] = {"dragon", "ninja", "iceman", "lion", "wolf"};
string Info::Rkind[] = {"dragon", "iceman", "lion", "wolf", "ninja"};
string Info::Bkind[] = {"wolf", "lion", "dragon", "ninja", "iceman"};
class Weapon {
public:
virtual void show() {};
virtual int getMeleeAttack() {
return 0;
};
virtual int actMeleeAttack() {
return 0;
};
virtual int getRangeAttack() {
return 0;
}
virtual int actRangeAttack() {
return 0;
}
virtual int getBombAttack() {
return 0;
}
virtual int actBombAttack() {
return 0;
}
};
class Sword: public Weapon {
public:
int attack;
Sword(int _attack): attack(_attack) {
}
int getMeleeAttack() {
return attack;
}
int actMeleeAttack() {
attack = attack * 8 / 10;
return attack > 0;
}
void show() {
printf("sword(%d)", attack);
}
};
class Arrow: public Weapon {
public:
int R, usedTime;
Arrow(int _R): R(_R) {
usedTime = 0;
}
int getRangeAttack() {
return usedTime < 3 ? R : 0;
}
int actRangeAttack() {
usedTime++;
return usedTime >= 3;
}
void show() {
printf("arrow(%d)", 3 - usedTime);
}
};
class Bomb: public Weapon {
public:
Bomb() {
}
int getBombAttack() {
return 1;
}
void show() {
printf("bomb");
}
};
class WeaponFactory {
public:
static Weapon* build(int n, int attack) {
if(n == 0) {
if(attack / 5 <= 0)
return NULL;
return new Sword(attack/5);
}
else if(n == 2)
return new Arrow(Info::R);
else
return new Bomb();
}
};
class Warrior {
public:
int n;
int life;
Warrior(int _n, int _life): n(_n), life(_life) {
}
virtual void show() {};
virtual void showName() {};
virtual void showWeapon() {};
virtual int getAttack() {return 0;}
virtual int getFled() {return 0;}
virtual int getMeleeAttack() {return 0;}
virtual void actMeleeAttack() {}
virtual int getBackAttack() {return 0;}
virtual void actBackAttack() {}
virtual void move() {};
virtual void actRangeAttack(Warrior* o) {};
};
class Dragon: public Warrior {
public:
Weapon *weapon;
float morale;
Dragon(int _n, int _life, float _morale): Warrior(_n, _life), morale(_morale) {
weapon = WeaponFactory::build(n%3, Info::ATK["dragon"]);
}
void show() {
printf("dragon %d born\n", n);
printf("Its morale is %.2f\n", morale);
}
void showName() {
printf("dragon %d", n);
}
void showWeapon() {
if(weapon != NULL)
weapon->show();
else
printf("no weapon");
}
int getAttack() {
return Info::ATK["dragon"];
}
int getMeleeAttack() {
int m = 0;
if(weapon != NULL)
m = weapon->getMeleeAttack();
return getAttack() + m;
}
int getBackAttack() {
int m = 0;
if(weapon != NULL)
m = weapon->getMeleeAttack();
return getAttack()/2 + m;
}
void actMeleeAttack() {
if(weapon != NULL) {
int f = weapon->actMeleeAttack();
if(f == 0) {
delete weapon;
weapon = NULL;
}
}
}
void actBackAttack() {
actMeleeAttack();
}
void actRangeAttack(Warrior* o) {
if(weapon != NULL) {
o->life -= weapon->getRangeAttack();
int f = weapon->actRangeAttack();
if(f == 1) {
delete weapon;
weapon = NULL;
}
}
}
};
class Ninja: public Warrior {
public:
Weapon *weapon[2];
Ninja(int _n, int _life): Warrior(_n, _life) {
weapon[0] = WeaponFactory::build(n%3, Info::ATK["ninja"]);
weapon[1] = WeaponFactory::build((n+1)%3, Info::ATK["ninja"]);
}
void show() {
printf("ninja %d born\n", n);
}
void showName() {
printf("ninja %d", n);
}
void showWeapon() {
int f1 = n%3, f2 = (n+1)%3, f = 0;
if(f1 < f2) {
if(weapon[0] != NULL)
weapon[0]->show(), f++;
if(f) putchar(',');
if(weapon[1] != NULL)
weapon[1]->show(), f++;
} else {
if(weapon[1] != NULL)
weapon[1]->show(), f++;
if(f) putchar(',');
if(weapon[0] != NULL)
weapon[0]->show(), f++;
}
if(f == 0)
printf("no weapon");
}
int getAttack() {
return Info::ATK["ninja"];
}
int getMeleeAttack() {
int m = 0;
if(weapon[0] != NULL)
m += weapon[0]->getMeleeAttack();
if(weapon[1] != NULL)
m += weapon[1]->getMeleeAttack();
return getAttack() + m;
}
int getBackAttack() {
int m = 0;
if(weapon[0] != NULL)
m += weapon[0]->getMeleeAttack();
if(weapon[1] != NULL)
m += weapon[1]->getMeleeAttack();
return getAttack()/2 + m;
}
void actMeleeAttack() {
if(weapon[0] != NULL) {
int f = weapon[0]->actMeleeAttack();
if(f == 0) {
delete weapon[0];
weapon[0] = NULL;
}
}
if(weapon[1] != NULL) {
int f = weapon[1]->actMeleeAttack();
if(f == 0) {
delete weapon[1];
weapon[1] = NULL;
}
}
}
void actBackAttack() {
actMeleeAttack();
}
void actRangeAttack(Warrior* o) {
for(int i = 0; i < 2; i++) {
if(weapon[i] != NULL) {
o->life -= weapon[i]->getRangeAttack();
int f = weapon[i]->actRangeAttack();
if(f == 1)
weapon[i] = NULL;
}
}
}
};
class Iceman: public Warrior {
public:
Weapon *weapon;
int move_count;
int attack;
Iceman(int _n, int _life): Warrior(_n, _life) {
weapon = WeaponFactory::build(n%3, Info::ATK["iceman"]);
move_count = 0;
attack = Info::ATK["iceman"];
}
void show(){
printf("iceman %d born\n", n);
}
void showName() {
printf("iceman %d", n);
}
void showWeapon() {
if(weapon != NULL)
weapon->show();
else
printf("no weapon");
}
int getAttack() {
return attack;
}
int getMeleeAttack() {
int m = 0;
if(weapon != NULL)
m = weapon->getMeleeAttack();
return getAttack() + m;
}
int getBackAttack() {
int m = 0;
if(weapon != NULL)
m = weapon->getMeleeAttack();
return getAttack()/2 + m;
}
void actMeleeAttack() {
if(weapon != NULL) {
int f = weapon->actMeleeAttack();
if(f == 0) {
delete weapon;
weapon = NULL;
}
}
}
void actBackAttack() {
actMeleeAttack();
}
void actRangeAttack(Warrior* o) {
if(weapon != NULL) {
o->life -= weapon->getRangeAttack();
int f = weapon->actRangeAttack();
if(f == 1) {
delete weapon;
weapon = NULL;
}
}
}
void move() {
move_count++;
if(move_count == 2) {
attack += 20;
life -= 9;
if(life <= 0)
life = 1;
move_count = 0;
}
}
};
class Lion: public Warrior {
public:
int loyalty;
Lion(int _n, int _life, int _loyalty): Warrior(_n, _life), loyalty(_loyalty) {
}
void show() {
printf("lion %d born\n", n);
printf("Its loyalty is %d\n", loyalty);
}
void showName() {
printf("lion %d", n);
}
void showWeapon() {
printf("no weapon");
}
int getAttack() {
return Info::ATK["lion"];
}
int getMeleeAttack() {
return getAttack();
}
int getBackAttack() {
return getAttack()/2;
}
int getFled() {
return loyalty <= 0;
}
};
class Wolf: public Warrior {
public:
Weapon *weapon[3];
Wolf(int _n, int _life): Warrior(_n, _life) {
weapon[0] = weapon[1] = weapon[2] = NULL;
}
void show() {
printf("wolf %d born\n", n);
}
void showName() {
printf("wolf %d", n);
}
void showWeapon() {
int f = 0;
for(int i = 0; i < 3; i++) {
if(weapon[i] != NULL) {
if(f) putchar(',');
weapon[i]->show(), f++;
}
}
if(f == 0)
printf("no weapon");
}
int getAttack() {
return Info::ATK["wolf"];
}
int getMeleeAttack() {
int m = 0;
if(weapon[2] != NULL)
m = weapon[2]->getMeleeAttack();
return getAttack() + m;
}
int getBackAttack() {
int m = 0;
if(weapon[2] != NULL)
m = weapon[2]->getMeleeAttack();
return getAttack()/2 + m;
}
void actMeleeAttack() {
if(weapon[2] != NULL) {
int f = weapon[2]->actMeleeAttack();
if(f == 0) {
delete weapon[2];
weapon[2] = NULL;
}
}
}
void actBackAttack() {
actMeleeAttack();
}
void actRangeAttack(Warrior* o) {
if(weapon[2] != NULL) {
o->life -= weapon[2]->getRangeAttack();
int f = weapon[2]->actRangeAttack();
if(f == 1)
weapon[2] = NULL;
}
}
};
class WarriorFactory {
public:
static Warrior* build(string kind, int n, float _morale, int _loyalty) {
if(!strcmp(kind.c_str(), "dragon"))
return new Dragon(n, Info::HP[kind], _morale);
else if(!strcmp(kind.c_str(), "ninja"))
return new Ninja(n, Info::HP[kind]);
else if(!strcmp(kind.c_str(), "iceman"))
return new Iceman(n, Info::HP[kind]);
else if(!strcmp(kind.c_str(), "lion"))
return new Lion(n, Info::HP[kind], _loyalty);
else
return new Wolf(n, Info::HP[kind]);
}
};
class Headquarter {
public:
int HP;
int dir;
int n;
Headquarter(int _HP, int _dir): HP(_HP), dir(_dir) {
n = 1;
}
void produce(vector<Warrior*> R[], vector<Warrior*> B[], int hh, int mm) {
string kind;
int born_cost;
if(dir == 1) { // RED
kind = Info::Rkind[n % 5];
} else { // BLUE
kind = Info::Bkind[n % 5];
}
born_cost = Info::HP[kind];
if(born_cost > HP)
return;
HP -= born_cost;
printf("%03d:%02d %s ", hh, mm, dir == 1 ? "red" : "blue");
Warrior *w = WarriorFactory::build(kind, n, (double) HP/ Info::HP[kind], HP);
w->show();
if(dir == 1) { // RED
R[0].push_back(w);
} else {
B[Info::N + 1].push_back(w);
}
n++;
}
};
void simulate() {
Headquarter RED(Info::M, 1), BLUE(Info::M, -1);
int timescale[] = {0, 5, 10, 20, 30, 35, 38, 40, 50, 55};
vector<Warrior*> R[Info::N + 2], B[Info::N + 2];
int cityHP[Info::N+2], cityFlag[Info::N+2], cityBattle[Info::N+2];
// cityFlag[], cityBattle[], NONE: 0, RED: 1, BLUE: 2
for(int i = 0; i <= Info::N + 1; i++)
cityHP[i] = cityFlag[i] = cityBattle[i] = 0;
for(int hour = 0; ; hour++) {
for(int i = 0; i < 10; i++) {
if(hour * 60 + timescale[i] > Info::T)
return;
int t = timescale[i];
if(t == 0) { // fixed
RED.produce(R, B, hour, t);
BLUE.produce(R, B, hour, t);
} else if(t == 5) { // fixed
for(int i = 0; i <= Info::N; i++) {
if(R[i].size() > 0) {
if(R[i][0]->getFled()) {
printf("%03d:%02d red ", hour, t);
R[i][0]->showName();
printf(" ran away\n");
R[i].clear();
}
}
}
for(int i = 1; i <= Info::N+1; i++) {
if(B[i].size() > 0) {
if(B[i][0]->getFled()) {
printf("%03d:%02d blue ", hour, t);
B[i][0]->showName();
printf(" ran away\n");
B[i].clear();
}
}
}
} else if(t == 10) { // fixed
for(int i = 0; i <= Info::N + 1; i++) {
if(R[i].size() > 0 && i <= Info::N) {
printf("%03d:%02d red ", hour, t);
R[i][0]->showName();
R[i][0]->move();
if(i + 1 < Info::N + 1)
printf(" marched to city %d with %d elements and force %d\n", i + 1, R[i][0]->life, R[i][0]->getAttack());
else
printf(" reached blue headquarter with %d elements and force %d\n", R[i][0]->life, R[i][0]->getAttack());
}
if(B[i].size() > 0 && i > 0) {
printf("%03d:%02d blue ", hour, t);
B[i][0]->showName();
B[i][0]->move();
if(i - 1 > 0)
printf(" marched to city %d with %d elements and force %d\n", i - 1, B[i][0]->life, B[i][0]->getAttack());
else
printf(" reached red headquarter with %d elements and force %d\n", B[i][0]->life, B[i][0]->getAttack());
}
}
for(int i = Info::N; i >= 0; i--) {
if(R[i].size() > 0) {
R[i+1].push_back(R[i][0]);
R[i].clear();
}
}
for(int i = 1; i <= Info::N + 1; i++) {
if(B[i].size() > 0) {
B[i-1].push_back(B[i][0]);
B[i].clear();
}
}
if(B[0].size() >= 2) {
printf("%03d:%02d red headquarter was taken\n", hour, t);
return ;
}
if(R[Info::N+1].size() >= 2) {
printf("%03d:%02d blue headquarter was taken\n", hour, t);
return ;
}
} else if(t == 20) { // fixed
for(int i = 1; i <= Info::N; i++)
cityHP[i] += 10;
} else if(t == 30) { // fixed
for(int i = 1; i <= Info::N; i++) {
if(R[i].size() == 1 && B[i].size() == 0) {
printf("%03d:%02d red ", hour, t);
R[i][0]->showName();
printf(" earned %d elements for his headquarter\n", cityHP[i]);
RED.HP += cityHP[i], cityHP[i] = 0;
}
if(R[i].size() == 0 && B[i].size() == 1) {
printf("%03d:%02d blue ", hour, t);
B[i][0]->showName();
printf(" earned %d elements for his headquarter\n", cityHP[i]);
BLUE.HP += cityHP[i], cityHP[i] = 0;
}
}
} else if(t == 35) { // fixed
for(int i = 0; i <= Info::N; i++) {
if(R[i].size() > 0 && B[i+1].size() > 0) {
R[i][0]->actRangeAttack(B[i+1][0]);
}
}
for(int i = 1; i <= Info::N + 1; i++) {
if(B[i].size() > 0 && R[i-1].size() > 0) {
B[i][0]->actRangeAttack(R[i-1][0]);
}
}
} else if(t == 38) { // fixed
for(int i = 0; i <= Info::N + 1; i++) {
if(R[i].size() > 0 && B[i].size() > 0) {
int rATK = R[i][0]->getMeleeAttack();
int bATK = B[i][0]->getMeleeAttack();
if(bATK >= R[i][0]->life) {
printf("%03d:%02d red ", hour, t);
R[i][0]->showName();
printf(" used a bomb and killed blue ");;
B[i][0]->showName();
puts("");
}
if(rATK >= B[i][0]->life) {
printf("%03d:%02d blue ", hour, t);
B[i][0]->showName();
printf(" used a bomb and killed red ");;
R[i][0]->showName();
puts("");
}
if(bATK >= R[i][0]->life || rATK >= B[i][0]->life) {
delete R[i][0];
R[i].clear();
delete B[i][0];
B[i].clear();
}
}
}
} else if(t == 40) {
int RB[Info::N+2];
for(int i = 1; i <= Info::N; i++) {
RB[i] = 0;
}
for(int i = 1; i <= Info::N; i++) {
if(R[i].size() > 0 && B[i].size() > 0) {
if(R[i][0]->life <= 0 || B[i][0]->life <= 0) {
} else {
if(cityFlag[i] == 1 || (cityFlag[i] == 0 && i%2 == 1)) {
int AT = R[i][0]->getMeleeAttack();
B[i][0]->life -= AT;
if(B[i][0]->life > 0) {
int BAT = B[i][0]->getBackAttack();
R[i][0]->life -= AT;
}
} else {
int AT = B[i][0]->getMeleeAttack();
R[i][0]->life -= AT;
if(R[i][0]->life > 0) {
int BAT = R[i][0]->getBackAttack();
B[i][0]->life -= AT;
}
}
}
if(R[i][0]->life > 0 && B[i][0]->life <= 0) {
RB[i] = 1;
if(cityBattle[i] == 1) {
cityFlag[i] = 1;
} else if(cityBattle[i] == 0) {
cityBattle[i] = 1;
}
}
if(B[i][0]->life > 0 && R[i][0]->life <= 0) {
RB[i] = 2;
if(cityBattle[i] == 2) {
cityFlag[i] = 2;
} else if(cityBattle[i] == 0) {
cityBattle[i] = 2;
}
}
}
if(R[i].size() > 0 && R[i][0]->life <= 0) {
delete R[i][0];
R[i].clear();
}
if(B[i].size() > 0 && B[i][0]->life <= 0) {
delete B[i][0];
B[i].clear();
}
}
for(int i = Info::N + 1; i >= 0; i--) {
if(RED.HP >= 8 && RB[i] == 1) {
RED.HP -= 8;
R[i][0]->life += 8;
}
}
for(int i = 0; i <= Info::N + 1; i++) {
if(BLUE.HP >= 8 && RB[i] == 2) {
BLUE.HP -= 8;
B[i][0]->life += 8;
}
}
for(int i = 0; i <= Info::N + 1; i++) {
if(RB[i] == 1) {
RED.HP += cityHP[i];
cityHP[i] = 0;
}
if(RB[i] == 2) {
BLUE.HP += cityHP[i];
cityHP[i] = 0;
}
}
} else if(t == 50) { // fixed
printf("%03d:%02d %d elements in red headquarter\n", hour, t, RED.HP);
printf("%03d:%02d %d elements in blue headquarter\n", hour, t, BLUE.HP);
} else if(t == 55) { // fixed
for(int i = 0; i <= Info::N + 1; i++) {
if(R[i].size() == 1) {
printf("%03d:%02d red ", hour, t);
R[i][0]->showName();
printf(" has ");
R[i][0]->showWeapon();
puts("");
}
if(B[i].size() == 1) {
printf("%03d:%02d blue ", hour, t);
B[i][0]->showName();
printf(" has ");
B[i][0]->showWeapon();
puts("");
}
}
}
}
}
}
int main() {
freopen("in.txt", "r+t", stdin);
freopen("out-my.txt", "w+t", stdout);
int testcase, cases = 0;
scanf("%d", &testcase);
while(testcase--) {
scanf("%d %d %d %d %d", &Info::M, &Info::N, &Info::R, &Info::K, &Info::T);
for(int i = 0; i < 5; i++)
scanf("%d", &Info::HP[Info::Mkind[i]]);
for(int i = 0; i < 5; i++)
scanf("%d", &Info::ATK[Info::Mkind[i]]);
printf("Case %d:\n", ++cases);
simulate();
}
return 0;
}