Files
werewolf/README.md
T

6.7 KiB
Raw Blame History

狼人杀 · Werewolf

一个 网页联机狼人杀框架:FastAPI + WebSocket 后端,React + TypeScript + Sass 前端, 支持 真人玩家与 AI 玩家混合对局,人数与板子可选,多人从不同浏览器/设备加入同一房间。

技术栈 ![前端](https://img.shields.io/badge/React-TypeScript Sass Vite-61dafb) 环境

功能特性

  • 人机混战:真人玩家占座后,空位一键补满 AI;也可以全部由 AI 对战观战
  • 真正的多人联机:房间码制,局域网/公网多设备加入,断线自动重连不掉座
  • 经典板子:
    • 经典 12 人局(4 狼 4 民 预言家/女巫/猎人/守卫)
    • 标准 10 人局(3 狼 3 民 预女猎守)
    • 快节奏 9 人局(3 狼 3 民 预女猎)
  • 完整规则:守卫守护(不可连守)→ 狼人刀人 → 预言家验人 → 女巫双药(首夜可自救、同守同救会死) → 警长竞选(警长 1.5 票、警徽流转、可撕徽)→ 白天发言 → 投票放逐 → 猎人开枪 → 屠边/屠城胜负判定
  • AI 玩家(LLM 驱动):接入任意 OpenAI 兼容大模型(DeepSeek / 智谱 / Kimi / OpenAI / 本地 Ollama …), AI 有人设性格、第一人称发言、夜间决策与投票;未配置密钥时自动回退内置启发式 AI,开箱即玩
  • 网页界面:座位圈、阶段横幅与倒计时、个人私密信息面板(身份/狼队友/查验/药水)、公开+私密对局记录、 按阶段切换的行动面板、结算复盘弹窗
  • 亮/暗主题:默认清爽浅色(白底 + 靛蓝主色),右上角 🌙/☀️ 一键切换暗色(深蓝灰),选择自动记忆

快速开始

环境要求

  • uv(管理 Python 后端环境,会自动安装 Python 解释器)
  • pnpm + Node.js 18+(管理前端)

方式一:单进程游玩(推荐)

# 1. 构建前端
cd frontend
pnpm install
pnpm build

# 2. 启动后端(自动托管前端构建产物)
cd ../backend
uv sync
uv run python run.py

打开 http://127.0.0.1:8000 —— 填昵称、创建房间、把房间号发给朋友, 各自浏览器打开后输入房间号加入,空位补 AI,开始游戏。

局域网联机:同一 WiFi 下的朋友访问 http://<你的IP>:8000 即可。

方式二:前端开发模式(热更新)

# 终端 1:后端
cd backend && uv sync && uv run uvicorn app.main:app --port 8000

# 终端 2:前端(Vite 会把 /api 与 /ws 代理到 8000 端口)
cd frontend && pnpm install && pnpm dev

打开 http://127.0.0.1:5173。

接入大模型 AI(可选)

cd backend
cp config.example.json config.json   # Windows: copy config.example.json config.json

编辑 config.json,填入任意 OpenAI 兼容服务:

{
  "llm": {
    "base_url": "https://api.deepseek.com/v1",
    "api_key": "sk-xxxx",
    "model": "deepseek-chat",
    "temperature": 0.8
  }
}

常见服务商的 base_url:

服务商 base_url 模型示例
DeepSeek https://api.deepseek.com/v1 deepseek-chat
智谱 GLM https://open.bigmodel.cn/api/paas/v4 glm-4-flash
Moonshot Kimi https://api.moonshot.cn/v1 moonshot-v1-8k
OpenAI https://api.openai.com/v1 gpt-4o-mini
本地 Ollama http://localhost:11434/v1 qwen2.5:7b
  • 也可用环境变量覆盖:WEREWOLF_LLM_BASE_URL / WEREWOLF_LLM_API_KEY / WEREWOLF_LLM_MODEL
  • 不配置或配置错误都不会影响游戏:AI 自动回退到内置启发式逻辑(调用失败也会单次降级,不会卡局)
  • 大厅页底部会显示当前 AI 状态(大模型已接入 / 启发式 AI)

房间操作说明

操作 说明
创建房间 大厅点击「创建房间」生成 4 位房间码,创建者成为房主
加入房间 输入房间号加入,自动分配空座位;对局中进入则为观战
补 AI 房主可「+ 添加 AI」逐个加,或「⚡ 一键补满 AI」
开始游戏 座位满员后房主点击「开始游戏」,私发身份
断线重连 刷新/断网后重新进入同一房间自动回到原座位(对局中为观战)
再来一局 结算后房主点击「回到房间」,全员身份重置回大厅

游戏规则细节

  • 夜晚顺序:守卫 → 狼人(狼队互相可见,先选的刀口生效)→ 预言家 → 女巫
  • 女巫:解药/毒药各一瓶,每夜限用一瓶;首夜可自救;同守同救会死
  • 警长:首日竞选,警长票计 1.5 票;警长死亡可移交警徽或撕徽
  • 猎人:被刀或被放逐时可开枪,被毒杀不能开枪
  • 放逐:平票无人出局,不翻牌
  • 胜负:默认屠边(狼人杀光全部神职或全部村民即获胜),房主可切换屠城(狼数 ≥ 好人数)

项目结构

├── backend/                # uv 管理的 FastAPI 后端
│   ├── pyproject.toml
│   ├── config.example.json # 复制为 config.json 接入大模型
│   ├── run.py              # 启动入口
│   ├── smoke_test.py       # 纯 AI 完整对局冒烟测试
│   ├── ws_test.py          # 双真人 + AI 无头联机测试
│   ├── side_player.py      # 加入指定房间自动玩的随从客户端
│   └── app/
│       ├── main.py         # REST + WebSocket + 静态托管
│       ├── config.py       # 配置加载
│       └── game/
│           ├── roles.py    # 角色定义
│           ├── board.py    # 板子预设
│           ├── player.py   # 玩家实体
│           ├── room.py     # 房间/连接管理/快照广播
│           ├── engine.py   # 昼夜状态机引擎
│           └── ai/         # LLM 客户端、提示词、Agent、启发式兜底
└── frontend/               # pnpm + Vite + React + TS + Sass 前端
    ├── vite.config.ts      # dev 代理 /api /ws
    └── src/
        ├── pages/          # Lobby 大厅 / Room 房间
        ├── components/     # 座位圈/阶段横幅/行动面板/信息面板/日志/结算
        ├── api/ws.ts       # WebSocket 封装(自动重连)
        ├── types.ts        # 与后端对齐的消息协议类型
        └── styles/         # Sass 主题变量与全局样式

开发测试

cd backend
uv run python smoke_test.py          # 12 个内置 AI 完整对局
uv run python ws_test.py             # 2 个程序化真人 + AI,覆盖建房/重连/重置
uv run python side_player.py 房间号   # 让一个自动玩家加入你的房间