Finished
44//
55
66export class Bowling {
7 roll() {
8 throw new Error('Remove this line and implement the function');
7 constructor() {
8 this.rolls = [];
9 this.currentRoll = 0;
10 }
11
12 roll(pins) {
13 // Edge Case: Negative pins
14 if (pins < 0) {
15 throw new Error('Negative roll is invalid');
16 }
17
18 // Edge Case: Too many pins
19 if (pins > 10) {
20 throw new Error('Pin count exceeds pins on the lane');
21 }
22
23 // Edge Case: Game already completed
24 if (this.isComplete()) {
25 throw new Error('Cannot roll after game is over');
26 }
27
28 // Simple approach: just add the roll and let isComplete() handle validation
29 this.rolls[this.currentRoll] = pins;
30 this.currentRoll++;
31
32 // Validate basic frame rules for regular frames
33 let frameCount = 0;
34 let rollIndex = 0;
35
36 while (frameCount < 9 && rollIndex < this.currentRoll) {
37 if (this.rolls[rollIndex] === 10) {
38 rollIndex += 1;
39 } else {
40 if (rollIndex + 1 < this.currentRoll) {
41 if (this.rolls[rollIndex] + this.rolls[rollIndex + 1] > 10) {
42 // Remove the invalid roll
43 this.currentRoll--;
44 this.rolls.pop();
45 throw new Error('Pin count exceeds pins on the lane');
46 }
47 }
48 rollIndex += 2;
49 }
50 frameCount++;
51 }
952 }
1053
1154 score() {
12 throw new Error('Remove this line and implement the function');
55 // Edge Case: Game not yet completed
56 if (!this.isComplete()) {
57 throw new Error('Score cannot be taken until the end of the game');
58 }
59
60 let score = 0;
61 let rollIndex = 0;
62
63 for (let frame = 0; frame < 10; frame++) {
64 if (frame < 9) {
65 // Frames 1-9
66 if (this.rolls[rollIndex] === 10) {
67 // Strike
68 score += 10 + this.rolls[rollIndex + 1] + this.rolls[rollIndex + 2];
69 rollIndex += 1;
70 } else if (this.rolls[rollIndex] + this.rolls[rollIndex + 1] === 10) {
71 // Spare
72 score += 10 + this.rolls[rollIndex + 2];
73 rollIndex += 2;
74 } else {
75 // Open frame
76 score += this.rolls[rollIndex] + this.rolls[rollIndex + 1];
77 rollIndex += 2;
78 }
79 } else {
80 // Tenth frame
81 const firstRoll = this.rolls[rollIndex];
82 const secondRoll = this.rolls[rollIndex + 1];
83
84 if (firstRoll === 10) {
85 // First roll is a strike
86 const thirdRoll = this.rolls[rollIndex + 2];
87 score += firstRoll + secondRoll + thirdRoll;
88 } else if (firstRoll + secondRoll === 10) {
89 // Spare in tenth frame
90 const thirdRoll = this.rolls[rollIndex + 2];
91 score += firstRoll + secondRoll + thirdRoll;
92 } else {
93 // Open tenth frame
94 score += firstRoll + secondRoll;
95 }
96 }
97 }
98
99 return score;
100 }
101
102 isComplete() {
103 let frameCount = 0;
104 let rollIndex = 0;
105
106 // Count frames for the first 9 frames
107 while (frameCount < 9 && rollIndex < this.currentRoll) {
108 if (this.rolls[rollIndex] === 10) {
109 // Strike
110 rollIndex += 1;
111 } else {
112 // Regular frame
113 rollIndex += 2;
114 }
115 frameCount++;
116 }
117
118 // If we haven't completed 9 frames yet
119 if (frameCount < 9) {
120 return false;
121 }
122
123 // Check if we've reached the 10th frame
124 if (rollIndex >= this.currentRoll) {
125 return false; // Haven't started 10th frame yet
126 }
127
128 // We're in the 10th frame
129 const tenthFrameStart = rollIndex;
130 const rollsInTenthFrame = this.currentRoll - tenthFrameStart;
131
132 if (rollsInTenthFrame === 0) {
133 return false;
134 }
135
136 const firstRoll = this.rolls[tenthFrameStart];
137
138 if (rollsInTenthFrame === 1) {
139 // Only one roll in 10th frame - need more
140 return false;
141 }
142
143 if (rollsInTenthFrame === 2) {
144 const secondRoll = this.rolls[tenthFrameStart + 1];
145
146 if (firstRoll === 10) {
147 // Strike in 10th frame - need 2 fill balls
148 return false;
149 } else if (firstRoll + secondRoll === 10) {
150 // Spare in 10th frame - need 1 fill ball
151 return false;
152 } else {
153 // Open frame in 10th frame - game complete
154 return true;
155 }
156 }
157
158 // 3 or more rolls in 10th frame
159 if (firstRoll === 10) {
160 // Strike - need exactly 2 fill balls
161 return rollsInTenthFrame >= 3;
162 } else {
163 // Spare - need exactly 1 fill ball
164 return rollsInTenthFrame >= 3;
165 }
13166 }
14167}
168// Handled Edge Cases: Negative pins, too many pins, game already completed, tenth frame validation, more than 10 pins in a frame, game not yet completed
Test NameStatus
two bonus rolls after a strike in the last frame cannot score more than 10 points
Fail
the second bonus rolls after a strike in the last frame cannot be a strike if the first one is not a strike
Fail
should be able to score a game with all zeros
Pass
should be able to score a game with no strikes or spares
Pass
a spare followed by zeros is worth ten points
Pass
points scored in the roll after a spare are counted twice
Pass
consecutive spares each get a one roll bonus
Pass
a spare in the last frame gets a one roll bonus that is counted once
Pass
a strike earns ten points in a frame with a single roll
Pass
points scored in the two rolls after a strike are counted twice as a bonus
Pass
consecutive strikes each get the two roll bonus
Pass
a strike in the last frame gets a two roll bonuses that is counted once
Pass
rolling a spare with the two roll bonus does not get a bonus roll
Pass
strikes with the two roll bonus do not get bonus rolls
Pass
last two strikes followed by only last bonus with non strike points
Pass
a strike with the one roll bonus after a spare in the last frame does not get a bonus
Pass
all strikes is a perfect game
Pass
rolls cannot score negative points
Pass
a roll cannot score more than 10 points
Pass
two rolls in a frame cannot score more than 10 points
Pass
bonus roll after a strike in the last frame cannot score more than 10 points
Pass
two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike
Pass
second bonus roll after a strike in the last frame cannot score more than 10 points
Pass
an unstarted game cannot be scored
Pass
an incomplete game cannot be scored
Pass
cannot roll if game already has ten frames
Pass
bonus rolls for a strike in the last frame must be rolled before score can be calculated
Pass
both bonus rolls for a strike in the last frame must be rolled before score can be calculated
Pass
bonus roll for a spare in the last frame must be rolled before score can be calculated
Pass
cannot roll after bonus roll for spare
Pass
cannot roll after bonus rolls for strike
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.