これ…少しだけ特殊ルールの「こいこい」をやってみたのだけど、んまぁシャッフルがひどい。
真ん中の左寄りに横4×縦2で並んでいるのが場札。下の8枚がプレイヤーの手札。
場札を見たらボタン2枚にサクラが2枚、ついでにアヤメも2枚。
手札はモミジが2枚にウメが2枚。
現実の花札で、こういうことはほぼ絶対に起きない。ところがこのゲームでは、こういうことが普通に起きる。キッチリ並んでる札をザクザクザクと3回ぐらい切った感じ。おかげでゲームバランスが悪いったらありゃしない。
自分のプログラミング経験から、まず乱数を疑ったのね。
私の若い頃、Microsoft 系 BASIC の疑似乱数ってば16ビットの線形合同法で質が悪くて。そのせいで、この手のカードゲームを組むってときシャッフルがどうにもならなかった。
メルセンヌ・ツイスタのご時世に、こんなシャッフルあるんかい???であって。
そんで調べたら JavaScript の乱数の実装は、仕様上はブラウザ任せだけど、普通は Xorshift らしい(Chrome は32ビットのようだ)。メルセンヌ・ツイスタほどじゃないにしても、16ビット線形合同法よりはるかにマトモであるようだ。
っつーことは、シャッフルのルーチン自体に問題がありそうだ。main.js を見てみる。JavaScript は完全に無経験だけど。
まずメインのところで
function start_oneplay()
{(中略)
// シャッフル
while( !shuffle() ){
}(後略)
そいじゃあ shuffle() はと見てみたら
function shuffle(){
var i;
for( i=0; i<48; i++ ){
var r = Math.floor(Math.random()*48);
var tmp=game.yama[i];
game.yama[i]=game.yama[r];
game.yama[r]=tmp;
}(後略)
一巡しか入れ替えやってないじゃん _| ̄|〇
いくら Xorshift が16ビット線形合同法よりマシなアルゴリズムだからって、入れ替えが一巡だけって…普通にありえんわ。
このコードには続きがあって、何をやってんだか読み解くのに苦労したけど、要するに場札・手札に同じ月(植物)の札が3枚あるかどうかをチェックして、3枚あったら false を返し、なかったら true を返すということのようだ。
そいでメインのところが while ( !shuffle() ) だから、3枚なかったら !shuffle() は false になるからそれでおしまい、あったらまた shuffle() を呼び出すという話。リアルなルールとまったく同じことだ…リアルでは札を配った後、手札あるいは場札に同じ月の札があったら再びシャッフルし直し。
アタマにきたので html やら何やらかんやらを PC にダウンロードして、main.js をいじってみた。いろいろ試行錯誤したけど:
function shuffle(){
var i, p, s, tmp;
for( i=0; i<6144; i++ ){
p = Math.floor(Math.random()*48);
s = Math.floor(Math.random()*48);
tmp=game.yama[p];
game.yama[p]=game.yama[s];
game.yama[s]=tmp;
}
変数 p と s は、この後の3枚チェックの部分で var p= なんて感じで宣言されて使われるので、関数の最初のところで宣言しといた。これで入れ替え48回×128回=6,144回ということになる。
これでどうやらマトモなシャッフルになったわい。やれやれ…とは言えこれ元々スマホ向けであって、これじゃあ回数が多すぎて重たいかも知れない。もっと少なくて良いと思う。
gamedesign.jp様、どうにかしてください。