駒に移動する以外の行動をとらせる：FEHというか将棋盤で学ぶモデル化とSingle responsibility principle.3

[前回で駒を動かすだけならできました。](https://qiita.com/turanukimaru/items/0fdf586fbcfb9c57f9b1)
動かすだけでは将棋やチェスしか作れないので、今回はこれに移動以外の行動もさせてみます。

ごちゃごちゃしてきたので駒と盤が移動範囲を計算するところは省きます。人からは見えませんし！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151783/91e50b10-a573-64d3-3b38-7214ffc09077.png)

#行動とは何か？

行動とは「対象に対し何かを行う」事です。今のところ盤上には枡と駒しかないので対象は枡かもしれませんし（自分を含む）駒かもしれません。そして一つの枡に一つの駒しか入れないので、枡を対象にする＝駒を対象にするとしていいでしょう。そして枡は必ずどこかの枡であり、座標を使って指定できます。よってできることは

```kotlin

fun 駒.行動(対象 : 座標)
fun 盤.行動(源 : 駒, 対象 : 座標)
```

となります。これらが行える盤と駒をそれぞれ行動盤と行動駒にしましょう。別に盤と駒に直接書き足してもいいのですが今回追加した分として継承関係に分けておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151783/ebcfb431-4b9a-2482-8802-2be99629d24d.png)

##行動には範囲がある。

FEHでは行動には射程距離があります。隣接する枡にしか行動できない近接武器と2枡に届く（隣接する枡には行動できない）遠距離武器の二つです。多くのSLGも同じように射程距離を持っています。ひょっとしたら1固定だったり無限に届いたり逆に自分自身だけかもしれませんがいずれにしろ射程が存在するという事です。
そしていくつかのゲームには射界が存在します。例えば戦車は砲塔の向いている方向にしか撃てません。
…つまり移動範囲を得るのと行動範囲を得るのは実はほぼ同じというわけですね。違いがあるとしたら移動範囲が駒の場所から探索するのに対して行動範囲は駒が移動できる場所から探索することくらいでしょうか？
あとは前回の記事を移動から行動へ書き換えて終わりでもういいかな？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151783/af69fc16-804a-7fe7-bf9d-418a4f892a97.png)


と言いたいところですが、FEHには味方をアシストして位置を変えるという行動があります。例えば体当たりすれば相手を一枡押せますし、ぶちかませば二枡押せます。
逆に相手を押せない（移動先に他のキャラがいる）ときは体当たりできないので行動範囲に入れることができない、つまり向きとか距離ではなく盤面を見て行動可能かを判定する必要ができてしまいます。
駒が盤面を見て判定するのはまぁできなくはありません

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151783/1243b60f-4975-c616-e772-65a02b021bfe.png)


が、「盤面で相手の向こう側の枡が空いてるか」はどの駒にとっても変わらない、駒に依存しない情報です。つまりこれは侵入状況にあるべき情報です。


侵入状況は盤への参照を持ち、関数が実行されたら盤を見て対象の前後＝盤の一部を返します。駒は返された盤面の一部を判定に使えばいいわけですね。
同じように「再帰させるのめんどくさいから距離が射程内ならいい」ときは現在地から対象への距離を測る関数とか、盤面と対象の枡に依存する関数はここに作ってしまっていいでしょう。ゲームによっては、例えばタクティクスオウガのように高さの概念が加わり、途中に十分な高さの障害物があった場合それにあたるなんてケースも出てきます。これらは侵入状況から一意に出力されるので、やはりSRPには反しません。

##行動した結果どうなるか？

駒が行動した結果、駒が動くなら単に動かせばいい（駒が動かせるか？は行動できるかを判定済みなので問題ないはずですよね？）のですが、FEHとかほとんどのSLGは駒にダメージを与えHPが減ったりステータスが変化したりします。行動の結果として変わるものなので行動駒が持つ分には不自然ではないでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151783/724e1c08-595e-ec50-62da-a4f8d09145f9.png)


駒から見た場合ではHPとかのステータスから能力への線はなくてもいいのですが、戦闘する際にはキャラクターのステータスと能力のセットを使う事になるので結局この形になります。FEHの戦闘モデルはもうできていますのでこれをそのまま使います。
つまり、行動＝キャラクターが対象に戦闘を仕掛け、その結果としてのキャラクターを行動駒からのキャラクターと置き換えることで行動結果を反映できます。

