コンテンツにスキップ

state リファレンス

あなたの担当 state読むだけです。書き換えても、ゲームには何も起きません。

update(state)state に、その瞬間の試合のすべてが入っています。 このページはその全項目です。困ったときに引くための表として書いてあります。

項目単位説明
state.tick思考した回数。0〜599
state.frameフレーム経過フレーム。0〜3599(60 フレーム = 1 秒)
state.time_left残り時間。60.0 から減っていく

tickframe の関係は frame = tick * 6 です。 思考は 6 フレームに 1 回だからです。

項目単位説明
grid_x / grid_yマス(整数)いるマスの番号
x / yマス(実数)正確な位置
vx / vyマス/フレーム速度。秒に直すには 60 倍
angle0〜359.99。0 = 右、時計回り
hp3 から減る。0 で負け
barrier_countバリアの残り回数
barrier_active真偽いまバリアを張っているか
barrier_leftバリアが切れるまで
barrier_cooldown次にバリアを使えるまで。0 なら使える
can_fire真偽いま撃てるか
reload_left次に撃てるまで
supply_boost_leftサプライの効果が切れるまで

自分とほぼ同じですが、見えるものが少し減ります。

項目単位説明
grid_x / grid_yマス(整数)いるマスの番号
x / yマス(実数)正確な位置
vx / vyマス/フレーム速度
angle向き
hp残り HP
barrier_countバリアの残り回数
barrier_active真偽いまバリアを張っているか
can_fire真偽相手がいま撃てるか
reload_left相手が次に撃てるまで
visible真偽いまはつねに True

barrier_leftbarrier_cooldownsupply_boost_left入っていません。 「相手のバリアがあと何秒で切れるか」までは分からない、ということです。

can_firereload_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}
項目説明
width / height2015(固定)
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 回はね返ったか

bouncedTrue の弾は、次に鉄へ触れると消えます。 そして 自分にも当たります跳弾のしくみ)。

state.incoming_missiles — 飛んでくる弾

Section titled “state.incoming_missiles — 飛んでくる弾”

自分に向かってくる弾のリストです。ここには 2 つの保証があります。

項目単位説明
x / yマス弾の位置
vx / vyマス/フレーム弾の速度
distanceマス自分との距離
eta自分にいちばん近づくまでの推定時間
bounced真偽はね返ったあとの弾か

対象になるのは相手の弾と、はね返ったあとの自分の弾です。 自分が撃ったばかりの弾は入りません。

項目単位説明
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}
項目単位説明
active真偽いま落ちているか
x / yマス位置。つねに (10.0, 7.5)
next_spawn_in次に落ちてくるまで

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() を使ってください。 理由は決定論にあります。

state は毎 tick 新しく作り直されます。

state.me.hp = 99 # 何も起きません

エラーにはなりませんが、エンジンには一切影響しません。 次の tick では元の値に戻っています。