Last active
April 2, 2016 02:34
-
-
Save arlk/8e676d713e9718e722fca902fe2eae85 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__author__='Arun Lakshmanan' | |
class bowlingScore(object): | |
""" This class generates the score for a bowling game based on the following rules: | |
-- 10 frames of 2 rolls | |
-- strike: 10 points 1st roll + points from next 2 rolls | |
-- spare: 10 points 1st and 2nd rolls + points from next roll | |
-- 10th frame may have 3 rolls for spare, strike bonus | |
Example: | |
>>fooList = [3, 5, 10, 3, 7, 8, 1, 10, 10, 6, 2, 5, 4, 7, 3, 1, 6] | |
>>fooGame = bowlingScore(fooList) | |
>>fooGame.calcScore() | |
""" | |
def __init__(self, pins): | |
self.game = pins | |
self.frameCounter = 1 | |
self.roll = 1 | |
self.score = 0 | |
def _addFrame(self): | |
""" Moves to new frame and sets current roll to 1 """ | |
self.frameCounter += 1 | |
self.roll = 1 | |
def _checkList(self): | |
""" Checks validity of the list of scoring values """ | |
if not isinstance(self.game, list): | |
raise ValueError('Please input scoring as a list ..') | |
isInt = all(isinstance(val, int) for val in self.game) | |
isValid = not any(map(lambda x: False if x>=0 and x<=10 else True, self.game)) | |
if not(isValid and isInt): | |
raise ValueError('Invalid values in list ..') | |
def _strikeScore(self,roll): | |
""" If a valid strike is acheived then adds bonus points to current roll """ | |
if self.game[roll] == 10: | |
if self.roll != 1: | |
raise ValueError('Invalid values in list ..') | |
self.score += self.game[roll] + self.game[roll+1] + self.game[roll+2] | |
self._addFrame() | |
return True | |
return False | |
def _spareScore(self,roll): | |
""" If a valid spare is acheived then adds bonus points to current roll """ | |
if self.game[roll-1] + self.game[roll] == 10: | |
self.score += self.game[roll+1] | |
def _lastFrame(self,roll): | |
""" Adds points to score from last frame. It also checks for the validity of a bonus roll """ | |
if (self.game[roll] + self.game[roll+1] == 10) or (self.game[roll] == 10) or (self.game[roll+1] == 10): | |
self.score += self.game[roll] + self.game[roll+1] + self.game[roll+2] | |
remaining = len(self.game) - roll - 3 | |
else: | |
self.score += self.game[roll] + self.game[roll+1] | |
remaining = len(self.game) - roll - 2 | |
if remaining: | |
raise ValueError('Invalid values in list ..') | |
self._addFrame() | |
def calcScore(self): | |
""" Calculate score of game based on the rules of a standard bowling game """ | |
self._checkList() | |
try: | |
for i in range(len(self.game)): | |
if self.frameCounter > 10: | |
raise ValueError('Too many scoring values ..') | |
if self.frameCounter == 10: | |
self._lastFrame(i) | |
break | |
if self._strikeScore(i): | |
continue | |
if self.roll == 1: | |
self.score += self.game[i] | |
self.roll += 1 | |
continue | |
if self.roll == 2: | |
if self.game[i] + self.game[i-1] > 10: | |
raise ValueError('Invalid values in list ..') | |
self.score += self.game[i] | |
self._spareScore(i) | |
self._addFrame() | |
continue | |
except IndexError: | |
print ('Incomplete scoring data..') | |
if self.frameCounter <= 10 and self.roll < 2: | |
raise IndexError('Incomplete scoring data..') | |
if __name__ == '__main__': | |
listPins = [3, 5, 10, 3, 7, 8, 1, 10, 10, 6, 2, 5, 4, 7, 3, 1, 6] | |
myGame = bowlingScore(listPins) | |
myGame.calcScore() | |
print "Total Score: ", myGame.score |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment