ルギア君の戯言

雑多な記事。

ポケダンのスクラッチくじ

ものの本性を見たくなるのは常にあることである(謎)。


真相は「たいようのいし」が欲しい (景品の中にあるのかも「僕は」知らないが…たしか「つきのいし」は見かけた)。
LV100 になるまえに絶対チュリネを進化させるぞ! と思っていたのだが、LV100 になるほうが残念ながら先になってしまった。『ドレディアを直接仲間にしろ』という話は受け付けないのでよろしく。


実力が伴う「ホッケー」や「潜水」は問題外として、くじはランダムだから、目的の物をゲットするのが少しむずかしいと思うのね。本当はダンジョン内で見つかるのが一番早いけど…。


なぜスクラッチかというと、

  • スピードくじはくじびきけんをとってくるのが面倒
  • けんしょうくじはダンジョンに行かないといけないのが面倒

というわけ。まあ、お金も 9,999 しか持てないからこれをいっぱいやっていると結構頻繁にあずかりボックスまで戻ることになるが…。

確認事項

  • 店員さんは乱数に無関係
  • 複数建設する理由もまずない
  • 1枚のスクラッチカードに対して、数学的なあたる確率は \frac{3}{5}。大当たりする確率は \frac{1}{5}。計算は省略。
  • 削る場所を選り好みしない。
  • ある特定の景品をゲットするのに何回くじをやれば良いかを考える。

ゲームから未確認の前提条件

  • 景品の種類があたり用、おおあたり用それぞれ別の 40 種類と仮定
    • 実際にカウントする際には、「てきしばりだま」「てきしばりだま×2」は別物と考える。
    • ここでは番号できめることにする (1〜80)。
  • 乱数にメルセンヌツイスタを使う
    • アルゴリズム以外にもどこからどのように使うかも問題はある。
    • メルセンヌツイスタなのは下で出てくる Ruby がそうだから。それだけ。

そこで、したのようなプログラムを作る (このプログラムは Ruby 1.9 以降でしか動かない上、いくつか問題を抱えています)。

#!/usr/bin/ruby

# カード (1 がマークのあるところ)
card = [0, 0, 1, 1, 1, 1]

# 景品 (1〜40 は あたり用、41〜80 はおおあたり用)
award = {
  :win     => (1..40).to_a,
  :jackpot => (41..80).to_a
}

# ゲットした景品
get  = []
# ほしい景品
want = 51

# 統計情報用 (それぞれ得た回数)
data = {
  :lose    => 0,
  :win     => 0,
  :jackpot => 0,

  :got_time => [],
  :got_time_max => nil,
  :got_time_min => nil,
}

# 1000回トライしてみて、取れるまでの平均を求める。
1000.times do
  # 得た景品をリセット
  get = []

  loop do |i|
    # 景品を決める
    aw = {
      :win => award[:win].sample,
      :jackpot => award[:jackpot].sample
    }

    # カードを作る
    card = card.shuffle

    # 削るところを選ぶ
    kezuri = card.sample(3)

    # 判定
    case kezuri.inject(0) { |s, m| s + m }
    when 1
      data[:lose] += 1
    when 2
      data[:win] += 1
      get << aw[:win]
    
      # 欲しい景品ならループを抜ける
      break if aw[:win] == want
    when 3
      data[:jackpot] += 1
      get << aw[:jackpot]
      break if aw[:jackpot] == want
    end
  end

  # 集計
  s = get.size
  data[:got_time] << s
  data[:got_time_max] ||= s
  data[:got_time_min] ||= s
  if data[:got_time_max] < s then
    data[:got_time_max] = s
  end
  if data[:got_time_min] > s then
    data[:got_time_min] = s
  end
end

# 結果を表示
puts "LOSE   : %7d" % data[:lose]
puts "WIN    : %7d" % data[:win]
puts "JACKPOT: %7d" % data[:jackpot]
puts ""
ave = data[:got_time].inject(0) { |s, m| s + m } / data[:got_time].size.to_f
puts "Average Challenge to get #{want}: #{ave}"

実行すると、

$ ruby scratch.rb
LOSE   :   40570
WIN    :  121298
JACKPOT:   40242

Average Challenge to get 51: 161.54
Maximum Challenge to get 51: 1622
Minimum Challenge to get 51: 1

となります。最悪で 1600 回もやらないと得られないとか、だるすぎる。


次、その景品が「あたり」の場合。

$ ruby scratch.rb
LOSE   :   13599
WIN    :   41162
JACKPOT:   13697

Average Challenge to get 11: 54.859
Maximum Challenge to get 11: 539
Minimum Challenge to get 11: 1

これでも最悪で 539 とかまで行ってますね。当然、あたる確率が3倍なので、必要な挑戦回数は3分の1で済みますね。また景品の種類が倍なら、必要な挑戦回数も倍になります。


ただ具体的な目安が欲しかったという話。


PS: そうとう金をつぎ込んだけど、やっぱり景品にない…?