Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[アマデウス] リファクタリングおよびResultの使用 #430

Merged
merged 7 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 110 additions & 93 deletions lib/bcdice/game_system/Amadeus.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# frozen_string_literal: true

require "bcdice/arithmetic_evaluator"
require "bcdice/format"
require "bcdice/normalize"

module BCDice
module GameSystem
class Amadeus < Base
Expand Down Expand Up @@ -46,111 +50,124 @@ def initialize(command)
end

def eval_game_system_specific_command(command)
text = amadeusDice(command)
return text unless text.nil?

return roll_tables(command, self.class::TABLES)
roll_amadeus(command) ||
roll_tables(command, self.class::TABLES)
end

def amadeusDice(command)
return nil unless /^(R([A-DS])([+\-\d]*))(@(\d))?((>(=)?)([+\-\d]*))?(@(\d))?$/i =~ command

commandText = Regexp.last_match(1)
skillRank = Regexp.last_match(2)
modifyText = Regexp.last_match(3)
signOfInequality = (Regexp.last_match(7).nil? ? ">=" : Regexp.last_match(7))
targetText = (Regexp.last_match(9).nil? ? "4" : Regexp.last_match(9))
if nil | Regexp.last_match(5)
specialNum = Regexp.last_match(5).to_i
elsif nil | Regexp.last_match(11)
specialNum = Regexp.last_match(11).to_i
else
specialNum = 6
private

def roll_amadeus(command)
m = /^R([A-DS])([+\-\d]*)(@(\d))?((>=?)([+\-\d]*))?(@(\d))?$/i.match(command)
unless m
return nil
end

diceCount = CHECK_DICE_COUNT[skillRank]
modify = ArithmeticEvaluator.eval(modifyText)
target = ArithmeticEvaluator.eval(targetText)

diceList = @randomizer.roll_barabara(diceCount, 6)
diceText = diceList.join(",")
specialText = (specialNum == 6 ? "" : "@#{specialNum}")

message = "(#{commandText}#{specialText}#{signOfInequality}#{targetText}) > [#{diceText}]#{modifyText} > "
diceList = [diceList.min] if skillRank == "D"
is_loop = false
diceList.each do |dice|
if is_loop
message += " / "
elsif diceList.length > 1
is_loop = true
rank = m[1]
modifier = ArithmeticEvaluator.eval(m[2])
cmp_op = m[6] ? Normalize.comparison_operator(m[6]) : :>=
target = m[7] ? ArithmeticEvaluator.eval(m[7]) : 4
special = (m[4] || m[9] || 6).to_i

dice_count = CHECK_DICE_COUNT[rank]

dice_list = @randomizer.roll_barabara(dice_count, 6)
dice_text = dice_list.join(",")
special_text = (special == 6 ? "" : "@#{special}")

dice_list = [dice_list.min] if rank == "D"
available_inga = dice_list.size > 1
inga_table = translate("Amadeus.inga_table")

success = false
critical = false
fumble = false

results =
dice_list.map do |dice|
total = dice + modifier
result =
if dice == 1
fumble = true
translate("Amadeus.fumble")
elsif dice >= special
critical = true
success = true
translate("Amadeus.special")
elsif total.send(cmp_op, target)
success = true
translate("success")
else
translate("failure")
end

if available_inga
inga = inga_table[dice - 1]
"#{total}_#{result}[#{dice}#{inga}]"
else
"#{total}_#{result}[#{dice}]"
end
end
achieve = dice + modify
result = check_success(achieve, dice, signOfInequality, target, specialNum)
if is_loop
inga_table = translate("Amadeus.inga_table")
inga = inga_table[dice - 1]
message += "#{achieve}_#{result}[#{dice}#{inga}]"

sequence = [
"(R#{rank}#{Format.modifier(modifier)}#{special_text}#{cmp_op}#{target})",
"[#{dice_text}]#{Format.modifier(modifier)}",
results.join(" / ")
]

Result.new.tap do |r|
r.text = sequence.join(" > ")
if success
r.success = true
r.critical = critical
else
message += "#{achieve}_#{result}[#{dice}]"
r.failure = true
r.fumble = fumble
end
end

return message
end

