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/05/03

麻雀の細かいルールが良く分からん

カンドラの処理を作成。チーする牌の選択で、同じ種類の牌が2つ以上あった場合に左側の牌しか選択できなかった問題を修正。それと、ロンできるときにロンせずにポン/チー/カンするときの操作を修正。

ところで、麻雀の細かいところのルールが良く分からなくて困る。
大明槓して嶺上牌をつもったときに暗槓 した場合。カンドラのめくり方はどうなるのか?とか
明槓したときの槍槓の見逃しはフリテン扱いなのか?また自分が明槓 した牌もフリテン扱いになるのかとかよく分からない細かいことが多い。何か細かいところまで定めた統一的なルールブックってないものなのだろうか。。。

総ステップ数:8303

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

2005/02/17

場に見えていない牌の数を数えるメソッド作成

場に見えていない牌の数を数えるメソッド作成した。いままでは1人麻雀用になっていたのを4人用に改修。

総ステップ数:6538

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

2005/01/21

ユーザ操作部作成

ユーザがマウスで切るパイを選択できるようにする処理を作成。
ユーザとCPUプレイヤー3人で摸打を繰り返す処理まで作った。
ただ、まだ、ポン、チーはおろか、ロンや自摸和了宣言もできてない。
なのでいまは自摸和了したら裏向きの牌を切った風な動作になってしまう。
明日から自摸和了チェック、ロン和了チェックなどをやっていく予定。

20050121

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

2004/11/30

再帰的評価関数作成中その2

再帰的に有効牌数を数えるアルゴリズム作成中。概ね出来上がったんだが、ものすごく遅い。一向聴でも、向聴数チェックのために手牌の解析処理を3000回も実行している。手牌解析処理自体も再帰呼び出しをバンバン使っているので、トータルでみると恐ろしいほどの計算時間がかかる。何とか高速化しなければいけない。せめて2向聴が1秒程度に収まって欲しいんだが。。。

高速化の方法はいくつか思い浮かぶ。
1つは、解析処理を改善しあきらかに無駄なパターンの解析を打ち切る方法。
2つめ解析プログラムを使わないで最初の1回の解析を使いまわす方法。1つめのほうが簡単だけど、果たしてこれで十分なスピードが出るかどうか。。。多分2つめの方法でやらなければ、満足のいくスピードにならないんだろうが、いま具体的なコードが頭に思い浮かばない。ちゃんと考えればきっとわかると思うけど。うーん、面倒だ。

総ステップ数:4359

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

2004/11/28

再帰的評価関数作成中

やってみると結構大変です。再帰的な評価関数の作成。もうなんかあきらめたくもなるけど、何とか頑張ろう。あせらずマッタリが今回のプログラミングのモットーだし。

総ステップ数:4308

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

2004/11/27

現状の問題点と今後の作業

大きくなっていたメソッドの整理、変数名の変更、コメントの整理などの細かいソースの修正を実施。


また、とりあえず今作っているプログラムを動かして変な切り方をするところを探してみた。
ポンチーロン無しの一人麻雀で以下の2つの手牌から何を切るか?
nanikiru
上は、1ピンか3ピン。下は3ピンが正解だと思う。
しかし現状のアルゴリズムだと上の手牌で3萬か4萬を切ってしまうし、下の手牌で3萬を切ってしまう。
これは目先の受け入れ枚数しか評価していないから起きてしまう。
上は、3,4萬を切ると目先の有効牌は5種16枚で、1,3ピンを切ったときの5種14枚を上回っていると考えてしまっている。これは、比較的単純に解決出るとは思う。有効牌を引いたときの受け入れ枚数を再帰呼びだしを使って,掛け算してやれば評価値がソレっぽい数字になる。また、さらにもっと厳密に計算する方法があらのHPで紹介されている。まあ、実際の4人麻雀だと相手が先に上がることがあるので「得点×あがる確率」の期待値計算ではあがる確率の方にやや重みをおいたほうがいいと思うので、単純に掛け算をするだけのプログラムでもある程度通用するかもしれない。

下の方は有効牌数を向聴数を向上させるものしか考えていないために起きてしまう。これは両面ターツへ変化する牌の枚数を評価式に何らかの形で反映させるようにしなければいけない。そのためには、両面ターツへの変化の有効枚数を数え上げるメソッドを作る必要がある。そしてその枚数をどのように評価点に反映させるかを考えなければいけない。

今後は、再帰的に呼び出して期待値計算するアルゴリズムの作成。そしてリャン面ターツへの変化の枚数を数え上げるアルゴリズムの作成をしていきたい。

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

2004/11/25

有効牌数え上げアルゴリズム作成とりあえず終了

