動作確認はこちらからどうぞ。

今回は戦闘に関する処理を実装します。

Turnメソッドのなかで城の状態に応じて処理をするわけですが、クラスをつかって処理をします。たとえば

どこからも攻め込まれていないプレイヤーの城
PlayerCastleIfNormalクラス

攻め込まれようとしているプレイヤーの城
PlayerCastleIfAttackingクラス

包囲されているプレイヤーの城
PlayerCastleIfSiegingクラス

プレイヤーに攻め込まれようとしている敵の城
EnemyCastleIfPlayerAttackingクラス

プレイヤーに包囲されている敵の城
EnemyCastleIfPlayerSiegingクラス

別の敵に攻め込まれようとしている敵の城
EnemyCastleIfOtherEnemyAttackingクラス

別の敵に包囲されている敵の城
EnemyCastleIfOtherEnemySiegingクラス

どこからも攻め込まれていない敵の城
EnemyCastleIfNormalクラス

クラスをわけないとIndexクラスが大きくなってしまうので城の挙動にかんする処理はわけました。

8個のクラスを作成したわけですが、共通しておこなわれる処理があります。そこでCastleBaseというクラスを作成して、これを継承して8個のクラスを作成します。

基底クラス CastleBase

ではCastleBaseクラスを示します。

まずフィールド変数だけ示します。コンストラクタ内でこの城を攻撃しようとしている軍団、この城を包囲している軍団、この城を支援しようとしている軍団(援軍)に関する情報をセットしてしまいます。

bool型のatCanReturn、sgCanReturn、spCanReturnは出兵元の城に戻ることができるかどうかを示すものです。出兵したものの他の敵に攻め込まれて占領されたり、包囲されているのであればその城に戻ることはできません。

城内に強行突入する場合を除くと兵が半数に減ったときに退却するのですが、出兵元の城に戻れない場合は全滅するまで戦うことになります。

CastleBaseクラスのコンストラクタを示します。

それから城が攻め込まれている状態であれば、守りの兵がいない城は占領されるし、それ以外の場合は強行突入、反撃、兵糧攻めがおこなわれるので、そのためのメソッドもここで定義してしまいましょう。

OccupyIfNoDefenseSoldiersメソッドは、守りの兵がいるかどうか調べていない場合は進軍してきた敵に城を占領されるという処理をおこなっています。占領の処理がおこなわれたら攻め方の兵と兵糧を入城させ、城主を交代してtrueを返します。そうでない場合はなにも処理はおこなわれずfalseが返します。

Siegeメソッドは兵糧攻めをおこないます。包囲されている側は兵の2倍の兵糧を消費します。兵がたくさんいる状態で包囲されると不利になります。兵糧がなくなったら落城で、城主は交代です。

先に城を包囲している側の兵糧がなくなることも考えられます。その場合は進軍の拠点になった城に退却しますが、ほかの敵に包囲されていると退却できません。その場合は城攻め側はその場で全滅とします。

兵糧攻めは1ターンでは決着しない場合があります。・・・といっても兵糧攻めで落城する場合は城側が反撃をするし、城側に十分な兵糧があり兵糧攻めで落城する見込みがない場合は強行突入するので、敵同士の包囲戦で兵糧がなくなるということは実はありません。

ForcedRushメソッドは強行突入です。強行突入の場合、城側のほうが2倍有利なのですが、兵糧攻めが通用しない場合は強行突入するしかありません。

強行突入は攻め方と城側のどちらか一方が全滅するまでおこなわれます。攻め方が勝ったら生き残った兵と兵糧を城にいれます。城側が撃退したら攻め方が持っていた兵糧も城側のものになります。

城側が兵糧攻めに耐えられない場合は無理な戦いであっても反撃する以外ありません。「座して死を待つ」はありえません。この処理をおこなうのがCounterattackメソッドです。引数は城側が反撃のために動員する軍団です。

どちらか一方の兵数が半分になるまで続けます。勝った側は相手の兵糧を奪うことができます。城側が勝利した場合は兵糧攻めは失敗で、攻め方は退却します。しかし攻め方が退却できる城がない場合は全滅するまで戦います。

また兵糧攻めが始まる前であってもこの処理が実行される場合があります。基本的に同じ処理がおこなわれます。この場合は城側が負けると城は包囲され、兵糧攻めが開始されます。

CombatForSupportメソッドは包囲されている城に援軍がかけつけ戦闘になったときの処理をおこないます。このメソッドの戻り値は生き残った援軍側の兵数です。戻り値が0なら援軍側の作戦失敗です。

この処理もどちらか一方の兵数が半分になるまで続けます。そして勝った側は相手の兵糧を奪うことができます。援軍側が勝利した場合は兵糧攻めは失敗で、攻め方は退却します。しかし攻め方が退却できる城がない場合は全滅するまで戦います。援軍側も出撃した城に戻れなくなっている場合があります。この場合は全滅するまで戦います。

GetEnemyCastlesメソッドは引数でわたされた城に隣接する敵の城のリストを返します。これは自分のターンになったときに進軍の選択肢を表示するときや敵の行動アルゴリズムを考えるときに必要です。

GetFriendlyCastlesメソッドはは引数でわたされた城に隣接する味方の城のリストを返します。

CastleOccupiedメソッドは城を占領されたときに呼び出されます。その城を出撃拠点にしていた場合、CastleStatus.AttackingCorps.BaseCastle、CastleStatus.SiegingCorps.BaseCastle、CastleStatus.SupportCorps.BaseCastleにnullが代入されるため、ここから出撃した軍団はその城に戻れなくなります。

引数はその城の元の所有者です。

引数で指定した武将が滅亡したかどうかを調べるメソッドです。所有するすべての城を失い、どこにも攻め込んでいない、包囲もしていないのであれば完全に滅亡したといえます。

プレイヤーが城を奪い取ったときや突入してきた敵の軍団を壊滅させたとき、これによって敵は滅亡しているかもしれません。またすべての敵を滅亡させれば天下統一が実現したことになります。

CheckGameClearIfEnemyRuinメソッドは引数の武将が滅亡したかどうかを調べるとともにゲームクリアのときはその表示の処理もおこなっています。

敵に城を奪われたときや突入して全滅したとき、プレイヤーは滅亡しているかもしれません。CheckGameOverIfRuinメソッドはプレイヤーが滅亡してしまったかを調べてその場合はゲームオーバー表示の処理もおこなっています。

以下はゲームクリアとゲームオーバーを判定するためのメソッドです。