*All archives* |  *Admin*

<<12  2017/01  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  02>>
麻雀ゲーム・麻雀AI製作その5・他家棒テン即リー全ツッパAI
前回の続き。
今回はいよいよ他家の思考部分を実装したいと思います。AIっぽくなってきましたね。
まずは単純な思考(棒テン・即リー・全ツッパ)からです。

他家のAIの行動は、
・シャンテン数を下げられるor変わらずになる打牌候補のうち、1次有効牌の残ってる枚数(自分の手牌+場に出てる牌から数えた単純に見えてない枚数)がもっとも大きくなる打牌をする。
・1次有効牌の枚数が同じ場合は、オタ風→役牌→19牌→28牌→37牌→46牌→5牌→ドラの優先順位で打牌選択する。
・手役は全く見ない。聴牌したら即リーチ。
・他家リーチに対しても同じ思考のもと、全ツッパする。

いちおうそれっぽいのはできたので動かしてみます。
170129-01.png
他家は最初は孤立字牌から切っていきます。自手はまずまずか…。
170129-02.png
と思ってたらさっそく先制リーチが飛んでくる。また、濃い捨て牌ですなぁ。
170129-03.png
他家は全ツッパなので、一発で当たり牌の1sが出ました。
上がりの形と役と点数が公開で表示されます。
170129-04.png
それで実際に点数のやり取りをする、と。
170129-05.png
次局。幸先よく先制良形リーチを打てたが、親からの追っかけが来る。
(見やすさのためにリーチをかけた人の捨て牌が黄色く表示されるようにした。)

なんとか上がりを拾えた。
170129-06.png
東3局。2軒リーチがきたので、自分はベタ降りに回る。流局。
ノーテン罰符がやりとりされる。親聴牌なので、連荘。
170129-07.png
東3局1本場。リーチ一発ドラ4の横移動。トップが入れ替わる。

特に棒テンAIは良形を目指すとかいうのは入れてないですが、有効牌が一番多くなる打牌選択をするので、自然に良形塔子が残るようにはなってます。攻めに関する部分はそこまで人間が打つのとかけ離れてるということはなさそうです。
170129-08.png
東4局。リーチのみが裏裏で満貫!トップをまくってトップ終了、
170129-09.png
かと思ったら唐突に東4局1本場が始まり、
きれいにまくられるというオチがつきました。

試合続行条件がおかしかったのでこれは修正ですねー。

主目的が麻雀AIの製作用のゲームなので、グラフィックは皆無で、テストで動かしてもなかなか他家の捨て牌の情報が頭に入ってきにくいですねぇ。

次は自分鳴きに関するところですかね。
あと、やってないのはフリテン関係とか。
その後にベタ降りのアルゴリズムを入れて、(押すか引くかは現在のシャンテン数+押す場合に切ろうとしてる牌程度の単純条件にするつもり。)
その後に今の四麻計算機のアルゴリズムを本格的に入れるか、
それとも先に牌譜の出力機能と再生機能をやるか、
麻雀AIの対戦場に接続するコードを解読するのをやるか。
そのへんは気分次第で決めましょう。
スポンサーサイト
麻雀ゲーム・麻雀AI製作その4・他家からロンする
今回は麻雀ゲームの続きで、有効牌の計算関数の作り直しと、他家からロン和了する処理を実装するところまで終わりました。

流れはこんな感じ。
170128-01.png
聴牌。立直ボタンを押して打4m。25p待ち。

170128-02.png
あ、5p出た。ロン!
170128-03.png
「はい」→「OK」。5200です。
(間違って「ツモ和了」って書いてるけど、「ロン和了」の間違い。点数計算自体は正常にできてる。)

なお、「和了」ボタンは廃止しました。(上がり牌をツモったときと出たときに、上がるかどうかを聞く方式に変更。こっちの方が設計的に楽だったので。)

次回はいよいよ他家の思考の部分です。ようやくAIっぽいところに手を付けられるところまで来ました。
まずは前回に書いた通り、一番有効牌が多い打牌をするだけの棒テン・即リー・全ツッパのAIから実装していきます。
麻雀ゲーム・麻雀AI製作その3・一人麻雀ゲーム
前回の続き。

