Skip to content

Commit 20bf20d

Browse files
committed
update
1 parent 96c3e38 commit 20bf20d

3 files changed

Lines changed: 445 additions & 221 deletions

File tree

README.md

Lines changed: 225 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,278 @@
11
# 雀阁 · 纸牌房
22

3-
> **Forked from** [laivv/doudizhu](https://github.com/laivv/doudizhu.git)
3+
雀阁是一个基于 Node.js、Socket.IO 和 Vue 2 的在线纸牌房项目。项目最初 fork 自 [laivv/doudizhu](https://github.com/laivv/doudizhu.git),现在已重构为“房间制 + 多玩法”的纸牌游戏平台,当前支持斗地主和掼蛋,并预留继续接入新玩法的结构。
44

5-
> 基于 Node.js + Vue 2 + Socket.IO 的多人在线纸牌房,支持 **动态开房 / 快速匹配 / 好友房号 / 斗地主 / 掼蛋 / 观战 / 国风音画**
5+
## 功能概览
66

7+
- 动态房间:支持公开房、私密房、房号加入、快速入局。
8+
- 斗地主:三人叫分、地主底牌、地主/农民阵营、炸弹与春天倍率、AI 对手、智囊推荐。
9+
- 掼蛋:四人两副牌、固定对家、级牌升级、红桃级牌逢人配、AI 补位、智囊推荐、局内队伍计分板。
10+
- 观战模式:可不入座观看正在进行的房间。
11+
- AI 系统:空位可补 AI,真人可顶替等待态 AI,AI 会自动重新准备。
12+
- 聊天系统:房间内自由文本聊天。
13+
- 音效与特效:出牌、不出、炸弹、王炸、同花顺等有局内反馈,可静音。
14+
- 积分系统:可选 MySQL 持久化,斗地主和掼蛋积分榜独立统计。
15+
- Discuz SSO:可选 JWT 单点登录,支持同步 Discuz 用户名和头像。
16+
- 移动端:大厅可响应式使用;牌桌在手机端要求横屏。
717

8-
---
18+
## 快速开始
919

10-
## 特性
20+
要求 Node.js 18 或更高版本。
1121

12-
- **动态房间** — 玩家可以开公开房、开私密房、输入房号加入好友房,也可以快速入局自动匹配空房。
13-
- **多玩法架构** — 斗地主与掼蛋作为独立玩法接入,后续可继续扩展新的纸牌规则。
14-
- **斗地主** — 三人叫分、底牌、地主/农民阵营、炸弹翻倍、春天结算、AI 陪玩与智囊推荐。
15-
- **掼蛋** — 四人两副牌、对家组队、级牌升级、红桃级牌逢人配、炸弹/同花顺/四王炸、头游队伍升级结算。
16-
- **AI 对手** — 斗地主房内一键「召唤 A I 对手」,自动填空座;真人加入时 AI 自动让座、全员退房时自动清场。
17-
- **观战模式** — 不入座也能旁观对局,棋谱牌势一览无余。
18-
- **智囊推荐** — 自己回合点「智 囊」即可由内置 AI 自动选出最经济的合法跟牌。
19-
- **国风视效** — 玉绿背景、朱漆按钮、鎏金徽印;地主登场金光,农民登场玉色光晕;炸弹/王炸/飞机各自专属字幕特效。
20-
- **Web Audio 音效** — 出牌、不出、叫分、炸弹皆有合成音色,可一键静音。
21-
- **房间聊天** — 茶馆闲话面板,自由输入或下拉选「快语」短句。
22-
- **移动端适配** — 大厅、开房、手牌、聊天和操作按钮针对手机竖屏做了响应式布局。
23-
- **可选 SSO** — 内置 JWT 校验入口,便于与 Discuz 等论坛对接(参见 [discuz-sso/README.md](discuz-sso/README.md))。
22+
```bash
23+
npm install
24+
npm start
25+
```
2426

25-
---
27+
默认监听 `8002`
2628

27-
## 截图
29+
```text
30+
http://localhost:8002/
31+
```
2832

29-
<img width="1702" height="1255" alt="f2f1befc878f15cbbcc39238c5bf0546" src="https://github.com/user-attachments/assets/c0f47639-e6af-4997-acc0-a038c1d9f319" />
30-
<img width="1700" height="1257" alt="e2384b186038c64b40103a9f2db9d653" src="https://github.com/user-attachments/assets/87b166c5-42a3-408c-bd00-d52e17a57634" />
33+
本地指定端口:
3134

35+
```powershell
36+
$env:PORT='8012'
37+
node server.js
38+
```
3239

33-
---
40+
## 配置
3441

35-
## 快速开始
42+
项目启动时按以下优先级读取配置:
3643

37-
确保已安装 Node.js(建议 ≥ 18)。
44+
1. 环境变量
45+
2. 根目录 `config.json`
46+
3. 代码默认值
3847

39-
```sh
40-
git clone https://github.com/laivv/doudizhu.git
41-
cd doudizhu
42-
npm install
43-
npm start
48+
复制示例配置:
49+
50+
```bash
51+
cp config.example.json config.json
4452
```
4553

46-
默认监听 **8002** 端口,浏览器访问:
54+
`config.json` 已加入 `.gitignore`,不要提交真实密钥和数据库密码。
4755

48-
```
49-
http://localhost:8002
50-
```
56+
常用配置:
57+
58+
| 字段 / 环境变量 | 说明 | 默认值 |
59+
| --- | --- | --- |
60+
| `PORT` | HTTP / Socket.IO 监听端口 | `8002` |
61+
| `JWT_SECRET` | Discuz SSO JWT 密钥,必须与论坛端一致 | `change_this_in_production` |
62+
| `DB_HOST` | MySQL 地址 | `127.0.0.1` |
63+
| `DB_PORT` | MySQL 端口 | `3306` |
64+
| `DB_USER` | MySQL 用户名 ||
65+
| `DB_PASSWORD` | MySQL 密码 ||
66+
| `DB_NAME` | MySQL 数据库名 ||
67+
| `DB_TABLE_PREFIX` | 表前缀,建议与 Discuz 一致 | `pre_` |
68+
| `DB_DISABLE` | 设为 `1` 禁用数据库持久化 | 未启用 |
69+
| `SCORE_BASE` | 每个基础分对应的积分 | `1` |
70+
| `DISCUZ_AVATAR_BASE` | Discuz 头像 URL 模板,支持 `{uid}` | `https://zwwx.club/uc_server/avatar.php?uid={uid}&size=middle` |
5171

52-
输入「雅号」后即可进入大厅:
72+
## 玩法说明
5373

54-
- 选择「斗地主」或「掼蛋」后点「快速入局」。
55-
- 点「开公开房」等待陌生玩家加入。
56-
- 点「开私密房」后把房号发给朋友。
57-
- 输入好友给你的房号可直接加入。
74+
### 斗地主
5875

59-
---
76+
- 三人参与。
77+
- 叫分后分为地主与农民两方。
78+
- 地主获得底牌。
79+
- 支持常见斗地主牌型,牌型识别由 `static/js/parser.js``game.js` 处理。
80+
- 结算时地主按双倍基础分输赢,农民按单倍基础分输赢。
6081

61-
## 操作指南
82+
### 掼蛋
6283

63-
### 自己回合的按钮顺序
84+
- 四人参与,两副牌,每人 27 张。
85+
- 座位 `0/2` 为一队,`1/3` 为一队。
86+
- 当前级牌从 `2` 开始,红桃级牌为逢人配。
87+
- 头游队伍升级:双下 `+3`,二三名 `+2`,其他胜局 `+1`
6488

65-
```
66-
[ 出 牌 ] [ 智 囊 ] [ 不 出 ]
67-
↑ 朱漆 ↑ 墨色 ↑ 玉绿
68-
```
89+
第一类牌型:
6990

70-
- **出 牌**:将选中的牌打出(必须是合法牌型,且能压过上家)。
71-
- **智 囊**:让 AI 自动帮你选牌;若无可压制的牌会提示「建议不出」。
72-
- **不 出**:跳过本轮(仅当上家不是自己时可见)。
91+
- 单张:任意一张牌。
92+
- 对子:两张点数相同的牌,包括对大王或对小王。
93+
- 三连对:三对连续对子,例如 `223344`
94+
- 三同张:三张点数相同的牌。
95+
- 二连三:两组三同张,例如 `333444`
96+
- 三带二:三同张带一个对子,例如 `55522`
97+
- 顺子:五张连续单牌,例如 `23456`
7398

74-
### 房间与等待区
99+
第一类牌型之间必须牌型相同才能压牌;三带二只比较三同张大小。
75100

76-
- **准 备**:标记自己已就绪;三人全部就绪自动开局。
77-
- **召 唤 A I 对 手**:斗地主房内有空座时显示,把所有空位填上 AI。
78-
- **请 走 A I**:斗地主房内有 AI 时显示,清退所有 AI 等真人。
79-
- **房号**:房间顶部显示,私密房可复制房号给好友加入。
101+
连续牌型中,`A` 可以作为最小值,也可以作为 `K+1`。例如 `A2345``23456``10JQKA``AA2233``QQKKAA` 都是合法连续牌型。
80102

81-
### 叫分
103+
第二类牌型:
82104

83-
听到「叫分」环节时,依次显示可叫分数(1/2/3)和「不叫」按钮,点击即可。
105+
- 炸弹:四张或四张以上点数相同的牌。
106+
- 同花顺:五张花色相同的顺子。
107+
- 天王炸:大小王各两张。
84108

85-
### 掼蛋
109+
第二类可以压任意第一类。第二类内部顺序:
86110

87-
- 四人开局,两副牌,每人 27 张。
88-
- 0/2 与 1/3 为固定对家。
89-
- 当前级牌从 2 开始,红桃级牌为逢人配,可参与常规牌型组合。
90-
- 支持单张、对子、三张、三带二、顺子、连对、钢板、炸弹、同花顺、四王炸。
91-
- 头游队伍按名次升级:双下 +3,二三名 +2,其余 +1。
111+
- 天王炸最大。
112+
- 炸弹张数越多越大,张数相同比点数。
113+
- 同花顺按顺子点数比较。
114+
- 同花顺可以压五张及以下炸弹,六张及以上炸弹大于同花顺。
92115

93-
### AI 让座规则
116+
## 智囊与 AI
94117

95-
- 真人入座时若该位被 AI 占用且未在游戏中 → AI **拱手让座**
96-
- 桌内最后一名真人离席 / 掉线 → 服务端自动清退该桌所有 AI 并重置牌局。
97-
- 一局结束后,留在桌上的 AI **自动重新就绪**;若全员就绪则立即开下一局。
118+
斗地主智囊由 `static/js/ai-suggest.js` 提供。
98119

99-
---
120+
掼蛋智囊由 `static/js/guandan-suggest.js` 提供,服务端机器人与前端“智囊”共用同一套规则分析。策略原则:
100121

101-
## 技术栈
122+
- 自由出牌时优先减少手数。
123+
- 跟牌时尽量用最小可压牌。
124+
- 队友出牌时通常不压,除非可以直接走完。
125+
- 炸弹和逢人配会尽量保留,除非局势需要。
102126

103-
|| 选型 |
127+
## 积分系统
128+
129+
数据库持久化是可选能力。未配置数据库时,游戏仍可正常运行,但不会保存积分。
130+
131+
启动时自动创建两张表:
132+
133+
```text
134+
pre_doudizhu_score
135+
pre_guandan_score
136+
```
137+
138+
表前缀由 `DB_TABLE_PREFIX` 决定。
139+
140+
HTTP 查询接口:
141+
142+
| 接口 | 说明 |
104143
| --- | --- |
105-
| 服务端 | Node.js · Express · Socket.IO 4 · jsonwebtoken |
106-
| 前端 | Vue 2(CDN 单文件)· jQuery · layer 弹层 |
107-
| 通信 | WebSocket(事件:`CREATE_ROOM` / `JOIN_ROOM` / `QUICK_JOIN` / `SITDOWN` / `PREPARE` / `CALL_SCORE` / `PLAY_CARD` / `USER_MESSAGE` / `SPECTATE` / `ADD_BOTS` / `REMOVE_BOTS` …) |
108-
| 音效 | 原生 Web Audio API(无第三方依赖) |
109-
| 牌型校验 | `static/js/parser.js`(A / AA / AAA / AAAB / AAABB / ABCDE / AABBCC / AAABBB / AAAABC / AAAABBCC / AAAA / KING) |
110-
| AI 决策 | `static/js/ai-suggest.js`(同时供前端「智囊」与服务端「机器人」使用) |
144+
| `GET /api/score/me?gameType=doudizhu&token=<JWT>` | 当前用户斗地主战绩 |
145+
| `GET /api/score/me?gameType=guandan&token=<JWT>` | 当前用户掼蛋战绩 |
146+
| `GET /api/score/top?gameType=doudizhu&limit=20` | 斗地主积分榜 |
147+
| `GET /api/score/top?gameType=guandan&limit=20` | 掼蛋积分榜 |
148+
149+
只有通过 JWT 登录的真人玩家会计入积分。游客、AI、观战用户不记录。
111150

112-
---
151+
## Discuz SSO
152+
153+
项目支持通过 Discuz 签发 JWT 进行单点登录。
154+
155+
- 论坛端示例代码在 `discuz-sso/`
156+
- 游戏端通过 Socket.IO `auth.token` 校验 JWT。
157+
- 登录成功后可同步 Discuz 用户名和头像。
158+
159+
详细部署见 [discuz-sso/README.md](discuz-sso/README.md)
113160

114161
## 项目结构
115162

116-
```
117-
quege-card-room/
118-
├── server.js # Express + Socket.IO 入口;含 AI 机器人调度
119-
├── game.js # 游戏状态机(发牌 / 叫分 / 出牌 / 胜负)
120-
├── guandan-game.js # 掼蛋状态机(两副牌 / 级牌 / 逢人配 / 升级)
121-
├── core-ai.js # 服务端 AI 辅助
122-
├── core-validator.js # 服务端牌型校验
123-
├── package.json
124-
├── discuz-sso/ # 可选:与 Discuz 论坛 SSO 对接示例
163+
```text
164+
.
165+
├── server.js # Express + Socket.IO 入口、房间、AI、API
166+
├── game.js # 斗地主状态机
167+
├── guandan-game.js # 掼蛋状态机与服务端判牌
168+
├── db.js # 分玩法积分持久化
169+
├── core-ai.js # 原斗地主 AI 辅助
170+
├── core-validator.js # 原斗地主校验辅助
171+
├── config.example.json # 本地配置示例
172+
├── discuz-sso/ # Discuz JWT SSO 示例
125173
└── static/
126-
├── index.html # Vue SPA 单页
174+
├── index.html # Vue 2 单页应用
127175
├── css/
128-
│ ├── base.css
129-
│ ├── style.css # 国风主题样式
130-
│ └── theme.css
131-
├── images/
132-
│ └── screenshots/ # 文档截图
176+
│ ├── theme.css # 主题变量
177+
│ └── style.css # 主要布局与组件样式
178+
├── images/ # 扑克图、桌面素材
133179
└── js/
134-
├── parser.js # 牌型识别
135-
├── ai-suggest.js # AI 选牌引擎(前后端共用)
136-
├── effects.js # 特效字幕 + Web Audio 音效
180+
├── parser.js # 斗地主牌型解析
181+
├── ai-suggest.js # 斗地主智囊
182+
├── guandan-suggest.js # 掼蛋智囊
183+
├── effects.js # 音效与特效
137184
├── vue.min.js
138185
├── jquery.min.js
139-
└── layer/ # layer 弹层组件
186+
└── layer/ # 弹窗组件
140187
```
141188

142-
---
143-
144-
## 可选:Discuz SSO 对接
145-
146-
若要让论坛会员免登录进入游戏,可参考 [discuz-sso/README.md](discuz-sso/README.md):论坛侧颁发 JWT,前端在 `?token=` 中带入,服务端 `io.use` 中间件校验通过后建立连接。
189+
## 常用 Socket 事件
190+
191+
客户端到服务端:
192+
193+
- `LOGIN`
194+
- `CREATE_ROOM`
195+
- `QUICK_JOIN`
196+
- `JOIN_ROOM`
197+
- `SITDOWN`
198+
- `PREPARE`
199+
- `CALL_SCORE`
200+
- `PLAY_CARD`
201+
- `USER_MESSAGE`
202+
- `SPECTATE`
203+
- `ADD_BOTS`
204+
- `REMOVE_BOTS`
205+
206+
服务端到客户端:
207+
208+
- `LOGIN_SUCCESS`
209+
- `LOGIN_FAIL`
210+
- `REFRESH_LIST`
211+
- `POS_STATUS_CHANGE`
212+
- `GAME_START`
213+
- `CTX_USER_CHANGE`
214+
- `CTX_PLAY_CHANGE`
215+
- `SHOW_TOP_CARD`
216+
- `PLAY_CARD_SUCCESS`
217+
- `PLAY_CARD_ERROR`
218+
- `GAME_OVER`
219+
- `USER_MESSAGE`
220+
- `MY_SCORE`
221+
222+
## 开发与验证
223+
224+
语法检查:
225+
226+
```bash
227+
node --check server.js
228+
node --check db.js
229+
node --check game.js
230+
node --check guandan-game.js
231+
node --check static/js/guandan-suggest.js
232+
node --check static/js/effects.js
233+
```
147234

148-
---
235+
本地规则回归建议覆盖:
236+
237+
- 掼蛋 `A2345``23456``10JQKA`
238+
- 掼蛋三连对、二连三、三带二
239+
- 同花顺压五张炸,六张炸压同花顺
240+
- 天王炸压所有牌型
241+
- 斗地主叫分、底牌、出牌、结算
242+
243+
## 部署建议
244+
245+
- 使用 HTTPS,特别是启用 Discuz SSO 时。
246+
- 生产环境必须设置强随机 `JWT_SECRET`
247+
- 建议用 systemd、pm2 或容器托管 Node 进程。
248+
- 如在 Cloudflare 等代理后运行,保留 WebSocket 支持。
249+
- 数据库账号只授予游戏积分表需要的权限。
250+
251+
systemd 示例:
252+
253+
```ini
254+
[Unit]
255+
Description=Quege Card Room
256+
After=network.target
257+
258+
[Service]
259+
WorkingDirectory=/var/www/quege-card-room
260+
ExecStart=/usr/bin/node server.js
261+
Restart=always
262+
Environment=PORT=8002
263+
Environment=JWT_SECRET=replace-with-a-strong-secret
264+
Environment=DB_HOST=127.0.0.1
265+
Environment=DB_USER=discuz
266+
Environment=DB_PASSWORD=replace-with-db-password
267+
Environment=DB_NAME=discuz
268+
Environment=DB_TABLE_PREFIX=pre_
269+
270+
[Install]
271+
WantedBy=multi-user.target
272+
```
149273

150274
## License
151275

152-
MIT — 详见 LICENSE。
276+
代码以 [MIT License](LICENSE) 发布
153277

154-
> 注:`static/images/` 内的扑克 / 桌面贴图素材来源于网络,**不在 MIT 许可范围内**,仅作演示用途;如商业使用请自行替换
278+
`static/images/` 中的牌面、桌面等素材仅作为演示资源;商业使用请确认素材授权或自行替换

config.example.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
"DB_NAME": "zwwx_discuz",
1010
"DB_TABLE_PREFIX": "pre_",
1111
"DB_DISABLE": 0,
12-
"SCORE_BASE": 1
12+
"SCORE_BASE": 1,
13+
"DISCUZ_AVATAR_BASE": "https://zwwx.club/uc_server/avatar.php?uid={uid}&size=middle"
1314
}

0 commit comments

Comments
 (0)