Compare commits

...

2 Commits

Author SHA1 Message Date
Trevor Vallender 1556ebe9c7 Reference features in rolls by slug 2024-07-08 16:15:48 +01:00
Trevor Vallender 7faebf0173 Use gem for dice rolling 2024-07-08 15:08:17 +01:00
7 changed files with 72 additions and 31 deletions

View File

@ -22,6 +22,8 @@ gem "mission_control-jobs"
gem "active_storage_validations"
gem "dice-roller", git: "https://github.com/Tablewarez/always_rolling"
group :development, :test do
gem "debug", platforms: %i[ mri windows ]
gem "dotenv"

View File

@ -1,3 +1,14 @@
GIT
remote: https://github.com/Tablewarez/always_rolling
revision: 44ed421d854dc41e6021da3ab9427455d9c807ba
specs:
dice-roller (0.0.5)
activesupport (>= 4.2)
expression_parser (~> 0.9)
pry (~> 0.10)
rspec (~> 3.4)
simplecov (~> 0.11)
GEM
remote: https://rubygems.org/
specs:
@ -100,6 +111,7 @@ GEM
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
childprocess (5.0.0)
coderay (1.1.3)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
crass (1.0.6)
@ -107,11 +119,14 @@ GEM
debug (1.9.2)
irb (~> 1.10)
reline (>= 0.3.8)
diff-lcs (1.5.1)
docile (1.4.0)
dotenv (3.1.2)
drb (2.2.1)
erubi (1.12.0)
et-orbi (1.2.11)
tzinfo
expression_parser (0.9.0)
ffi (1.16.3)
fugit (1.10.1)
et-orbi (~> 1, >= 1.2.7)
@ -151,6 +166,7 @@ GEM
net-smtp
marcel (1.0.4)
matrix (0.4.2)
method_source (1.1.0)
mini_magick (4.12.0)
mini_mime (1.1.5)
minitest (5.23.1)
@ -193,6 +209,9 @@ GEM
activesupport (>= 7.0.0)
rack
railties (>= 7.0.0)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
psych (5.1.2)
stringio
public_suffix (5.0.5)
@ -246,6 +265,19 @@ GEM
io-console (~> 0.5)
rexml (3.2.8)
strscan (>= 3.0.9)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.0)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-support (3.13.1)
rubocop (1.64.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
@ -284,6 +316,12 @@ GEM
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
solid_queue (0.3.1)
activejob (>= 7.1)
activerecord (>= 7.1)
@ -331,6 +369,7 @@ DEPENDENCIES
bootsnap
capybara
debug
dice-roller!
dotenv
image_processing (~> 1.2)
importmap-rails

View File

@ -1,5 +1,7 @@
# frozen_string_literal: true
require "dice"
class DiceRoller
attr_reader :dice
attr_reader :result
@ -11,21 +13,8 @@ class DiceRoller
end
def roll
result = 0
operator = nil
roll_command_parts.each do |part|
case part
when /\A\d*d\d+\z/
operator.nil? ? (result += roll_dice(part)) : (result = result.send(operator, roll_dice(part)))
when /\A\d+\z/
operator.nil? ? (result += part.to_i) : (result = result.send(operator, part.to_i))
when "self"
operator.nil? ? (result += @stat) : (result = result.send(operator, @stat))
when /\A[+\-*\/]\z/
operator = part
end
end
result
roll_command = parse_roll_command_references(roll_command)
Dice.roll(roll_command)
end
def valid?
@ -50,10 +39,8 @@ class DiceRoller
private
def roll_command_parts
@roll_command.scan(/([+\-*\/])|(\d*d\d+)|(\d+)|(self)/xi)
.flatten
.compact_blank
def roll_delimiters
[ "+", "-", "*", "/" ]
end
def roll_dice(command)
@ -69,4 +56,18 @@ class DiceRoller
end
result
end
def parse_roll_command_references(roll_command)
roll_command = @roll_command.include?("self") ? @roll_command.gsub("self", @stat.to_s) : @roll_command
roll_command.split(Regexp.union(roll_delimiters)).each do |part|
next if part.match?(/\A\d*\z/)
next if part.match?(/\A\d*d\d*\z/)
value = CharacterSheetFeature.find_by(slug: part).featurable.value
raise "#{part} not found" if value.blank?
roll_command.gsub!(part, value.to_s)
end
roll_command
end
end

View File

@ -1,14 +1,14 @@
strength:
name: Strength
value: 10
roll_command: d20+self
roll_command: 1d20+self
dexterity:
name: Dexterity
value: 10
roll_command: d20+self
roll_command: 1d20+self
constitution:
name: Constitution
value: 10
roll_command: d20+self
roll_command: 1d20+self

View File

@ -27,7 +27,7 @@ class StatTest < ActiveSupport::TestCase
test "rolls with roll_command" do
stat = stats(:strength)
stat.roll_command = "1d6"
stat.update(roll_command: "1d6")
100.times { assert (1..6).cover?(stat.roll(tables(:dnd_table))) }
end
end

View File

@ -8,15 +8,15 @@ class DiceRollerTest < ActiveSupport::TestCase
"2d6",
"12",
"self",
"d12",
"d20+self",
"8+D8-self",
"1d12",
"1d20+self",
"8+1D8-self",
]
invalid_strings = [
"+",
"sel+10",
"d8++13",
"1d8++13",
]
valid_strings.each do |roll_command|
@ -30,9 +30,9 @@ class DiceRollerTest < ActiveSupport::TestCase
test "rolls appropriate results" do
100.times do
assert (1..6).include? DiceRoller.new("d6").roll
assert (1..6).include? DiceRoller.new("1d6").roll
assert (2..12).include? DiceRoller.new("2d6").roll
assert (11..30).include? DiceRoller.new("d20+self", stat: stats(:strength)).roll
assert (11..30).include? DiceRoller.new("1d20+self", stat: stats(:strength)).roll
end
end
end

View File

@ -1,10 +1,9 @@
Character sheets
= Must haves
- Refer to stat in roll (Skill in Troika)
- Add tests for feature references
- Lists
- Reorganise sections
- Edit additional roll types
- improve dice roll parsing to allow e.g. choose highest
= Nice to haves
- Calculate from result - e.g. troika damage roll should calc. damage amount from die roll:w
- Add min/max when creating stats