- ベストアンサー
CGI ビンゴゲームの作り方教えてください
CGIでビンゴゲーム(biglobeの「ただのビンゴ」みたいなやつ)を作りたいのですが、カードの生成方法で悩んでいます。カードの番号の並びが、だぶらないように、登録者へ配布(ページへ表示)するには、どうしたらよいでしょうか? CGIで生成したビンゴカードの数字の並びが、すでに配布済みのカードとだぶっていないかどうか、一から調べると、登録者が多い場合、処理が重くなってしまいます。 何か効率のいい方法がありましたら、教えてください。お願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
この問題、一般人には厳しいですね。 考え方としては、「あらかじめカードを作成しておき、それを一枚ずつ出す」というので正解だと思います。 で、カードの重複しない作成ですが、ビンゴカードが5×5で真中がフリーの24の数字とします(本当は1行目は1~20までの数字とか決まりがあるんだと思うけど、よく知らないので無視します)。 ○99の数字から24個を抽出 ○24個をランダムに並べる(順列) という手続きだと思います。 順列を作るプログラムは参考URLを参照していただくとして、問題は組合せですね。ちょっとサンプルが発見できませんでした。 ちょっとアルゴリズムに詳しい人なら、簡単に書けるような気がするんですが、私には無理です。すみません。 なんかヒントになるといいのですが。
その他の回答 (4)
補足見ました。 ダブりのない完全乱数を自動的に生成するのは、コンピュータが「計算機」である以上、実質不可能です。 コンピュータに任せられないのであれば自分で作るしかありません。 ですがある程度、でよければ、ランダムシードと呼ばれる数値をこちら側で制御してあげればOKです。 ランダムシードはPerlでは、関数srandに渡す値のことです。関数srandは、関数randから返ってくるランダム値の値の順番を初期化します。 ですから、以前使用したランダムシードを二度と使わないようにすれば、同じ順序のランダムがもう一度発生することはありません。 通常は srand(time); で充分ですが、これで足りないのであればこちら側でランダムシードに渡す順序をファイルか何かに格納しておけばいいでしょう。 なお、それでも不安だということであれば、1つ1つ比較するしかありません(チェックサム方式でよければそれも1つの手ですが)。
通常、重複のない複数の乱数を発生する場合は、次のようなルーチンを組みます。 for ( $i = 0; $i < 10; $i++ ) { retry: $table[$i] = int(rand(100)); for ( $j = 0; $j < $i; $j++ ) { if ( $table[$i] == $table[$j] ) { goto retry; } } } こうすれば、配列変数@table[1..10]に重複のない0~99の数字を入れることができます。 また、CGIの場合、この数字を保存したり他の利用者と共有するにはファイルを使います。 その昔、コンピュータがまだ8ビットだった頃からこの手法を使っていましたが、これで重くなったという話は聞いたことがありません(^_^; ですからこの方法で特に問題ないと思います。
- Meddlesome
- ベストアンサー率39% (59/151)
種を与えて乱数使えばよいのでは? それなら他の人とだぶらないでしょう。
お礼
ご回答、ありがとうございます。 乱数を利用して、番号の並びを変えても、同じ並びのカードができないとは言い切れないですし…。(やっぱり、多少のだぶりは仕方ないのかな?) なにか良い方法(アルゴリズム)がありましたらよろしくお願いします。
- marimo_cx
- ベストアンサー率25% (873/3452)
作り置きしてあるカードをダブらないように配付するのは別に負荷なんかかからないように思うのですが、どんなもんでしょう?
お礼
ご回答、ありがとうございます。 確かにあらかじめカードを作っておけば、番号の並びがだぶらないカードを配布する事はできるのですが、その肝心の「番号の並びがだぶらないカード」を作る方法がよくわからないので、困っています…。 乱数を利用して、番号の並びを変えても、同じ並びのカードができないとは言い切れないですし…。(やっぱり、多少のだぶりは仕方ないのかな?) なにか良い方法(アルゴリズム)がありましたらよろしくお願いします。
お礼
ご回答ありがとうございます。 今回、質問しているのは、番号の重複というより、番号の並びの重複を避ける方法が知りたいのです。(質問がわかりづらくてすみませんでした。) 乱数を利用して、番号の並びを変えても、必ず並びが重複しない!とは言い切れませんし…。 なにか良い方法がありましたら、よろしくお願いいたします。