|
|
|
|
|
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 = [ |
|
"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 = { |
|
"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"]) |
|
|
|
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 = [] |
|
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() |
|
|