Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the final commit - Ezana Adugna #1624

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions js_lib/lib/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
const readlineSync = require('readline-sync');
const Repository = require('./repository.js');

console.log('Welcome to Bowling Scorecard!');
console.log('Enter the score for each frame (roll 1 and roll 2). Press enter after each frame.');
console.log('Enter 10 for a strike.');

function play_game() {
const repository = new Repository();

for (let frame_number = 0; frame_number < 10; frame_number++) {
if (frame_number <= 8) {
process.stdout.write(`Frame ${frame_number + 1} - Roll 1: `);
let roll1 = parseInt(readlineSync.question(''));

while (roll1 > 10) {
console.log('VALUE INVALID');
console.log('---------------------------------------------------------------------------');
console.log('ENTER VALID SCORE');
process.stdout.write(`Frame ${frame_number + 1} - Roll 1: `);
roll1 = parseInt(readlineSync.question(''));
}

if (roll1 === 10) {
repository.add_frame(roll1, 0, 0);
continue;
}

process.stdout.write('Roll 2: ');
let roll2 = parseInt(readlineSync.question(''));

while (roll1 + roll2 > 10) {
console.log('VALUE INVALID');
console.log('---------------------------------------------------------------------------');
console.log('ENTER VALID SCORE');
process.stdout.write('Roll 2: ');
roll2 = parseInt(readlineSync.question(''));
}

repository.add_frame(roll1, roll2, 0);
} else if (frame_number === 9) {
process.stdout.write(`Frame ${frame_number + 1} - Roll 1: `);
let roll1 = parseInt(readlineSync.question(''));

while (roll1 > 10) {
console.log('VALUE INVALID');
console.log('---------------------------------------------------------------------------');
console.log('ENTER VALID SCORE');
process.stdout.write(`Frame ${frame_number + 1} - Roll 1: `);
roll1 = parseInt(readlineSync.question(''));
}

process.stdout.write('Roll 2: ');
let roll2 = parseInt(readlineSync.question(''));

if (roll1 !== 10) {
while (roll1 + roll2 > 10) {
console.log('VALUE INVALID');
console.log('---------------------------------------------------------------------------');
console.log('ENTER VALID SCORE');
process.stdout.write('Roll 2: ');
roll2 = parseInt(readlineSync.question(''));
}
} else if (roll1 === 10) {
while (roll2 > 10) {
console.log('VALUE INVALID');
console.log('---------------------------------------------------------------------------');
console.log('ENTER VALID SCORE');
process.stdout.write('Roll 2: ');
roll2 = parseInt(readlineSync.question(''));
}
}

if (roll1 + roll2 >= 10) {
process.stdout.write('Roll 3: ');
const roll3 = parseInt(readlineSync.question(''));

while (roll3 > 10) {
console.log('VALUE INVALID');
console.log('---------------------------------------------------------------------------');
console.log('ENTER VALID SCORE');
process.stdout.write('Roll 3: ');
roll3 = parseInt(readlineSync.question(''));
}

repository.add_frame(roll1, roll2, roll3);
} else {
repository.add_frame(roll1, roll2, 0);
}
}
}
}

play_game();
15 changes: 15 additions & 0 deletions js_lib/lib/repository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Repository {
constructor() {
this._frames = [];
}

add_frame(roll1, roll2, roll3) {
this._frames.push([roll1, roll2, roll3]);
}

get frames() {
return this._frames;
}
}

module.exports = Repository;
23 changes: 23 additions & 0 deletions js_lib/lib/repository.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const Repository = require('./repository');

