bag_of_holding 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +37 -0
  3. data/Rakefile +17 -0
  4. data/bin/boh +28 -0
  5. data/lib/bag_of_holding/dice/addition_operation.rb +18 -0
  6. data/lib/bag_of_holding/dice/constant.rb +23 -0
  7. data/lib/bag_of_holding/dice/constant_result.rb +27 -0
  8. data/lib/bag_of_holding/dice/die.rb +39 -0
  9. data/lib/bag_of_holding/dice/die_result.rb +26 -0
  10. data/lib/bag_of_holding/dice/die_roller.rb +51 -0
  11. data/lib/bag_of_holding/dice/die_validator.rb +23 -0
  12. data/lib/bag_of_holding/dice/division_operation.rb +18 -0
  13. data/lib/bag_of_holding/dice/multiplication_operation.rb +18 -0
  14. data/lib/bag_of_holding/dice/operation.rb +45 -0
  15. data/lib/bag_of_holding/dice/operation_result.rb +38 -0
  16. data/lib/bag_of_holding/dice/parser.rb +50 -0
  17. data/lib/bag_of_holding/dice/pool.rb +58 -0
  18. data/lib/bag_of_holding/dice/pool_factory.rb +70 -0
  19. data/lib/bag_of_holding/dice/pool_result.rb +37 -0
  20. data/lib/bag_of_holding/dice/subtraction_operation.rb +18 -0
  21. data/lib/bag_of_holding/dice/transform.rb +59 -0
  22. data/lib/bag_of_holding/dice.rb +41 -0
  23. data/lib/bag_of_holding.rb +1 -0
  24. data/spec/dice/addition_operation_spec.rb +23 -0
  25. data/spec/dice/constant_result_spec.rb +48 -0
  26. data/spec/dice/constant_spec.rb +31 -0
  27. data/spec/dice/die_result_spec.rb +70 -0
  28. data/spec/dice/die_roller_spec.rb +76 -0
  29. data/spec/dice/die_spec.rb +111 -0
  30. data/spec/dice/die_validator_spec.rb +34 -0
  31. data/spec/dice/division_operation_spec.rb +35 -0
  32. data/spec/dice/multiplication_operation_spec.rb +27 -0
  33. data/spec/dice/operation_result_spec.rb +64 -0
  34. data/spec/dice/operation_spec.rb +55 -0
  35. data/spec/dice/parser_spec.rb +215 -0
  36. data/spec/dice/pool_factory_spec.rb +71 -0
  37. data/spec/dice/pool_result_spec.rb +63 -0
  38. data/spec/dice/pool_spec.rb +126 -0
  39. data/spec/dice/subtraction_operation_spec.rb +27 -0
  40. data/spec/dice/transform_spec.rb +237 -0
  41. data/spec/spec_helper.rb +24 -0
  42. metadata +186 -0
