Class: SGK::Gacha::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/sgk/gacha/engine.rb

Overview

重み付きガチャエンジン

Instance Method Summary collapse

Constructor Details

#initialize(card_relation) ⇒ Engine

Returns a new instance of Engine.



7
8
9
10
11
# File 'lib/sgk/gacha/engine.rb', line 7

def initialize(card_relation)
  @cards = card_relation.to_a
  validate_cards!
  @total_weight = @cards.sum(&:weight)
end

Instance Method Details

#drawObject



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/sgk/gacha/engine.rb', line 13

def draw
  return nil if @cards.empty?

  random_value = rand(0...@total_weight)
  current_sum = 0

  @cards.each do |card|
    current_sum += card.weight
    return card if random_value < current_sum
  end

  # NOTE: 浮動小数点誤差を考慮して最後のカードを返す実装だが、重み付き抽選の特性上起こる可能性はほとんどない。
  @cards.last
end

#draw_multiple(count) ⇒ Array<Object>

単一操作で複数のカードを抽選する(例:10連ガチャ)。

Parameters:

  • count (Integer)

    抽選するカードの枚数

Returns:

  • (Array<Object>)

    抽選されたカードの配列

Raises:

  • (ArgumentError)

    countが正の値でない場合



33
34
35
36
37
# File 'lib/sgk/gacha/engine.rb', line 33

def draw_multiple(count)
  raise ArgumentError, "Draw count must be positive" unless count.positive?

  Array.new(count) { draw }
end

#probabilitiesObject



39
40
41
42
43
44
45
# File 'lib/sgk/gacha/engine.rb', line 39

def probabilities
  result = {}
  @cards.each do |card|
    result[card.id] = (card.weight.to_f / @total_weight * 100).round(2)
  end
  result
end