« 2004年10月 | トップページ | 2004年12月 »

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/24

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

パターン2で有効牌を数え上げる処理を作成中。
懸念していた動作速度だがまったく問題ない。
ほぼ出来上がってるがまだテストが不十分。それと、種類は数え上げてるが枚数の数え上げ処理がまだなのでそこら辺を明日以降作成する。

effective01
総ステップ数:4209

| | コメント (3) | トラックバック (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)

2004/11/20

ドラ関係処理作成中

今まで後回しにしていたドラ関係の処理を作成中。

ゲームクラスのドラを表現するメンバー変数の追加。王牌表示GUI作成。得点計算にドラを追加(作業中)などなどの処理を追加。

dora
総ステップ数:3800

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

2004/11/19

一人麻雀ゲーム最低限の機能はできた

一人麻雀ゲームとして最低限遊べる機能を作成した。
GUI操作しづらいし見栄えも悪いけど今のGUIはどうせテスト用なので気にしないことにする。
まだドラ表示もない。せめてドラくらいはやっておきたい。その後は最低限シャンテン数を落とさないアルゴリズムを作成する。

Game01
総ステップ数:3596

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

2004/11/18

一人麻雀ゲーム化作成中

プログラム構造上の関係で当面の作業として、まずは一人麻雀ゲームとして遊べるようにしてきたい。
まずは、GUI部分で、捨て牌表示、積もった牌は理牌せずに右端に描画するように変える作業を行う。
それと平行してゲーム、プレイヤーを表現するクラスを作っていく。

総ステップ数:3523

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

2004/11/17

これからが大変

メンツ候補を抜き出す方法のアルゴリズムでシャンテン数を数えるプログラムを作成。
シャンテン数を数えるという最低限のことはできるようになった。今後は、死にメンツがある場合どうするかとか考えなければいけないことはまだありそう。
当面の予定としては、受け入れ枚数を数える処理とそして棒テンアルゴリズムの作成をやっていきたい。
けれど、ここ数日頭の中で、棒テンアルゴリズムをどうすればいいのか考えているけれど、かなり大変そうだ。
果たして本当にできるだろうか。

shantenB
総ステップ数:3379

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

2004/11/13

向聴数チェックアルゴリズムその2作成中

2番目のパターンで向聴数チェックプログラムを作成中。
これは、順子や暗刻だけでなく、ターツ(ペン、カン、リャン)やトイツ、浮き牌として手牌を抜き出すように上がり形チェックプログラムを変更すればできる。

たとえば、
2,3,4,5萬の場合以下の10パターンで抜き出す。

浮2/浮3/浮4/浮5
順子234/浮5
浮2/順子345
ターツ23/ターツ45
浮2/浮3/45
ターツ23/浮4/浮5
ターツ24/ターツ35
浮2/浮4/ターツ35
ターツ24/浮3/浮5
浮2/ターツ34/浮5

ためしに、九連宝燈9面待ち状態を抜き出してみたが、一瞬で終わった。まだこのロジックには追加が必要だが、十分使えそうな感触をえることができた。
9ren

総ステップ数:3298

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

2004/11/12

向聴数チェックアルゴリズムその1作成

先日のパターン1で向聴数チェックプログラムを作成。

動作させてみたが。うーんやっぱり遅い。3向聴の全パターンをチェックするのに1分近くかかる。まあ、すべての牌を追加して毎回上がり形判定を繰り返しているのだから聴向数が1増えるたびに34倍遅くなる。このままでは、このアルゴリズムは2向聴程度からしかつかえないだろう。
なにか無駄な処理を省けるといいのだが。

/*
 *向聴数チェック アルゴリズム1
 *
 */
void ShantenCheck(void)
{
    TPai paiVector[34] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,   //1萬~9萬
                          11,12,13,14,15,16,17,18,19,   //1ピン~9ピン
                          21,22,23,24,25,26,27,28,29,   //1ソウ~9ソウ
                          31,33,35,37,41,43,45};        //字牌
    char *shantenStr[] = {
        "聴牌",
        "一向聴",
        "二向聴",
        "三向聴",
    };
    vector<TTehai> agariList;
    int i,j;
    int crrShanten, result = 100;
    AnsiString msg;
    TTehai tehai2;
    int pai;
    getAgariStyle(*tehai, &agariList);

    if ( agariList.size() > 0 ){
        debug("あがっている");
        goto Exit;
    }
    // 牌(34種類)を最大4枚まで追加して上がり形になるか調べる
    for ( i = 0; i < 34 * 34 * 34 * 34; i++ ){
        agariList.clear();
        tehai2 = *tehai;
        for ( j = i, crrShanten = 0; j > 0; j = j / 34, crrShanten++ ){
            pai = paiVector[j % 34];
            if ( (tehai2.paiArray[pai-1]
                  + tehai2.paiArray[pai]
                  + tehai2.paiArray[pai+1]) == 0 ){
                //孤立している牌は計算しない
                goto LoopEnd;
            }
            tehai2.addPai(pai);
        }
        getAgariStyle(tehai2, &agariList);
        if ( agariList.size() > 0 ){
            if (crrShanten < result ){
                debug(shantenStr[crrShanten-1]);
                result = crrShanten;
            }
        }
LoopEnd:
    }
Exit:
    debug("終了");
    return;
}

shanten

総ステップ数:3165

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

点数計算ひとまず完了

点数計算の処理がひとまず完了。

今後は、向聴数チェックの処理を作成する。

向聴数チェックは現在2通りアルゴリズムを考えている。
1.順番に牌を追加してあがっているかどうかを確認する方法。
2.手配を面子候補(塔子、浮き牌)に分けてカウントする方法。

1.は有効枚数を数えやすく複雑なパターンに強いが手がバラバラの時に時間がかかるはず。
2.は処理速度が速いはず(とくに手がバラバラのときに)、ただ有効枚数の数え上げ等がやや面倒で、面前清一色聴牌などの複雑な手のときに処理速度が遅くなるかもしれない。

1も2もプログラミングとしては、すでに作成済みの、上がり形になっているかどうかの判定処理をちょこっと手を加えればできるのでそれほど難しくはないだろう。まずは両方とも作って試してみる予定。

総ステップ:3084

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

2004/11/11

点数計算作成中

点数計算早見表のような処理を作成中。
単純なんですが、なぜか意外と時間がかかるものです。数字入力に気を使うからかもしれない。
総ステップ数:3028

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

2004/11/10

液晶ディプレイが壊れた

ディスプレイがぶっ壊れた。左上に黒い長方形が…。買ったばかりなのに。
ここが壊れるとアプリのファイルメニューが開きにくくてしかたない。
仕方ないんで、C++Builderのツールバーを画面下部に配置する変則スタイルで作業実施。
display01

さて、本日はチャンタ、ジュンチャン、三色、一通の食い下がり処理が抜けていたので追加。また、その他細かい修正を実施。
総ステップ数:2751

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

2004/11/08

符計算作成

符の計算ロジックを作成。
なお、昨日は酒飲んで頭回らなかったのでほとんど捗らず。単純なロジックとはいえ、やっぱボーっとしてるときは、プログラミングはできません。

s4

総ステップ数:2681

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

2004/11/06

役判定作成完了

一気通貫、平和、断ヤオの判定ロジックを作成。

ひとまずこれで役判定の作成が完了した。
役判定ロジックはどれも単純なんでそれほど難易度は高くはなかった。

明日からは符計算をつくり得点計算を終わらせる。

総ステップ:2545

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

もうちょっと

純全帯、全帯、二盃口、一盃口の役判定を作成

目的の役は全部で以下の分だけある。
(○は作成済み。△は役判定ロジック作成不要。×は未作成。)
あとは、とりあえず、平和、一通、断ヤオのみ。
なんとか明日位には役判定は出来上がるかな。

△リーチ
△一発(イッパツ)
△門前清模和(ツモ)
×平和(ピンフ)
×断ヤオ(タンヤオ)
△槍槓(チャンカン)
△海底撈月(ハイテイツモ)
△海底撈魚(ハイテイロン)
△嶺上開花(リンシャン)
○一盃口(イーペイコウ)
○飜牌(ファンパイ) 白、発、中、自風、場風
○全帯(チャンタ)
○三色同順(サンショク)
×一気通貫(イッツウ)
○対々和(トイトイ)
○三色同刻(サンショクドウポン)
○混老頭(ホンロウ)
○三暗刻(サンアンコウ)
○三槓子(サンカンツ)
○小三元(ショウサンゲン)
○七対子(チートイツ)
△ダブルリーチ
○二盃口(リャンペイコウ)
○混一色(ホンイツ)
○純全帯(ジュンチャン)
△流し満貫(ナガシマンガン)
○清一色(チンイツ)
△天和(テンホウ)
△地和(チーホウ)
○字一色(ツウイーソウ)
○四暗刻(スーアンコウ)
○四暗刻(スーアンコウ タンキ)
○緑一色(リューイーソウ)
○小四喜和(スーシーホウ)
○大四喜和(ダイスーシーホウ)
○大三元(ダイサンゲン)
○九蓮宝燈(チューレンポウトウ)
○九蓮宝燈(チューレンポウトウ 9面待)
○清老頭(チンロウトウ)
△国士無双(コクシムソウ)
△国士無双(コクシムソウ 13面待)
○四槓子(スーカンツ)

その後の予定は
符の計算
向聴数チェック
棒テン即リーアルゴリズム作成
データ取り
etc...

総ステップ:2350

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

2004/11/05

三色

三色同刻、三色同順の判定を作成。
それと、向聴数チェックのテストプログラムもつくってみた。
総ステップ数2174

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

2004/11/03

まだまだ役判定作成中

三カンツ、トイトイ、混老頭、小三元の役判定を作成。
三色の判定を途中まで作成中。
総ステップ数:2042

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

三暗刻、染め手

清一、混一、三暗刻の判定を作成。
三暗刻と四暗刻なんぞ同じメソッドにすりゃよかったかもしれない。
最初に1役ごとに1メソッドで作ると決めたので、その方針したがってるがちょっと無駄が多い感じもする。
しかし、あまりくよくよしてると完成しなくなるし、これはこれで判りやすいので今はまだ作り変えるのはやめておく。
総ステップ数:1794

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

2004/11/01

七対子、役牌の判定作成

体調不良のため作業時間は短め。完成をあせらずに、作っていく過程を楽しむつもりでやっていく予定。
今日は七対子と役牌の判定を作成

ss3
総ステップ数:1637

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

« 2004年10月 | トップページ | 2004年12月 »