2017年01月15日

麻雀プログラムの作成 その8

寒いですね。チャンタ系(清老頭、純チャン、チャンタ)とトイトイ系(対々和、三暗刻、四暗刻、三槓子、四槓子)の判定を実装しました。後は混一色系と、三色同順など順子系の判定を実装すれば、大体の役判定は終わりです。七対子判定はバグがありますが…。

実行結果

副露が多いと右にはみ出します…。

mj_result_012.png

mj_result_013.png
web拍手 by FC2
posted by シンドラー at 15:46 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2017年01月07日

麻雀プログラムの作成 その7

前回の続きです。とりあえず親の連荘と得点計算を実装しました。点数表示も付けたので後は役判定を実装していけばとりあえず一人で四人打ちは完成で、後はAIなどをどうするか考えたいです。

実行結果

mj_result_011.png

画像で見ると小さいですが、一応東とか南とかの自風の下に得点を表示しています。
web拍手 by FC2
posted by シンドラー at 03:52 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2017年01月04日

麻雀プログラムの作成 その6

明けましておめでとうございます。冬休みがもう終わってしまいました。年始も一応コツコツ作ってはいて、3割ぐらいの役判定と得点計算を実装しました。まだまだ残りの役判定もバグもいっぱい残っています。麻雀プログラムの作成は大変ですね。

実行結果

mj_result_010.png

メンタンピンツモで20符判定なども一応はうまくいっているようです。点数は表示しているだけで反映していないので、その辺も実装しないといけないですね。
web拍手 by FC2
posted by シンドラー at 22:58 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2016年12月31日

麻雀プログラムの作成 その5

大晦日ですね。昨日の続きで国士無双の判定と、日本語文字の表示を行いました。国士無双に関しては、么九牌13種全て揃っているということと、頭1つで14枚揃っているという二つの条件が必要です。そのため、完成までの牌数の計算にちょっと迷いました。

日本語表示に関しては、画像の読込みにOpenCVを使用していましたので、そのままOpenCV使ってやることにしました。ただ、OpenCVも2系の段階では日本語表示に対応していないようでしたので、[1]のヘッダファイルを使用させていただきました。

実行結果

mj_result_009.png

国士無双は4人打ちで揃えるのは大変ですので、1人打ちにしてデバッグしました。日本語表示するとかなりましになった気がしますね。特殊な判定が必要な国士無双と七対子が終わりましたので、後はその他の役を少しずつ追加していきたいと思います。

[1] OpenCV で日本語を出力しようパート2
web拍手 by FC2
posted by シンドラー at 18:50 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

麻雀プログラムの作成 その4

もう年末ですね。テレビを見ながらゆっくり実装です。今回は七対子の判定を追加しました。七対子は、名前の通り対子が7個ですので、それぞれの種類の牌の数を数えて、2個のものが7個あれば完成となります。分割したパターンでは、槓子を対子2つと区切る場合もありますが、4枚使いの七対子は無しの方針なので、そこの判定にだけ注意が必要です。

後は[1]の背景画像を使用させていただき、上がった時に表示される画面を追加してみました。次は他の役判定と点数計算です。今使っているビットマップフォントはアルファベットのみなので、役の表示とかどうしましょうかね。

実行結果

mj_result_007.png

[1] 4K バックグラウンド 無料素材
web拍手 by FC2
posted by シンドラー at 00:32 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2016年12月28日

麻雀プログラムの作成 その3

続きです。リーチ判定ができるようになっていたので、ツモ及びロン判定はすぐできました。ツモの時は手牌の14枚、ロンの時は手牌13枚+捨て牌の組を作成し、それの待ちが1個(対子)のみであれば上がれるという判定です。七対子と国士無双は後回しです。

実行結果

mj_result_006.png

これで後は役判定ができれば、一人で四人打ち麻雀ができるようになります。役判定も基本的には力押しで組み合わせパターンを列挙して一番役数が多いものを採用になると思います。
web拍手 by FC2
posted by シンドラー at 03:31 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2016年12月25日

麻雀プログラムの作成 その2

前回の続きです。リーチ判定をするためには、役が揃うまでに後何手か判定できる必要があるので、まずは役判定の前にリーチ判定を実装しました。

鳴き判定をするために、萬子、索子、筒子、字牌それぞれで対子や順子、両面待ちなどの数を数えていますので、それで判定します。リーチできるのは後2つ必要な牌が来れば上がれる状態ですので、頭の対子を除いて待ちの数が2の場合リーチ可能とします。そして、リーチ可能となる捨て牌の判定ですが、これも力業で(最大)14個の手牌のうち、それぞれ1個取り除いて待ちの数が1になるものを見つけました。

実行結果

mj_result_004.png
リーチするための捨て牌候補を赤枠表示

mj_result_005.png
リーチ後

少し試した範囲では問題なく判定できているようですので、次はロンやツモできるようにしたいと思います。
web拍手 by FC2
posted by シンドラー at 19:59 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2016年12月23日

麻雀プログラムの作成 その1

いつの間にか年末ですね…。今回は麻雀プログラムの作成です。役判定とかAIとかかなり面倒な実装が必要ですね。参考文献は[1][2]などです。本はあまりなく、ネットで検索した方が色々情報がありそうでした。言語としてはC++でOpenGL使っています。OpenGLは一枚の平面に画像貼って表示してるだけです。