グローバル変数をなるべく使わない関数への設計変更をぼちぼちと進めています。
ただ、自分の打牌等についてはフォーム上からButtonのClickイベントで関数を呼び出す関係でグローバル変数がいりそうなのがそこそこの数あったので、そこはまぁ割り切ります。
グローバル変数にするのは4人の手牌情報、晒し手牌、捨て牌、リーチ状態等など、すでに確定している情報だけです。
メイン関数(自分の行動、他家の行動)以外からはグローバル変数の変更はさせないようにします。
個別の役判定とか点数計算とかの関数については複製(Clone)した配列とかを引数として渡して、それらの引数以外の情報は使わないように設計します。(関数の引数の種類数がかなり多いところもあるが、それはやむなし。)

今日はシャンテン数判定と手役・得点計算系の関数を全部作り替えました。
(手役判定だけで30種類以上の数あったのでとても大変。)

テストについては、
一人麻雀計算機制作計画その3・メンツの切り分けと役満手役判定
一人麻雀計算機制作計画その4・一般手役判定と得点計算とその他
でやったのと同じ手牌を入力し、全部の役について正しく判定されてるのを確認しました。

その後、麻雀ゲームにおいて、自分の立直処理とツモ和了処理をゲームとして組み込みました。

こんな感じの流れ。
170127-01.png
まずまずの配牌。

聴牌目指してツモと打牌を繰り返します。(他家はあいかわらずツモ切りマシーン。)
170127-02.png
面前聴牌(まぁ鳴きがないから必然的に面前でしか聴牌しないのですが)。立直ボタンを押す。
打牌候補がシャンテン数0になる4pと7pからしか選択できないようになる。
170127-03.png
一発はならず。リーチ状態なので、ツモ切りするしかないです。(暗槓もまだできていない。)
170127-04.png
高めの6sツモ。(他家からのロンはまだできてない。)
手役とハン数、裏ドラの情報を載せて、最終的に計算された上がりハン数と符数と点数が表示されると。

今日はもうちょっとゲームの流れに穴がないかをテストでチェックして、
次回は他家からのロンと有効牌計算と他家の簡単なAI(シャンテン数の下がる有効牌の枚数が最も多い打牌をする。聴牌したら立直してツモ和了・ロン和了をする。)を入れるところまでいきたいですね。
麻雀ゲーム・麻雀AI製作その2・ツモ切りゲーム2
前回で他家(CPU)はツモ切りするものとしてツモって捨てる動作までできたのですが、
今後CPUがAIとして前に作った計算機をベースに最適打牌・行動を計算するのに時間がかかることは明らかなので、
CPUの思考部分をバックグラウンド処理することを考えます。

ただ、CPUが3人いる関係で、3つのバックグラウンド処理を同時並行ですることが想定される
(基本的には自分のツモ順のときにのみ最適打牌を考慮しておけばいいのであれば、同時に処理されるバックグラウンド処理は1個までになるが、ロンと鳴きに関するところを計算時間を短時間で済ませることを考えれば、他家、特に自分の手番のときにも思考の処理をすることは有効になり得る…かもしれない。)
ということで、問題点が1個あります。

現状のプログラムだとどこからでもアクセスできるグローバル変数を多用していますが、それだと、
複数のバックグラウンド処理からグローバル変数にアクセス(特に値の書き換え)があった時にデータの不整合が発生する可能性が極めて高いということです。

これを防ぐために変数のスコープをバックグラウンド処理内での宣言で完結させて、他のバックグラウンド処理からはさわれないようにする必要があります。
ということで、今まで計算機のために作った大量の関数をグローバル変数を使わないで、単純に引数を渡し、戻り値を返すだけの設計に全部書き換える必要が出てきました(既存の計算機部分は現状それなりに動いていて新たなバグを作りたくないので、書き換えではなく、関数の新設になる)。かなり分量が多いので大変です。

今回はバックグランド処理に関する情報の受け渡し関係をなんとかやりました。

backgroundworkerの引数(e.Argument)として、今までの履歴(各プレイヤーのツモ、打牌)を渡し、
それを手牌情報、捨て牌情報のローカル変数に代入し、(もちろん考慮者以外の手牌情報は不明なので、その分の情報は切り捨てられる)
計算はそのローカル変数に対して行い
戻り値(e.Result)に思考した結果の最適打牌を返すというプログラムです。(今は単純にツモ切り。)

