麻雀のアガリ・テンパイ判定ルーチン
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNGスッキリとまとめることはできませんかね?
あと、チンイツの解析が全然うまくいかないんで、いいアルゴリズムがあれば教えていただきたい。
#麻雀板で聞くべきですか?
0002よくわからんのであげない
NGNG判定すればよいのじゃないの???
0003デフォルトの名無しさん
NGNG(麻雀用語良く覚えてないから記述が正確かどうか自信ないけど)
まず、シュンツ、コーツになってるものにわけるでしょ、
(これに複数の場合があるけど、以下の解析で役になってるやつ採用)
そんでそれぞれに19牌つきか、それ以外か、とかワンズだかソーズ
だか字牌だかって属性ふっていって、それみて判断ちゅうことでしょ。
(一部例外の役除く)
ってんでうまくいかないの?
00043
NGNG00051
NGNG一番聞きたいことをさらっと流さんでくれ(kw
それがうまくいかんのよ。
0006デフォルトの名無しさん
NGNGのをサーチすればいいんでしょ?アガリ判定はそんなに
難しくないのでは?
でもテンパイは結構トリッキーかも。
00073
NGNGああごめんなさいね。素直にやるなら以下のような感じかな。
これに高速化の工夫なり、手の判定のための属性つけなり、
例外的な役のための判定を付け加えればよいんでないかな。
牌の配列をaとする。
二枚同一の牌のある全ての組み合わせについて、
その二枚をaから除外し、pickup(aの最初の要素, aの最初の要素を除いた残り)を実行
上のpickupが無事終了したら、役になってる
二枚同一牌の組み合わせがない→終了
pickup(牌 p,牌の配列 a){
pに繋がるもの(シュンツ、コーツを形成するもの)を二枚aからピックアップ
ピックアップの仕方の全ての場合について、pickup(aの最初の要素, aの最初の要素を除いた残り)
ピックアップする事ができない→役になってない終了
}
0008デフォルトの名無しさん
NGNG最近のCPUはめちゃ早いから多少無駄な計算しても十分OK!
0009デフォルトの名無しさん
NGNG0010デフォルトの名無しさん
NGNG0011デフォルトの名無しさん
NGNG真意を教えてくれる?
0012デフォルトの名無しさん
NGNG直感的にそう思ったんだけど
ちょっと考えたらだめっぽい。
もっと考えるとやっぱりいいかもしんないけど。
0013デフォルトの名無しさん
NGNG和了の判定はまだ見当が付きやすいだけど、聴牌はちょと面倒そうだね。
5枚目の牌を待つような判定をするなよ〜。
0014デフォルトの名無しさん
NGNGソースが見れます
0015デフォルトの名無しさん
NGNG単純な縦型検索でも結構いけないかな?
0018デフォルトの名無しさん
NGNG>ANSIのCじゃない
ただのクレクレ君か。
0019ちょっと考えてみた
NGNG面子セット :探索中に見つかったすべての面子パターンを記録する
アガリ手 :アガリ手が見つかったとき登録する
聴牌フラグ :聴牌だったらON 最初はOFFではじめる
待ちパターンセット:聴牌だったときの待ち牌を登録する
start
与えられた手牌から面子セットにまだ登録されていない面子を探し出す。
(対子は1つまで、または七対子ですべて対子という制約条件付)
→見つからない。
このさき探索してもむだなのでリターン。
→見つかった。
→残り手牌がもうない。
点数がすでにあるアガリ手より高ければアガリ手に登録
リターン
→残り手牌が待ちになっている。
五枚目だったりフリテンでなければ待ちパターンに登録
聴牌フラグを立てる
リターン
→その他
残り手牌を引数にして再帰
0020ちょっと考えてみた追加
NGNGあとフリテンでもツモできるから待ちは待ちだね。
0021某ランド
NGNG1) 単純にソートして
2) 23333 32333 33233 33323 33332 2222222
の5通りに区分けしてそれぞれのシュンツ コウツ トイツ 判断 が簡単では?
てんぱいは、
1) 単純にソートする
2) 先頭から順に1個をオールマイテイとして あがり検索
0022デフォルトの名無しさん
NGNGその視点はいい(見習いたい)と思うが、単にソートしただけでは
"122334" という並びから [123] と [234] の順子を見つけられないぞ。
002322
NGNG「順子を見つけよう」という方針で "1 があったから 2 と 3 があれば取り除き"、
残りについて同じことを繰り返せばいいわけね。
俺の脳みそがソートよりも単純でした。
0024デフォルトの名無しさん
NGNGやっとわかった。脳のマージャン中枢がPC以下だったんだ。一生やめよ。
0025某ランド>22
NGNG5+1通りじゃなくて 2^4*5+1=81通りに区分けが要りますね
S=シュンツ K=コウツとして
23333 32333 33233 33323 33332 2222222
の3の所は S or K
Sの時は同じ数字が並んでいれば保留して調査させる
0026デフォルトの名無しさん
NGNG昨年末には18禁でえらいことになったゲームも有るからな。
因みに、同じパイの枚数を数えるのが肝だ>1
0027デフォルトの名無しさん
NGNGとこ少ないね(除くアーケード)
0028デフォルトの名無しさん
NGNG4枚使いの処理にも場合分けが必要な気がします。
0029デフォルトの名無しさん
NGNGとりあえず和了の判定なら槓の数だけ手牌の数が多いし
(明槓にしろ暗槓にしろ)どの4枚が槓子かは確定しているから
刻子の特殊な場合とすればいいやね。
で、聴牌判定は、当面は‘槓しない’という方針で逝っときゃいいさ。
0030ボソ
NGNGまーそもそもこんなクソ簡単な事も人に聞いちゃうレベルだからねぇ
0031デフォルトの名無しさん
NGNGですでに逝ってしまっている気が(^-^;)...
上がりのチェックだけならこんな感じでいいんじゃない?
(但し、国士・チートイは除く)
int t[44] =
/*
手牌の牌種ごとの持ち数。
全ての要素の合計は 3*X+2 枚(山からツモった時の状態とする)。
*/
{ /*九連宝燈状態*/
3,1,1,1,2,1,1,1,3,/*筒子*/ 0,/*番兵*/
0,0,0,0,0,0,0,0,0,/*索子*/ 0,/*番兵*/
0,0,0,0,0,0,0,0,0,/*万子*/ 0,/*番兵*/
0,/*東*/ 0,/*番兵*/
0,/*南*/ 0,/*番兵*/
0,/*西*/ 0,/*番兵*/
0,/*北*/ 0,/*番兵*/
0,/*白*/ 0,/*番兵*/
0,/*発*/ 0,/*番兵*/
0,/*中*/ 0,/*番兵*/
};
void f(int i)
{
for(;!t[i];i++)
if(43<=i) /*上がってる!*/
return;
if(3==t[i]){ /*刻子*/
t[i]-=3;
f(i);
t[i]+=3;
}
if(t[i+1]&&t[i+2]){ /*順子*/
t[i]--,t[i+1]--,t[i+2]--;
f(i);
t[i]++,t[i+1]++,t[i+2]++;
}
}
int main(void)
{
int i;
for(i=0;i<44;i++)
if(2<=t[i]){ /*雀頭*/
t[i]-=2;
f(0);
t[i]+=2;
}
return 0;
}
0032デフォルトの名無しさん
NGNG003331
NGNG003431
NGNG32 の言っていることは大当たりです。
何が言いたかったかというと前述 21,22 の"122334"の話の
ように現実の麻雀牌が持つ位相をコンピューター内に持ち
込もうとして苦心しているあたり、「ちょっとセンスに
問題あるんじゃない?」と思っただけです。スマン。
0035デフォルトの名無しさん
NGNG直感的にわかりやすいし、面子が分割できるので、役の判定も容易になる。
三連刻の状態ををシュンツととる/コーツととるのような多様性にも対応できる。
再帰を使うので計算時間はかかるが、今時のCPUなら問題にならない程度だろうし。
i-modeのjavaだとちときついか。
00361
NGNGいやいや、付いていけなくなってるわけじゃないですよ。ただあんまりここ来ないもんで。
皆さんレスありがとうございます。おかげさまであがりかどうかの判定は完璧に行きそうです。
しかしながら、やっかいなのが「上がり形を全部見つける」ことでして、これがどうもうまくいかない、というか
うまくいっているのかどうか自信がもてません。
ループが大量かつ煩瑣になるため、清一色のような特に多義の解釈が多い手では、
その全てを検索できているかどうかどうもよくわからないのです。
上手い方法はありませんかね。
0037デフォルトの名無しさん
NGNGチートイツ、国士判定。
for (手牌)
その牌が頭になるー>取り除いて再帰関数呼び出し
}
保存された上がり型から一番点の高いやつを選ぶ。
再帰関数(){
もし残り牌がないなら、今のきりわけ方から点数計算して保存、return
for(残りの牌)
同じ牌が2枚あるー>取り除いて再起呼び出し。
X,X+1,X+2になるー>取り除いて再起呼び出し。
}
}
0038デフォルトの名無しさん
NGNG>うまくいっているのかどうか自信がもてません。
この辺りの感覚がよく理解できないんだけど…。アルゴリズムを
見たら、うまくいっているか、穴があるかなんてすぐに分かるよね。
ループが大量?…再帰使えばそんなこと無いと思うけど。どうせ大した
場合の数じゃないんだし、じゃかすか再帰させればいいじゃん。
そしたらサクっと読みやすいんだし。
003931
NGNGもしかしてコードを読んで(or 理解して)くれて
いないんでは?(まあ、いいけど...)
もし、理解しているつもりならここでひとつクイズ。
上記 31 の刻子判定部で
if(3==t[i])
としているところは
if(3<=t[i])
としても問題なく動作するはずです。
ではなぜそうしていないのでしょうか?
そうしない利点は何でしょうか?
(暇な奴の回答もキボーン)
0040名無しさん@お腹いっぱい。
NGNGとあるとき、
先ず[3]*4を除してしまうと順子が判定されないからってことでいいの?>31
004140
NGNG0042暇な奴の回答
NGNG3==t[i] が 3<=t[i] よりいいのは、こうすると重複する検査がなくなるからだ。
例えば、fの呼び出し時に 配列 t の状態が、
int t[44] = { 4, 1, 1, 0, 0, (以下すべて0 ) };
であるような場合について考えると、3<=t[i] だと、
1筒のアンコを抜く
1-2-3筒の順子を抜く
上がってる!
1-2-3筒の順子を抜く
1筒のアンコを抜く
上がってる!
このように 上がりの形が同じであるものを2回調べてしまう。
3 == t[i] だと 1回しか調べない(下の方だけ)
ってことで合ってる?
0044デフォルトの名無しさん
NGNG途端に難しくなる。
>>21の理牌式はその点も考えているから
>ちょっとセンスに 問題あるんじゃない? は言い過ぎじゃないか?
0045デフォルトの名無しさん
NGNG画像を役全部の分用意して一部分を切り取って保存して役画像と一致するか見りゃいいだろうが!ぼけ!!
そう、何千通りの画像を用意して。
0046デフォルトの名無しさん
NGNG生姜臭え
0047デフォルトの名無しさん
NGNG0048デフォルトの名無しさん
NGNG上がり形は約1200億通りほどあるので、
1画像1kBとしてもおよそ20万GBほどの容量が必要になります。
0049デフォルトの名無しさん
NGNG>テンパイに応用しようとすると
> 途端に難しくなる。
とのことだが、
聴牌判定しようとしている手配に1筒を加えたものが
上がりになっているかどうかを判定する。
聴牌判定しようとしている手配に2筒を加えたものが
上がりになっているかどうかを判定する。
聴牌判定しようとしている手配に3筒を加えたものが
上がりになっているかどうかを判定する。
この調子で 34回(牌の種類分)調べればいいだけでは?
もちろん、実際は34回もしらべなくてもいい。
005044
NGNG要る訳で ”これがオールマイティなら” よりも重そうに思ったもので。
005145
NGNGアホだなあ。牌のパターン描いた絵から13牌取って並べればいいだろう。
0052デフォルトの名無しさん
NGNG上がり形は約1200億通りほどあるので、
1秒間に1万通り検索したとしてもおよそ4ヶ月半かかります。
0053デフォルトの名無しさん
NGNGここでも読んで頭冷やせ
0054デフォルトの名無しさん
NGNG234/234/234という分割が出来ないと思う。
0055デフォルトの名無しさん
NGNGできるよ。
刻子を取り除いたパターンの探索が終わった時点で
書き戻してるじゃん。
0056名無しサンプリング@48kHz
NGNG0057デフォルトの名無しさん
NGNG0058トリッキーの1
NGNG後は役の判定ですか。
それよりも、麻雀思考ルーチンを作ってみたい。
複数の参加者を集めて、思考ルーチン対決とか面白いかも。
ベースプログラム(配牌とか役の判定とか)は誰かが作って、
参加者は純粋にプログラムのみを作成する感じで。
言語を選ばないようにしようとすると面倒だけど(COMかソケット?)
仮に誰かがやってくれるなら是非参加したいな。
誰かがやるならば、ね。俺は面倒そうなので企画はいやです(笑)
というわけでsage
0059デフォルトの名無しさん
NGNGの数を数え上げて分類するしかないみたいだね。
思考ルーチン含めてCで1000行。
0060デフォルトの名無しさん
NGNG私もそこ紹介しようか?と思ったら外出だった。
0061デフォルトの名無しさん
NGNG僕は西原のマンガよんで、棒テン即リー全ツッパな
プログラム書いて殴られました。
0062名無しさん@お腹いっぱい。
NGNG■ このスレッドは過去ログ倉庫に格納されています