cluedo / app.py
ilyassh's picture
Update app.py
dcd204e verified
raw
history blame
9.04 kB
# murder_mystery.py
import random
import gradio as gr
from huggingface_hub import InferenceClient
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=512,
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
},
"Dr. Orchid": {
"personality": "",
"knowledge": "",
"is_murderer": False
}
}
weapons = ["Candlestick", "Dagger", "Lead Pipe", "Revolver", "Rope", "Wrench", "Poison"]
locations = ["Kitchen", "Ballroom", "Conservatory", "Dining Room", "Library", "Study", "Billiard Room", "Lounge"]
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",
"sarcastic and witty",
"arrogant and dismissive"
]
game_state = {
"murderer": "",
"weapon": "",
"location": "",
"is_game_over": False,
"clues": [],
"history": [],
"accused": False
}
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"] = []
game_state["accused"] = False
personalities_copy = possible_personalities.copy()
random.shuffle(personalities_copy)
for i, suspect in enumerate(suspects):
suspects[suspect]["is_murderer"] = (suspect == game_state["murderer"])
suspects[suspect]["personality"] = personalities_copy[i % len(personalities_copy)]
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 = []
elements = ["weapon", "location", "murderer"]
random.shuffle(elements)
known_item = elements[0]
if known_item == "weapon":
known_elements.append(f"You know that the weapon is {game_state['weapon']}.")
elif known_item == "location":
known_elements.append(f"You know that the location is {game_state['location']}.")
elif known_item == "murderer":
not_murderer = random.choice([s for s in suspects if s != suspect_name and s != game_state["murderer"]])
known_elements.append(f"You know that {not_murderer} is not the murderer.")
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} When answering questions, you may reveal hints subtly based on what you know."
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"]
if game_state["accused"]:
return "You have already made an accusation. Please restart to play again.", game_state["history"]
game_state["history"].append(("Detective", player_input))
if "accuse" in player_input.lower():
game_state["accused"] = True
result = handle_accusation(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))
extract_clues(ai_response)
return ai_response, game_state["history"]
return "Please direct your question to a suspect.", game_state["history"]
def extract_clues(ai_response):
clues = []
for weapon in weapons:
if weapon.lower() in ai_response.lower() and weapon != game_state["weapon"]:
clues.append(f"The weapon is not the {weapon}.")
for location in locations:
if location.lower() in ai_response.lower() and location != game_state["location"]:
clues.append(f"The location is not the {location}.")
for suspect in suspects:
if suspect.lower() in ai_response.lower() and suspect != game_state["murderer"]:
clues.append(f"{suspect} is not the murderer.")
for clue in clues:
if clue not in game_state["clues"]:
game_state["clues"].append(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! You lose. 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():
gr.Markdown("## Commands")
gr.Markdown("- **Ask a question to a suspect**: Include the suspect's name in your question.\n Example: *\"Miss Scarlett, where were you during the evening?\"*")
gr.Markdown("- **Make an accusation**: Include the word *\"accuse\"*.\n Example: *\"I accuse Colonel Mustard with the Rope in the Study.\"*")
player_input = gr.Textbox(lines=1, label="Your Input")
send_button = gr.Button("Send")
restart_button = gr.Button("Restart Game")
chatbox = gr.Textbox(lines=15, label="Chat History", interactive=False)
with gr.Column():
gr.Markdown("## Suspects")
gr.Markdown(', '.join(suspects.keys()))
gr.Markdown("## Weapons")
gr.Markdown(', '.join(weapons))
gr.Markdown("## Locations")
gr.Markdown(', '.join(locations))
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()