nuffle 0.1.0 → 1.0.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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nuffle.rb +90 -7
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b849e017faea3c21e8d0447341d5ac796029ad8
4
- data.tar.gz: df918be95dad4fb9fc62170838d61cb0342e959b
3
+ metadata.gz: 2b1880e05185b3d3a5224d94c51631030f18799a
4
+ data.tar.gz: 2b052a7e840a08705166b6027e61c9d49a92f224
5
5
  SHA512:
6
- metadata.gz: c68ee6dc1917642d21d14fc1ed760b046b1bf7181b4b532d000550790836f9a947ac9480fb25071f37924759e29b0d1fdafa23a3f7d7ef43a17079e3dca36d96
7
- data.tar.gz: 29518a23005a0c2b540facbbc42bd35f15a127fffb59b8ab2f9c4737d0a077cff69058d5941633239b91cf725a4201bd73ee56c279d307c21187858a9c90f2be
6
+ metadata.gz: 7b25d91e48637f1591ebd115e72e8c042c97e8d674e669519be5219c847e68511d6bbd6ff98c6faf38c3f239939bcf5439ead5abedf564810e3dce07f66c0a2c
7
+ data.tar.gz: d0fc966473b6061f5716eae6a8ea788c644449470997f459fc2cf96b8d4e7814b232e0414f8b9b327a884eaee465a368b17a44ed710635642cfcb982ba7042b2
data/lib/nuffle.rb CHANGED
@@ -1,11 +1,94 @@
1
1
  class Nuffle
2
2
 
3
- # Roll an x-sided dice
4
- def self.roll(x)
5
- # validate
6
- raise "Invalid number of sides." if !x.is_a?(Integer) || x < 2
7
-
8
- # roll
9
- return 1 + rand(x);
3
+ def self.roll(x = '')
4
+ ::Nuffle::Calculator.new(x).calculate
10
5
  end
11
6
  end
7
+
8
+ class Nuffle::Calculator
9
+
10
+ attr_reader :input,
11
+ :rolls,
12
+ :equation,
13
+ :result
14
+
15
+ def initialize(input)
16
+ validate(input)
17
+ end
18
+
19
+ def calculate
20
+ # reset the rolls array
21
+ @rolls = []
22
+
23
+ # throw rolls and replace 'xdy' dice notation with results
24
+ @equation = @input.gsub(/(\d+)d(\d+)/) do |match|
25
+ rolls = []
26
+
27
+ (1..$1.to_i).each do
28
+ rolls << 1 + rand($2.to_i)
29
+ end
30
+
31
+ # save individual roll results
32
+ @rolls << {
33
+ 'notation' => match,
34
+ 'rolls' => rolls
35
+ }
36
+
37
+ "(#{rolls.join(" + ")})"
38
+ end
39
+
40
+ # cast integers to floats
41
+ equation = @equation.gsub(/\b(\d+)\b/) do |match|
42
+ $1.to_f.to_s
43
+ end
44
+
45
+ # calculate result
46
+ @result = eval(equation);
47
+
48
+ # cast result to integer if a whole float
49
+ @result = @result.to_i if @result % 1 == 0
50
+
51
+ self
52
+ end
53
+
54
+ private
55
+
56
+ def validate(input)
57
+ # has to be something we can calculate
58
+ raise("Input must be an equation or a number.") unless input.is_a?(String) || input.is_a?(Numeric)
59
+
60
+ # no empty inputs
61
+ raise("Input can't be blank.") if input.to_s.strip == ''
62
+
63
+ # cast input to a string
64
+ input = input.to_s
65
+
66
+ # validate the input format
67
+ raise("Invalid equation.") unless /^[\(\s]*(([1-9][0-9]*d[1-9][0-9]*)|\d+)[\s\)]*(\s*([\-\+\*\/])[\s\(]*(([1-9][0-9]*d[1-9][0-9]*)|\d+)\)*)*$/i.match(input)
68
+
69
+ # make sure the parens are balanced
70
+ raise("Unbalanced parens.") unless is_balanced?(input)
71
+
72
+ @input = input
73
+ end
74
+
75
+ def is_balanced?(input)
76
+ balance = 0
77
+
78
+ input.split("").each do |char|
79
+ if char == '('
80
+ balance += 1
81
+ elsif char == ')'
82
+ balance -= 1
83
+ end
84
+
85
+ # found a close paren without a matching open paren,
86
+ # no need to continue further
87
+ if balance < 0
88
+ break
89
+ end
90
+ end
91
+
92
+ return balance === 0
93
+ end
94
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nuffle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zachary Flower
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-13 00:00:00.000000000 Z
11
+ date: 2016-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest