diff --git a/command_handlers.py b/command_handlers.py index ce2259b..def5ec7 100644 --- a/command_handlers.py +++ b/command_handlers.py @@ -701,40 +701,34 @@ def get_games_available(game_files): def handle_games_command(sender_id, interface): """Handles the Games Menu and lists available text-based games.""" - - # Find files in ./games that: - # - Have a .txt or .csv extension - # - OR have no extension + game_files = [ f for f in os.listdir('./games') if os.path.isfile(os.path.join('./games', f)) and (f.endswith('.txt') or f.endswith('.csv') or '.' not in f) ] games_available = get_games_available(game_files) - if not games_available: send_message("No games available yet. Come back soon.", sender_id, interface) update_user_state(sender_id, {'command': 'UTILITIES', 'step': 1}) return None - # Store game filenames in state to avoid title-related issues game_titles = list(games_available.keys()) # Display titles game_filenames = list(games_available.values()) # Actual filenames - - # Include exit option + numbered_games = "\n".join(f"{i+1}. {title}" for i, title in enumerate(game_titles)) numbered_games += "\n[X] Exit" response = f"šŸŽ® Games Menu šŸŽ®\nWhich game would you like to play?\n{numbered_games}" send_message(response, sender_id, interface) + # āœ… Ensure `games` state is always reset when displaying the menu update_user_state(sender_id, {'command': 'GAMES', 'step': 1, 'games': game_filenames, 'titles': game_titles}) return response - def handle_game_menu_selection(sender_id, message, step, interface, state): """Handles the user's selection of a game from the Games Menu, allowing exit with 'X' and starting immediately.""" @@ -750,6 +744,9 @@ def handle_game_menu_selection(sender_id, message, step, interface, state): if 0 <= game_index < len(games_available): selected_game = games_available[game_index] + # Reset user state to ensure a clean start + update_user_state(sender_id, None) + # Update state to indicate the user is now in-game update_user_state(sender_id, {'command': 'IN_GAME', 'step': 3, 'game': selected_game}) @@ -761,6 +758,7 @@ def handle_game_menu_selection(sender_id, message, step, interface, state): except ValueError: send_message("Invalid input. Please enter a number corresponding to a game or 'X' to exit.", sender_id, interface) + def start_selected_game(sender_id, interface, state): """Starts the game selected by the user and ensures title detection.""" @@ -844,24 +842,37 @@ def load_game_map(file_path): print(f"āŒ ERROR inside load_game_map(): {e}") return None - def present_story_segment(sender_id, interface, state): """Presents the current segment of the game and available choices.""" game_name = state.get('game') - game_title = state.get('game_title', "Unknown Game") # āœ… Prevent KeyError + game_title = state.get('game_title', "Unknown Game") game_map = state.get('game_map', {}) game_position = state.get('game_position', 1) if game_position not in game_map: send_message("Error: Invalid game state.", sender_id, interface) update_user_state(sender_id, {'command': 'GAMES', 'step': 1}) + handle_games_command(sender_id, interface) return # Retrieve the current story segment segment = game_map[game_position] storyline = segment[0] - choices = segment[1:] + choices = segment[1:] # Extract choices + + # šŸ› ļø **Check if this is a game-over state (no choices)** + if not choices: + send_message(f"šŸŽ® {game_title} šŸŽ®\n\n{storyline}\n\nšŸ’€ GAME OVER! Returning to the game menu...", sender_id, interface) + + # Reset user state before returning to menu + update_user_state(sender_id, {'command': 'GAMES', 'step': 1}) + + import time + time.sleep(1) # Ensure the message is processed before switching menus + + handle_games_command(sender_id, interface) + return # Build response message response = f"šŸŽ® {game_title} šŸŽ®\n\n{storyline}\n\n" @@ -872,16 +883,17 @@ def present_story_segment(sender_id, interface, state): send_message(response, sender_id, interface) - # Update user state to track the current game progress + # Ensure user state is properly tracked update_user_state(sender_id, { 'command': 'IN_GAME', 'step': 3, 'game': game_name, - 'game_title': game_title, # āœ… Ensure it stays in state + 'game_title': game_title, 'game_map': game_map, 'game_position': game_position }) + def process_game_choice(sender_id, message, interface, state): """Processes the player's choice and advances the game.""" @@ -891,65 +903,50 @@ def process_game_choice(sender_id, message, interface, state): if game_position not in game_map: send_message("Error: Invalid game state.", sender_id, interface) update_user_state(sender_id, {'command': 'GAMES', 'step': 1}) + handle_games_command(sender_id, interface) return segment = game_map[game_position] # Extract the storyline and choices - storyline = segment[0] # First element is the story text - choices = segment[1:] # Remaining elements are choices + storyline = segment[0] + choices = segment[1:] - # Ensure choices are properly formatted (must be in pairs) + # Ensure choices are properly formatted if len(choices) % 2 != 0: send_message("Error: Game data is corrupted.", sender_id, interface) update_user_state(sender_id, {'command': 'GAMES', 'step': 1}) + handle_games_command(sender_id, interface) return # Handle Exit if message.lower() == "x": send_message(f"Exiting '{state['game_title']}'... Returning to Games Menu.", sender_id, interface) update_user_state(sender_id, {'command': 'GAMES', 'step': 1}) - handle_games_command(sender_id, interface) # Immediately display the game menu + handle_games_command(sender_id, interface) return try: - # Convert user input to index (1-based to 0-based) choice_index = int(message) - 1 - # Validate choice selection if choice_index < 0 or choice_index * 2 + 1 >= len(choices): send_message("Invalid selection. Please enter a valid number.", sender_id, interface) return - # Retrieve the target position for the chosen option target_position = int(choices[choice_index * 2 + 1]) - # Check if the target position exists if target_position not in game_map: - send_message("šŸ’€ Game Over! You fell into an abyss. šŸ’€", sender_id, interface) + send_message("šŸ’€ GAME OVER! No further choices available. šŸ’€ Returning to the game menu...", sender_id, interface) update_user_state(sender_id, {'command': 'GAMES', 'step': 1}) - handle_games_command(sender_id, interface) # Return to game menu + handle_games_command(sender_id, interface) return - # Update state with the new game position - update_user_state(sender_id, { - 'command': 'IN_GAME', - 'step': 3, - 'game': state['game'], - 'game_title': state['game_title'], - 'game_map': game_map, - 'game_position': target_position - }) + # āœ… FIX: Pass `state` instead of `update_user_state` + state['game_position'] = target_position + update_user_state(sender_id, state) - # Present the new story segment - present_story_segment(sender_id, interface, { - 'command': 'IN_GAME', - 'step': 3, - 'game': state['game'], - 'game_title': state['game_title'], - 'game_map': game_map, - 'game_position': target_position - }) + # āœ… FIX: Pass the correct `state` variable, NOT `update_user_state` + present_story_segment(sender_id, interface, state) - except (ValueError, IndexError): - send_message("Invalid selection. Please enter a valid number.", sender_id, interface) + except ValueError: + send_message("Invalid input. Please enter a valid number.", sender_id, interface) diff --git a/games/lost_forest_no_title b/games/lost_forest_no_title deleted file mode 100644 index 8aa02c0..0000000 --- a/games/lost_forest_no_title +++ /dev/null @@ -1,7 +0,0 @@ -What is your first choice?, East, 2, West, 3, North, 4, South, 5 -You chose East. A dense forest appears., Run forward, 6, Look around, 7 -You chose West. A river blocks your path., Try to swim, 8, Walk along the bank, 9 -You chose North. The path is blocked by rocks. -You chose South. A cave entrance looms ahead., Enter the cave, 10, Turn back, 11 -You went East and chose to run. The ground gives way and you fall. GAME OVER. -You went East and looked around. You see a hidden path., Follow it, 12, Stay put, 13 \ No newline at end of file diff --git a/games/the_shortest_game.csv b/games/the_shortest_game.csv new file mode 100644 index 0000000..20665f8 --- /dev/null +++ b/games/the_shortest_game.csv @@ -0,0 +1,12 @@ +title="The Shortest Game" +You awaken at a crossroads. Which way will you go?, North, 2, East, 3, South, 4, West, 5 +You chose north. There was a cottage. Will you:, Explore it, 6, Keep going, 7 +You chose East. The way is dark. What will you do?, Keep going, 8, Light a fire, 9 +You chose South. You walked for a mile and found nothing. +You chose West. There is a man on the path., Ignore him, 10, Talk to him, 11 +You fell through the floor of the cottage. +Just beyond the cottage you see a village full of people. They seem to recognize you. You make this your new home. +You are brave. After a short walk through the dark forest you find a clearing you recognize. You know the way home. +Marauders spot your fire in the night. You don't wake again. +The man snickers as you pass. Later down the trail you are robbed. +The man tells you where you are and how to get back home. \ No newline at end of file