class BCDice::GameSystem::CthulhuTech::Test

行為判定のノード

Constants

COMPARE_OP

判定で用いる比較演算子

対抗判定で変えられるように定数で定義する。

Public Class Methods

new(num, modifier, difficulty) click to toggle source

ノードを初期化する @param [Integer] num ダイス数 @param [Integer] modifier 修正値 @param [Integer] difficulty 難易度

# File lib/bcdice/game_system/CthulhuTech.rb, line 43
def initialize(num, modifier, difficulty)
  @num = num
  @modifier = modifier
  @difficulty = difficulty
end

Public Instance Methods

execute(randomizer) click to toggle source

判定を行う @param randomizer [Randoizer] @return [String] 判定結果

# File lib/bcdice/game_system/CthulhuTech.rb, line 52
def execute(randomizer)
  dice_values = randomizer.roll_barabara(@num, 10)

  # ファンブル:出目の半分(小数点以下切り上げ)以上が1の場合
  fumble = dice_values.count(1) >= (dice_values.length + 1) / 2

  sorted_dice_values = dice_values.sort
  roll_result = calculate_roll_result(sorted_dice_values)
  test_value = roll_result + @modifier

  diff = test_value - @difficulty

  # diff と @difficulty との比較の演算子が変わるので、send で対応
  # 例:COMPARE_OP が :>= ならば、diff >= 0 と同じ
  success = !fumble && diff.send(self.class::COMPARE_OP, 0)

  critical = diff >= 10

  output_parts = [
    "(#{expression()})",
    test_value_expression(sorted_dice_values, roll_result),
    test_value,
    result_str(success, fumble, critical, diff)
  ]

  return output_parts.join(' > ')
end

Private Instance Methods

calculate_roll_result(sorted_dice_values) click to toggle source

ダイスロール結果を計算する

以下のうち最大のものを返す。

  • 出目の最大値

  • ゾロ目の和の最大値

  • ストレート(昇順で連続する3個以上の値)の和の最大値

@param [Array<Integer>] sorted_dice_values 昇順でソートされた出目の配列 @return [Integer]

# File lib/bcdice/game_system/CthulhuTech.rb, line 123
def calculate_roll_result(sorted_dice_values)
  highest_single_roll = sorted_dice_values.last

  sum_of_highest_set_of_multiples = sorted_dice_values
                                    .group_by(&:itself)
                                    .values
                                    .map(&:sum)
                                    .max

  candidates = [
    highest_single_roll,
    sum_of_highest_set_of_multiples,
    sum_of_largest_straight(sorted_dice_values)
  ]

  return candidates.max
end
expression() click to toggle source

数式表現を返す @return [String]

# File lib/bcdice/game_system/CthulhuTech.rb, line 84
def expression
  modifier_str = Format.modifier(@modifier)
  return "#{@num}D10#{modifier_str}#{self.class::COMPARE_OP}#{@difficulty}"
end
result_str(success, fumble, critical, _diff) click to toggle source

判定結果の文字列を返す @param [Boolean] success 成功したか @param [Boolean] fumble ファンブルだったか @param [Boolean] critical クリティカルだったか @param [Integer] _diff 判定値と難易度の差 @return [String]

# File lib/bcdice/game_system/CthulhuTech.rb, line 106
def result_str(success, fumble, critical, _diff)
  return 'ファンブル' if fumble
  return 'クリティカル' if critical

  return success ? '成功' : '失敗'
end
sum_of_largest_straight(sorted_dice_values) click to toggle source

ストレートの和の最大値を求める

ストレートとは、昇順で3個以上連続した値のこと。

@param [Array<Integer>] sorted_dice_values 昇順にソートされた出目の配列 @return [Integer] ストレートの和の最大値 @return [0] ストレートが存在しなかった場合

# File lib/bcdice/game_system/CthulhuTech.rb, line 148
def sum_of_largest_straight(sorted_dice_values)
  # 出目が3個未満ならば、ストレートは存在しない
  return 0 if sorted_dice_values.length < 3

  # ストレートの和の最大値
  max_sum = 0

  # 連続した値の数
  n_consecutive_values = 0
  # 連続した値の和
  sum = 0
  # 直前の値
  # 初期値を負の値にして、最初の値と連続にならないようにする
  last = -1

  sorted_dice_values.uniq.each do |value|
    # 値が連続でなければ、状態を初期化する(現在の値を連続1個目とする)
    if value - last > 1
      n_consecutive_values = 1
      sum = value
      last = value

      next
    end

    # 連続した値なので溜める
    n_consecutive_values += 1
    sum += value
    last = value

    # ストレートならば、和の最大値を更新する
    if n_consecutive_values >= 3 && sum > max_sum
      max_sum = sum
    end
  end

  return max_sum
end
test_value_expression(dice_values, roll_result) click to toggle source

判定値の数式表現を返す @param [Array<Integer>] dice_values 出目の配列 @param [Integer] roll_result ダイスロール結果の値 @return [String]

# File lib/bcdice/game_system/CthulhuTech.rb, line 93
def test_value_expression(dice_values, roll_result)
  dice_str = dice_values.join(',')
  modifier_str = Format.modifier(@modifier)

  return "#{roll_result}[#{dice_str}]#{modifier_str}"
end