bag_of_holding 0.0.1

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 (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