組み込みの道具
あなたの担当 bot から呼んで使う道具です。計算そのものはエンジンと同じ実装が引き受けます。
import は要りません。update の中で、いつでも使えます。
(import は、math も含めて書けません。math は、最初から使えます)
| 関数 | 返すもの | 使いどころ |
|---|---|---|
angle_to(ax, ay, bx, by) | 度(0〜359.99) | a から b を向く角度 |
distance(ax, ay, bx, by) | マス | 2 点の距離 |
angle_diff(a, b) | 度(−180〜180) | 2 つの向きの差(最短の回りかた) |
line_of_sight(grid, ax, ay, bx, by) | 真偽 | 2 点のあいだに壁がないか |
find_path_bfs(grid, start, goal) | マスのリスト | 最短経路(行けなければ []) |
find_path_astar(grid, start, goal) | マスのリスト | 同じ。A* 版 |
predict_lead(enemy, 弾の速さ, 自分x, 自分y) | (x, y) | 動く敵に当てる狙い点 |
clamp(v, lo, hi) | 数 | 値を範囲におさめる |
stable_sort(リスト, key=関数) | リスト | 順序が安定した並べかえ |
rand() / randint(a, b) / choice(リスト) | 数・要素 | 乱数(試合ごとに同じ目が出る) |
print(...) | — | 実行ログに出す(対戦画面の下に出る) |
座標はマスで、画面の左上が (0, 0) です。下に行くほど y が大きくなります。
angle_to — そこへ向かう角度
Section titled “angle_to — そこへ向かう角度”want = angle_to(state.me.x, state.me.y, state.enemy.x, state.enemy.y)自分から敵を向く角度が、0〜359.99 の度で返ります。0 が右で、時計回りに増えます。
steer に、そのまま入れられます。
distance — 距離
Section titled “distance — 距離”d = distance(state.me.x, state.me.y, state.enemy.x, state.enemy.y)マス単位の距離です。「近づく」「離れる」の判断に使います。
angle_diff — 向きの差
Section titled “angle_diff — 向きの差”diff = angle_diff(want, state.me.angle) # want - me.angle を、-180〜180 に収める「あと何度まわればいいか」が分かります。正なら時計回り、負なら反時計回りです。
abs(diff) < 5 なら「ほぼ向きが合っている」と言えます。
want - me.angle をそのまま引き算してはいけません。 350 度と 10 度の差は 20 度ですが、引き算すると 340 になります。
line_of_sight — 壁ごしに見えるか
Section titled “line_of_sight — 壁ごしに見えるか”見える = line_of_sight(state.map.grid, me.x, me.y, en.x, en.y)あいだに壁(木箱・鉄)がなければ True です。水たまりは、弾が上を通るので、視線をさえぎりません。
くわしい計算は 視線判定と DDA にあります。
find_path_bfs / find_path_astar — 道さがし
Section titled “find_path_bfs / find_path_astar — 道さがし”path = find_path_bfs(state.map.grid, (me.grid_x, me.grid_y), (en.grid_x, en.grid_y))スタートとゴールはマスの番号 (x, y) で渡します。返るのは、通るマスの番号のリストです。
path[0] は、いま自分がいるマスなので、進むべきは path[1] です。行けないときは [] です。
重い道具です。 広げたマスの数だけ、命令数が使われます。毎回探し直さず、覚えておきましょう。 → 経路探索と計算量
predict_lead — 動く敵に当てる
Section titled “predict_lead — 動く敵に当てる”tx, ty = predict_lead(state.enemy, 8.0, state.me.x, state.me.y)want = angle_to(state.me.x, state.me.y, tx, ty)弾が届くころに敵がいる場所 (tx, ty) を返します。まっすぐ進む敵なら、そこを向いて撃てば当たります。 向きを変えつづける敵には、効かないことがあります(動く敵に当てる)。
当てられない場合は、敵のいまの位置が返ります。
中身の計算は 偏差射撃 にあります。
rand() # 0.0 以上 1.0 未満randint(1, 6) # 1 以上 6 以下の整数choice(["a", "b", "c"])random モジュールは使えません。同じ試合なら、同じ目が出ます。 試合を再生し直しても、同じ結果になるためです。
理由は 決定論と固定小数点 にあります。
print — 中を見る
Section titled “print — 中を見る”print("いまの距離", distance(state.me.x, state.me.y, state.enemy.x, state.enemy.y))対戦画面の下の実行ログに出ます。値がおかしいときに、確かめるのに使います。