ただ、キャラクターへの問い合わせや戦闘結果での置き換えはゲームに依存するので「盤と駒の関係」内には収まりません。そろそろ行動駒を「そのゲームのルールを体現する行動駒」にしたほうがいいでしょう。
行動駒を行動盤との関係性のみから存在する（のでゲームのルールを含まない）抽象的な行動駒と、ゲームのルールを含む具体的な行動駒に分離します。
これにより、ゲームのルールを含まない盤と駒だけの関係性は「移動サブドメイン」として完全に隔離され、ゲームに依存しない形で存在することになります。ゲームのルールを含まないのでモデルは他のゲームにも再利用可能となり、一般的にライブラリと呼ばれるものになるでしょう。
また、キャラクターの能力や戦闘モデルは移動から完全に切り離され戦闘サブドメインとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151783/5ea0a873-c47f-d63f-5921-9e63a99e8fda.png)

戦闘ドメインモデルは盤とは関係なく駆動します。例えば戦闘はスパロボのようにユニットが攻撃しあっても良いし、ガチャポン戦士みたいにアクションゲームになってもいい、どちらにしろ駒を動かすのとは別にゲームとしてデザインすることができる、という事です。
他にも「ゲームエンジン・アーキテクチャ」という本によるとゲーム制作の際には戦闘結果はシミュレータを用意してバランスを取ると良いそうです。リソースの管理を楽しむゲームの多くは開発者がデータを網羅したExcelを持っていて、続編を作るときの試算に使っているなんてのもよく聞く話です。。FEHでも実際の制作体制は知りませんが戦闘結果シミュレータを作ることでキャラの強弱が解ったりとかその場に最適な編成や装備などの検討に使えます。

##戦闘サブドメインがあるという事は戦術サブドメインもあるのでしょうか？

私は戦争に関しては素人ですが、[戦術とは移動であり空間リソースと時間リソースを有効に活用することで戦争での勝利を目指すものだそうです。](https://news.denfaminicogamer.jp/interview/170922)つまり、そのゲームにおける地形や行動駒が戦術サブドメインとなるわけですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151783/f267783a-658c-e6be-7cfa-e26a85e4060e.png)

こうやって分けてみると、戦術と戦闘が完全に分かれていることがわかるかと思います。実のところ戦術というのは陣取りゲームなわけですね。実際のゲームでも戦術画面と戦闘画面が違ったり別のルールが支配してることは多々ありますよね？
現在の図では移動モデルが大きいため邪魔ですが、移動モデルは「将棋盤上で駒を動かすメカニズムを実現しているけどゲームのルールには依存していない」ため次からは省略や別に記載ができるようになります。戦術サブドメイン…つまり陣取りゲームとしてどうデザインするか？を検討する際には「駒を動かす」という必要はありますが「駒を動かすとはどういうことか」に言及する必要は既に無い、ということです。将棋盤サブドメインとしてモデル化できる、と言ってもいいかもしれませんしこれはゲームデザインの土台として使えますがゲームには依存しない、つまりライブラリにすることもできます。
これら操作をドメインとして切り離すことで、地形やそのゲームでの駒の動きやキャラクターの強さや硬派SLGなら現実の兵器のデータ化に集中できるでしょう。まぁそこから先はゲームデザインの話なのでここでは扱いませんが。

##さて、これで盤上に駒を「置く／除く」ことと「動かす」ことと「駒同士で行動させる」ことができるようになりました

これがボードゲームならこれで終了です。盤なり適当な紙に枡を描くなりして駒なりフィギュアなりを並べて戦わせりゃいいわけですね。私も子供のころにはゲームが買ってもらえなかったためよく自分で作ったものです。もちろん子供のやることですからルールやバランスは壊滅的なわけですが。

実際にこの盤をゲームに使う事もできますが、駒を置ける場所以外に置こうとすると例外が発生するようなちょっと使いにくい盤になります。
また、ユーザの振る舞いがモデル化されていないため、このモデルを扱う指針みたいなものがないため人によって使い方が違ってきます。
人によって使い方が違うのはある意味当然ではあるのですが、想定外の使い方をされては後々変更しにくくなってしまいます。
そこで盤を扱うユースケースを作ってみましょう。ユースケースを想定することでそれに適したモデルに修正できるかもしれませんし。