#Colors.
viridis = plt.get_cmap('viridis_r')
newcolors = viridis(np.linspace(0, 1, 181))
def getScore(game) :
"""
Return the score given bowling pins knocked down over bowls and frames.
Parameters:
game : A list of 12 lists.
Each of the first 10 lists is an ordered pair representing the two bowls in a frame.
Last two lists are single numbers.
Returns:
Total score.
"""
score = 0
for i in range(10) :
frame = sum(game[i])
#Get points for current frame.
frame_score = frame
#If strike [10, 0] or spare [n, 10-n].
if frame == 10 :
#Add the next bowl.
frame_score += game[i+1][0]
#Strike for i?
if game[i][0] == 10 :
#Strike for i+1?
if game[i+1][0] == 10 :
#Add i+2 (Could be a strike?) :
frame_score += game[i+2][0]
#Non-strike for i+1 and not last frame.
elif i != 9 :
#Add the second bowl (Could be a spare for i+1?) :
frame_score += game[i+1][1]
#Non-strike for i+1 and last frame.
elif i == 9 :
#Add the second bowl (Could be a spare for i+1?) :
frame_score += game[i+2][0]
score += frame_score
return(score)
def getPins(game) :
"""
Return the number of pins.
Parameters:
game : A list of 12 lists. Each of the 12 lists is an ordered pair representing a frame.
Returns:
Total pins dropped.
"""
pins = 0
for i in range(12) :
pins += sum(game[i])
return(pins)
def createMinMax(p) :
"""
Return the minimum scoring and maximum scoring game given a number of pins.
Parameters:
p : number of pins dropped in a game.
Returns:
List of two scores.
The first is the min and the second is the max.
"""
mins = []
maxs = []
#12 frames to add.
for i in range(12) :
#First ten frames have two bowls each.
if i < 10 :
if p > 10 :
#Append a spare.
mins.append([0, 10])
#Append a strike.
maxs.append([10, 0])
p = p-10
else :
#Append remaining.
mins.append([0, p])
#Append remaining.
maxs.append([p, 0])
p = 0
#11th Frame.
elif i == 10 :
if p > 10 :
#Append a spare.
mins.append([10])
#Append a strike.
maxs.append([10])
p = p-10
else :
#Append remaining.
mins.append([p])
#Append remaining.
maxs.append([p])
p = 0
#12th Frame.
elif i == 11 :
#Change frame 9 spare to strike to allow frame 11 to happen!
if p > 0 :
mins[9] = [10, 0]
#Append remaining.
mins.append([p])
#Append remaining.
maxs.append([p])
return(mins, maxs)
def createDF() :
"""
Create the main dataframe.
Parameters:
None.
Returns:
df : 180 rows, columns are Pins, Min_Score, Max_Score, and Difference.
"""
mins = []
maxs = []
for i in range(121) :
a, b = (createMinMax(i))
mins.append(getScore(a))
maxs.append(getScore(b))
df = pd.DataFrame({'Pins': list(range(121)),
'Min_Score': mins,
'Max_Score': maxs})
df['Difference'] = df['Max_Score'] - df['Min_Score']
return(df)
def diffRegion(df, p) :
"""
Create the trapezoid of width 1 between min and max scores for a particular number of pins.
Parameters:
df - Main dataframe.
p - # of pins dropped, or index of df.
Returns:
Polygon patch that is a trapezoid of width 1, filled by color representing the difference.
"""
#Previous pin data
data1 = df.loc[p-1]
#Current pin data
data2 = df.loc[p]
#Color represents difference.
c = MC.to_hex(newcolors[data2[3]])
return(mpP([(data1[0], data1[1]),
(data1[0], data1[2]),
(data2[0], data2[2]),
(data2[0], data2[1])],
edgecolor = c,
facecolor = c,
lw = 1,
zorder = 2))