Skip to content

Instantly share code, notes, and snippets.

@arlk
Last active April 2, 2016 02:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arlk/8e676d713e9718e722fca902fe2eae85 to your computer and use it in GitHub Desktop.
Save arlk/8e676d713e9718e722fca902fe2eae85 to your computer and use it in GitHub Desktop.
__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