|
1 | 1 | { |
2 | 2 | "#": [ |
3 | | - "Bowling is game where players roll a heavy ball to knock down pins", |
4 | | - "arranged in a triangle. Write code to keep track of the score of a", |
5 | | - "game of bowling." |
| 3 | + "Students should implement roll and score methods.", |
| 4 | + "Roll should accept a single integer.", |
| 5 | + "Score should return the game's final score, when possible", |
| 6 | + "For brevity the tests display all the rolls in an array;", |
| 7 | + "each element of the rolls array should be passed to the roll method", |
| 8 | + "The final tests define situations where the score can not be returned", |
| 9 | + "The expection for these tests is -1, indicating an error", |
| 10 | + "In these cases you should expect an error as is idiomatic for your language", |
| 11 | + "When to error is also left up to your implementation. There are two options", |
| 12 | + " - Error as soon as an invalid roll is made", |
| 13 | + " - Error when scoring a game with an invalid roll", |
| 14 | + "You can also error in both cases." |
6 | 15 | ], |
7 | | - "methods": { |
8 | | - "description": [ |
9 | | - "Check the public API is correct." |
10 | | - ], |
11 | | - "cases": [{ |
12 | | - "description": "must be able to roll with a number of pins", |
13 | | - "method": "roll", |
14 | | - "arity": 1 |
15 | | - }, { |
16 | | - "description": "must have a score", |
17 | | - "method": "score", |
18 | | - "arity": 0 |
19 | | - }] |
20 | | - }, |
21 | 16 | "score": { |
22 | 17 | "description": [ |
23 | | - "Check game can be scored correctly." |
| 18 | + "Returns the final score of a bowling game" |
24 | 19 | ], |
25 | 20 | "cases": [{ |
26 | | - "description": "should be able to score open frame", |
27 | | - "rolls": [3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
28 | | - "expected": 7 |
29 | | - }, { |
30 | | - "description": "should be able to score multiple frames", |
31 | | - "rolls": [3, 4, 2, 3, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
32 | | - "expected": 19 |
33 | | - }, { |
34 | | - "description": "should be able to score a game with all gutterballs", |
| 21 | + "description": "should be able to score a game with all zeros", |
35 | 22 | "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
36 | 23 | "expected": 0 |
37 | 24 | }, { |
38 | | - "description": "should be able to score a game with all single pin rolls", |
39 | | - "rolls": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], |
40 | | - "expected": 20 |
41 | | - }, { |
42 | | - "description": "should be able to score a game with all open frames", |
| 25 | + "description": "should be able to score a game with no strikes or spares", |
43 | 26 | "rolls": [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6], |
44 | 27 | "expected": 90 |
45 | 28 | }, { |
46 | | - "description": "should be able to score a strike not in the last frame", |
| 29 | + "description": "a spare followed by zeros is worth ten points", |
| 30 | + "rolls": [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
| 31 | + "expected": 10 |
| 32 | + }, { |
| 33 | + "description": "points scored in the roll after a spare are counted twice", |
| 34 | + "rolls": [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
| 35 | + "expected": 16 |
| 36 | + }, { |
| 37 | + "description": "consecutive spares each get a one roll bonus", |
| 38 | + "rolls": [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
| 39 | + "expected": 31 |
| 40 | + }, { |
| 41 | + "description": "a spare in the last frame gets a one roll bonus that is counted once", |
| 42 | + "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7], |
| 43 | + "expected": 17 |
| 44 | + }, { |
| 45 | + "description": "a strike earns ten points in frame with a single roll", |
| 46 | + "rolls": [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
| 47 | + "expected": 10 |
| 48 | + }, { |
| 49 | + "description": "points scored in the two rolls after a strike are counted twice as a bonus", |
47 | 50 | "rolls": [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
48 | 51 | "expected": 26 |
49 | 52 | }, { |
50 | | - "description": "should be able to score a spare not in the last frame", |
51 | | - "rolls": [5, 5, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
52 | | - "expected": 20 |
53 | | - }, { |
54 | | - "description": "should be able to score multiple strikes in a row", |
| 53 | + "description": "consecutive strikes each get the two roll bonus", |
55 | 54 | "rolls": [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
56 | 55 | "expected": 81 |
57 | 56 | }, { |
58 | | - "description": "should be able to score multiple spares in a row", |
59 | | - "rolls": [5, 5, 3, 7, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
60 | | - "expected": 32 |
61 | | - }, { |
62 | | - "description": "should allow fill balls when the last frame is a strike", |
| 57 | + "description": "a strike in the last frame gets a two roll bonus that is counted once", |
63 | 58 | "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1], |
64 | 59 | "expected": 18 |
65 | 60 | }, { |
66 | | - "description": "should allow fill ball when the last frame is a spare", |
67 | | - "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 7], |
68 | | - "expected": 17 |
| 61 | + "description": "rolling a spare with the two roll bonus does not get a bonus roll", |
| 62 | + "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3], |
| 63 | + "expected": 20 |
69 | 64 | }, { |
70 | | - "description": "should allow fill balls to be a strike", |
| 65 | + "description": "strikes with the two roll bonus do not get bonus rolls", |
71 | 66 | "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10], |
72 | 67 | "expected": 30 |
73 | 68 | }, { |
74 | | - "description": "should be able to score a perfect game", |
| 69 | + "description": "a strike with the one roll bonus after a spare in the last frame does not get a bonus", |
| 70 | + "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10], |
| 71 | + "expected": 20 |
| 72 | + }, { |
| 73 | + "description": "all strikes is a perfect game", |
75 | 74 | "rolls": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], |
76 | 75 | "expected": 300 |
77 | | - }] |
78 | | - }, |
79 | | - "validations": { |
80 | | - "description": [ |
81 | | - "Check game rules." |
82 | | - ], |
83 | | - "cases": [{ |
84 | | - "description": "should not allow rolls with negative pins", |
85 | | - "rolls": [-1], |
86 | | - "expected": "Pins must have a value from 0 to 10" |
87 | 76 | }, { |
88 | | - "description": "should not allow rolls better than strike", |
89 | | - "rolls": [11], |
90 | | - "expected": "Pins must have a value from 0 to 10" |
| 77 | + "description": "Rolls can not score negative points", |
| 78 | + "rolls": [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
| 79 | + "expected": -1 |
91 | 80 | }, { |
92 | | - "description": "should not allow two normal rolls better than strike", |
93 | | - "rolls": [5, 6], |
94 | | - "expected": "Pin count exceeds pins on the lane" |
| 81 | + "description": "A roll can not score more than 10 points", |
| 82 | + "rolls": [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
| 83 | + "expected": -1 |
95 | 84 | }, { |
96 | | - "description": "should not allow two normal rolls better than strike in last frame", |
97 | | - "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6], |
98 | | - "expected": "Pin count exceeds pins on the lane" |
| 85 | + "description": "Two rolls in a frame can not score more than 10 points", |
| 86 | + "rolls": [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
| 87 | + "expected": -1 |
99 | 88 | }, { |
100 | | - "description": "should not allow to take score at the beginning of the game", |
| 89 | + "description": "Two bonus rolls after a strike in the last frame can not score more than 10 points", |
| 90 | + "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6], |
| 91 | + "expected": -1 |
| 92 | + }, { |
| 93 | + "description": "An unstarted game can not be scored", |
101 | 94 | "rolls": [], |
102 | | - "expected": "Score cannot be taken until the end of the game" |
| 95 | + "expected": -1 |
103 | 96 | }, { |
104 | | - "description": "should not allow to take score before the game has ended", |
105 | | - "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
106 | | - "expected": "Score cannot be taken until the end of the game" |
| 97 | + "description": "An incomplete game can not be scored", |
| 98 | + "rolls": [0, 0], |
| 99 | + "expected": -1 |
107 | 100 | }, { |
108 | | - "description": "should not allow rolls after the tenth frame", |
| 101 | + "description": "A game with more than ten frames can not be scored", |
109 | 102 | "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
110 | | - "expected": "Should not be able to roll after game is over" |
| 103 | + "expected": -1 |
| 104 | + }, { |
| 105 | + "description": "bonus rolls for a strike in the last frame must be rolled before score can be calculated", |
| 106 | + "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10], |
| 107 | + "expected": -1 |
| 108 | + }, { |
| 109 | + "description": "both bonus rolls for a strike in the last frame must be rolled before score can be calculated", |
| 110 | + "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10], |
| 111 | + "expected": -1 |
111 | 112 | }, { |
112 | | - "description": "should not calculate score before fill balls have been played", |
113 | | - "rolls": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10], |
114 | | - "expected": "Score cannot be taken until the end of the game" |
| 113 | + "description": "bonus roll for a spare in the last frame must be rolled before score can be calculated", |
| 114 | + "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3], |
| 115 | + "expected": -1 |
115 | 116 | }] |
116 | 117 | } |
117 | 118 | } |
0 commit comments