contentC#で梅花碁の勝ち判定を行うC#アルゴリズムC#小品集シリースBoardパズル梅花碁とは梅花碁は、碁盤と碁石であそぶ連珠の一種です。「うめはなご」と読むのかと思ったら、「ばいかご」なんですね。黒、白交互に打ち進めて、十字の勝ちパターンを作ったほうが勝ちというゲームです。十字の大きさは問いませんが、辺の方向は水平、垂直、45度の角度に限ります。以下のようなパターンができれば、白の勝ちとなります。作成したプログラム梅花碁の対戦ゲームを作成しようかとも思ったのですが、その前段階として、梅花碁のある局面で白黒どちらが勝ったかどうか(上記の十字形ができたかどうか)を調べるプログラムを書いてみました。勝ちパターンがあるかどうかを調べる方法は、注目している石を梅花の中心とみなして、十字の勝ちパターンになっているかを地道に一点一点確認するという当たり前の方法を採用しました。盤面の状態はファイルから読み込むようにしています。ソースコードは、GitHubでも公開しています。Program.csMainメソッドのあるクラスです。Solverクラスを使って勝ちパターンがあるかどうかを調べ、勝ちパターンがあれば、それを表示しています。どこで勝ちパターンが作られたかを色を変えることで示すようにしています。盤面のデータファイル名は、"board.txt"と固定にしています。Console.WriteLine("見つかりません。}}Solver.cs勝ちパターンがあるかを調べるクラスです。効率面やクラス設計ではまだまだ改良のよりがありそうですが、正しく動作することを優先してこの形に落ち着きました。タプルを使いましたが、outキーワードの引数で勝ちパターンの石の配置を返した方が良かったかもしれません。主なメソッドは以下の通りです。IsWinPatternある点を与えると、その点を中心とした十字パターンがあるかどうかを調べるメソッド。bool値とその勝ちパターンの石の配置をタプルで返します。CreateWinPattern2を作成して、このメソッドからそれを呼び出しています。することでIsWinPatternがすっきりとしたと思います。trueを返せば、勝ちパターンがあると判定。IsWinPatternと同様に、bool値とその勝ちパターンの石の配置をタプルで返します。WhichWonどちらの石が勝ったのかを判定するメソッド。石の種類と勝ちパターンの石の配置をタプルで返します。IsWinを白石と黒石に対して呼び出すことで実現しています。}}Board.cs盤面を表すクラス(Board)と石クラス(Stone)。Stone.Emptyは何も置いていないことを示す仮のStoneオブジェクト。盤面を表すBoardクラスは、Boardbase<T>(後述)を継承しています。このプログラムでは、初期化以外は、Boardbase<T>で定義されている基本機能だけを使っています。スクリーンショット勝ちパターンの石の色を赤で示しています。Coreで作成し、Macで動かしていますが、ソースコードの修正なしで、Windowsでも動作するはずです。めオセロ」などで利用したものと同じものです。前述のBoardクラスの基底クラスです。盤面を表し、基本的な操作を定義しています。これは似たようなパズルでも再利用できるような汎用的な機能に絞っています。このBoardBaseクラスは、コンソールアプリに依存しない作りにしています。UWP、WinFormsでもそのまま使えると思います。このBoardBaseを継承して、当パズル専用のBoardクラスを定義します。内部では1次元配列を使っていますが、インデクサを定義して、1次元配列、2次元配列としても扱えるようにしています。すべてのメソッドで1次元対応と2次元対応のものを用意するのは面倒なので、どちらか一方にしています。これは好み以外の何物でもありません。1次元のインデックスによるアクセスができるようにしている理由は、一重ループで処理が書けるので、コードが簡潔になるからです。LINQのコードも書きやすくなります。なく、1から始まります。左上を示し、8×8の盤ならば、board[8,8]が右下を示すことになります。盤の周りには番兵用の領域を用意しています。これにより範囲外かどうかの判断を簡単に出来るようにしています。チェスのナイト(騎士)の動きにも対応できるよう、番兵は二重にしています。4×4の盤を表していますが、グレー部分が番兵が置いてある盤の周囲で、水色部分が実際の盤です。盤面上の数値は、1次元配列のインデックスを表しています。派生クラスや派生クラスを利用するクラスが、この番兵の存在に依存しないように、ToDirectionという関数を定義し、X方向、Y方向のペアで表す移動方向(ベクトル)をインデックスで表す方向に変換するようにしています。BoardBaseクラスはジェネリッククラスにしていて、そのパラメータの型は、盤面上に置けるクラスの型です。Tは、盤面に置けるオブジェクトの型。参照型でnew()ができれば何でも良い。upLoginユーザーは見つかりませんでした。