para_dice 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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