nerd_dice 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a931b4532dcafcb4ce3aeddf3ac30399bb9334d25bf78671a0811366670d719
4
- data.tar.gz: 970d96a32b68dc1fc75618376bf059707c5c711441d30edd6302dcd37e831c8b
3
+ metadata.gz: fa0fb8eebb2386727cce81ce7a3c301599322a3531db13f01329aa26225c88b3
4
+ data.tar.gz: 205640e5b275ae107e0c2ee0ff1c10b777782f21c7a3c0ae7a5aac98e27f4841
5
5
  SHA512:
6
- metadata.gz: 5cdbd36e786d2c4e6f8950f4486119548bb1a62babdbf3c9ae4fadba095170b9300461411926d19ca50e5e8d277804c3f8cb61e28d96605fd5fad8b7e9c9b700
7
- data.tar.gz: 21b2b92dbf7ad4060a888d267383e9c87b3e310dff4931bb1853f401fb417f480a2bea7cca859ad75d3eac83608a4631541a36afc7449955a68ea8ff84c319c7
6
+ metadata.gz: 0d275950feb1506a5a7602450690dab697c0ccd35b8d85a0869c4675c2dd714c85d2c744854ac7f69c7f204b1e55ecbf7e80f9209eb672ef4705d15fdbd10fd7
7
+ data.tar.gz: fb8d5aa2297ecbf722b9242caf2680272a502d801dbd94fd53c6bd359a21a50e6e0e1096a5c5518a25a9ef842609c6db0af7c6b5273f4a1fd2e4f2f6089d393e
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,67 @@
1
+ # This is a basic workflow to help you get started with Actions
2
+
3
+ name: Nerd Dice CI
4
+
5
+ # Controls when the action will run.
6
+ on: [push, pull_request]
7
+
8
+ # Allows you to run this workflow manually from the Actions tab
9
+ # workflow_dispatch:
10
+
11
+ jobs:
12
+ test_rspec:
13
+
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ ruby-version: ['2.7', '3.0']
18
+
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - name: Set up Ruby
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: ${{ matrix.ruby-version }}
25
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
26
+ - name: Run tests
27
+ run: bundle exec rake
28
+ - name: Coveralls Parallel
29
+ uses: coverallsapp/github-action@master
30
+ with:
31
+ github-token: ${{ secrets.github_token }}
32
+ flag-name: run-${{ matrix.test_number }}
33
+ parallel: true
34
+
35
+ rubocop:
36
+ runs-on: ubuntu-latest
37
+ steps:
38
+ - uses: actions/checkout@v2
39
+ - name: Set up Ruby
40
+ uses: ruby/setup-ruby@v1
41
+ with:
42
+ ruby-version: '3.0'
43
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
44
+ - name: Run rubocop
45
+ run: bundle exec rubocop --parallel
46
+
47
+ benchmark:
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v2
51
+ - name: Set up Ruby
52
+ uses: ruby/setup-ruby@v1
53
+ with:
54
+ ruby-version: '3.0'
55
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
56
+ - name: Run benchmark script
57
+ run: bin/nerd_dice_benchmark
58
+
59
+ finish:
60
+ needs: test_rspec
61
+ runs-on: ubuntu-latest
62
+ steps:
63
+ - name: Coveralls Finished
64
+ uses: coverallsapp/github-action@master
65
+ with:
66
+ github-token: ${{ secrets.github_token }}
67
+ parallel-finished: true
data/.rubocop.yml CHANGED
@@ -334,3 +334,69 @@ Style/EndlessMethod: # (new in 1.8)
334
334
 
335
335
  Style/HashExcept: # (new in 1.7)
336
336
  Enabled: true