def check_success(total_n, dice_n, signOfInequality, diff, special_n)
return translate("Amadeus.fumble") if dice_n == 1
return translate("Amadeus.special") if dice_n >= special_n

cmp_op = Normalize.comparison_operator(signOfInequality)
target_num = diff.to_i

if total_n.send(cmp_op, target_num)
translate("success")
else
translate("failure")
end
end

CHECK_DICE_COUNT = {"S" => 4, "A" => 3, "B" => 2, "C" => 1, "D" => 2}.freeze

def self.translate_tables(locale)
{
"ECT" => DiceTable::Table.from_i18n("Amadeus.table.ECT", locale),
"BST" => DiceTable::Table.from_i18n("Amadeus.table.BST", locale),
"RT" => DiceTable::Table.from_i18n("Amadeus.table.RT", locale),
"PRT" => DiceTable::Table.from_i18n("Amadeus.table.PRT", locale),
"FT" => DiceTable::Table.from_i18n("Amadeus.table.FT", locale),
"BT" => DiceTable::D66Table.from_i18n("Amadeus.table.BT", locale),
"FWT" => DiceTable::Table.from_i18n("Amadeus.table.FWT", locale),
"BRT" => DiceTable::Table.from_i18n("Amadeus.table.BRT", locale),
"RIT" => DiceTable::Table.from_i18n("Amadeus.table.RIT", locale),
"WT" => DiceTable::Table.from_i18n("Amadeus.table.WT", locale),
"NMT" => DiceTable::Table.from_i18n("Amadeus.table.NMT", locale),
"TGT" => DiceTable::Table.from_i18n("Amadeus.table.TGT", locale),
"CST" => DiceTable::Table.from_i18n("Amadeus.table.CST", locale),
"GCVT" => DiceTable::Table.from_i18n("Amadeus.table.GCVT", locale),
"YCVT" => DiceTable::Table.from_i18n("Amadeus.table.YCVT", locale),
"ECVT" => DiceTable::Table.from_i18n("Amadeus.table.ECVT", locale),
"CCVT" => DiceTable::Table.from_i18n("Amadeus.table.CCVT", locale),
"NCVT" => DiceTable::Table.from_i18n("Amadeus.table.NCVT", locale),
"DGVT" => DiceTable::Table.from_i18n("Amadeus.table.DGVT", locale),
"DAVT" => DiceTable::Table.from_i18n("Amadeus.table.DAVT", locale),
"PRCT" => DiceTable::Table.from_i18n("Amadeus.table.PRCT", locale),
"TCCT" => DiceTable::Table.from_i18n("Amadeus.table.TCCT", locale),
"INCT" => DiceTable::Table.from_i18n("Amadeus.table.INCT", locale),
"PSCT" => DiceTable::Table.from_i18n("Amadeus.table.PSCT", locale),
"LVCT" => DiceTable::Table.from_i18n("Amadeus.table.LVCT", locale),
"DACT" => DiceTable::Table.from_i18n("Amadeus.table.DACT", locale),
"RGT" => DiceTable::Table.from_i18n("Amadeus.table.RGT", locale),
"FBT" => DiceTable::Table.from_i18n("Amadeus.table.FBT", locale),
"CHVT" => DiceTable::Table.from_i18n("Amadeus.table.CHVT", locale),
"LCVT" => DiceTable::Table.from_i18n("Amadeus.table.LCVT", locale),
"KCVT" => DiceTable::Table.from_i18n("Amadeus.table.KCVT", locale),
"SAT" => DiceTable::D66Table.from_i18n("Amadeus.table.SAT", locale),
"SMT" => DiceTable::D66Table.from_i18n("Amadeus.table.SMT", locale),
}
class << self
private

