-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathleaderboard.py
141 lines (116 loc) · 4.48 KB
/
leaderboard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import traceback
import easygui
FILE_PATH = "leaderboard.txt"
def leaderboard_append(name, points):
""" Append a new record to the leaderboard
Input: name (str) - the name of the player
points (int) - the number of points the player has
Output: None
Time Complexity worst & average case: O(1) """
name = ''.join([char for char in name if char != ' '])
try:
with open(FILE_PATH, 'a') as file:
# Add new name score pair to the file
file.write(f"{name} {points}\n")
except Exception as e:
print(f"Error reading leaderboard: {e}, {traceback.print_exc()}")
def leaderboard_read():
""" Read the leaderboard
Input: None
Output: records (list) - a list of records
Time Complexity worst & average case: O(n) """
try:
# Creating an empty list to store the records
records = []
with open(FILE_PATH, 'r') as file:
for line in file:
# We split each line into name and points using whitespace as a separator
name, points = line.strip().split()
records.append((name, int(points)))
return records
except Exception as e:
print(f"Error reading leaderboard: {e}, {traceback.print_exc()}")
return []
def merge_sort(records) -> list:
""" Sort a list of records using merge sort
Input: records (list) - a list of records
Output: sorted_records (list) - a sorted list of records
Time Complexity worst & average case: O(n log n) """
if len(records) <= 1:
return records
# Split the list in two
mid = len(records) // 2
left_half = records[:mid]
right_half = records[mid:]
# Recursively sort each half
left_half = merge_sort(left_half)
right_half = merge_sort(right_half)
# Merge the halves
sorted_records = merge(left_half, right_half)
return sorted_records
def merge(left, right) -> list:
""" Merge two sorted lists
Input: left (list) - the left half
right (list) - the right half
Output: merged (list) - the merged list
Time Complexity: O(n) """
merged = []
i = j = 0
# Compare the elements of the two halves
while i < len(left) and j < len(right):
if left[i][1] < right[j][1]:
merged.append(left[i])
i += 1
else:
merged.append(right[j])
j += 1
# Add the remaining elements
merged.extend(left[i:])
merged.extend(right[j:])
return merged
class LeaderboardUI:
def __init__(self):
self.leaderboard = []
def populate_leaderboard(self) -> None:
""" Populate the leaderboard with the records
Input: None
Output: None
Time Complexity worst & average case: O(n log n) we take n* because of merge sort"""
records = leaderboard_read()
sorted_records = merge_sort(records)
leaderboard_text = "\n".join([f"{index + 1}. {record[0]} - {record[1]} points" for index, record in enumerate(sorted_records)])
if leaderboard_text == "":
leaderboard_text = "No records yet! Play a game to add a record."
easygui.msgbox(leaderboard_text, "Leaderboard")
def submit_score(self, points) -> None:
""" Submit the score to the leaderboard
Input: points (int) - the number of points the player has
Output: None
Time Complexity worst & average case: O(1)"""
name = easygui.enterbox("Enter your name:")
if name:
leaderboard_append(name, points)
self.populate_leaderboard()
def quit_leaderboard(self) -> None:
""" Function to quit the leaderboard
Input: None
Output: None
Time Complexity worst & average case: O(1)"""
easygui.msgbox("Goodbye! :)")
quit()
def show_leaderboard_options(self, points, game_over) -> None:
""" Show options for the leaderboard
Input: None
Output: None
Time Complexity worst & average case: O(1)"""
choices = ["Submit Score", "View Leaderboard", "Quit"]
choice = easygui.buttonbox("Select an option", "Leaderboard Options", choices=choices)
if choice == "Submit Score":
if game_over == False:
easygui.msgbox("You can't submit a score if the game is not over!")
else:
self.submit_score(points)
elif choice == "View Leaderboard":
self.populate_leaderboard()
elif choice == "Quit":
self.quit_leaderboard()