このブログを検索

2013/04/09

麻雀メンツ検索プログラム



直した。ただし、配牌から3個ずつの牌を選ぶパターンを洗い出すのみ。


刻子や順子になっているかは判定していない。


配牌は5枚から13枚まで試して、パターン数が正しいことだけ確かめた。


たとえば10枚の時は combin(10,3) * combin(7,3) * combin(4,3) = 16800。


だが、すでにこの時点ですごく遅い。とてもじゃないが麻雀ゲームには使えない。


デバッグ用のprint文がたくさん入っているがそれだけの問題ではないだろう・・・


と思ったら、パターン数が正しいだけで同じものが大量に出力されているので削除。





どうにもならないので、簡単なものから徐々に作っていく。


まずは、与えられた文字列から3文字ずつ選ぶパターンを網羅するもの。



use strict;
use warnings;

my $haipai = shift;

if(length($haipai)<0){print "specify haipai.\n"; exit;};

print "haipai : $haipai\n";

my $max_menz = int(length($haipai) / 3);

print "max_menz : $max_menz\n";

my @haipai = split("", $haipai);

my $count = 0;

&select_menz(\@haipai);

sub select_menz{
my ($array_ref) = @_;

my ($i, $j, $k) = (0, 1, 2);

while($i<$#$array_ref-1){
$count++;
print "$count : ".$array_ref->[$i].$array_ref->[$j].$array_ref->[$k]."\n";
$k++;
if($k>$#$array_ref){
$j++;
$k=$j+1;
if($j>$#$array_ref-1){
$i++;
$j=$i+1;
$k=$j+1;
}
}
}
}


これは間違いないと思う。


ここからが問題だ。


配列のリファレンスを与えて、その配列から3個の要素を選択するパターンを網羅することはできた。


それなら、各パターンについて、選択済みの要素を削除した配列を、再度このサブルーチンに渡せば、のこった要素の中から3個を選ぶパターンが網羅され、


それを要素が3個になるまで繰り返せばよい、と思う。


だが、問題がある。


まず、「配列から選択済みの要素を削除する」をどうするかだ。


たとえば「12345」という文字列から最初に選択する3文字のパターンは「123」である。


これを削除した配列は「45」である。


@array = (1,2,3,4,5)


だったとすると、


$array[0], $array[1], $array[2] を削除すればよい。


しかし・・・