■ 33日目のまとめ
前回(31〜32日目)は③数値変動フェーズを本実装し、コマンドが勢力の数値へ反映されるようになった。今回はその結果をプレイヤーに見せる「④結果表示フェーズ」の応答処理と、捜索コマンドの完成が中心である。
33日目は2つのセッションに分かれた。前半(その1)は結果フェーズで武将登用のYES/NO判断ができる仕組みの実装と、捜索コマンドの発見→登用→候補図鑑登録の一気通貫。
後半(その2)は大きなリファクタ(ManagerPhaseの分離)と、AIが実際にコマンドを
発行し始める⑦AIコマンド入力フェーズの暫定実装だ。最後にはAI勢力が内政・軍事の
数値を動かし、格段と戦略ゲームらしくなった。
■ 33日目(5/31)その1:結果フェーズの応答処理・捜索本実装
④結果表示フェーズ ― 応答が必要な結果を扱えるようにする
③数値変動の結果を表示するだけなら、テキストを縦に並べればよかった。しかし捜索で
発見した武将の登用可否など、「プレイヤーが判断しなければいけない結果」が存在する。
これをどう扱うかが今回の設計の核だった。
方針は「応答が必要な結果」と「応答が不要な結果」を同じスクロールビューに混在させて縦積みで表示し、前者には判断ボタンを付ける形にした。YESを押すと即座に確定し後から戻せない(武将の登用や解雇は巻き戻しのコストが高いため)。明確なNOボタンは設けず、「閉じる=保留=結果的にNO」として、確認完了ボタンを押したタイミングで未判断を一律NO扱いとした。ボタンを2つに収めるこのルール整理は地味に重要で、UI設計の
方向性がここで固まった。
実装物としては3つの新規クラスと既存パネルの改修になった。
まず ResultPendingDecision は「応答が必要な結果1件」を表すデータクラスで、
種別(登用・外交)と状態(保留・承認・却下)を持つ。YES確定時の処理本体は
持たず、コールバック経由で上位(ManagerMain)へ委譲する。パネルが処理の主体に
なってしまうことを防ぐ設計だ。
次に Panel_ResultConfirm はYES/Cancel 2ボタンの小さな確認パネル。ラベルは
動的に変更でき、パネル自体は日本語か英語かを知らない。呼び出し側が言語解決済みの
文字列を渡す方式にしたことで、将来の多言語追加に際して触る箇所がゼロになる。
そして ResultDecisionInfo が実際に結果一覧の中に混在する「判断ボタン付き部品」
である。ResultSimpleInfo(数値変動を表示するだけの部品)と対になる存在で、同じ
Listに入って縦積みされる。型混在でも動くのはGameObjectで統一しているおかげだ。
捜索(Search)の本実装 ― 発見から図鑑登録まで
③数値変動フェーズ内に、捜索コマンドの処理ブロックを追加した。
発見率は「(知力+魅力)÷200+0.2」で、最大1.0。特技「人脈」があれば+0.2が乗る。
在野武将の抽選は重み付き(重み=10-レアリティ)で、高レアほど出にくい。
以下の4つの特技が発動すると抽選結果が変わる。
- 抜擢:在野の最高レアのみを対象として抽選
- 審美眼:抽選結果のレアリティ+1のテーブルで再抽選(対象不在なら不発)
- 新星発見:確定図鑑にも候補図鑑にも未登録の武将から再抽選(不在なら不発)
- 人脈:発見率に+0.2
特技は重複して持てないため、上記は排他になる(1人の武将が「抜擢かつ審美眼」を
同時に持つことはない)。ただし「人脈持ちの武将が発見率を上げ、別の武将が抽選を
担当する」という組み合わせは設計上ありうる。現在の実装では1コマンド1武将のため
この組み合わせは起きないが、将来の仕様拡張を念頭に分離して書いてある。
発見が確定したら ResultPendingDecision にデータを積み、④で判断パネルを呼ぶ流れに
なる。YESで登用すると在野リストから削除・配下に追加・候補図鑑に登録の3点セットが
走る。候補図鑑へ登録するのは通常武将のみで、カスタム武将はint型IDが意味を持たない
ため対象外としている。
なお同一ターン内の二重発見防止のため、除外セットを全勢力共通で保持し捜索処理に
配布している。フィールドには持たせず揮発(毎ターン生成・破棄)としたのは、ターンをまたいで状態が残るリスクを避けるためだ。
結果パネルに登用ボタンを追加して武将を登用可能にした。

登用により空席が全て埋まった画像。

