-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
🎮 项目需求:基于PocketBase的四色牌在线多人游戏(含智能机器人)
- 项目愿景
构建一个基于 Web 的在线多人“四色牌”卡牌游戏。后端使用 PocketBase 实现数据驱动和实时通信,前端使用 Vue 3 并适配移动端。项目需支持多房间并发以及房主添加智能机器人代打的功能。 - 技术栈
后端: PocketBase (v0.22+), Go (用于 Hooks 和 自定义 API), JavaScript (用于游戏逻辑插件)。
前端: Vue 3 (Composition API), Vite, Pinia, Vant 4 (移动端 UI 组件), PocketBase JS SDK。
理念: “万物皆对象”,游戏状态由数据库记录驱动,逻辑可插拔。 - 数据库设计 (PocketBase Collections)
请创建以下集合结构,确保关系字段正确设置:
3.1 users (扩展内置用户表)
{
"username": "string (required)",
"is_bot": "bool (default: false)",
"bot_level": "select (easy, normal, hard)",
"avatar": "file"
}
3.2 game_rules
{
"name": "string (required)",
"logic_file": "string (required, e.g., 'four_color_card.js')",
"config_json": "json (required)"
}
3.3 tables (牌桌)
{
"name": "string",
"owner_id": "relation (users)",
"status": "select (waiting, playing, finished)",
"player_ids": "relation (users, multiple, max: 4)",
"player_states": "json (记录座位号、分数、准备状态)",
"current_game_id": "relation (game_states)",
"is_private": "bool"
}
3.4 game_states (单局快照)
{
"table_id": "relation (tables)",
"round_number": "number",
"current_player_index": "number (0-3)",
"dealer_index": "number (0-3)",
"player_hands": "json (map: index -> card_ids)",
"deck": "json (card_ids)",
"discard_pile": "json (card_ids)",
"player_melds": "json (map: index -> meld_arrays)",
"revealed_card": "json (庄家首张翻牌信息)",
"game_specific_data": "json (剩余牌数计数等)"
}
3.5 game_actions (事件溯源)
{
"table_id": "relation (tables)",
"player_id": "relation (users)",
"action_type": "select (deal, draw, play, chi, peng, kai, hu, pass)",
"action_data": "json (具体牌面数据)",
"sequence_number": "number"
} - 核心业务逻辑:四色牌规则实现
请在 four_color_card.js 中严格实现以下逻辑:
4.1 牌组定义
基础牌: {将, 士, 象, 车, 马, 炮, 卒} × {黄, 红, 绿, 白} = 28张。
特殊牌: {公, 侯, 伯, 子, 男} (统称“金条”,算红色特殊将) = 5张。
总计: 33张。
4.2 开局与定庄
发牌: 庄家 21 张,闲家 20 张。
首局定庄: 随机翻一张牌,颜色决定庄家位置(黄=1, 红=2, 绿=3, 白=4)。
连庄逻辑: 大胡后胜利方的对家坐庄;小胡后庄家连庄;流局庄家连庄。
翻牌: 庄家多出的一张牌需公开显示(revealed_card)。
4.3 运转规则
出牌阶段: 玩家从手牌打出一张。
响应阶段:
下家优先选择从牌堆翻一张牌。
翻牌判定: 翻出的牌公开,先检查其他玩家是否有“胡、开、碰”。若有,按优先级抢断。
若无人抢断,翻牌玩家必须选择“吃”或“打出该牌”(若无法吃,则该翻牌强制变为弃牌)。
优先级: 胡 > 开 > 碰 > 吃 > 过。
4.4 牌组与计分 (核心算法)
必须实现以下校验和计算函数:
A. 吃牌
仅限吃上家打出的牌。
组合与分数:
同色:车马炮 (1分)。
同色:将士象 (1分)。
异色卒:3张不同色卒 (1分),4张不同色卒 (2分)。
单张:将 (1分),金条 (3分)。
B. 碰
3张同色同字 (1分)。
金条碰分值按普通牌计算,但作为高价值牌保留。
C. 开 - 4张同色同字
计 6 分。
可以由暗杠(手牌)或碰后补杠触发。
D. 坎 - 3张同色同字
暗坎计 3 分。
金条坎计 9 分。
E. 鱼 - 4张同色同字
计 8 分。
金条鱼计 24 分。
F. 胡牌判定与计分
小胡: 无“鱼”或“开”。
公式: (基础分3 + 吃牌分 + 碰牌分 + 暗坎分)。
大胡: 手牌或明牌中有“鱼”或“开”。
公式: (基础分3 + 吃碰坎分 + 开鱼分) × 2。
结算:
赢家向所有闲家收取最终分数。
闲家之间根据“坎、开、鱼”互相结算分数(赢家不参与闲家互分)。 - 智能机器人系统
5.1 后端实现
在 PocketBase Go 代码中实现一个 Bot Scheduler。
逻辑:
定时扫描状态为 playing 且 current_player_index 对应的是 is_bot=true 的牌桌。
模拟人类思考延迟(随机 2-5 秒)。
读取当前 Game State,调用 four_color_card.js 中的 botDecision(state, botLevel) 函数。
以机器人身份调用 /api/game/action 执行决策。
5.2 机器人 AI 逻辑 (botDecision 函数)
请实现基于启发式评估的 AI:
胡 (Hu): 最高优先级。检查手牌 + 待处理牌是否满足胡牌型。
开/碰 (Kai/Peng): 高优先级。特别是金条和高分牌。
吃:
优先吃能形成“车马炮”或“将士象”的牌。
其次考虑吃卒凑色。
权衡:吃这张牌是否会破坏原本潜在的胡牌型?
出牌策略:
优先打出孤张(无匹配的牌)。
拆散烂牌(如单张将)。
保留金条和高价值连张。
难度分级:
Easy: 随机出牌,只胡大牌。
Normal: 标准贪心算法。
Hard: 记忆弃牌堆,预测对手需求,尽量不点炮(如已知对手在等车,则不打车)。 - 前端功能需求
6.1 大厅与房间
创建房间(支持设置密码)。
加入房间。
房主功能:
点击空闲座位(如“玩家2 空”),弹出菜单“添加机器人”。
选择机器人难度 -> 自动创建并分配 Bot User 到该座位。
游戏开始前可踢出机器人。
6.2 游戏界面 (移动端适配)
布局:屏幕下方为“我”,左、上、右为其他玩家(根据座位号旋转)。
展示:手牌(明/暗)、出牌区、当前剩余牌数。
交互:轮到玩家时,高亮可选操作(吃/碰/胡/出)。
流局/结算弹窗:清晰显示分数变化。 - API 接口规范
POST /api/tables/create: 创建房间。
POST /api/tables/{id}/add-bot: 房主添加机器人 (Body: { seat_index, level })。
POST /api/game/action: 统一动作入口。
GET /api/realtime: 订阅 tables/{id} 事件流。
请根据以上需求,生成完整的项目目录结构、Go Hooks 代码、JavaScript 游戏逻辑文件以及 Vue 3 的核心组件代码。
Reactions are currently unavailable