コンテンツにスキップ

フィールドと地形

エンジンの担当 この章は、フィールドの決まりです。地形・サプライ・縮小エリアは、エンジンが自動で起こします。あなたの bot は、state を通して見ることができます。

試合(しあい)をする場所(ばしょ)は、横(よこ) 20 マス × 縦(たて) 15 マスの方眼(ほうがん)です。 いちばん外(そと)の 1 周(しゅう)はかならず鉄(てつ)の壁(かべ)なので、実際(じっさい)に走(はし)れるのは 18 × 13 マスです。

地形数タンクたま
平地(へいち)(EMPTY)0通れる通る
木箱(きばこ)(BRICK)1通れないこわせる。2 発(はつ)で消える
鉄(てつ)ブロック(STEEL)2通れないはね返る(1 発につき 1 回)
水(みず)たまり(WATER)3通れない上を飛(と)びこえる

この 4 つのちがいが、そのまま作戦になります。

  • 木箱のかげにかくれる → でも撃たれると 2 発でこわれる。一時(いちじ)しのぎ
  • 鉄のかげにかくれる → こわれない。でも相手(あいて)の跳弾(ちょうだん)が回りこんでくる
  • 水たまりのむこうの敵(てき) → 近(ちか)づけないのに、たまは届(とど)く。一方的に撃てる場所

水たまりは「安全(あんぜん)な堀(ほり)」ではありません。たまは平気(へいき)で越(こ)えてきます。

地形は state.map.grid に入っています。grid[y][x] の順で、Y が先です。

def update(state):
grid = state.map.grid
# 自分のすぐ右のマスは何か
gx = state.me.grid_x
gy = state.me.grid_y
right = grid[gy][gx + 1]
if right == 2: # 鉄ブロックだった
return {"drive": "stop", "fire": False}
return {"drive": "forward", "fire": True}

木箱のこわれぐあいは state.map.brick_hp[y][x] で見られます(2 → 1 → 0)。 0 になったマスは平地に変わります。

マップは毎回ちがう。でも公平

Section titled “マップは毎回ちがう。でも公平”

マップは試合ごとに作(つく)りなおされます。木箱や鉄の場所は毎回ちがいます。

ただし、でたらめではありません。「シード」という数字(すうじ)ひとつから作られるので、 同(おな)じシードなら何度(なんど)でも同(おな)じマップができます。 だから「さっきの試合をもう一度」ができます(くわしくは決定論)。

そしてもうひとつ、大事な約束(やくそく)があります。

作(つく)られる割合(わりあい)はこうなっています。

地形割合
平地70%
木箱18%
鉄ブロック7%
水たまり5%

さらに、次(つぎ)の場所はかならず平地になります。

  • スタート地点のまわり 3×3((2,2) と (17,12) のまわり)— 出たとたんに詰(つ)んでいた、を防(ふせ)ぐため
  • まん中の 6 マス — あとで出(で)てくる「サプライ」が落(お)ちてくる場所

そして最後(さいご)に「スタートからスタートまで歩いて行けるか」を確(たし)かめています。 行けなければ、壁(かべ)をひとつずつ消(け)して道(みち)を通(とお)します。 「行けない場所」があるマップは出(で)てきません。

場所最初(さいしょ)の向き
● A(赤(あか)まる)(2.5, 2.5) 左上(ひだりうえ)0 度(右)
■ B(青(あお)四角(しかく))(17.5, 12.5) 右下(みぎした)180 度(左)

色(いろ)だけでなく 形(かたち)でも見分(みわ)けられるようにしてあります(A = ● / B = ■)。 色の見え方は人によってちがうからです。

試合(しあい)の途中(とちゅう)、20 秒(びょう)と 40 秒のときに、まん中 (10.0, 7.5) にサプライが落ちてきます。 0.5 マスまで近(ちか)づくと拾(ひろ)えます。

拾(ひろ)うといいことが 2 つあります。

  • バリアの残(のこ)り回数(かいすう)が 1 増(ふ)える(さいだい 4 回(かい))
  • 10 秒のあいだ、つぎに撃てるまでが 1.2 秒から 0.8 秒に短(みじか)くなる

効果(こうか)が 10 秒で切れるのはわざとです。 先(さき)に取(と)ったほうが一方的(いっぽうてき)に強(つよ)いままにならないようにしてあります。 2 回落ちてくるので、1 回目を取られても逆転(ぎゃくてん)のチャンスがあります。

両方(りょうほう)が同時(どうじ)に届(とど)いたときは、2 人とも取れます。取りあいで喧嘩(けんか)になりません。

終わりが近づくと、戦う場所がせまくなる

Section titled “終わりが近づくと、戦う場所がせまくなる”

残(のこ)り 20 秒(40 秒経過(けいか))から、2.5 秒ごとに 6 回、まわりが鉄の壁に変わっていきます。

最後(さいご)に残(のこ)るのは、まん中の 8 × 3 マスだけです。

最初は20×15マス全体を使えるが、残り20秒からまわりが鉄の壁に変わっていき、最後はまん中の8×3マスだけが安全地帯として残る図

def update(state):
# 縮小がはじまったら、まん中へ向かう
if state.shrink.active:
want = angle_to(state.me.x, state.me.y, 10.0, 7.5)
return {"drive": "forward", "steer": want, "fire": True, "barrier": False}
return {"drive": "forward", "steer": state.me.angle, "fire": True, "barrier": False}

state.shrink には、いまの安全(あんぜん)な範囲(はんい)(min_x / max_x / min_y / max_y)と、 次(つぎ)にせまくなるまでの秒数(びょうすう)(next_in)が入っています。

この仕組(しく)みのおかげで、逃(に)げ回(まわ)って時間(じかん)切れという試合はほぼ起きません。