import tkinter as tk from tkinter import scrolledtext as st # Create the Tkinter window window = tk.Tk() window.title("The Fog") # Create the text area text_area = st.ScrolledText(window, bg="darkgreen", height=12, width=50, foreground="white", font=("Times New Roman", 10)) text_area.pack() last_display_index = "1.0" # Create the input field input_field = tk.Entry(window) input_field.after(1, input_field.focus_set()) input_field.pack() action_buttons = [] # Bind the Enter key to the handle_input function input_field.bind("", lambda event: handle_input()) def press(key): global current_text if key == "Space": key = " " elif key == "Back": current_text = input_field.get() input_field.delete(0, tk.END) input_field.insert(0, current_text[:-1]) return elif key == "Enter": handle_input() return current_text = key input_field.insert(tk.END, current_text) # Function to handle user input def handle_input(event=None): global last_display_index user_input = input_field.get() text_area.insert(tk.END, f"\n> {user_input}") last_display_index = text_area.index(tk.END) # Update the last display index input_field.delete(0, tk.END) process_input(user_input) # Change the color of previously read text after processing the input text_area.tag_config("read", foreground="white", background="black") text_area.tag_add("read", "1.0", last_display_index) # Apply the tag to the previously displayed text # Function to process user input and update game state def process_input(user_input): global current_location, inventory, encounter_enemy, enemy_encountered, enemy_defeated, previous_location, keyboard_frame actions = graph["locations"].get(current_location, {}) if enemy_defeated: keyboard_frame.pack_forget() # Hide the keyboard frame if encounter_enemy: keyboard_frame.pack(pady=10) if user_input.lower() == "attack": if "Sword" in inventory: text_area.insert(tk.END, "\nYou swing your sword and defeat the enemy!") encounter_enemy = False enemy_encountered = True enemy_defeated = True keyboard_frame.pack_forget() # Hide the keyboard frame else: text_area.insert(tk.END, "\nYou don't have a weapon to attack!") elif user_input.lower() == "run": text_area.insert(tk.END, "\nYou run away from the enemy!") enemy_encountered = True encounter_enemy = False enemy_defeated = False current_location = previous_location[-1] keyboard_frame.pack_forget() # Hide the keyboard frame elif user_input.lower() == "use an item": text_area.insert(tk.END, "\nYou have the following items:") for item in inventory: text_area.insert(tk.END, f"\n- {item}") if any(item in inventory for item in graph["items"]): for item in inventory: if item in graph["items"]: item_data = graph["items"][item] if item_data.get("usable"): if item_data.get("action") == "attack": text_area.insert(tk.END, f"\nYou use the {item} to attack the enemy!") current_location = actions[("Bridge", "cross a rickety bridge")] encounter_enemy = False enemy_encountered = True enemy_defeated = True keyboard_frame.pack_forget() # Hide the keyboard frame else: text_area.insert(tk.END, "\nInvalid item choice.") else: text_area.insert(tk.END, "\nYou don't have any usable items.") else: text_area.insert(tk.END, "\nInvalid choice. Please try again.") else: if user_input.lower() == "quit": exit(0) if user_input.lower() in [action[0].lower() for action in actions]: for action, next_location in actions.items(): if user_input.lower() == action[0].lower(): if next_location == "Swamp" and not encounter_enemy and not enemy_encountered and not enemy_defeated: if "Sword" in inventory: encounter_enemy = True if next_location == "Swamp" and not enemy_defeated: if "Sword" in inventory: encounter_enemy = True if user_input.lower() == "waterfall": if "Sword" in inventory: text_area.insert(tk.END, "\nwet and empty!") else: text_area.insert(tk.END, "\nYou took the sword of Alexander!") inventory.append("Sword") if user_input.lower() == "fish": if "Fish" in inventory: text_area.insert(tk.END, "\nGrabbing nothing but water") else: text_area.insert(tk.END, "\nYou go to the Fishing Spot and find a fish!") inventory.append("Fish") if next_location == "Top": if user_input.lower() == "key": if "Key" in inventory: text_area.insert(tk.END, "\nNothing here anymore") else: text_area.insert(tk.END, "\nYou go to the top and find a key!") inventory.append("Key") elif next_location == "Cave": if "Key" in inventory: text_area.insert(tk.END, "\nYou unlock the Cave and discover a hidden path to the Forest!") inventory.remove("Key") graph["locations"]["Cave"][("Secret Passage", "enter the secret room")] = "Secret_Room" graph["locations"]["Secret_Room"] = {} graph["locations"]["Secret_Room"][("Exit", "exit the secret room")] = "Swamp" graph["locations"]["Exit"] = {} else: text_area.insert(tk.END, "\nThe Cave is locked. You need a key to unlock it.") previous_location.append(current_location) current_location = next_location else: text_area.insert(tk.END, "\nInvalid choice. Please try again.") # Print the updated game state text_area.configure(state='normal') print_game_state() update_buttons() # Function to print the game state def print_game_state(): if encounter_enemy and not enemy_defeated: text_area.insert(tk.END, "\nAn enemy is blocking your way!") text_area.insert(tk.END, "\nWhat do you want to do?") text_area.insert(tk.END, "\n- Attack") text_area.insert(tk.END, "\n- Run") text_area.insert(tk.END, "\n- Use an item") text_area.after(1, text_area.see("end")) if encounter_enemy is False: text_area.insert(tk.END, f"\nYou are in the {current_location}") text_area.insert(tk.END, "\nAvailable actions:") actions = graph["locations"].get(current_location, {}) for action, next_location in actions.items(): if encounter_enemy is False: text_area.insert(tk.END, f"\n* {action[0]} *") text_area.insert(tk.END, f"\n- {action[1]}-") if encounter_enemy is False: text_area.insert(tk.END, f"\nInventory: {inventory}") text_area.after(1, text_area.see("end")) def update_buttons(): global actions, keyboard_frame for button in action_buttons: button.destroy() # Remove existing buttons actions = graph["locations"].get(current_location, {}) if encounter_enemy and not enemy_defeated: # Do not display any buttons when an enemy encounter is in progress input_field.pack() submit_button.pack() input_field.after(1, input_field.focus_set()) else: for action, next_location in actions.items(): action_text = action[0] button = tk.Button(window, text=action_text, height=5, width=len(action_text), command=lambda action_text=action_text: usebutton(action_text)) button.pack() action_buttons.append(button) # Add the button to the list # Add the input field and Submit button input_field.pack() submit_button.pack() input_field.after(1, input_field.focus_set()) def usebutton(action_text): input_field.delete(0, tk.END) # Clear the input field input_field.insert(0, action_text) graph = { "locations": { "Swamp": { ("Water", "trudge through deep water, getting soaked"): "Fishing_Spot", ("Bridge", "cross a rickety bridge"): "Forest", }, "Forest": { ("Tree", "climb a tall tree"): "Top", ("Path", "follow a winding path"): "Cave", ("Hole", "drop into the water again"): "Swamp" }, "Top": { ("Ladder", "climb down tree"): "Forest", ("Key", "a brown key"): "Top" }, "Cave": { ("Tunnel", "crawl through a narrow tunnel"): "Forest" }, "Fishing_Spot": { ("Fish", "see a fish"): "Fishing_Spot", ("Waterfall", "reach into the waterfall"): "Fishing_Spot", ("Shallow", "trudge back"): "Swamp" } }, "items": { "Fish": { "description": "A freshly caught fish", "usable": False, "action": "cook" }, "Sword": { "description": "A shiny sword", "usable": True, "action": "attack", "target": "Dragon" }, "Key": { "description": "A rusty key", "usable": True, "action": "unlock", "target": "Cave" } } } # Game state variables current_location = "Swamp" previous_location = [] inventory = [] encounter_enemy = False enemy_encountered = False # Flag variable to track if the enemy has been encountered enemy_defeated = False submit_button = tk.Button(window, text="Submit", command=handle_input) submit_button.pack() actions = graph["locations"].get(current_location, {}) update_buttons() print_game_state() text_area.configure(state='disabled') window.bind("", lambda x: handle_input) keyboard_frame = tk.Frame(window) # Define keyboard layout keys = [ ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'], ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'], ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Enter'], ['Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', 'Back'], ['Space'], ] for row in keys: frame = tk.Frame(keyboard_frame) frame.pack(side=tk.TOP) for k in row: buttonkb = tk.Button(frame, text=k, command=lambda k=k: press(k), padx=10, pady=10) buttonkb.pack(side=tk.LEFT) # Start the Tkinter event loop window.mainloop()