import unittest
import Game
class TestGame(unittest.TestCase):
def setUp(self):
self.game = Game.Game()
def testGutterGameHasZeroScore(self):
for i in range(20):
self.game.roll(0)
assert self.game.score() == 0, "Score is zero"
def testGameAllOnesHasScoreOfTwenty(self):
for i in range(20):
self.game.roll(1)
assert self.game.score() == 20
def testGameThrowsExceptionWithMoreThanTwentyOneRolls(self):
try:
for i in range(22):
self.game.roll(10)
except ValueError:
pass
else:
self.fail("Expected a ValueError")
def testGameWithOneSpare(self):
self.game.roll(1)
self.game.roll(9)
self.game.roll(5)
for i in range(17):
self.game.roll(0)
assert self.game.score() == 20
def testGameWithOneStrike(self):
self.game.roll(10)
self.game.roll(1)
self.game.roll(1)
for i in range(17):
self.game.roll(0)
assert self.game.score() == 14
def testPerfectGameScores300(self):
for i in range(12):
self.game.roll(10)
assert self.game.score() == 300, "Perfect Game should score 300"
if __name__ == "__main__":
unittest.main()
My finished Game.py:
MAX_ROLLS = 21
FRAMES = 10
STRIKE = 10
SPARE = 10
class Game:
def __init__(self):
self.scoreArr = []
def roll(self, pins):
if self.numberOfRollsTaken() > MAX_ROLLS:
raise ValueError
self.scoreArr.append(pins)
def score(self):
score = 0
currentRoll = 0
frame = 0
while frame < FRAMES:
if self.scoreArr[currentRoll] == STRIKE:
score += self.scoreNextTwoBalls(currentRoll)
currentRoll += 1
elif self.frameScore(currentRoll) == SPARE:
score += self.scoreNextTwoBalls(currentRoll)
currentRoll += 2
else:
score += self.frameScore(currentRoll)
currentRoll += 2
frame = frame + 1
return score
def numberOfRollsTaken(self):
return len(self.scoreArr) +1
def scoreNextTwoBalls(self, index):
return self.scoreArr[index] + self.scoreArr[index + 1] + self.scoreArr[index + 2]
def frameScore(self, index):
return self.scoreArr[index] + self.scoreArr[index + 1]
A couple of things that I learned while doing this Bowling Game kata:
- It appears that it is a requirement for test methods to start with the word 'test' or PyUnit will not recognize them as tests that need to be run.
- A variable and a method in the same class cannot both have the same name, or at least my syntax was wrong
- The ':' at the end of class/method definitions and control statements gets me almost everytime; I cannot seem to remember that it needs to be there