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 "active_storage_validations"
gem "dice-roller", git: "https://github.com/Tablewarez/always_rolling"
group :development, :test do group :development, :test do
gem "debug", platforms: %i[ mri windows ] gem "debug", platforms: %i[ mri windows ]
gem "dotenv" 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 GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
@ -100,6 +111,7 @@ GEM
regexp_parser (>= 1.5, < 3.0) regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2) xpath (~> 3.2)
childprocess (5.0.0) childprocess (5.0.0)
coderay (1.1.3)
concurrent-ruby (1.2.3) concurrent-ruby (1.2.3)
connection_pool (2.4.1) connection_pool (2.4.1)
crass (1.0.6) crass (1.0.6)
@ -107,11 +119,14 @@ GEM
debug (1.9.2) debug (1.9.2)
irb (~> 1.10) irb (~> 1.10)
reline (>= 0.3.8) reline (>= 0.3.8)
diff-lcs (1.5.1)
docile (1.4.0)
dotenv (3.1.2) dotenv (3.1.2)
drb (2.2.1) drb (2.2.1)
erubi (1.12.0) erubi (1.12.0)
et-orbi (1.2.11) et-orbi (1.2.11)
tzinfo tzinfo
expression_parser (0.9.0)
ffi (1.16.3) ffi (1.16.3)
fugit (1.10.1) fugit (1.10.1)
et-orbi (~> 1, >= 1.2.7) et-orbi (~> 1, >= 1.2.7)
@ -151,6 +166,7 @@ GEM
net-smtp net-smtp
marcel (1.0.4) marcel (1.0.4)
matrix (0.4.2) matrix (0.4.2)
method_source (1.1.0)
mini_magick (4.12.0) mini_magick (4.12.0)
mini_mime (1.1.5) mini_mime (1.1.5)
minitest (5.23.1) minitest (5.23.1)
@ -193,6 +209,9 @@ GEM
activesupport (>= 7.0.0) activesupport (>= 7.0.0)
rack rack
railties (>= 7.0.0) railties (>= 7.0.0)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
psych (5.1.2) psych (5.1.2)
stringio stringio
public_suffix (5.0.5) public_suffix (5.0.5)
@ -246,6 +265,19 @@ GEM
io-console (~> 0.5) io-console (~> 0.5)
rexml (3.2.8) rexml (3.2.8)
strscan (>= 3.0.9) 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) rubocop (1.64.0)
json (~> 2.3) json (~> 2.3)
language_server-protocol (>= 3.17.0) language_server-protocol (>= 3.17.0)
@ -284,6 +316,12 @@ GEM
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0) rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.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) solid_queue (0.3.1)
activejob (>= 7.1) activejob (>= 7.1)
activerecord (>= 7.1) activerecord (>= 7.1)
@ -331,6 +369,7 @@ DEPENDENCIES
bootsnap bootsnap
capybara capybara
debug debug
dice-roller!
dotenv dotenv
image_processing (~> 1.2) image_processing (~> 1.2)
importmap-rails importmap-rails

View File

@ -1,5 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require "dice"
class DiceRoller class DiceRoller
attr_reader :dice attr_reader :dice
attr_reader :result attr_reader :result
@ -11,21 +13,8 @@ class DiceRoller
end end
def roll def roll
result = 0 roll_command = parse_roll_command_references(roll_command)
operator = nil Dice.roll(roll_command)
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
end end
def valid? def valid?
@ -50,10 +39,8 @@ class DiceRoller
private private
def roll_command_parts def roll_delimiters
@roll_command.scan(/([+\-*\/])|(\d*d\d+)|(\d+)|(self)/xi) [ "+", "-", "*", "/" ]
.flatten
.compact_blank
end end
def roll_dice(command) def roll_dice(command)
@ -69,4 +56,18 @@ class DiceRoller
end end
result result
end 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 end

View File

@ -1,14 +1,14 @@
strength: strength:
name: Strength name: Strength
value: 10 value: 10
roll_command: d20+self roll_command: 1d20+self
dexterity: dexterity:
name: Dexterity name: Dexterity
value: 10 value: 10
roll_command: d20+self roll_command: 1d20+self
constitution: constitution:
name: Constitution name: Constitution
value: 10 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 test "rolls with roll_command" do
stat = stats(:strength) stat = stats(:strength)
stat.roll_command = "1d6" stat.update(roll_command: "1d6")
100.times { assert (1..6).cover?(stat.roll(tables(:dnd_table))) } 100.times { assert (1..6).cover?(stat.roll(tables(:dnd_table))) }
end end
end end

View File

@ -8,15 +8,15 @@ class DiceRollerTest < ActiveSupport::TestCase
"2d6", "2d6",
"12", "12",
"self", "self",
"d12", "1d12",
"d20+self", "1d20+self",
"8+D8-self", "8+1D8-self",
] ]
invalid_strings = [ invalid_strings = [
"+", "+",
"sel+10", "sel+10",
"d8++13", "1d8++13",
] ]
valid_strings.each do |roll_command| valid_strings.each do |roll_command|
@ -30,9 +30,9 @@ class DiceRollerTest < ActiveSupport::TestCase
test "rolls appropriate results" do test "rolls appropriate results" do
100.times 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 (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 end
end end

View File

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