337
+
338
+ # Added 2021-08-14
339
+ Gemspec/DateAssignment: # (new in 1.10)
340
+ Enabled: true
341
+
342
+ Layout/LineEndStringConcatenationIndentation: # (new in 1.18)
343
+ Enabled: true
344
+
345
+ Lint/EmptyInPattern: # (new in 1.16)
346
+ Enabled: true
347
+
348
+ Lint/NumberedParameterAssignment: # (new in 1.9)
349
+ Enabled: true
350
+
351
+ Lint/OrAssignmentToConstant: # (new in 1.9)
352
+ Enabled: true
353
+
354
+ Lint/SymbolConversion: # (new in 1.9)
355
+ Enabled: true
356
+
357
+ Lint/TripleQuotes: # (new in 1.9)
358
+ Enabled: true
359
+
360
+ Naming/InclusiveLanguage: # (new in 1.18)
361
+ Enabled: false
362
+
363
+ Style/HashConversion: # (new in 1.10)
364
+ Enabled: true
365
+
366
+ Style/IfWithBooleanLiteralBranches: # (new in 1.9)
367
+ Enabled: true
368
+
369
+ Style/InPatternThen: # (new in 1.16)
370
+ Enabled: true
371
+
372
+ Style/MultilineInPatternThen: # (new in 1.16)
373
+ Enabled: true
374
+
375
+ Style/QuotedSymbols: # (new in 1.16)
376
+ Enabled: true
377
+
378
+ Style/StringChars: # (new in 1.12)
379
+ Enabled: true
380
+
381
+ Performance/MapCompact: # (new in 1.11)
382
+ Enabled: true
383
+
384
+ Performance/RedundantEqualityComparisonBlock: # (new in 1.10)
385
+ Enabled: true
386
+
387
+ Performance/RedundantSplitRegexpArgument: # (new in 1.10)
388
+ Enabled: true
389
+
390
+ RSpec/IdenticalEqualityAssertion: # (new in 2.4)
391
+ Enabled: true
392
+
393
+ RSpec/Rails/AvoidSetupHook: # (new in 2.4)
394
+ Enabled: true
395
+
396
+ RSpec/MessageSpies:
397
+ EnforcedStyle: receive
398
+
399
+ Lint/AmbiguousRange: # new in 1.19
400
+ Enabled: true
401
+ Style/RedundantSelfAssignmentBranch: # new in 1.19
402
+ Enabled: true
data/CHANGELOG.md CHANGED
@@ -5,7 +5,35 @@
5
5
  ### Changed
6
6
  ### Fixed
7
7
 
8
- ## 0.2.0 \(2020-12-12\)
8
+ ## 0.3.0 \(2021-09-11\)
9
+ ### Added
10
+ * Add new options to `NerdDice::Configuration`
11
+ - `ability_score_number_of_sides`
12
+ - `ability_score_dice_rolled`
13
+ - `ability_score_dice_kept`
14
+ * Add `NerdDice.harvest_totals` method that takes in a collection and returns the results of calling `total` on each element
15
+ * Add `NerdDice.roll_ability_scores` convenience method that returns an array of `DiceSet` objects based on options and/or configuration
16
+ * Add `NerdDice.total_ability_scores` convenience method that returns an array of integers based on options and/or configuration
17
+ * Add `NerdDice::Die` class that represents a single die object and mixes in the `Comparable` module
18
+ * Add `NerdDice::DiceSet` class that represents a collection of `Die` objects and mixes in the `Enumerable` module
19
+ * Add `NerdDice::SetsRandomizationTechnique` mixin module and include in the `DiceSet` and `Die` classes
20
+ * Add `die_background_color` and `die_foreground_color` to `Configuration` class with defaults defined as constants
21
+ * Add `NerdDice.roll_dice` method that behaves in a similar fashion to `total_dice` but returns a `DiceSet` object instead of an `Integer` and has additional optional arguments relating to the non-numeric attributes of the dice
22
+ * Add `coveralls_reborn` to RSpec and GitHub actions
23
+ * Add build badge to README
24
+ * Add Code Climate maintainability integration and badge to README
25
+ * Add `nerd_dice_benchmark` script to bin directory
26
+ * Add GitHub Action CI build
27
+ - Run RSpec test suite, fail if specs fail, report coverage via Coveralls
28
+ - Run RuboCop and fail if violations
29
+ - Run benchmark suite and fail if outside of allowed ratios
30
+ ### Changed
31
+ * Update RuboCop version and configuration
32
+ * Break up the NerdDice source code file into several smaller files that are included by the module
33
+ * Enforce that `NerdDice.configuration.ability_score_array_size` must be a positive duck-type integer
34
+ ### Fixed
35
+
36
+ ## 0.2.0 \(2021-01-28\)
9
37
  ### Added
10
38
  * Add ability to configure with `NerdDice.configure` block or `NerdDice.configuration`
11
39
  - Configure `randomization_technique` as `:random_rand`, `:securerandom`, `:random_object`, or `randomized`