describe('Repository', () => {
let repository;

beforeEach(() => {
repository = new Repository();
});

it('should add frames correctly', () => {
repository.add_frame(1, 2, 3);
repository.add_frame(4, 5, 6);

expect(repository.frames).toEqual([[1, 2, 3], [4, 5, 6]]);
});

it('should return frames correctly', () => {
repository.add_frame(1, 2, 3);
repository.add_frame(4, 5, 6);

expect(repository.frames).toEqual([[1, 2, 3], [4, 5, 6]]);
});
});
70 changes: 70 additions & 0 deletions js_lib/lib/scoreCalculator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
class ScoreCalculator {
static calculate_score(frames) {
let score = 0;
let frame_index = 0;
let consecutive_strikes = 0;

for (let frame_number = 0; frame_number < 10; frame_number++) {
const [roll1, roll2, roll3] = frames[frame_index] || [0, 0, 0];

if (frame_number === 9) {
score += roll1 + roll2;

if (roll1 === 10 || roll1 + roll2 === 10) {
const roll3 = frames[frame_index][2] || 0;
score += roll3;
}
} else if (roll1 === 10) {
score += 10 + ScoreCalculator.strike_bonus(frame_index, frames);
consecutive_strikes += 1;
frame_index += 1;
} else if (roll1 + roll2 === 10) {
score += 10 + ScoreCalculator.spare_bonus(frame_index, frames);
consecutive_strikes = 0;
frame_index += 1;
} else {
score += roll1 + roll2;
consecutive_strikes = 0;
frame_index += 1;
}

if (consecutive_strikes >= 2) {
score += roll1;
}
}

return score;
}

static strike_bonus(frame_index, frames) {
const next_frame = frames[frame_index + 1] || [0, 0, 0];
const next_next_frame = frames[frame_index + 2] || [0, 0, 0];
const [next_roll1, next_roll2] = next_frame;

if (next_roll1 === 10) {
if (next_next_frame[0] === 10) {
return next_next_frame[0];
} else {
return 10 + next_next_frame[0] + next_next_frame[1];
}
} else {
return next_roll1 + next_roll2;
}
}


static spare_bonus(frame_index, frames) {
const next_frame = frames[frame_index + 1] || [0, 0, 0];
const [next_roll1] = next_frame;

if (next_roll1 === 10) {
return 10;
} else {
return next_roll1;
}
}
}

module.exports = ScoreCalculator;


98 changes: 98 additions & 0 deletions js_lib/lib/scoreCalculator.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const ScoreCalculator = require('./scoreCalculator');

describe('ScoreCalculator', () => {
it('should calculate score correctly with all strikes', () => {
const frames = [
[10, 0],
[10, 0],
[10, 0],
[10, 0],
[10, 0],
[10, 0],
[10, 0],
[10, 0],
[10, 0],
[10, 10, 10],
];

const score = ScoreCalculator.calculate_score(frames);

expect(score).toBe(300);
});

it('should calculate score correctly with all spares', () => {
const frames = [
[5, 5, 0],
[5, 5, 0],
[5, 5, 0],
[5, 5, 0],
[5, 5, 0],
[5, 5, 0],
[5, 5, 0],
[5, 5, 0],
[5, 5, 0],
[5, 5, 5],
];

const score = ScoreCalculator.calculate_score(frames);

expect(score).toBe(150);
});

it('calculates the score for a game without strikes or spares', () => {
const frames = [
[2, 3],
[4, 5],
[6, 3],
[1, 4],
[5, 2],
[3, 6],
[4, 2],
[1, 3],
[5, 3],
[2, 1],
];

const score = ScoreCalculator.calculate_score(frames);

expect(score).toBe(65);
});

it('should calculate score correctly with a mix of strikes, spares, and open frames', () => {
const frames = [
[10, 0, 0],
[7, 3, 0],
[9, 0, 0],
[0, 10, 0],
[10, 0, 0],
[10, 0, 0],
[2, 3, 0],
[8, 1, 0],
[10, 0, 0],
[10, 9, 0],
];

const score = ScoreCalculator.calculate_score(frames);

expect(score).toBe(167);
});

it('should calculate the score for a game with strikes and spares and the thrid roll on the tenth frame', () => {
const frames = [
[10, 0, 0],
[7, 3, 0],
[9, 0, 0],
[0, 10, 0],
[10, 0, 0],
[10, 0, 0],
[2, 3, 0],
[8, 1, 0],
[10, 0, 0],
[10, 10, 10],
];

const score = ScoreCalculator.calculate_score(frames);

expect(score).toBe(179);
});
});
Loading