functional-yahtzee 0.0.3
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.
- checksums.yaml +7 -0
- data/.bundle/config +1 -0
- data/.gitignore +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +71 -0
- data/Guardfile +6 -0
- data/README.md +115 -0
- data/Rakefile +13 -0
- data/artifacts/score_card.jpg +0 -0
- data/bin/console +31 -0
- data/functional_yahtzee.gemspec +25 -0
- data/lib/dice.rb +19 -0
- data/lib/errors.rb +5 -0
- data/lib/game.rb +33 -0
- data/lib/probability.rb +32 -0
- data/lib/round.rb +11 -0
- data/lib/score_card.rb +59 -0
- data/lib/scoring.rb +48 -0
- data/lib/scoring/lower_card.rb +62 -0
- data/lib/scoring/upper_card.rb +34 -0
- data/lib/yahtzee.rb +13 -0
- data/test/integration/dice_test.rb +20 -0
- data/test/integration/game_test.rb +431 -0
- data/test/integration/scoring_test.rb +20 -0
- data/test/test_helper.rb +19 -0
- data/test/unit/dice_test.rb +40 -0
- data/test/unit/game_test.rb +27 -0
- data/test/unit/probability_test.rb +35 -0
- data/test/unit/score_card_test.rb +77 -0
- data/test/unit/scoring/lower_card_test.rb +71 -0
- data/test/unit/scoring/upper_card_test.rb +53 -0
- data/test/unit/scoring_test.rb +169 -0
- metadata +145 -0
data/lib/scoring.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'yahtzee'
|
2
|
+
require 'score_card'
|
3
|
+
require 'scoring/upper_card'
|
4
|
+
require 'scoring/lower_card'
|
5
|
+
|
6
|
+
# Yahtzee::Scoring is our mechnism for scoring dice
|
7
|
+
# to placement spots on the score card. If the method
|
8
|
+
# is located here, it will include a callback you can
|
9
|
+
# define. Right now it is used for writing the value
|
10
|
+
# to the object, but you could print the value instead.
|
11
|
+
#
|
12
|
+
# Notice there is no direct coupling of type between this
|
13
|
+
# and the possible caller, just a contract on the params
|
14
|
+
module Yahtzee
|
15
|
+
module Scoring
|
16
|
+
|
17
|
+
extend UpperCard
|
18
|
+
extend LowerCard
|
19
|
+
|
20
|
+
module_function
|
21
|
+
def score(dice, placement, &updater)
|
22
|
+
value = send("score_#{placement.to_s}", dice)
|
23
|
+
updater.call(placement, value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def score_subtotal(scores, placement, &updater)
|
27
|
+
value = reduce_values_from_hash(scores)
|
28
|
+
updater.call(placement, value)
|
29
|
+
end
|
30
|
+
|
31
|
+
def score_upper_total(scores, &updater)
|
32
|
+
subtotal = reduce_values_from_hash(scores)
|
33
|
+
bonus = subtotal >= 63 ? 35 : 0
|
34
|
+
updater.call(:upper_total, bonus+subtotal)
|
35
|
+
end
|
36
|
+
|
37
|
+
def score_game_total(scores, &updater)
|
38
|
+
value = reduce_values_from_hash(scores)
|
39
|
+
updater.call(:game_total, value)
|
40
|
+
end
|
41
|
+
|
42
|
+
def reduce_values_from_hash(hash)
|
43
|
+
hash.values.compact.reduce(:+)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'yahtzee'
|
2
|
+
|
3
|
+
module Yahtzee::Scoring
|
4
|
+
module LowerCard
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def score_chance(dice)
|
8
|
+
dice.reduce(:+)
|
9
|
+
end
|
10
|
+
|
11
|
+
def score_full_house(dice)
|
12
|
+
sorted = dice.sort
|
13
|
+
(sorted.count(sorted.first) +
|
14
|
+
sorted.count(sorted.last) == 5) ? 25 : 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def score_small_straight(dice)
|
18
|
+
dice.each_cons(4).any? do |a,b,c,d|
|
19
|
+
a+1==b && b+1==c && c+1==d
|
20
|
+
end ? 30 : 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def score_large_straight(dice)
|
24
|
+
dice.each_cons(5).any? do |a,b,c,d,e|
|
25
|
+
a+1==b && b+1==c && c+1==d && d+1==e
|
26
|
+
end ? 40 : 0
|
27
|
+
end
|
28
|
+
|
29
|
+
def score_three_of_a_kind(dice)
|
30
|
+
score_min_of_a_kind(dice, 3)
|
31
|
+
end
|
32
|
+
|
33
|
+
def score_four_of_a_kind(dice)
|
34
|
+
score_min_of_a_kind(dice, 4)
|
35
|
+
end
|
36
|
+
|
37
|
+
def score_yahtzee(dice)
|
38
|
+
dice.uniq.count == 1 ? 50 : 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def score_bonus_yahtzee(dice)
|
42
|
+
dice.uniq.count == 1 ? 100 : 0
|
43
|
+
end
|
44
|
+
alias_method :score_bonus_yahtzee_1, :score_bonus_yahtzee
|
45
|
+
alias_method :score_bonus_yahtzee_2, :score_bonus_yahtzee
|
46
|
+
alias_method :score_bonus_yahtzee_3, :score_bonus_yahtzee
|
47
|
+
|
48
|
+
def score_min_of_a_kind(dice, min)
|
49
|
+
value = max_dupe_count_as_hash(dice)
|
50
|
+
value[1] >= min ? value.reduce(:*) : 0
|
51
|
+
end
|
52
|
+
|
53
|
+
def dup_counts_as_hash(dice)
|
54
|
+
dice.each_with_object(Hash.new(0)) {|o, h| h[o] += 1 }
|
55
|
+
end
|
56
|
+
|
57
|
+
def max_dupe_count_as_hash(dice)
|
58
|
+
dup_counts_as_hash(dice).max_by {|_,v| v }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Yahtzee::Scoring
|
2
|
+
module UpperCard
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def score_aces(dice)
|
6
|
+
score_sums(dice, 1)
|
7
|
+
end
|
8
|
+
|
9
|
+
def score_twos(dice)
|
10
|
+
score_sums(dice, 2)
|
11
|
+
end
|
12
|
+
|
13
|
+
def score_threes(dice)
|
14
|
+
score_sums(dice, 3)
|
15
|
+
end
|
16
|
+
|
17
|
+
def score_fours(dice)
|
18
|
+
score_sums(dice, 4)
|
19
|
+
end
|
20
|
+
|
21
|
+
def score_fives(dice)
|
22
|
+
score_sums(dice, 5)
|
23
|
+
end
|
24
|
+
|
25
|
+
def score_sixes(dice)
|
26
|
+
score_sums(dice, 6)
|
27
|
+
end
|
28
|
+
|
29
|
+
def score_sums(dice, scoring_die)
|
30
|
+
dice.select {|die| die == scoring_die}.reduce(:+)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/yahtzee.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
2
|
+
|
3
|
+
# Yahtzee is the namespace for the whole project
|
4
|
+
# it is therefore used in every file. Every file
|
5
|
+
# also need access to our error defs, so that is
|
6
|
+
# here as well.
|
7
|
+
#
|
8
|
+
module Yahtzee
|
9
|
+
VERSION = "0.0.3"
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'errors'
|
13
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'dice'
|
4
|
+
|
5
|
+
describe "A turn of dice rolling" do
|
6
|
+
subject { Yahtzee::Dice }
|
7
|
+
|
8
|
+
it "will return 5 new dice values" do
|
9
|
+
subject.roll(5).count.must_equal 5
|
10
|
+
end
|
11
|
+
|
12
|
+
it "will play a turn to a large straight" do
|
13
|
+
roll_1 = [1,2,3,6,6]
|
14
|
+
|
15
|
+
roll_2 = subject.reroll(roll_1[0..2])
|
16
|
+
roll_3 = roll_2[0..2] + [4,5]
|
17
|
+
|
18
|
+
roll_3.must_equal (1..5).to_a
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,431 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'game'
|
3
|
+
include Yahtzee
|
4
|
+
include Yahtzee::Game
|
5
|
+
|
6
|
+
describe Yahtzee::Game do
|
7
|
+
it "must play a full 1 person game" do
|
8
|
+
# Inore Dice stubs. They are only here to 'cheat'
|
9
|
+
# the outcomewhile testing the 'dsl'
|
10
|
+
|
11
|
+
score_card = ScoreCard.new
|
12
|
+
writer = ScoreCard.persist(score_card)
|
13
|
+
|
14
|
+
# Round 1: Yahtzee
|
15
|
+
Round.new do
|
16
|
+
Dice.stub :roll, [2,2,4,6,6] do
|
17
|
+
first_roll.must_equal [2,2,4,6,6]
|
18
|
+
end
|
19
|
+
|
20
|
+
Dice.stub :roll, [2,2,6] do
|
21
|
+
second_roll([2,2]).must_equal [2,2,2,2,6]
|
22
|
+
end
|
23
|
+
|
24
|
+
Dice.stub :roll, [2] do
|
25
|
+
third_roll = third_roll([2,2,2,2])
|
26
|
+
third_roll.must_equal [2,2,2,2,2]
|
27
|
+
|
28
|
+
score_card = Scoring.score(third_roll,
|
29
|
+
:yahtzee, &writer)
|
30
|
+
|
31
|
+
score_card.yahtzee.must_equal 50
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Round 2: Small Straight
|
36
|
+
Round.new do
|
37
|
+
Dice.stub :roll, [1,2,3,6,6] do
|
38
|
+
first_roll.must_equal [1,2,3,6,6]
|
39
|
+
end
|
40
|
+
|
41
|
+
Dice.stub :roll, [4,4,4] do
|
42
|
+
second_roll([1,2,3]).must_equal [1,2,3,4,4]
|
43
|
+
end
|
44
|
+
|
45
|
+
Dice.stub :roll, [2] do
|
46
|
+
third_roll = third_roll([1,2,3,4])
|
47
|
+
third_roll.must_equal [1,2,3,4,2]
|
48
|
+
|
49
|
+
score_card = Scoring.score(third_roll,
|
50
|
+
:small_straight, &writer)
|
51
|
+
|
52
|
+
score_card.small_straight.must_equal 30
|
53
|
+
score_card.yahtzee.must_equal 50
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Round 3: Aces
|
58
|
+
Round.new do
|
59
|
+
Dice.stub :roll, [1,1,1,3,6] do
|
60
|
+
first_roll.must_equal [1,1,1,3,6]
|
61
|
+
end
|
62
|
+
|
63
|
+
Dice.stub :roll, [1,4] do
|
64
|
+
second_roll([1,1,1]).must_equal [1,1,1,1,4]
|
65
|
+
end
|
66
|
+
|
67
|
+
Dice.stub :roll, [2] do
|
68
|
+
third_roll = third_roll([1,1,1,1])
|
69
|
+
third_roll.must_equal [1,1,1,1,2]
|
70
|
+
|
71
|
+
score_card = Scoring.score(third_roll,
|
72
|
+
:aces, &writer)
|
73
|
+
|
74
|
+
score_card.aces.must_equal 4
|
75
|
+
score_card.small_straight.must_equal 30
|
76
|
+
score_card.yahtzee.must_equal 50
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Round 4: Full House
|
81
|
+
Round.new do
|
82
|
+
Dice.stub :roll, [1,1,2,3,6] do
|
83
|
+
first_roll.must_equal [1,1,2,3,6]
|
84
|
+
end
|
85
|
+
|
86
|
+
Dice.stub :roll, [1,4,5] do
|
87
|
+
second_roll([1,1]).must_equal [1,1,1,4,5]
|
88
|
+
end
|
89
|
+
|
90
|
+
Dice.stub :roll, [4,4] do
|
91
|
+
third_roll = third_roll([1,1,1])
|
92
|
+
third_roll.must_equal [1,1,1,4,4]
|
93
|
+
|
94
|
+
score_card = Scoring.score(third_roll,
|
95
|
+
:full_house, &writer)
|
96
|
+
|
97
|
+
score_card.full_house.must_equal 25
|
98
|
+
score_card.aces.must_equal 4
|
99
|
+
score_card.small_straight.must_equal 30
|
100
|
+
score_card.yahtzee.must_equal 50
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Round 5: Fives
|
105
|
+
Round.new do
|
106
|
+
Dice.stub :roll, [1,5,2,5,5] do
|
107
|
+
first_roll.must_equal [1,5,2,5,5]
|
108
|
+
end
|
109
|
+
|
110
|
+
Dice.stub :roll, [4,5] do
|
111
|
+
second_roll([5,5,5]).must_equal [5,5,5,4,5]
|
112
|
+
end
|
113
|
+
|
114
|
+
Dice.stub :roll, [4] do
|
115
|
+
third_roll = third_roll([5,5,5,5])
|
116
|
+
third_roll.must_equal [5,5,5,5,4]
|
117
|
+
|
118
|
+
score_card = Scoring.score(third_roll,
|
119
|
+
:fives, &writer)
|
120
|
+
|
121
|
+
score_card.fives.must_equal 20
|
122
|
+
score_card.full_house.must_equal 25
|
123
|
+
score_card.aces.must_equal 4
|
124
|
+
score_card.small_straight.must_equal 30
|
125
|
+
score_card.yahtzee.must_equal 50
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Round 6: Four of a Kind
|
130
|
+
Round.new do
|
131
|
+
Dice.stub :roll, [4,4,4,5,5] do
|
132
|
+
first_roll.must_equal [4,4,4,5,5]
|
133
|
+
end
|
134
|
+
|
135
|
+
Dice.stub :roll, [4,5] do
|
136
|
+
second_roll([4,4,4]).must_equal [4,4,4,4,5]
|
137
|
+
end
|
138
|
+
|
139
|
+
Dice.stub :roll, [4,3] do
|
140
|
+
third_roll = third_roll([4,4,4])
|
141
|
+
third_roll.must_equal [4,4,4,4,3]
|
142
|
+
|
143
|
+
score_card = Scoring.score(third_roll,
|
144
|
+
:four_of_a_kind, &writer)
|
145
|
+
|
146
|
+
score_card.four_of_a_kind.must_equal 16
|
147
|
+
score_card.fives.must_equal 20
|
148
|
+
score_card.full_house.must_equal 25
|
149
|
+
score_card.aces.must_equal 4
|
150
|
+
score_card.small_straight.must_equal 30
|
151
|
+
score_card.yahtzee.must_equal 50
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Round 7: Bonus Yahtzee 1
|
156
|
+
Round.new do
|
157
|
+
Dice.stub :roll, [4,4,4,6,5] do
|
158
|
+
first_roll.must_equal [4,4,4,6,5]
|
159
|
+
end
|
160
|
+
|
161
|
+
Dice.stub :roll, [4,2] do
|
162
|
+
second_roll([4,4,4]).must_equal [4,4,4,4,2]
|
163
|
+
end
|
164
|
+
|
165
|
+
Dice.stub :roll, [4,4] do
|
166
|
+
third_roll = third_roll([4,4,4])
|
167
|
+
third_roll.must_equal [4,4,4,4,4]
|
168
|
+
|
169
|
+
score_card = Scoring.score(third_roll,
|
170
|
+
:bonus_yahtzee_1, &writer)
|
171
|
+
|
172
|
+
score_card.bonus_yahtzee_1.must_equal 100
|
173
|
+
score_card.four_of_a_kind.must_equal 16
|
174
|
+
score_card.fives.must_equal 20
|
175
|
+
score_card.full_house.must_equal 25
|
176
|
+
score_card.aces.must_equal 4
|
177
|
+
score_card.small_straight.must_equal 30
|
178
|
+
score_card.yahtzee.must_equal 50
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# Round 8: sixes
|
183
|
+
Round.new do
|
184
|
+
Dice.stub :roll, [6,6,6,6,5] do
|
185
|
+
first_roll.must_equal [6,6,6,6,5]
|
186
|
+
end
|
187
|
+
|
188
|
+
Dice.stub :roll, [2] do
|
189
|
+
second_roll([6,6,6,6]).must_equal [6,6,6,6,2]
|
190
|
+
end
|
191
|
+
|
192
|
+
Dice.stub :roll, [4] do
|
193
|
+
third_roll = third_roll([6,6,6,6])
|
194
|
+
third_roll.must_equal [6,6,6,6,4]
|
195
|
+
|
196
|
+
score_card = Scoring.score(third_roll,
|
197
|
+
:sixes, &writer)
|
198
|
+
|
199
|
+
score_card.sixes.must_equal 24
|
200
|
+
score_card.bonus_yahtzee_1.must_equal 100
|
201
|
+
score_card.four_of_a_kind.must_equal 16
|
202
|
+
score_card.fives.must_equal 20
|
203
|
+
score_card.full_house.must_equal 25
|
204
|
+
score_card.aces.must_equal 4
|
205
|
+
score_card.small_straight.must_equal 30
|
206
|
+
score_card.yahtzee.must_equal 50
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Round 9: threes
|
211
|
+
Round.new do
|
212
|
+
Dice.stub :roll, [3,3,2,2,1] do
|
213
|
+
first_roll.must_equal [3,3,2,2,1]
|
214
|
+
end
|
215
|
+
|
216
|
+
Dice.stub :roll, [3,2,2] do
|
217
|
+
second_roll([3,3]).must_equal [3,3,3,2,2]
|
218
|
+
end
|
219
|
+
|
220
|
+
Dice.stub :roll, [3,1] do
|
221
|
+
third_roll = third_roll([3,3,3])
|
222
|
+
third_roll.must_equal [3,3,3,3,1]
|
223
|
+
|
224
|
+
score_card = Scoring.score(third_roll,
|
225
|
+
:threes, &writer)
|
226
|
+
|
227
|
+
score_card.threes.must_equal 12
|
228
|
+
score_card.sixes.must_equal 24
|
229
|
+
score_card.bonus_yahtzee_1.must_equal 100
|
230
|
+
score_card.four_of_a_kind.must_equal 16
|
231
|
+
score_card.fives.must_equal 20
|
232
|
+
score_card.full_house.must_equal 25
|
233
|
+
score_card.aces.must_equal 4
|
234
|
+
score_card.small_straight.must_equal 30
|
235
|
+
score_card.yahtzee.must_equal 50
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# Round 10: large straight
|
240
|
+
Round.new do
|
241
|
+
Dice.stub :roll, [2,3,4,5,4] do
|
242
|
+
first_roll.must_equal [2,3,4,5,4]
|
243
|
+
end
|
244
|
+
|
245
|
+
Dice.stub :roll, [3] do
|
246
|
+
second_roll([2,3,4,5]).must_equal [2,3,4,5,3]
|
247
|
+
end
|
248
|
+
|
249
|
+
Dice.stub :roll, [6] do
|
250
|
+
third_roll = third_roll([2,3,4,5])
|
251
|
+
third_roll.must_equal [2,3,4,5,6]
|
252
|
+
|
253
|
+
score_card = Scoring.score(third_roll,
|
254
|
+
:large_straight, &writer)
|
255
|
+
|
256
|
+
score_card.large_straight.must_equal 40
|
257
|
+
score_card.threes.must_equal 12
|
258
|
+
score_card.sixes.must_equal 24
|
259
|
+
score_card.bonus_yahtzee_1.must_equal 100
|
260
|
+
score_card.four_of_a_kind.must_equal 16
|
261
|
+
score_card.fives.must_equal 20
|
262
|
+
score_card.full_house.must_equal 25
|
263
|
+
score_card.aces.must_equal 4
|
264
|
+
score_card.small_straight.must_equal 30
|
265
|
+
score_card.yahtzee.must_equal 50
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Round 11: twos
|
270
|
+
Round.new do
|
271
|
+
Dice.stub :roll, [2,2,2,5,4] do
|
272
|
+
first_roll.must_equal [2,2,2,5,4]
|
273
|
+
end
|
274
|
+
|
275
|
+
Dice.stub :roll, [2,1] do
|
276
|
+
second_roll([2,2,2]).must_equal [2,2,2,2,1]
|
277
|
+
end
|
278
|
+
|
279
|
+
Dice.stub :roll, [4] do
|
280
|
+
third_roll = third_roll([2,2,2,2])
|
281
|
+
third_roll.must_equal [2,2,2,2,4]
|
282
|
+
|
283
|
+
score_card = Scoring.score(third_roll,
|
284
|
+
:twos, &writer)
|
285
|
+
|
286
|
+
score_card.twos.must_equal 8
|
287
|
+
score_card.large_straight.must_equal 40
|
288
|
+
score_card.threes.must_equal 12
|
289
|
+
score_card.sixes.must_equal 24
|
290
|
+
score_card.bonus_yahtzee_1.must_equal 100
|
291
|
+
score_card.four_of_a_kind.must_equal 16
|
292
|
+
score_card.fives.must_equal 20
|
293
|
+
score_card.full_house.must_equal 25
|
294
|
+
score_card.aces.must_equal 4
|
295
|
+
score_card.small_straight.must_equal 30
|
296
|
+
score_card.yahtzee.must_equal 50
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
# Round 12: three of a kind
|
301
|
+
Round.new do
|
302
|
+
Dice.stub :roll, [2,2,2,5,4] do
|
303
|
+
first_roll.must_equal [2,2,2,5,4]
|
304
|
+
end
|
305
|
+
|
306
|
+
Dice.stub :roll, [1,1] do
|
307
|
+
second_roll([2,2,2]).must_equal [2,2,2,1,1]
|
308
|
+
end
|
309
|
+
|
310
|
+
Dice.stub :roll, [3,4] do
|
311
|
+
third_roll = third_roll([2,2,2])
|
312
|
+
third_roll.must_equal [2,2,2,3,4]
|
313
|
+
|
314
|
+
score_card = Scoring.score(third_roll,
|
315
|
+
:three_of_a_kind, &writer)
|
316
|
+
|
317
|
+
score_card.three_of_a_kind.must_equal 6
|
318
|
+
score_card.twos.must_equal 8
|
319
|
+
score_card.large_straight.must_equal 40
|
320
|
+
score_card.threes.must_equal 12
|
321
|
+
score_card.sixes.must_equal 24
|
322
|
+
score_card.bonus_yahtzee_1.must_equal 100
|
323
|
+
score_card.four_of_a_kind.must_equal 16
|
324
|
+
score_card.fives.must_equal 20
|
325
|
+
score_card.full_house.must_equal 25
|
326
|
+
score_card.aces.must_equal 4
|
327
|
+
score_card.small_straight.must_equal 30
|
328
|
+
score_card.yahtzee.must_equal 50
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
# Round 13: fours
|
333
|
+
Round.new do
|
334
|
+
Dice.stub :roll, [4,4,4,5,4] do
|
335
|
+
first_roll.must_equal [4,4,4,5,4]
|
336
|
+
end
|
337
|
+
|
338
|
+
Dice.stub :roll, [1] do
|
339
|
+
second_roll([4,4,4,4]).must_equal [4,4,4,4,1]
|
340
|
+
end
|
341
|
+
|
342
|
+
Dice.stub :roll, [3] do
|
343
|
+
third_roll = third_roll([4,4,4,4])
|
344
|
+
third_roll.must_equal [4,4,4,4,3]
|
345
|
+
|
346
|
+
score_card = Scoring.score(third_roll,
|
347
|
+
:fours, &writer)
|
348
|
+
|
349
|
+
score_card.fours.must_equal 16
|
350
|
+
score_card.three_of_a_kind.must_equal 6
|
351
|
+
score_card.twos.must_equal 8
|
352
|
+
score_card.large_straight.must_equal 40
|
353
|
+
score_card.threes.must_equal 12
|
354
|
+
score_card.sixes.must_equal 24
|
355
|
+
score_card.bonus_yahtzee_1.must_equal 100
|
356
|
+
score_card.four_of_a_kind.must_equal 16
|
357
|
+
score_card.fives.must_equal 20
|
358
|
+
score_card.full_house.must_equal 25
|
359
|
+
score_card.aces.must_equal 4
|
360
|
+
score_card.small_straight.must_equal 30
|
361
|
+
score_card.yahtzee.must_equal 50
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
# Round 14: chance
|
366
|
+
Round.new do
|
367
|
+
Dice.stub :roll, [4,4,4,5,4] do
|
368
|
+
first_roll.must_equal [4,4,4,5,4]
|
369
|
+
end
|
370
|
+
|
371
|
+
Dice.stub :roll, [1] do
|
372
|
+
second_roll([4,4,4,4]).must_equal [4,4,4,4,1]
|
373
|
+
end
|
374
|
+
|
375
|
+
Dice.stub :roll, [3] do
|
376
|
+
third_roll = third_roll([4,4,4,4])
|
377
|
+
third_roll.must_equal [4,4,4,4,3]
|
378
|
+
|
379
|
+
score_card = Scoring.score(third_roll,
|
380
|
+
:chance, &writer)
|
381
|
+
|
382
|
+
score_card.chance.must_equal 19
|
383
|
+
score_card.fours.must_equal 16
|
384
|
+
score_card.three_of_a_kind.must_equal 6
|
385
|
+
score_card.twos.must_equal 8
|
386
|
+
score_card.large_straight.must_equal 40
|
387
|
+
score_card.threes.must_equal 12
|
388
|
+
score_card.sixes.must_equal 24
|
389
|
+
score_card.bonus_yahtzee_1.must_equal 100
|
390
|
+
score_card.four_of_a_kind.must_equal 16
|
391
|
+
score_card.fives.must_equal 20
|
392
|
+
score_card.full_house.must_equal 25
|
393
|
+
score_card.aces.must_equal 4
|
394
|
+
score_card.small_straight.must_equal 30
|
395
|
+
score_card.yahtzee.must_equal 50
|
396
|
+
|
397
|
+
assert (score_card.to_hash.
|
398
|
+
select {|_,v| v.nil? }.
|
399
|
+
keys - ScoreCard.meta_keys).
|
400
|
+
none?, "all required fields must be filled"
|
401
|
+
end
|
402
|
+
|
403
|
+
# Collect the score from the 'upper' section
|
404
|
+
upper_scores = score_card.to_hash.select do |k,_|
|
405
|
+
ScoreCard.upper_keys.include? k
|
406
|
+
end
|
407
|
+
# Score and persist upper total
|
408
|
+
score_card = Scoring.score_upper_total(upper_scores,
|
409
|
+
&writer)
|
410
|
+
|
411
|
+
score_card.upper_total.must_equal 119
|
412
|
+
|
413
|
+
# Collect the score from the 'lower' section
|
414
|
+
lower_scores = score_card.to_hash.select do |k,_|
|
415
|
+
ScoreCard.lower_keys.include? k
|
416
|
+
end
|
417
|
+
|
418
|
+
# Merge the upper total with the lower scores
|
419
|
+
game_scores = lower_scores.merge(
|
420
|
+
upper_total: score_card.upper_total)
|
421
|
+
|
422
|
+
# Score and persist game total
|
423
|
+
score_card = Scoring.score_game_total(game_scores,
|
424
|
+
&writer)
|
425
|
+
|
426
|
+
score_card.game_total.must_equal 405
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|