-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrounding_game.py
197 lines (158 loc) · 7.77 KB
/
rounding_game.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
import tkinter as tk
import random
# import emoji
# Initialize score tracking
correct_count = 0
total_count = 0
score_update = True
time_delay = 3000
# Function to generate a random integer and a random rounding base
def generate_number_and_base():
global number, rounding_base, correct_answer
number = random.randint(1, 100000)
rounding_base = random.choice([10, 100, 1000, 10000]) # Randomly select the rounding base
correct_answer = logical_round(number, rounding_base)
number_label.config(text=f"Number: {number:,}") # Format number with commas
base_label.config(text=f"Round to the nearest: {rounding_base:,}")
hint_label.config(text="") # Clear previous hint
canvas.delete("all") # Clear previous number line
generate_choices()
# Function to logically round the number
def logical_round(num, base):
return round(num / base) * base
# Function to generate multiple choice answers
def generate_choices():
global correct_answer, rounding_base
# Generate the correct answer
correct_answer = logical_round(number, rounding_base)
# Generate a wrong answer by rounding to a different base
different_base = random.choice([b for b in [10, 100, 1000, 10000] if b != rounding_base])
wrong_answer_different_base = logical_round(number, different_base)
# Generate a wrong answer by rounding incorrectly to the same base (floor or ceiling)
wrong_answer_incorrect_rounding = correct_answer + random.choice([-rounding_base, rounding_base])
if wrong_answer_incorrect_rounding < 0:
wrong_answer_incorrect_rounding = correct_answer + rounding_base
# Ensure all answers are distinct
choices = [correct_answer, wrong_answer_different_base, wrong_answer_incorrect_rounding]
if len(set(choices)) < 3: # Ensure uniqueness
choices[2] = wrong_answer_different_base + 10 # Modify one of the incorrect answers if needed
random.shuffle(choices) # Shuffle the choices
# Assign the choices to buttons
button1.config(text=f"{choices[0]:,}", command=lambda: check_answer(choices[0]))
button2.config(text=f"{choices[1]:,}", command=lambda: check_answer(choices[1]))
button3.config(text=f"{choices[2]:,}", command=lambda: check_answer(choices[2]))
# Function to check the user's answer and update score
def check_answer(user_input):
global correct_count, total_count, score_update
disable_buttons()
if user_input == correct_answer:
hint_label.config(text=f"Correct! The correct rounded value is {correct_answer:,}.", fg="green")
root.after(time_delay, lambda: hint_label.config(text="")) # Clear hint after 5 seconds
root.after(time_delay, generate_number_and_base) # Wait 5 seconds, then generate a new number and base for the next round
root.after(time_delay, lambda: enable_buttons()) # Re-enable buttons after 3 seconds
if score_update:
total_count += 1
correct_count += 1
update_score() # Update score and percentage display
question_counter_label.config(text=f"Answered: {total_count}")
score_update = True
else:
hint_label.config(text=f"Incorrect. Look at the number line below to help you!", fg="red")
draw_number_line() # Show the number line
enable_buttons()
if score_update:
total_count += 1
update_score() # Update score and percentage display
score_update = False
# Function to provide hints by drawing a pretty number line
def draw_number_line():
canvas.delete("all") # Clear the canvas
start = correct_answer - 5 * rounding_base # Start 5 increments before the original number
end = correct_answer + 5 * rounding_base # End 5 increments after the original number
number_range = list(range(start, end + rounding_base, rounding_base)) # List of numbers for the number line
# Draw the line
canvas.create_line(50, 50, 1150, 50, width=2)
# Draw dots and numbers
for i, num in enumerate(number_range):
x_pos = 50 + (i * 100) # Spread dots evenly along the line
canvas.create_oval(x_pos-5, 45, x_pos+5, 55, fill="blue") # Draw the dot
canvas.create_text(x_pos, 70, text=f"{num:,}", font=("Helvetica", 10)) # Display the number
# Draw a red tick at the actual number
if start <= number <= end:
# Calculate position of actual number on the line
num_position = (number - start) / (end - start) * 1100
actual_x_pos = num_position
canvas.create_line(actual_x_pos, 30, actual_x_pos, 70, fill="red", width=3) # Mark the actual number
# Function to update and display the score percentage with emojis
def update_score():
if total_count > 0:
percentage = (correct_count / total_count) * 100
score_text = f"Score: {percentage:.2f}% "
if percentage < 50:
score_label.config(fg="red")
elif percentage < 90:
score_label.config(fg="orange")
elif percentage < 95:
score_label.config(fg="lightgreen")
else:
score_label.config(fg="darkgreen")
score_label.config(text=score_text)
# Check for prize condition
if (total_count == prize_threshold and percentage > 90) or (total_count == 2*prize_threshold and percentage > 70):
show_prize_popup()
def show_prize_popup():
prize_popup = tk.Toplevel(root)
prize_popup.title("Well Done Madeleine!")
prize_popup.geometry("800x100")
prize_popup.config(bg="#F0F0F0")
message_label = tk.Label(prize_popup, text="Congratulations for your hard work! You get a prize! ", font=("Helvetica", 12), bg="#F0F0F0")
message_label.pack(pady=20, padx=20)
# Disable main window interaction until popup is closed
root.wait_window(prize_popup)
def enable_buttons():
button1.config(state=tk.NORMAL)
button2.config(state=tk.NORMAL)
button3.config(state=tk.NORMAL)
def disable_buttons():
button1.config(state=tk.DISABLED)
button2.config(state=tk.DISABLED)
button3.config(state=tk.DISABLED)
# Setup the main window
root = tk.Tk()
root.title("Rounding Game")
root.geometry("1500x600")
root.config(bg="#F0F0F0")
# Labels and widgets
number_label = tk.Label(root, text="", font=("Helvetica", 16), bg="#F0F0F0")
number_label.pack(pady=10)
base_label = tk.Label(root, text="", font=("Helvetica", 12), bg="#F0F0F0")
base_label.pack(pady=10)
entry_label = tk.Label(root, text="Choose the correct rounded value:", font=("Helvetica", 12), bg="#F0F0F0")
entry_label.pack(pady=10)
# Frame to hold the buttons side by side
button_frame = tk.Frame(root, bg="#F0F0F0")
button_frame.pack(pady=5)
# Multiple-choice buttons
button1 = tk.Button(button_frame, text="", font=("Helvetica", 12), bg="#0a95e6", fg="white")
button1.pack(side="left", padx=10)
button2 = tk.Button(button_frame, text="", font=("Helvetica", 12), bg="#0a95e6", fg="white")
button2.pack(side="left", padx=10)
button3 = tk.Button(button_frame, text="", font=("Helvetica", 12), bg="#0a95e6", fg="white")
button3.pack(side="left", padx=10)
# Hint label to display feedback
hint_label = tk.Label(root, text="", font=("Helvetica", 12), bg="#F0F0F0", fg="red")
hint_label.pack(pady=10)
# Canvas for the number line
canvas = tk.Canvas(root, width=1200, height=100, bg="#F0F0F0")
canvas.pack(pady=10)
# Score label at the bottom right
score_label = tk.Label(root, text="Score: 0%", font=("Helvetica", 12), bg="#F0F0F0", fg="black")
score_label.pack(pady=10, padx=10, anchor="se")
# Create a label for the question counter
question_counter_label = tk.Label(root, text="Answered: 0", font=("Helvetica", 14), bg="#F0F0F0")
question_counter_label.pack(pady=10, padx=10, anchor="sw")
prize_threshold = random.randint(35, 75)
# Start the game by generating a random number and rounding base
generate_number_and_base()
# Run the tkinter loop
root.mainloop()