
マイケル
みなさんこんにちは!
マイケルです!
マイケルです!

エレキベア
こんにちクマ〜〜

マイケル
突然だけど題名にもある通り、
今日からはしばらくオセロAIの開発を進めていくよ!
今日からはしばらくオセロAIの開発を進めていくよ!

エレキベア
オセロクマか〜〜〜
単純だからAI作成入門によさそうクマね
単純だからAI作成入門によさそうクマね

マイケル
まさしくAI作成の方に集中できそうだよね!
とりあえず今回は準備としてオセロゲームの基盤を作ったから
実装した内容について簡単に紹介していくよ!
とりあえず今回は準備としてオセロゲームの基盤を作ったから
実装した内容について簡単に紹介していくよ!

エレキベア
これは中々ちゃんとしてるクマね

マイケル
それと今回はランダムに石を置くAIまでしか作成していないけど、
次回以降、下記のような有名なアルゴリズムもいくつか実装する予定だよ!
次回以降、下記のような有名なアルゴリズムもいくつか実装する予定だよ!
- MiniMax法
- モンテカルロ法
- 何らかの機械学習手法

エレキベア
なんか聞いたことはあるクマね
楽しみクマ〜〜〜
楽しみクマ〜〜〜

マイケル
そして強いAIを作るだけじゃつまらないので、上記アルゴリズムをミックスしながら
キャラクターと実際に対戦しているような仕組みも作ってみようと思っています。
作ったゲームは公開するまでを目標に頑張ってみます!
キャラクターと実際に対戦しているような仕組みも作ってみようと思っています。
作ったゲームは公開するまでを目標に頑張ってみます!

エレキベア
エレキベアも是非参戦させてほしいクマ〜〜〜
ゲーム全体構成

マイケル
それでは全体の構成を見ていきます!
GitHubにも上げていますが、アセットをいくつも使用しているため
今回はソースコードのみ公開としています。
参考程度にお使いください!
GitHubにも上げていますが、アセットをいくつも使用しているため
今回はソースコードのみ公開としています。
参考程度にお使いください!
GitHub – masarito617/unity-reversi-game-scripts

エレキベア
ライセンス周りが面倒くさいクマからね
検証環境

マイケル
検証環境は下記の通り!
[Unityバージョン]
2021.3.1f1 LTS
[使用パッケージ]
・UniRx
・UniTask
・VContainer
・DOTween
・Japanese School Classroom

エレキベア
UniRx、VContainerと流行りのアセットが盛り沢山クマね

マイケル
簡単なゲームだし練習がてら使ってみようと思ってね!
それとJapanese School Classroomは有料のアセットだけど、クオリティの高い教室が手に入って汎用性も高いからおすすめです!!
それとJapanese School Classroomは有料のアセットだけど、クオリティの高い教室が手に入って汎用性も高いからおすすめです!!

エレキベア
何か前も使ってたクマね

マイケル
たくさん使わせていただいてます!
スクリプト構成

マイケル
各クラス、パッケージの関係性としてはざっくりと下記のようになっています!
VContainerやUniRxを使用した構成で、DIコンテナからクラスを注入したり、UI側からManagersの状態を監視して更新するようにしています。
VContainerやUniRxを使用した構成で、DIコンテナからクラスを注入したり、UI側からManagersの状態を監視して更新するようにしています。
パッケージ | 役割 |
LifeTimeScopes | クラスの注入やエントリーポイントの指定 |
EntryPoints | 全体の処理のエントリーポイント |
Managers | ゲーム全体やプレイヤー、石といったオブジェクトの管理 |
UIs | UIの表示 |
Players | プレイヤーとAIに関連する処理 |
Stones | 石と関連する処理 |

マイケル
まだまだ甘いところはあるかと思いますが、
下記書籍のUniRx、Zenjectの章や、とりすーぷさんのコードを参考にさせていただきました!いつも勉強させていただいてます!
下記書籍のUniRx、Zenjectの章や、とりすーぷさんのコードを参考にさせていただきました!いつも勉強させていただいてます!
Unityゲーム プログラミング・バイブル 2nd Generation
参考記事:
グローバルゲームジャムでクラス設計をやった話2020

エレキベア
UniRx、UniTaskの書籍を出した方クマね

マイケル
LifeTimeScope、EntryPointのコードは下記のようになっています。
この辺りの詳細について知りたい方は、VContainerの公式チュートリアルをご参照ください!
この辺りの詳細について知りたい方は、VContainerの公式チュートリアルをご参照ください!
公式チュートリアル:
Hello World | VContainer
↑依存関係、エントリーポイントの定義
↑用意されたインターフェースを使用することでUnityEngineを使わずにライフサイクルを定義できる

エレキベア
これがいわゆるDIコンテナというやつクマね

マイケル
そしてUI(Presenter)からの監視は下記のようになっています。
Managerクラス側にReactivePropertyを定義してその状態を監視するシンプルな構成です。
Managerクラス側にReactivePropertyを定義してその状態を監視するシンプルな構成です。
↑ReactivePropertyの定義
↑Presenter側で状態を監視してUIを更新する

エレキベア
Manager側からUIを全く気にせずに済むのは気持ちいいクマね
オブジェクト構成

マイケル
次はオブジェクトの構成についてです。
シーン内は下記のようになっていて、LifeTimeScope、Presenter、Canvasのオブジェクトを用意してそれぞれアタッチしています。
また、ボードに関しては土台のみ先に置いています。
シーン内は下記のようになっていて、LifeTimeScope、Presenter、Canvasのオブジェクトを用意してそれぞれアタッチしています。
また、ボードに関しては土台のみ先に置いています。

