nuffle 0.1.0 → 1.0.0

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