state リファレンス
あなたの担当 state は読むだけです。書き換えても、ゲームには何も起きません。
update(state) の state に、その瞬間の試合のすべてが入っています。
このページはその全項目です。困ったときに引くための表として書いてあります。
いちばん外側
Section titled “いちばん外側”| 項目 | 単位 | 説明 |
|---|---|---|
state.tick | 回 | 思考した回数。0〜599 |
state.frame | フレーム | 経過フレーム。0〜3599(60 フレーム = 1 秒) |
state.time_left | 秒 | 残り時間。60.0 から減っていく |
tick と frame の関係は frame = tick * 6 です。
思考は 6 フレームに 1 回だからです。
state.me — 自分
Section titled “state.me — 自分”| 項目 | 単位 | 説明 |
|---|---|---|
grid_x / grid_y | マス(整数) | いるマスの番号 |
x / y | マス(実数) | 正確な位置 |
vx / vy | マス/フレーム | 速度。秒に直すには 60 倍 |
angle | 度 | 0〜359.99。0 = 右、時計回り |
hp | — | 3 から減る。0 で負け |
barrier_count | 回 | バリアの残り回数 |
barrier_active | 真偽 | いまバリアを張っているか |
barrier_left | 秒 | バリアが切れるまで |
barrier_cooldown | 秒 | 次にバリアを使えるまで。0 なら使える |
can_fire | 真偽 | いま撃てるか |
reload_left | 秒 | 次に撃てるまで |
supply_boost_left | 秒 | サプライの効果が切れるまで |
state.enemy — 相手
Section titled “state.enemy — 相手”自分とほぼ同じですが、見えるものが少し減ります。
| 項目 | 単位 | 説明 |
|---|---|---|
grid_x / grid_y | マス(整数) | いるマスの番号 |
x / y | マス(実数) | 正確な位置 |
vx / vy | マス/フレーム | 速度 |
angle | 度 | 向き |
hp | — | 残り HP |
barrier_count | 回 | バリアの残り回数 |
barrier_active | 真偽 | いまバリアを張っているか |
can_fire | 真偽 | 相手がいま撃てるか |
reload_left | 秒 | 相手が次に撃てるまで |
visible | 真偽 | いまはつねに True |
barrier_left と barrier_cooldown と supply_boost_left は入っていません。
「相手のバリアがあと何秒で切れるか」までは分からない、ということです。
can_fire と reload_left は、実は強い情報です。
相手が撃てない 1.2 秒のあいだは、安全に近づけます。
def update(state): want = angle_to(state.me.x, state.me.y, state.enemy.x, state.enemy.y)
if state.enemy.can_fire: # 撃たれる。止まって狙うだけにする return {"drive": "stop", "steer": want, "fire": True, "barrier": False}
# いまは撃たれない。踏みこむ return {"drive": "forward", "steer": want, "fire": True, "barrier": False}state.map — 地形
Section titled “state.map — 地形”| 項目 | 説明 |
|---|---|
width / height | 20 と 15(固定) |
grid[y][x] | 0 = 平地 / 1 = 木箱 / 2 = 鉄 / 3 = 水 |
brick_hp[y][x] | 木箱の残り耐久 0〜2 |
grid[y][x] です。grid[x][y] ではありません。 Y が先です。
state.my_missiles — 自分が撃った弾
Section titled “state.my_missiles — 自分が撃った弾”リストです。空のこともあります。
| 項目 | 単位 | 説明 |
|---|---|---|
x / y | マス | 弾の位置 |
vx / vy | マス/フレーム | 弾の速度 |
bounced | 真偽 | もう 1 回はね返ったか |
bounced が True の弾は、次に鉄へ触れると消えます。
そして 自分にも当たります(跳弾のしくみ)。
state.incoming_missiles — 飛んでくる弾
Section titled “state.incoming_missiles — 飛んでくる弾”自分に向かってくる弾のリストです。ここには 2 つの保証があります。
| 項目 | 単位 | 説明 |
|---|---|---|
x / y | マス | 弾の位置 |
vx / vy | マス/フレーム | 弾の速度 |
distance | マス | 自分との距離 |
eta | 秒 | 自分にいちばん近づくまでの推定時間 |
bounced | 真偽 | はね返ったあとの弾か |
対象になるのは相手の弾と、はね返ったあとの自分の弾です。 自分が撃ったばかりの弾は入りません。
state.shrink — 縮小エリア
Section titled “state.shrink — 縮小エリア”| 項目 | 単位 | 説明 |
|---|---|---|
active | 真偽 | 縮小が始まっているか |
min_x / max_x | マス | 安全な範囲(X) |
min_y / max_y | マス | 安全な範囲(Y) |
next_in | 秒 | 次にせまくなるまで |
範囲の外に立っていると、次の縮小で即死します。
active になったら中心へ戻る処理を、必ず入れておいてください。
def update(state): s = state.shrink はみ出している = ( state.me.grid_x < s.min_x or state.me.grid_x > s.max_x or state.me.grid_y < s.min_y or state.me.grid_y > s.max_y )
if s.active and はみ出している: # 安全な範囲の中心へ cx = (s.min_x + s.max_x) / 2.0 cy = (s.min_y + s.max_y) / 2.0 want = angle_to(state.me.x, state.me.y, cx, cy) return {"drive": "forward", "steer": want, "fire": False, "barrier": False}
want = angle_to(state.me.x, state.me.y, state.enemy.x, state.enemy.y) return {"drive": "forward", "steer": want, "fire": True, "barrier": False}state.supply — 中央サプライ
Section titled “state.supply — 中央サプライ”| 項目 | 単位 | 説明 |
|---|---|---|
active | 真偽 | いま落ちているか |
x / y | マス | 位置。つねに (10.0, 7.5) |
next_spawn_in | 秒 | 次に落ちてくるまで |
組み込みの道具
Section titled “組み込みの道具”state ではありませんが、いつでも使えます。
# 幾何angle_to(ax, ay, bx, by) # → 度(0〜359.99)distance(ax, ay, bx, by) # → マスangle_diff(a, b) # → a - b を -180〜180 に収めたものline_of_sight(grid, ax, ay, bx, by) # → 真偽
# 経路探索find_path_bfs(grid, start, goal) # → [(x, y), ...]。行けなければ []find_path_astar(grid, start, goal) # → 同上
# 補助predict_lead(enemy, missile_speed, from_x, from_y) # → (x, y) 偏差射撃の狙点clamp(v, lo, hi)stable_sort(seq, key=None)
# 乱数(試合ごとにシード固定。同じ試合なら同じ目が出る)rand() # → 0.0 以上 1.0 未満randint(a, b) # → a 以上 b 以下の整数choice(seq)
# math は import なしで使えますmath.sqrt(2.0)math.atan2(dy, dx)random モジュールは使えません。上の rand() を使ってください。
理由は決定論にあります。
書き換えても意味がない
Section titled “書き換えても意味がない”state は毎 tick 新しく作り直されます。
state.me.hp = 99 # 何も起きませんエラーにはなりませんが、エンジンには一切影響しません。 次の tick では元の値に戻っています。
- 書ける構文の範囲 → Sub-Python の構文
vxを使った計算の実例 → 偏差射撃- なぜ並び順が「仕様」なのか → 決定論と固定小数点