とりあえずは役判定やAIは後回しにして、配牌や自摸切り、鳴きを実装してみました。牌画像は[3]のものを使用させていただいております。

実行結果

mj_result_001.png

縦に手牌と捨て牌並べているので見えづらいですね。加槓が捨て牌に重なってたり文字表示もビットマップフォント使っていたり手作り感満載です。

ここまでで問題になったのは、鳴けるかどうかの判定処理です。これをするためには、手牌を解析してトイツや両面待ちなどがあるかどうか調べておく必要があります。最近は計算機の性能が上がっていてゴリ押しでも十分速いので、スタックを使ってすべての組み合わせを列挙して保持しておくことにしました。

mj_algo_001.png

最初に上記のように1個だけ、一番左を処理候補としたデータをスタックに積みます。

mj_algo_002.png

その後、1個取り出して取りうる候補(A〜F)を列挙して、またスタックに積みます。次はFを取り出して…とFILO方式ですべての候補がなくなるまで繰り返します。

上の方法の場合、対子―単騎と単騎―対子などの組み合わせがダブってしまいますが、とりあえず列挙して後で被っているものは削除しました。ちゃんと考えれば被らずに一度で終わらせる方法もあるとは思います。

チーの場合は複数候補が考えられますので、それを表示して選択するようにしました。ここまでで上がれないけれど一応打つことはできるようになったので、次は役判定に入りたいと思います。

mj_result_003.png

[1] 有馬元嗣著,"ゲームプログラミング 遊びのレシピ", ソフトバンク株式会社,1997
[2] 石畑恭平著, "コンピュータ麻雀のアルゴリズム", 株式会社工学社,2007
[3] 【保存版】商用無料の高クオリティーの麻雀画像の無料素材まとめ
web拍手 by FC2
posted by シンドラー at 21:41 | Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2016年11月02日

RANSACのテスト その2

前回は2次曲線で近似しましたが、今回はPCLに付属のサンプル点群をオーソドックスな平面で近似してみました。PCLで使用されているPCDデータですが、ファイルフォーマット的には簡単なのですが、binary_compressedデータは圧縮が入ってきて面倒だったので、結局PCLを使うことにしました。表示は自前でOpenGL使ってやっています。

PCLは以前all-in-one-installerを使用してインストールしていたのですが、すっかり忘れていてソースからCMake使ってコンパイルしました。FLANNとかBoostとか必要で結構面倒でした。

平面近似についてはこちらも前回同様特異値分解を用いてパラメータ推定をしました。平面の方程式は以前の記事でまとめていましたので、そこを参考にしました。

実行結果

PCL付属のfive_people.pcdを読み込んで表示した結果です。PCDファイルとはY軸が反転しているのか、上下が逆さまになっていましたが、気にしないことにしました。

pcl_test_001.png

以前の記事でOctreeを使った近傍探索も試していましたので、おまけでマウスでクリックしたところに赤い球を表示して、そこの座標を表示するようにしてみました。

続いて、平面近似した結果です。未知数4個なので、4点使って点と平面の距離が0.1以下の点群の数を、10000パターン試して最も一致数が多いものをRANSACで選んでいます。こちらもおまけで平面の領域+閾値の幅を適当に区切った直方体と、範囲内の点群を緑色で表示しています。

pcl_test_002.png

前回も書きましたが、この辺は自分で実装しなくてもPCLでできるのでほぼ確認の意味ですが、RANSACは大体使えるようになったので何か機会があれば使ってみたいと思います。
web拍手 by FC2
posted by シンドラー at 19:03 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする

2016年10月15日

RANSACのテスト

論文などでよく見るRANSACですが、試してなかったので試してみました。RANSACについては[1]を参考にさせていただきました。アルゴリズム的には簡単ですね。モデルも自由に変更できますし。今回は2次曲線の方程式を使ってみます。

equation_001.png

テスト画像は下記のものです。ペイントで適当に書きました。楕円で近似できればいいなといった図形です。

circle_test.png

白画素を点群として、2次曲線で近似します。未知数が6個ですので、6点以上使って特異値分解します。この辺のやり方は過去記事を参考にしました。全ての点群を使って特異値分解した場合には、左上の円に引っ張られて誤差の大きな近似曲線になります。

use_all_points.png

今回はRANSACで6点使って特異値分解で近似して、点群との距離?が閾値以下の点の数が最も多いパラメータを選んでみました。本当は点と曲線の距離を計算しないといけないのですが、近似したパラメータに点の座標を代入して、0に近いかどうかで判定したので正確ではありません。

実行結果

use_ransac_001.png

赤が全画素に対して行った閾値以下の点の領域で、緑が点群の中で閾値以下のものです。適当に描いた絵なのできれいにとはいきませんが、2次曲線で大きい方の楕円が近似できています。切り出しを行いたい場合は、範囲内の点で再度パラメータを計算して、閾値以下の点を取り除いて、残った点でまたRANSACということを行えば、2つの2次曲線を取り出せるみたいですが、今回はそこまでは試していません。

本当は3次元でKinectなどで取得した点群から球や平面を抽出したりといったことをしようと思っていたのですが、その辺はまた今度試してみたいと思います。まぁPCLなどで実装されているので、自分でやる意味はあまりないのですが。

[1] 【お勉強してみた】RANSACのおはなし - Qiita
web拍手 by FC2
posted by シンドラー at 18:18 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする