« 2005年6月 | トップページ | 2005年8月 »

2005/07/30

牌種別ツモロン比率集計

牌の種別ごとにどの程度ツモロンの比率に差がでるか知りたかったので東風荘のデータをもとに調べて見た。
ベースになってるのは、第一超と第二超のデータ。
リーチをかけて和了したとき限定でデータを集計した結果が以下のとおり。
comRate_reach
概ね、456牌ではツモロン比率が1:1。1,9牌で1:2。3、7牌で1:1.5。28牌は19と27の中間程度になるみたい。


また、ヒッカケリーチして和了したとき限定のデータが以下のとおり。データが少ないので19,28などはまとめて集計した。
compRate_trick

スジ19牌はほぼ1:4で無警戒に近い。
ちなみに、上下ランで同様のデータを取ると、19牌待ちのヒッカケリーチだと、ツモロン比率が1:3を超える。つまり恐らくは、中途半端な降り方をして結構オリ打ちしてるのだろう。

よく分からんのが456牌と37牌の差。両スジとも通っているならば456牌の方がペンチャン待ちがない分安全な気がするのだが、実際に超ランのメンバーはなぜか456の方が危険であると認識しているようにみえるんだがどういうことなんだろう。

| | コメント (0) | トラックバック (0)

2005/07/28

eval7そこそこ完成

eval7(多牌->最終形リストアップ版)の門前評価版がそこそこ完成。
(「そこそこ」と書いたのは細部の確率計算で手を抜いている箇所があるため。)

動作させてみるとやはり単騎待ちの評価値が高くなりすぎるようなので補正をした。
その後はまずまずの打牌選択をしているようだが、孤立している役牌とオタ風の選択などで、先に役牌を切るケースが多い。どうも門前縛りだと平和の頭になることの有利性>飜牌メンツの有利性になってしまう模様。
他にも私の感覚では疑問と思える評価値がでるケースが無いわけではない。

ただ、これは門前用ではなく鳴き評価が目的。なので、細部の妥当性を検証するよりも、まずは、ポンチーするか否かを評価できるようにeval7の修正することを優先して作業していく予定。


| | コメント (0) | トラックバック (0)

2005/07/25

eval7まだまだ作成中

まだまだeval7の作成中。

裏ドラと一発、ロンとツモの比率を考慮した和了点数を求めるロジックを作成した。
ツモ:ロンの比率は、第2超ランのデータをベースに、1:1.5にしている。将来的には、待ち牌の種類とスジになっているかなどを考慮して変更するようにしたい。

eval7-2


また、今は和了形を引き抜いているけれど、平和のように最後に積もった牌によって役が異なる場合があるので、
入れ替えた牌のそれぞれについて、最後に積もる確率を計算する必要がある。その確率を計算するプログラムをためしにRubyで書いてみた。
下のプログラムは3向聴(入れ替える牌は全部で4種類)で、場に見えてない牌がそれぞれ、2,4,3,3枚ある場合に、見えていない牌が2枚である牌で最後に和了形になる確率を求めるプログラム。

# index番目の有効牌を最後に引く確率を求める関数
# arrayはN種類の有効牌のそれぞれ見えていない枚数

def func1(array, index)
    val = 0;
    sum = 0;

    array.length.times do |i|
        sum += array[i];
        i += 1;
    end

    if sum == array[index] then
        return 1.0;
    end;

    array.length.times do |i|
        if i != index && array[i] > 0 then
            array2 = Marshal.load(Marshal.dump(array)); # deep copy
            array2[i] = 0;
            f = func1(array2, index);
            val += f  *  array[i] / sum;
        end
    end;
    return val;
end


array = [2, 4, 3, 3];
val = func1(array, 0);

p val;

| | コメント (2) | トラックバック (0)

2005/07/23

eval7作成中

同一の和了形をリストアップしないように、和了パターン抜きだしメソッドを修正。
あと、一部メソッドが多牌に対応していなかったので修正。
それと、ためしにリストしたパターンについて得点計算をするようにしてみたけど、速度的には問題ないようだ。
明日からは確率を求める関数を作成する。

| | コメント (0) | トラックバック (0)

2005/07/19

eval7作成開始

評価関数7作成開始。久々に一人麻雀用のプログラムを引っ張り出す。

評価関数7のやり方を単純に言うと、始めに和了形を全部羅列する方法。


例えば、下の画像の手牌の場合、二向聴数なので最低3枚入れ替えれば、和了形になる。
eval7-1

まずは、有効牌をリストアップする。
そしてその有効牌をすべて手牌に加えた多牌状態の手牌を作る。

一二二二三(4)(5)(6)(6)(6)(7)(8)(8)(8)12234発発発

その手牌から和了形のパターンをすべて抜き出し、その和了形の点数とその和了形になる確率を求める。
点数と確率をかけた値をその和了形に使わなかった牌の点数をして加算する。

例えば上記の手牌のうちの和了形のひとつとして

二二(4)(5)(6)(6)(7)(8)123発発発

を抜き出した場合、点数は(ドラなどを考えないと)リーチツモ発で4000点

元の手牌から追加した牌は(4)(7)発だが、これらを17回のツモの間に少なくとも1枚ずつ引く確率をPとするとPは以下の式で表現できる。

P = C(4,1)*C(4,1)*C(2,1) * C(見えてない牌の数-3,14) / C(見えてない牌の数,17)
※C(N,M)はN枚からM枚を選んだ場合の組み合わせ数

そして元の手牌にあった牌の内で上記の和了形に使わなかった一(8)2の評価点として4000*Pを加算する。

これをすべての和了パターンに行ない、不要牌に点数を加算する。
最終的に一番点数が高かった牌が一番いらない牌になる。


この方式のメリットとデメリットは以下の通り

メリット
1.
期待値版評価関数より計算速度が早いため、向聴数が悪くても計算できる。
2.
上記理由で手変わりについても評価しやすい。
3.
鳴き和了の時の評価点を出しやすくなる。
4.
最初に和了形をリストしているのでオーラスのように特定の点数を上がる必要があるケースでの評価がやりやすい。

デメリット
1.
厳密な意味での期待値とは異なる評価点になる。(例えば、ある特定の和了パターンになる前に別のパターンで和了する場合が考慮されていない)
2.
メンツオーバー形、リャンカン形、単騎待ち、特に七対子は本来の価値より高い点数になるはず。


今日までの作業状況:
入れ替え枚数を考慮しないで、すべての和了形のリストアップをしようとしたら、手牌のパターンによってはメモリ不足になるほどにパターン数が爆発していたので、和了形リストアップアルゴリズムを改造して、入れ替え枚数を考慮したリストアップを行なうように修正。(単純な修正でもっと工夫すればスピードアップが図れることは分かっているけれど、いまのままでも十分なスピードがでているようなのでいまはまだそのままにしておく。)

現在は同一パターンを重複して抜き出しているようなのでそこら辺の修正などを明日以降行なっていく。

| | コメント (4) | トラックバック (0)

2005/07/17

ちっとも進まん

若干仕事が忙しくなりつつあり、あまり時間がとれず。とりあえず、プログラムの汚い部分の整理等の処理をちまちまとやってた。

鳴きを意識した評価関数(eval7)の構想はあるにはあるんだけど、考えてみるといろいろと問題がありそうでプログラミングを始めるのを躊躇していた。でもまあ、私のようなアホがいきなり完璧なものを作れるはずもないんだからまずは行動して結果を出そう。結果を出してみて駄目だったら、その駄目だった箇所を修正すればいいんだから。

総ステップ数:9464

| | コメント (0) | トラックバック (0)

2005/07/09

期待値版評価関数の4人麻雀化

鳴くべきか門前リーチを目指すべきか判断するために、速さと高さをより正確に評価する必要がある。

そのために、まずは現状の門前用の評価関数を改造する。
現状は一人麻雀用の評価関数を4人分の河に出ている枚数を考慮するように修正しただけだが、和了順目分布、裏ドラ、一発、ツモ/ロン比率を考慮するように改造する予定。

まずは、1局当たりのツモ回数の確率分布を東風荘の牌譜から統計をとり、(自分は上がっていない前提で)、3人分に補正し、そのデータを評価関数に組み込むところまで作成した。

今回の牌譜解析のような使い捨てプログラムをC++で書くのは牛刀を持って鶏を割くようなものなんで、Rubyの本を買ってきてお勉強。美しい言語ですなRuby。正直驚いた。

