Fixed an issue with Game Over states not being correctly detected/handled.

This commit is contained in:
Jonathan Hite 2025-02-07 13:25:27 -05:00
parent 34704013bd
commit dfeea2d36f
3 changed files with 53 additions and 51 deletions

View file

@ -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)

View file

@ -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

View file

@ -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.
Can't render this file because it contains an unexpected character in line 1 and column 7.