From 7faebf017328df2b6626f7e047bdcc22dad87225 Mon Sep 17 00:00:00 2001 From: Trevor Vallender Date: Mon, 8 Jul 2024 15:08:17 +0100 Subject: [PATCH] Use gem for dice rolling --- Gemfile | 2 ++ Gemfile.lock | 39 +++++++++++++++++++++++++++++++ app/services/dice_roller.rb | 25 ++++---------------- test/fixtures/stats.yml | 6 ++--- test/models/stat_test.rb | 2 +- test/services/dice_roller_test.rb | 12 +++++----- 6 files changed, 55 insertions(+), 31 deletions(-) diff --git a/Gemfile b/Gemfile index 4134b9a..9dd7c87 100644 --- a/Gemfile +++ b/Gemfile @@ -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" diff --git a/Gemfile.lock b/Gemfile.lock index 8050c1c..ccfd26f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 diff --git a/app/services/dice_roller.rb b/app/services/dice_roller.rb index 5743f7e..3056a1a 100644 --- a/app/services/dice_roller.rb +++ b/app/services/dice_roller.rb @@ -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 = @roll_command.sub("self", @stat.to_s) if @roll_command.include?("self") + Dice.roll(@roll_command) end def valid? @@ -50,12 +39,6 @@ class DiceRoller private - def roll_command_parts - @roll_command.scan(/([+\-*\/])|(\d*d\d+)|(\d+)|(self)/xi) - .flatten - .compact_blank - end - def roll_dice(command) parts = command.downcase.split("d").compact_blank die_type = parts.last diff --git a/test/fixtures/stats.yml b/test/fixtures/stats.yml index 1e1165e..472bca5 100644 --- a/test/fixtures/stats.yml +++ b/test/fixtures/stats.yml @@ -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 diff --git a/test/models/stat_test.rb b/test/models/stat_test.rb index 775807a..63ddfc8 100644 --- a/test/models/stat_test.rb +++ b/test/models/stat_test.rb @@ -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 diff --git a/test/services/dice_roller_test.rb b/test/services/dice_roller_test.rb index 23266fa..e91b43e 100644 --- a/test/services/dice_roller_test.rb +++ b/test/services/dice_roller_test.rb @@ -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