@@ -0,0 +1,71 @@
1
+ RSpec.describe BagOfHolding::Dice::PoolFactory do
2
+ subject { BagOfHolding::Dice::PoolFactory }
3
+
4
+ describe '::build' do
5
+ it 'builds a pool simple labeled 20 sided die' do
6
+ pool = subject.build count: 10, die: [{ sides: 20 }], label: 'Spec'
7
+ expect(pool).to eq(
8
+ BagOfHolding::Dice::Pool.new(
9
+ count: 10,
10
+ die: BagOfHolding::Dice::Die.new(sides: 20),
11
+ label: 'Spec'
12
+ )
13
+ )
14
+ end
15
+
16
+ it 'defaults a pool count to 1' do
17
+ pool = subject.build count: nil, die: [{ sides: 20 }], label: 'Spec'
18
+ expect(pool).to eq(
19
+ BagOfHolding::Dice::Pool.new(
20
+ count: 1,
21
+ die: BagOfHolding::Dice::Die.new(sides: 20),
22
+ label: 'Spec'
23
+ )
24
+ )
25
+ end
26
+
27
+ it 'defaults explosions to the number of sides' do
28
+ pool = subject.build count: nil,
29
+ die: [{ sides: 20 }, { explode: nil }]
30
+ expect(pool).to eq(
31
+ BagOfHolding::Dice::Pool.new(
32
+ count: 1,
33
+ die: BagOfHolding::Dice::Die.new(sides: 20, explode: 20)
34
+ )
35
+ )
36
+ end
37
+
38
+ it 'sets the explode value' do
39
+ pool = subject.build count: nil,
40
+ die: [{ sides: 20 }, { explode: 15 }]
41
+ expect(pool).to eq(
42
+ BagOfHolding::Dice::Pool.new(
43
+ count: 1,
44
+ die: BagOfHolding::Dice::Die.new(sides: 20, explode: 15)
45
+ )
46
+ )
47
+ end
48
+
49
+ it 'defaults rerolls to 1' do
50
+ pool = subject.build count: nil,
51
+ die: [{ sides: 20 }, { reroll: nil }]
52
+ expect(pool).to eq(
53
+ BagOfHolding::Dice::Pool.new(
54
+ count: 1,
55
+ die: BagOfHolding::Dice::Die.new(sides: 20, reroll: 1)
56
+ )
57
+ )
58
+ end
59
+
60
+ it 'sets the reroll value' do
61
+ pool = subject.build count: nil,
62
+ die: [{ sides: 20 }, { reroll: 5 }]
63
+ expect(pool).to eq(
64
+ BagOfHolding::Dice::Pool.new(
65
+ count: 1,
66
+ die: BagOfHolding::Dice::Die.new(sides: 20, reroll: 5)
67
+ )
68
+ )
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,63 @@
1
+ RSpec.describe BagOfHolding::Dice::PoolResult do
2
+ let(:die_results) do
3
+ [
4
+ BagOfHolding::Dice::DieResult.new(rolls: [3], value: 3),
5
+ BagOfHolding::Dice::DieResult.new(rolls: [4], value: 4),
6
+ BagOfHolding::Dice::DieResult.new(rolls: [5], value: 5)
7
+ ]
8
+ end
9
+
10
+ subject do
11
+ BagOfHolding::Dice::PoolResult.new(
12
+ die_results: die_results,
13
+ value: 12
14
+ )
15
+ end
16
+
17
+ describe '#initialize' do
18
+ it 'sets the die_results and value attributes' do
19
+ result = BagOfHolding::Dice::PoolResult.new die_results: die_results,
20
+ value: 12
21
+
22
+ expect(result.die_results).to eq(die_results)
23
+ expect(result.value).to eq(12)
24
+ end
25
+ end
26
+
27
+ describe '#==' do
28
+ let(:other) do
29
+ BagOfHolding::Dice::PoolResult.new(
30
+ die_results: subject.die_results,
31
+ value: subject.value
32
+ )
33
+ end
34
+
35
+ it 'returns true when compared to an identical pool result' do
36
+ expect(subject == other).to eq(true)
37
+ end
38
+
39
+ it 'returns false when compared to a pool with a different value' do
40
+ other.value = 42
41
+ expect(subject == other).to eq(false)
42
+ end
43
+
44
+ it 'returns false when compared to a pool with different die results' do
45
+ other.die_results = []
46
+ expect(subject == other).to eq(false)
47
+ end
48
+ end
49
+
50
+ describe '#to_s' do
51
+ it 'returns the value and the pool string' do
52
+ subject.pool = double(to_s: '2d20')
53
+ expect(subject.to_s).to eq('12 (2d20)')
54
+ end
55
+ end
56
+
57
+ describe '#inspect' do
58
+ it 'returns a string with the specific rolls' do
59
+ subject.pool = double(to_s: '2d20')
60
+ expect(subject.inspect).to eq('12 (2d20) [3] [4] [5]')
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,126 @@
1
+ RSpec.describe BagOfHolding::Dice::Pool do
2
+ let(:die) { BagOfHolding::Dice::Die.new sides: 10 }
3
+ subject { BagOfHolding::Dice::Pool.new count: 2, die: die }
4
+
5
+ describe '#initialize' do
6
+ it 'sets the attributes on the class' do
7
+ pool = BagOfHolding::Dice::Pool.new(
8
+ count: 2,
9
+ die: BagOfHolding::Dice::Die.new(sides: 10),
10
+ label: 'Specs'
11
+ )
12
+
13
+ expect(pool.count).to eq(2)
14
+ expect(pool.die).to eq(BagOfHolding::Dice::Die.new(sides: 10))
15
+ expect(pool.label).to eq('Specs')
16
+ end
17
+ end
18
+
19
+ describe '#count=' do
20
+ it 'sets the number of dice in the pool' do
21
+ subject.count = 100
22
+ expect(subject.count).to eq(100)
23
+ end
24
+ end
25
+
26
+ describe '#count' do
27
+ it 'returns the number of dice in the pool' do
28
+ expect(subject.count).to eq(2)
29
+ end
30
+ end
31
+
32
+ describe '#die=' do
33
+ it 'sets the die the pool is made of' do
34
+ die = BagOfHolding::Dice::Die.new sides: 76
35
+ subject.die = die
36
+ expect(subject.die).to eq(die)
37
+ end
38
+ end
39
+
40
+ describe '#die' do
41
+ it 'returns the die the pool is made of' do
42
+ expect(subject.die).to eq(die)
43
+ end
44
+ end
45
+
46
+ describe '#==' do
47
+ let(:other) do
48
+ BagOfHolding::Dice::Pool.new count: subject.count,
49
+ die: subject.die,
50
+ label: subject.label
51
+ end
52
+
53
+ it 'returns true for a pool with the same attributes' do
54
+ expect(subject == other).to eq(true)
55
+ end
56
+
57
+ it 'returns false for a pool with a different count' do
58
+ other.count = 10_00
59
+ expect(subject == other).to eq(false)
60
+ end
61
+
62
+ it 'returns false for a pool with a different die' do
63
+ other.die = BagOfHolding::Dice::Die.new sides: 4
64
+ expect(subject == other).to eq(false)
65
+ end
66
+
67
+ it 'returns false for a pool with a different label' do
68
+ other.label = 'Others'
69
+ expect(subject == other).to eq(false)
70
+ end
71
+ end
72
+
73
+ describe '#roll' do
74
+ let(:die_results) do
75
+ [
76
+ BagOfHolding::Dice::DieResult.new(rolls: [3], value: 3),
77
+ BagOfHolding::Dice::DieResult.new(rolls: [5], value: 5),
78
+ BagOfHolding::Dice::DieResult.new(rolls: [1], value: 1)
79
+ ]
80
+ end
81
+ subject { BagOfHolding::Dice::Pool.new count: 3, die: die }
82
+
83
+ before :each do
84
+ allow(die).to receive(:roll).and_return(*die_results)
85
+ end
86
+
87
+ context 'without a keep value' do
88
+ it 'sums the rolls of the dice in the pool' do
89
+ expect(subject.roll).to eq(
90
+ BagOfHolding::Dice::PoolResult.new die_results: die_results,
91
+ value: 9,
92
+ pool: subject
93
+ )
94
+ end
95
+ end
96
+
97
+ context 'with a keep value of 1' do
98
+ it 'returns the value of the highest die' do
99
+ subject.keep = 1
100
+ expect(subject.roll).to eq(
101
+ BagOfHolding::Dice::PoolResult.new die_results: die_results,
102
+ value: 5,
103
+ pool: subject
104
+ )
105
+ end
106
+ end
107
+
108
+ context 'with a keep value of 2' do
109
+ it 'returns the value of the highest die' do
110
+ subject.keep = 2
111
+ expect(subject.roll).to eq(
112
+ BagOfHolding::Dice::PoolResult.new die_results: die_results,
113
+ value: 8,
114
+ pool: subject
115
+ )
116
+ end
117
+ end
118
+ end
119
+
120
+ describe '#to_s' do
121
+ it 'returns the die str' do
122
+ subject.die = double(to_s: 'd172')
123
+ expect(subject.to_s).to eq('2d172')
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,27 @@
1
+ RSpec.describe BagOfHolding::Dice::SubtractionOperation do
2
+ let(:left) { BagOfHolding::Dice::Constant.new value: 11 }
3
+ let(:right) { BagOfHolding::Dice::Constant.new value: 7 }
4
+
5
+ subject do
6
+ BagOfHolding::Dice::SubtractionOperation.new left: left,
7
+ right: right
8
+ end
9
+
10
+ describe '::operator' do
11
+ it 'returns -' do
12
+ expect(BagOfHolding::Dice::SubtractionOperation.operator).to eq('-')
13
+ end
14
+ end
15
+
16
+ describe '#value' do
17
+ it 'subtracts the right value from the left' do
18
+ expect(subject.value).to eq(4)
19
+ end
20
+ end
21
+
22
+ describe '#operator' do
23
+ it 'returns -' do
24
+ expect(subject.operator).to eq('-')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,237 @@
1
+ RSpec.describe BagOfHolding::Dice::Transform do
2
+ subject { BagOfHolding::Dice::Transform.new }
3
+ let(:parser) { BagOfHolding::Dice::Parser.new }
4
+
5
+ describe '#apply' do
6
+ it 'transforms 5' do
7
+ tree = parser.parse '5'
8
+ expect(subject.apply(tree)).to match([
9
+ BagOfHolding::Dice::Constant.new(value: 5)
10
+ ])
11
+ end
12
+
13
+ it 'transforms 1d20' do
14
+ tree = parser.parse '1d20'
15
+ expect(subject.apply(tree)).to match([
16
+ BagOfHolding::Dice::Pool.new(
17
+ count: 1,
18
+ die: BagOfHolding::Dice::Die.new(sides: 20)
19
+ )
20
+ ])
21
+ end
22
+
23
+ it 'transforms 2d20k' do
24
+ tree = parser.parse '2d20k'
25
+ expect(subject.apply(tree)).to match([
26
+ BagOfHolding::Dice::Pool.new(
27
+ count: 2,
28
+ die: BagOfHolding::Dice::Die.new(sides: 20),
29
+ keep: 1
30
+ )
31
+ ])
32
+ end
33
+
34
+ it 'transforms 1d20,1d8' do
35
+ tree = parser.parse '1d20,1d8'
36
+ expect(subject.apply(tree)).to match([
37
+ BagOfHolding::Dice::Pool.new(
38
+ count: 1,
39
+ die: BagOfHolding::Dice::Die.new(sides: 20)
40
+ ),
41
+ BagOfHolding::Dice::Pool.new(
42
+ count: 1,
43
+ die: BagOfHolding::Dice::Die.new(sides: 8)
44
+ )
45
+ ])
46
+ end
47
+
48
+ it 'transforms d20' do
49
+ tree = parser.parse 'd20'
50
+ expect(subject.apply(tree)).to match([
51
+ BagOfHolding::Dice::Pool.new(
52
+ count: 1,
53
+ die: BagOfHolding::Dice::Die.new(sides: 20)
54
+ )
55
+ ])
56
+ end
57
+
58
+ it 'transforms 3d8 (Attack)' do
59
+ tree = parser.parse '3d8 (Attack)'
60
+ expect(subject.apply(tree)).to match([
61
+ BagOfHolding::Dice::Pool.new(
62
+ count: 3,
63
+ label: 'Attack',
64
+ die: BagOfHolding::Dice::Die.new(sides: 8)
65
+ )
66
+ ])
67
+ end
68
+
69
+ it 'transforms 1d20r' do
70
+ tree = parser.parse '1d20r'
71
+ expect(subject.apply(tree)).to match([
72
+ BagOfHolding::Dice::Pool.new(
73
+ count: 1,
74
+ die: BagOfHolding::Dice::Die.new(sides: 20, reroll: 1)
75
+ )
76
+ ])
77
+ end
78
+
79
+ it 'transforms 5+6' do
80
+ tree = parser.parse '5+6'
81
+ expect(subject.apply(tree)).to match([
82
+ BagOfHolding::Dice::AdditionOperation.new(
83
+ left: BagOfHolding::Dice::Constant.new(value: 5),
84
+ right: BagOfHolding::Dice::Constant.new(value: 6)
85
+ )
86
+ ])
87
+ end
88
+
89
+ it 'transforms 5-6' do
90
+ tree = parser.parse '5-6'
91
+ expect(subject.apply(tree)).to match([
92
+ BagOfHolding::Dice::SubtractionOperation.new(
93
+ left: BagOfHolding::Dice::Constant.new(value: 5),
94
+ right: BagOfHolding::Dice::Constant.new(value: 6)
95
+ )
96
+ ])
97
+ end
98
+
99
+ it 'transforms 4/2' do
100
+ tree = parser.parse '4/2'
101
+ expect(subject.apply(tree)).to match([
102
+ BagOfHolding::Dice::DivisionOperation.new(
103
+ left: BagOfHolding::Dice::Constant.new(value: 4),
104
+ right: BagOfHolding::Dice::Constant.new(value: 2)
105
+ )
106
+ ])
107
+ end
108
+
109
+ it 'transforms 4*2' do
110
+ tree = parser.parse '4*2'
111
+ expect(subject.apply(tree)).to match([
112
+ BagOfHolding::Dice::MultiplicationOperation.new(
113
+ left: BagOfHolding::Dice::Constant.new(value: 4),
114
+ right: BagOfHolding::Dice::Constant.new(value: 2)
115
+ )
116
+ ])
117
+ end
118
+
119
+ it 'transforms 8, 9' do
120
+ tree = parser.parse '8, 9'
121
+ expect(subject.apply(tree)).to match([
122
+ BagOfHolding::Dice::Constant.new(value: 8),
123
+ BagOfHolding::Dice::Constant.new(value: 9)
124
+ ])
125
+ end
126
+
127
+ it 'transforms 1 + 2, 3' do
128
+ tree = parser.parse '1 + 2, 3'
129
+ expect(subject.apply(tree)).to match([
130
+ BagOfHolding::Dice::AdditionOperation.new(
131
+ left: BagOfHolding::Dice::Constant.new(value: 1),
132
+ right: BagOfHolding::Dice::Constant.new(value: 2)
133
+ ),
134
+ BagOfHolding::Dice::Constant.new(value: 3)
135
+ ])
136
+ end
137
+
138
+ it 'transforms 1d20r (Defense)' do
139
+ tree = parser.parse '1d20r (Defense)'
140
+ expect(subject.apply(tree)).to match([
141
+ BagOfHolding::Dice::Pool.new(
142
+ count: 1,
143
+ die: BagOfHolding::Dice::Die.new(sides: 20, reroll: 1),
144
+ label: 'Defense'
145
+ )
146
+ ])
147
+ end
148
+
149
+ it 'transforms 1d20r2' do
150
+ tree = parser.parse '1d20r2'
151
+ expect(subject.apply(tree)).to match([
152
+ BagOfHolding::Dice::Pool.new(
153
+ count: 1,
154
+ die: BagOfHolding::Dice::Die.new(sides: 20, reroll: 2)
155
+ )
156
+ ])
157
+ end
158
+
159
+ it 'transforms 1d20e' do
160
+ tree = parser.parse '1d20e'
161
+ expect(subject.apply(tree)).to match([
162
+ BagOfHolding::Dice::Pool.new(
163
+ count: 1,
164
+ die: BagOfHolding::Dice::Die.new(sides: 20, explode: 20)
165
+ )
166
+ ])
167
+ end
168
+
169
+ it 'transforms 1d20e18' do
170
+ tree = parser.parse '1d20e18'
171
+ expect(subject.apply(tree)).to match([
172
+ BagOfHolding::Dice::Pool.new(
173
+ count: 1,
174
+ die: BagOfHolding::Dice::Die.new(sides: 20, explode: 18)
175
+ )
176
+ ])
177
+ end
178
+
179
+ it 'transforms 1d20e18r2' do
180
+ tree = parser.parse '1d20e18r2'
181
+ expect(subject.apply(tree)).to match([
182
+ BagOfHolding::Dice::Pool.new(
183
+ count: 1,
184
+ die: BagOfHolding::Dice::Die.new(sides: 20, explode: 18, reroll: 2)
185
+ )
186
+ ])
187
+ end
188
+
189
+ it 'transforms 1d20r2e18' do
190
+ tree = parser.parse '1d20r2e18'
191
+ expect(subject.apply(tree)).to match([
192
+ BagOfHolding::Dice::Pool.new(
193
+ count: 1,
194
+ die: BagOfHolding::Dice::Die.new(sides: 20, explode: 18, reroll: 2)
195
+ )
196
+ ])
197
+ end
198
+
199
+ it 'transforms 1d20 + 5' do
200
+ tree = parser.parse '1d20 + 5'
201
+ expect(subject.apply(tree)).to match([
202
+ BagOfHolding::Dice::AdditionOperation.new(
203
+ left: BagOfHolding::Dice::Pool.new(
204
+ count: 1,
205
+ die: BagOfHolding::Dice::Die.new(sides: 20)
206
+ ),
207
+ right: BagOfHolding::Dice::Constant.new(value: 5)
208
+ )
209
+ ])
210
+ end
211
+
212
+ it 'transforms 2d6r+ 1d4 + 2+1d8' do
213
+ tree = parser.parse '2d6r+ 1d4 + 2+1d8'
214
+ expect(subject.apply(tree)).to match([
215
+ BagOfHolding::Dice::AdditionOperation.new(
216
+ left: BagOfHolding::Dice::Pool.new(
217
+ count: 2,
218
+ die: BagOfHolding::Dice::Die.new(sides: 6, reroll: 1)
219
+ ),
220
+ right: BagOfHolding::Dice::AdditionOperation.new(
221
+ left: BagOfHolding::Dice::Pool.new(
222
+ count: 1,
223
+ die: BagOfHolding::Dice::Die.new(sides: 4)
224
+ ),
225
+ right: BagOfHolding::Dice::AdditionOperation.new(
226
+ left: BagOfHolding::Dice::Constant.new(value: 2),
227
+ right: BagOfHolding::Dice::Pool.new(
228
+ count: 1,
229
+ die: BagOfHolding::Dice::Die.new(sides: 8)
230
+ )
231
+ )
232
+ )
233
+ )
234
+ ])
235
+ end
236
+ end
237
+ end