cluedo / app.py
ilyassh's picture
Create app.py
b1e12f0 verified
raw
history blame
8.79 kB
# murder_mystery.py
import random
import gradio as gr
from huggingface_hub import InferenceClient
import os
model_name = "Qwen/Qwen2.5-72B-Instruct"
client = InferenceClient(model_name)
def llm_inference(messages):
eos_token = "<|endoftext|>"
output = client.chat.completions.create(
messages=messages,
stream=False,
temperature=0.7,
top_p=0.1,
max_tokens=412,
stop=[eos_token]
)
response = ''
for choice in output.choices:
response += choice['message']['content']
return response
suspects = {
"Colonel Mustard": {
"personality": "",
"knowledge": "",
"is_murderer": False
},
"Miss Scarlett": {
"personality": "",
"knowledge": "",
"is_murderer": False
},
"Professor Plum": {
"personality": "",
"knowledge": "",
"is_murderer": False
},
"Mrs. Peacock": {
"personality": "",
"knowledge": "",
"is_murderer": False
},
"Mr. Green": {
"personality": "",
"knowledge": "",
"is_murderer": False
}
}
weapons = ["Candlestick", "Dagger", "Lead Pipe", "Revolver", "Rope", "Wrench"]
locations = ["Kitchen", "Ballroom", "Conservatory", "Dining Room", "Library", "Study"]
# Possible personalities
possible_personalities = [
"stern and suspicious",
"charming but evasive",
"intellectual and nervous",
"gracious but secretive",
"amiable yet deceptive",
"hot-headed and impulsive",
"calm and collected",
"mysterious and aloof",
"jovial but cunning",
"nervous and jittery"
]
# Game state
game_state = {
"murderer": "",
"weapon": "",
"location": "",
"is_game_over": False,
"clues": [],
"history": []
}
def initialize_game():
game_state["murderer"] = random.choice(list(suspects.keys()))
game_state["weapon"] = random.choice(weapons)
game_state["location"] = random.choice(locations)
game_state["is_game_over"] = False
game_state["clues"] = []
game_state["history"] = []
personalities_copy = possible_personalities.copy()
random.shuffle(personalities_copy)
for i, suspect in enumerate(suspects):
suspects[suspect]["is_murderer"] = (suspect == game_state["murderer"])
# Assign a random personality
suspects[suspect]["personality"] = personalities_copy[i % len(personalities_copy)]
# Generate knowledge
suspects[suspect]["knowledge"] = generate_knowledge(suspect)
print(f"Debug: Murderer is {game_state['murderer']}, Weapon is {game_state['weapon']}, Location is {game_state['location']}")
for suspect in suspects:
print(f"Debug: {suspect}'s personality is {suspects[suspect]['personality']}")
def generate_knowledge(suspect_name):
knowledge = []
if suspects[suspect_name]["is_murderer"]:
knowledge.append("You are the murderer. Deflect suspicion subtly.")
else:
known_elements = []
if random.choice([True, False]):
known_elements.append(f"The weapon is {game_state['weapon']}.")
if random.choice([True, False]):
known_elements.append(f"The location is {game_state['location']}.")
if random.choice([True, False]):
not_murderer = random.choice([s for s in suspects if s != suspect_name and s != game_state["murderer"]])
known_elements.append(f"The murderer is not {not_murderer}.")
if not known_elements:
known_elements.append("You don't have any specific knowledge about the murder.")
knowledge.extend(known_elements)
return ' '.join(knowledge)
def get_ai_response(suspect_name, player_input):
personality = suspects[suspect_name]["personality"]
knowledge = suspects[suspect_name]["knowledge"]
system_prompt = f"You are {suspect_name}, who is {personality}. {knowledge}"
user_message = f"The detective asks: \"{player_input}\" As {suspect_name}, respond in first person, staying in character."
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message}
]
response = llm_inference(messages)
return response.strip()
def process_input(player_input):
if game_state["is_game_over"]:
return "The game is over. Please restart to play again.", game_state["history"]
game_state["history"].append(("Detective", player_input))
if "accuse" in player_input.lower():
result = handle_accusation(player_input)
game_state["history"].append(("System", result))
return result, game_state["history"]
elif "was it" in player_input.lower() or "suggest" in player_input.lower():
result = handle_suggestion(player_input)
game_state["history"].append(("System", result))
return result, game_state["history"]
else:
for suspect in suspects:
if suspect.lower() in player_input.lower():
ai_response = get_ai_response(suspect, player_input)
game_state["history"].append((suspect, ai_response))
return ai_response, game_state["history"]
return "Please direct your question to a suspect.", game_state["history"]
def handle_suggestion(player_input):
suspect_guess = None
weapon_guess = None
location_guess = None
for suspect in suspects:
if suspect.lower() in player_input.lower():
suspect_guess = suspect
break
for weapon in weapons:
if weapon.lower() in player_input.lower():
weapon_guess = weapon
break
for location in locations:
if location.lower() in player_input.lower():
location_guess = location
break
feedback = []
if suspect_guess == game_state["murderer"]:
feedback.append("The suspect is correct.")
elif suspect_guess:
feedback.append("The suspect is incorrect.")
if weapon_guess == game_state["weapon"]:
feedback.append("The weapon is correct.")
elif weapon_guess:
feedback.append("The weapon is incorrect.")
if location_guess == game_state["location"]:
feedback.append("The location is correct.")
elif location_guess:
feedback.append("The location is incorrect.")
if not feedback:
return "Your suggestion could not be understood. Please specify a suspect, weapon, and location."
clue = ' '.join(feedback)
game_state["clues"].append(clue)
return clue
def handle_accusation(player_input):
suspect_guess = None
weapon_guess = None
location_guess = None
for suspect in suspects:
if suspect.lower() in player_input.lower():
suspect_guess = suspect
break
for weapon in weapons:
if weapon.lower() in player_input.lower():
weapon_guess = weapon
break
for location in locations:
if location.lower() in player_input.lower():
location_guess = location
break
if (suspect_guess == game_state["murderer"] and
weapon_guess == game_state["weapon"] and
location_guess == game_state["location"]):
game_state["is_game_over"] = True
return f"Congratulations! You solved the case. It was {suspect_guess} with the {weapon_guess} in the {location_guess}."
else:
game_state["is_game_over"] = True
return f"Incorrect accusation! The real murderer was {game_state['murderer']} with the {game_state['weapon']} in the {game_state['location']}."
def chat_interface(player_input):
response, history = process_input(player_input)
chat_history = ""
for speaker, text in history:
chat_history += f"**{speaker}:** {text}\n\n"
clues_display = "\n".join(game_state["clues"])
return chat_history, clues_display
def restart_game():
initialize_game()
return "", ""
with gr.Blocks() as demo:
gr.Markdown("# Murder Mystery Game")
with gr.Row():
with gr.Column():
chatbox = gr.Textbox(lines=15, label="Chat History", interactive=False)
player_input = gr.Textbox(lines=1, label="Your Input")
send_button = gr.Button("Send")
restart_button = gr.Button("Restart Game")
with gr.Column():
clues = gr.Textbox(lines=15, label="Discovered Clues", interactive=False)
def send_message(player_input):
chat_history, clues_display = chat_interface(player_input)
return chat_history, "", clues_display
send_button.click(send_message, inputs=player_input, outputs=[chatbox, player_input, clues])
restart_button.click(fn=restart_game, inputs=None, outputs=[chatbox, clues])
initialize_game()
demo.launch()