def translate_tables(locale)
{
"ECT" => DiceTable::Table.from_i18n("Amadeus.table.ECT", locale),
"BST" => DiceTable::Table.from_i18n("Amadeus.table.BST", locale),
"RT" => DiceTable::Table.from_i18n("Amadeus.table.RT", locale),
"PRT" => DiceTable::Table.from_i18n("Amadeus.table.PRT", locale),
"FT" => DiceTable::Table.from_i18n("Amadeus.table.FT", locale),
"BT" => DiceTable::D66Table.from_i18n("Amadeus.table.BT", locale),
"FWT" => DiceTable::Table.from_i18n("Amadeus.table.FWT", locale),
"BRT" => DiceTable::Table.from_i18n("Amadeus.table.BRT", locale),
"RIT" => DiceTable::Table.from_i18n("Amadeus.table.RIT", locale),
"WT" => DiceTable::Table.from_i18n("Amadeus.table.WT", locale),
"NMT" => DiceTable::Table.from_i18n("Amadeus.table.NMT", locale),
"TGT" => DiceTable::Table.from_i18n("Amadeus.table.TGT", locale),
"CST" => DiceTable::Table.from_i18n("Amadeus.table.CST", locale),
"GCVT" => DiceTable::Table.from_i18n("Amadeus.table.GCVT", locale),
"YCVT" => DiceTable::Table.from_i18n("Amadeus.table.YCVT", locale),
"ECVT" => DiceTable::Table.from_i18n("Amadeus.table.ECVT", locale),
"CCVT" => DiceTable::Table.from_i18n("Amadeus.table.CCVT", locale),
"NCVT" => DiceTable::Table.from_i18n("Amadeus.table.NCVT", locale),
"DGVT" => DiceTable::Table.from_i18n("Amadeus.table.DGVT", locale),
"DAVT" => DiceTable::Table.from_i18n("Amadeus.table.DAVT", locale),
"PRCT" => DiceTable::Table.from_i18n("Amadeus.table.PRCT", locale),
"TCCT" => DiceTable::Table.from_i18n("Amadeus.table.TCCT", locale),
"INCT" => DiceTable::Table.from_i18n("Amadeus.table.INCT", locale),
"PSCT" => DiceTable::Table.from_i18n("Amadeus.table.PSCT", locale),
"LVCT" => DiceTable::Table.from_i18n("Amadeus.table.LVCT", locale),
"DACT" => DiceTable::Table.from_i18n("Amadeus.table.DACT", locale),
"RGT" => DiceTable::Table.from_i18n("Amadeus.table.RGT", locale),
"FBT" => DiceTable::Table.from_i18n("Amadeus.table.FBT", locale),
"CHVT" => DiceTable::Table.from_i18n("Amadeus.table.CHVT", locale),
"LCVT" => DiceTable::Table.from_i18n("Amadeus.table.LCVT", locale),
"KCVT" => DiceTable::Table.from_i18n("Amadeus.table.KCVT", locale),
"SAT" => DiceTable::D66Table.from_i18n("Amadeus.table.SAT", locale),
"SMT" => DiceTable::D66Table.from_i18n("Amadeus.table.SMT", locale),
}
end
end

