Skip to content

Commit c5f530f

Browse files
authored
Create AdventureQuest.py
1 parent 25ab040 commit c5f530f

1 file changed

Lines changed: 303 additions & 0 deletions

File tree

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
import sys
2+
import os
3+
import threading
4+
import random
5+
import tkinter as tk
6+
from tkinter import ttk, messagebox
7+
import sv_ttk
8+
9+
# =========================
10+
# Helpers
11+
# =========================
12+
def resource_path(file_name):
13+
base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
14+
return os.path.join(base_path, file_name)
15+
16+
def set_status(msg):
17+
status_var.set(msg)
18+
root.update_idletasks()
19+
20+
def delayed_update(event=None):
21+
threading.Timer(0.1, update_ui).start()
22+
23+
# =========================
24+
# App Setup
25+
# =========================
26+
root = tk.Tk()
27+
root.title("AdventureQuest")
28+
root.geometry("900x600")
29+
sv_ttk.set_theme("light")
30+
31+
# =========================
32+
# Globals
33+
# =========================
34+
dark_mode_var = tk.BooleanVar(value=False)
35+
36+
story_var = tk.StringVar(value="Welcome to AdventureQuest!\nYour journey begins...\n")
37+
action_var = tk.StringVar()
38+
39+
player = {
40+
"health": 100,
41+
"gold": 0,
42+
"location": "forest",
43+
"attack": 10,
44+
}
45+
46+
inventory = []
47+
48+
locations = {
49+
"forest": {
50+
"description": "You are in a dark forest. Paths lead north and east.",
51+
"actions": {"north": "cave", "east": "village"}
52+
},
53+
"cave": {
54+
"description": "A spooky cave. You see a shiny sword.",
55+
"actions": {"south": "forest", "take sword": None}
56+
},
57+
"village": {
58+
"description": "A small village with friendly villagers.",
59+
"actions": {"west": "forest", "shop": None}
60+
},
61+
}
62+
63+
enemies = {
64+
"forest": {"Goblin": {"health": 30, "attack": 5}, "Wolf": {"health": 25, "attack": 6}},
65+
"cave": {"Bat": {"health": 20, "attack": 4}, "Skeleton": {"health": 40, "attack": 8}},
66+
}
67+
68+
treasures = {
69+
"forest": ["gold coin", "healing herb"],
70+
"cave": ["gold coin", "magic potion"],
71+
"village": ["gold coin"]
72+
}
73+
74+
# =========================
75+
# Theme Toggle
76+
# =========================
77+
def toggle_theme():
78+
style.theme_use("clam")
79+
bg = "#2E2E2E" if dark_mode_var.get() else "#FFFFFF"
80+
fg = "white" if dark_mode_var.get() else "black"
81+
82+
root.configure(bg=bg)
83+
for w in ["TFrame", "TLabel", "TLabelframe", "TLabelframe.Label", "TCheckbutton"]:
84+
style.configure(w, background=bg, foreground=fg)
85+
86+
text_area.configure(
87+
bg="#1e1e1e" if dark_mode_var.get() else "white",
88+
fg="white" if dark_mode_var.get() else "black",
89+
insertbackground="white" if dark_mode_var.get() else "black"
90+
)
91+
92+
set_status(f"Theme switched to {'Dark' if dark_mode_var.get() else 'Light'} mode")
93+
94+
# =========================
95+
# Game Logic
96+
# =========================
97+
def update_ui():
98+
location = player["location"]
99+
loc_info = locations[location]
100+
story_text = f"{loc_info['description']}\n"
101+
story_text += f"\nHealth: {player['health']} | Gold: {player['gold']} | Inventory: {', '.join(inventory) if inventory else 'Empty'}"
102+
story_var.set(story_text)
103+
104+
def encounter_enemy():
105+
location = player["location"]
106+
if location in enemies and random.random() < 0.6: # 60% chance
107+
enemy_name = random.choice(list(enemies[location].keys()))
108+
enemy = enemies[location][enemy_name]
109+
set_status(f"⚔️ You encounter a {enemy_name}!")
110+
combat(enemy_name, enemy)
111+
112+
def find_treasure():
113+
location = player["location"]
114+
if location in treasures and random.random() < 0.5: # 50% chance
115+
item = random.choice(treasures[location])
116+
inventory.append(item)
117+
set_status(f"💎 You found a {item}!")
118+
119+
def combat(enemy_name, enemy):
120+
while enemy["health"] > 0 and player["health"] > 0:
121+
damage = player["attack"] + (5 if "sword" in inventory else 0)
122+
enemy["health"] -= damage
123+
set_status(f"You hit {enemy_name} for {damage} damage!")
124+
root.update()
125+
root.after(500)
126+
127+
if enemy["health"] <= 0:
128+
gold_found = random.randint(5, 20)
129+
player["gold"] += gold_found
130+
set_status(f"🎉 You defeated {enemy_name} and gained {gold_found} gold!")
131+
root.update()
132+
root.after(500)
133+
return
134+
135+
# Enemy attacks
136+
player["health"] -= enemy["attack"]
137+
set_status(f"{enemy_name} hits you for {enemy['attack']} damage!")
138+
root.update()
139+
root.after(500)
140+
141+
if player["health"] <= 0:
142+
set_status("💀 You were defeated! Game over.")
143+
messagebox.showinfo("Game Over", "You have died! Restarting game...")
144+
reset_game()
145+
return
146+
147+
def reset_game():
148+
player["health"] = 100
149+
player["gold"] = 0
150+
player["location"] = "forest"
151+
inventory.clear()
152+
update_ui()
153+
154+
def process_action():
155+
action = action_var.get().strip().lower()
156+
location = player["location"]
157+
loc_info = locations[location]
158+
valid_actions = loc_info["actions"]
159+
160+
if action in valid_actions:
161+
# Move to another location
162+
if valid_actions[action]:
163+
player["location"] = valid_actions[action]
164+
set_status(f"You move to {valid_actions[action].capitalize()}.")
165+
encounter_enemy()
166+
find_treasure()
167+
else:
168+
# Special actions
169+
if action == "take sword" and "sword" not in inventory:
170+
inventory.append("sword")
171+
set_status("🗡 You picked up the sword!")
172+
elif action == "shop":
173+
if player["gold"] >= 10:
174+
player["gold"] -= 10
175+
inventory.append("potion")
176+
set_status("💊 You bought a healing potion!")
177+
else:
178+
set_status("Not enough gold!")
179+
else:
180+
set_status("❌ Invalid action!")
181+
182+
action_var.set("")
183+
update_ui()
184+
185+
# =========================
186+
# Help Window
187+
# =========================
188+
def show_help():
189+
win = tk.Toplevel(root)
190+
win.title("AdventureQuest - Help")
191+
win.geometry("480x360")
192+
win.configure(bg="#2e2e2e")
193+
win.resizable(False, False)
194+
win.transient(root)
195+
win.grab_set()
196+
197+
frame = tk.Frame(win, bg="#2e2e2e")
198+
frame.pack(fill="both", expand=True, padx=12, pady=12)
199+
200+
text = tk.Text(
201+
frame,
202+
bg="#2e2e2e",
203+
fg="#f0f0f0",
204+
font=("Segoe UI", 11),
205+
wrap="word",
206+
borderwidth=0
207+
)
208+
text.pack(fill="both", expand=True)
209+
210+
help_text = """🗺 AdventureQuest — Quick Help
211+
212+
• Read the story in the main window.
213+
• Type actions (commands) in the input box:
214+
- Directions: north, south, east, west
215+
- Special: take sword, shop, etc.
216+
• Combat occurs randomly when exploring.
217+
• You can find treasures randomly.
218+
• Press 'Enter' or click 'Act' to perform action.
219+
• Keep track of health, gold, and inventory.
220+
221+
Your adventure awaits!"""
222+
text.insert("1.0", help_text)
223+
text.config(state="disabled")
224+
225+
# =========================
226+
# Styles
227+
# =========================
228+
style = ttk.Style()
229+
style.theme_use("clam")
230+
style.configure(
231+
"Action.TButton",
232+
font=("Segoe UI", 11, "bold"),
233+
foreground="white",
234+
background="#4CAF50",
235+
padding=8
236+
)
237+
style.map("Action.TButton", background=[("active", "#45a049")])
238+
239+
# =========================
240+
# Status Bar
241+
# =========================
242+
status_var = tk.StringVar(value="Ready")
243+
ttk.Label(root, textvariable=status_var, anchor="w").pack(side=tk.BOTTOM, fill="x")
244+
245+
# =========================
246+
# Main UI
247+
# =========================
248+
main = ttk.Frame(root, padding=20)
249+
main.pack(expand=True, fill="both")
250+
251+
ttk.Label(main, text="AdventureQuest", font=("Segoe UI", 22, "bold")).pack()
252+
ttk.Label(main, text="A text-based adventure game", font=("Segoe UI", 11)).pack(pady=(0, 10))
253+
254+
# =========================
255+
# Text Area
256+
# =========================
257+
text_frame = ttk.LabelFrame(main, text="Story", padding=10)
258+
text_frame.pack(fill="both", pady=10, expand=True)
259+
260+
text_area = tk.Text(
261+
text_frame,
262+
font=("Segoe UI", 11),
263+
wrap="word",
264+
height=15,
265+
state="disabled"
266+
)
267+
text_area.pack(fill="both", expand=True)
268+
269+
def refresh_story(*args):
270+
text_area.config(state="normal")
271+
text_area.delete("1.0", tk.END)
272+
text_area.insert("1.0", story_var.get())
273+
text_area.config(state="disabled")
274+
275+
story_var.trace_add("write", refresh_story)
276+
277+
# =========================
278+
# Action Input
279+
# =========================
280+
action_frame = ttk.Frame(main)
281+
action_frame.pack(fill="x", pady=8)
282+
283+
ttk.Label(action_frame, text="Your Action:", font=("Segoe UI", 10, "bold")).pack(side="left", padx=(0, 6))
284+
285+
action_entry = ttk.Entry(action_frame, textvariable=action_var, width=30)
286+
action_entry.pack(side="left", padx=(0, 6))
287+
action_entry.bind("<Return>", lambda e: process_action())
288+
289+
ttk.Button(action_frame, text="Act", command=process_action, style="Action.TButton").pack(side="left", padx=6)
290+
ttk.Button(action_frame, text="❓ Help", command=show_help, style="Action.TButton").pack(side="left", padx=6)
291+
292+
ttk.Checkbutton(
293+
action_frame,
294+
text="Dark Mode",
295+
variable=dark_mode_var,
296+
command=toggle_theme
297+
).pack(side="right", padx=14)
298+
299+
# =========================
300+
# Start Game
301+
# =========================
302+
update_ui()
303+
root.mainloop()

0 commit comments

Comments
 (0)