class BCDice::CommonCommand::Repeat
リピート
繰り返し回数を指定して、特定のコマンドを複数回実行する 例)
x5 choice[A,B,C,D] #=> `choice[A,B,C,D]`を5回実行する rep2 CC<=75 #=> `CC<=75`を2回実行する repeat10 2D6+5 #=> `2D6+6`を10回実行する
このコマンドを入れ子させることは許容しない。繰り返し回数の爆発に繋がるためである。 以下は実行時にエラーとなる。
x10 repeat100 100D100
Constants
- PREFIX_PATTERN
- REPEAT_LIMIT
Public Class Methods
eval(command, game_system, randomizer)
click to toggle source
# File lib/bcdice/common_command/repeat.rb, line 24 def eval(command, game_system, randomizer) cmd = parse(command) cmd&.roll(game_system, randomizer) end
new(secret:, times:, trailer:)
click to toggle source
# File lib/bcdice/common_command/repeat.rb, line 55 def initialize(secret:, times:, trailer:) @secret = secret @times = times @trailer = trailer end
Private Class Methods
parse(command)
click to toggle source
# File lib/bcdice/common_command/repeat.rb, line 31 def parse(command) scanner = StringScanner.new(command) secret = !scanner.scan(/s/i).nil? keyword = scanner.scan(/repeat|rep|x/i) repeat_times = scanner.scan(/\d+/)&.to_i whitespace = scanner.scan(/\s+/) if keyword.nil? || repeat_times.nil? || whitespace.nil? return nil end trailer = scanner.post_match if trailer.nil? || trailer.empty? return nil end new( secret: secret, times: repeat_times, trailer: trailer ) end
Public Instance Methods
roll(game_system, randomizer)
click to toggle source
# File lib/bcdice/common_command/repeat.rb, line 61 def roll(game_system, randomizer) err = validate() return err if err results = Array.new(@times) do cmd = game_system.class.new(@trailer) cmd.randomizer = randomizer cmd.eval() end if results.count(nil) == @times return result_with_text("繰り返し対象のコマンドが実行できませんでした (#{@trailer})") end text = results.map.with_index(1) { |r, index| "\##{index}\n#{r.text}" }.join("\n\n") secret = @secret || results.any?(&:secret?) Result.new.tap do |r| r.secret = secret r.text = text end end
Private Instance Methods
result_with_text(text)
click to toggle source
# File lib/bcdice/common_command/repeat.rb, line 94 def result_with_text(text) Result.new.tap do |r| r.secret = @secret r.text = text end end
validate()
click to toggle source
# File lib/bcdice/common_command/repeat.rb, line 86 def validate if /\A(repeat|rep|x)\d+/.match?(@trailer) result_with_text("Repeatコマンドの重複はできません") elsif @times < 1 || REPEAT_LIMIT < @times result_with_text("繰り返し回数は1以上、#{REPEAT_LIMIT}以下としてください") end end