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