不具合2件の対応
実装中に不具合が2件、デバッグログによる原因特定→修正の流れで解消した。
1件目は解雇した武将が「前の武将のコマンド入力で復帰する」というもの。原因は
Panel_Commandsが内部に持つ武将リストと、解雇で操作される配下リスト本体の参照が
断絶していたことだ。解雇後にPanel_Commandsを閉じて開き直す方式(毎回配下リスト
基準で再構築)に変えて構造的に解消した。
2件目はより根深かった。「解雇後に別の武将でコマンド入力すると全員が入力済に見える」という現象で、解雇が原因と思って調べたら全く無関係の場所が壊れていた。
Panel_Commands.FindCommandのOfficerId比較が「AのIDかつBのIDの片方が一致する」というOR条件になっており、別人のコマンドに誤マッチしていたのだ。デバッグログを仕込んで「OfficerId=56の武将がOfficerId=33のコマンドにヒット」という実測値を確認してから修正した。IsCustomフラグで通常/カスタムを排他分岐し、通常武将はAND条件で厳密に一致を取るよう書き直して根治している。
■ 33日目(5/31)その2:ManagerPhase分離・AIコマンド入力暫定実装
ManagerPhaseの切り出し ― 大きなリファクタ
ここ数日の実装でManagerMain.csが2143行まで膨らんでいた。「動いているコードを
別の場所に移す」は最もデグレードを引き起こしやすい作業だが、次に控えているA-2
(戦闘計算)を安全に入れるには先に構造を整えておく必要があった。
新規クラスManagerPhaseを同一GameObjectのコンポーネントとして追加し、ターンフェーズ処理を移動した。
設計で一番大事にしたのは「所有権を論理的に正しい場所に置くこと」だ。
当初は「ManagerMainにフィールドを残したままManagerPhaseから同名プロパティで
参照する」方式も検討したが、それはコピーを無改変のままにするための逃げに過ぎない。
フェーズ専用の揮発stateはManagerPhaseが物理的に所有すべきであり、
ManagerMainは自身の領分(UI・マップ・入力)だけを持てばよい。
結果として「UIに触る3メソッドだけManagerMainのpublicメソッドへ委譲し、残り37メソッドは無改変コピー」という形に落ち着いた。デグレードリスクを書き換えた3メソッドに局所化した。TurnPhase enumはGameEnums.csへ移設し、両クラスから無改変参照できるようにしている。
ManagerMain.cs:2143行 → 1077行
ManagerPhase.cs:新規 1529行
一見増えているように見えるが、ManagerMainの行数で考えると実質半減である。
⑦AIコマンド入力フェーズ ― AIが動き始める
Phase_AICommand()はここまで「Phase_EndTurnを呼ぶだけ」というモックだった。
今回、AI行動仕様(暫定PDF)をベースに、実装済みコマンドのみを実発行する暫定方式で本実装した。
実発行するのは「③数値変動フェーズで処理が回るコマンド」に限定している。
- 捜索 / 諜報 / 施し / 徴兵 / 募兵 / 訓練 / 開発
- 褒賞(特1・AIコマンドとは別ループで処理)
出陣・外交・計略・引抜はロジックの骨格だけ作り、発行部分をスキップする。
「本実装時にガードを外すだけで動く」形にしてある。
AIの行動優先度はPDFに定義されている。空き枠があれば捜索(優先1)・同盟締結に
向けた外交(優先2)・諜報力の維持(優先3)、といった順番で、各数値の閾値や確率テーブルに従って判断する。確率カーブと特技序列はstaticテーブルで一元管理し、調整時はテーブルの数値を書き換えるだけにした。
武将の選択ロジックは全優先度で「特技序列>能力値」という同型のため、
PickOfficerBySkillPriorityという共通ヘルパーに集約している。
ループ構造はPDF暫定版に合わせた。優先1/2はループ外の単発(2名以上実行しない
仕様を構造で保証する)。優先3〜10は3周まで通常の確率判定でループし、それでも
未行動武将が残れば4周目は確率100%(ハード条件は維持)で割り当てを試みる。
それでも残った武将はそのターン待機となる。
実装後、プレイヤーもAIも内政しかしない平和な世界ではあるが(笑)、AI勢力の国力・兵数・資金が毎ターン変動するようになり、戦略ゲームとしての体裁が一気に整った。出陣が実装されたときの変化が楽しみである。

上の画像は1年目・夏の状態で下の画像は翌ターンの状態。
資金が20減少し、訓練度が51→72、諜報力が54→85となり、武将の忠誠度が一部上昇しているのが確認できる。AIが内政している。

潜在バグの根治・褒賞計算式の共通化
リファクタのついでに潜在バグを1件根治した。_aiCommandsがどこでもClearされて
おらず、AIがコマンドを積み始めると毎ターン累積する構造だったのだ。これまでは
AIが空だったため無害だったが、今回の実装で顕在化する前に対処した。
また、褒賞の忠誠上昇計算式をGameUtility.CalcRewardLoyaltyGainという純粋関数に抽出した。プレイヤー褒賞(ManagerMain)とAI褒賞(ManagerPhase)の両方から呼ぶことで、計算ロジックの重複をなくしている。
■ 現時点の開発状況
| カテゴリ | 状況 |
|---|---|
| データクラス全般 | ✅ 完了 |
| Scene_Initialize / Title / Start | ✅ 完了 |
| Scene_Main(地図・情報パネル・コマンド入力) | ✅ 完了 |
| Scene_Main(数値変動演出) | ✅ 完了 |
| Scene_Main(フェーズ管理・骨格) | ✅ 完了 |
| Scene_Main(③数値変動フェーズ) | ✅ 本実装 |
| Scene_Main(④結果表示フェーズ ― 応答処理) | ✅ 本実装(武将入替UIは別タスク) |
| Scene_Main(捜索コマンド) | ✅ 発見→登用→候補図鑑登録まで完了 |
| Scene_Main(ManagerPhaseへの分離) | ✅ 完了 |
| Scene_Main(⑦AIコマンド入力) | 🔲 暫定実装(内政・軍事・人事・謀略のみ) |
| Scene_Main(②戦争解決・戦闘計算) | 🔲 未実装 |
| Scene_Main(外交・計略・引抜コマンド) | 🔲 入力UI未実装 |
| Scene_End | 🔲 未着手 |
| コレクション画面・武将登録画面 | ✅ 完成(最終調整は別途) |
■ 次回の作業予定
次の本丸は②戦争解決フェーズ(戦闘計算)である。AIの行動仕様のうち出陣・迎撃・
援軍に関わる部分がこのフェーズを待って詰まっており、ここを突破するとドミノ式に
多くの機能が実装可能になる。
ただし戦闘は「画面・見せ方・演出の設計がまだ」という状態で、ロジックより先に
設計から始まる重いタスクだ。並行して、外交・計略・引抜のコマンド確定パネル(
プレイヤーが入力できる状態にするUI)を先行させるか、次回冒頭で方針を決める。























