#P2729. Robocode

Robocode

描述

Robocode 是一个旨在帮助学习 Java 的教育游戏。玩家编写程序控制坦克在战场上相互战斗。这个游戏的想法看似简单,但要写出能取胜的坦克程序却需付出大量努力。今天我们不打算编写智能坦克,而是设计一个简化版的 robocode 游戏引擎。

假设整个战场是 $120\times120$ 像素。每辆坦克只能在固定路径上沿垂直或水平方向移动(战场上每隔 10 像素在垂直和水平方向都有一条路径,共有 13 条垂直路径和 13 条水平路径,如图 1 所示)。坦克的形状和大小可忽略,用 $(x,y)$ 表示其坐标位置,$x,y\in\{0,10,20,\dots,120\}$,用 $\alpha\in\{0,90,180,270\}$ 表示其朝向($\alpha=0,90,180,270$ 分别表示向右、向上、向左、向下)。坦克移动时速度恒为 $10$ 像素/秒,触碰边界时会立即停止(停在当前朝向,不再越界)。坦克无论移动还是静止,均可朝当前朝向开火。子弹速度恒为 $20$ 像素/秒,大小可忽略,若在路径上击中坦克则爆炸。若多颗子弹同时命中同一坦克,则会在同一位置同时爆炸。被爆炸击中的坦克会立即被摧毁并从战场移除。子弹爆炸或飞出边界后也会被移除。

图 1

游戏开始时,所有坦克都静止地分布在不同路径交叉点上。给定所有坦克的初始信息和若干条命令,要求在所有命令执行完毕(或被忽略)且战场上不再有子弹时,找出最终存活的最后一辆坦克——即“胜利者”。

输入

包含多组测试用例。战场和路径如图 1 所示,对所有测试用例相同。每组测试用例首先给出整数 $N$ ($1\le N\le10$) 和 $M$ ($1\le M\le1000$),中间以空格分隔。$N$ 表示坦克数量,$M$ 表示控制命令条数。接下来的 $N$ 行给出每辆坦克在时刻 0 的初始信息,格式为:

Name x y α

其中 Name 是不超过 10 个字母的字符串,$x,y\in\{0,10,20,\dots,120\}$,$\alpha\in\{0,90,180,270\}$,字段间以空格分隔。

再后 $M$ 行给出命令,格式为:

Time Name Content

字段间以空格分隔。所有命令按 Time 升序给出,$0\le\text{Time}\le30$,Time 为命令发送的时间戳(秒)。Name 指明接收命令的坦克。Content 有四种:

MOVE接到此命令时,坦克开始沿当前朝向移动;若已在移动,则无效。
STOP接到此命令时,坦克停止移动;若已静止,则无效。
TURN angle接到此命令时,坦克朝向 $\alpha=(\alpha+\text{angle}+360)\bmod360$;无论移动状态如何,均可转向,并保证结果仍在 $\{0,90,180,270\}$。
SHOOT接到此命令时,坦克朝当前朝向发射一枚子弹。

坦克在接收命令的瞬间立刻动作。例如,坐标 $(0,0)$、$\alpha=90$ 的坦克在时刻 1 收到 MOVE 时会立即开始移动,并在时刻 2 到达 $(0,10)$。注意,一秒内可接收多条命令并依序执行。例如,“TURN 90; SHOOT; TURN -90” 会先转向再开火再转回;“MOVE; STOP” 则保持原地静止。

注意事项:

  • 若坦克在一时刻被炸毁,则该时刻的所有命令对其无效,后续发给已摧毁坦克的命令也忽略。
  • 虽然命令按整秒发送,但坦克移动和子弹飞行、爆炸都在连续时间域发生。
  • 输入保证不会出现两坦克相遇的路径点,无需处理碰撞。
  • 所有输入均合法。

当 $N=M=0$ 时输入结束,该行不做处理。

输出

对每组测试用例,输出胜利者的名称(最后存活的一辆坦克)。若最终没有坦克或存活坦克多于一辆,则输出NO WINNER!。

2 2 A 0 0 90 B 0 120 180 1 A MOVE 2 A SHOOT 2 2 A 0 0 90 B 0 120 270 1 A SHOOT 2 B SHOOT 2 6 A 0 0 90 B 0 120 0 1 A MOVE 2 A SHOOT 6 B MOVE 30 B STOP 30 B TURN 180 30 B SHOOT 0 0 
A NO WINNER! B 

来源

Beijing 2005