hellnearメモ帳

ゲームに関することとかプログラム関係だとかのメモ

ガチャの抽選っぽいもの

ちょっとしたゲーム作ってみたいなと思って、rubyでガチャの抽選っぽいもの作ってみた。
ランクの抽選→カードの抽選

class Gacha
  def initialize(args)
    @rank_weight_table = args[:rank_weight_table]
    @card_list         = args[:card_list]
  end

  # 排出されるランク
  def pick_rank
    range = @rank_weight_table.values.inject(:+)
    rank_pick_num = rand(range) + 1

    pick_rank = @rank_weight_table.each do |rank, weight|
      break rank if rank_pick_num <= weight

      rank_pick_num -= weight
    end
  end

  def pick_card_num(rank)
    rand(@card_list[rank].length)
  end

  def pick_card(rank, num)
    @card_list[rank][num]
  end

  def pick(rank: nil)
    rank ||= pick_rank
    pick_card(rank, pick_card_num(rank))
  end
end

class Card
  attr_reader :name, :rank
  def initialize(args)
    @name = args[:name] || "card"
    @rank = args[:rank] || :N
  end
end

# ランクごとの重み
# 今は合計100なので、Nが60%の確率で排出
rank_weight_table = {
  N: 60,
  R: 30,
  SR: 5,
  SSR: 3,
  LR: 2,
}

# ランクごとの枚数
# 下のカードリスト生成で必要
card_num = {
  N: 30,
  R: 45,
  SR: 30,
  SSR: 20,
  LR: 10, 
}

card_list = {}

# ランクごとにカードを作成して格納
card_num.each do |rank, c_num|
  card_list[rank] = []
  c_num.times do |num|
    card = Card.new(
      name: "#{rank}_#{num}",
      rank: rank
    )
    card_list[rank] << card
  end
end

# 10連
g = Gacha.new(rank_weight_table: rank_weight_table, card_list: card_list)
10.times do
  p g.pick.name
end

# "N_22"
# "N_21"
# "R_44"
# "N_6"
# "N_8"
# "N_8"
# "SSR_14"
# "R_35"
# "N_21"
# "N_2"