たまとバリア
エンジンの担当 この章は、弾とバリアの決まりです。当たる・はね返る・消えるは、エンジンが自動でやります。いつ撃つか・いつ張るかを決めるのは、あなたの担当です(4 つの入力)。
fire を True にすると撃ちます。ただし、いつでも撃てるわけではありません。
| 撃てないとき | どうなる |
|---|---|
| 前に撃ってから 1.2 秒たっていない | 何も起きない(エラーにもならない) |
| バリアを張っている | 何も起きない |
いま撃てるかどうかは state.me.can_fire で分かります。
あと何秒で撃てるかは state.me.reload_left です。
def update(state): # 撃てるときだけ撃つ return { "drive": "forward", "steer": angle_to(state.me.x, state.me.y, state.enemy.x, state.enemy.y), "fire": state.me.can_fire, "barrier": False, }| 項目 | 数 |
|---|---|
| 速さ | 8.0 マス/秒(タンクの 2.7 倍) |
| 大きさ | 半径 0.08 マス(とても小さい) |
| 出てくる場所 | タンクの中心から前へ 0.45 マス |
| 消えるまで | 3.0 秒 |
| はね返る回数 | 1 発につき 1 回だけ |
| ダメージ | 1(HP は 3 なので 3 発で負け) |
3.0 秒で消えるので、たまが届くのは 24 マスまでです。 フィールドのななめの長さは 25 マスくらいあるので、端から端は届きません。
たまどうしがぶつかると、両方消える
Section titled “たまどうしがぶつかると、両方消える”正面から撃ちあうと、たまが空中でぶつかって2 発とも消えます。 0.20 マスまで近づいたら消える、というルールです。
だから「まっすぐ向かいあって撃ちあう」だけでは、いつまでも決着がつきません。 すこし横にずれるのが大事です。
飛んでくるたまを見る
Section titled “飛んでくるたまを見る”自分に向かってくるたまは state.incoming_missiles に入っています。
危ない順にならんでいます。 いちばん先に当たるたまが incoming_missiles[0] です。
この順番は決まりごとなので、安心して頼っていいです。
def update(state): # 0.4 秒以内に当たるたまがあるか danger = False if len(state.incoming_missiles) > 0: if state.incoming_missiles[0].eta < 0.4: danger = True
if danger: return {"drive": "forward", "steer": state.me.angle, "fire": False, "barrier": True}
return {"drive": "forward", "steer": state.me.angle, "fire": True, "barrier": False}eta は「あと何秒でいちばん近づくか」です。
通りすぎて遠ざかっていくたまは、はじめからこの一覧に入りません。
「もう危なくないたま」に驚かなくて済むようになっています。
barrier を True にすると、正面にバリアが出ます。
| 項目 | 数 |
|---|---|
| 使える回数 | 1 試合に 3 回(サプライで 4 回まで) |
| 続く時間 | 2.0 秒 |
| 次に使えるまで | 終わってから 5.0 秒 |
| 守る範囲 | 正面から左右 45 度だけ |
| そのあいだ | 移動が半分の速さ・撃てない |
わざと不便にしてある
Section titled “わざと不便にしてある”「まわり全部を守るバリア」にすると、答えが 1 つに決まってしまいます。 「たまが近かったら張る」だけで最強になり、考えることが無くなります。
正面だけにすると「どっちから飛んできているか」を計算しないといけません。 これは偏差射撃とまったく同じ算数です。 1 度おぼえたことを、攻めにも守りにも使えるように、わざとこうしてあります。
def update(state): if len(state.incoming_missiles) == 0: return {"drive": "forward", "fire": True, "barrier": False}
m = state.incoming_missiles[0] # たまが「いま居るほう」を向く toward = angle_to(state.me.x, state.me.y, m.x, m.y) ready = state.me.barrier_count > 0 and state.me.barrier_cooldown == 0.0
if m.eta < 0.5 and ready: return {"drive": "stop", "steer": toward, "fire": False, "barrier": True}
return {"drive": "forward", "steer": toward, "fire": True, "barrier": False}勝ち負けの決まりかた
Section titled “勝ち負けの決まりかた”試合は 60 秒です。上から順に比べて、先に差がついたほうが勝ちです。
| 順番 | くらべるもの |
|---|---|
| 1 | 相手の HP を 0 にした(KO 勝ち) |
| 2 | 残っている HP が多い |
| 3 | 与えたダメージが多い |
| 4 | 当たった回数が少ない |
| 5 | 動いた距離が多い |
| 6 | ぜんぶ同じなら引き分け |
5 番目に「動いた距離」があるのは、じっと隠れているだけの bot が勝たないようにするためです。
- 動く敵に当てたい → 偏差射撃
- 壁ではね返らせたい → 跳弾のしくみ
stateに何が入っているか全部見たい → state リファレンス