マイケル
ボードの上のセル(マス)については、下記のようにPrefabを用意してスクリプト内で生成しています。
↑セルの生成

マイケル
オセロの石についてもPrefabを用意してスクリプトから生成するようにしています。
置ける場合にフォーカスするエリアについても、Prefab内に含めています。
置ける場合にフォーカスするエリアについても、Prefab内に含めています。
↑石の生成処理

マイケル
そして、Managerクラスにはメンバ変数として
ボードに対する石の状態配列と、
表示用のオブジェクト配列を持たせています。
状態配列を変更した後に別途表示の更新を行う構成としました。
ボードに対する石の状態配列と、
表示用のオブジェクト配列を持たせています。
状態配列を変更した後に別途表示の更新を行う構成としました。
↑状態配列と表示用の配列
↑石の状態

エレキベア
最後に表示を更新することで見た目上の遅延を少なくしているクマね

マイケル
変更後の状態によって石の表示を変える処理は下記になります。
エフェクトやアニメーションもこの時生成するようにしています。
エフェクトやアニメーションもこの時生成するようにしています。
↑石の表示を変える処理
↑アニメーションはDOTWeenで作成

マイケル
準備するのはこれだけ!
以上の構成で下記のような画面が出来上がります。
以上の構成で下記のような画面が出来上がります。

エレキベア
これぞオセロクマ〜〜〜
メイン処理の解説

マイケル
ざっくりとした構成が分かったところで、
いよいよオセロのメイン処理を解説していきます。
いよいよオセロのメイン処理を解説していきます。

エレキベア
待ってましたクマ
ストーン関連の処理

マイケル
まずはオセロの石(ストーン)関連の処理を見ていきます。
ロジックについては主にStoneCalculator.csにまとめています。
ロジックについては主にStoneCalculator.csにまとめています。

マイケル
下記はオセロの肝となる、
「置いた位置からひっくり返せる石を判定する」処理になります。
「置いた位置からひっくり返せる石を判定する」処理になります。
↑ひっくり返せる石の判定

マイケル
石の配列と置く位置を受け取って8方向分調べています。
もっと効率いい方法もあるかと思いますが、そこはお許しください。。
もっと効率いい方法もあるかと思いますが、そこはお許しください。。

エレキベア
シンプルな判定クマね

マイケル
ちなみに返却しているStoneIndexについては、
下記のように位置情報を格納しているだけのクラスになります。
下記のように位置情報を格納しているだけのクラスになります。
↑石の位置クラス

エレキベア
簡易Vectorクマね

マイケル
あとはこの関数を利用して
・置いた後の配列を返却する処理
・置くことが可能な石を返却する処理
も作成しています。
・置いた後の配列を返却する処理
・置くことが可能な石を返却する処理
も作成しています。
↑他のメイン処理

マイケル
これでほぼオセロは完成したようなもんですね!
テストも記述しているのでよければこちらもご参照ください!
テストも記述しているのでよければこちらもご参照ください!
GitHub – unity-reversi-game-scripts – StoneCalculatorTest.cs

エレキベア
ちょろいもんクマ〜〜
プレイヤー関連の処理

マイケル
次は実際にオセロをプレイするプレイヤー関連の処理についてです。
インターフェースとしてIPlayerを用意し、外部からは基本的にターン開始、ターン更新の処理しか呼べなくしています。
インターフェースとしてIPlayerを用意し、外部からは基本的にターン開始、ターン更新の処理しか呼べなくしています。
↑プレイヤーのインターフェース

マイケル
そしてこれを継承したPlayerクラスで具体的な処理を実装しています。
後々作成する入力プレイヤーやAIに共通する処理を記述しています。
後々作成する入力プレイヤーやAIに共通する処理を記述しています。

マイケル
AI含む各プレイヤークラスではこのクラスを継承して、
StartThink()、UpdateThink()をオーバーライドすることで実装しています。
StartThink()、UpdateThink()をオーバーライドすることで実装しています。

エレキベア
Template Methodパターンクマね

マイケル
入力するプレイヤークラスは下記の通り!
UpdateTurn()をオーバーライドして入力検知した石を設定しています。
UpdateTurn()をオーバーライドして入力検知した石を設定しています。
↑入力検知した石を設定する

エレキベア
各プレイヤーのクラスはだいぶシンプルになるクマね
ランダムに置くAIの処理

マイケル
そして最後にランダムに石を置くAIを作成します!
置くことが可能な石を取得する処理を使ってランダムに返すようにしています。
置くことが可能な石を取得する処理を使ってランダムに返すようにしています。
↑ランダムに置くAI

エレキベア
これもだいぶシンプルにまとまったクマ〜〜

マイケル
以上でオセロゲームの基盤は完成です!!
おわりに

マイケル
というわけで今回はオセロゲーム基盤の作成でした!
どうだったかな??
どうだったかな??

エレキベア
設計もちゃんと考えて作るのは楽しかったクマ〜〜
今後ちゃんとしたAIを作るのが楽しみクマ
今後ちゃんとしたAIを作るのが楽しみクマ

マイケル
シンプルながら作って楽しかったね!
次回はオセロAI定番の、MiniMaxアルゴリズムを使ったAIの作成だ!
お楽しみに〜〜!
次回はオセロAI定番の、MiniMaxアルゴリズムを使ったAIの作成だ!
お楽しみに〜〜!

エレキベア
クマ〜〜〜〜
【Unity】第一回 オセロAI開発 〜ゲーム基盤とランダムに置くAIの作成〜【ゲームAI】〜完〜
次回の記事はこちら!