明日は裏ドラ、一発、ツモ/ロン比率について作成していきたい。

| | コメント (0) | トラックバック (0)

2005/07/06

却って弱くなったような気がする

ベタオリを組み込んだCPU雀士3人と自分で試しに打ってみたが、どうも却って弱くなっている気がする。
数試合しかやってないので偶然かとも思ったのだが、そうでは無さそう。
かといってベタオリアルゴリズムが下手で結局振り込んでるとか、無駄にベタオリしていて上がるチャンスを逃しているとかではない。
リーチに対してきっちりベタオリをするようになったことでリーチ攻撃の有効性が低くなり、相対的に鳴きによる攻撃の有効性がかなり高くなったことが原因のようだ。今のCPUはまだ鳴けるように出来てないので、1人だけ鳴きありでプレイしている人間側がかなり有利になってしまったらしい。(試しに自分もCPUに付き合って鳴き無し門前縛りでプレイしてみると以前の全ツッパのときよりベタオリありの今のアルゴリズムの方が苦戦を強いられる。)


そろそろ、CPUの鳴きのアルゴリズムを考えなければならない時期が来たようだ。しかし、はっきりいっていいアイディアが無い。上手いこと計算で鳴くか鳴かないかが判定できればいいんだがめどが立たない。さあどうするかな……


2005/7/10追記
麻雀愛好家でよく攻撃麻雀と守備麻雀どっちが強いかとか話題になるけど、門前リーチ派<ベタオリ派、ベタオリ派<鳴き和了派、鳴き和了派<門前リーチ派の3すくみ構造になってるんじゃないのかって気がしてきた。
(もちろんバランスがとれた最適混合戦略あるならそれが一番いいのだろうけれど。)

| | コメント (0) | トラックバック (1)

2005/07/05

ベタオリVS全ツッパ1000試合勝負

危険度指数判定を組み込んだ評価関数を作成。「科学する麻雀」によると、一向聴からリーチに勝負するのは不利らしいので、相手がリーチしたときにテンパってなければ原則ベタオリ、テンパってればすべて勝負するようにした。

どの程度今までの全ツッパと強さが違うか調べたかったので、全ツッパCOM雀士2人とベタオリありCOM雀士2人で1000回の東南戦をやらせてみた。(和了に向かうアルゴリズムはまったく同じもの)
CPU4人に打たせると、東南戦1回が大体70秒程度で終わる。

結果は以下の通り

全ツ雀士1 -3315
オリ雀士1 +3937
全ツ雀士2 -4077
オリ雀士2 +3419
(単位は千点)

半荘で差し引き7千点以上の差がつくのだからかなりの差があると見ていいのだろう。まずはこれをベースにすることに。


| | コメント (0) | トラックバック (0)

2005/07/02

危険度指数評価関数作成

危険度指数評価関数を作成した。まだ、デバッグでダイアログに出してるだけで、CPUの判定には組み込んでない。どんな感じか2つほど載せます。(画像はクリックすると大きくなります)

anpaiRate


右下のダイアログが手前の雀士からみた対面と下家のリーチに対する危険度指数。大きい数字ほど危ない。
3,5は三萬、五萬、11,17,18は筒子、22,23がソウズ。

共通安牌の1筒が一番安全で、
次に安全なのが7筒。これは、親に現物であること、しかも8筒が4枚見えていて7筒も3枚見えているため下家に単騎でしか当たらない。
3番目が8筒。両者に筋。しかも4枚見えているので単騎、シャボの可能性なし。カンチャン79はありえるけれど、両方3枚ずつ見えているので薄い。

さすがに、終盤で情報が多いんで、結構妥当な順位だと思います。
(このときは、対面の親が2,5ソウ待ち、下家がペンチャン3萬モロ引っ掛けでした。)

中盤だとこんな感じ
anpai2
両者共通の安牌がないで、候補は伍萬(親の現物,子の片筋)か二萬(子の現物で親のスジ)あたりになる。
親の危険度は子の1.5倍として評価していますが、それでも親の現物の伍萬より、子の現物の二萬の方が3倍以上安全であると評価している。2萬が3枚見えてシャボが無いというのと三萬が2枚見えているのことが評価点に影響しているのでしょう。

| | コメント (0) | トラックバック (0)

« 2005年6月 | トップページ | 2005年8月 »