🌟 項目特點
- 🤖 智能AI:基于文心一言大模型,具有強大的推理能力
- 🎯 實時思考:展示AI的思考過程,讓你了解AI是如何推理的
- 🎮 互動性強:通過簡單的"是/否"問答,讓游戲更加有趣
- 📊 計分系統:記錄AI和人類的得分,增加游戲競技性
- 🎨 精美界面:采用現代化的UI設計,提供流暢的游戲體驗
🎯 游戲規則
- 玩家在心中想一個物體
- AI會通過最多20個"是/否"問題來猜測這個物體
- 玩家需要誠實回答每個問題
- 如果AI在20個問題內猜對,AI得1分
- 如果AI沒有猜對,人類得1分
- 游戲結束后可以重新開始,繼續挑戰
💡 特色功能
- 實時思考展示:AI會展示它的思考過程,讓你了解它是如何推理的
- 智能問題生成:AI會根據之前的回答,生成更有針對性的問題
- 容錯機制:考慮到玩家可能回答錯誤的情況,AI會進行更全面的推理
- 分數統計:記錄游戲得分,增加競技性
- 輪數顯示:清晰顯示當前問題輪數,讓游戲進度一目了然
🎮 如何開始
- 在輸入框中輸入你想讓AI猜的物體
- 點擊"設置目標物體"按鈕開始游戲
- 回答AI提出的"是/否"問題
- 等待AI的最終猜測
- 查看結果并開始新的游戲
🎯 游戲技巧
- 選擇具體的物體,避免抽象概念
- 誠實回答每個問題
- 觀察AI的思考過程,了解它的推理方式
- 嘗試選擇一些不常見的物體,增加游戲難度
🎨 界面預覽
游戲界面采用現代化的設計風格,包含:
- 清晰的游戲標題和說明
- 醒目的輪數計數器
- 實時更新的分數顯示
- 優雅的輸入框和按鈕
- 流暢的動畫效果
import os
import gradio as gr
from openai import OpenAI
import time# 初始化OpenAI客戶端
client = OpenAI(api_key="填寫你的密鑰",base_url="https://aistudio.baidu.com/llm/lmapi/v3"
)# 游戲狀態
class GameState:def __init__(self):self.questions_asked = 0self.max_questions = 20self.game_history = []self.target_object = Noneself.is_game_over = Falseself.current_question = Noneself.is_game_started = Falseself.ai_score = 0self.human_score = 0game_state = GameState()def stream_response(response, history_text):"""流式輸出響應"""full_response = ""for chunk in response:if chunk.choices[0].delta.content:full_response += chunk.choices[0].delta.contentyield full_response, history_textreturn full_response, history_textdef set_target_object(target):"""設置目標物體并開始游戲"""if not target.strip():return "請輸入目標物體!", "", "", "0/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", ""game_state.target_object = target.strip()game_state.is_game_started = Truegame_state.questions_asked = 0game_state.game_history = []game_state.is_game_over = Falsegame_state.current_question = None# 讓AI提出第一個問題prompt = """你正在玩20問游戲。請提出第一個問題來猜測玩家心中的物體。
問題應該是一個簡單的"是/否"問題,比如"它是活物嗎?"、"它比汽車大嗎?"等。
請先思考一下,然后只輸出問題,不要輸出其他內容。"""try:yield "游戲開始!", "\n".join(game_state.game_history), "", "0/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", "AI正在思考第一個問題..."response = client.chat.completions.create(model="ernie-x1-turbo-32k",messages=[{"role": "user", "content": prompt}],temperature=0.7,max_tokens=100,stream=True)first_question = ""thinking_process = "AI正在思考第一個問題...\n\n"for chunk in response:if hasattr(chunk.choices[0].delta, 'reasoning_content') and chunk.choices[0].delta.reasoning_content:thinking_process += chunk.choices[0].delta.reasoning_contentyield "游戲開始!", "\n".join(game_state.game_history), "", "0/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", thinking_processif chunk.choices[0].delta.content:first_question += chunk.choices[0].delta.contentgame_state.current_question = first_question.strip()game_state.game_history.append(f"AI問題 {game_state.questions_asked + 1}: {first_question.strip()}")yield f"游戲開始!\nAI的第一個問題:{first_question.strip()}", "\n".join(game_state.game_history), "", "0/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", thinking_process + "\n\n思考完成!"except Exception as e:yield f"發生錯誤: {str(e)}", "", "", "0/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", ""def answer_question(answer):"""處理玩家的回答"""if not game_state.is_game_started:return "請先設置目標物體!", "", "", f"{game_state.questions_asked}/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", ""if game_state.is_game_over:return "游戲已結束,請開始新游戲!", "", "", f"{game_state.questions_asked}/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", ""if not answer.strip():return "請輸入你的回答!", "", "", f"{game_state.questions_asked}/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", ""# 記錄玩家的回答game_state.game_history.append(f"玩家回答: {answer}")game_state.questions_asked += 1# 如果是最后一輪,讓AI進行最終猜測if game_state.questions_asked >= game_state.max_questions:game_state.is_game_over = True# 讓AI進行最終猜測guess_prompt = f"""基于之前的對話:
{chr(10).join(game_state.game_history)}這是最后一輪了,請根據所有信息,給出你的最終猜測。
請先分析一下已有的信息,然后給出你的猜測。
只輸出一個具體的物體名稱,不要輸出其他內容。"""try:yield "游戲即將結束...", "\n".join(game_state.game_history), "", "20/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", "AI正在分析所有信息并做出最終猜測..."guess_response = client.chat.completions.create(model="ernie-x1-turbo-32k",messages=[{"role": "user", "content": guess_prompt}],temperature=0.7,max_tokens=50,stream=True)guess = ""thinking_process = "AI正在分析所有信息并做出最終猜測...\n\n"for chunk in guess_response:if hasattr(chunk.choices[0].delta, 'reasoning_content') and chunk.choices[0].delta.reasoning_content:thinking_process += chunk.choices[0].delta.reasoning_contentyield "游戲即將結束...", "\n".join(game_state.game_history), "", "20/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", thinking_processif chunk.choices[0].delta.content:guess += chunk.choices[0].delta.contentguess = guess.strip()game_state.game_history.append(f"AI最終猜測: {guess}")# 判斷AI的猜測是否正確if guess.lower().strip() == game_state.target_object.lower().strip():game_state.ai_score += 1result = f"AI猜對了!目標物體就是:{game_state.target_object}\nAI得1分!"else:game_state.human_score += 1result = f"AI猜錯了!目標物體是:{game_state.target_object}\n人類得1分!"history_text = "\n".join(game_state.game_history)yield result, history_text, "", "20/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", thinking_process + "\n\n思考完成!"returnexcept Exception as e:yield f"發生錯誤: {str(e)}", "", "", "20/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", ""return# 如果不是最后一輪,讓AI繼續提問next_prompt = f"""基于之前的對話:
{chr(10).join(game_state.game_history)}請分析這些問答,提出下一個問題來猜測玩家心中的物體。
問題應該是一個簡單的"是/否"問題,要基于之前的回答來縮小范圍,但也要注意,有時玩家并不知道這個物體應該選是還是否,可能會出現回答錯誤,因此要考慮這種情況。
請先思考一下,然后只輸出問題,不要輸出其他內容。"""try:yield "AI正在思考...", "\n".join(game_state.game_history), "", f"{game_state.questions_asked}/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", f"AI正在分析第{game_state.questions_asked}輪的回答并思考下一個問題..."next_response = client.chat.completions.create(model="ernie-x1-turbo-32k",messages=[{"role": "user", "content": next_prompt}],temperature=0.7,max_tokens=100,stream=True)next_question = ""thinking_process = f"AI正在分析第{game_state.questions_asked}輪的回答并思考下一個問題...\n\n"for chunk in next_response:if hasattr(chunk.choices[0].delta, 'reasoning_content') and chunk.choices[0].delta.reasoning_content:thinking_process += chunk.choices[0].delta.reasoning_contentyield "AI正在思考...", "\n".join(game_state.game_history), "", f"{game_state.questions_asked}/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", thinking_processif chunk.choices[0].delta.content:next_question += chunk.choices[0].delta.contentnext_question = next_question.strip()game_state.current_question = next_questiongame_state.game_history.append(f"AI問題 {game_state.questions_asked + 1}: {next_question}")history_text = "\n".join(game_state.game_history)yield f"AI的問題 {game_state.questions_asked + 1}/20: {next_question}", history_text, "", f"{game_state.questions_asked}/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", thinking_process + "\n\n思考完成!"except Exception as e:yield f"發生錯誤: {str(e)}", "", "", f"{game_state.questions_asked}/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", ""def reset_game():"""重置游戲"""game_state.questions_asked = 0game_state.game_history = []game_state.is_game_over = Falsegame_state.target_object = Nonegame_state.current_question = Nonegame_state.is_game_started = Falsereturn "游戲已重置!請設置新的目標物體。", "", "", "0/20", f"AI: {game_state.ai_score} - 人類: {game_state.human_score}", "游戲已重置,等待開始新游戲..."# 自定義CSS樣式
custom_css = """
.round-counter {font-size: 24px !important;font-weight: bold !important;color: #4a90e2 !important;padding: 10px 20px !important;background-color: #f5f5f5 !important;border-radius: 10px !important;box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;margin-left: auto !important;
}.score-counter {font-size: 20px !important;font-weight: bold !important;color: #2c3e50 !important;padding: 8px 16px !important;background-color: #ecf0f1 !important;border-radius: 8px !important;box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;margin-left: 20px !important;
}.thinking {color: #666 !important;font-style: italic !important;
}.ai-thinking {font-family: 'Courier New', monospace !important;background-color: #f8f9fa !important;padding: 15px !important;border-radius: 8px !important;border-left: 4px solid #4a90e2 !important;margin: 10px 0 !important;white-space: pre-wrap !important;font-size: 14px !important;line-height: 1.5 !important;
}
"""# 創建Gradio界面
with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as demo:with gr.Row():gr.Markdown("# 🎮 知你所想")round_counter = gr.Markdown("0/20", elem_classes=["round-counter"])score_counter = gr.Markdown("AI: 0 - 人類: 0", elem_classes=["score-counter"])gr.Markdown("### 20個問題,猜中你所想的東西,來挑戰一下吧!")with gr.Row():with gr.Column(scale=1):target_input = gr.Textbox(label="輸入你想讓AI猜的物體",placeholder="例如:長頸鹿",lines=2)set_target_button = gr.Button("設置目標物體", variant="primary")with gr.Column(scale=1):answer_input = gr.Textbox(label="回答AI的問題",placeholder="輸入:是、否、或不知道",lines=2)answer_button = gr.Button("回答", variant="primary")with gr.Row():reset_button = gr.Button("開始新游戲", variant="stop")with gr.Row():ai_thinking = gr.Textbox(label="AI思考過程",lines=5,elem_classes=["ai-thinking"],interactive=False)with gr.Row():output = gr.Textbox(label="游戲狀態", lines=10)history = gr.Textbox(label="游戲歷史", lines=10)error = gr.Textbox(label="錯誤信息", lines=10)# 設置事件處理set_target_button.click(set_target_object,inputs=[target_input],outputs=[output, history, error, round_counter, score_counter, ai_thinking],queue=True)answer_button.click(answer_question,inputs=[answer_input],outputs=[output, history, error, round_counter, score_counter, ai_thinking],queue=True)reset_button.click(reset_game,outputs=[output, history, error, round_counter, score_counter, ai_thinking])if __name__ == "__main__":demo.queue().launch()