直した。ただし、配牌から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] を削除すればよい。
しかし・・・