町という単位を持たせたら、AIが離れた土地を開拓しはじめた

3つの要望と1つの不具合が、同じ土台の欠落に集約されていた。

日本進化シミュレーション第13回 / 全16回目次

「町がある程度育ったら、少し距離を置いて次の町を開拓してほしい」
「町どうしに、流通という概念を持たせてほしい」
「近代以降は、町が都市へ育ってほしい」

要望は3つあったけれど、コードを眺めながら僕は気づいたことがあった。
このゲームには、そもそも「町」という単位そのものが存在していなかった。
地図全体がひとつながりの土地として扱われているだけで、どこからどこまでが一つの町なのか、システムのどこにも答えが無い。

「無作為に建設し始める」の正体も、同じ穴だった

実はもう一つ、別に報告されていた不具合があった。
「開発がある程度進むと、無作為にあちこちへ何かを建て始める」というものだ。

調べてみると、これは既存のAIロジックの中に、道の延伸先が見つからない時の保険として仕込まれていた処理だった。
地図全国から、実在都市の重みだけを頼りに空き地を選ぶ。
距離の制約が一切ないので、今いる町から遠く離れた、別の実在都市の重みが高い場所へ、ぽつんと1軒だけ配置されてしまう。

「離れた場所に新しい芽を作る」という動きそのものは、要望していた新規開拓と本質的に同じだった。
偶発的な事故として起きていたものを、意図的で制御されたものに作り替えればいい。
3つの要望と1つの不具合が、同じ土台の欠落に集約されることが見えてきた。

町という単位を、道路のつながりから作る

新しく作ったのは「町」というデータそのものではなく、それを毎回その場で計算し直す仕組みだった。

道路のセルを4方向でたどって、つながっている一塊をひとつの町とみなす。
セーブはしない。道路の並びさえあれば、いつでも同じ結果を再計算できるからだ。

実はこの少し前、施設の種類を増やす作業で、配列の並びを変えただけでセーブデータの街が別物になるという事故を起こしていた。
その反省があったので、今回は最初から「セーブしない、揮発性の派生データ」という設計方針を崩さないと決めていた。

町ができたことで、他の要望も自然に解けた

町という単位ができると、残りの要望はその上に積み上げるだけで済んだ。

新しい町を興す条件は、今ある全部の町がある程度育っていること。
1つでも育っていればいい、という緩い条件にすると、行き詰まるたびに次々と新天地に種をまいてしまい、作りかけの町が放置されて拡散する。
全部揃うまで待つ、という厳しめの条件にして初めて、狙った通りの落ち着いたペースになった。

町どうしをまたぐ輸送には、収入の割り増しを付けた。
「明治以降に育った町は都市へ」という条件も、町を判定する関数の中に組み込んだので、それより前の時代には絶対に都市が生まれない。

チューニングで一番苦労したのは、間引きの頻度だった

町の再計算は、地図全体を毎回なめる処理なので、頻度を間引きたくなる。
最初は「前回の計算から3秒経ったら」という実時間の間引きを入れた。

これが、ゲームの倍速機能とぶつかった。
30倍速で遊ぶと、AIは3秒の間に何十手も判断を下す。
その間、町の情報は3秒前のまま古くなり続け、「まだ町が無い」という誤った判断のまま、AIが地図中に種をまき散らした。

実時間で間引くのをやめて、何か変化があった時だけ再計算する方式に切り替えた。
これで全マスを走査しても1ミリ秒もかからず、倍速がどれだけ上がっても情報が古くなることはなくなった。
「時間で間引く」と「倍速機能」は、相性が悪いという教訓を、ここでもう一つ持ち帰った。

スタンプラリーに挑戦する 行った場所・気になる場所は、現地チェックインでスタンプに残せます。 みんなのコースを見てみる 会員が作ったスポット巡りのコースを都道府県から探せます。自分だけのコースも作れます。 運営者の個人noteも書いています AI活用やサイト運営で気づいたことを、もう少し個人の視点で掘り下げています。

※運営者が個人で書いているnoteです。

技術ブログ一覧へ戻る