From be60cc7ac30199096027815b7fcab9856f5ba97c Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 01:53:35 +0900 Subject: [PATCH 01/20] =?UTF-8?q?=E3=83=91=E3=83=BC=E3=82=B5=E3=83=BC?= =?UTF-8?q?=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .rubocop.yml | 1 + Rakefile | 1 + .../game_system/sword_world/rating_lexer.rb | 47 ++++ .../game_system/sword_world/rating_parsed.rb | 65 ++++++ .../game_system/sword_world/rating_parser.y | 215 ++++++++++++++++++ .../test_sword_world_rating_command_parser.rb | 158 +++++++++++++ 7 files changed, 488 insertions(+) create mode 100644 lib/bcdice/game_system/sword_world/rating_lexer.rb create mode 100644 lib/bcdice/game_system/sword_world/rating_parsed.rb create mode 100644 lib/bcdice/game_system/sword_world/rating_parser.y create mode 100644 test/test_sword_world_rating_command_parser.rb diff --git a/.gitignore b/.gitignore index 23fad00c6..7d7be8be3 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ lib/bcdice/common_command/barabara_dice/parser.rb lib/bcdice/common_command/calc/parser.rb lib/bcdice/common_command/reroll_dice/parser.rb lib/bcdice/common_command/upper_dice/parser.rb +lib/bcdice/game_system/sword_world/rating_parser.rb diff --git a/.rubocop.yml b/.rubocop.yml index b57ea1f7a..d085fb8ff 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -15,6 +15,7 @@ AllCops: - lib/bcdice/common_command/calc/parser.rb - lib/bcdice/common_command/reroll_dice/parser.rb - lib/bcdice/common_command/upper_dice/parser.rb + - lib/bcdice/game_system/sword_world/rating_parser.rb # Due to old Ruby 1.8.x Style/Lambda: diff --git a/Rakefile b/Rakefile index d44c804e5..687430f11 100644 --- a/Rakefile +++ b/Rakefile @@ -28,6 +28,7 @@ RACC_TARGETS = [ "lib/bcdice/common_command/calc/parser.rb", "lib/bcdice/common_command/reroll_dice/parser.rb", "lib/bcdice/common_command/upper_dice/parser.rb", + "lib/bcdice/game_system/sword_world/rating_parser.rb", ].freeze task racc: RACC_TARGETS diff --git a/lib/bcdice/game_system/sword_world/rating_lexer.rb b/lib/bcdice/game_system/sword_world/rating_lexer.rb new file mode 100644 index 000000000..d316ca96a --- /dev/null +++ b/lib/bcdice/game_system/sword_world/rating_lexer.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require "strscan" + +module BCDice + module GameSystem + class SwordWorld < Base + class RatingLexer + SYMBOLS = { + "+" => :PLUS, + "-" => :MINUS, + "*" => :ASTERISK, + "/" => :SLASH, + "(" => :PARENL, + ")" => :PARENR, + "[" => :BRACKETL, + "]" => :BRACKETR, + "@" => :AT, + "#" => :SHARP, + "$" => :DOLLAR, + }.freeze + + def initialize(source) + # sourceが空文字だとString#splitが空になる + source = source&.split(" ", 2)&.first || "" + @scanner = StringScanner.new(source) + end + + def next_token + return [false, "$"] if @scanner.eos? + + if (number = @scanner.scan(/\d+/)) + [:NUMBER, number.to_i] + else + char = @scanner.getch.upcase + type = SYMBOLS[char] || char.to_sym + [type, char] + end + end + + def source + @scanner.string + end + end + end + end +end diff --git a/lib/bcdice/game_system/sword_world/rating_parsed.rb b/lib/bcdice/game_system/sword_world/rating_parsed.rb new file mode 100644 index 000000000..cd7368115 --- /dev/null +++ b/lib/bcdice/game_system/sword_world/rating_parsed.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module BCDice + module GameSystem + class SwordWorld < Base + class RatingParsed + # @return [Boolean] + attr_accessor :half + + # @return [Integer] + attr_accessor :rate + + # @return [Integer, nil] + attr_accessor :critical + + # @return [Integer, nil] + attr_accessor :kept_modify + + # @return [Integer, nil] + attr_accessor :first_to + + # @return [Integer, nil] + attr_accessor :first_modify + + # @return [Integer, nil] + attr_accessor :rateup + + # @return [Boolean, nil] + attr_accessor :greatest_fortune + + # @return [Integer] + attr_accessor :modifier + + # @return [Integer] + attr_accessor :modifier_after_half + + def initialize + @half = false + @critical = nil + @kept_modify = nil + @first_to = nil + @first_modify = nil + @greatest_fortune = nil + @rateup = nil + end + + # @return [String] + def to_s() + h = @half ? "H" : nil + r = "K#{@rate}" + c = @critical ? "@#{@critical}" : nil + ft = @first_to ? "$#{@first_to}" : nil + fm = @first_modify ? "$#{Format.modifier(@first_modify)}" : nil + km = @kept_modify ? "##{@kept_modify}" : nil + gf = @greatest_fortune ? "GF" : nil + ru = @rateup ? "r#{@rateup}" : nil + m = Format.modifier(@modifier) + mah = @half ? Format.modifier(@modifier_after_half) : nil + + [r, m, c, ft, fm, km, gf, ru, h, mah].join() + end + end + end + end +end diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y new file mode 100644 index 000000000..8e16c5d35 --- /dev/null +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -0,0 +1,215 @@ +class RatingParser + token NUMBER K R H G F PLUS MINUS ASTERISK SLASH PARENL PARENR BRACKETL BRACKETR AT SHARP DOLLAR + + expect 4 + + rule + expr: rate option + { + rate, option = val + modifier = option[:modifier].nil? ? Arithmetic::Node::Number.new(0) : option[:modifier] + result = parsed(rate, modifier, option) + } + | H rate option + { + _, rate, option = val + option[:modifier_after_half] = Arithmetic::Node::Number.new(0) if option[:modifier_after_half].nil? + modifier = option[:modifier].nil? ? Arithmetic::Node::Number.new(0) : option[:modifier] + result = parsed(rate, modifier, option) + } + + + rate: K NUMBER + { result = val[1].to_i } + + option: /* none */ + { + result = {} + } + | option modifier + { + option, term = val + raise ParseError unless option[:modifier].nil? + + option[:modifier] = term + result = option + } + | option BRACKETL unary BRACKETR + { + option, _, term, _ = val + raise ParseError unless option[:critical].nil? + + option[:critical] = term + result = option + } + | option AT unary + { + option, _, term = val + raise ParseError unless option[:critical].nil? + + option[:critical] = term + result = option + } + | option DOLLAR NUMBER + { + option, _, term = val + raise ParseError unless option[:first_to].nil? && option[:first_modify].nil? + + option[:first_to] = term.to_i + result = option + } + | option DOLLAR PLUS NUMBER + { + option, _, _, term = val + raise ParseError unless option[:first_to].nil? && option[:first_modify].nil? + + option[:first_modify] = term.to_i + result = option + } + | option DOLLAR MINUS NUMBER + { + option, _, _, term = val + raise ParseError unless option[:first_to].nil? && option[:first_modify].nil? + + option[:first_modify] = -(term.to_i) + result = option + } + | option H + { + option, _ = val + option[:modifier_after_half] = Arithmetic::Node::Number.new(0) + result = option + } + | option H unary + { + option, _, term = val + raise ParseError unless option[:modifier_after_half].nil? + + option[:modifier_after_half] = term + result = option + } + | option R unary + { + option, _, term = val + raise ParseError unless [:v2_5, :v2_0].include?(@version) && option[:rateup].nil? + + option[:rateup] = term + result = option + } + | option G F + { + option, _, _ = val + raise ParseError unless [:v2_5, :v2_0].include?(@version) && option[:greatest_fortune].nil? + + option[:greatest_fortune] = true + result = option + } + | option SHARP unary + { + option, _, term = val + raise ParseError unless @version == :v2_5 && option[:kept_modify].nil? + + option[:kept_modify] = term + result = option + } + + modifier: PLUS mul + { result = val[1] } + | MINUS mul + { result = Arithmetic::Node::Negative.new(val[1]) } + | modifier PLUS mul + { result = Arithmetic::Node::BinaryOp.new(val[0], :+, val[2]) } + | modifier MINUS mul + { result = Arithmetic::Node::BinaryOp.new(val[0], :-, val[2]) } + + add: add PLUS mul + { result = Arithmetic::Node::BinaryOp.new(val[0], :+, val[2]) } + | add MINUS mul + { result = Arithmetic::Node::BinaryOp.new(val[0], :-, val[2]) } + | mul + + mul: mul ASTERISK unary + { result = Arithmetic::Node::BinaryOp.new(val[0], :*, val[2]) } + | mul SLASH unary + { + divied_class = val[3] + result = divied_class.new(val[0], val[2]) + } + | unary + + unary: PLUS unary + { result = val[1] } + | MINUS unary + { result = Arithmetic::Node::Negative.new(val[1]) } + | term + + term: PARENL add PARENR + { result = val[1] } + | NUMBER + { result = Arithmetic::Node::Number.new(val[0]) } +end + +---- header + +require "bcdice/arithmetic/node" +require "bcdice/game_system/sword_world/rating_lexer" +require "bcdice/game_system/sword_world/rating_parsed" + +# SwordWorldの威力表コマンドをパースするクラス +module BCDice + module GameSystem + class SwordWorld < Base + +---- inner + +def initialize() + super() + @version = :v1_0 +end + +# バージョンを指定する +# @return [BCDice::GameSystem::SwordWorld::RatingParser] +def set_version(version) + @version = version + self +end + +def set_debug + @yydebug = true + return self +end + +# @param source [String] +# @return [BCDice::GameSystem::SwordWorld::RatingParsed, nil] +def parse(source) + @lexer = RatingLexer.new(source) + do_parse() +rescue ParseError, ZeroDivisionError + nil +end + +private + +def parsed(rate, modifier, option) + RatingParsed.new.tap do |p| + p.rate = rate + p.critical = option[:critical]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) + p.kept_modify = option[:kept_modify]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) + p.first_to = option[:first_to] + p.first_modify = option[:first_modify] + p.rateup = option[:rateup]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) + p.greatest_fortune = option.fetch(:greatest_fortune, false) + p.modifier = modifier.eval(Arithmetic::Node::DivideWithGameSystemDefault) + p.half = !option[:modifier_after_half].nil? + p.modifier_after_half = option[:modifier_after_half]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) + end +end + +def next_token + @lexer.next_token +end + +---- footer + end + end +end diff --git a/test/test_sword_world_rating_command_parser.rb b/test/test_sword_world_rating_command_parser.rb new file mode 100644 index 000000000..9f57de913 --- /dev/null +++ b/test/test_sword_world_rating_command_parser.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true + +require "test/unit" +require "bcdice/base" +require "bcdice/game_system/sword_world/rating_parser" + +class BCDice::GameSystem::SwordWorld < BCDice::Base; end + +class TestSwordWorldRatingCommandParser < Test::Unit::TestCase + def setup + @parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + end + + def test_parse_v1_full_first_modify + parsed = @parser.parse("K20+5+3@9$+1H+2") + + assert_not_nil(parsed) + assert_equal(20, parsed.rate) + assert_equal(8, parsed.modifier) + assert_equal(9, parsed.critical) + assert_nil(parsed.kept_modify) + assert_nil(parsed.first_to) + assert_equal(1, parsed.first_modify) + assert_false(parsed.greatest_fortune) + assert_nil(parsed.rateup) + assert_true(parsed.half) + assert_equal(2, parsed.modifier_after_half) + end + + def test_parse_v1_full_first_to + parsed = @parser.parse("K20+5+3@9$8H+2") + + assert_not_nil(parsed) + assert_equal(20, parsed.rate) + assert_equal(8, parsed.modifier) + assert_equal(9, parsed.critical) + assert_nil(parsed.kept_modify) + assert_equal(8, parsed.first_to) + assert_nil(parsed.first_modify) + assert_false(parsed.greatest_fortune) + assert_nil(parsed.rateup) + assert_true(parsed.half) + assert_equal(2, parsed.modifier_after_half) + end + + def test_parse_v1_head_half + parsed = @parser.parse("HK30+5+3") + + assert_not_nil(parsed) + assert_equal(30, parsed.rate) + assert_equal(8, parsed.modifier) + assert_nil(parsed.critical) + assert_nil(parsed.kept_modify) + assert_nil(parsed.first_to) + assert_nil(parsed.first_modify) + assert_false(parsed.greatest_fortune) + assert_nil(parsed.rateup) + assert_true(parsed.half) + assert_equal(0, parsed.modifier_after_half) + end + + def test_parse_v1_brace_critical + parsed = @parser.parse("K50[8]+5+3") + + assert_not_nil(parsed) + assert_equal(50, parsed.rate) + assert_equal(8, parsed.modifier) + assert_equal(8, parsed.critical) + assert_nil(parsed.kept_modify) + assert_nil(parsed.first_to) + assert_nil(parsed.first_modify) + assert_false(parsed.greatest_fortune) + assert_nil(parsed.rateup) + assert_false(parsed.half) + assert_nil(parsed.modifier_after_half) + end + + def test_parse_v1_brace_critical_only + parsed = @parser.parse("K50[8]") + assert_not_nil(parsed) + assert_equal(50, parsed.rate) + assert_equal(0, parsed.modifier) + assert_equal(8, parsed.critical) + assert_nil(parsed.kept_modify) + assert_nil(parsed.first_to) + assert_nil(parsed.first_modify) + assert_false(parsed.greatest_fortune) + assert_nil(parsed.rateup) + assert_false(parsed.half) + assert_nil(parsed.modifier_after_half) + end + + def test_parse_v1_brace_critical_duplicate + parsed = @parser.parse("K50[8]+5+3@9") + + assert_nil(parsed) + end + + def test_parse_v1_gf_unsupported + parsed = @parser.parse("K50[8]+5+3gf") + + assert_nil(parsed) + end + + def test_parse_v1_kept_modify_unsupported + parsed = @parser.parse("K50[8]+5+3#+1") + + assert_nil(parsed) + end + + def test_parse_v1_rateup_unsupported + parsed = @parser.parse("K50[8]+5+3r10") + + assert_nil(parsed) + end + + def test_parse_v20_full + @parser.set_version(:v2_0) + parsed = @parser.parse("K20+5+3@9$+1gfr5H+2") + + assert_not_nil(parsed) + assert_equal(20, parsed.rate) + assert_equal(8, parsed.modifier) + assert_equal(9, parsed.critical) + assert_nil(parsed.kept_modify) + assert_nil(parsed.first_to) + assert_equal(1, parsed.first_modify) + assert_true(parsed.greatest_fortune) + assert_equal(5, parsed.rateup) + assert_true(parsed.half) + assert_equal(2, parsed.modifier_after_half) + end + + def test_parse_v20_kept_modify_unsupported + @parser.set_version(:v2_0) + parsed = @parser.parse("K20+5+3#1") + + assert_nil(parsed) + end + + def test_parse_v25_full + @parser.set_version(:v2_5) + parsed = @parser.parse("K20+5+3@9#+2$+1gfr5H+2") + + assert_not_nil(parsed) + assert_equal(20, parsed.rate) + assert_equal(8, parsed.modifier) + assert_equal(9, parsed.critical) + assert_equal(2, parsed.kept_modify) + assert_nil(parsed.first_to) + assert_equal(1, parsed.first_modify) + assert_true(parsed.greatest_fortune) + assert_equal(5, parsed.rateup) + assert_true(parsed.half) + assert_equal(2, parsed.modifier_after_half) + end + +end From 2ea85fee9397de9ba4fc09e4e43eb6ea664f0cdd Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 17:34:34 +0900 Subject: [PATCH 02/20] =?UTF-8?q?=E3=83=91=E3=83=BC=E3=82=B5=E3=82=92?= =?UTF-8?q?=E4=BD=BF=E3=81=A3=E3=81=9F=E5=BD=A2=E3=81=AB=E6=9B=B8=E3=81=8D?= =?UTF-8?q?=E6=8F=9B=E3=81=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 190 ++++++++---------------- lib/bcdice/game_system/SwordWorld2_0.rb | 41 +---- lib/bcdice/game_system/SwordWorld2_5.rb | 46 +----- test/data/SwordWorld.toml | 18 +++ 4 files changed, 83 insertions(+), 212 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 4806c90a6..edc945343 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -1,4 +1,7 @@ -# frozen_string_literal: true +# coding: utf-8 + # frozen_string_literal: true + +require "bcdice/game_system/sword_world/rating_parser" module BCDice module GameSystem @@ -22,28 +25,6 @@ def initialize(command) @rating_table = 0 end - # change_textで使うレーティング表コマンドの正規表現 - # - # SW 2.5のダイスボットでも必要なため、共通化のために定数として定義する - RATING_TABLE_RE_FOR_CHANGE_TEXT = /\AS?H?K\d+/i.freeze - - # コマンド実行前にメッセージを置換する - # @param [String] string 受信したメッセージ - # @return [String] - def replace_text(string) - return string unless RATING_TABLE_RE_FOR_CHANGE_TEXT.match?(string) - - string - .gsub(/\[(\d+)\]/) { "c[#{Regexp.last_match(1)}]" } - .gsub(/@(\d+)/) { "c[#{Regexp.last_match(1)}]" } - .gsub(/\$([-+]?\d+)/) { "m[#{Regexp.last_match(1)}]" } - .gsub(/r([-+]?\d+)/i) { "r[#{Regexp.last_match(1)}]" } - end - - def getRatingCommandStrings - "cmCM" - end - def result_2d6(total, dice_total, _dice_list, cmp_op, target) if dice_total >= 12 Result.critical("自動的成功") @@ -64,57 +45,55 @@ def eval_game_system_specific_command(command) private + def rating_parser + return RatingParser.new + end + #################### SWレーティング表 ######################## def rating(string) # レーティング表 - string = replace_text(string) debug("rating string", string) + command = rating_parser.parse(string) - commands = getRatingCommandStrings - - m = /^S?(H?K[\d+\-]+([#{commands}]\[([\d+\-]+)\])*([\d+\-]*)([CMR]\[([\d+\-]+)\]|GF|H)*)/i.match(string) - unless m + unless command debug("not matched") return '1' end - string = m[1] - half = string.include?("H") - - rateUp, string = getRateUpFromString(string) - crit, string = getCriticalFromString(string, half) - firstDiceChanteTo, firstDiceChangeModify, string = getDiceChangesFromString(string) - - key, addValue = getKeyAndAddValueFromString(string) - - return '1' unless key =~ /(\d+)/ - - key = Regexp.last_match(1).to_i - # 2.0対応 rate_sw2_0 = getSW2_0_RatingTable keyMax = rate_sw2_0.length - 1 debug("keyMax", keyMax) - if key > keyMax + if command.rate > keyMax return "キーナンバーは#{keyMax}までです" end newRates = getNewRates(rate_sw2_0) - output = "KeyNo.#{key}" + crit = case + when command.critical.nil? + command.half ? 13 : 10 + else + command.critical + end + crit = 3 if crit < 3 # エラートラップ(クリティカル値が3未満なら3とする) + first_modify = command.first_modify.nil? ? 0 : command.first_modify + first_to = command.first_to.nil? ? 0 : command.first_to + rateup = command.rateup.nil? ? 0 : command.rateup + kept_modify = command.kept_modify.nil? ? 0 : command.kept_modify + modifier_after_half = command.modifier_after_half.nil? ? 0 : command.modifier_after_half + + output = "KeyNo.#{command.rate}" output += "c[#{crit}]" if crit < 13 - output += "m[#{firstDiceChangeModify}]" if firstDiceChangeModify != 0 - output += "m[#{firstDiceChanteTo}]" if firstDiceChanteTo != 0 - output += "r[#{rateUp}]" if rateUp != 0 - - output, values = getAdditionalString(string, output) - - debug('output', output) - - if addValue != 0 - output += "+#{addValue}" if addValue > 0 - output += addValue.to_s if addValue < 0 + output += "m[#{Format.modifier(first_modify)}]" if first_modify != 0 + output += "m[#{first_to}]" if first_to != 0 + output += "r[#{rateup}]" if rateup != 0 + output += "gf" if command.greatest_fortune + output += "a[#{Format.modifier(kept_modify)}]" if kept_modify != 0 + + if command.modifier != 0 + output += Format.modifier(command.modifier) end output += " > " @@ -128,15 +107,15 @@ def rating(string) # レーティング表 round = 0 loop do - dice_raw, diceText = rollDice(values) + dice_raw, diceText = rollDice(command) dice = dice_raw - if firstDiceChanteTo != 0 - dice = dice_raw = firstDiceChanteTo - firstDiceChanteTo = 0 - elsif firstDiceChangeModify != 0 - dice += firstDiceChangeModify.to_i - firstDiceChangeModify = 0 + if first_to != 0 + dice = dice_raw = first_to + first_to = 0 + elsif first_modify != 0 + dice += first_modify + first_modify = 0 end # 出目がピンゾロの時にはそこで終了 @@ -149,12 +128,12 @@ def rating(string) # レーティング表 break end - dice += getAdditionalDiceValue(dice, values) + dice += kept_modify if (kept_modify != 0) && (dice != 2) dice = 2 if dice < 2 dice = 12 if dice > 12 - currentKey = [key + round * rateUp, keyMax].min + currentKey = [command.rate + round * rateup, keyMax].min debug("currentKey", currentKey) rateValue = newRates[dice][currentKey] debug("rateValue", rateValue) @@ -171,76 +150,12 @@ def rating(string) # レーティング表 break unless dice >= crit end - output += getResultText(totalValue, addValue, diceResults, diceResultTotals, - rateResults, diceOnlyTotal, round, half) + output += getResultText(totalValue, command.modifier, diceResults, diceResultTotals, + rateResults, diceOnlyTotal, round, command.half, modifier_after_half) return output end - def getAdditionalString(_string, output) - values = {} - return output, values - end - - def getAdditionalDiceValue(_dice, _values) - 0 - end - - def getCriticalFromString(string, half) - crit = half ? 13 : 10 - - regexp = /c\[(\d+)\]/i - - if regexp =~ string - crit = Regexp.last_match(1).to_i - crit = 3 if crit < 3 # エラートラップ(クリティカル値が3未満なら3とする) - string = string.gsub(regexp, '') - end - - return crit, string - end - - def getDiceChangesFromString(string) - firstDiceChanteTo = 0 - firstDiceChangeModify = 0 - - regexp = /m\[([\d+\-]+)\]/i - - if regexp =~ string - firstDiceChangeModify = Regexp.last_match(1) - - unless /[+\-]/ =~ firstDiceChangeModify - firstDiceChanteTo = firstDiceChangeModify.to_i - firstDiceChangeModify = 0 - end - - string = string.gsub(regexp, '') - end - - return firstDiceChanteTo, firstDiceChangeModify, string - end - - def getRateUpFromString(string) - rateUp = 0 - return rateUp, string - end - - def getKeyAndAddValueFromString(string) - key = nil - addValue = 0 - - if /K(\d+)([\d+\-]*)/i =~ string # ボーナスの抽出 - key = Regexp.last_match(1) - if Regexp.last_match(2) - addValue = ArithmeticEvaluator.eval(Regexp.last_match(2)) - end - else - key = string - end - - return key, addValue - end - def getSW2_0_RatingTable rate_sw2_0 = [ # 0 @@ -397,7 +312,7 @@ def getNewRates(rate_sw2_0) return newRates end - def rollDice(_values) + def rollDice(_command) dice_list = @randomizer.roll_barabara(2, 6) total = dice_list.sum() dice_str = dice_list.join(",") @@ -412,8 +327,9 @@ def rollDice(_values) # @param dice_total [Integer] # @param round [Integer] # @param half [Boolean] + # @param modifier_after_half [Integer, nil] def getResultText(rating_total, modifier, diceResults, diceResultTotals, - rateResults, dice_total, round, half) + rateResults, dice_total, round, half, modifier_after_half) sequence = [] sequence.push("2D:[#{diceResults.join(' ')}]=#{diceResultTotals.join(',')}") @@ -429,10 +345,17 @@ def getResultText(rating_total, modifier, diceResults, diceResultTotals, text = rateResults.join(',') + Format.modifier(modifier) if half text = "(#{text})/2" + if modifier_after_half != 0 + text += Format.modifier(modifier_after_half) + end end sequence.push(text) elsif half - sequence.push("#{rateResults.first}/2") + text = "#{rateResults.first}/2" + if modifier_after_half != 0 + text += Format.modifier(modifier_after_half) + end + sequence.push(text) end if round > 1 @@ -443,6 +366,9 @@ def getResultText(rating_total, modifier, diceResults, diceResultTotals, total = rating_total + modifier if half total = (total / 2.0).ceil + if modifier_after_half > 0 + total += modifier_after_half + end end total_text = total.to_s diff --git a/lib/bcdice/game_system/SwordWorld2_0.rb b/lib/bcdice/game_system/SwordWorld2_0.rb index fd8c5a5c2..bf084eec5 100644 --- a/lib/bcdice/game_system/SwordWorld2_0.rb +++ b/lib/bcdice/game_system/SwordWorld2_0.rb @@ -201,32 +201,13 @@ def eval_game_system_specific_command(command) end end - def getRateUpFromString(string) - rateUp = 0 - - regexp = /r\[(\d+)\]/i - if (m = regexp.match(string)) - rateUp = m[1].to_i - string = string.gsub(regexp, '') - end - - return rateUp, string + def rating_parser + return RatingParser.new.set_version(:v2_0) end - def getAdditionalString(string, output) - output, values = super(string, output) - - isGratestFortune, = getGratestFortuneFromString(string) - - values['isGratestFortune'] = isGratestFortune - output += "gf" if isGratestFortune - - return output, values - end - - def rollDice(values) - unless values['isGratestFortune'] - return super(values) + def rollDice(command) + unless command.greatest_fortune + return super(command) end dice = @randomizer.roll_once(6) @@ -234,18 +215,6 @@ def rollDice(values) return dice * 2, "#{dice},#{dice}" end - def getGratestFortuneFromString(string) - isGratestFortune = false - - regexp = /gf/i - if regexp.match?(string) - isGratestFortune = true - string = string.gsub(regexp, '') - end - - return isGratestFortune, string - end - def growth(count = 1) ((1..count).map { growth_step }).join " | " end diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index 28e3b10f0..f7c931998 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -70,50 +70,8 @@ class SwordWorld2_5 < SwordWorld2_0 register_prefix('H?K\d+.*', 'Gr(\d+)?', '2D6?@\d+.*', 'FT', 'TT') - # コマンド実行前にメッセージを置換する - # @param [String] string 受信したメッセージ - # @return [String] - def replace_text(string) - return string unless RATING_TABLE_RE_FOR_CHANGE_TEXT.match?(string) - - super(string).gsub(/#([-+]?\d+)/) do - modifier = Regexp.last_match(1).to_i - "a[#{Format.modifier(modifier)}]" - end - end - - def getRatingCommandStrings - super + "aA" - end - - def getAdditionalString(string, output) - output, values = super(string, output) - - keptDiceChangeModify, = getKeptDiceChangesFromString(string) - - values['keptDiceChangeModify'] = keptDiceChangeModify - output += "a[#{keptDiceChangeModify}]" if keptDiceChangeModify != 0 - - return output, values - end - - def getAdditionalDiceValue(dice, values) - keptDiceChangeModify = values['keptDiceChangeModify'].to_i - - value = 0 - value += keptDiceChangeModify.to_i if (keptDiceChangeModify != 0) && (dice != 2) - - return value - end - - def getKeptDiceChangesFromString(string) - keptDiceChangeModify = 0 - regexp = /a\[([+\-]\d+)\]/i - if regexp =~ string - keptDiceChangeModify = Regexp.last_match(1) - string = string.gsub(regexp, '') - end - return keptDiceChangeModify, string + def rating_parser + return RatingParser.new.set_version(:v2_5) end end end diff --git a/test/data/SwordWorld.toml b/test/data/SwordWorld.toml index 3f4e143c2..de4d3e9a5 100644 --- a/test/data/SwordWorld.toml +++ b/test/data/SwordWorld.toml @@ -4991,6 +4991,24 @@ rands = [ { sides = 6, value = 6 }, ] +[[ test ]] +game_system = "SwordWorld" +input = "k10h+1 半減後加算" +output = "KeyNo.10 > 2D:[6,6]=12 > 7/2+1 > 5" +rands = [ + { sides = 6, value = 6 }, + { sides = 6, value = 6 }, +] + +[[ test ]] +game_system = "SwordWorld" +input = "k10h+1+1 半減後加算に使えるのは1項のみ。それ以外は加減算値となる" +output = "KeyNo.10+1 > 2D:[6,6]=12 > (7+1)/2+1 > 5" +rands = [ + { sides = 6, value = 6 }, + { sides = 6, value = 6 }, +] + [[ test ]] game_system = "SwordWorld" input = "hk10h" From a2d5f1f03ec8c43515de21c251baae987a4b075c Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 18:15:34 +0900 Subject: [PATCH 03/20] =?UTF-8?q?=E3=83=80=E3=82=A4=E3=82=B9=E3=83=86?= =?UTF-8?q?=E3=82=AD=E3=82=B9=E3=83=88=E3=81=AE=E4=BD=9C=E6=88=90=E3=81=8A?= =?UTF-8?q?=E3=82=88=E3=81=B3=E3=82=B5=E3=83=8B=E3=82=BF=E3=82=A4=E3=82=BA?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92RatingParsed=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=81=AB=E7=A7=BB=E7=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 72 ++++++------------ .../game_system/sword_world/rating_parsed.rb | 75 ++++++++++++++----- .../game_system/sword_world/rating_parser.y | 1 - 3 files changed, 80 insertions(+), 68 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index edc945343..9ab921b9a 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -70,33 +70,7 @@ def rating(string) # レーティング表 newRates = getNewRates(rate_sw2_0) - crit = case - when command.critical.nil? - command.half ? 13 : 10 - else - command.critical - end - crit = 3 if crit < 3 # エラートラップ(クリティカル値が3未満なら3とする) - first_modify = command.first_modify.nil? ? 0 : command.first_modify - first_to = command.first_to.nil? ? 0 : command.first_to - rateup = command.rateup.nil? ? 0 : command.rateup - kept_modify = command.kept_modify.nil? ? 0 : command.kept_modify - modifier_after_half = command.modifier_after_half.nil? ? 0 : command.modifier_after_half - - output = "KeyNo.#{command.rate}" - - output += "c[#{crit}]" if crit < 13 - output += "m[#{Format.modifier(first_modify)}]" if first_modify != 0 - output += "m[#{first_to}]" if first_to != 0 - output += "r[#{rateup}]" if rateup != 0 - output += "gf" if command.greatest_fortune - output += "a[#{Format.modifier(kept_modify)}]" if kept_modify != 0 - - if command.modifier != 0 - output += Format.modifier(command.modifier) - end - - output += " > " + output = "#{command.to_s} > " diceResultTotals = [] diceResults = [] @@ -105,6 +79,8 @@ def rating(string) # レーティング表 diceOnlyTotal = 0 totalValue = 0 round = 0 + first_to = command.sanitized_first_to + first_modify = command.sanitized_first_modify loop do dice_raw, diceText = rollDice(command) @@ -128,12 +104,12 @@ def rating(string) # レーティング表 break end - dice += kept_modify if (kept_modify != 0) && (dice != 2) + dice += command.sanitized_kept_modify if (command.sanitized_kept_modify != 0) && (dice != 2) dice = 2 if dice < 2 dice = 12 if dice > 12 - currentKey = [command.rate + round * rateup, keyMax].min + currentKey = [command.rate + round * command.sanitized_rateup, keyMax].min debug("currentKey", currentKey) rateValue = newRates[dice][currentKey] debug("rateValue", rateValue) @@ -147,11 +123,11 @@ def rating(string) # レーティング表 round += 1 - break unless dice >= crit + break unless dice >= command.sanitized_critical end - output += getResultText(totalValue, command.modifier, diceResults, diceResultTotals, - rateResults, diceOnlyTotal, round, command.half, modifier_after_half) + output += getResultText(totalValue, command, diceResults, diceResultTotals, + rateResults, diceOnlyTotal, round) return output end @@ -320,16 +296,14 @@ def rollDice(_command) end # @param rating_total [Integer] - # @param modifier [Integer] + # @param command [SwordWorld::RatingParsed] # @param diceResults [Array] # @param diceResultTotals [Array] # @param rateResults [Array] # @param dice_total [Integer] # @param round [Integer] - # @param half [Boolean] - # @param modifier_after_half [Integer, nil] - def getResultText(rating_total, modifier, diceResults, diceResultTotals, - rateResults, dice_total, round, half, modifier_after_half) + def getResultText(rating_total, command, diceResults, diceResultTotals, + rateResults, dice_total, round) sequence = [] sequence.push("2D:[#{diceResults.join(' ')}]=#{diceResultTotals.join(',')}") @@ -341,19 +315,19 @@ def getResultText(rating_total, modifier, diceResults, diceResultTotals, end # rate回数が1回で、修正値がない時には途中式と最終結果が一致するので、途中式を省略する - if rateResults.size > 1 || modifier != 0 - text = rateResults.join(',') + Format.modifier(modifier) - if half + if rateResults.size > 1 || command.modifier != 0 + text = rateResults.join(',') + Format.modifier(command.modifier) + if command.half text = "(#{text})/2" - if modifier_after_half != 0 - text += Format.modifier(modifier_after_half) + if command.sanitized_modifier_after_half != 0 + text += Format.modifier(command.sanitized_modifier_after_half) end end sequence.push(text) - elsif half + elsif command.half text = "#{rateResults.first}/2" - if modifier_after_half != 0 - text += Format.modifier(modifier_after_half) + if command.sanitized_modifier_after_half != 0 + text += Format.modifier(command.sanitized_modifier_after_half) end sequence.push(text) end @@ -363,11 +337,11 @@ def getResultText(rating_total, modifier, diceResults, diceResultTotals, sequence.push(round_text) end - total = rating_total + modifier - if half + total = rating_total + command.modifier + if command.half total = (total / 2.0).ceil - if modifier_after_half > 0 - total += modifier_after_half + if command.sanitized_modifier_after_half > 0 + total += command.sanitized_modifier_after_half end end diff --git a/lib/bcdice/game_system/sword_world/rating_parsed.rb b/lib/bcdice/game_system/sword_world/rating_parsed.rb index cd7368115..baa027105 100644 --- a/lib/bcdice/game_system/sword_world/rating_parsed.rb +++ b/lib/bcdice/game_system/sword_world/rating_parsed.rb @@ -4,9 +4,6 @@ module BCDice module GameSystem class SwordWorld < Base class RatingParsed - # @return [Boolean] - attr_accessor :half - # @return [Integer] attr_accessor :rate @@ -25,17 +22,16 @@ class RatingParsed # @return [Integer, nil] attr_accessor :rateup - # @return [Boolean, nil] + # @return [Boolean] attr_accessor :greatest_fortune # @return [Integer] attr_accessor :modifier - # @return [Integer] + # @return [Integer, nil] attr_accessor :modifier_after_half def initialize - @half = false @critical = nil @kept_modify = nil @first_to = nil @@ -44,20 +40,63 @@ def initialize @rateup = nil end + # @return [Boolean] + def half + return !modifier_after_half.nil? + end + + # @return [Integer] + def sanitized_critical + crit = case + when @critical.nil? + half ? 13 : 10 + else + @critical + end + crit = 3 if crit < 3 + return crit + end + + # @return [Integer] + def sanitized_first_modify + return @first_modify.nil? ? 0 : @first_modify + end + + # @return @[Integer] + def sanitized_first_to + return @first_to.nil? ? 0 : @first_to + end + + # @return @[Integer] + def sanitized_rateup + return @rateup.nil? ? 0 : @rateup + end + + # @return @[Integer] + def sanitized_kept_modify + return @kept_modify.nil? ? 0 : @kept_modify + end + + # @return @[Integer] + def sanitized_modifier_after_half + return @modifier_after_half.nil? ? 0 : @modifier_after_half + end + # @return [String] def to_s() - h = @half ? "H" : nil - r = "K#{@rate}" - c = @critical ? "@#{@critical}" : nil - ft = @first_to ? "$#{@first_to}" : nil - fm = @first_modify ? "$#{Format.modifier(@first_modify)}" : nil - km = @kept_modify ? "##{@kept_modify}" : nil - gf = @greatest_fortune ? "GF" : nil - ru = @rateup ? "r#{@rateup}" : nil - m = Format.modifier(@modifier) - mah = @half ? Format.modifier(@modifier_after_half) : nil - - [r, m, c, ft, fm, km, gf, ru, h, mah].join() + output = "KeyNo.#{@rate}" + + output += "c[#{sanitized_critical}]" if sanitized_critical < 13 + output += "m[#{Format.modifier(sanitized_first_modify)}]" if sanitized_first_modify != 0 + output += "m[#{sanitized_first_to}]" if sanitized_first_to != 0 + output += "r[#{sanitized_rateup}]" if sanitized_rateup != 0 + output += "gf" if @greatest_fortune + output += "a[#{Format.modifier(sanitized_kept_modify)}]" if sanitized_kept_modify != 0 + + if @modifier != 0 + output += Format.modifier(@modifier) + end + return output end end end diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index 8e16c5d35..83577c8bf 100644 --- a/lib/bcdice/game_system/sword_world/rating_parser.y +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -200,7 +200,6 @@ def parsed(rate, modifier, option) p.rateup = option[:rateup]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) p.greatest_fortune = option.fetch(:greatest_fortune, false) p.modifier = modifier.eval(Arithmetic::Node::DivideWithGameSystemDefault) - p.half = !option[:modifier_after_half].nil? p.modifier_after_half = option[:modifier_after_half]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) end end From 5bdd1e4d8ed402d2c60d411a10f9671fd329eba2 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 18:26:17 +0900 Subject: [PATCH 04/20] =?UTF-8?q?=E3=83=98=E3=83=AB=E3=83=97=E3=81=AB?= =?UTF-8?q?=E5=8D=8A=E6=B8=9B=E5=BE=8C=E5=8A=A0=E7=AE=97=E3=81=AB=E3=81=A4?= =?UTF-8?q?=E3=81=84=E3=81=A6=E8=A8=98=E8=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_0.rb | 5 +++-- lib/bcdice/game_system/SwordWorld2_5.rb | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld2_0.rb b/lib/bcdice/game_system/SwordWorld2_0.rb index bf084eec5..34d444732 100644 --- a/lib/bcdice/game_system/SwordWorld2_0.rb +++ b/lib/bcdice/game_system/SwordWorld2_0.rb @@ -34,10 +34,11 @@ class SwordWorld2_0 < SwordWorld  またタイプの軽減化のために末尾に「@クリティカル値」でも処理するようにしました。  例)K20[10]   K10+5[9]   k30[10]   k10[9]+10   k10-5@9 - ・レーティング表の半減 (HKx) + ・レーティング表の半減 (HKx, KxH+N)  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。 +  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。  クリティカル値を指定しない場合、クリティカルなしと扱われます。 -  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH +  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2 ・ダイス目の修正(運命変転やクリティカルレイ用)  末尾に「$修正値」でダイス目に修正がかかります。 diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index f7c931998..4158bd7ef 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -32,10 +32,11 @@ class SwordWorld2_5 < SwordWorld2_0  またタイプの軽減化のために末尾に「@クリティカル値」でも処理するようにしました。  例)K20[10]   K10+5[9]   k30[10]   k10[9]+10   k10-5@9 - ・レーティング表の半減 (HKx) + ・レーティング表の半減 (HKx, KxH+N)  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。 +  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。  クリティカル値を指定しない場合、クリティカルなしと扱われます。 -  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH +  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2 ・ダイス目の修正(運命変転やクリティカルレイ用)  末尾に「$修正値」でダイス目に修正がかかります。 From 8883a8c3bebf97adcc7c67f675a25a8c3a554391 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 18:30:25 +0900 Subject: [PATCH 05/20] =?UTF-8?q?=E3=82=AB=E3=83=83=E3=82=B3=E3=81=AE?= =?UTF-8?q?=E3=83=91=E3=82=BF=E3=83=BC=E3=83=B3=E8=BF=BD=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_0.rb | 2 +- test/data/SwordWorld.toml | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/bcdice/game_system/SwordWorld2_0.rb b/lib/bcdice/game_system/SwordWorld2_0.rb index 34d444732..05480a1e5 100644 --- a/lib/bcdice/game_system/SwordWorld2_0.rb +++ b/lib/bcdice/game_system/SwordWorld2_0.rb @@ -38,7 +38,7 @@ class SwordWorld2_0 < SwordWorld  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。  クリティカル値を指定しない場合、クリティカルなしと扱われます。 -  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2 +  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H+(1+1) ・ダイス目の修正(運命変転やクリティカルレイ用)  末尾に「$修正値」でダイス目に修正がかかります。 diff --git a/test/data/SwordWorld.toml b/test/data/SwordWorld.toml index de4d3e9a5..4338ff617 100644 --- a/test/data/SwordWorld.toml +++ b/test/data/SwordWorld.toml @@ -5009,6 +5009,15 @@ rands = [ { sides = 6, value = 6 }, ] +[[ test ]] +game_system = "SwordWorld" +input = "k10h+(1+1) カッコをつければ半減後加算に繰り込まれる" +output = "KeyNo.10 > 2D:[6,6]=12 > 7/2+2 > 6" +rands = [ + { sides = 6, value = 6 }, + { sides = 6, value = 6 }, +] + [[ test ]] game_system = "SwordWorld" input = "hk10h" From 42c692f0e2aea69062c8bf45e58169f66b3481ff Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 18:44:29 +0900 Subject: [PATCH 06/20] =?UTF-8?q?=E8=A4=87=E6=95=B0=E7=AE=87=E6=89=80?= =?UTF-8?q?=E3=81=A7=E3=81=AEmodifier=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game_system/sword_world/rating_parser.y | 8 +++++--- test/data/SwordWorld.toml | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index 83577c8bf..9c88192a5 100644 --- a/lib/bcdice/game_system/sword_world/rating_parser.y +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -29,9 +29,11 @@ class RatingParser | option modifier { option, term = val - raise ParseError unless option[:modifier].nil? - - option[:modifier] = term + if option.key?(:modifier) # 分散したmodifierは足し込む + option[:modifier] = Arithmetic::Node::BinaryOp.new(option[:modifier], :+, term) + else + option[:modifier] = term + end result = option } | option BRACKETL unary BRACKETR diff --git a/test/data/SwordWorld.toml b/test/data/SwordWorld.toml index 4338ff617..03d61d400 100644 --- a/test/data/SwordWorld.toml +++ b/test/data/SwordWorld.toml @@ -4973,6 +4973,26 @@ rands = [ { sides = 6, value = 1 }, ] +[[ test ]] +game_system = "SwordWorld" +input = "k10+10@8+5 複数箇所での修正。クリティカル値が13にはならない" +output = "KeyNo.10c[8]+15 > 2D:[3,5 3,1]=8,4 > 4,1+15 > 1回転 > 20" +rands = [ + { sides = 6, value = 3 }, + { sides = 6, value = 5 }, + { sides = 6, value = 3 }, + { sides = 6, value = 1 }, +] + +[[ test ]] +game_system = "SwordWorld" +input = "k10+10@(8+5) カッコをつけるとクリティカル値が加算される" +output = "KeyNo.10+10 > 2D:[6,5]=11 > 6+10 > 16" +rands = [ + { sides = 6, value = 6 }, + { sides = 6, value = 5 }, +] + [[ test ]] game_system = "SwordWorld" input = "hk10 HKのクリティカル値は13" From 49591b9f5deba3d8b858213270dfea6080775064 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 18:49:12 +0900 Subject: [PATCH 07/20] rubocop --- lib/bcdice/game_system/SwordWorld.rb | 5 ++--- lib/bcdice/game_system/sword_world/rating_parsed.rb | 3 +-- test/test_sword_world_rating_command_parser.rb | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 9ab921b9a..a1bb730e6 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -1,5 +1,4 @@ -# coding: utf-8 - # frozen_string_literal: true +# frozen_string_literal: true require "bcdice/game_system/sword_world/rating_parser" @@ -70,7 +69,7 @@ def rating(string) # レーティング表 newRates = getNewRates(rate_sw2_0) - output = "#{command.to_s} > " + output = "#{command} > " diceResultTotals = [] diceResults = [] diff --git a/lib/bcdice/game_system/sword_world/rating_parsed.rb b/lib/bcdice/game_system/sword_world/rating_parsed.rb index baa027105..736e3c4f7 100644 --- a/lib/bcdice/game_system/sword_world/rating_parsed.rb +++ b/lib/bcdice/game_system/sword_world/rating_parsed.rb @@ -47,8 +47,7 @@ def half # @return [Integer] def sanitized_critical - crit = case - when @critical.nil? + crit = if @critical.nil? half ? 13 : 10 else @critical diff --git a/test/test_sword_world_rating_command_parser.rb b/test/test_sword_world_rating_command_parser.rb index 9f57de913..163672245 100644 --- a/test/test_sword_world_rating_command_parser.rb +++ b/test/test_sword_world_rating_command_parser.rb @@ -4,8 +4,6 @@ require "bcdice/base" require "bcdice/game_system/sword_world/rating_parser" -class BCDice::GameSystem::SwordWorld < BCDice::Base; end - class TestSwordWorldRatingCommandParser < Test::Unit::TestCase def setup @parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() @@ -154,5 +152,4 @@ def test_parse_v25_full assert_true(parsed.half) assert_equal(2, parsed.modifier_after_half) end - end From e653dcd8831b006f2e49a503510f49299c9143a6 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 20:10:26 +0900 Subject: [PATCH 08/20] =?UTF-8?q?=E9=99=A4=E7=AE=97=E3=81=8C=E3=83=90?= =?UTF-8?q?=E3=82=B0=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE=E3=81=A7?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E3=80=81=E3=83=86=E3=82=B9=E3=83=88=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game_system/sword_world/rating_parser.y | 3 +-- test/test_sword_world_rating_command_parser.rb | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index 9c88192a5..4c778eda7 100644 --- a/lib/bcdice/game_system/sword_world/rating_parser.y +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -134,8 +134,7 @@ class RatingParser { result = Arithmetic::Node::BinaryOp.new(val[0], :*, val[2]) } | mul SLASH unary { - divied_class = val[3] - result = divied_class.new(val[0], val[2]) + result = Arithmetic::Node::DivideWithGameSystemDefault.new(val[0], val[2]) } | unary diff --git a/test/test_sword_world_rating_command_parser.rb b/test/test_sword_world_rating_command_parser.rb index 163672245..f51d2da84 100644 --- a/test/test_sword_world_rating_command_parser.rb +++ b/test/test_sword_world_rating_command_parser.rb @@ -112,6 +112,22 @@ def test_parse_v1_rateup_unsupported assert_nil(parsed) end + def test_parse_v1_arithmetic + parsed = @parser.parse("K50+5*4/2-1+3@10") + + assert_not_nil(parsed) + assert_equal(50, parsed.rate) + assert_equal(12, parsed.modifier) + assert_equal(10, parsed.critical) + assert_nil(parsed.kept_modify) + assert_nil(parsed.first_to) + assert_nil(parsed.first_modify) + assert_false(parsed.greatest_fortune) + assert_nil(parsed.rateup) + assert_false(parsed.half) + assert_nil(parsed.modifier_after_half) + end + def test_parse_v20_full @parser.set_version(:v2_0) parsed = @parser.parse("K20+5+3@9$+1gfr5H+2") From 92f3005c30efa5d8c6ead4959559aa1997f10818 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 20:12:32 +0900 Subject: [PATCH 09/20] =?UTF-8?q?2.5=E3=81=AE=E3=83=98=E3=83=AB=E3=83=97?= =?UTF-8?q?=E3=83=86=E3=82=AD=E3=82=B9=E3=83=88=E3=81=8C=E4=B8=8D=E5=AE=8C?= =?UTF-8?q?=E5=85=A8=E3=81=A0=E3=81=A3=E3=81=9F=E3=81=AE=E3=81=A7=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_5.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index 4158bd7ef..f7e70d8e3 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -36,7 +36,7 @@ class SwordWorld2_5 < SwordWorld2_0  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。  クリティカル値を指定しない場合、クリティカルなしと扱われます。 -  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2 +  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H+(1+1) ・ダイス目の修正(運命変転やクリティカルレイ用)  末尾に「$修正値」でダイス目に修正がかかります。 From 297e196037ed63d6210bdb9322fd62d9fcfe51ea Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 20:41:48 +0900 Subject: [PATCH 10/20] =?UTF-8?q?=E8=B2=A0=E6=95=B0=E3=81=AE=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92=E3=82=B9=E3=82=AD=E3=83=83=E3=83=97=E3=81=97?= =?UTF-8?q?=E3=81=A6=E3=81=97=E3=81=BE=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F?= =?UTF-8?q?=E3=83=90=E3=82=B0=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index a1bb730e6..e27673018 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -339,7 +339,7 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, total = rating_total + command.modifier if command.half total = (total / 2.0).ceil - if command.sanitized_modifier_after_half > 0 + if command.sanitized_modifier_after_half != 0 total += command.sanitized_modifier_after_half end end From 7c217a28f592ca5c4eb53b8e439adb6bc4bdece0 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Thu, 28 Jan 2021 21:19:30 +0900 Subject: [PATCH 11/20] =?UTF-8?q?=E4=BB=95=E6=A7=98=E3=81=8C=E9=9D=9E?= =?UTF-8?q?=E7=9B=B4=E6=84=9F=E7=9A=84=E3=81=A8=E6=8C=87=E6=91=98=E3=82=92?= =?UTF-8?q?=E5=8F=97=E3=81=91=E3=81=9F=E3=81=AE=E3=81=A7=E3=83=98=E3=83=AB?= =?UTF-8?q?=E3=83=97=E3=83=86=E3=82=AD=E3=82=B9=E3=83=88=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_0.rb | 3 ++- lib/bcdice/game_system/SwordWorld2_5.rb | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/bcdice/game_system/SwordWorld2_0.rb b/lib/bcdice/game_system/SwordWorld2_0.rb index 05480a1e5..c336e0182 100644 --- a/lib/bcdice/game_system/SwordWorld2_0.rb +++ b/lib/bcdice/game_system/SwordWorld2_0.rb @@ -37,8 +37,9 @@ class SwordWorld2_0 < SwordWorld ・レーティング表の半減 (HKx, KxH+N)  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。 +  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないと、半減前の値の修正として扱われます)  クリティカル値を指定しない場合、クリティカルなしと扱われます。 -  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H+(1+1) +  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H(1+1) ・ダイス目の修正(運命変転やクリティカルレイ用)  末尾に「$修正値」でダイス目に修正がかかります。 diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index f7e70d8e3..08f656bdc 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -35,6 +35,7 @@ class SwordWorld2_5 < SwordWorld2_0 ・レーティング表の半減 (HKx, KxH+N)  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。 +  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないと、半減前の値の修正として扱われます)  クリティカル値を指定しない場合、クリティカルなしと扱われます。  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H+(1+1) From c9cd903d9863928ebe1625327cebd9eb4670d3a0 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Fri, 29 Jan 2021 12:42:07 +0900 Subject: [PATCH 12/20] =?UTF-8?q?=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_0.rb | 2 +- lib/bcdice/game_system/SwordWorld2_5.rb | 2 +- .../game_system/sword_world/rating_parsed.rb | 16 +++---- .../game_system/sword_world/rating_parser.y | 29 ++++++------ .../test_sword_world_rating_command_parser.rb | 46 +++++++++++-------- 5 files changed, 51 insertions(+), 44 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld2_0.rb b/lib/bcdice/game_system/SwordWorld2_0.rb index c336e0182..8fa10b182 100644 --- a/lib/bcdice/game_system/SwordWorld2_0.rb +++ b/lib/bcdice/game_system/SwordWorld2_0.rb @@ -204,7 +204,7 @@ def eval_game_system_specific_command(command) end def rating_parser - return RatingParser.new.set_version(:v2_0) + return RatingParser.new(version: :v2_0) end def rollDice(command) diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index 08f656bdc..3ec212700 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -73,7 +73,7 @@ class SwordWorld2_5 < SwordWorld2_0 register_prefix('H?K\d+.*', 'Gr(\d+)?', '2D6?@\d+.*', 'FT', 'TT') def rating_parser - return RatingParser.new.set_version(:v2_5) + return RatingParser.new(version: :v2_5) end end end diff --git a/lib/bcdice/game_system/sword_world/rating_parsed.rb b/lib/bcdice/game_system/sword_world/rating_parsed.rb index 736e3c4f7..c7d89181d 100644 --- a/lib/bcdice/game_system/sword_world/rating_parsed.rb +++ b/lib/bcdice/game_system/sword_world/rating_parsed.rb @@ -47,38 +47,34 @@ def half # @return [Integer] def sanitized_critical - crit = if @critical.nil? - half ? 13 : 10 - else - @critical - end + crit = @critical || (half ? 13 : 10) crit = 3 if crit < 3 return crit end # @return [Integer] def sanitized_first_modify - return @first_modify.nil? ? 0 : @first_modify + return @first_modify || 0 end # @return @[Integer] def sanitized_first_to - return @first_to.nil? ? 0 : @first_to + return @first_to || 0 end # @return @[Integer] def sanitized_rateup - return @rateup.nil? ? 0 : @rateup + return @rateup || 0 end # @return @[Integer] def sanitized_kept_modify - return @kept_modify.nil? ? 0 : @kept_modify + return @kept_modify || 0 end # @return @[Integer] def sanitized_modifier_after_half - return @modifier_after_half.nil? ? 0 : @modifier_after_half + return @modifier_after_half || 0 end # @return [String] diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index 4c778eda7..b80a2c0d4 100644 --- a/lib/bcdice/game_system/sword_world/rating_parser.y +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -7,14 +7,14 @@ class RatingParser expr: rate option { rate, option = val - modifier = option[:modifier].nil? ? Arithmetic::Node::Number.new(0) : option[:modifier] + modifier = option[:modifier] || Arithmetic::Node::Number.new(0) result = parsed(rate, modifier, option) } | H rate option { _, rate, option = val - option[:modifier_after_half] = Arithmetic::Node::Number.new(0) if option[:modifier_after_half].nil? - modifier = option[:modifier].nil? ? Arithmetic::Node::Number.new(0) : option[:modifier] + option[:modifier_after_half] ||= Arithmetic::Node::Number.new(0) + modifier = option[:modifier] || Arithmetic::Node::Number.new(0) result = parsed(rate, modifier, option) } @@ -153,6 +153,7 @@ end ---- header require "bcdice/arithmetic/node" +require "bcdice/enum" require "bcdice/game_system/sword_world/rating_lexer" require "bcdice/game_system/sword_world/rating_parsed" @@ -163,15 +164,17 @@ module BCDice ---- inner -def initialize() +# デフォルトの丸めを切り上げとしているが、SwordWorldには切り捨てもあるので決め切れない(四捨五入は現状ない) +def initialize(version: :v1_0, round_type: RoundType::CEIL) super() - @version = :v1_0 + @version = version + @round_type = round_type end -# バージョンを指定する +# 割り算の丸め方を指定する # @return [BCDice::GameSystem::SwordWorld::RatingParser] -def set_version(version) - @version = version +def set_round_type(round_type) + @round_type = round_type self end @@ -194,14 +197,14 @@ private def parsed(rate, modifier, option) RatingParsed.new.tap do |p| p.rate = rate - p.critical = option[:critical]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) - p.kept_modify = option[:kept_modify]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) + p.critical = option[:critical]&.eval(@round_type) + p.kept_modify = option[:kept_modify]&.eval(@round_type) p.first_to = option[:first_to] p.first_modify = option[:first_modify] - p.rateup = option[:rateup]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) + p.rateup = option[:rateup]&.eval(@round_type) p.greatest_fortune = option.fetch(:greatest_fortune, false) - p.modifier = modifier.eval(Arithmetic::Node::DivideWithGameSystemDefault) - p.modifier_after_half = option[:modifier_after_half]&.eval(Arithmetic::Node::DivideWithGameSystemDefault) + p.modifier = modifier.eval(@round_type) + p.modifier_after_half = option[:modifier_after_half]&.eval(@round_type) end end diff --git a/test/test_sword_world_rating_command_parser.rb b/test/test_sword_world_rating_command_parser.rb index f51d2da84..cc809ef69 100644 --- a/test/test_sword_world_rating_command_parser.rb +++ b/test/test_sword_world_rating_command_parser.rb @@ -5,12 +5,10 @@ require "bcdice/game_system/sword_world/rating_parser" class TestSwordWorldRatingCommandParser < Test::Unit::TestCase - def setup - @parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() - end def test_parse_v1_full_first_modify - parsed = @parser.parse("K20+5+3@9$+1H+2") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K20+5+3@9$+1H+2") assert_not_nil(parsed) assert_equal(20, parsed.rate) @@ -26,7 +24,8 @@ def test_parse_v1_full_first_modify end def test_parse_v1_full_first_to - parsed = @parser.parse("K20+5+3@9$8H+2") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K20+5+3@9$8H+2") assert_not_nil(parsed) assert_equal(20, parsed.rate) @@ -42,7 +41,8 @@ def test_parse_v1_full_first_to end def test_parse_v1_head_half - parsed = @parser.parse("HK30+5+3") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("HK30+5+3") assert_not_nil(parsed) assert_equal(30, parsed.rate) @@ -58,7 +58,8 @@ def test_parse_v1_head_half end def test_parse_v1_brace_critical - parsed = @parser.parse("K50[8]+5+3") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K50[8]+5+3") assert_not_nil(parsed) assert_equal(50, parsed.rate) @@ -74,7 +75,9 @@ def test_parse_v1_brace_critical end def test_parse_v1_brace_critical_only - parsed = @parser.parse("K50[8]") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K50[8]") + assert_not_nil(parsed) assert_equal(50, parsed.rate) assert_equal(0, parsed.modifier) @@ -89,31 +92,36 @@ def test_parse_v1_brace_critical_only end def test_parse_v1_brace_critical_duplicate - parsed = @parser.parse("K50[8]+5+3@9") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K50[8]+5+3@9") assert_nil(parsed) end def test_parse_v1_gf_unsupported - parsed = @parser.parse("K50[8]+5+3gf") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K50[8]+5+3gf") assert_nil(parsed) end def test_parse_v1_kept_modify_unsupported - parsed = @parser.parse("K50[8]+5+3#+1") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K50[8]+5+3#+1") assert_nil(parsed) end def test_parse_v1_rateup_unsupported - parsed = @parser.parse("K50[8]+5+3r10") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K50[8]+5+3r10") assert_nil(parsed) end def test_parse_v1_arithmetic - parsed = @parser.parse("K50+5*4/2-1+3@10") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K50+5*4/2-1+3@10") assert_not_nil(parsed) assert_equal(50, parsed.rate) @@ -129,8 +137,8 @@ def test_parse_v1_arithmetic end def test_parse_v20_full - @parser.set_version(:v2_0) - parsed = @parser.parse("K20+5+3@9$+1gfr5H+2") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new(version: :v2_0).set_debug() + parsed = parser.parse("K20+5+3@9$+1gfr5H+2") assert_not_nil(parsed) assert_equal(20, parsed.rate) @@ -146,15 +154,15 @@ def test_parse_v20_full end def test_parse_v20_kept_modify_unsupported - @parser.set_version(:v2_0) - parsed = @parser.parse("K20+5+3#1") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new(version: :v2_0).set_debug() + parsed = parser.parse("K20+5+3#1") assert_nil(parsed) end def test_parse_v25_full - @parser.set_version(:v2_5) - parsed = @parser.parse("K20+5+3@9#+2$+1gfr5H+2") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new(version: :v2_5).set_debug() + parsed = parser.parse("K20+5+3@9#+2$+1gfr5H+2") assert_not_nil(parsed) assert_equal(20, parsed.rate) From 8aaeca083ac1d392fc880fa05fc072009e84bf7a Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Fri, 29 Jan 2021 12:48:07 +0900 Subject: [PATCH 13/20] rubocop --- test/test_sword_world_rating_command_parser.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_sword_world_rating_command_parser.rb b/test/test_sword_world_rating_command_parser.rb index cc809ef69..e1791bf2a 100644 --- a/test/test_sword_world_rating_command_parser.rb +++ b/test/test_sword_world_rating_command_parser.rb @@ -5,7 +5,6 @@ require "bcdice/game_system/sword_world/rating_parser" class TestSwordWorldRatingCommandParser < Test::Unit::TestCase - def test_parse_v1_full_first_modify parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() parsed = parser.parse("K20+5+3@9$+1H+2") From b2e7776a7a226564c89eedec71d3f58d21787bd9 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Fri, 29 Jan 2021 23:17:41 +0900 Subject: [PATCH 14/20] =?UTF-8?q?=E8=A4=87=E6=95=B0=E7=AE=87=E6=89=80?= =?UTF-8?q?=E3=81=A7=E3=81=AEmodifier=E3=81=AE=E7=B5=B1=E5=90=88=E3=82=92?= =?UTF-8?q?=E8=A8=B1=E5=8F=AF=E3=81=97=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/sword_world/rating_parser.y | 8 +++----- test/data/SwordWorld.toml | 11 ----------- test/test_sword_world_rating_command_parser.rb | 6 ++++++ 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index b80a2c0d4..6bf6705de 100644 --- a/lib/bcdice/game_system/sword_world/rating_parser.y +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -29,11 +29,9 @@ class RatingParser | option modifier { option, term = val - if option.key?(:modifier) # 分散したmodifierは足し込む - option[:modifier] = Arithmetic::Node::BinaryOp.new(option[:modifier], :+, term) - else - option[:modifier] = term - end + raise ParseError unless option[:modifier].nil? + + option[:modifier] = term result = option } | option BRACKETL unary BRACKETR diff --git a/test/data/SwordWorld.toml b/test/data/SwordWorld.toml index 03d61d400..00d5e1a19 100644 --- a/test/data/SwordWorld.toml +++ b/test/data/SwordWorld.toml @@ -4973,17 +4973,6 @@ rands = [ { sides = 6, value = 1 }, ] -[[ test ]] -game_system = "SwordWorld" -input = "k10+10@8+5 複数箇所での修正。クリティカル値が13にはならない" -output = "KeyNo.10c[8]+15 > 2D:[3,5 3,1]=8,4 > 4,1+15 > 1回転 > 20" -rands = [ - { sides = 6, value = 3 }, - { sides = 6, value = 5 }, - { sides = 6, value = 3 }, - { sides = 6, value = 1 }, -] - [[ test ]] game_system = "SwordWorld" input = "k10+10@(8+5) カッコをつけるとクリティカル値が加算される" diff --git a/test/test_sword_world_rating_command_parser.rb b/test/test_sword_world_rating_command_parser.rb index e1791bf2a..13b3a880e 100644 --- a/test/test_sword_world_rating_command_parser.rb +++ b/test/test_sword_world_rating_command_parser.rb @@ -97,6 +97,12 @@ def test_parse_v1_brace_critical_duplicate assert_nil(parsed) end + def test_parse_v1_multiple_modifier + parsed = @parser.parse("K20+5H+3+2") + + assert_nil(parsed) + end + def test_parse_v1_gf_unsupported parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() parsed = parser.parse("K50[8]+5+3gf") From f1bddb3060e52c36846e58ff43fb0719594429cd Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Fri, 29 Jan 2021 23:30:42 +0900 Subject: [PATCH 15/20] =?UTF-8?q?=E3=82=B3=E3=83=9F=E3=83=83=E3=83=88?= =?UTF-8?q?=E6=BC=8F=E3=82=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test_sword_world_rating_command_parser.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test_sword_world_rating_command_parser.rb b/test/test_sword_world_rating_command_parser.rb index 13b3a880e..37d543ece 100644 --- a/test/test_sword_world_rating_command_parser.rb +++ b/test/test_sword_world_rating_command_parser.rb @@ -98,7 +98,8 @@ def test_parse_v1_brace_critical_duplicate end def test_parse_v1_multiple_modifier - parsed = @parser.parse("K20+5H+3+2") + parser = BCDice::GameSystem::SwordWorld::RatingParser.new().set_debug() + parsed = parser.parse("K20+5H+3+2") assert_nil(parsed) end From 657eddbb6a1cd24f6808f2902b535bf99cd64e5f Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Sat, 30 Jan 2021 14:04:22 +0900 Subject: [PATCH 16/20] =?UTF-8?q?=E5=8D=8A=E6=B8=9B=E5=BE=8C=E5=8A=A0?= =?UTF-8?q?=E7=AE=97=E4=BF=AE=E6=AD=A3=E3=81=AA=E3=81=97=E3=81=AE=E6=96=B9?= =?UTF-8?q?=E3=81=AE=E3=83=91=E3=83=BC=E3=82=B9=E3=81=A7=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E5=87=A6=E7=90=86=E6=BC=8F=E3=82=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/sword_world/rating_parser.y | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index 6bf6705de..097c9251e 100644 --- a/lib/bcdice/game_system/sword_world/rating_parser.y +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -77,6 +77,8 @@ class RatingParser | option H { option, _ = val + raise ParseError unless option[:modifier_after_half].nil? + option[:modifier_after_half] = Arithmetic::Node::Number.new(0) result = option } From 2209b44a32defe9f901eada2f646435feb47b9b1 Mon Sep 17 00:00:00 2001 From: Hideyo Mikisato Date: Wed, 3 Feb 2021 02:30:22 +0900 Subject: [PATCH 17/20] =?UTF-8?q?=E3=83=98=E3=83=AB=E3=83=97=E3=83=A1?= =?UTF-8?q?=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=81=8C=E3=83=AC=E3=83=93?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E5=89=8D=E3=81=AE=E4=BB=95=E6=A7=98=E3=81=A0?= =?UTF-8?q?=E3=81=A3=E3=81=9F=E3=81=AE=E3=81=A7=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_0.rb | 2 +- lib/bcdice/game_system/SwordWorld2_5.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld2_0.rb b/lib/bcdice/game_system/SwordWorld2_0.rb index 8fa10b182..e0eb075a2 100644 --- a/lib/bcdice/game_system/SwordWorld2_0.rb +++ b/lib/bcdice/game_system/SwordWorld2_0.rb @@ -37,7 +37,7 @@ class SwordWorld2_0 < SwordWorld ・レーティング表の半減 (HKx, KxH+N)  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。 -  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないと、半減前の値の修正として扱われます) +  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します)  クリティカル値を指定しない場合、クリティカルなしと扱われます。  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H(1+1) diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index 3ec212700..4e84743ad 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -35,7 +35,7 @@ class SwordWorld2_5 < SwordWorld2_0 ・レーティング表の半減 (HKx, KxH+N)  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。 -  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないと、半減前の値の修正として扱われます) +  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します)  クリティカル値を指定しない場合、クリティカルなしと扱われます。  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H+(1+1) From 1111cef03d1b44836aebd26d58a61fe1723264ad Mon Sep 17 00:00:00 2001 From: SAKATA Sinji Date: Thu, 25 Feb 2021 20:45:03 +0900 Subject: [PATCH 18/20] Remove set_round_type --- lib/bcdice/game_system/sword_world/rating_parser.y | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index 097c9251e..305b1fe88 100644 --- a/lib/bcdice/game_system/sword_world/rating_parser.y +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -171,13 +171,6 @@ def initialize(version: :v1_0, round_type: RoundType::CEIL) @round_type = round_type end -# 割り算の丸め方を指定する -# @return [BCDice::GameSystem::SwordWorld::RatingParser] -def set_round_type(round_type) - @round_type = round_type - self -end - def set_debug @yydebug = true return self From 92db21ae369db33980ab1bfe501ec6c16dd469ab Mon Sep 17 00:00:00 2001 From: SAKATA Sinji Date: Thu, 25 Feb 2021 20:57:40 +0900 Subject: [PATCH 19/20] =?UTF-8?q?sanitized=5F=E3=81=A7=E3=81=AF=E3=81=AA?= =?UTF-8?q?=E3=81=8Fgetter=E3=81=A7=E9=9A=A0=E8=94=BD=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 22 +++---- .../game_system/sword_world/rating_parsed.rb | 38 ++++++------ .../test_sword_world_rating_command_parser.rb | 58 +++++++++---------- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index e27673018..72f6340a2 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -78,8 +78,8 @@ def rating(string) # レーティング表 diceOnlyTotal = 0 totalValue = 0 round = 0 - first_to = command.sanitized_first_to - first_modify = command.sanitized_first_modify + first_to = command.first_to + first_modify = command.first_modify loop do dice_raw, diceText = rollDice(command) @@ -103,12 +103,12 @@ def rating(string) # レーティング表 break end - dice += command.sanitized_kept_modify if (command.sanitized_kept_modify != 0) && (dice != 2) + dice += command.kept_modify if (command.kept_modify != 0) && (dice != 2) dice = 2 if dice < 2 dice = 12 if dice > 12 - currentKey = [command.rate + round * command.sanitized_rateup, keyMax].min + currentKey = [command.rate + round * command.rateup, keyMax].min debug("currentKey", currentKey) rateValue = newRates[dice][currentKey] debug("rateValue", rateValue) @@ -122,7 +122,7 @@ def rating(string) # レーティング表 round += 1 - break unless dice >= command.sanitized_critical + break unless dice >= command.critical end output += getResultText(totalValue, command, diceResults, diceResultTotals, @@ -318,15 +318,15 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, text = rateResults.join(',') + Format.modifier(command.modifier) if command.half text = "(#{text})/2" - if command.sanitized_modifier_after_half != 0 - text += Format.modifier(command.sanitized_modifier_after_half) + if command.modifier_after_half != 0 + text += Format.modifier(command.modifier_after_half) end end sequence.push(text) elsif command.half text = "#{rateResults.first}/2" - if command.sanitized_modifier_after_half != 0 - text += Format.modifier(command.sanitized_modifier_after_half) + if command.modifier_after_half != 0 + text += Format.modifier(command.modifier_after_half) end sequence.push(text) end @@ -339,8 +339,8 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, total = rating_total + command.modifier if command.half total = (total / 2.0).ceil - if command.sanitized_modifier_after_half != 0 - total += command.sanitized_modifier_after_half + if command.modifier_after_half != 0 + total += command.modifier_after_half end end diff --git a/lib/bcdice/game_system/sword_world/rating_parsed.rb b/lib/bcdice/game_system/sword_world/rating_parsed.rb index c7d89181d..49740eea5 100644 --- a/lib/bcdice/game_system/sword_world/rating_parsed.rb +++ b/lib/bcdice/game_system/sword_world/rating_parsed.rb @@ -8,19 +8,19 @@ class RatingParsed attr_accessor :rate # @return [Integer, nil] - attr_accessor :critical + attr_writer :critical # @return [Integer, nil] - attr_accessor :kept_modify + attr_writer :kept_modify # @return [Integer, nil] - attr_accessor :first_to + attr_writer :first_to # @return [Integer, nil] - attr_accessor :first_modify + attr_writer :first_modify # @return [Integer, nil] - attr_accessor :rateup + attr_writer :rateup # @return [Boolean] attr_accessor :greatest_fortune @@ -29,51 +29,51 @@ class RatingParsed attr_accessor :modifier # @return [Integer, nil] - attr_accessor :modifier_after_half + attr_writer :modifier_after_half def initialize @critical = nil @kept_modify = nil @first_to = nil @first_modify = nil - @greatest_fortune = nil + @greatest_fortune = false @rateup = nil end # @return [Boolean] def half - return !modifier_after_half.nil? + return !@modifier_after_half.nil? end # @return [Integer] - def sanitized_critical + def critical crit = @critical || (half ? 13 : 10) crit = 3 if crit < 3 return crit end # @return [Integer] - def sanitized_first_modify + def first_modify return @first_modify || 0 end # @return @[Integer] - def sanitized_first_to + def first_to return @first_to || 0 end # @return @[Integer] - def sanitized_rateup + def rateup return @rateup || 0 end # @return @[Integer] - def sanitized_kept_modify + def kept_modify return @kept_modify || 0 end # @return @[Integer] - def sanitized_modifier_after_half + def modifier_after_half return @modifier_after_half || 0 end @@ -81,12 +81,12 @@ def sanitized_modifier_after_half def to_s() output = "KeyNo.#{@rate}" - output += "c[#{sanitized_critical}]" if sanitized_critical < 13 - output += "m[#{Format.modifier(sanitized_first_modify)}]" if sanitized_first_modify != 0 - output += "m[#{sanitized_first_to}]" if sanitized_first_to != 0 - output += "r[#{sanitized_rateup}]" if sanitized_rateup != 0 + output += "c[#{critical}]" if critical < 13 + output += "m[#{Format.modifier(first_modify)}]" if first_modify != 0 + output += "m[#{first_to}]" if first_to != 0 + output += "r[#{rateup}]" if rateup != 0 output += "gf" if @greatest_fortune - output += "a[#{Format.modifier(sanitized_kept_modify)}]" if sanitized_kept_modify != 0 + output += "a[#{Format.modifier(kept_modify)}]" if kept_modify != 0 if @modifier != 0 output += Format.modifier(@modifier) diff --git a/test/test_sword_world_rating_command_parser.rb b/test/test_sword_world_rating_command_parser.rb index 37d543ece..c31d2cf9d 100644 --- a/test/test_sword_world_rating_command_parser.rb +++ b/test/test_sword_world_rating_command_parser.rb @@ -13,11 +13,11 @@ def test_parse_v1_full_first_modify assert_equal(20, parsed.rate) assert_equal(8, parsed.modifier) assert_equal(9, parsed.critical) - assert_nil(parsed.kept_modify) - assert_nil(parsed.first_to) + assert_equal(0, parsed.kept_modify) + assert_equal(0, parsed.first_to) assert_equal(1, parsed.first_modify) assert_false(parsed.greatest_fortune) - assert_nil(parsed.rateup) + assert_equal(0, parsed.rateup) assert_true(parsed.half) assert_equal(2, parsed.modifier_after_half) end @@ -30,11 +30,11 @@ def test_parse_v1_full_first_to assert_equal(20, parsed.rate) assert_equal(8, parsed.modifier) assert_equal(9, parsed.critical) - assert_nil(parsed.kept_modify) + assert_equal(0, parsed.kept_modify) assert_equal(8, parsed.first_to) - assert_nil(parsed.first_modify) + assert_equal(0, parsed.first_modify) assert_false(parsed.greatest_fortune) - assert_nil(parsed.rateup) + assert_equal(0, parsed.rateup) assert_true(parsed.half) assert_equal(2, parsed.modifier_after_half) end @@ -46,12 +46,12 @@ def test_parse_v1_head_half assert_not_nil(parsed) assert_equal(30, parsed.rate) assert_equal(8, parsed.modifier) - assert_nil(parsed.critical) - assert_nil(parsed.kept_modify) - assert_nil(parsed.first_to) - assert_nil(parsed.first_modify) + assert_equal(13, parsed.critical) + assert_equal(0, parsed.kept_modify) + assert_equal(0, parsed.first_to) + assert_equal(0, parsed.first_modify) assert_false(parsed.greatest_fortune) - assert_nil(parsed.rateup) + assert_equal(0, parsed.rateup) assert_true(parsed.half) assert_equal(0, parsed.modifier_after_half) end @@ -64,13 +64,13 @@ def test_parse_v1_brace_critical assert_equal(50, parsed.rate) assert_equal(8, parsed.modifier) assert_equal(8, parsed.critical) - assert_nil(parsed.kept_modify) - assert_nil(parsed.first_to) - assert_nil(parsed.first_modify) + assert_equal(0, parsed.kept_modify) + assert_equal(0, parsed.first_to) + assert_equal(0, parsed.first_modify) assert_false(parsed.greatest_fortune) - assert_nil(parsed.rateup) + assert_equal(0, parsed.rateup) assert_false(parsed.half) - assert_nil(parsed.modifier_after_half) + assert_equal(0, parsed.modifier_after_half) end def test_parse_v1_brace_critical_only @@ -81,13 +81,13 @@ def test_parse_v1_brace_critical_only assert_equal(50, parsed.rate) assert_equal(0, parsed.modifier) assert_equal(8, parsed.critical) - assert_nil(parsed.kept_modify) - assert_nil(parsed.first_to) - assert_nil(parsed.first_modify) + assert_equal(0, parsed.kept_modify) + assert_equal(0, parsed.first_to) + assert_equal(0, parsed.first_modify) assert_false(parsed.greatest_fortune) - assert_nil(parsed.rateup) + assert_equal(0, parsed.rateup) assert_false(parsed.half) - assert_nil(parsed.modifier_after_half) + assert_equal(0, parsed.modifier_after_half) end def test_parse_v1_brace_critical_duplicate @@ -133,13 +133,13 @@ def test_parse_v1_arithmetic assert_equal(50, parsed.rate) assert_equal(12, parsed.modifier) assert_equal(10, parsed.critical) - assert_nil(parsed.kept_modify) - assert_nil(parsed.first_to) - assert_nil(parsed.first_modify) + assert_equal(0, parsed.kept_modify) + assert_equal(0, parsed.first_to) + assert_equal(0, parsed.first_modify) assert_false(parsed.greatest_fortune) - assert_nil(parsed.rateup) + assert_equal(0, parsed.rateup) assert_false(parsed.half) - assert_nil(parsed.modifier_after_half) + assert_equal(0, parsed.modifier_after_half) end def test_parse_v20_full @@ -150,8 +150,8 @@ def test_parse_v20_full assert_equal(20, parsed.rate) assert_equal(8, parsed.modifier) assert_equal(9, parsed.critical) - assert_nil(parsed.kept_modify) - assert_nil(parsed.first_to) + assert_equal(0, parsed.kept_modify) + assert_equal(0, parsed.first_to) assert_equal(1, parsed.first_modify) assert_true(parsed.greatest_fortune) assert_equal(5, parsed.rateup) @@ -175,7 +175,7 @@ def test_parse_v25_full assert_equal(8, parsed.modifier) assert_equal(9, parsed.critical) assert_equal(2, parsed.kept_modify) - assert_nil(parsed.first_to) + assert_equal(0, parsed.first_to) assert_equal(1, parsed.first_modify) assert_true(parsed.greatest_fortune) assert_equal(5, parsed.rateup) From 9e60567ff026faad4534104939613c7e8961378f Mon Sep 17 00:00:00 2001 From: SAKATA Sinji Date: Thu, 25 Feb 2021 20:59:37 +0900 Subject: [PATCH 20/20] =?UTF-8?q?SwordWorld#setRatingTable=20=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 35 ---------------------------- 1 file changed, 35 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 72f6340a2..5792226a6 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -349,41 +349,6 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, return sequence.join(" > ") end - - def setRatingTable(tnick) - mode_str = "" - pre_mode = @rating_table - - if /(\d+)/ =~ tnick - @rating_table = Regexp.last_match(1).to_i - if @rating_table > 1 - mode_str = "2.0-mode" - @rating_table = 2 - elsif @rating_table > 0 - mode_str = "new-mode" - @rating_table = 1 - else - mode_str = "old-mode" - @rating_table = 0 - end - else - case tnick - when /old/i - @rating_table = 0 - mode_str = "old-mode" - when /new/i - @rating_table = 1 - mode_str = "new-mode" - when /2\.0/i - @rating_table = 2 - mode_str = "2.0-mode" - end - end - - return '1' if @rating_table == pre_mode - - return "RatingTableを#{mode_str}に変更しました" - end end end end