nerd_dice 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c50b3a0288e78cec77247885129b370ba6d88f7a012cfefd8fceed049363487
4
- data.tar.gz: 456c3ff3d8816a567e4b80cbc49641811270483ce79cabf5fd8f4738bcd23722
3
+ metadata.gz: 8f64389429514a7d0c2a8410b2e27575e5c11b316b50cee41b37c58d8f8af953
4
+ data.tar.gz: 4d2365e3ce8139d4675695dfe47edf9ef5d52b9cc873beb5c7c314b8955aaa33
5
5
  SHA512:
6
- metadata.gz: fa26b32b8b95d4d926faa59071535b5958cc271ad190eea66a23a2fb25280c33c7d563962800a19f3f7c4947e130464450a76b8a59279b6fef9768278dbd61ec
7
- data.tar.gz: faae3546363de7437f9425f08666ba934bdb5bb4bd626e4dd3cf4c33c85147453f080c7a42cc3a9d594dc8fdb2f976aecc909261a8533f5c348fa25ee2414bdd
6
+ metadata.gz: d8bf0ea2c85e3aedf952d82d0f511463accedcad5122b14a7d6769a94100902887ca0e52cf85a6d8b69a75a6cd750858852ad71e34980e61624d39666bedff5b
7
+ data.tar.gz: ee2e8117b3071872a3d07353dabd4685c4a20e188591e80cbcb93609ba9f134ab22082ae01bee152c34c9cdd1a81a6a40aec2b1521d3e2a106d10f0c8fa313ae
checksums.yaml.gz.sig CHANGED
Binary file
@@ -14,7 +14,7 @@ jobs:
14
14
  runs-on: ubuntu-latest
15
15
  strategy:
16
16
  matrix:
17
- ruby-version: ['3.0', '3.1', '3.2']
17
+ ruby-version: ['2.7', '3.0']
18
18
 
19
19
  steps:
20
20
  - uses: actions/checkout@v2
@@ -39,7 +39,7 @@ jobs:
39
39
  - name: Set up Ruby
40
40
  uses: ruby/setup-ruby@v1
41
41
  with:
42
- ruby-version: '3.2'
42
+ ruby-version: '3.0'
43
43
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
44
44
  - name: Run rubocop
45
45
  run: bundle exec rubocop --parallel
@@ -51,7 +51,7 @@ jobs:
51
51
  - name: Set up Ruby
52
52
  uses: ruby/setup-ruby@v1
53
53
  with:
54
- ruby-version: '3.2'
54
+ ruby-version: '3.0'
55
55
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
56
56
  - name: Run benchmark script
57
57
  run: bin/nerd_dice_benchmark
data/.rubocop.yml CHANGED
@@ -1,11 +1,3 @@
1
- # RuboCop configuration file for NerdDice gem
2
- #
3
- # This is the RuboCop configuration for the gem. By default new cops are enabled
4
- # by default when the RuboCop gems are updated in the bundle. Before the would
5
- # show up as warnings until they were added to the configuration file. Now they
6
- # will be enabled by default, and a case-by-case descision can be made whether
7
- # to exclude new violations in the configuration explicitly or update the
8
- # codebase to the gem to conform to the new standard.
9
1
  require:
10
2
  - rubocop-performance
11
3
  - rubocop-rake
@@ -16,12 +8,14 @@ AllCops:
16
8
  # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
17
9
  # to ignore them, so only the ones explicitly set in this file are enabled.
18
10
  #DisabledByDefault: true
19
-
20
- # New cops are now enabled by default as of 2023-02-20
21
- NewCops: enable
22
11
  Exclude:
23
12
  - '**/templates/**/*'
24
13
  - '**/vendor/**/*'
14
+ - 'node_modules/**/*'
15
+
16
+ Performance:
17
+ Exclude:
18
+ - '**/test/**/*'
25
19
 
26
20
  # Prefer &&/|| over and/or.
27
21
  Style/AndOr:
@@ -117,6 +111,15 @@ Style/MethodDefParentheses:
117
111
  Style/FrozenStringLiteralComment:
118
112
  Enabled: true
119
113
  EnforcedStyle: always
114
+ Exclude:
115
+ - 'actionview/test/**/*.builder'
116
+ - 'actionview/test/**/*.ruby'
117
+ - 'actionpack/test/**/*.builder'
118
+ - 'actionpack/test/**/*.ruby'
119
+ - 'activestorage/db/migrate/**/*.rb'
120
+ - 'activestorage/db/update_migrate/**/*.rb'
121
+ - 'actionmailbox/db/migrate/**/*.rb'
122
+ - 'actiontext/db/migrate/**/*.rb'
120
123
 
121
124
  Style/RedundantFreeze:
122
125
  Enabled: true
@@ -188,6 +191,30 @@ Lint/UselessAssignment:
188
191
  Lint/DeprecatedClassMethods:
189
192
  Enabled: true
190
193
 
194
+ Lint/DuplicateBranch: # (new in 1.3)
195
+ Enabled: true
196
+
197
+ Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
198
+ Enabled: true
199
+
200
+ Lint/EmptyBlock: # (new in 1.1)
201
+ Enabled: true
202
+
203
+ Lint/EmptyClass: # (new in 1.3)
204
+ Enabled: true
205
+
206
+ Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
207
+ Enabled: true
208
+
209
+ Lint/ToEnumArguments: # (new in 1.1)
210
+ Enabled: true
211
+
212
+ Lint/UnexpectedBlockArity: # (new in 1.5)
213
+ Enabled: true
214
+
215
+ Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
216
+ Enabled: true
217
+
191
218
  Style/ParenthesesAroundCondition:
192
219
  Enabled: true
193
220
 
@@ -209,6 +236,27 @@ Style/ColonMethodCall:
209
236
  Style/TrivialAccessors:
210
237
  Enabled: true
211
238
 
239
+ Style/ArgumentsForwarding: # (new in 1.1)
240
+ Enabled: true
241
+
242
+ Style/CollectionCompact: # (new in 1.2)
243
+ Enabled: true
244
+
245
+ Style/DocumentDynamicEvalDefinition: # (new in 1.1)
246
+ Enabled: true
247
+
248
+ Style/NegatedIfElseCondition: # (new in 1.2)
249
+ Enabled: true
250
+
251
+ Style/NilLambda: # (new in 1.3)
252
+ Enabled: true
253
+
254
+ Style/RedundantArgument: # (new in 1.4)
255
+ Enabled: true
256
+
257
+ Style/SwapValues: # (new in 1.1)
258
+ Enabled: true
259
+
212
260
  Performance/FlatMap:
213
261
  Enabled: true
214
262
 
@@ -227,9 +275,147 @@ Performance/RegexpMatch:
227
275
  Performance/UnfreezeString:
228
276
  Enabled: true
229
277
 
278
+ Performance/AncestorsInclude: # (new in 1.7)
279
+ Enabled: true
280
+
281
+ Performance/BigDecimalWithNumericArgument: # (new in 1.7)
282
+ Enabled: true
283
+
284
+ Performance/BlockGivenWithExplicitBlock: # (new in 1.9)
285
+ Enabled: true
286
+
287
+ Performance/CollectionLiteralInLoop: # (new in 1.8)
288
+ Enabled: true
289
+
290
+ Performance/ConstantRegexp: # (new in 1.9)
291
+ Enabled: true
292
+
293
+ Performance/MethodObjectAsBlock: # (new in 1.9)
294
+ Enabled: true
295
+
296
+ Performance/RedundantSortBlock: # (new in 1.7)
297
+ Enabled: true
298
+
299
+ Performance/RedundantStringChars: # (new in 1.7)
300
+ Enabled: true
301
+
302
+ Performance/ReverseFirst: # (new in 1.7)
303
+ Enabled: true
304
+
305
+ Performance/SortReverse: # (new in 1.7)
306
+ Enabled: true
307
+
308
+ Performance/Squeeze: # (new in 1.7)
309
+ Enabled: true
310
+
311
+ Performance/StringInclude: # (new in 1.7)
312
+ Enabled: true
313
+
314
+ Performance/Sum: # (new in 1.8)
315
+ Enabled: true
316
+
317
+ Layout/SpaceBeforeBrackets: # (new in 1.7)
318
+ Enabled: true
319
+
320
+ Lint/AmbiguousAssignment: # (new in 1.7)
321
+ Enabled: true
322
+
323
+ Lint/DeprecatedConstants: # (new in 1.8)
324
+ Enabled: true
325
+
326
+ Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
327
+ Enabled: true
328
+
329
+ Lint/RedundantDirGlobSort: # (new in 1.8)
330
+ Enabled: true
331
+
332
+ Style/EndlessMethod: # (new in 1.8)
333
+ Enabled: true
334
+
335
+ Style/HashExcept: # (new in 1.7)
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
+
230
396
  RSpec/MessageSpies:
231
397
  EnforcedStyle: receive
232
398
 
233
- # Disable inclusive language cop. None of RuboCop's business
234
- Naming/InclusiveLanguage:
235
- Enabled: false
399
+ Lint/AmbiguousRange: # new in 1.19
400
+ Enabled: true
401
+ Style/RedundantSelfAssignmentBranch: # new in 1.19
402
+ Enabled: true
403
+
404
+ Lint/AmbiguousOperatorPrecedence: # new in 1.21
405
+ Enabled: true
406
+ Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
407
+ Enabled: true
408
+ Lint/RequireRelativeSelfPath: # new in 1.22
409
+ Enabled: true
410
+ Security/IoMethods: # new in 1.22
411
+ Enabled: true
412
+ Style/NumberedParameters: # new in 1.22
413
+ Enabled: true
414
+ Style/NumberedParametersLimit: # new in 1.22
415
+ Enabled: true
416
+ Style/SelectByRegexp: # new in 1.22
417
+ Enabled: true
418
+ RSpec/ExcessiveDocstringSpacing: # new in 2.5
419
+ Enabled: true
420
+ RSpec/SubjectDeclaration: # new in 2.5
421
+ Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,8 +1,82 @@
1
1
  # Nerd Dice Changelog
2
2
 
3
- <img src="https://i.kym-cdn.com/photos/images/newsfeed/000/186/610/thankyou.png?1318726198" alt="Our CHANGELOG is in another castle" />
3
+ ## master \(unreleased\)
4
+ ### Added
5
+ ### Changed
6
+ ### Fixed
4
7
 
