contentC#で3目並べ(○×ゲーム)の思考ルーチンを書いてみたC#アルゴリズムobserver対戦ゲーム思考ルーチン3目並べとは3×3の格子盤を用意し、二人が交互に「○」と「×」を書き込んでいき、先に3つ並べたほうが勝ちになるゲームでです。tooとして知られています。ほとんどの人が一度はやったことのあるゲームだと思います。このゲームは、両者が最善手を打った場合は、必ず引き分けになります。作成したプログラム人間とコンピュータが対戦を行う形式としました。コンピュータは常に最善手を打つようにプログラムしています。絶対に負けません(僕のプログラムが正しければですが...)まずは、どんなプログラムを書いたのか、その実行例を示します。見てののとおり、コンソール画面で動作する実にシンプルな見た目のプログラムです。上のスクリーンショットは、ゲームの途中の画面です。人間の手番で23と入力しています。2桁の数字でどこに打つのかの位置を指定しています。23は、2行目、3列目を意味します。次のスクリーンショットは、ゲームが終了(引き分け)した時の画面です。プログラムを構成するクラス主要なクラスは、以下の通りです。いわゆるビューに依存したクラスは、ControllerクラスとHumanPlayerクラスだけです。Controllerクラスゲームを制御するクラスです。先手後手を決め、ゲームを開始します。ゲームが終了したら再度ゲームをするかを確認します。実質的なメインプログラムです。いわゆる購読者クラスで、ゲームの状況が変わるとその盤面の状況を受け取ることができます。盤面が変化するとその内容を表示します。いわゆるViewerの役割も担っています。Gameクラス1回のゲームを表すクラスです。PerfectPlayerとHumanPlayerを交互に呼び出しゲームを進めます。いわゆる発行者クラスです。1手指すたびにその状況を購読者に通知します。そのため、見た目とは完全に独立したクラスになっています。Boardクラス盤の状態を表すクラスです。BoardBase<T>(後述)を継承しています。型引数Tには、駒を示すStoneクラスを割り当てます。Stoneクラス○×の石を表すクラスです。何も置いていない場所には、空のStone(Stone.Empty)が置いてあるものとします。IPlayerインターフェイスプレイヤーを表すインターフェース。PerfectPlayerクラスコンピュータ側のプレイヤーを表すクラスです。BestMoveというメソッドを定義し、ここで最善手を見つけています。BestMoveでは、相手が最善手を指すものと仮定して、最後まで(再帰的に)先読みをします。自分が勝つ手があればそれを指し、なければ引き分けの手を、引き分けもなければ、負けの手を指します。このゲームに限っては負ける手を指すことはないはずです。最低でも引き分けの手を指します。このルーチンをもっとシンプルなコードにしたかったのですが、この手のプログラミングに慣れていないせいか、思ったよりも長いコードになってしまいました。HumanPlayerクラス人間のプレイヤーを表すクラスです。キーボードから手を入力します。ソースコードクラスの数を少なくして、もっと短いコードのプログラムにすることもできると思いますが、クラスに分割したい派なので、多少長いコードになっても、僕にとってのわかりやすさを優先しました。3×3の盤面を表すBoardクラスは他のプログラムでも利用しているBoardBase<T>から派生させています。オーバースペックかもしれません。以下に、全てのソースコードを載せます。ここで終わったということは、引き分けしかない。ここまで来たということは勝ちは無かった。引分けがあったので、引分けの手を最善手として戻る。Tは、盤面に置けるオブジェクトの型。参照型でnew()ができれば何でも良い。upLoginユーザーは見つかりませんでした。