data/Gemfile.lock CHANGED
@@ -1,21 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nerd_dice (0.2.0)
4
+ nerd_dice (0.3.0)
5
5
  securerandom (~> 0.1, >= 0.1.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  ast (2.4.2)
11
+ coveralls_reborn (0.22.0)
12
+ simplecov (>= 0.18.1, < 0.22.0)
13
+ term-ansicolor (~> 1.6)
14
+ thor (>= 0.20.3, < 2.0)
15
+ tins (~> 1.16)
11
16
  diff-lcs (1.4.4)
17
+ docile (1.4.0)
12
18
  parallel (1.20.1)
13
- parser (3.0.0.0)
19
+ parser (3.0.2.0)
14
20
  ast (~> 2.4.1)
15
21
  rainbow (3.0.0)
16
22
  rake (12.3.3)
17
- regexp_parser (2.0.3)
18
- rexml (3.2.4)
23
+ regexp_parser (2.1.1)
24
+ rexml (3.2.5)
19
25
  rspec (3.10.0)
20
26
  rspec-core (~> 3.10.0)
21
27
  rspec-expectations (~> 3.10.0)
@@ -25,44 +31,59 @@ GEM
25
31
  rspec-expectations (3.10.1)
26
32
  diff-lcs (>= 1.2.0, < 2.0)
27
33
  rspec-support (~> 3.10.0)
28
- rspec-mocks (3.10.1)
34
+ rspec-mocks (3.10.2)
29
35
  diff-lcs (>= 1.2.0, < 2.0)
30
36
  rspec-support (~> 3.10.0)
31
- rspec-support (3.10.1)
32
- rubocop (1.8.1)
37
+ rspec-support (3.10.2)
38
+ rubocop (1.20.0)
33
39
  parallel (~> 1.10)
34
40
  parser (>= 3.0.0.0)
35
41
  rainbow (>= 2.2.2, < 4.0)
36
42
  regexp_parser (>= 1.8, < 3.0)
37
43
  rexml
38
- rubocop-ast (>= 1.2.0, < 2.0)
44
+ rubocop-ast (>= 1.9.1, < 2.0)
39
45
  ruby-progressbar (~> 1.7)
40
46
  unicode-display_width (>= 1.4.0, < 3.0)
41
- rubocop-ast (1.4.1)
42
- parser (>= 2.7.1.5)
43
- rubocop-performance (1.9.2)
44
- rubocop (>= 0.90.0, < 2.0)
47
+ rubocop-ast (1.11.0)
48
+ parser (>= 3.0.1.1)
49
+ rubocop-performance (1.11.5)
50
+ rubocop (>= 1.7.0, < 2.0)
45
51
  rubocop-ast (>= 0.4.0)
46
- rubocop-rake (0.5.1)
47
- rubocop
48
- rubocop-rspec (2.1.0)
52
+ rubocop-rake (0.6.0)
53
+ rubocop (~> 1.0)
54
+ rubocop-rspec (2.4.0)
49
55
  rubocop (~> 1.0)
50
56
  rubocop-ast (>= 1.1.0)
51
57
  ruby-progressbar (1.11.0)
52
58
  securerandom (0.1.0)
59
+ simplecov (0.21.2)
60
+ docile (~> 1.1)
61
+ simplecov-html (~> 0.11)
62
+ simplecov_json_formatter (~> 0.1)
63
+ simplecov-html (0.12.3)
64
+ simplecov-lcov (0.8.0)
65
+ simplecov_json_formatter (0.1.3)
66
+ sync (0.5.0)
67
+ term-ansicolor (1.7.1)
68
+ tins (~> 1.0)
69
+ thor (1.1.0)
70
+ tins (1.29.1)
71
+ sync
53
72
  unicode-display_width (2.0.0)
54
73
 
55
74
  PLATFORMS
56
75
  ruby
57
76
 
58
77
  DEPENDENCIES
78
+ coveralls_reborn (~> 0.22.0)
59
79
  nerd_dice!
60
80
  rake (~> 12.0)
61
81
  rspec (~> 3.0)
62
- rubocop (~> 1.8, >= 1.8.1)
63
- rubocop-performance (~> 1.9, >= 1.9.1)
64
- rubocop-rake (~> 0.5, >= 0.5.1)
65
- rubocop-rspec (~> 2.1, >= 2.1.0)
82
+ rubocop (~> 1.20, >= 1.20.0)
83
+ rubocop-performance (~> 1.11, >= 1.11.5)
84
+ rubocop-rake (~> 0.6, >= 0.6.0)
85
+ rubocop-rspec (~> 2.4, >= 2.4.0)
86
+ simplecov-lcov (~> 0.8.0)
66
87
 
67
88
  BUNDLED WITH
68
- 2.2.3
89
+ 2.2.22
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
+ [![Coverage Status](https://coveralls.io/repos/github/statelesscode/nerd_dice/badge.svg?branch=master)](https://coveralls.io/github/statelesscode/nerd_dice?branch=master)
2
+ ![Build](https://github.com/statelesscode/nerd_dice/actions/workflows/main.yml/badge.svg)
3
+ [![Maintainability](https://api.codeclimate.com/v1/badges/721f587b792d583065be/maintainability)](https://codeclimate.com/github/statelesscode/nerd_dice/maintainability)
1
4
  # NerdDice
2
5
  Nerd dice allows you to roll polyhedral dice and add bonuses as you would in a tabletop roleplaying game. You can choose to roll multiple dice and keep a specified number of dice such as rolling 4d6 and dropping the lowest for ability scores or rolling with advantage and disadvantage if those mechanics exist in your game.
3
6
 
7
+ ## Educational Videos By Stateless Code
8
+ The end-to-end process of developing this gem has been captured as [instructional videos](https://www.youtube.com/playlist?list=PL9kkbu1kLUeOnUtMpAnJOCtHdThx1Efkt). The videos are in a one-take style so that the mistakes along the way have troubleshooting and the concepts used to develop the gem are explained as they are covered.
9
+
4
10
  ## Installation
5
11
 
6
12
  Add this line to your application's Gemfile:
@@ -25,7 +31,17 @@ You can customize the behavior of NerdDice via a configuration block as below or
25
31
  NerdDice.configure do | config|
26
32
 
27
33
  # number of ability scores to place in an ability score array
28
- config.ability_score_array_size = 6
34
+ config.ability_score_array_size = 6 # must duck-type to positive Integer
35
+
36
+ # number of sides for each ability score Die
37
+ config.ability_score_number_of_sides = 6 # must duck-type to positive Integer
38
+
39
+ # total number of dice rolled for each ability score
40
+ config.ability_score_dice_rolled = 4 # must duck-type to positive Integer
41
+
42
+ # highest(n) dice from the total number of dice rolled that are included in the ability score total
43
+ # CANNOT EXCEED ability_score_dice_rolled see Note below
44
+ config.ability_score_dice_kept = 3 # must duck-type to positive Integer
29
45
 
30
46
  # randomization technique options are:
31
47
  # :securerandom => Uses SecureRandom.rand(). Good entropy, medium speed.
@@ -40,26 +56,167 @@ NerdDice.configure do | config|
40
56
  # 1 very slow and heavy pressure on processor and memory but very high entropy
41
57
  # 1000 would refresh the object every 1000 times you call rand()
42
58
  config.refresh_seed_interval = nil # don't refresh the seed
59
+ # Background and foreground die colors are string values. By default these correspond to the constants in the class
60
+ # Defaults: DEFAULT_BACKGROUND_COLOR = "#0000DD" DEFAULT_FOREGROUND_COLOR = "#DDDDDD"
61
+ # It is recommended but not enforced that these should be valid CSS color property attributes
62
+ config.die_background_color = "red"
63
+ config.die_foreground_color = "#000"
43
64
  end
44
65
  ```
66
+ **Note:** You cannot set `ability_score_dice_kept` greater than `ability_score_dice_rolled`. If you try to set `ability_score_dice_kept` higher than `ability_score_dice_rolled`, an error will be raised. If you set `ability_score_dice_rolled` _lower_ than the existing value of `ability_score_dice_kept`, no error will be thrown, but `ability_score_dice_kept` will be _**modified**_ to match `ability_score_dice_rolled` and a warning will be printed.
45
67
 
46
68
  ### Rolling a number of dice and adding a bonus
69
+ You can use two different methods to roll dice. The `total_dice` method returns an `Integer` representing the total of the dice plus any applicable bonuses. The `total_dice` method does not support chaining additional methods like `highest`, `lowest`, `with_advantage`, `with_disadvantage`. The `roll_dice` method returns a `DiceSet` collection object, and allows for chaining the methods mentioned above and iterating over the individual `Die` objects. `NerdDice.roll_dice.total` and `NerdDice.total_dice` are roughly equivalent.
70
+
47
71
  ```ruby
48
72
  # roll a single d4
49
73
  NerdDice.total_dice(4) # => return random Integer between 1-4
74
+ NerdDice.roll_dice(4) # => return a DiceSet with one 4-sided Die with a value between 1-4
75
+ NerdDice.roll_dice(4).total # => return random Integer between 1-4
50
76
 
51
77
  # roll 3d6
52
78
  NerdDice.total_dice(6, 3) # => return Integer total of three 6-sided dice
79
+ NerdDice.roll_dice(6, 3) # => return a DiceSet with three 6-sided Die objects, each with values between 1-6
80
+ NerdDice.roll_dice(6, 3).total # => return Integer total of three 6-sided dice
53
81
 
54
82
  # roll a d20 and add 5 to the value
55
- NerdDice.total_dice(20, bonus: 5)
83
+ NerdDice.total_dice(20, bonus: 5) # rolls a d20 and adds the bonus to the total => Integer
84
+ NerdDice.roll_dice(20, bonus: 5) # return a DiceSet with one 20-sided Die with a value between 1-20 and a bonus attribute of 5
85
+ NerdDice.roll_dice(20, bonus: 5).total # rolls a d20 and adds the bonus to the total => Integer
56
86
 
87
+ # without changing the config at the module level
57
88
  # roll a d20 and overide the configured randomization_technique one time
58
- # without changing the config
59
- NerdDice.total_dice(20, randomization_technique: :randomized)
89
+ NerdDice.total_dice(20, randomization_technique: :randomized) # => Integer
90
+ # roll a d20 and overide the configured randomization_technique for the DiceSet object will persist on the DiceSet object for subsequent rerolls
91
+ NerdDice.roll_dice(20, randomization_technique: :randomized) # => DiceSet with randomization_technique: :randomized
60
92
  ```
61
93
  __NOTE:__ If provided, the bonus must respond to `:to_i` or an `ArgumentError` will be raised
62
94
 
95
+ ### Taking actions on the dice as objects using the DiceSet object
96
+ The `NerdDice.roll_dice` method or the `NerdDice::DiceSet.new` methods return a collection object with an array of one or more `Die` objects. There are properties on both the `DiceSet` object and the `Die` object. Applicable properties are cascaded from the `DiceSet` to the `Die` objects in the collection by default.
97
+
98
+ ```ruby
99
+ # These are equivalent
100
+ dice_set = NerdDice.roll_dice(6, 3, bonus: 2, randomization_technique: :randomized, damage_type: 'psychic', foreground_color: '#FFF', background_color: '#0FF')
101
+ # => NerdDice::DiceSet
102
+ dice_set = NerdDice::DiceSet.new(6, 3, bonus: 2, randomization_technique: :randomized, damage_type: 'psychic', foreground_color: '#FFF', background_color: '#0FF')
103
+ # => NerdDice::DiceSet
104
+ ```
105
+ #### Available options for NerdDice::DiceSet objects
106
+ There are a number of options that can be provided when initializing a `NerdDice::DiceSet` object after specifying the mandatory number of sides and the optional number of dice \(default: 1\). The list below provides the options and indicates whether they are cascaded to the Die objects in the collection.
107
+ * `bonus` \(Duck-type Integer, _default: 0_\): Bonus or penalty to apply to the total after all dice are rolled. _**Not applied** to Die objects_
108
+ * `randomization_technique` \(Symbol, _default: nil_\): Randomization technique override to use for the `DiceSet`. If `nil` it will use the value in `NerdDice.configuration`. _**Applied** to Die objects by default with ability modify_
109
+ * `damage_type` \(String, _default: nil_\): Optional string indicating the damage type associated with the dice for systems where it is relevant. _**Applied** to Die objects by default with ability modify_
110
+ * `foreground_color` \(String, _default: `NerdDice.configuration.die_foreground_color`_\): Intended foreground color to apply to the dice in the `DiceSet`. Should be a valid CSS color but is not validated or enforced and doesn\'t currently have any real functionality associated with it. _**Applied** to Die objects by default with ability modify_
111
+ * `background_color` \(String, _default: `NerdDice.configuration.die_background_color`_\): Intended background color to apply to the dice in the `DiceSet`. Should be a valid CSS color but is not validated or enforced and doesn\'t currently have any real functionality associated with it. _**Applied** to Die objects by default with ability modify_
112
+
113
+ #### Properties of individual Die objects
114
+ When initialized from a `DiceSet` object most of the properties of the `Die` object are inherited from the `DiceSet` object. In addition, there is an `is_included_in_total` public attribute that can be set to indicate whether the value of that particular die should be included in the total for its parent `DiceSet`. This property always starts out as true when the `Die` is initialized, but can be set to false.
115
+
116
+ ```ruby
117
+ # six sided die
118
+ die = NerdDice::Die.new(6, randomization_technique: :randomized, damage_type: 'psychic', foreground_color: '#FFF', background_color: '#0FF')
119
+ die.is_included_in_total # => true
120
+ die.included_in_total? # => true
121
+ die.is_included_in_total = false
122
+ die.included_in_total? # => false
123
+
124
+ # value property
125
+ die.value # => Integer between 1 and number_of_sides
126
+ die.roll # => Integer. Rolls/rerolls the Die and sets value to the result of the roll. Returns the new value
127
+ ```
128
+ #### Iterating through dices in a DiceSet
129
+ The `DiceSet` class mixes in the `Enumerable` module and the `Die` object mixes in the `Comparable` module. This allows you to iterate over the dice in the collection. The `sort` method on the dice will return the die objects in ascending value from lowest to highest.
130
+
131
+ ```ruby
132
+ dice_set = NerdDice.roll_dice(6, 3) # => NerdDice::DiceSet
133
+ dice_set.dice => Array of Die objects
134
+ dice_set.length # => 3. (dice_set.dice.length)
135
+ dice_set[0] # => NerdDice::Die (first element of dice array)
136
+ # take actions on each die
137
+ dice_set.each do |die|
138
+ # print the current value
139
+ puts "Die value before reroll is #{die.value}"
140
+ # set the foreground_color of the die
141
+ die.foreground_color = ["gray", "#FF0000#", "#d9d9d9", "green"].shuffle.first
142
+ # reroll the die
143
+ die.roll
144
+ # print the new value
145
+ puts "Die value after reroll is #{die.value}"
146
+ # do other things
147
+ end
148
+ ```
149
+ #### Methods and method chaining on the DiceSet
150
+ Since the DiceSet is an object, you can call methods that operate on the result returned and allow for things like the 5e advantage/disadvantage mechanic, the ability to re-roll all of the dice in the `DiceSet`, or to mark them all as included in the total.
151
+
152
+ ```ruby
153
+ ##############################################
154
+ # highest/with_advantage and lowest/with_disadvantage methods
155
+ # assuming 4d6 with values of [1, 3, 4, 6]
156
+ ##############################################
157
+ dice_set = NerdDice.roll_dice(6, 4)
158
+ # the 6, 4, and 3 will have is_included_in_total true while the 1 has it false
159
+ dice_set.highest(3) # => Returns the existing DiceSet object with the changes made to dice inclusion
160
+ dice_set.with_advantage(3) # => Alias of highest method
161
+ # calling total after highest/with_advantage for this DiceSet
162
+ dice_set.total # => 13
163
+ # same DiceSet using lowest. The 1, 3, and 4 will have is_included_in_total true while the 6 has it false
164
+ dice_set.lowest(3) # => Returns the existing DiceSet object with the changes made to dice inclusion
165
+ dice_set.with_disadvantage(3) # => Alias of lowest method
166
+ # calling total after lowest/with_disadvantage for this DiceSet
167
+ dice_set.total # => 8
168
+ # you can chain these methods (assumes the same seed as the above examples)
169
+ NerdDice.roll_dice(6, 4).with_advantage(3).total # => 13
170
+ NerdDice.roll_dice(6, 4).lowest(3).total # => 8
171
+
172
+ # reroll_all! method
173
+ dice_set = NerdDice.roll_dice(6, 4)
174
+ dice_set.reroll_all! # rerolls each of the Die objects in the collection and re-includes them in the total
175
+
176
+ # include_all_dice! method
177
+ dice_set.include_all_dice! # resets is_included_in_total to true for all Die objects
178
+ ```
179
+
180
+ ### Rolling Ability Scores
181
+ You can call `roll_ability_scores` or `total_ability_scores` to get back an array of `DiceSet` objects or `Integer` objects, respectively. The `total_ability_scores` method calls `total` on each `DiceSet` and returns those numbers with one value per ability score. The `Configuration` object defaults to 6 ability scores using a methodology of __4d6 drop the lowest__ by default.
182
+
183
+ ```ruby
184
+ # return an array of DiceSet objects including info about the discarded dice
185
+ #
186
+ NerdDice.roll_ability_scores
187
+ #=> [DiceSet0, DiceSet1, ...]
188
+ # => DiceSet0 hash representation { total: 12, dice: [
189
+ # {value: 2, is_included_in_total: true},
190
+ # {value: 6, is_included_in_total: true},
191
+ # {value: 4, is_included_in_total: true},
192
+ # {value: 1, is_included_in_total: false}
193
+ # ]}
194
+ # if you want to get back DiceSet objects that you can interact with
195
+
196
+ # just return an array of totaled ability scores
197
+ NerdDice.total_ability_scores
198
+ #=> [12, 14, 13, 15, 10, 8]
199
+ ```
200
+
201
+ Both methods can be called without arguments to use the values specified in `NerdDice.configuration` or passed a set of options.
202
+ ```ruby
203
+
204
+ # total_dice and roll_dice take the same set of options
205
+ NerdDice.roll_ability_scores(
206
+ ability_score_array_size: 7,
207
+ ability_score_number_of_sides: 8,
208
+ ability_score_dice_rolled: 5,
209
+ ability_score_dice_kept: 4,
210
+ randomization_technique: :randomized,
211
+ foreground_color: "#FF0000",
212
+ background_color: "#FFFFFF"
213
+ )
214
+ # => [DiceSet0, DiceSet1, ...] with 7 ability scores that each roll 5d8 dropping the lowest
215
+ # or if called with total_ability_scores
216
+ # => [27, 17, 21, 17, 23, 13, 27]
217
+ ```
218
+ **Note:** If you try to call this method with `ability_score_dice_kept` greater than `ability_score_dice_rolled` an error will be raised.
219
+
63
220
  ### Manually setting or refreshing the random generator seed
64
221
  For randomization techniques other than `:securerandom` you can manually set or refresh the generator's seed by calling the `refresh_seed!` method. This is automatically called at the interval specified in `NerdDice.configuration.refresh_seed_interval` if it is not nil.
65
222
 
@@ -77,6 +234,23 @@ NerdDice.refresh_seed!(randomization_technique: :randomized,
77
234
  ```
78
235
  __NOTE:__ Ability to specify a seed it primarily provided for testing purposes. This makes all random numbers generated _transparently deterministic_ and should not be used if you want behavior approximating randomness.
79
236
 
237
+ ### Utility Methods
238
+
239
+ #### Harvesting Totals from DiceSets
240
+ The `harvest_totals` method take any collection of objects where each element responds to `total` and return an array of the results of the total method.
241
+ ```ruby
242
+ ability_score_array = NerdDice.roll_ability_scores
243
+ # => Array of 6 DiceSet objects
244
+
245
+ # Arguments:
246
+ # collection (Enumerable) a collection where each element responds to total
247
+ #
248
+ # Return (Array) => Data type of each element will be whatever is returned by total method
249
+ totals_array = NerdDice.harvest_totals(totals_array)
250
+ # => [15, 14, 13, 12, 10, 8]
251
+ # yes, it just happened to be the standard array by amazing coincidence
252
+ ```
253
+
80
254
  ## Development
81
255
 
82
256
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -90,4 +264,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/statel
90
264
 
91
265
  ## Unlicense, License, and Copyright
92
266
 
93
- The document is dual-licensed under the [MIT](https://opensource.org/licenses/MIT) license and the [UNLICENSE](https://unlicense.org/) \(with strong preference toward the UNLICENSE\)\. The content is released under [CC0](https://creativecommons.org/share-your-work/public-domain/cc0/) \(no rights reserved\). You are free to include it in its original form or modified with or without modification in your own project\.
267
+ The document is dual-licensed under the [MIT](https://opensource.org/licenses/MIT) license and the [UNLICENSE](https://unlicense.org/) \(with strong preference toward the UNLICENSE\)\. The content is released under [CC0](https://creativecommons.org/share-your-work/public-domain/cc0/) \(no rights reserved\). You are free to include it in its original form or modified with or without additional modification in your own project\.