5
- ## Legacy Branch: See master
6
- This is a legacy maintenance branch.
8
+ ## 0.4.0 \(2021-10-23\)
9
+ ### Added
10
+ * Add `NerdDice::ConvenienceMethods` method_missing mixin module that allows for dynamic invocation of patterns in the method name that get converted into calls to `NerdDice.roll_dice` or `NerdDice.total_dice` along with allowing the advantage/disadvantage mechanic or bonuses to be parsed from the method name. Full documentation of the module can be found in the [Convenience Methods Mixin](README.md#convenience-methods-mixin) section of the README.
11
+ * Add exensive specs to support the ConvenienceMethods module
12
+ ### Changed
13
+ * Replace `Benchmark.bmbm` with `Benchmark.bm` in the nerd_dice_benchmark
14
+ * Add convenience_methods to nerd_dice_benchmark
15
+ * Extend `NerdDice::ConvenienceMethods` into top-level module as class methods
16
+ ### Fixed
17
+ * Fix typos and horizontal scrolling in README
18
+ * Fix CodeClimate Code Smell on harvest_totals
7
19
 
8
- The [authoritative version of the CHANGELOG](https://github.com/statelesscode/nerd_dice/blob/master/CHANGELOG.md) is found on the master branch. All other release and maintenance branches are updated to point to master after being created.
20
+ ## 0.3.0 \(2021-09-11\)
21
+ ### Added
22
+ * Add new options to `NerdDice::Configuration`
23
+ - `ability_score_number_of_sides`
24
+ - `ability_score_dice_rolled`
25
+ - `ability_score_dice_kept`
26
+ * Add `NerdDice.harvest_totals` method that takes in a collection and returns the results of calling `total` on each element
27
+ * Add `NerdDice.roll_ability_scores` convenience method that returns an array of `DiceSet` objects based on options and/or configuration
28
+ * Add `NerdDice.total_ability_scores` convenience method that returns an array of integers based on options and/or configuration
29
+ * Add `NerdDice::Die` class that represents a single die object and mixes in the `Comparable` module
30
+ * Add `NerdDice::DiceSet` class that represents a collection of `Die` objects and mixes in the `Enumerable` module
31
+ * Add `NerdDice::SetsRandomizationTechnique` mixin module and include in the `DiceSet` and `Die` classes
32
+ * Add `die_background_color` and `die_foreground_color` to `Configuration` class with defaults defined as constants
33
+ * 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
34
+ * Add `coveralls_reborn` to RSpec and GitHub actions
35
+ * Add build badge to README
36
+ * Add Code Climate maintainability integration and badge to README
37
+ * Add `nerd_dice_benchmark` script to bin directory
38
+ * Add GitHub Action CI build
39
+ - Run RSpec test suite, fail if specs fail, report coverage via Coveralls
40
+ - Run RuboCop and fail if violations
41
+ - Run benchmark suite and fail if outside of allowed ratios
42
+ ### Changed
43
+ * Update RuboCop version and configuration
44
+ * Break up the NerdDice source code file into several smaller files that are included by the module
45
+ * Enforce that `NerdDice.configuration.ability_score_array_size` must be a positive duck-type integer
46
+ ### Fixed
47
+
48
+ ## 0.2.0 \(2021-01-28\)
49
+ ### Added
50
+ * Add ability to configure with `NerdDice.configure` block or `NerdDice.configuration`
51
+ - Configure `randomization_technique` as `:random_rand`, `:securerandom`, `:random_object`, or `randomized`
52
+ - Configure `refresh_seed_interval` to allow a periodic refresh of the seed
53
+ * Add `randomization_technique` option to `NerdDice.total_dice` method keyword arguments
54
+ * Add a lower-level `execute_die_roll` method that allows you to roll a single die with a generator specified
55
+ * Add ability to manually refresh or specify seed with `:refresh_seed!` method
56
+ ### Changed
57
+ * Change `opts = {}` final argument to use keyword args `**opts` in the `NerdDice.total_dice` method. Now the method can be called as follows:
58
+ ```ruby
59
+ # old
60
+ NerdDice.total_dice(20, 1, {bonus: 5})
61
+ NerdDice.total_dice(6, 3, {bonus: 1})
62
+
63
+ # new
64
+ NerdDice.total_dice(20, bonus: 5)
65
+ NerdDice.total_dice(6, 3, bonus: 1)
66
+ ```
67
+ * Call `:to_i` on bonus instead of using `:is_a?` and raise ArgumentError in the `NerdDice.total_dice` method if it doesn't respond to `:to_i`
68
+ * Added `securerandom` as an explicit dependency due to Ruby 3.x change to bundled gem
69
+ * `total_dice` no longer calls unqualified `.rand` which improves performance on all generators except for `:securerandom`
70
+ ### Fixed
71
+
72
+ ## 0.1.1 \(2020-12-12\)
73
+ ### Added
74
+ ### Changed
75
+ ### Fixed
76
+ * Fix broken link to CHANGELOG in gemspec
77
+ * Fix rubocop offenses from 0.1.0 and refactor specs
78
+
79
+ ## 0.1.0 \(2020-12-07\)
80
+
81
+ ### Added
82
+ * Add NerdDice.total_dice class method with the ability to roll multiple polyhedral dice and add a bonus
data/Gemfile CHANGED
@@ -6,4 +6,4 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
- gem "rspec", "~> 3.12"
9
+ gem "rspec", "~> 3.10"
data/Gemfile.lock CHANGED
@@ -1,92 +1,87 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nerd_dice (0.3.1)
5
- securerandom (~> 0.2, >= 0.2.2)
4
+ nerd_dice (0.4.0)
5
+ securerandom (~> 0.1, >= 0.1.1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  ast (2.4.2)
11
- coveralls_reborn (0.27.0)
12
- simplecov (~> 0.22.0)
13
- term-ansicolor (~> 1.7)
14
- thor (~> 1.2)
15
- tins (~> 1.32)
16
- diff-lcs (1.5.0)
11
+ coveralls_reborn (0.23.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)
16
+ diff-lcs (1.4.4)
17
17
  docile (1.4.0)
18
- json (2.6.3)
19
- parallel (1.22.1)
20
- parser (3.2.1.0)
18
+ parallel (1.21.0)
19
+ parser (3.0.2.0)
21
20
  ast (~> 2.4.1)
22
- rainbow (3.1.1)
21
+ rainbow (3.0.0)
23
22
  rake (13.0.6)
24
- regexp_parser (2.7.0)
23
+ regexp_parser (2.1.1)
25
24
  rexml (3.2.5)
26
- rspec (3.12.0)
27
- rspec-core (~> 3.12.0)
28
- rspec-expectations (~> 3.12.0)
29
- rspec-mocks (~> 3.12.0)
30
- rspec-core (3.12.1)
31
- rspec-support (~> 3.12.0)
32
- rspec-expectations (3.12.2)
25
+ rspec (3.10.0)
26
+ rspec-core (~> 3.10.0)
27
+ rspec-expectations (~> 3.10.0)
28
+ rspec-mocks (~> 3.10.0)
29
+ rspec-core (3.10.1)
30
+ rspec-support (~> 3.10.0)
31
+ rspec-expectations (3.10.1)
33
32
  diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.12.0)
35
- rspec-mocks (3.12.3)
33
+ rspec-support (~> 3.10.0)
34
+ rspec-mocks (3.10.2)
36
35
  diff-lcs (>= 1.2.0, < 2.0)
37
- rspec-support (~> 3.12.0)
38
- rspec-support (3.12.0)
39
- rubocop (1.46.0)
40
- json (~> 2.3)
36
+ rspec-support (~> 3.10.0)
37
+ rspec-support (3.10.2)
38
+ rubocop (1.22.2)
41
39
  parallel (~> 1.10)
42
- parser (>= 3.2.0.0)
40
+ parser (>= 3.0.0.0)
43
41
  rainbow (>= 2.2.2, < 4.0)
44
42
  regexp_parser (>= 1.8, < 3.0)
45
- rexml (>= 3.2.5, < 4.0)
46
- rubocop-ast (>= 1.26.0, < 2.0)
43
+ rexml
44
+ rubocop-ast (>= 1.12.0, < 2.0)
47
45
  ruby-progressbar (~> 1.7)
48
- unicode-display_width (>= 2.4.0, < 3.0)
49
- rubocop-ast (1.26.0)
50
- parser (>= 3.2.1.0)
51
- rubocop-capybara (2.17.1)
52
- rubocop (~> 1.41)
53
- rubocop-performance (1.16.0)
46
+ unicode-display_width (>= 1.4.0, < 3.0)
47
+ rubocop-ast (1.12.0)
48
+ parser (>= 3.0.1.1)
49
+ rubocop-performance (1.11.5)
54
50
  rubocop (>= 1.7.0, < 2.0)
55
51
  rubocop-ast (>= 0.4.0)
56
52
  rubocop-rake (0.6.0)
57
53
  rubocop (~> 1.0)
58
- rubocop-rspec (2.18.1)
59
- rubocop (~> 1.33)
60
- rubocop-capybara (~> 2.17)
54
+ rubocop-rspec (2.5.0)
55
+ rubocop (~> 1.19)
61
56
  ruby-progressbar (1.11.0)
62
- securerandom (0.2.2)
63
- simplecov (0.22.0)
57
+ securerandom (0.1.1)
58
+ simplecov (0.21.2)
64
59
  docile (~> 1.1)
65
60
  simplecov-html (~> 0.11)
66
61
  simplecov_json_formatter (~> 0.1)
67
62
  simplecov-html (0.12.3)
68
63
  simplecov-lcov (0.8.0)
69
- simplecov_json_formatter (0.1.4)
64
+ simplecov_json_formatter (0.1.3)
70
65
  sync (0.5.0)
71
66
  term-ansicolor (1.7.1)
72
67
  tins (~> 1.0)
73
- thor (1.2.1)
74
- tins (1.32.1)
68
+ thor (1.1.0)
69
+ tins (1.29.1)
75
70
  sync
76
- unicode-display_width (2.4.2)
71
+ unicode-display_width (2.1.0)
77
72
 
78
73
  PLATFORMS
79
74
  ruby
80
75
 
81
76
  DEPENDENCIES
82
- coveralls_reborn (~> 0.27.0)
77
+ coveralls_reborn (~> 0.23.0)
83
78
  nerd_dice!
84
79
  rake (~> 13.0)
85
- rspec (~> 3.12)
86
- rubocop (~> 1.46, >= 1.46.0)
87
- rubocop-performance (~> 1.16, >= 1.16.0)
80
+ rspec (~> 3.10)
81
+ rubocop (~> 1.22, >= 1.22.2)
82
+ rubocop-performance (~> 1.11, >= 1.11.5)
88
83
  rubocop-rake (~> 0.6, >= 0.6.0)
89
- rubocop-rspec (~> 2.18, >= 2.18.1)
84
+ rubocop-rspec (~> 2.5, >= 2.5.0)
90
85
  simplecov-lcov (~> 0.8.0)
91
86
 
92
87
  BUNDLED WITH
data/README.md CHANGED
@@ -24,6 +24,15 @@ Or install it yourself as:
24
24
  $ gem install nerd_dice
25
25
 
26
26
  ## Usage
27
+ After the gem is installed, you can require it as you would any other gem.
28
+
29
+ ```ruby
30
+ require 'nerd_dice'
31
+ ```
32
+
33
+ ### Module methods or a dynamic method_missing DSL
34
+ There are two main patterns for using NerdDice in your project. You can invoke the module-level methods like `NerdDice.total_dice` or you can include the `NerdDice::ConvenienceMethods` module to your class \(or IRB \). Once mixed in, you can dynamically invoke methods like `roll_d20_with_advantage` or `total_3d8_plus5`. See the [Convenience Methods Mixin](#convenience-methods-mixin) section for usage details.
35
+
27
36
  ### Configuration
28
37
  You can customize the behavior of NerdDice via a configuration block as below or by assigning an individual property via the ```NerdDice.configuration.property = value``` syntax \(where ```property``` is the config property and ```value``` is the value you want to assign\)\. The available configuration options as well as their defaults, if applicable, are listed in the example configuration block below:
29
38
 
@@ -268,6 +277,126 @@ totals_array = NerdDice.harvest_totals(totals_array)
268
277
  # => [15, 14, 13, 12, 10, 8]
269
278
  # yes, it just happened to be the standard array by amazing coincidence
270
279
  ```
280
+ <a name="convenience-methods-mixin"></a>
281
+ ### Convenience Methods Mixin
282
+ NerdDice provides an optional mixin `NerdDice::ConvenienceMethods` that uses Ruby\'s `method_missing` metaprogramming pattern to allow you to roll any number of dice with bonuses and/or the advantage/disadvantage mechanic by dynamically responding to methods that you type that match the `roll_` or `total_` pattern.
283
+
284
+ #### Considerations for ConvenienceMethods
285
+ Before mixing in this method with a class, be aware of other `method_missing` gems that you are also mixing into your project and be sure to write robust tests. We have sought to use `method_missing` in a responsible manner that delegates back to the default implementation using `super` if the method does not match the `ConvenienceMethods` pattern, but there is no guarantee that other gems included in your project are doing the same. If you run into problems with the `ConvenienceMethods` module interacting with other `method_missing` gems, everything that the `ConvenienceMethods` module does can be replicated using the module\-level methods described above or by calling the convenience method on `NerdDice`.
286
+
287
+ Once a particular method has been called, it will define that method so that the next time it will invoke the method directly instead of traversing up the call stack for `method_missing`, which improves performance. The method will remain defined for the duration of the Ruby interpreter process.
288
+
289
+ #### Calling ConvenienceMethods as NerdDice class methods
290
+ NerdDice extends the `ConvenienceMethods` module into the top-level module as class methods, so you can call the methods on the NerdDice module without needing to worry about the implications of extending it into your own class.
291
+ ```ruby
292
+ require 'nerd_dice'
293
+ # works with all the examples and patterns below
294
+ NerdDice.roll_3d6_lowest2_minus1
295
+ NerdDice.total_d20_with_advantage_p6
296
+ ```
297
+
298
+ #### Mixing in the ConvenienceMethods module
299
+ To mix the NerdDice DSL into your class, make sure the gem is required if not already and then use `include NerdDice::ConvenienceMethods` as shown below:
300
+ ```ruby
301
+ # example of a class that mixes in NerdDice::ConvenienceMethods
302
+ require 'nerd_dice'
303
+ class Monster
304
+ include NerdDice::ConvenienceMethods
305
+
306
+ # hard-coding probably not the best solution
307
+ # but gives you an idea how to mix in to a simple class
308
+ def hits_the_monster
309
+ # using the ConvenienceMethods version
310
+ total_d20_plus5 >= @armor_class ? "hit" : "miss"
311
+ end
312
+
313
+ def initialize(armor_class=16)
314
+ @armor_class = armor_class
315
+ end
316
+ end
317
+ ```
318
+ To mix in the module as class methods, you can use `extend NerdDice::ConvenienceMethods`
319
+ ```ruby
320
+ # example of a class that mixes in NerdDice::ConvenienceMethods
321
+ require 'nerd_dice'
322
+ class OtherClass
323
+ extend NerdDice::ConvenienceMethods
324
+ end
325
+ OtherClass.roll_3d6_lowest2_minus1 # returns NerdDice::DiceSet
326
+ ```
327
+
328
+ #### ConvenienceMethods usage examples
329
+ Any invocation of `NerdDice.roll_dice` and `NerdDice.total_dice` can be duplicated using the `NerdDice::ConvenienceMethods` mixin. Here are some examples of what you can do with the return types and equivalent methods in the comments:
330
+
331
+ * `roll_dNN` and `total_dNN` roll one die
332
+ ```ruby
333
+ roll_d20 # => DiceSet: NerdDice.roll_dice(20)
334
+ roll_d8 # => DiceSet: NerdDice.roll_dice(8)
335
+ roll_d1000 # => DiceSet: NerdDice.roll_dice(1000)
336
+ total_d20 # => Integer NerdDice.total_dice(20)
337
+ total_d8 # => Integer NerdDice.total_dice(8)
338
+ total_d1000 # => Integer NerdDice.total_dice(1000)
339
+ ```
340
+ * `roll_NNdNN` and `total_NNdNN` roll specified quantity of dice
341
+ ```ruby
342
+ roll_2d20 # => DiceSet: NerdDice.roll_dice(20, 2)
343
+ roll_3d8 # => DiceSet: NerdDice.roll_dice(8, 3)
344
+ roll_22d1000 # => DiceSet: NerdDice.roll_dice(1000, 22)
345
+ total_2d20 # => Integer NerdDice.total_dice(20, 2)
346
+ total_3d8 # => Integer NerdDice.total_dice(8, 3)
347
+ total_22d1000 # => Integer NerdDice.total_dice(1000, 22)
348
+ ```
349
+ * Keyword arguments are passed on to `roll_dice`/`total_dice` method
350
+ ```ruby
351
+ roll_2d20 foreground_color: "blue" # => DiceSet: NerdDice.roll_dice(20, 2, foreground_color: "blue")
352
+
353
+ total_d12 randomization_technique: :randomized
354
+ # => Integer NerdDice.total_dice(12, randomization_technique: :randomized)
355
+ total_22d1000 randomization_technique: :random_rand
356
+ # => Integer NerdDice.total_dice(1000, 22, randomization_technique: :random_rand)
357
+
358
+ roll_4d6_with_advantage3 background_color: 'blue'
359
+ # => DiceSet: NerdDice.roll_dice(4, 3, background_color: 'blue').highest(3)
360
+ total_4d6_with_advantage3 randomization_technique: :random_rand
361
+ # => Integer: NerdDice.roll_dice(4, 3, randomization_technique: :random_rand).highest(3).total
362
+ ```
363
+ * Positive and negative bonuses can be used with `plus` (alias `p`) or `minus` (alias `m`)
364
+ ```ruby
365
+ roll_d20_plus6 # => DiceSet: NerdDice.roll_dice(20, bonus: 6)
366
+ total_3d8_p2 # => Integer: NerdDice.total_dice(8, 3, bonus: 2)
367
+ total_d20_minus5 # => Integer: NerdDice.total_dice(20, bonus: -6)
368
+ roll_3d8_m3 # => DiceSet: NerdDice.roll_dice(8, 3, bonus: -3)
369
+ ```
370
+ * `_with_advantageN` or `highestN` roll with advantage
371
+ * `_with_disadvantageN` or `lowestN` roll with disadvantage
372
+ * Calling `roll_dNN_with_advantage` \(and variants\) rolls 2 dice and keeps one
373
+ ```ruby
374
+ # equivalent
375
+ roll_3d8_with_advantage1
376
+ roll_3d8_highest1
377
+ # => DiceSet: NerdDice.roll_dice(8, 3).with_advantage(1)
378
+
379
+ # calls roll_dice and total to return an integer
380
+ total_3d8_with_advantage1
381
+ total_3d8_highest1
382
+ # => Integer: NerdDice.roll_dice(8, 3).with_advantage(1).total
383
+
384
+ # rolls two dice in this case
385
+ # equal to roll_2d20_with_advantage but more natural
386
+ roll_d20_with_advantage # => DiceSet: NerdDice.roll_dice(20, 2).with_advantage(1)
387
+ # equal to total_2d20_with_advantage but more natural
388
+ total_d20_with_advantage # => Integer: NerdDice.roll_dice(20, 2).with_advantage(1).total
389
+ ```
390
+ #### ConvenienceMethods error handling
391
+ * If you try to call with a plus and a minus, an Exception is raised
392
+ * If you call with a bonus and a keyword argument and they don't match, an Exception is raised
393
+ * Any combination not expressly allowed or matched will call `super` on `method_missing`
394
+ ```ruby
395
+ roll_3d8_plus3_m2 # will raise NameError using super method_missing
396
+ roll_3d8_plus3 bonus: 1 # will raise NerdDice::Error with message about "Bonus integrity failure"
397
+ roll_d20_with_advantage_lowest # will raise NameError using super method_missing
398
+ total_4d6_lowest3_highest2 # will raise NameError using super method_missing
399
+ ```
271
400
 
272
401
  ## Development
273
402
 
@@ -277,7 +406,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
277
406
 
278
407
  ## Contributing
279
408
 
280
- Bug reports and pull requests are welcome on GitHub at https://github.com/statelesscode/nerd_dice/issues. We welcome and encourage your participation in this open-source project. We welcome those of all backgrounds and abilities, but we refuse to adopt the Contributor Covenant for reasons outlined in [BURN_THE_CONTRIBUTOR_COVENANT_WITH_FIRE.md](BURN_THE_CONTRIBUTOR_COVENANT_WITH_FIRE.md)
409
+ Bug reports and pull requests are welcome on GitHub at https://github.com/statelesscode/nerd_dice/issues. We welcome and encourage your participation in this open-source project. We welcome those of all backgrounds and abilities, but we refuse to adopt the Contributor Covenant for reasons outlined in [BURN_THE_CONTRIBUTOR_COVENANT_WITH_FIRE.md](https://github.com/statelesscode/nerd_dice/blob/master/BURN_THE_CONTRIBUTOR_COVENANT_WITH_FIRE.md)
410
+
281
411
 
282
412
  ## Unlicense, License, and Copyright
283
413