-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdice_roller.py
More file actions
109 lines (81 loc) · 3.25 KB
/
Copy pathdice_roller.py
File metadata and controls
109 lines (81 loc) · 3.25 KB
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
import customtkinter as ctk
import random
import matplotlib.pyplot as plt
# Set up the main app window
ctk.set_appearance_mode("dark") # Options: "light" or "dark"
ctk.set_default_color_theme("blue") # You can try "green" or "dark-blue" too
app = ctk.CTk()
app.title("Dice Roller Sim")
app.geometry("420x420")
# --- Widgets ---
ctk.CTkLabel(app, text="Select dice types and quantities:").pack(pady=(10, 10))
# --- Dice selection grid ---
frame = ctk.CTkFrame(app)
frame.pack(pady=10)
dice_types = ["d4", "d6", "d8", "d10", "d12", "d20"]
dice_controls = {}
for dice in dice_types:
# Each dice gets a checkbox + entry box
var = ctk.BooleanVar(value=False)
count_var = ctk.StringVar(value="1")
row = ctk.CTkFrame(frame)
row.pack(fill="x", pady=3)
ctk.CTkCheckBox(row, text=dice, variable=var, width=80).pack(side="left", padx=(20, 10))
ctk.CTkEntry(row, textvariable=count_var, width=60, placeholder_text="1").pack(side="left")
ctk.CTkLabel(row, text="dice").pack(side="left")
dice_controls[dice] = {"selected": var, "count": count_var}
trial_var = ctk.StringVar(value="1000")
trial_row = ctk.CTkFrame(frame)
trial_row.pack(fill="x", pady=3)
ctk.CTkLabel(trial_row, text="Trials:").pack(side="left", padx=5)
ctk.CTkEntry(trial_row, textvariable=trial_var, width=60, placeholder_text="1000").pack(side="left")
def simulate_rolls(selections, trials=1000):
results = {}
for _ in range(trials):
total = 0
for dice, count in selections:
sides = int(dice[1:])
total += sum(random.randint(1, sides) for _ in range(count))
results[total] = results.get(total, 0) + 1
return results
# --- Plotting the dice results ---
def plot_results(results, selections, trials):
totals = sorted(results.keys())
freqs = [results[t] for t in totals]
plt.figure(figsize=(8, 4))
plt.bar(totals, freqs, width=0.9, color="#4E9AF1")
dice_title = ""
for die, count in selections:
dice_title += f"{count}{die} + "
strip_title = dice_title.rstrip(" +")
plt.title(f"Dice rolled: {strip_title}")
plt.xlabel("Combined value of dice")
plt.ylabel(f"Frequency (out of {trials})")
plt.grid(axis="y", linestyle="--", alpha=0.6)
plt.tight_layout()
plt.show()
# --- Roll button ---
def roll_dice():
selections = []
for dice, controls in dice_controls.items():
if controls["selected"].get():
try:
count = int(controls["count"].get())
except ValueError:
count = 0
if count > 0:
selections.append((dice, count))
if not selections:
print("No dice selected")
return
results = simulate_rolls(selections, int(trial_var.get()))
print("\nSimulation complete!\n")
sorted_results = sorted(results.items())
for res in sorted_results:
print(f"{res}")
avg = sum(k * v for k, v in results.items()) / sum(results.values())
print(f"Average roll total ≈ {avg:.2f}")
plot_results(results, selections, int(trial_var.get()))
ctk.CTkButton(app, text="Roll!", command=roll_dice).pack(pady=20)
# Run the app
app.mainloop()