コンテンツにスキップ

フィールドと地形

エンジンの担当 この章は、フィールドの決まりです。地形・サプライ・縮小エリアは、エンジンが自動で起こします。あなたの 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)が入っています。

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