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

[WIP] Implement exercise bowling #790

Merged
merged 30 commits into from
Jan 23, 2018
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c382caa
Implement exercise bowling
thecouchcoder Oct 10, 2017
ad21e2a
bowling: created the files
thecouchcoder Oct 10, 2017
1e16f9e
bowling: implemented test for an all 0 game
thecouchcoder Oct 11, 2017
5b29088
bowling: passing all zeros test
thecouchcoder Oct 11, 2017
028ce96
bowling tested and implemented logic for spares
thecouchcoder Oct 11, 2017
5b61ca4
bowling: bonus roll implemented
thecouchcoder Oct 11, 2017
4527240
bowling: heavily refactored code. Now passing 9 tests
thecouchcoder Oct 11, 2017
1785b1f
bowling: tested and implemeneted first 14 tests
thecouchcoder Oct 12, 2017
73c311f
fix travis issues with line length
thecouchcoder Oct 12, 2017
3eb75d1
bowling: setup config
thecouchcoder Oct 12, 2017
9fb30a7
bowling: passing 19 tests
thecouchcoder Oct 13, 2017
090300d
bowling: fixed error in config.json
thecouchcoder Oct 13, 2017
ff70fd5
bowling: heavily refactoring code to implement frame logic during rol…
thecouchcoder Oct 13, 2017
293bf44
bowling: still alot of refactoring going on and alot is broken
thecouchcoder Oct 13, 2017
0cd0fc1
bowling: still refactoring and still alot of errors, but closer
thecouchcoder Oct 13, 2017
3f1777e
bowling: nearly done refactoring
thecouchcoder Oct 13, 2017
55c3c6c
bowling: finally back to passing all tests like before refactor
thecouchcoder Oct 14, 2017
53b6e52
bowling: added a few more tests and cleaned up after refactor
thecouchcoder Oct 14, 2017
be6cf1c
bowling: passes all tests
thecouchcoder Oct 14, 2017
91d1cf0
bowling: fixing travis issue
thecouchcoder Oct 14, 2017
6034a95
bowling: fixes as requested
thecouchcoder Nov 29, 2017
511732a
bowling: fixes as requested
thecouchcoder Nov 29, 2017
5298cbb
bowling: Travis fixes
thecouchcoder Nov 29, 2017
d3c349d
bowling: Travis fixes
thecouchcoder Nov 29, 2017
833dce2
bowling: Travis fixes
thecouchcoder Nov 29, 2017
1cf050f
bowling: Travis fixes
thecouchcoder Nov 29, 2017
5f8b980
bowling: fixes as requested
thecouchcoder Dec 1, 2017
dca0f0e
Merge branch 'master' into bowling
cmccandless Jan 15, 2018
95b7666
Merge branch 'master' into bowling
cmccandless Jan 19, 2018
de5a2bb
Merge branch 'master' into bowling
cmccandless Jan 23, 2018
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
1 change: 0 additions & 1 deletion exercises/bowling/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
.cache/
11 changes: 11 additions & 0 deletions exercises/bowling/bowling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@


class BowlingGame(object):
def __init__(self):
pass

def roll(self, pins):
pass

def score(self):
pass
137 changes: 34 additions & 103 deletions exercises/bowling/bowling_test.py
Original file line number Diff line number Diff line change
@@ -1,258 +1,189 @@
# Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with the other exercises, could you please move this line like so:

from bowling import BowlingGame


# Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.1

class BowlingTests(unittest.TestCase):
...

Please note the number of blank lines before and after.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

import unittest

from example import BowlingGame
from bowling import BowlingGame


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please also leave a comment stating what version of canonical-data.json the tests were adopted as discussed in #784 if aplicable?
The format is:

# Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0

class BowlingTests(unittest.TestCase):
def setUp(self):
self.game = BowlingGame()

def roll(self, rolls):
[self.game.roll(roll) for roll in rolls]

def roll_and_score(self, rolls):
self.roll(rolls)
return self.game.score()

def test_should_be_able_to_score_a_game_with_all_zeros(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 0)

def test_should_be_able_to_score_a_game_with_no_strikes_or_spares(self):
rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 90)

def test_a_spare_follow_by_zeros_is_worth_ten_points(self):
rolls = [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 10)

def test_points_scored_in_the_roll_after_a_spare_are_counted_twice(self):
rolls = [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 16)

def test_consecutive_spares_each_get_a_one_roll_bonus(self):
rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 31)

def test_last_frame_spare_gets_bonus_roll_that_is_counted_twice(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 17)

def test_a_strike_earns_ten_points_in_a_frame_with_a_single_roll(self):
rolls = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 10)

def test_two_rolls_points_after_strike_are_counted_twice(self):
rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 26)

def test_consecutive_stikes_each_get_the_two_roll_bonus(self):
rolls = [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 81)

def test_strike_in_last_frame_gets_two_roll_bonus_counted_once(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10, 7, 1]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 18)

def test_rolling_spare_with_bonus_roll_does_not_get_bonus(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 10, 7, 3]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 20)

def test_strikes_with_the_two_bonus_rolls_do_not_get_bonus_rolls(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
10, 10]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 30)

def test_strike_with_bonus_after_spare_in_last_frame_gets_no_bonus(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
3, 10]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 20)

def test_all_strikes_is_a_perfect_game(self):
rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 300)

def test_rolls_cannot_score_negative_points(self):
self.game = BowlingGame()

self.assertRaises(ValueError, self.game.roll, -11)

def test_a_roll_cannot_score_more_than_10_points(self):
self.game = BowlingGame()

self.assertRaises(ValueError, self.game.roll, 11)

def test_two_rolls_in_a_frame_cannot_score_more_than_10_points(self):
self.game = BowlingGame()
self.game.roll(5)

self.assertRaises(ValueError, self.game.roll, 6)

def test_bonus_after_strike_in_last_frame_cannot_score_more_than_10(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
self.roll(rolls)

self.assertRaises(ValueError, self.game.roll, 11)

def test_bonus_aft_last_frame_strk_can_be_more_than_10_if_1_is_strk(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
10, 6]
self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
score = self.game.score()
score = self.roll_and_score(rolls)

self.assertEqual(score, 26)

def test_bonus_aft_last_frame_strk_cnt_be_strk_if_first_is_not_strk(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6]
self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
self.roll(rolls)

self.assertRaises(ValueError, self.game.roll, 10)

def test_an_incomplete_game_cannot_be_scored(self):
rolls = [0, 0]
self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
self.roll(rolls)

self.assertRaises(IndexError, self.game.score)

def test_cannot_roll_if_there_are_already_ten_frames(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
self.roll(rolls)

self.assertRaises(IndexError, self.game.roll, 0)

def test_bonus_rolls_for_strike_must_be_rolled_before_score_is_calc(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
self.roll(rolls)

self.assertRaises(IndexError, self.game.score)

def test_both_bonuses_for_strike_must_be_rolled_before_score(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
self.roll(rolls)

self.assertRaises(IndexError, self.game.score)

def test_bonus_rolls_for_spare_must_be_rolled_before_score_is_calc(self):
rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3]

self.game = BowlingGame()

for roll in rolls:
self.game.roll(roll)
self.roll(rolls)

self.assertRaises(IndexError, self.game.score)

Expand Down
Loading