シャンテン数を下げる有効牌を数え上げる処理の作成完了。
棒テンアルゴリズムを聴数を下げない牌選択のうちもっとも受け入れ枚数が多くなるように捨て牌を選択するように評価関数を設定してみた。しかし、シャンテン数が変わらない手変わりを一切無視しているために浮き牌のどれを切るかがかなり大雑把になってしまっていて期待したほどは納得のいく選択をしなかった。

いい方法が思いつかなかったので、苦肉の策として、捨てるパイのロスを評価式に加えてみた。これならば(点数やフリテンをアルゴリズムに入れてないことを考慮すれば)90%以上は納得のいく牌を切るようになる。評価式にロスを入れたおかげで比較的真ん中に牌を寄せるようになるのでタンピン系の手ができやすくなった。
effective02


ただ、どうもまだ3456の形や3445のような良形をおろそかにしていてリャン面ターツをはずしてカンチャンや浮き牌を残してしまうケースがある。単純に有効牌数を数えるのではなくやはりしっかり再帰的に確率計算をしてやる必要があるのかもしれない。
総ステップ数:4164

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

2004/11/23

有効牌数え上げアルゴリズム作成中

有効牌(向聴数を下げることができる牌)の種類と枚数を数える処理を作成中。

有効牌を数える方法としては2通りのやり方を考えている。

1.順番に牌を追加して作成済みの向聴数チェックアルゴリズムに掛け向聴数が改善された場合有効牌とする。
2.現状の手牌を向聴数が最善になるような面子、ターツ、対子、浮き牌の組み合わせするパターンをリストアップし、その組むあわせをベースに4面子1雀頭に向かう牌をピックアップし有効牌とする。

とりあえず1は今まで作ったアルゴリズムの組み合わせで簡単に出来るので処理速度を計測してみた。
私が開発に使っているマシン[DELL Dimension 8400(Pentium4の2.8GHz)]で2秒から3秒かかるので麻雀ゲームとしては残念ながら微妙に遅い。2の処理のための下準備の処理を作成中。こっちはややプログラムが面倒だが果たして高速化されるだろうか。理屈上は1のやり方より早いはずだがちょっと心配。これでだめだったら他にいい方法が思いつかない。

2の方法をやる前に面子、ターツ、トイツの数とシャンテン数の関係を調べておく必要があったので調べてみた。
結果は以下のとおり。


向,面,タ,対
1,3,0,2
1,3,1,1
1,4,0,0
2,2,0,3
2,2,1,2
2,2,2,1
2,3,0,1
2,3,1,0
2,3,2,0
3,1,0,4
3,1,0,5
3,1,1,3
3,1,1,4
3,1,2,2
3,1,2,3
3,1,3,1
3,1,3,2
3,1,4,1
3,2,0,2
3,2,1,1
3,2,2,0
3,2,3,0
3,3,0,0
4,0,0,5
4,0,0,6
4,0,1,4
4,0,1,5
4,0,2,3
4,0,2,4
4,0,3,2
4,0,3,3
4,0,4,1
4,0,4,2
4,0,5,1
4,1,0,3
4,1,1,2
4,1,2,1
4,1,3,0
4,1,4,0
4,1,5,0
4,2,0,1
4,2,1,0
5,0,0,4
5,0,1,3
5,0,2,2
5,0,3,1
5,0,4,0
5,0,5,0
5,0,6,0
5,1,0,2
5,1,1,1
5,1,2,0
5,2,0,0
6,0,0,3
6,0,1,2
6,0,2,1
6,0,3,0
6,1,0,1
6,1,1,0
7,0,0,2
7,0,1,1
7,0,2,0
7,1,0,0
8,0,0,1
8,0,1,0
9,0,0,0

向:向聴数+1(聴牌なら1,一向聴なら2)/面:面子の数/タ:ターツの数/対(対子の数)

総ステップ数:4093

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

2004/11/22

至上最弱?のアルゴリズム完成

単純に向聴数を落とさない牌をランダムに選んで切るだけのアルゴリズムを作成。
むう、見てると凄いことしてます。
自分が切った字牌を切らずに取っておいてトイツにしたり、リャンメンターツよりカンチャンターツやトイツを残したり。序盤でヤオチュウ牌残して3,4,5辺りを切ったり。もうメチャチャ。
でも、そんなアルゴリズムでも運に恵まれると和了することもある。
これは4,5回目試した段階で初めて和了したときの画像。3色崩れのダブ東ツモの2000点オールだった。
まだまだ始まったばかりだけど自分の作った麻雀アルゴリズムで上がり形までたどりついたのにはチョット感動する。
今後は有効受け入れ枚数を数える処理を追加する。

worst_ai
総ステップ数:3944

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