feat: 初始化海龟汤游戏项目,包含核心逻辑、前端界面和文档
- 添加核心游戏逻辑文件structual.py,实现海龟汤游戏基本功能 - 创建HTML前端界面turtle_soup_html.html,提供交互式游戏体验 - 编写详细README.md文档,包含项目介绍、运行指南和贡献说明 - 添加项目配置文件pyproject.toml和环境变量示例 - 实现游戏数据存储功能,使用JSON保存游戏记录 - 包含15个预设海龟汤题目和关键词匹配系统
This commit is contained in:
commit
72bec8db47
1
.env_example copy
Normal file
1
.env_example copy
Normal file
@ -0,0 +1 @@
|
||||
DEEPSEEK_API_KEY=*****
|
||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.env
|
||||
.venv/
|
||||
__pycache__/
|
||||
.DS_Store
|
||||
1
.python-version
Normal file
1
.python-version
Normal file
@ -0,0 +1 @@
|
||||
3.13
|
||||
104
README.md
Normal file
104
README.md
Normal file
@ -0,0 +1,104 @@
|
||||
# 海龟汤游戏项目
|
||||
|
||||
## 团队成员与贡献
|
||||
|
||||
| 姓名 | 学号 | 主要贡献 (具体分工) |
|
||||
| ---- | ---- | ------------------ |
|
||||
| 张三 | 2023xxxx | (组长) 核心逻辑开发、Prompt 编写 |
|
||||
| 李四 | 2023xxxx | 前端界面设计、HTML版本开发 |
|
||||
| 王五 | 2023xxxx | 文档撰写、测试与Bug修复 |
|
||||
|
||||
## 项目简介 & 运行指南
|
||||
|
||||
### 简介
|
||||
这是一个海龟汤游戏项目,提供了一个交互式平台,用户可以通过提问来猜测海龟汤题目的答案。项目包含HTML版本和Python版本,支持15个精心设计的海龟汤题目,包括代孕等主题,具有完善的关键词匹配系统和现代化的用户界面。
|
||||
|
||||
### 如何运行
|
||||
|
||||
#### HTML版本(推荐,无需配置)
|
||||
1. 直接在浏览器中打开 `turtle_soup_html.html` 文件
|
||||
2. 点击"新游戏"按钮开始游戏
|
||||
3. 在输入框中输入问题,点击"发送"或按Enter键提交
|
||||
4. 使用"提示"、"查看答案"或"我来猜测"按钮辅助游戏
|
||||
|
||||
#### Python版本(需要配置)
|
||||
1. **安装依赖**:
|
||||
```bash
|
||||
uv sync
|
||||
```
|
||||
|
||||
2. **配置环境变量**:
|
||||
- 复制 `.env_example copy` 为 `.env`
|
||||
- 在 `.env` 文件中填入你的 DeepSeek API Key
|
||||
|
||||
3. **启动游戏**:
|
||||
```bash
|
||||
uv run python main.py
|
||||
```
|
||||
|
||||
或者使用GUI版本:
|
||||
```bash
|
||||
uv run python turtle_soup_gui.py
|
||||
```
|
||||
|
||||
### 游戏说明
|
||||
|
||||
1. **游戏流程**:
|
||||
- 点击"新游戏"随机选择一个海龟汤题目
|
||||
- 输入问题,系统会根据关键词匹配回答"是"、"否"或"无关"
|
||||
- 使用"提示"按钮获取线索
|
||||
- 使用"我来猜测"按钮尝试猜测答案
|
||||
- 使用"查看答案"按钮直接查看完整答案
|
||||
|
||||
2. **题目特点**:
|
||||
- 包含15个多样化的海龟汤题目
|
||||
- 涵盖代孕、犯罪、情感等多种主题
|
||||
- 每个题目都有详细的关键词匹配系统
|
||||
|
||||
3. **技术特点**:
|
||||
- HTML版本:纯前端实现,无需依赖,可直接运行
|
||||
- Python版本:支持AI生成题目和回答,提供命令行和GUI界面
|
||||
- 现代化的响应式设计,支持多种设备
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
├── turtle_soup_html.html # HTML版本游戏
|
||||
├── main.py # Python命令行版本
|
||||
├── turtle_soup_gui.py # Python GUI版本
|
||||
├── structual.py # 核心游戏逻辑
|
||||
├── pyproject.toml # 项目配置文件
|
||||
├── uv.lock # 依赖锁定文件
|
||||
├── .env_example copy # 环境变量示例
|
||||
└── README.md # 项目说明文档
|
||||
```
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **前端**:HTML5, CSS3, JavaScript
|
||||
- **后端**:Python 3.13
|
||||
- **依赖管理**:uv
|
||||
- **AI API**:DeepSeek API
|
||||
- **GUI框架**:tkinter
|
||||
|
||||
## 开发与维护
|
||||
|
||||
### 开发环境
|
||||
- Python 3.13
|
||||
- uv >= 0.1.0
|
||||
|
||||
### 测试
|
||||
```bash
|
||||
uv run python -m pytest
|
||||
```
|
||||
|
||||
### 贡献指南
|
||||
1. Fork 项目
|
||||
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
|
||||
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||||
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||
5. 开启 Pull Request
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。
|
||||
6
main.py
Normal file
6
main.py
Normal file
@ -0,0 +1,6 @@
|
||||
def main():
|
||||
print("Hello from my-project!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
10
pyproject.toml
Normal file
10
pyproject.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[project]
|
||||
name = "my-project"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"openai>=2.14.0",
|
||||
"python-dotenv>=1.2.1",
|
||||
]
|
||||
445
structual.py
Normal file
445
structual.py
Normal file
@ -0,0 +1,445 @@
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime
|
||||
from openai import OpenAI
|
||||
from dotenv import load_dotenv
|
||||
import traceback
|
||||
|
||||
# 加载环境变量
|
||||
load_dotenv()
|
||||
|
||||
# 初始化OpenAI客户端
|
||||
try:
|
||||
client = OpenAI(
|
||||
api_key=os.getenv("DEEPSEEK_API_KEY"),
|
||||
base_url="https://api.deepseek.com"
|
||||
)
|
||||
print(f"API客户端初始化成功,使用的API Key: {os.getenv('DEEPSEEK_API_KEY')[:10]}...")
|
||||
except Exception as e:
|
||||
print(f"API客户端初始化失败: {e}")
|
||||
traceback.print_exc()
|
||||
exit(1)
|
||||
|
||||
# 游戏数据存储文件
|
||||
GAME_DATA_FILE = "turtle_soup_data.json"
|
||||
|
||||
# 确保数据文件存在
|
||||
def ensure_data_file_exists():
|
||||
if not os.path.exists(GAME_DATA_FILE):
|
||||
with open(GAME_DATA_FILE, "w", encoding="utf-8") as f:
|
||||
json.dump({"games": [], "statistics": {"total_games": 0, "total_questions": 0, "win_rate": 0.0}}, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 加载游戏数据
|
||||
def load_game_data():
|
||||
ensure_data_file_exists()
|
||||
with open(GAME_DATA_FILE, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
# 保存游戏数据
|
||||
def save_game_data(data):
|
||||
with open(GAME_DATA_FILE, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
class TurtleSoupGame:
|
||||
"""海龟汤游戏类"""
|
||||
|
||||
def __init__(self):
|
||||
self.story = None
|
||||
self.solution = None
|
||||
self.game_over = False
|
||||
self.session_id = str(int(time.time()))
|
||||
self.game_start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.game_end_time = None
|
||||
self.session_data = {
|
||||
"session_id": self.session_id,
|
||||
"start_time": self.game_start_time,
|
||||
"end_time": None,
|
||||
"story": None,
|
||||
"solution": None,
|
||||
"game_type": "",
|
||||
"is_custom": False,
|
||||
"questions": [],
|
||||
"guesses": [],
|
||||
"hints": [],
|
||||
"result": "未完成"
|
||||
}
|
||||
|
||||
def generate_story(self, story_type="随机"):
|
||||
"""生成海龟汤题目"""
|
||||
print("正在生成海龟汤题目...")
|
||||
|
||||
try:
|
||||
response = client.chat.completions.create(
|
||||
model="deepseek-chat",
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": "你是一个海龟汤游戏的出题者。请生成一个有趣且有挑战性的海龟汤题目,包含两个部分:1) 简短的奇怪情境描述(2-3句话);2) 完整的故事解释(包含事件的前因后果)。请确保情境足够引人入胜,让玩家有探索的欲望。"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "生成一个海龟汤题目,用中文回答。格式要求:\n情境:[情境描述]\n答案:[完整解释]"
|
||||
}
|
||||
],
|
||||
temperature=1.3,
|
||||
timeout=30 # 添加30秒超时设置
|
||||
)
|
||||
|
||||
print("API调用成功,正在解析结果...")
|
||||
result = response.choices[0].message.content.strip()
|
||||
print(f"\nAPI返回的原始内容: {result[:100]}...\n")
|
||||
|
||||
# 解析生成的内容
|
||||
if "情境:" in result and "答案:" in result:
|
||||
scenario_part = result.split("情境:")[1].split("答案:")[0].strip()
|
||||
solution_part = result.split("答案:")[1].strip()
|
||||
|
||||
self.story = scenario_part
|
||||
self.solution = solution_part
|
||||
|
||||
# 更新会话数据
|
||||
self.session_data["story"] = self.story
|
||||
self.session_data["solution"] = self.solution
|
||||
self.session_data["game_type"] = story_type
|
||||
self.session_data["is_custom"] = False
|
||||
|
||||
print("✅ 海龟汤题目生成成功 ✅")
|
||||
print(f"\n🥣 汤面:{self.story}\n")
|
||||
print("🔍 你可以通过提问来猜测故事的真相,游戏中我只会回答'是'、'否'或'无关'。")
|
||||
print("📋 输入'答案'查看完整故事,输入'新题'生成新的题目,输入'结束'退出游戏。\n")
|
||||
else:
|
||||
print("⚠️ 生成的内容格式不符合要求,使用默认题目...")
|
||||
# 使用默认题目
|
||||
self.story = "一个男人走进一家餐厅,点了一份海龟汤。喝了一口后,他放下汤匙,默默地付了钱离开了餐厅。"
|
||||
self.solution = "这个男人曾经遭遇海难,和同伴被困在荒岛上。为了生存,同伴们煮了海龟汤给他喝,并告诉他这是他妻子的肉。获救后,他在餐厅喝到真正的海龟汤,才知道自己被骗了,同伴们牺牲了自己来救他。"
|
||||
|
||||
# 更新会话数据
|
||||
self.session_data["story"] = self.story
|
||||
self.session_data["solution"] = self.solution
|
||||
self.session_data["game_type"] = story_type
|
||||
self.session_data["is_custom"] = False
|
||||
|
||||
print("✅ 海龟汤题目生成成功 ✅")
|
||||
print(f"\n🥣 汤面:{self.story}\n")
|
||||
print("🔍 你可以通过提问来猜测故事的真相,游戏中我只会回答'是'、'否'或'无关'。")
|
||||
print("📋 输入'答案'查看完整故事,输入'新题'生成新的题目,输入'结束'退出游戏。\n")
|
||||
except Exception as e:
|
||||
print(f"❌ 生成题目时出错: {e}")
|
||||
print("❌ 详细错误信息:")
|
||||
traceback.print_exc()
|
||||
# 使用默认题目作为备选
|
||||
print("\n⚠️ 使用默认题目...")
|
||||
self.story = "一个男人走进一家餐厅,点了一份海龟汤。喝了一口后,他放下汤匙,默默地付了钱离开了餐厅。"
|
||||
self.solution = "这个男人曾经遭遇海难,和同伴被困在荒岛上。为了生存,同伴们煮了海龟汤给他喝,并告诉他这是他妻子的肉。获救后,他在餐厅喝到真正的海龟汤,才知道自己被骗了,同伴们牺牲了自己来救他。"
|
||||
|
||||
# 更新会话数据
|
||||
self.session_data["story"] = self.story
|
||||
self.session_data["solution"] = self.solution
|
||||
self.session_data["game_type"] = story_type
|
||||
self.session_data["is_custom"] = False
|
||||
|
||||
print("✅ 海龟汤题目生成成功 ✅")
|
||||
print(f"\n🥣 汤面:{self.story}\n")
|
||||
print("🔍 你可以通过提问来猜测故事的真相,游戏中我只会回答'是'、'否'或'无关'。")
|
||||
print("📋 输入'答案'查看完整故事,输入'新题'生成新的题目,输入'结束'退出游戏。\n")
|
||||
|
||||
def guess_solution(self, guess):
|
||||
"""处理玩家的答案猜测"""
|
||||
print(f"\n🎯 你的猜测:{guess}")
|
||||
print("🤔 正在评估你的猜测...")
|
||||
|
||||
# 记录猜测
|
||||
self.session_data["guesses"].append({
|
||||
"guess": guess,
|
||||
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
})
|
||||
|
||||
try:
|
||||
# 使用AI评估玩家的猜测
|
||||
response = client.chat.completions.create(
|
||||
model="deepseek-chat",
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": f"你是一个海龟汤游戏的裁判。以下是海龟汤的完整汤底:{self.solution}\n\n现在玩家提出了一个猜测,请你根据汤底内容,评估玩家的猜测是否正确。\n\n评估标准:\n1. 如果玩家的猜测准确包含了汤底的核心信息(主要人物、关键事件、因果关系),回答'正确'\n2. 如果玩家的猜测部分正确,但缺少关键信息,回答'部分正确'\n3. 如果玩家的猜测完全错误,回答'错误'\n\n请只返回'正确'、'部分正确'或'错误',不要添加任何其他解释。"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": guess
|
||||
}
|
||||
],
|
||||
temperature=0.3
|
||||
)
|
||||
|
||||
result = response.choices[0].message.content.strip()
|
||||
|
||||
# 根据评估结果显示反馈
|
||||
if result == "正确":
|
||||
print("\n🎉 恭喜你!你的猜测完全正确!")
|
||||
print(f"🔓 === 完整答案(汤底)=== 🔓")
|
||||
print(f"🍲 汤底:{self.solution}\n")
|
||||
self.game_over = True
|
||||
self.session_data["result"] = "胜利"
|
||||
self.save_game_session()
|
||||
elif result == "部分正确":
|
||||
print("\n👍 你的猜测部分正确,但还有一些关键信息没有猜出来。")
|
||||
print("🔍 继续提问,获取更多线索吧!\n")
|
||||
else:
|
||||
print("\n👎 你的猜测不正确,再试一次吧!")
|
||||
print("🔍 继续提问,获取更多线索吧!\n")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ 评估猜测时出错: {e}")
|
||||
traceback.print_exc()
|
||||
print("🔍 继续提问,获取更多线索吧!\n")
|
||||
|
||||
def get_hint(self):
|
||||
"""生成游戏提示"""
|
||||
print("\n💡 正在生成提示...")
|
||||
|
||||
try:
|
||||
# 使用AI从汤底中生成提示
|
||||
response = client.chat.completions.create(
|
||||
model="deepseek-chat",
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": f"你是一个海龟汤游戏的裁判。以下是海龟汤的完整汤底:{self.solution}\n\n请从汤底中提取1-2条关键线索,这些线索应该能够帮助玩家更好地理解故事,但又不会直接泄露答案。\n\n线索要求:\n1. 只提供事实性信息,不包含解释\n2. 使用简洁的语言\n3. 不要提到汤底的最终结局\n4. 每条线索以'提示X:'开头"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "请生成1-2条线索"
|
||||
}
|
||||
],
|
||||
temperature=0.5
|
||||
)
|
||||
|
||||
hint = response.choices[0].message.content.strip()
|
||||
print(f"\n🎯 提示:\n{hint}\n")
|
||||
|
||||
# 记录提示
|
||||
self.session_data["hints"].append({
|
||||
"hint": hint,
|
||||
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ 生成提示时出错: {e}")
|
||||
traceback.print_exc()
|
||||
# 如果AI生成失败,提供一个通用提示
|
||||
generic_hint = "提示1:关注汤面中的异常细节\n提示2:考虑人物之间的关系和动机"
|
||||
print(f"\n🎯 提示:\n{generic_hint}\n")
|
||||
|
||||
# 记录提示
|
||||
self.session_data["hints"].append({
|
||||
"hint": generic_hint,
|
||||
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
})
|
||||
|
||||
def answer_question(self, question):
|
||||
"""回答用户的问题"""
|
||||
# 检查是否是查看答案命令
|
||||
if question.strip().lower() in ["答案", "查看答案"]:
|
||||
print(f"\n🔓 === 完整答案(汤底)=== 🔓")
|
||||
print(f"🍲 汤底:{self.solution}\n")
|
||||
self.game_over = True
|
||||
self.session_data["result"] = "查看答案"
|
||||
self.save_game_session()
|
||||
return
|
||||
|
||||
# 检查是否是结束游戏命令
|
||||
if question.strip().lower() in ["结束", "退出"]:
|
||||
print("\n👋 游戏已结束,感谢参与!")
|
||||
self.game_over = True
|
||||
self.session_data["result"] = "中途退出"
|
||||
self.save_game_session()
|
||||
return
|
||||
|
||||
# 检查是否是生成新题命令
|
||||
if question.strip().lower() in ["新题", "重新开始", "生成新题", "换一个"]:
|
||||
print("\n🔄 正在生成新的海龟汤题目...\n")
|
||||
self.save_game_session() # 保存当前游戏
|
||||
self.__init__() # 重置游戏状态
|
||||
self.generate_story()
|
||||
return
|
||||
|
||||
# 检查是否是创建自定义题目命令
|
||||
if question.strip().lower() in ["自定义", "创建题目", "自己出题"]:
|
||||
self.create_custom_story()
|
||||
return
|
||||
|
||||
# 检查是否是获取提示命令
|
||||
if question.strip().lower() in ["提示", "线索", "给个提示", "给点线索"]:
|
||||
self.get_hint()
|
||||
return
|
||||
|
||||
# 检查是否是猜测答案命令
|
||||
if question.strip().lower().startswith("猜测") or question.strip().lower().startswith("我猜"):
|
||||
# 提取猜测内容(去除命令前缀)
|
||||
guess = question.strip()[2:].strip()
|
||||
if guess:
|
||||
self.guess_solution(guess)
|
||||
else:
|
||||
print("\n⚠️ 请输入你的猜测内容,例如:猜测 小明是个摄影师\n")
|
||||
return
|
||||
|
||||
# 记录问题
|
||||
self.session_data["questions"].append({
|
||||
"question": question,
|
||||
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
})
|
||||
|
||||
try:
|
||||
# 使用AI回答问题
|
||||
response = client.chat.completions.create(
|
||||
model="deepseek-chat",
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": f"你是一个海龟汤游戏的裁判。以下是海龟汤的完整故事:{self.solution}\n\n现在玩家提出了一个问题,请你根据故事内容,只能用'是'、'否'或'无关'来回答。如果问题直接或间接涉及到故事的关键信息,回答'是'或'否';如果问题与故事完全无关,回答'无关'。"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": question
|
||||
}
|
||||
],
|
||||
temperature=0.3 # 降低温度,使回答更准确
|
||||
)
|
||||
|
||||
answer = response.choices[0].message.content.strip()
|
||||
|
||||
# 确保回答符合要求
|
||||
if answer not in ["是", "否", "无关"]:
|
||||
# 如果回答不符合要求,尝试解析
|
||||
if "是" in answer:
|
||||
answer = "是"
|
||||
elif "否" in answer:
|
||||
answer = "否"
|
||||
else:
|
||||
answer = "无关"
|
||||
|
||||
# 记录回答
|
||||
self.session_data["questions"][-1]["answer"] = answer
|
||||
|
||||
return answer
|
||||
except Exception as e:
|
||||
print(f"回答问题时出错: {e}")
|
||||
traceback.print_exc()
|
||||
return "无关"
|
||||
|
||||
def save_game_session(self):
|
||||
"""保存游戏会话数据到JSON文件"""
|
||||
self.game_end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.session_data["end_time"] = self.game_end_time
|
||||
|
||||
# 加载现有数据
|
||||
ensure_data_file_exists()
|
||||
game_data = load_game_data()
|
||||
|
||||
# 添加当前游戏数据
|
||||
game_data["games"].append(self.session_data)
|
||||
|
||||
# 更新统计信息
|
||||
total_games = len(game_data["games"])
|
||||
won_games = sum(1 for game in game_data["games"] if game["result"] == "胜利")
|
||||
total_questions = sum(len(game["questions"]) for game in game_data["games"])
|
||||
|
||||
game_data["statistics"] = {
|
||||
"total_games": total_games,
|
||||
"total_questions": total_questions,
|
||||
"win_rate": won_games / total_games if total_games > 0 else 0.0
|
||||
}
|
||||
|
||||
# 保存数据
|
||||
save_game_data(game_data)
|
||||
print("📊 游戏数据已保存!")
|
||||
|
||||
def create_custom_story(self):
|
||||
"""创建自定义题目"""
|
||||
print("\n📝 创建自定义海龟汤题目")
|
||||
|
||||
try:
|
||||
# 获取用户输入的汤面
|
||||
story = input("请输入汤面(奇怪的情境): ")
|
||||
if not story.strip():
|
||||
print("⚠️ 汤面不能为空,请重新输入!\n")
|
||||
return
|
||||
|
||||
# 获取用户输入的汤底
|
||||
solution = input("请输入汤底(完整解释): ")
|
||||
if not solution.strip():
|
||||
print("⚠️ 汤底不能为空,请重新输入!\n")
|
||||
return
|
||||
|
||||
self.story = story.strip()
|
||||
self.solution = solution.strip()
|
||||
|
||||
# 更新会话数据
|
||||
self.session_data["story"] = self.story
|
||||
self.session_data["solution"] = self.solution
|
||||
self.session_data["game_type"] = "自定义"
|
||||
self.session_data["is_custom"] = True
|
||||
|
||||
print("\n✅ 自定义题目创建成功!")
|
||||
print(f"🥣 汤面:{self.story}\n")
|
||||
print("🔍 你可以通过提问来猜测故事的真相,游戏中我只会回答'是'、'否'或'无关'。")
|
||||
print("📋 输入'答案'查看完整故事,输入'新题'生成新的题目,输入'结束'退出游戏。\n")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ 创建自定义题目时出错: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
def play(self):
|
||||
"""开始游戏"""
|
||||
print("📜 🐢 ================== 海龟汤游戏 ================== 🐢 📜")
|
||||
print("🔍 海龟汤是一种情境猜谜游戏,我会给出一个奇怪的情境,你可以通过提问来猜测故事的真相。")
|
||||
print("💬 我只会回答'是'、'否'或'无关'。")
|
||||
print("📋 输入'答案'查看完整故事,输入'新题'生成新的题目,输入'自定义'创建自己的题目,")
|
||||
print("📋 输入'提示'获取线索,输入'猜测 内容'尝试猜测答案,输入'结束'退出游戏。\n")
|
||||
|
||||
# 确保数据文件存在
|
||||
ensure_data_file_exists()
|
||||
|
||||
# 游戏模式选择
|
||||
while True:
|
||||
print("🎮 游戏模式选择:")
|
||||
print("1. 使用AI生成的题目")
|
||||
print("2. 自定义题目")
|
||||
|
||||
choice = input("请选择模式 (1/2): ")
|
||||
if choice == "1":
|
||||
# 生成题目
|
||||
self.generate_story()
|
||||
break
|
||||
elif choice == "2":
|
||||
# 创建自定义题目
|
||||
self.create_custom_story()
|
||||
break
|
||||
else:
|
||||
print("⚠️ 无效的选择,请重新输入!\n")
|
||||
|
||||
# 游戏主循环
|
||||
while not self.game_over:
|
||||
try:
|
||||
question = input("👤 请提问:")
|
||||
if not question.strip():
|
||||
continue
|
||||
|
||||
answer = self.answer_question(question)
|
||||
if not self.game_over: # 如果游戏还没结束且有回答
|
||||
print(f"🤖 回答:{answer}\n")
|
||||
except Exception as e:
|
||||
print(f"❌ 游戏交互时出错: {e}")
|
||||
traceback.print_exc()
|
||||
continue
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
game = TurtleSoupGame()
|
||||
game.play()
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n游戏已中断,感谢参与!")
|
||||
except Exception as e:
|
||||
print(f"\n游戏出错:{e}")
|
||||
traceback.print_exc()
|
||||
52
test_keyword_fix.py
Normal file
52
test_keyword_fix.py
Normal file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
# 测试关键词修复脚本
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加当前目录到sys.path
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# 直接导入structual模块
|
||||
import structual
|
||||
|
||||
def test_keyword_fix():
|
||||
"""测试关键词修复"""
|
||||
print("=== 测试关键词修复 ===")
|
||||
|
||||
# 创建游戏实例
|
||||
game = structual.TurtleSoupGame()
|
||||
|
||||
# 手动设置代孕相关的故事(第12个故事,索引11)
|
||||
target_story_index = 11
|
||||
game.story = game.DEFAULT_STORIES[target_story_index]["scenario"]
|
||||
game.solution = game.DEFAULT_STORIES[target_story_index]["solution"]
|
||||
|
||||
print(f"\n选择的故事:{game.story}")
|
||||
print(f"答案:{game.solution}")
|
||||
|
||||
# 测试问题列表
|
||||
test_questions = [
|
||||
"涉及代孕吗?",
|
||||
"这个女人是代孕妈妈吗?",
|
||||
"是否有代孕相关的内容?",
|
||||
"孩子的父亲存在吗?",
|
||||
"这是关于犯罪的吗?"
|
||||
]
|
||||
|
||||
print("\n=== 测试问题和回答 ===")
|
||||
for question in test_questions:
|
||||
# 调用实际的answer_question方法
|
||||
answer = game.answer_question(question)
|
||||
|
||||
print(f"问题:{question}")
|
||||
print(f"回答:{answer}")
|
||||
|
||||
# 检查关键修复点
|
||||
if "代孕" in question.lower() and answer == "是":
|
||||
print("✅ 关键修复:'代孕'关键词匹配成功!")
|
||||
|
||||
print("\n=== 测试完成 ===")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_keyword_fix()
|
||||
111
turtle_soup_data.json
Normal file
111
turtle_soup_data.json
Normal file
@ -0,0 +1,111 @@
|
||||
{
|
||||
"games": [
|
||||
{
|
||||
"session_id": "1767764942",
|
||||
"start_time": "2026-01-07 13:49:02",
|
||||
"end_time": "2026-01-07 13:49:58",
|
||||
"story": "** \n一个男人走进一家24小时营业的便利店,买了一把剪刀、一卷胶带和一束白花。第二天清晨,店员在监控中发现这个男人在店外的人行道上站了整整一夜,但男人手中只剩下胶带和剪刀,白花却消失了。更奇怪的是,男人离开时表情平静,仿佛完成了一件重要的事。 \n\n**",
|
||||
"solution": "** \n男人是一名葬礼策划师,他的妻子在前一天因车祸去世。妻子生前最爱白花,曾开玩笑说如果自己先离开,希望丈夫能在他们第一次相遇的地方为她守夜。男人在便利店买白花是为了祭奠,剪刀和胶带则是为了修剪花束并固定悼念卡片。 \n当天午夜,他带着花来到便利店外的路口——那里正是他和妻子初次相遇的地点。他在寒风中站了一夜,默默回忆过往。天亮前,一阵强风将白花吹散,花瓣飘进路边的排水沟,只剩空枝被男人收起。他用胶带和剪刀简单处理了残枝,随后离开。店员通过监控只看到男人手持物品的变化,却不知风带走了花,也不懂男人守夜后释然的心情。",
|
||||
"game_type": "随机",
|
||||
"is_custom": false,
|
||||
"questions": [],
|
||||
"guesses": [],
|
||||
"hints": [],
|
||||
"result": "中途退出"
|
||||
},
|
||||
{
|
||||
"session_id": "1767765875",
|
||||
"start_time": "2026-01-07 14:04:35",
|
||||
"end_time": "2026-01-07 14:07:26",
|
||||
"story": "一个女人打开了窗户,然后她就死了。",
|
||||
"solution": "这个女人是一个囚犯,被关在一个密封的房间里。她打开的是飞机的窗户,导致机舱失压,她因此死亡。",
|
||||
"game_type": "随机",
|
||||
"is_custom": false,
|
||||
"questions": [
|
||||
{
|
||||
"question": "女人是意外死的吗",
|
||||
"timestamp": "2026-01-07 14:04:53",
|
||||
"answer": "无关"
|
||||
},
|
||||
{
|
||||
"question": "女人是被吓死的吗",
|
||||
"timestamp": "2026-01-07 14:05:24",
|
||||
"answer": "无关"
|
||||
},
|
||||
{
|
||||
"question": "女人是自杀吗",
|
||||
"timestamp": "2026-01-07 14:05:40",
|
||||
"answer": "否"
|
||||
},
|
||||
{
|
||||
"question": "女人是他杀吗",
|
||||
"timestamp": "2026-01-07 14:05:48",
|
||||
"answer": "否"
|
||||
}
|
||||
],
|
||||
"guesses": [
|
||||
{
|
||||
"guess": "她是被监禁的,好不容易打开窗户想逃走,被人发现了",
|
||||
"timestamp": "2026-01-07 14:06:37"
|
||||
}
|
||||
],
|
||||
"hints": [
|
||||
{
|
||||
"hint": "提示1:与监禁有关",
|
||||
"timestamp": "2026-01-07 14:06:00"
|
||||
}
|
||||
],
|
||||
"result": "查看答案"
|
||||
},
|
||||
{
|
||||
"session_id": "1767766209",
|
||||
"start_time": "2026-01-07 14:10:09",
|
||||
"end_time": "2026-01-07 14:10:18",
|
||||
"story": "一个女人打开了窗户,然后她就死了。",
|
||||
"solution": "这个女人是一个囚犯,被关在一个密封的房间里。她打开的是飞机的窗户,导致机舱失压,她因此死亡。",
|
||||
"game_type": "随机",
|
||||
"is_custom": false,
|
||||
"questions": [],
|
||||
"guesses": [],
|
||||
"hints": [],
|
||||
"result": "查看答案"
|
||||
},
|
||||
{
|
||||
"session_id": "1767766220",
|
||||
"start_time": "2026-01-07 14:10:20",
|
||||
"end_time": "2026-01-07 14:10:49",
|
||||
"story": "一个女人在夜晚独自在家,她听到敲门声,打开门却没有人。第二天早上,她发现邻居死了。",
|
||||
"solution": "邻居是一个小偷,想要进入女人的家。他敲门时,女人开门,他被吓得从楼梯上摔了下去,死亡。",
|
||||
"game_type": "随机",
|
||||
"is_custom": false,
|
||||
"questions": [],
|
||||
"guesses": [],
|
||||
"hints": [],
|
||||
"result": "中途退出"
|
||||
},
|
||||
{
|
||||
"session_id": "1767766445",
|
||||
"start_time": "2026-01-07 14:14:05",
|
||||
"end_time": "2026-01-07 14:14:46",
|
||||
"story": "一个男人在雨中行走,没有打伞,也没有戴帽子,但是他的头发没有湿。",
|
||||
"solution": "这个男人是一个秃头。",
|
||||
"game_type": "随机",
|
||||
"is_custom": false,
|
||||
"questions": [
|
||||
{
|
||||
"question": "男人死了吗",
|
||||
"timestamp": "2026-01-07 14:14:35",
|
||||
"answer": "无关"
|
||||
}
|
||||
],
|
||||
"guesses": [],
|
||||
"hints": [],
|
||||
"result": "查看答案"
|
||||
}
|
||||
],
|
||||
"statistics": {
|
||||
"total_games": 5,
|
||||
"total_questions": 5,
|
||||
"win_rate": 0.0
|
||||
}
|
||||
}
|
||||
634
turtle_soup_html.html
Normal file
634
turtle_soup_html.html
Normal file
@ -0,0 +1,634 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🐢 海龟汤游戏</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Microsoft YaHei', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.game-container {
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.game-header {
|
||||
background: linear-gradient(135deg, #4a6fa5 0%, #16222a 100%);
|
||||
color: white;
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.game-header h1 {
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.game-header p {
|
||||
font-size: 1.1em;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.game-main {
|
||||
flex: 1;
|
||||
padding: 30px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.soup-section {
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.soup-section h2 {
|
||||
color: #4a6fa5;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.soup-text {
|
||||
background: #f8f9fa;
|
||||
padding: 25px;
|
||||
border-radius: 15px;
|
||||
font-size: 1.2em;
|
||||
line-height: 1.8;
|
||||
border-left: 5px solid #4a6fa5;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.chat-section {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.chat-section h2 {
|
||||
color: #4a6fa5;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.chat-history {
|
||||
background: #f8f9fa;
|
||||
padding: 20px;
|
||||
border-radius: 15px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.chat-message {
|
||||
margin-bottom: 15px;
|
||||
padding: 12px 18px;
|
||||
border-radius: 18px;
|
||||
max-width: 80%;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.user-message {
|
||||
background: #4a6fa5;
|
||||
color: white;
|
||||
margin-left: auto;
|
||||
border-bottom-right-radius: 6px;
|
||||
}
|
||||
|
||||
.bot-message {
|
||||
background: #e9ecef;
|
||||
color: #495057;
|
||||
margin-right: auto;
|
||||
border-bottom-left-radius: 6px;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
text-align: center;
|
||||
margin: 0 auto 15px;
|
||||
max-width: 90%;
|
||||
border-radius: 12px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.input-section {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
#question-input {
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
border: 2px solid #ced4da;
|
||||
border-radius: 25px;
|
||||
font-size: 1em;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
#question-input:focus {
|
||||
outline: none;
|
||||
border-color: #4a6fa5;
|
||||
box-shadow: 0 0 0 0.2rem rgba(74, 111, 165, 0.25);
|
||||
}
|
||||
|
||||
#send-button {
|
||||
padding: 15px 30px;
|
||||
background: linear-gradient(135deg, #4a6fa5, #16222a);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
#send-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 15px rgba(74, 111, 165, 0.4);
|
||||
}
|
||||
|
||||
#send-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.game-controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
flex: 1;
|
||||
min-width: 120px;
|
||||
padding: 12px;
|
||||
background: linear-gradient(135deg, #6c757d, #495057);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
font-size: 0.9em;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.control-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(108, 117, 125, 0.4);
|
||||
}
|
||||
|
||||
.new-game-btn {
|
||||
background: linear-gradient(135deg, #28a745, #218838);
|
||||
}
|
||||
|
||||
.hint-btn {
|
||||
background: linear-gradient(135deg, #ffc107, #e0a800);
|
||||
}
|
||||
|
||||
.answer-btn {
|
||||
background: linear-gradient(135deg, #dc3545, #c82333);
|
||||
}
|
||||
|
||||
.guess-btn {
|
||||
background: linear-gradient(135deg, #fd7e14, #e0a800);
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
background: #f8f9fa;
|
||||
border-top: 1px solid #dee2e6;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.game-container {
|
||||
margin: 10px;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.game-header {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.game-header h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.game-main {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.input-section {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="game-container">
|
||||
<header class="game-header">
|
||||
<h1>🐢 海龟汤游戏</h1>
|
||||
<p>通过提问来猜测故事的真相,我只会回答「是」、「否」或「无关」</p>
|
||||
</header>
|
||||
|
||||
<main class="game-main">
|
||||
<section class="soup-section">
|
||||
<h2>🥣 汤面</h2>
|
||||
<div class="soup-text" id="soup-text">点击「新游戏」开始游戏</div>
|
||||
</section>
|
||||
|
||||
<section class="chat-section">
|
||||
<h2>💬 对话</h2>
|
||||
<div class="chat-history" id="chat-history">
|
||||
<div class="system-message">欢迎来到海龟汤游戏!点击「新游戏」开始,或者查看规则。</div>
|
||||
</div>
|
||||
|
||||
<div class="input-section">
|
||||
<input type="text" id="question-input" placeholder="请输入你的问题..." autocomplete="off">
|
||||
<button id="send-button">发送</button>
|
||||
</div>
|
||||
|
||||
<div class="game-controls">
|
||||
<button class="control-button new-game-btn" id="new-game-btn">新游戏</button>
|
||||
<button class="control-button hint-btn" id="hint-btn">提示</button>
|
||||
<button class="control-button answer-btn" id="answer-btn">查看答案</button>
|
||||
<button class="control-button guess-btn" id="guess-btn">我来猜测</button>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<p>🐢 海龟汤游戏 | 直接在浏览器中游玩</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 初始化函数,确保页面加载完成后执行所有DOM操作
|
||||
window.addEventListener('load', () => {
|
||||
// 海龟汤题目库
|
||||
const DEFAULT_STORIES = [
|
||||
{
|
||||
scenario: "一个男人走进一家餐厅,点了一份海龟汤。喝了一口后,他放下汤匙,默默地付了钱离开了餐厅。",
|
||||
solution: "这个男人曾经遭遇海难,和同伴被困在荒岛上。为了生存,同伴们煮了海龟汤给他喝,并告诉他这是他妻子的肉。获救后,他在餐厅喝到真正的海龟汤,才知道自己被骗了,同伴们牺牲了自己来救他。"
|
||||
},
|
||||
{
|
||||
scenario: "一个女人从窗户跳了出去,却没有受伤。她回头看了看,然后笑了。",
|
||||
solution: "这个女人是一名囚犯,她被关在飞机的货舱里。当飞机飞行时,她打开了飞机上的紧急出口窗户,利用降落伞安全着陆。回头看到飞机继续飞行,她知道自己成功逃脱了,所以笑了。"
|
||||
},
|
||||
{
|
||||
scenario: "一个人下雨天走在路上,没有打伞,头发却没有湿。他是怎么做到的?",
|
||||
solution: "这个人是秃头,没有头发,所以头发不会湿。"
|
||||
},
|
||||
{
|
||||
scenario: "一个小偷晚上潜入一栋房子,偷了一些贵重物品。当他准备离开时,听到了敲门声, subsequent邻居死了。",
|
||||
solution: "小偷在偷东西时,不小心碰倒了楼梯上的花瓶,花瓶滚下楼梯,发出很大的声响。邻居听到声响后出来查看,在下楼梯时被滚下来的花瓶绊倒,摔死了。"
|
||||
},
|
||||
{
|
||||
scenario: "一个人在沙漠中发现了一个瓶子,打开后却死亡了。",
|
||||
solution: "这个瓶子是一个地雷的触发装置。当这个人打开瓶子时,触发了地雷,导致他死亡。"
|
||||
},
|
||||
{
|
||||
scenario: "一个小女孩在生日宴会上吹灭了蜡烛,她的父母却哭了。",
|
||||
solution: "小女孩患有绝症,医生告诉她的父母她只能活到七岁。今天是她的七岁生日,当她吹灭蜡烛时,她的父母知道这可能是她最后一个生日了,所以哭了。"
|
||||
},
|
||||
{
|
||||
scenario: "一个消防员在火灾现场救出了所有人,当他准备离开时,按下了电梯按钮,却突然哭了。",
|
||||
solution: "消防员在火灾中救出了所有人,但在最后一次进入火场时,他的队友被困在了里面。当他按下电梯按钮,准备离开时,看到了电梯里显示的楼层,意识到队友所在的楼层已经被大火吞噬,队友已经牺牲,所以哭了。"
|
||||
},
|
||||
{
|
||||
scenario: "一个女人在图书馆工作,每天都会在一本书里夹一张纸条。有一天,她没有夹纸条,她的丈夫失踪了。",
|
||||
solution: "女人的丈夫是一名记者,正在调查一个犯罪团伙。他每天都会到图书馆找女人,通过书中的纸条传递信息。有一天,犯罪团伙发现了他们的计划,绑架了丈夫,并威胁女人如果再传递信息就杀死丈夫。所以女人不敢再夹纸条了。"
|
||||
},
|
||||
{
|
||||
scenario: "一个猎人在森林中开枪,结果却被捕了。",
|
||||
solution: "猎人在森林中打猎时,误将一名徒步旅行者当成了猎物开枪打死了。他因为过失杀人而被捕。"
|
||||
},
|
||||
{
|
||||
scenario: "一个人买了一瓶饮料,看到瓶盖里写着「再来一瓶」,却哭了。",
|
||||
solution: "这个人患有癌症,需要昂贵的治疗费用。他的家庭已经负债累累,当他看到瓶盖里的「再来一瓶」时,想起自己的病情和家庭的困境,感到绝望,所以哭了。"
|
||||
},
|
||||
{
|
||||
scenario: "一个火车站的工作人员,每天都会在站台上做一个奇怪的手势,火车司机看到后就会停车。",
|
||||
solution: "这个工作人员负责在站台上保护乘客的安全。有一天,一个小孩跑到了铁轨上,工作人员看到后,做出了紧急停车的手势。火车司机看到后立即停车,避免了悲剧的发生。从那以后,工作人员每天都会做这个手势,提醒火车司机注意安全。"
|
||||
},
|
||||
{
|
||||
scenario: "一个女人在医院里生下了一个孩子,但是她却没有见过这个孩子的父亲。",
|
||||
solution: "这个女人是一名代孕妈妈。一对不能生育的夫妇雇佣她代孕,孩子的生物学父亲是这对夫妇中的丈夫,但女人从未见过他。"
|
||||
},
|
||||
{
|
||||
scenario: "一个警察在咖啡馆里喝咖啡,突然打翻了杯子,然后冲出了咖啡馆。",
|
||||
solution: "警察正在追捕一名通缉犯。当他在咖啡馆里喝咖啡时,看到通缉犯走进了咖啡馆。他不小心打翻了杯子,然后立即冲出咖啡馆去追捕通缉犯。"
|
||||
},
|
||||
{
|
||||
scenario: "一个男人在马路上行走,突然心脏病发作。一辆路过的汽车紧急刹车,却导致了他的死亡。",
|
||||
solution: "男人心脏病发作时,一辆汽车紧急刹车,发出很大的声响。这个声响导致男人受到惊吓,心脏病加重,最终死亡。"
|
||||
},
|
||||
{
|
||||
scenario: "一个人在海边散步,捡到了一个漂流瓶。当他打开瓶子看到里面的内容后,跳海自杀了。",
|
||||
solution: "这个人患有抑郁症,曾经在绝望中写了一封遗书,装进漂流瓶里扔进了大海。几年后,他的病情有所好转,开始重新面对生活。当他在海边捡到这个漂流瓶,看到自己几年前写的遗书时,想起了过去的痛苦,感到绝望,所以跳海自杀了。"
|
||||
}
|
||||
];
|
||||
|
||||
// 关键词列表
|
||||
const YES_KEYWORDS = [
|
||||
// 海难荒岛系列
|
||||
"海难", "荒岛", "同伴", "牺牲", "妻子", "肉", "获救", "被困", "生存",
|
||||
// 囚犯飞机系列
|
||||
"囚犯", "飞机", "窗户", "失压", "密封", "机舱",
|
||||
// 秃头系列
|
||||
"秃头", "头发", "湿",
|
||||
// 小偷系列
|
||||
"小偷", "楼梯", "摔", "敲门", "邻居",
|
||||
// 地雷系列
|
||||
"地雷", "触发", "沙漠", "瓶子",
|
||||
// 绝症生日系列
|
||||
"绝症", "生日", "蜡烛", "提前", "父母", "哭泣",
|
||||
// 消防员系列
|
||||
"消防员", "火灾", "队友", "牺牲", "电梯", "楼层", "哭泣",
|
||||
// 图书馆记者系列
|
||||
"图书馆", "纸条", "丈夫", "失踪", "记者", "绑架", "囚禁", "犯罪团伙",
|
||||
// 猎人误伤系列
|
||||
"猎人", "误伤", "森林", "徒步旅行", "法律责任", "枪声",
|
||||
// 癌症治疗系列
|
||||
"癌症", "治疗费用", "再来一瓶", "承受能力", "昂贵",
|
||||
// 火车站救孩子系列
|
||||
"火车站", "工作人员", "救孩子", "刹车", "站台", "手势",
|
||||
// 代孕系列
|
||||
"代孕妈妈", "代孕", "不能生育", "夫妇", "医院", "孩子", "父亲", "生物学父亲",
|
||||
// 警察通缉犯系列
|
||||
"警察", "通缉犯", "追捕", "咖啡馆", "打翻", "冲出",
|
||||
// 心脏病发作系列
|
||||
"心脏病", "紧急刹车", "巧合", "外伤", "过马路", "发作",
|
||||
// 漂流瓶自杀系列
|
||||
"漂流瓶", "自杀", "抑郁症", "荒岛", "幸存", "命运的讽刺", "跳海", "海浪"
|
||||
];
|
||||
|
||||
const NO_KEYWORDS = [
|
||||
"毒药", "刀", "枪", "炸弹", "爆炸",
|
||||
"中毒", "淹死", "电击", "触电",
|
||||
"刺杀", "枪杀", "投毒", "谋杀",
|
||||
"自杀死", "他杀死", "掐死", "勒死"
|
||||
];
|
||||
|
||||
// 游戏状态
|
||||
let currentStory = null;
|
||||
let currentSolution = null;
|
||||
let gameOver = false;
|
||||
|
||||
// DOM元素 - 在页面加载完成后获取
|
||||
const soupText = document.getElementById('soup-text');
|
||||
const chatHistory = document.getElementById('chat-history');
|
||||
const questionInput = document.getElementById('question-input');
|
||||
const sendButton = document.getElementById('send-button');
|
||||
const newGameBtn = document.getElementById('new-game-btn');
|
||||
const hintBtn = document.getElementById('hint-btn');
|
||||
const answerBtn = document.getElementById('answer-btn');
|
||||
const guessBtn = document.getElementById('guess-btn');
|
||||
|
||||
// 初始化游戏
|
||||
function initGame() {
|
||||
// 随机选择一个题目
|
||||
const randomIndex = Math.floor(Math.random() * DEFAULT_STORIES.length);
|
||||
const story = DEFAULT_STORIES[randomIndex];
|
||||
|
||||
currentStory = story.scenario;
|
||||
currentSolution = story.solution;
|
||||
gameOver = false;
|
||||
|
||||
// 更新界面
|
||||
updateSoupText();
|
||||
clearChatHistory();
|
||||
addSystemMessage('游戏开始!请开始提问,我只会回答「是」、「否」或「无关」。');
|
||||
}
|
||||
|
||||
// 更新汤面显示
|
||||
function updateSoupText() {
|
||||
soupText.textContent = currentStory;
|
||||
}
|
||||
|
||||
// 清空聊天历史
|
||||
function clearChatHistory() {
|
||||
chatHistory.innerHTML = '';
|
||||
}
|
||||
|
||||
// 添加系统消息
|
||||
function addSystemMessage(message) {
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = 'system-message';
|
||||
messageDiv.textContent = message;
|
||||
chatHistory.appendChild(messageDiv);
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
// 添加用户消息
|
||||
function addUserMessage(message) {
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = 'chat-message user-message';
|
||||
messageDiv.textContent = message;
|
||||
chatHistory.appendChild(messageDiv);
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
// 添加机器人消息
|
||||
function addBotMessage(message) {
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = 'chat-message bot-message';
|
||||
messageDiv.textContent = message;
|
||||
chatHistory.appendChild(messageDiv);
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
// 滚动到底部
|
||||
function scrollToBottom() {
|
||||
chatHistory.scrollTop = chatHistory.scrollHeight;
|
||||
}
|
||||
|
||||
// 回答问题
|
||||
function answerQuestion(question) {
|
||||
if (gameOver) return "游戏已结束,请点击「新游戏」重新开始。";
|
||||
|
||||
const questionLower = question.toLowerCase();
|
||||
const solutionLower = currentSolution.toLowerCase();
|
||||
|
||||
// 检查命令
|
||||
if (questionLower.includes("答案") || questionLower.includes("真相")) {
|
||||
revealAnswer();
|
||||
return;
|
||||
}
|
||||
|
||||
if (questionLower.includes("提示") || questionLower.includes("线索")) {
|
||||
giveHint();
|
||||
return;
|
||||
}
|
||||
|
||||
// 关键词匹配
|
||||
const questionYesKeywords = YES_KEYWORDS.filter(keyword => questionLower.includes(keyword));
|
||||
|
||||
if (questionYesKeywords.length > 0) {
|
||||
// 检查这些关键词是否在答案中出现
|
||||
for (const keyword of questionYesKeywords) {
|
||||
if (solutionLower.includes(keyword)) {
|
||||
return "是";
|
||||
}
|
||||
}
|
||||
return "否";
|
||||
} else if (NO_KEYWORDS.some(keyword => questionLower.includes(keyword))) {
|
||||
return "否";
|
||||
} else {
|
||||
return "无关";
|
||||
}
|
||||
}
|
||||
|
||||
// 给出提示
|
||||
function giveHint() {
|
||||
if (!currentSolution) return;
|
||||
|
||||
const solution = currentSolution;
|
||||
let hint = "";
|
||||
|
||||
// 简单的提示生成逻辑
|
||||
if (solution.includes("海难")) {
|
||||
hint = "这个故事与海难和生存有关。";
|
||||
} else if (solution.includes("囚犯")) {
|
||||
hint = "这个故事与囚犯和飞机有关。";
|
||||
} else if (solution.includes("秃头")) {
|
||||
hint = "这个故事与头发有关。";
|
||||
} else if (solution.includes("小偷")) {
|
||||
hint = "这个故事与小偷和邻居有关。";
|
||||
} else if (solution.includes("地雷")) {
|
||||
hint = "这个故事与沙漠和危险物品有关。";
|
||||
} else if (solution.includes("绝症")) {
|
||||
hint = "这个故事与疾病和生日有关。";
|
||||
} else if (solution.includes("消防员")) {
|
||||
hint = "这个故事与火灾救援有关。";
|
||||
} else if (solution.includes("图书馆")) {
|
||||
hint = "这个故事与图书馆和信息传递有关。";
|
||||
} else if (solution.includes("猎人")) {
|
||||
hint = "这个故事与打猎和意外有关。";
|
||||
} else if (solution.includes("癌症")) {
|
||||
hint = "这个故事与疾病和经济困难有关。";
|
||||
} else if (solution.includes("火车站")) {
|
||||
hint = "这个故事与火车站和安全有关。";
|
||||
} else if (solution.includes("代孕")) {
|
||||
hint = "这个故事与生育和医院有关。";
|
||||
} else if (solution.includes("警察")) {
|
||||
hint = "这个故事与警察和追捕有关。";
|
||||
} else if (solution.includes("心脏病")) {
|
||||
hint = "这个故事与疾病和交通事故有关。";
|
||||
} else if (solution.includes("漂流瓶")) {
|
||||
hint = "这个故事与海洋和心理健康有关。";
|
||||
} else {
|
||||
hint = "关注故事中的关键人物和事件之间的联系。";
|
||||
}
|
||||
|
||||
addSystemMessage(`💡 提示:${hint}`);
|
||||
}
|
||||
|
||||
// 显示答案
|
||||
function revealAnswer() {
|
||||
if (!currentSolution) return;
|
||||
|
||||
gameOver = true;
|
||||
addSystemMessage(`🔓 答案:${currentSolution}`);
|
||||
addSystemMessage('游戏结束!点击「新游戏」开始新的一局。');
|
||||
}
|
||||
|
||||
// 处理猜测
|
||||
function handleGuess() {
|
||||
const guess = prompt("请输入你的猜测:");
|
||||
if (guess) {
|
||||
addUserMessage(`猜测:${guess}`);
|
||||
|
||||
const guessLower = guess.toLowerCase();
|
||||
const solutionLower = currentSolution.toLowerCase();
|
||||
|
||||
// 简单的猜测评估逻辑
|
||||
if (solutionLower.includes(guessLower)) {
|
||||
addBotMessage("恭喜你!猜测正确!");
|
||||
revealAnswer();
|
||||
} else {
|
||||
addBotMessage("猜测不正确,请继续提问。");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 发送问题
|
||||
function sendQuestion() {
|
||||
const question = questionInput.value.trim();
|
||||
if (!question) return;
|
||||
|
||||
addUserMessage(question);
|
||||
questionInput.value = '';
|
||||
|
||||
const answer = answerQuestion(question);
|
||||
if (answer) {
|
||||
addBotMessage(answer);
|
||||
}
|
||||
}
|
||||
|
||||
// 事件监听器 - 在页面加载完成后绑定
|
||||
sendButton.addEventListener('click', sendQuestion);
|
||||
|
||||
questionInput.addEventListener('keypress', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
sendQuestion();
|
||||
}
|
||||
});
|
||||
|
||||
newGameBtn.addEventListener('click', initGame);
|
||||
|
||||
hintBtn.addEventListener('click', () => {
|
||||
if (!currentStory) {
|
||||
addSystemMessage('请先点击「新游戏」开始游戏。');
|
||||
} else {
|
||||
giveHint();
|
||||
}
|
||||
});
|
||||
|
||||
answerBtn.addEventListener('click', () => {
|
||||
if (!currentStory) {
|
||||
addSystemMessage('请先点击「新游戏」开始游戏。');
|
||||
} else {
|
||||
revealAnswer();
|
||||
}
|
||||
});
|
||||
|
||||
guessBtn.addEventListener('click', () => {
|
||||
if (!currentStory) {
|
||||
addSystemMessage('请先点击「新游戏」开始游戏。');
|
||||
} else {
|
||||
handleGuess();
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化 - 添加欢迎消息
|
||||
addSystemMessage('欢迎来到海龟汤游戏!点击「新游戏」开始游戏。');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
301
uv.lock
generated
Normal file
301
uv.lock
generated
Normal file
@ -0,0 +1,301 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.13"
|
||||
|
||||
[[package]]
|
||||
name = "annotated-types"
|
||||
version = "0.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.12.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2026.1.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "distro"
|
||||
version = "1.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.16.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "h11" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.28.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "certifi" },
|
||||
{ name = "httpcore" },
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.11"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jiter"
|
||||
version = "0.12.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/45/9d/e0660989c1370e25848bb4c52d061c71837239738ad937e83edca174c273/jiter-0.12.0.tar.gz", hash = "sha256:64dfcd7d5c168b38d3f9f8bba7fc639edb3418abcc74f22fdbe6b8938293f30b", size = 168294, upload-time = "2025-11-09T20:49:23.302Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/a6/97209693b177716e22576ee1161674d1d58029eb178e01866a0422b69224/jiter-0.12.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6cc49d5130a14b732e0612bc76ae8db3b49898732223ef8b7599aa8d9810683e", size = 313658, upload-time = "2025-11-09T20:47:44.424Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/4d/125c5c1537c7d8ee73ad3d530a442d6c619714b95027143f1b61c0b4dfe0/jiter-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37f27a32ce36364d2fa4f7fdc507279db604d27d239ea2e044c8f148410defe1", size = 318605, upload-time = "2025-11-09T20:47:45.973Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/bf/a840b89847885064c41a5f52de6e312e91fa84a520848ee56c97e4fa0205/jiter-0.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbc0944aa3d4b4773e348cda635252824a78f4ba44328e042ef1ff3f6080d1cf", size = 349803, upload-time = "2025-11-09T20:47:47.535Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/88/e63441c28e0db50e305ae23e19c1d8fae012d78ed55365da392c1f34b09c/jiter-0.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da25c62d4ee1ffbacb97fac6dfe4dcd6759ebdc9015991e92a6eae5816287f44", size = 365120, upload-time = "2025-11-09T20:47:49.284Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/7c/49b02714af4343970eb8aca63396bc1c82fa01197dbb1e9b0d274b550d4e/jiter-0.12.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:048485c654b838140b007390b8182ba9774621103bd4d77c9c3f6f117474ba45", size = 479918, upload-time = "2025-11-09T20:47:50.807Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/ba/0a809817fdd5a1db80490b9150645f3aae16afad166960bcd562be194f3b/jiter-0.12.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:635e737fbb7315bef0037c19b88b799143d2d7d3507e61a76751025226b3ac87", size = 379008, upload-time = "2025-11-09T20:47:52.211Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/c3/c9fc0232e736c8877d9e6d83d6eeb0ba4e90c6c073835cc2e8f73fdeef51/jiter-0.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e017c417b1ebda911bd13b1e40612704b1f5420e30695112efdbed8a4b389ed", size = 361785, upload-time = "2025-11-09T20:47:53.512Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/61/61f69b7e442e97ca6cd53086ddc1cf59fb830549bc72c0a293713a60c525/jiter-0.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:89b0bfb8b2bf2351fba36bb211ef8bfceba73ef58e7f0c68fb67b5a2795ca2f9", size = 386108, upload-time = "2025-11-09T20:47:54.893Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/2e/76bb3332f28550c8f1eba3bf6e5efe211efda0ddbbaf24976bc7078d42a5/jiter-0.12.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:f5aa5427a629a824a543672778c9ce0c5e556550d1569bb6ea28a85015287626", size = 519937, upload-time = "2025-11-09T20:47:56.253Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/d6/fa96efa87dc8bff2094fb947f51f66368fa56d8d4fc9e77b25d7fbb23375/jiter-0.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed53b3d6acbcb0fd0b90f20c7cb3b24c357fe82a3518934d4edfa8c6898e498c", size = 510853, upload-time = "2025-11-09T20:47:58.32Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/28/93f67fdb4d5904a708119a6ab58a8f1ec226ff10a94a282e0215402a8462/jiter-0.12.0-cp313-cp313-win32.whl", hash = "sha256:4747de73d6b8c78f2e253a2787930f4fffc68da7fa319739f57437f95963c4de", size = 204699, upload-time = "2025-11-09T20:47:59.686Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/1f/30b0eb087045a0abe2a5c9c0c0c8da110875a1d3be83afd4a9a4e548be3c/jiter-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:e25012eb0c456fcc13354255d0338cd5397cce26c77b2832b3c4e2e255ea5d9a", size = 204258, upload-time = "2025-11-09T20:48:01.01Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/f4/2b4daf99b96bce6fc47971890b14b2a36aef88d7beb9f057fafa032c6141/jiter-0.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:c97b92c54fe6110138c872add030a1f99aea2401ddcdaa21edf74705a646dd60", size = 185503, upload-time = "2025-11-09T20:48:02.35Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/ca/67bb15a7061d6fe20b9b2a2fd783e296a1e0f93468252c093481a2f00efa/jiter-0.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:53839b35a38f56b8be26a7851a48b89bc47e5d88e900929df10ed93b95fea3d6", size = 317965, upload-time = "2025-11-09T20:48:03.783Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/af/1788031cd22e29c3b14bc6ca80b16a39a0b10e611367ffd480c06a259831/jiter-0.12.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94f669548e55c91ab47fef8bddd9c954dab1938644e715ea49d7e117015110a4", size = 345831, upload-time = "2025-11-09T20:48:05.55Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/17/710bf8472d1dff0d3caf4ced6031060091c1320f84ee7d5dcbed1f352417/jiter-0.12.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:351d54f2b09a41600ffea43d081522d792e81dcfb915f6d2d242744c1cc48beb", size = 361272, upload-time = "2025-11-09T20:48:06.951Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/f1/1dcc4618b59761fef92d10bcbb0b038b5160be653b003651566a185f1a5c/jiter-0.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2a5e90604620f94bf62264e7c2c038704d38217b7465b863896c6d7c902b06c7", size = 204604, upload-time = "2025-11-09T20:48:08.328Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/32/63cb1d9f1c5c6632a783c0052cde9ef7ba82688f7065e2f0d5f10a7e3edb/jiter-0.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:88ef757017e78d2860f96250f9393b7b577b06a956ad102c29c8237554380db3", size = 185628, upload-time = "2025-11-09T20:48:09.572Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/99/45c9f0dbe4a1416b2b9a8a6d1236459540f43d7fb8883cff769a8db0612d/jiter-0.12.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c46d927acd09c67a9fb1416df45c5a04c27e83aae969267e98fba35b74e99525", size = 312478, upload-time = "2025-11-09T20:48:10.898Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/a7/54ae75613ba9e0f55fcb0bc5d1f807823b5167cc944e9333ff322e9f07dd/jiter-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:774ff60b27a84a85b27b88cd5583899c59940bcc126caca97eb2a9df6aa00c49", size = 318706, upload-time = "2025-11-09T20:48:12.266Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/31/2aa241ad2c10774baf6c37f8b8e1f39c07db358f1329f4eb40eba179c2a2/jiter-0.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5433fab222fb072237df3f637d01b81f040a07dcac1cb4a5c75c7aa9ed0bef1", size = 351894, upload-time = "2025-11-09T20:48:13.673Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/4f/0f2759522719133a9042781b18cc94e335b6d290f5e2d3e6899d6af933e3/jiter-0.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8c593c6e71c07866ec6bfb790e202a833eeec885022296aff6b9e0b92d6a70e", size = 365714, upload-time = "2025-11-09T20:48:15.083Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/6f/806b895f476582c62a2f52c453151edd8a0fde5411b0497baaa41018e878/jiter-0.12.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90d32894d4c6877a87ae00c6b915b609406819dce8bc0d4e962e4de2784e567e", size = 478989, upload-time = "2025-11-09T20:48:16.706Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/6c/012d894dc6e1033acd8db2b8346add33e413ec1c7c002598915278a37f79/jiter-0.12.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:798e46eed9eb10c3adbbacbd3bdb5ecd4cf7064e453d00dbef08802dae6937ff", size = 378615, upload-time = "2025-11-09T20:48:18.614Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/30/d718d599f6700163e28e2c71c0bbaf6dace692e7df2592fd793ac9276717/jiter-0.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3f1368f0a6719ea80013a4eb90ba72e75d7ea67cfc7846db2ca504f3df0169a", size = 364745, upload-time = "2025-11-09T20:48:20.117Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/85/315b45ce4b6ddc7d7fceca24068543b02bdc8782942f4ee49d652e2cc89f/jiter-0.12.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f04a9d0b4406f7e51279710b27484af411896246200e461d80d3ba0caa901a", size = 386502, upload-time = "2025-11-09T20:48:21.543Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/0b/ce0434fb40c5b24b368fe81b17074d2840748b4952256bab451b72290a49/jiter-0.12.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:fd990541982a24281d12b67a335e44f117e4c6cbad3c3b75c7dea68bf4ce3a67", size = 519845, upload-time = "2025-11-09T20:48:22.964Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/a3/7a7a4488ba052767846b9c916d208b3ed114e3eb670ee984e4c565b9cf0d/jiter-0.12.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:b111b0e9152fa7df870ecaebb0bd30240d9f7fff1f2003bcb4ed0f519941820b", size = 510701, upload-time = "2025-11-09T20:48:24.483Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/16/052ffbf9d0467b70af24e30f91e0579e13ded0c17bb4a8eb2aed3cb60131/jiter-0.12.0-cp314-cp314-win32.whl", hash = "sha256:a78befb9cc0a45b5a5a0d537b06f8544c2ebb60d19d02c41ff15da28a9e22d42", size = 205029, upload-time = "2025-11-09T20:48:25.749Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/18/3cf1f3f0ccc789f76b9a754bdb7a6977e5d1d671ee97a9e14f7eb728d80e/jiter-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:e1fe01c082f6aafbe5c8faf0ff074f38dfb911d53f07ec333ca03f8f6226debf", size = 204960, upload-time = "2025-11-09T20:48:27.415Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/68/736821e52ecfdeeb0f024b8ab01b5a229f6b9293bbdb444c27efade50b0f/jiter-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:d72f3b5a432a4c546ea4bedc84cce0c3404874f1d1676260b9c7f048a9855451", size = 185529, upload-time = "2025-11-09T20:48:29.125Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/61/12ed8ee7a643cce29ac97c2281f9ce3956eb76b037e88d290f4ed0d41480/jiter-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e6ded41aeba3603f9728ed2b6196e4df875348ab97b28fc8afff115ed42ba7a7", size = 318974, upload-time = "2025-11-09T20:48:30.87Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/c6/f3041ede6d0ed5e0e79ff0de4c8f14f401bbf196f2ef3971cdbe5fd08d1d/jiter-0.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a947920902420a6ada6ad51892082521978e9dd44a802663b001436e4b771684", size = 345932, upload-time = "2025-11-09T20:48:32.658Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/5d/4d94835889edd01ad0e2dbfc05f7bdfaed46292e7b504a6ac7839aa00edb/jiter-0.12.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:add5e227e0554d3a52cf390a7635edaffdf4f8fce4fdbcef3cc2055bb396a30c", size = 367243, upload-time = "2025-11-09T20:48:34.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/76/0051b0ac2816253a99d27baf3dda198663aff882fa6ea7deeb94046da24e/jiter-0.12.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9b1cda8fcb736250d7e8711d4580ebf004a46771432be0ae4796944b5dfa5d", size = 479315, upload-time = "2025-11-09T20:48:35.507Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/ae/83f793acd68e5cb24e483f44f482a1a15601848b9b6f199dacb970098f77/jiter-0.12.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deeb12a2223fe0135c7ff1356a143d57f95bbf1f4a66584f1fc74df21d86b993", size = 380714, upload-time = "2025-11-09T20:48:40.014Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/5e/4808a88338ad2c228b1126b93fcd8ba145e919e886fe910d578230dabe3b/jiter-0.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c596cc0f4cb574877550ce4ecd51f8037469146addd676d7c1a30ebe6391923f", size = 365168, upload-time = "2025-11-09T20:48:41.462Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/d4/04619a9e8095b42aef436b5aeb4c0282b4ff1b27d1db1508df9f5dc82750/jiter-0.12.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ab4c823b216a4aeab3fdbf579c5843165756bd9ad87cc6b1c65919c4715f783", size = 387893, upload-time = "2025-11-09T20:48:42.921Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/ea/d3c7e62e4546fdc39197fa4a4315a563a89b95b6d54c0d25373842a59cbe/jiter-0.12.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e427eee51149edf962203ff8db75a7514ab89be5cb623fb9cea1f20b54f1107b", size = 520828, upload-time = "2025-11-09T20:48:44.278Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/0b/c6d3562a03fd767e31cb119d9041ea7958c3c80cb3d753eafb19b3b18349/jiter-0.12.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:edb868841f84c111255ba5e80339d386d937ec1fdce419518ce1bd9370fac5b6", size = 511009, upload-time = "2025-11-09T20:48:45.726Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/51/2cb4468b3448a8385ebcd15059d325c9ce67df4e2758d133ab9442b19834/jiter-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8bbcfe2791dfdb7c5e48baf646d37a6a3dcb5a97a032017741dea9f817dca183", size = 205110, upload-time = "2025-11-09T20:48:47.033Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/c5/ae5ec83dec9c2d1af805fd5fe8f74ebded9c8670c5210ec7820ce0dbeb1e/jiter-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2fa940963bf02e1d8226027ef461e36af472dea85d36054ff835aeed944dd873", size = 205223, upload-time = "2025-11-09T20:48:49.076Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/9a/3c5391907277f0e55195550cf3fa8e293ae9ee0c00fb402fec1e38c0c82f/jiter-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:506c9708dd29b27288f9f8f1140c3cb0e3d8ddb045956d7757b1fa0e0f39a473", size = 185564, upload-time = "2025-11-09T20:48:50.376Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "my-project"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "openai" },
|
||||
{ name = "python-dotenv" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "openai", specifier = ">=2.14.0" },
|
||||
{ name = "python-dotenv", specifier = ">=1.2.1" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "2.14.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "distro" },
|
||||
{ name = "httpx" },
|
||||
{ name = "jiter" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "sniffio" },
|
||||
{ name = "tqdm" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/b1/12fe1c196bea326261718eb037307c1c1fe1dedc2d2d4de777df822e6238/openai-2.14.0.tar.gz", hash = "sha256:419357bedde9402d23bf8f2ee372fca1985a73348debba94bddff06f19459952", size = 626938, upload-time = "2025-12-19T03:28:45.742Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/27/4b/7c1a00c2c3fbd004253937f7520f692a9650767aa73894d7a34f0d65d3f4/openai-2.14.0-py3-none-any.whl", hash = "sha256:7ea40aca4ffc4c4a776e77679021b47eec1160e341f42ae086ba949c9dcc9183", size = 1067558, upload-time = "2025-12-19T03:28:43.727Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.12.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "annotated-types" },
|
||||
{ name = "pydantic-core" },
|
||||
{ name = "typing-extensions" },
|
||||
{ name = "typing-inspection" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.41.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "1.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tqdm"
|
||||
version = "4.67.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.15.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-inspection"
|
||||
version = "0.4.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
|
||||
]
|
||||
Loading…
Reference in New Issue
Block a user