現状はただのツモ切りだけなので、自分以外のツモ番が回ってきたときに、各手番者のbackgroundworkerを起動させて、打牌が決定したらbackgroundworker処理を完結させるというだけです。
鳴きについてはまだまだ全く考慮できてないので、他家の手番中は考慮はさせません。(1回につき1個のbackgroundworkerのみを起動する)

というわけで、今回は見た目と機能は全く同じですが、かなり設計の中身を書き換えました、という話でした。
まだ完成は遠いけど、方向性は見えたかなー。
麻雀ゲーム・麻雀AI製作その1・ツモ切りゲーム
今日からは四麻計算機からちょっと離れて、別のテーマをやっていきます。

今の計算機を麻雀AIへと進化させるために、AIが麻雀を打てる環境を麻雀ゲームという形で整えていきます。
画面の見た目はこんな感じ。
170123-01.png
右下に麻雀ゲーム用のボタンを複数用意しました。

「ゲーム開始」ボタンを押すと、…
170123-02.png
配牌が配られていきなりゲームが始まります。自分は北家からスタート。(乱数で席は決まる。)ドラ表示牌は2p。
自分の手牌はいつも通り、左上のテキストボックスに入っています。
現在はデバッグ用なので、他家の手牌、山(備考欄)は全部オープンになっています。

さっそく東家から打牌がされていきます。
170123-03.png
まだ作り立てなので、CPUは全部ツモ切りです。

それで、自分の手番。赤5pツモ。
170123-04.png
「切る」ボタンの左のコンボボックスで切る牌を選択して「切る」ボタンを押す。とりあえず浮いてる南を切る。
170123-05.png
切ったらまた他家のターン。

しばらく淡々と摸打を繰り返して…、
170123-06.png
聴牌。だけどまだ「立直」や「和了」の機能はついてないです。(「立直」「和了」ボタンはハリボテ。)

それで、18巡目の南家の打牌が終わったら、
170123-07.png
これでおしまい。

単純にツモって捨てるだけのゲームなのでまだつまらないですね。
次回は自分について「立直」機能と「和了」機能をつけるところですかね。
四人麻雀計算機その45・カベ効果等のテスト6
カベ効果等の影響の続き。

カベ効果のリーチ和了率の実測値を取りました。
集計対象は両面14,69待ち(残り8枚)で、リーチ時点の内側牌(23牌と78牌)の場に切れてる枚数(のうち多い方)と巡目ごとに分けました。
170122-01.png
で、取ってみたのはいいのだけど、ワンチャンス(3枚)のサンプル数が100もなく、数値が凸凹でよくわかんない…。
0枚(23牌が場に全く切れてない)と2枚(ツーチャンス)だと和了率5%くらいの違いに見えるから、
0枚と3枚の間の差ならそれよりちょっと大きいくらいかなぁ。

次にシミュレーションの方もカベ効果の切られ率のパラメータを周りの牌の見えてる枚数準拠(無関係他家視点)だったのを、切れてる枚数準拠に変えました。
おそらくこっちの方が合理的ではないかなーと。
自分暗刻のノーチャンスは他家から見てノーチャンスとわからないので、リーチを掛けた場合、出やすいわけではない。
後は切れてる枚数準拠にしておけば誰から見ても同じ値になるので、誰視点で枚数を見るかという問題が起こらなくなるのでわかりやすい。

序盤5切りの方は切られる牌そのものの枚数なので、単純に自分から見えてる枚数でカウントした方がよさそうだから変えませんでした。

それで、カベ効果を再計算し直すと。
170122-02.png
場に3枚のマンズ待ちと場に切れてないソーズ待ちとの間の和了率の差は8%。
ちょっと差が縮まった。さっきの実測値での差を見てもまぁそこそこ妥当ではないかと思います。

というわけでこの話題についてはよしということにしましょう。
もうそろそろ同じ話題で停滞するのもどうかと思うから次に行こうかな。
四人麻雀計算機その44・カベ効果等のテスト5
カベ効果等を考慮に入れてから、普通に牌姿を無作為に取ってきてテストしてましたが、
実際にどの程度カベとかの効果が和了率に影響するのか?というのをまだやってなかったので、
捨て牌をてきとうに仮定してシミュレータを動かしてみます。
(動かしてみたら、序盤外側効果と5切り効果が全く機能してなかったバグとパラメータの計算ミスがあって全然違う結果が出てきて焦った。バグのないプログラムはないとはいうけれど、それにしてもバグ多すぎな気がします。我ながらセンスない。)

