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