TABLES = translate_tables(:ja_jp)
Expand Down
39 changes: 36 additions & 3 deletions test/data/Amadeus.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
game_system = "Amadeus"
input = "RC>=5"
output = "(RC>=5) > [5] > 5_成功[5]"
success = true
rands = [
{ sides = 6, value = 5 },
]
Expand All @@ -10,6 +11,7 @@ rands = [
game_system = "Amadeus"
input = "RC"
output = "(RC>=4) > [5] > 5_成功[5]"
success = true
rands = [
{ sides = 6, value = 5 },
]
Expand All @@ -18,6 +20,7 @@ rands = [
game_system = "Amadeus"
input = "RC"
output = "(RC>=4) > [2] > 2_失敗[2]"
failure = true
rands = [
{ sides = 6, value = 2 },
]
Expand All @@ -26,6 +29,7 @@ rands = [
game_system = "Amadeus"
input = "RC+2"
output = "(RC+2>=4) > [2]+2 > 4_成功[2]"
success = true
rands = [
{ sides = 6, value = 2 },
]
Expand All @@ -34,30 +38,34 @@ rands = [
game_system = "Amadeus"
input = "RC-3"
output = "(RC-3>=4) > [2]-3 > -1_失敗[2]"
failure = true
rands = [
{ sides = 6, value = 2 },
]

[[ test ]]
game_system = "Amadeus"
input = "RC-3+2"
output = "(RC-3+2>=4) > [2]-3+2 > 1_失敗[2]"
output = "(RC-1>=4) > [2]-1 > 1_失敗[2]"
failure = true
rands = [
{ sides = 6, value = 2 },
]

[[ test ]]
game_system = "Amadeus"
input = "RC>=5-1"
output = "(RC>=5-1) > [5] > 5_成功[5]"
output = "(RC>=4) > [5] > 5_成功[5]"
success = true
rands = [
{ sides = 6, value = 5 },
]

[[ test ]]
game_system = "Amadeus"
input = "RC>=5-2 hogehoge"
output = "(RC>=5-2) > [5] > 5_成功[5]"
output = "(RC>=3) > [5] > 5_成功[5]"
success = true
rands = [
{ sides = 6, value = 5 },
]
Expand All @@ -66,15 +74,28 @@ rands = [
game_system = "Amadeus"
input = "RB+1>=5"
output = "(RB+1>=5) > [2,4]+1 > 3_失敗[2赤] / 5_成功[4緑]"
success = true
rands = [
{ sides = 6, value = 2 },
{ sides = 6, value = 4 },
]

[[ test ]]
game_system = "Amadeus"
input = "RB+2 ファンブルかつ成功のときはsuccessのみ"
output = "(RB+2>=4) > [1,2]+2 > 3_ファンブル![1黒] / 4_成功[2赤]"
success = true
rands = [
{ sides = 6, value = 1 },
{ sides = 6, value = 2 },
]

[[ test ]]
game_system = "Amadeus"
input = "RA-1"
output = "(RA-1>=4) > [1,5,6]-1 > 0_ファンブル![1黒] / 4_成功[5白] / 5_スペシャル![6任意]"
success = true
critical = true
rands = [
{ sides = 6, value = 1 },
{ sides = 6, value = 5 },
Expand All @@ -85,6 +106,8 @@ rands = [
game_system = "Amadeus"
input = "RS"
output = "(RS>=4) > [2,1,5,6] > 2_失敗[2赤] / 1_ファンブル![1黒] / 5_成功[5白] / 6_スペシャル![6任意]"
success = true
critical = true
rands = [
{ sides = 6, value = 2 },
{ sides = 6, value = 1 },
Expand All @@ -96,6 +119,7 @@ rands = [
game_system = "Amadeus"
input = "RD+1>=5"
output = "(RD+1>=5) > [2,4]+1 > 3_失敗[2]"
failure = true
rands = [
{ sides = 6, value = 2 },
{ sides = 6, value = 4 },
Expand All @@ -105,6 +129,8 @@ rands = [
game_system = "Amadeus"
input = "RB@5"
output = "(RB@5>=4) > [2,5] > 2_失敗[2赤] / 5_スペシャル![5白]"
success = true
critical = true
rands = [
{ sides = 6, value = 2 },
{ sides = 6, value = 5 },
Expand All @@ -114,6 +140,8 @@ rands = [
game_system = "Amadeus"
input = "RB+2@5"
output = "(RB+2@5>=4) > [2,5]+2 > 4_成功[2赤] / 7_スペシャル![5白]"
success = true
critical = true
rands = [
{ sides = 6, value = 2 },
{ sides = 6, value = 5 },
Expand All @@ -123,6 +151,8 @@ rands = [
game_system = "Amadeus"
input = "RB+2@5>=5"
output = "(RB+2@5>=5) > [2,5]+2 > 4_失敗[2赤] / 7_スペシャル![5白]"
success = true
critical = true
rands = [
{ sides = 6, value = 2 },
{ sides = 6, value = 5 },
Expand All @@ -132,6 +162,8 @@ rands = [
game_system = "Amadeus"
input = "RB+2>=5@5"
output = "(RB+2@5>=5) > [2,5]+2 > 4_失敗[2赤] / 7_スペシャル![5白]"
success = true
critical = true
rands = [
{ sides = 6, value = 2 },
{ sides = 6, value = 5 },
Expand Down Expand Up @@ -667,6 +699,7 @@ rands = [
game_system = "Amadeus"
input = "RB+1>3 不要な機能だけど一応実装してみる。"
output = "(RB+1>3) > [2,4]+1 > 3_失敗[2赤] / 5_成功[4緑]"
success = true
rands = [
{ sides = 6, value = 2 },
{ sides = 6, value = 4 },
Expand Down
Loading