para_dice 0.6.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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.pullreview.yml +77 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +7 -0
  6. data/Gemfile +9 -0
  7. data/Guardfile +27 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +51 -0
  10. data/Rakefile +10 -0
  11. data/VERSION +1 -0
  12. data/bin/dice_tests.rb +27 -0
  13. data/data/face_types.yml +27 -0
  14. data/data/gotham_dice.yml +55 -0
  15. data/data/specs/not_really_yaml.yml +22 -0
  16. data/data/specs/simple_array.yml +7 -0
  17. data/data/specs/simple_hash.yml +4 -0
  18. data/data/star_wars_dice.yml +87 -0
  19. data/lib/gotham_dice.rb +44 -0
  20. data/lib/para_dice/bag.rb +44 -0
  21. data/lib/para_dice/cup.rb +19 -0
  22. data/lib/para_dice/die.rb +64 -0
  23. data/lib/para_dice/faces/arrayed.rb +34 -0
  24. data/lib/para_dice/faces/ranged.rb +38 -0
  25. data/lib/para_dice/numbered_die.rb +13 -0
  26. data/lib/para_dice/poly_bag.rb +31 -0
  27. data/lib/para_dice/results/and_keep.rb +34 -0
  28. data/lib/para_dice/results/array.rb +13 -0
  29. data/lib/para_dice/results/cancel_opposing.rb +46 -0
  30. data/lib/para_dice/results/hash.rb +14 -0
  31. data/lib/para_dice/results/number.rb +39 -0
  32. data/lib/para_dice/results/split_faces.rb +23 -0
  33. data/lib/para_dice/string_die.rb +15 -0
  34. data/lib/para_dice/utility.rb +54 -0
  35. data/lib/para_dice.rb +9 -0
  36. data/lib/star_wars_dice.rb +41 -0
  37. data/para_dice.gemspec +34 -0
  38. data/spec/gotham_dice_spec.rb +19 -0
  39. data/spec/para_dice/bag_spec.rb +53 -0
  40. data/spec/para_dice/cup_spec.rb +73 -0
  41. data/spec/para_dice/die_spec.rb +21 -0
  42. data/spec/para_dice/faces/ranged_spec.rb +42 -0
  43. data/spec/para_dice/faces/string_arrayed_spec.rb +41 -0
  44. data/spec/para_dice/numbered_die_spec.rb +19 -0
  45. data/spec/para_dice/poly_bag_spec.rb +9 -0
  46. data/spec/para_dice/results/and_keep_spec.rb +30 -0
  47. data/spec/para_dice/results/array_spec.rb +8 -0
  48. data/spec/para_dice/results/cancel_opposing_spec.rb +18 -0
  49. data/spec/para_dice/results/hash_spec.rb +6 -0
  50. data/spec/para_dice/results/number_spec.rb +44 -0
  51. data/spec/para_dice/results/parse_faces_spec.rb +9 -0
  52. data/spec/para_dice/string_die_spec.rb +14 -0
  53. data/spec/para_dice/utility_spec.rb +82 -0
  54. data/spec/para_dice_spec.rb +10 -0
  55. data/spec/spec_helper.rb +82 -0
  56. data/spec/star_wars_dice_spec.rb +19 -0
  57. metadata +274 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e84f99eb4b926c858463cb3e1f5d38795aa83a42
4
+ data.tar.gz: 397c26eec927b3da43e367c705483c986f614e46
5
+ SHA512:
6
+ metadata.gz: f442d38d1210ab0b9f87db37def9f475e620d944c5eb7bbce849487ac4e1d2468d34a097a93ee7a9f8610faaeed30eb1429a5ccda648619aabd9ff0b87d7280a
7
+ data.tar.gz: 16c1d751f0ddf24bd9cedbd555fc450917ed4c5daeb7c60c33adcf14a6b74e76c16cd737b60af3dc93824f31bdaebcc9df50bab57ef34d7d708986ae8abce6c2
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ /.idea
data/.pullreview.yml ADDED
@@ -0,0 +1,77 @@
1
+ ---
2
+ rules:
3
+ ignore:
4
+ # - add_db_index
5
+ # - add_underscores_to_large_numeric
6
+ # - always_else_in_case
7
+ # - ambiguous_first_argument
8
+ # - assigned_but_unused_variable
9
+ # - assignment_in_conditional
10
+ - avoid_copy_paste
11
+ # - avoid_empty_rescue_block
12
+ # - avoid_global_variable
13
+ # - avoid_similar_code
14
+ # - avoid_singleton_variable
15
+ # - avoid_using_curly_braces_for_multi-line_blocks
16
+ # - check_return_value_of_save
17
+ # - don_t_use_parentheses_around_the_condition
18
+ # - extra_blank_line_detected
19
+ # - extra_blank_line_detected_at_body_beginning
20
+ # - extra_blank_line_detected_at_body_end
21
+ # - favor_if_unless_for_single_line
22
+ # - improve_coverage_of_class
23
+ # - improve_coverage_of_method
24
+ # - improve_coverage_of_project
25
+ # - indent_when_as_deep_as_case
26
+ # - missing_class_documentation
27
+ # - missing_method_documentation
28
+ # - naming_convention_for_class
29
+ # - naming_convention_for_method
30
+ # - naming_convention_for_module
31
+ # - no_for_loop
32
+ # - no_instance_variable_in_partial
33
+ # - no_params_in_view
34
+ # - no_session_in_view
35
+ # - omit_parentheses_when_no_args
36
+ # - prefer_accolades_over_doend_for_single-line_blocks
37
+ # - prefer_map_over_collect
38
+ # - prefer_reduce_over_inject
39
+ # - prefer_ruby_19_new_hash_syntax
40
+ # - prefer_ruby_19_new_lambda_syntax
41
+ # - prefer_single_quoted_strings
42
+ # - reduce_number_of_params
43
+ # - refactor_complex_class
44
+ # - refactor_complex_method
45
+ # - remove_trailing_whitespace
46
+ # - restrict_auto_generated_routes
47
+ # - shadowing_outer_local_variable
48
+ # - simplify_call_to_render
49
+ # - simplify_call_to_render_partial
50
+ # - space_between_curly_brace_and_pipe_missing
51
+ # - space_inside_closing_curly_brace_missing
52
+ # - space_inside_opening_curly_brace_missing
53
+ # - space_inside_parentheses_detected
54
+ # - space_inside_square_brackets_detected
55
+ # - space_missing_after_colon
56
+ # - space_missing_after_comma
57
+ # - space_missing_after_hash_sign
58
+ # - space_missing_after_semicolon
59
+ # - space_missing_inside_closing_curly_brace
60
+ # - space_missing_inside_opening_curly_brace
61
+ # - space_missing_to_left_of_parentheses
62
+ # - star_interpreted_as_argument_prefix
63
+ # - surrounding_space_missing_for_accolade
64
+ # - surrounding_space_missing_for_addition
65
+ # - surrounding_space_missing_for_arrow
66
+ # - surrounding_space_missing_for_assign
67
+ # - surrounding_space_missing_for_divide
68
+ # - surrounding_space_missing_for_equality
69
+ # - surrounding_space_missing_for_greater_than
70
+ # - surrounding_space_missing_for_incr
71
+ # - surrounding_space_missing_for_minus
72
+ # - surrounding_space_missing_for_multiplication
73
+ # - surrounding_space_missing_for_not_equal
74
+ # - surrounding_space_missing_for_t_square
75
+ - use_a_logger
76
+ # - use_def_with_parentheses_when_there_are_arguments
77
+ # - uses_spaces_instead_of_tabs
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem uninstall bundler
4
+ - gem install bundler --version '1.7.6'
5
+ rvm:
6
+ - 2.1
7
+ script: bundle exec rake
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+ group :test do
3
+ gem "codeclimate-test-reporter", '~>0.4.1', require: nil
4
+ gem 'pullreview-coverage', require: false
5
+ end
6
+
7
+ gem 'tty', '~>0.1.0', group: :development
8
+ # Specify your gem's dependencies in para_dixe.gemspec
9
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,27 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ # Note: The cmd option is now required due to the increasing number of ways
5
+ # rspec may be run, below are examples of the most common uses.
6
+ # * bundler: 'bundle exec rspec'
7
+ # * bundler binstubs: 'bin/rspec'
8
+ # * spring: 'bin/rsspec' (This will use spring if running and you have
9
+ # installed the spring binstubs per the docs)
10
+ # * zeus: 'zeus rspec' (requires the server to be started separetly)
11
+ # * 'just' rspec: 'rspec'
12
+ guard :rspec,
13
+ all_after_pass: true,
14
+ all_on_start: true,
15
+ run_all: { cmd: 'bundle exec rspec --color'},
16
+ cmd: 'bundle exec rspec --format Fuubar --color' do
17
+ watch(%r{^spec/.+_spec\.rb$})
18
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
19
+ watch('spec/spec_helper.rb') { "spec" }
20
+ watch(%r{^data/(.+)\.yml}) {"spec"}
21
+ end
22
+
23
+
24
+ guard :bundler do
25
+ watch('Gemfile')
26
+ watch(/^.+\.gemspec/)
27
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Scott M Parrish
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # ParaDice
2
+
3
+ [![Build Status](https://travis-ci.org/anithri/para_dice.svg?branch=master)](https://travis-ci.org/anithri/para_dice)
4
+ [![Code Climate](https://codeclimate.com/github/anithri/para_dice/badges/gpa.svg)](https://codeclimate.com/github/anithri/para_dice)
5
+ [![Test Coverage](https://codeclimate.com/github/anithri/para_dice/badges/coverage.svg)](https://codeclimate.com/github/anithri/para_dice)
6
+ [![Dependency Status](https://gemnasium.com/anithri/para_dice.svg)](https://gemnasium.com/anithri/para_dice)
7
+ [![PullReview stats](https://www.pullreview.com/github/anithri/para_dice/badges/master.svg?)](https://www.pullreview.com/github/anithri/para_dice/reviews/master)
8
+
9
+ An extensible dice gem.
10
+
11
+ ## Introduction
12
+ ParaDice is a ruby library that provides customizable dice and results of rolling one or more.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'para_dice'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install para_dice
29
+
30
+
31
+ ## Usage
32
+
33
+ ```ruby
34
+ require para_dice
35
+
36
+ # Use a set of polyhedral dice
37
+ bag = ParaDice::GenerateDiceBag.poly
38
+ # Get a dice cup to roll 3 d6 in this case
39
+ cup = bag.take_cup([:d6, :d6, :d6])
40
+ cup.roll! # [4, 2, 4]
41
+ result = cup.roll # ParaDice::Results::Sum object
42
+ result.raw # [4,2,
43
+
44
+ ```
45
+ ## Contributing
46
+
47
+ 1. Fork it ( https://github.com/anithri/para_dice/fork )
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/version_task'
3
+ require 'rspec/core/rake_task'
4
+
5
+ Rake::VersionTask.new
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task :default => :spec
10
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.6.0
data/bin/dice_tests.rb ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gotham_dice'
3
+ require 'tty'
4
+
5
+ # number of times to test
6
+ ITERATIONS = 10_000
7
+
8
+ # all dice faces for gotham_dice
9
+ HEADERS = ['pow', 'move', 'clue', 'totals']
10
+
11
+ bag = GothamDice.get
12
+ cup = bag.get_cup('combat', 'combat', 'detect', 'detect', 'move', 'move')
13
+
14
+ table = TTY::Table.new(header: HEADERS)
15
+ # totals = Hash.new{|h,k| h[k] = []}
16
+ totals = Hash.new(0)
17
+
18
+ ITERATIONS.times do
19
+ r = cup.roll
20
+ r['totals'] = r.values.reduce(:+)
21
+ HEADERS.each do |h|
22
+ totals[h] += r[h]
23
+ end
24
+ end
25
+ puts totals.inspect
26
+ table << totals.values.map { |e| e * 1.0 / ITERATIONS }
27
+ puts table.render width: 120, resize: true
@@ -0,0 +1,27 @@
1
+ ---
2
+ #name are unique
3
+ #redefining the same name will result in original being lost.
4
+ :move:
5
+ :name: move
6
+ :val: move
7
+ :pow:
8
+ :name: pow
9
+ :val: pow
10
+ :clue:
11
+ :name: clue
12
+ :val: clue
13
+ :blank:
14
+ :name: blank
15
+ :val: blank
16
+ :batman:
17
+ :name: batman
18
+ :val: batman
19
+ :times2:
20
+ :name: Plus 1
21
+ :val: :plus_1
22
+ :plus3:
23
+ :name: Plus 3
24
+ :val: :plus_3
25
+ :joker:
26
+ :name: joker
27
+ :val: joker
@@ -0,0 +1,55 @@
1
+ ---
2
+ :combat:
3
+ :name: Combat
4
+ :faces:
5
+ - pow_pow_pow
6
+ - pow_pow
7
+ - pow
8
+ - clue
9
+ - clue_clue
10
+ - blank
11
+ :detect:
12
+ :name: Detect
13
+ :faces:
14
+ - clue_clue_clue
15
+ - clue_clue
16
+ - clue
17
+ - move
18
+ - move_move
19
+ - blank
20
+ :move:
21
+ :name: Move
22
+ :faces:
23
+ - move_move_move
24
+ - move_move
25
+ - move
26
+ - pow
27
+ - pow_pow
28
+ - blank
29
+ :hero:
30
+ :name: Hero
31
+ :faces:
32
+ - move
33
+ - clue
34
+ - pow
35
+ - plus1
36
+ - plus3
37
+ - batman
38
+ :crime:
39
+ :name: Crime
40
+ :faces:
41
+ - antipow
42
+ - antipow
43
+ - anticlue
44
+ - anticlue
45
+ - antimove
46
+ - antimove
47
+ :villain:
48
+ :name: Villain
49
+ :faces:
50
+ - antipow
51
+ - anticlue
52
+ - antimove
53
+ - antiplus_1
54
+ - antiplus_3
55
+ - joker
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Scott M Parrish
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,7 @@
1
+ ---
2
+ - Batgirl
3
+ - Robin
4
+ - Nightwing
5
+ - Huntress
6
+ - Red Robin
7
+ - Batwoman
@@ -0,0 +1,4 @@
1
+ ---
2
+ a: 1
3
+ b: 2
4
+ c: 3
@@ -0,0 +1,87 @@
1
+ ---
2
+ :boost:
3
+ :name: boost
4
+ :faces:
5
+ - blank
6
+ - blank
7
+ - success
8
+ - advantage
9
+ - advantage_advantage
10
+ - success_advantage
11
+ :setback:
12
+ :name: setback
13
+ :faces:
14
+ - blank
15
+ - blank
16
+ - failure
17
+ - failure
18
+ - threat
19
+ - threat
20
+ :ability:
21
+ :name: ability
22
+ :faces:
23
+ - blank
24
+ - success
25
+ - success
26
+ - success_success
27
+ - advantage
28
+ - advantage
29
+ - success_advantage
30
+ - advantage_advantage
31
+ :difficulty:
32
+ :name: difficulty
33
+ :faces:
34
+ - blank
35
+ - failure
36
+ - failure_failure
37
+ - threat
38
+ - threat
39
+ - threat
40
+ - threat_threat
41
+ - failure_threat
42
+ :proficincy:
43
+ :name: proficincy
44
+ :faces:
45
+ - blank
46
+ - success
47
+ - success
48
+ - success_success
49
+ - success_success
50
+ - advantage
51
+ - success_advantage
52
+ - success_advantage
53
+ - success_advantage
54
+ - advantage_advantage
55
+ - advantage_advantage
56
+ - triumph_success
57
+ :challenge:
58
+ :name: challenge
59
+ :faces:
60
+ - blank
61
+ - failure
62
+ - failure
63
+ - failure_failure
64
+ - failure_failure
65
+ - threat
66
+ - threat
67
+ - failure_threat
68
+ - failute_threat
69
+ - threat_threat
70
+ - threat_threat
71
+ - despair_failure
72
+ :force:
73
+ :name: force
74
+ :faces:
75
+ - dark
76
+ - dark
77
+ - dark
78
+ - dark
79
+ - dark
80
+ - dark
81
+ - dark_dark
82
+ - light
83
+ - light
84
+ - light_light
85
+ - light_light
86
+ - light_light
87
+
@@ -0,0 +1,44 @@
1
+ require 'para_dice/string_die'
2
+ require 'para_dice/bag'
3
+ require 'para_dice/results/cancel_opposing'
4
+ require 'para_dice/results/split_faces'
5
+ require 'para_dice/results/hash'
6
+ require 'yaml'
7
+
8
+ # Another example of creating a custom set of dice
9
+ class GothamDice < ParaDice::Bag
10
+ # path to yml file
11
+ DATA_FILE_NAME = 'data/gotham_dice.yml'
12
+
13
+ # which faces are considered opposing, and thus cancel out in CancelOpposing
14
+ # readers
15
+ OPPOSING = [
16
+ ['blank', 'blank'],
17
+ ['pow', 'antipow'],
18
+ ['clue', 'anticlue'],
19
+ ['move', 'antimove'],
20
+ ]
21
+ # The Readers to use in order, in this case, use '_' to split face names
22
+ # (allowing single faces with multiple results), then cancel all of the
23
+ # opposing results, then present the results as a frequency hash
24
+ DEFAULT_READERS = [
25
+ ParaDice::Results::SplitFaces.new('_'),
26
+ ParaDice::Results::CancelOpposing.new(OPPOSING),
27
+ ParaDice::Results::Hash
28
+ ]
29
+
30
+ # @!attribute dice
31
+ # @return [Hash<String,Paradise::StringDie]
32
+ attribute :dice, Hash[String => ParaDice::StringDie]
33
+
34
+ # @!attribute default_readers
35
+ # @return [Array<#resolve>], defaults to DEFAULT_READERS
36
+ attribute :default_readers, Array, default: ->(*a) { DEFAULT_READERS }
37
+
38
+ # simple way to get a bag of dice with optional rng
39
+ # @return [GothamDice]
40
+ def self.get(rng = nil)
41
+ hash = YAML.load_file(DATA_FILE_NAME)
42
+ self.new(name: 'Gotham Dice', dice: hash, rng: rng)
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ require 'virtus'
2
+ require 'para_dice/die'
3
+ require 'para_dice/cup'
4
+ module ParaDice
5
+ # Class to provide a convienent container for and roller of dice
6
+ class Bag
7
+ # Is a virtus.model
8
+ include Virtus.model
9
+
10
+ # @!attribute name
11
+ # @return [String] default: 'Dice Bag'
12
+ attribute :name, String, default: 'Dice Bag'
13
+ # @!attribute dice
14
+ # @return [Hash<String,Die>] default: {}
15
+ attribute :dice, Hash[String => Die], default: ->(*a) { {} }
16
+ # @!attribute default_readers
17
+ # @return [Array<#resolve>] default: []
18
+ attribute :default_readers, Array, default: ->(*a) { [] }
19
+ # @!attribute rng
20
+ # @return [Random] default: Random.new
21
+ attribute :rng, Random, default: ->(*a) { Random.new }
22
+
23
+ # add a die to the bag
24
+ # @param [Die]
25
+ def add_die(die)
26
+ dice[die.name] = die
27
+ end
28
+
29
+ # get an array of dice from an array of dice names
30
+ # @param(*dice_names) array of dice names.
31
+ def get_dice(*dice_names)
32
+ dice_names.flatten.map { |die_name| dice[die_name.to_s] }
33
+ end
34
+
35
+ # given an array of dice_names, create a Cup using them and default_readers
36
+ # @param(*dice_names) array of dice names.
37
+ def get_cup(*dice_names)
38
+ Cup.new(dice: get_dice(*dice_names),
39
+ rng: rng,
40
+ readers: default_readers
41
+ )
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ require 'para_dice/die'
2
+ module ParaDice
3
+ class Cup
4
+ # Includes Virtus.model
5
+ include Virtus.model
6
+
7
+ attribute :dice, Array[ParaDice::Die], default: []
8
+ attribute :rng, Random, default: ->(c, a) { Random.new }
9
+ attribute :readers, Array, default: []
10
+
11
+ def roll(roll_rng = rng)
12
+ readers.reduce(roll!(roll_rng)) { |faces, reader| reader.resolve(faces) }
13
+ end
14
+
15
+ def roll!(roll_rng = rng)
16
+ dice.map { |d| d.roll(roll_rng) }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,64 @@
1
+ require 'virtus'
2
+
3
+ module ParaDice
4
+ # @abstract A module meant to be the basis of a custom Die object with
5
+ # behaviour included from this die.
6
+ # @see GothamDice
7
+ # @see StarWarsDice
8
+ module Die
9
+ ERROR_MSG = ': Must be implemented in your Die class or included in a faces module.'
10
+
11
+ # @!method initialize(params = {})
12
+ # @see Virtus for details
13
+ # creates new Die object and populates it's attributes with values from params.
14
+ # this list may not be comprehensive. Check modules you include for other
15
+ # options.
16
+ # @param [Hash] params
17
+ # @option params [String] :name
18
+ # @option params [Random] :rng
19
+ # @option params [String] :description
20
+
21
+ include Virtus.module
22
+
23
+ # @!attribute [rw] name
24
+ # @return [String] required
25
+ # @!attribute [rw] rng
26
+ # @return [Random] default Random.new
27
+ # @!attribute [rw] description
28
+ # @return [String] default ''
29
+ attribute :name, String, default: :quit_if_no_name
30
+ attribute :rng, Random, default: ->(*args) { Random.new() }
31
+ attribute :description, String, default: ''
32
+
33
+ # for overloading and calling super on to allow more complex arrangements of
34
+ # face and dice behavior modules
35
+ # @param [Random] roll_rng
36
+ # @return [Object] random face from die
37
+ def roll(roll_rng = rng)
38
+ random_face(roll_rng)
39
+ end
40
+
41
+ # @abstract Implement in Include-able Module and override {#face_count} to implement
42
+ # a custom Threadable class.
43
+ def face_count
44
+ raise NotImplementedError.new ('face_count' + ERROR_MSG)
45
+ end
46
+
47
+ # @abstract Implement in Include-able Module and override {#face_count} to implement
48
+ # a custom Threadable class.
49
+ def random_face(this_rng = rng)
50
+ raise NotImplementedError.new ('random_face' + ERROR_MSG)
51
+ end
52
+
53
+ # @abstract Implement in Include-able Module and override {#face_count} to implement
54
+ # a custom Threadable class.
55
+ def faces
56
+ raise NotImplementedError.new ('faces' + ERROR_MSG)
57
+ end
58
+
59
+ private
60
+ def quit_if_no_name
61
+ raise ArgumentError.new('no :name entry found in initialization hash')
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,34 @@
1
+ require 'para_dice/die'
2
+ module ParaDice
3
+ module Faces
4
+ # a module to be included into a ParaDice::Die or similar object.
5
+ # Uses an Array object to provide faces, and provides count and
6
+ # random_face methods
7
+ # @note, these are strings, but the pattern could easily be symbols, numbers,
8
+ # json objects, etc. the only difference would be in how you
9
+ module Arrayed
10
+ include ParaDice::Die
11
+
12
+ # @!attribute faces
13
+ # @return Array<String>
14
+ attribute :faces, Array[String], default: :quit_if_no_faces
15
+
16
+ # returns size of array
17
+ # @return [Fixnum]
18
+ def face_count
19
+ faces.size
20
+ end
21
+
22
+ # returns a random face from faces using rng
23
+ # @return [String]
24
+ def random_face(r = rng)
25
+ faces.sample(random: r)
26
+ end
27
+
28
+ private
29
+ def quit_if_no_faces
30
+ raise ArgumentError.new('no :faces entry found in initialization hash')
31
+ end
32
+ end
33
+ end
34
+ end