昨日の続きなのですが,いくつかビンゴカードを見て,間違いに気づきました.たとえば「1〜15から5個」取って縦方向に並べる際,数値の順番はばらばらです.昨日のプログラムをそのまま使うと,各列,上から下へ数字が大きくなってしまいます.
修正の方法としては,「array << ofst」のところを,
array.insert(rand(array.size + 1), ofst)
とすればいいようです.arrayが空のとき,rand(1)は仕様により常に0になり,結局「array[0] = ofst」と等価になりますが,ちょっと気持ち悪いですね.
chooseを丸ごと変えてしまうという別解もあります.
def choose(max, pcs, ofst = 1) (ofst...(ofst + max)).to_a.shuffle[0, pcs] end
shuffleは Ruby 1.9で組み込まれたメソッドですが,1.8.7でも使用可能になっています*1.ただし,1.8.7で試したところ,単純なchooseの取り換えでは,何度実行しても,同じ結果になります.実行の初めに「srand」を入れれば*2,変わりました.randでは暗黙のsrandがありますが,shuffleでは明示しないといけないようです.
字数はなるべく減らしています.「(ofst...(ofst + max))」は「(ofst..(ofst + max - 1))」と同じです.ofstが1,maxが15なら,いずれも「1〜15のRangeオブジェクト」となります.shuffleの直後の「[0, pcs]」は,shuffleの引数ではなく,shuffleにより得られた配列の先頭pcs個を取り出すものです.
うーん,まだビンゴカード生成にたどりつけません.明日こそ.
*1:Ruby 1.8.7で使えるようになったRuby 1.9のメソッドたち - http://rubikitch.com/に移転しました,配列のシャッフルの決まり文句は「sort_by{ rand }」だった - http://rubikitch.com/に移転しました.自前で定義するなら,http://ruby.kyoto-wu.ac.jp/RubyKan/?%CC%E4%C2%EA1%20%C7%DB%CE%F3%A4%CE%A5%B7%A5%E3%A5%C3%A5%D5%A5%EB
*2:chooseの中でなくてもかまいません.繰り返しchooseを呼び出すことを考えると,中に書かないほうがいいでしょうね.