dicebag 3.2.2 → 3.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.
@@ -1,30 +1,49 @@
1
- # Encoding: UTF-8
2
-
3
- # This continues definining the DiceBag module.
1
+ # DiceBag module.
4
2
  module DiceBag
5
- # This is the Transform subclass that takes the
6
- # parsed tree and transforms it into its (almost)
7
- # final form. (It gets a normalization pass later.)
3
+ # This is the Transform subclass that takes the parsed tree and
4
+ # transforms it into its (almost) final form. (It gets a normalization
5
+ # pass later.)
8
6
  class Transform < Parslet::Transform
9
7
  def self.hashify_options(options)
10
8
  opts = {}
11
9
 
12
- options.each { |val| opts.update val } if options.respond_to? :each
10
+ options.each { |val| opts.update val } if options.respond_to?(:each)
13
11
 
14
12
  opts
15
13
  end
16
14
 
17
15
  # Options.
18
- # The full options hash is updated later with these
19
- # sub-hashes.
20
- rule(drop: simple(:x)) { { drop: Integer(x) } }
21
- rule(keep: simple(:x)) { { keep: Integer(x) } }
22
- rule(reroll: simple(:x)) { { reroll: Integer(x) } }
23
- rule(target: simple(:x)) { { target: Integer(x) } }
16
+ #
17
+ # The full options hash is updated later with these sub-hashes.
18
+ rule(drop: simple(:x)) do
19
+ { drop: Integer(x) }
20
+ end
21
+
22
+ rule(keep: simple(:x)) do
23
+ { keep: Integer(x) }
24
+ end
25
+
26
+ rule(keeplowest: simple(:x)) do
27
+ { keeplowest: Integer(x) }
28
+ end
24
29
 
25
- # Explode is special, in that if it is nil, then it
26
- # must remain that way.
27
- rule(explode: simple(:x)) { { explode: (x ? Integer(x) : 1) } }
30
+ rule(reroll: simple(:x)) do
31
+ { reroll: Integer(x) }
32
+ end
33
+
34
+ rule(target: simple(:x)) do
35
+ { target: Integer(x) }
36
+ end
37
+
38
+ rule(failure: simple(:x)) do
39
+ { failure: Integer(x) }
40
+ end
41
+
42
+ # Explode is special, in that if it is nil, then we set it to -1 to
43
+ # reflect that.
44
+ rule(explode: simple(:x)) do
45
+ { explode: (x ? Integer(x) : nil) }
46
+ end
28
47
 
29
48
  # Match a label by itself.
30
49
  rule(label: simple(:s)) { [:label, LabelPart.new(String(s))] }
@@ -44,16 +63,19 @@ module DiceBag
44
63
 
45
64
  # Match the xdx and options hash.
46
65
  #
47
- # TODO: Remove the .as(:xdx) in the Parser sub-class
48
- # and then update this class to account for it. It'll
49
- # make the resulting data much cleaner.
66
+ # TODO: Remove the .as(:xdx) in the Parser sub-class and then update
67
+ # this class to account for it. It'll make the resulting data much
68
+ # cleaner.
50
69
  rule(xdx: subtree(:xdx), options: subtree(:opts)) do
51
70
  { xdx: xdx, options: Transform.hashify_options(opts) }
52
71
  end
53
72
 
54
73
  # Convert the count and sides of an :xdx part.
55
74
  rule(count: simple(:c), sides: simple(:s)) do
56
- { count: (c ? Integer(c) : 1), sides: Integer(s) }
75
+ {
76
+ count: (c ? Integer(c) : 1),
77
+ sides: Integer(s)
78
+ }
57
79
  end
58
80
 
59
81
  # Match an operator followed by an :xdx subtree.
@@ -63,6 +85,7 @@ module DiceBag
63
85
  [String(o), part]
64
86
  end
65
87
 
88
+ # Match an operator followed by a immediate value.
66
89
  rule(op: simple(:o), value: simple(:v)) do
67
90
  [String(o), Integer(v)]
68
91
  end
data/lib/dicebag.rb CHANGED
@@ -1,189 +1,33 @@
1
- # Copyright (c) 2012 Randy Carnahan <syn at dragonsbait dot com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the "Software"),
5
- # to deal in the Software without restriction, including without limitation
6
- # the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
- # and/or sell copies of the Software, and to permit persons to whom the
8
- # Software is furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included
11
- # in all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
16
- # NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
- # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18
- # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19
- # USE OR OTHER DEALINGS IN THE SOFTWARE.
20
- #
21
- # dicelib.rb -- version: 3.2.2
22
-
23
1
  require 'parslet'
24
2
 
25
3
  # This defined the main DiceBag module.
26
4
  module DiceBag
27
- DEFAULT_ROLL = '1d6'.freeze
28
-
29
- # This is our generic DiceBagError
30
- # exception subclass.
31
- class DiceBagError < Exception; end
32
-
33
- ###
34
- # Module Methods
35
- ###
36
-
37
- # This takes the parsed tree, AFTER it has
38
- # been through the Transform class, and massages
39
- # the data a bit more, to ease the iteration that
40
- # happens in the Roll class. It will convert all
41
- # values into the correct *Part class.
42
- def self.normalize_tree(tree)
43
- tree = [tree] unless tree.first.is_a? Array
44
-
45
- tree.map { |part| normalize part }
46
- end
47
-
48
- def self.normalize(part)
49
- [
50
- normalize_op(part.first),
51
- normalize_value(part.last)
52
- ]
53
- end
54
-
55
- def self.normalize_op(op)
56
- # We swap out the strings for symbols.
57
- # If the op is not one of the arithimetic
58
- # operators, then the op itself is returned.
59
- # (This should only happen on :start arrays.)
60
- case op
61
- when '+' then :add
62
- when '-' then :sub
63
- when '*' then :mul
64
- when '/' then :div
65
- else
66
- op
67
- end
68
- end
69
-
70
- def self.normalize_value(val)
71
- case val
72
- when String
73
- LabelPart.new val
74
- when Hash
75
- RollPart.new normalize_xdx(val)
76
- when Integer
77
- StaticPart.new val
78
- else
79
- val
80
- end
81
- end
82
-
83
- # This further massages the xDx hashes.
84
- def self.normalize_xdx(hash)
85
- count = hash[:xdx][:count]
86
- sides = hash[:xdx][:sides]
87
-
88
- # Delete the no longer needed :xdx key.
89
- hash.delete(:xdx)
90
-
91
- # Default to at least 1 die.
92
- count = 1 if count.zero? || count.nil?
93
-
94
- # Set the :count and :sides keys directly
95
- # and set the notes array.
96
- hash[:count] = count
97
- hash[:sides] = sides
98
- hash[:notes] = []
99
-
100
- normalize_options hash
101
- end
102
-
103
- def self.normalize_options(hash)
104
- if hash[:options].empty?
105
- hash.delete(:options)
106
- else
107
- normalize_explode hash
108
- normalize_reroll hash
109
- normalize_drop_keep hash
110
- normalize_target hash
111
- end
112
-
113
- hash
114
- end
5
+ # This is our generic DiceBagError exception subclass.
6
+ class DiceBagError < StandardError; end
115
7
 
116
- # Prevent Explosion abuse.
117
- def self.normalize_explode(hash)
118
- return unless hash[:options].key? :explode
119
-
120
- if hash[:options][:explode] == 1
121
- hash[:options][:explode] = hash[:sides]
122
-
123
- hash[:notes].push("Explode set to #{hash[:sides]}")
124
- end
125
- end
126
-
127
- # Prevent Reroll abuse.
128
- def self.normalize_reroll(hash)
129
- return unless hash[:options].key? :reroll
130
-
131
- if hash[:options][:reroll] >= hash[:sides]
132
- hash[:options][:reroll] = 0
133
-
134
- hash[:notes].push 'Reroll reset to 0.'
135
- end
136
- end
137
-
138
- # Make sure there are enough dice to
139
- # handle both Drop and Keep values.
140
- # If not, both are reset to 0. Harsh.
141
- def self.normalize_drop_keep(hash)
142
- drop = hash[:options].fetch(:drop, 0)
143
- keep = hash[:options].fetch(:keep, 0)
144
-
145
- if (drop + keep) >= hash[:count]
146
- hash[:options][:drop] = 0
147
- hash[:options][:keep] = 0
148
-
149
- hash[:notes].push 'Drop and Keep Conflict. Both reset to 0.'
150
- end
151
- end
152
-
153
- # Finally, if we have a target number,
154
- # make sure it is equal to or less than
155
- # the dice sides and greater than 0,
156
- # otherwise, set it to 0 (aka no target
157
- # number) and add a note.
158
- def self.normalize_target(hash)
159
- return unless hash[:options].key? :target
160
-
161
- target = hash[:options][:target]
162
-
163
- return if target >= 0 && target <= hash[:sides]
164
-
165
- hash[:options][:target] = 0
166
-
167
- hash[:notes].push 'Target number too large or is negative; reset to 0.'
168
- end
169
-
170
- # This is the wrapper for the parse, transform,
171
- # and normalize calls. This is called by the Roll
172
- # class, but may be called to get the raw returned
173
- # array of parsed bits for other purposes.
8
+ # This is the wrapper for the parse, transform, and normalize calls.
9
+ # This is called by the Roll class, but may be called to get the raw
10
+ # returned array of parsed parts for other purposes.
174
11
  def self.parse(dstr = '')
175
12
  tree = Parser.new.parse(dstr)
176
13
  ast = Transform.new.apply(tree)
177
14
 
178
- normalize_tree ast
15
+ Normalize.call ast
16
+ end
17
+
18
+ ### Main Syntatic Sugar Interface
19
+ def self.roll(dstr)
20
+ DiceBag::Roll.new(dstr).roll
179
21
  end
180
22
 
181
- def self.roll(dstr = '')
182
- Roll.new(dstr).roll
23
+ # The default roll if one is not given.
24
+ def self.default_roll
25
+ '1d6'
183
26
  end
184
27
  end
185
28
 
186
29
  # Our sub-modules.
30
+ require_relative './dicebag/normalize'
187
31
  require_relative './dicebag/roll_string'
188
32
  require_relative './dicebag/roll_part_string'
189
33
  require_relative './dicebag/parser'
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dicebag
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.2
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SynTruth
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2016-04-25 00:00:00.000000000 Z
@@ -32,12 +32,15 @@ dependencies:
32
32
  version: 1.4.0
33
33
  description: A very flexible dice rolling library for Ruby.
34
34
  email: syntruth@gmail.com
35
- executables: []
35
+ executables:
36
+ - dicebag
36
37
  extensions: []
37
38
  extra_rdoc_files: []
38
39
  files:
40
+ - bin/dicebag
39
41
  - lib/dicebag.rb
40
42
  - lib/dicebag/label_part.rb
43
+ - lib/dicebag/normalize.rb
41
44
  - lib/dicebag/parser.rb
42
45
  - lib/dicebag/result.rb
43
46
  - lib/dicebag/roll.rb
@@ -46,29 +49,35 @@ files:
46
49
  - lib/dicebag/roll_string.rb
47
50
  - lib/dicebag/simple_part.rb
48
51
  - lib/dicebag/static_part.rb
52
+ - lib/dicebag/systems/dnd.rb
53
+ - lib/dicebag/systems/fudge.rb
54
+ - lib/dicebag/systems/gurps.rb
55
+ - lib/dicebag/systems/savage_worlds.rb
56
+ - lib/dicebag/systems/standard.rb
57
+ - lib/dicebag/systems/storyteller.rb
49
58
  - lib/dicebag/transform.rb
50
59
  homepage: https://github.com/syntruth/Dice-Bag
51
60
  licenses:
52
61
  - MIT
53
62
  metadata: {}
54
- post_install_message:
63
+ post_install_message:
55
64
  rdoc_options: []
56
65
  require_paths:
57
66
  - lib
67
+ - lib/systems
58
68
  required_ruby_version: !ruby/object:Gem::Requirement
59
69
  requirements:
60
70
  - - ">="
61
71
  - !ruby/object:Gem::Version
62
- version: '0'
72
+ version: 2.7.1
63
73
  required_rubygems_version: !ruby/object:Gem::Requirement
64
74
  requirements:
65
75
  - - ">="
66
76
  - !ruby/object:Gem::Version
67
77
  version: '0'
68
78
  requirements: []
69
- rubyforge_project:
70
- rubygems_version: 2.4.5.1
71
- signing_key:
79
+ rubygems_version: 3.1.2
80
+ signing_key:
72
81
  specification_version: 4
73
82
  summary: 'Dice Bag: Ruby Dice Rolling Library'
74
83
  test_files: []