dicebag 3.2.2 → 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,30 +1,51 @@
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)
8
+ return options if options.is_a? Hash
9
+
10
10
  opts = {}
11
11
 
12
- options.each { |val| opts.update val } if options.respond_to? :each
12
+ options.each { |val| opts.update val } if options.respond_to?(:each)
13
13
 
14
14
  opts
15
15
  end
16
16
 
17
17
  # 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) } }
18
+ #
19
+ # The full options hash is updated later with these sub-hashes.
20
+ rule(drop: simple(:x)) do
21
+ { drop: Integer(x) }
22
+ end
23
+
24
+ rule(keep: simple(:x)) do
25
+ { keep: Integer(x) }
26
+ end
27
+
28
+ rule(keeplowest: simple(:x)) do
29
+ { keeplowest: Integer(x) }
30
+ end
24
31
 
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) } }
32
+ rule(reroll: simple(:x)) do
33
+ { reroll: Integer(x) }
34
+ end
35
+
36
+ rule(target: simple(:x)) do
37
+ { target: Integer(x) }
38
+ end
39
+
40
+ rule(failure: simple(:x)) do
41
+ { failure: Integer(x) }
42
+ end
43
+
44
+ # Explode is special, in that if it is nil, then we set it to -1 to
45
+ # reflect that, and it'll be updated in the normalization phase.
46
+ rule(explode: simple(:x)) do
47
+ { explode: (x ? Integer(x) : -1) }
48
+ end
28
49
 
29
50
  # Match a label by itself.
30
51
  rule(label: simple(:s)) { [:label, LabelPart.new(String(s))] }
@@ -44,16 +65,19 @@ module DiceBag
44
65
 
45
66
  # Match the xdx and options hash.
46
67
  #
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.
68
+ # TODO: Remove the .as(:xdx) in the Parser sub-class and then update
69
+ # this class to account for it. It'll make the resulting data much
70
+ # cleaner.
50
71
  rule(xdx: subtree(:xdx), options: subtree(:opts)) do
51
72
  { xdx: xdx, options: Transform.hashify_options(opts) }
52
73
  end
53
74
 
54
75
  # Convert the count and sides of an :xdx part.
55
76
  rule(count: simple(:c), sides: simple(:s)) do
56
- { count: (c ? Integer(c) : 1), sides: Integer(s) }
77
+ {
78
+ count: (c ? Integer(c) : 1),
79
+ sides: Integer(s)
80
+ }
57
81
  end
58
82
 
59
83
  # Match an operator followed by an :xdx subtree.
@@ -63,6 +87,7 @@ module DiceBag
63
87
  [String(o), part]
64
88
  end
65
89
 
90
+ # Match an operator followed by a immediate value.
66
91
  rule(op: simple(:o), value: simple(:v)) do
67
92
  [String(o), Integer(v)]
68
93
  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.1
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: []