まずはワンチャンスから。3m3枚切れのときにマンズの14m待ちとソーズの14s待ちとで和了率等がどの程度変わるか。
170121-01.png
ワンチャンスの14mの方が周りが見えてない14sより10%くらい和了率が高いという結果に。

なんか和了率の増加幅が大きすぎて、かなり嘘くさい感じがするので、実測値との突き合わせはやった方がよさそうですね。(今牌譜解析中。)

次に序盤の外側効果。1巡目に3sを切ってる時と7巡目に3sを切ってる時(3巡目と6巡目までの捨て牌で判定してるので、外側牌にあたらない。)の和了率等を見てみます。
170121-02.png
序盤外側効果で5%くらい和了率が上がっています。

こちらは前に実測値を取っていました。
両面待ちと迷彩効果
実測値だと外側効果で和了率約8%差。
今回のは実測より差が小さいですが、シミュレーションでは、7巡目に3sを切っているという情報を加えている(見えてる枚数をそろえて同条件にするため)のに対し、
実測値の方はそういう補正のない生データという違いだろうと思います。
まぁ5%UPと8%UPというくらいの違いなら著しく不合理ということはないでしょう。

最後に序盤5切り効果についてです。自分の切ってる3sを5sに変えただけです。
170121-03.png
和了率の差は1%。そんなに大きくはないです。
序盤5切りは多少は警戒されて切られる率が多少は下がるけれども、ノーマル無筋19牌もそうそう出る牌ではない(切られる率の絶対値が小さい)ので、最終的にそんなに差が出ないみたいな感じの気がします。

序盤5切りについては実測値がないですが、まぁこれはいいでしょう。差がわずかなので、やっても面白くないし。
四人麻雀計算機その43・カベ効果等のテスト4
170120-01.png
鳴きも考慮して打9mか。
170120-02.png
170120-03.png
好形が見込めそうなので、チートイは見切って打2m
170120-04.png
鳴いてもそんなに速度・打点が上がるわけでないのでスルー。(ドラポンで警戒される効果も考えればなおさらスルー。)
170120-05.png
点棒状況的にドラの補充を見たいところだが、両者微差とのこと。暗刻にして、立直ツモ裏1狙いということだろうか。
四人麻雀計算機その42・カベ効果等のテスト3
今日も創作意欲がわかなかったので、テストの単純作業に従事します。

170119-01.png
8sと2sが1枚切れたけど、ふつうに浮き牌切りの打6m
170119-02.png
愚形×2でドラを切るのは厳しいので向聴戻し。
170119-03.png
ここで惰性で赤5pを切ってしまったのはかなりのミス。14p69pの待ちが透け透けになるのも含めて罪が重い。
170119-04.png
よくわかんない。
170119-05.png
これもポンとスルー微差?
170119-06.png
打4sダマにして7mポロリを待つ。跳満で十分です、の構えの方がよかった。
170119-07.png
170119-08.png
3900両面現物待ち。ダマで押す。
170119-09.png
6sは当たりそうな気がするが、リターンが大きい手でノーテン罰符も大きいので、6s押す。
170119-10.png
上がればトップだが、12000打つと2着順落ちる。上がれる雰囲気は全くしないが、とりあえず1m打っておいてしばらく一向聴でねばる。
四人麻雀計算機その41・カベ効果等のテスト2
今日はあまりやる気が出なかったので、大幅なプログラム変更はせず、単純なテスト作業だけにしました。
(またけっこう重篤なバグが出てきて、修正の作業もやったけど。)
170118-01.png
打点があって6pは一人に通りそうなので、聴牌は取るけど、47mが現物で極薄なので、リーチはやりすぎだった模様。
(この後7sでダブロン食らって悶絶。ダマなら回避できたなー。)
170118-02.png
ダマ5200だけど、序盤なので立直で足止めした方がかえって安全だったみたい。
170118-03.png
170118-04.png
トイトイでもチートイでも上がればトップ。1sはスルーだが、4pはポンというバランス。
170118-05.png
上がりトップ。8mは押す。降りて満貫ツモくらいされて次局ラス目に上がられるパターンがあるので、むしろ降りる方が危ないまである。
プロフィール

Author:nisi5028
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
FC2カウンター
フリーエリア
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード