### [猜拳 · 21 点 PK:一个插件两种对战,人机即开、真人异步押注 PK](https://guaqi.com/topic/78036) **Published:** 2026-10-07T03:36:27 **Author:** 星动优创 **Excerpt:** 这个插件给站里补的是「随时能开一局」的轻量对战。它塞了两样东西:石头剪刀布和 21 点。玩法本身没什么新鲜的—… 这个插件给站里补的是「**随时能开一局**」的轻量对战。它塞了两样东西:石头剪刀布和 21 点。玩法本身没什么新鲜的——新鲜的是它的对手模型:**人机局即点即玩**,不等待;**真人局走异步 PK**,你先出手把战局挂进列表,别人看到点「应战」,两边出完招服务端当场判定。你不需要在线蹲对手,也不用做实时通信。 钱的部分很直白:**双方各押同样多进彩池,赢家拿走彩池,平台抽水直接销毁,平局全额退回本金**。所以它同时干了两件事——给社区一个能反复玩的小玩意,顺手把站内积分的总量往下压一点。 另外说明一句:它**不是赌博**。积分只能靠站内行为获得、不可提现、不可兑换现金、不可转让;押注是零和分池,平台只从池子里抽一点点销毁,不靠这个挣钱。文末「合规提醒」再说一遍。 ## 一、两种玩法,两种对手 面板分三页:猜拳、21 点、战绩。三页共用同一套积分、战绩和额度体系,装一次就都有了。 | | | | | --- | --- | --- | | **玩法** | **怎么玩** | **一局多久** | | 猜拳 | 点石头 / 布 / 剪刀,一次出手定胜负 | 瞬间 | | 21 点 | 发两张牌,选择继续要牌或停牌,和庄家比点数 | 几秒到十几秒 | 每种玩法都有两种对手形态,用面板上的「人机对战 / 真人 PK」开关切换: | | | | | --- | --- | --- | | **形态** | **对手是谁** | **特点** | | 人机对战 | 服务端即时随机的机器人 / 庄家 | 即点即玩,不用等人;出手全在服务端生成,没有固定套路 | | 真人 PK | 站内其他用户 | 异步:你出手挂进列表,别人应战即判定;对手看不到你出的什么 | ## 二、猜拳:一次出手定胜负 没什么好解释的,只有三个手势:石头、布、剪刀。赢、输、平各占三分之一。 唯一要留意的是钱的部分(下一节细说):**平局双方本金原路退回,不抽水**;分出胜负的那一局,赢家拿到的不是两倍,而是**彩池抽掉平台抽水之后的额度**。押 10 分赢一局,回来的是 19 分,净赚 9。 ## 三、21 点:规则全公开,庄家不偷看 这里的 21 点是「简化版」,规则写在代码里,也写在页面上: | | | | --- | --- | | **项** | **规则** | | 牌面 | 标准 52 张,4 种花色 × 13 个点数 | | A 怎么算 | 先按 11 计;一旦爆牌,全部 A 自动降为 1 | | 目标 | 不超 21 点的情况下,点数比庄家大 | | 庄家怎么跟牌 | **17 点以下(含 16)必跟牌,17 点及以上必停牌**,最多 8 张封顶 | | 爆牌怎么算 | 你爆庄家不爆 → 你输;**双方都爆 → 算平局,退本金** | | 黑杰克 | **不设额外赔率**:首两张凑成 21 点按普通赢局结算,没有 1.5 倍 | 看不清庄家的牌是故意的:**你还在要牌的时候,庄家只下发一张明牌**,暗牌根本不出服务器,界面上的背面牌也只是一个占位方块。你停牌(或爆牌)之后,庄家才按上面的规则补完,并把两张牌一起揭晓。 **为什么不做 21 点 1.5 倍黑杰克赔率?**因为那会让「听牌型玩法」出现一个高赔率的收益口子,而这里的定位是**温和回收**,不是给技巧型玩家刷收益。规则简单、赔率统一,用户不会算出一堆疑问,你也不用去解释为什么他的 21 点只赔了 19。 ## 四、钱怎么走:彩池对赌,抽水销毁 模型很简单,一句话讲完:**双方各押一份进池,赢家拿走池子减去平台抽水的部分,平局各退本金。** ```tap 彩池 pool = 押注 × 2 抽水 rake = floor(pool × 抽水% / 100) ← 直接销毁,谁都不拿 赢家实得 payout = pool − rake 举例(默认抽水 5%): 押 10 分 → 池 20 → 抽 1 → 赢家拿回 19,净赚 +9 押 50 分 → 池 100 → 抽 5 → 赢家拿回 95,净赚 +45 输 → 押注进池且无人领取,等于销毁 平 → 双方本金原路退回,不抽水 ``` 复制 有三个细节值得单独说: - **抽水是销毁,不是平台收入**。这部分积分直接从系统里消失,所以它是通缩的——这就是「回收积分」的着力点。 - **胜率不是 50%,所以长期期望为负**。猜拳赢、输、平各三分之一,单局净收益分别是 `+9 / −10 / 0`,三局平均下来是负的(每押 10 分约亏 0.33 分)。这不是 bug,是有意的:玩法必须长期略微通缩,否则积分只会在站里越滚越多。 - **人机局也是这套规则**。有人会问「和机器人玩,赢的钱从哪来」——人机局本质是**跟站里对赌**,赢了由系统派彩,输了本金进池销毁。抽水的意义就在于把赔率压到 50% 以下,让这条路整体通缩。 ## 五、真人 PK 是异步的:先出手,挂出去,等人应战 这是整个插件设计上最关键的一点,也是最容易被误解的一点。**瓜奇没有实时长连接通道**,所以我们没做「两人同时在线对局」,而是做了异步 PK: 1. **你是发起方**:选好押注,出手(猜拳选手势 / 21 点先打完自己的牌),点「挂一局出去」。押注从余额扣走,战局进列表。 2. **别人看到你的战局**:显示玩法、押注额、还剩多久,以及**你的昵称**——但**看不到你出的是什么**。 3. **有人应战**:他押同样的额度,出他自己的招。两边都齐了,服务端**当场判定**并结算,赢家收钱。 4. **没人应战**:24 小时后自动全额退款给你,不抽水。 5. **你反悔了**:战局还挂在列表里(无人应战)时可以点「撤回」,本金全额退回。 21 点的真人局稍微多一步,因为一手牌要打好几下:**发起方先和牌堆打自己的牌**(要牌 / 停牌),停牌之后这一局才进入列表等人应战;应战方接上之后打自己的牌,打完两边一起揭晓。页面上那句提示写得很清楚:「对手的手牌要等双方都打完才揭晓」。 ## 六、反作弊:判定前一个字都不下发 异步 PK 最怕的就是「能看到对方再决定」。所以下发的数据被卡死在闸门上: | | | | --- | --- | | **风险** | **处理方式** | | 应战方先偷看发起方出了什么 | **只有「已判定」且「我是当事人」时才下发双方牌面 / 手势**;等待期一个字都不给,界面上连手势文案都不渲染 | | 21 点偷看庄家暗牌 | 进行中只下发一张明牌,且**只把明牌算进点数**;暗牌和牌堆全程留在服务端 | | 客户端伪造牌面 | 客户端只能提交「要牌 / 停牌 / 出什么手势」,**不能提交任何牌面数据**;牌堆用服务端 CSPRNG 生成,洗完就下不来 | | 连点重复扣分 | 每次动作带一次性 `requestId`,**10 分钟幂等窗口**内同一个 id 只生效一次 | | 并发超押(余额只够一次却押了两次) | 真人局走**双层命名锁**:先锁这一局,再锁这个人,锁内重新读余额和额度再扣分 | | 扣分成功但写战局失败 | 写失败立即**原路退款**,不会出现「钱扣了没局」 | | 改价 / 改抽水 | 所有钱规则**只读服务端配置**,浏览器里改模块设置改不动价格——下面第九节细说 | ## 七、界面上你会看到什么 模块拖进页面后长这样(自上而下): | | | | --- | --- | | **区块** | **内容** | | 顶部状态条 | 「我的积分」当前余额、「今日已押 N / 200」当日额度 | | 三个选项卡 | 猜拳 / 21 点 / 战绩 | | 押注行 | 按服务端下发的档位选额度(默认 10 / 20 / 50),右侧显示今日还能押多少 | | 对手开关 | 「人机对战」/「真人 PK」 | | 猜拳区 · 人机 | 三个手势大按钮,点一下立刻开一局 | | 猜拳区 · 真人 | 「出手即挂出去」,选好手势点「挂一局出去」 | | 21 点区 · 人机 | 「发牌」→ 你的手牌 + 庄家的明牌与暗牌背面 → 「要牌」/「停牌」 | | 21 点区 · 真人 | 「真人 PK 进行中」牌桌,只列你的手牌;打完停牌后进入战局列表 | | 战局列表 | 「我挂出去的」(带撤回按钮)和「等你应战」(带应战按钮),显示玩法、押注、对手昵称、剩余时间 | | 上一局 / 结果行 | 赢 / 输 / 平 + 净收益(赢红、输绿、平灰) | | 战绩页 | 总对局 / 胜 / 负 / 平 / 净收益五格汇总 + 最近 8 条明细 | | 规则区 | 把押注上下限、日额度、抽水比例、平局退款、异步规则写在页面上,用户不用问 | 游客看到的是「登录后就能开始对战」和一个「去登录」按钮,点了会拉起站点自己的登录弹窗,不会跳走。 ## 八、结算的三重保障 「24 小时没人应战就退款」最怕的是错过时机或者退一半挂掉,所以这里做了三层: 1. **定时器**:每一局挂出去时就按 24 小时挂一个单次计划任务(WP-Cron)。 2. **惰性兜底**:只要有人打开页面读数据,系统顺手检查一遍有没有到点没处理的战局,有就补上。就算你站点的计划任务不准,也不会拖很久。 3. **派彩补发**:发钱失败(比如某个用户写积分时出错)时,战局**保持未结清状态**,下一次读数据再补一次,直到发成功为止。 整个流程带锁、锁内重新读一遍战局状态,所以**重复触发也不会重复派彩**——同一局被处理一百次,用户拿到的钱还是那么多。 ## 九、安装(按顺序做) 拿到安装包:`guaqi-pk-arena-1.0.0.zip`(49 KB)。 1. **上传**:进 WordPress 后台的**瓜奇插件管理页**上传 ZIP。首次上传只安装,**不自动启用**。 2. **开开关**:在插件列表里,把「猜拳 · 21点 PK」在你要用的那个前端网站上启用(按前端网站独立启停)。 3. **拖到页面上**:进 builder,从模块里把「猜拳 · 21点 PK」**拖进任意页面**(模块型插件,不是表单型,首页、文章页、侧栏区块都能放)。 4. **点发布**:这一步务必别漏——builder 里改完必须点「发布」,前台才会生效。 5. **验收**:见下一节。 ## 十、装完怎么验收 用带密钥的调试接口一次看完全部体检信息(当前配置、彩池试算、战局表、你的战绩与额度): ```css mutation { gqPkDebug(input: { key: "gqpk-diag-6b1f83c25a97", action: "status" }) { result } } ``` 复制 `action` 还支持四个运维动作,省得你去数据库里手动改: | | | | --- | --- | | **action** | **作用** | | `status`(默认) | 体检:读一遍配置、彩池试算、战局表、战绩与额度 | | `config` | 改钱规则,可带 `maxStake` / `dailyCap` / `rakePercent` | | `expire` | 立刻跑一次超时退款(想验证 24 小时那条路是否正常) | | `clear` | 清空战局表(**只清已结束的**,未结束的一律保留,避免吞掉别人的本金) | | `reset` | 重置当前用户的战绩 / 日志 / 额度 / 人机牌局(**不动积分**) | ```nix mutation { gqPkDebug(input: { key: "gqpk-diag-6b1f83c25a97" action: "config" maxStake: 50 dailyCap: 200 rakePercent: 5 }) { result } } ``` 复制 前端调用的接口是 `gqPkState`(读状态)、`gqPkPlay`(出手 / 要牌 / 停牌 / 打真人局)、`gqPkCreate`(挂一局出去)、`gqPkJoin`(应战)、`gqPkCancel`(撤回),都不需要密钥,走正常的登录身份校验。 ## 十一、什么能调,什么不能调 这里有个刻意的分工,**关系到你的站会不会被人钻空子**: | | | | | | --- | --- | --- | --- | | **配置项** | **在哪改** | **默认值** | **硬上限** | | 是否显示真人 PK 区 | builder 里的模块设置 | 显示 | — | | 是否显示战绩历史 | builder 里的模块设置 | 显示 | — | | 是否显示规则说明 | builder 里的模块设置 | 显示 | — | | 单次押注上限 | **仅服务端**(调试接口 / 过滤器) | 50 分 | 500 分 | | 每人每日上限 | **仅服务端** | 200 分 | 2000 分 | | 平台抽水比例 | **仅服务端** | 5% | 20% | | 单次最低押注 | 固定(同时是下限天花板) | 10 分 | — | | 战局有效期 | 固定 | 24 小时 | — | **为什么钱规则不给 builder 改?**因为模块设置是**浏览器可以伪造的**。如果押注上限、抽水比例从页面上传过来,任何人改一下请求参数就能把自己的押注上限调到 99999、把抽水调到 0。**所以钱规则一律只认服务端配置**,而且读出来之后还要再夹一次天花板(500 / 2000 / 20%)——就算有人能改数据库,也不可能把抽水调到 100% 去收割用户。builder 里能调的只有三个「展示类」开关。 想用代码接管钱规则也可以,挂过滤器即可: ```haxe add_filter('guaqi_pk_rules', function ($rules) { $rules['maxStake'] = 100; // 单次上限(服务端仍会夹到 500) $rules['dailyCap'] = 500; // 每人每日上限(仍会夹到 2000) $rules['rakePercent'] = 3; // 抽水(仍会夹到 20) return $rules; }); ``` 复制 ## 十二、常见问题 **Q:装了但页面上什么都没有?** 按顺序查三步:插件在你这个前端网站上是不是启用状态 → builder 里模块有没有拖进页面 → builder 有没有点「发布」。三步缺一步都不显示。 **Q:真人 PK 没人应战怎么办?** 24 小时后自动全额退款,不抽水。也可以自己点「撤回」立刻拿回本金。真人局要有人气才有意思,建议放在社区首页或者发个帖子引流——毕竟战局列表里能看见对手昵称。 **Q:为什么我 21 点拿到 21 还是只赔了 19?** 这个版本**不设黑杰克 1.5 倍赔率**,首两张 21 点和普通赢局一样按彩池结算。规则区里写了,不藏着。 **Q:能不能和机器人一直刷分?** 刷不了。人机局的期望值本身是负的(猜拳单局净收益 +9 / −10 / 0,平均下来每押 10 分亏约 0.33 分),玩得越多亏得越多;再加上每日额度上限是服务端权威值,连点也有幂等窗拦着。 **Q:为什么我停牌了,别人还能看到我的牌?** 看不到。整条规则是:**只有这一局已经判定、并且你本人是当事人**,服务端才会下发双方牌面。等待应战期间,连你自己都只能看到自己的牌。 **Q:抽水那部分积分去哪了?** 销毁。不写进任何人的账户,也不进平台账。这是有意的——这个插件的定位就是**温和通缩**。默认 5% 已经够用,调到 20% 用户会算得出来。 **Q:升级会不会丢数据?** 不会。战局、战绩、额度、人机牌局都存在服务端(战局放 option,个人数据放 user\_meta),覆盖安装新版本即可。 **Q:游客点「去登录」没反应?** 已确认这个按钮会真的拉起站点登录弹窗(沿用平台标准登录桥)。如果你的前端域名和源站不是同一个域,需要在 nginx 上把 `/graphql` 反代到源站——这是本站踩过的坑,写在这里省你一轮排查。 ## 十三、给站长的两句实话 第一,**别指望它单独解决通胀**。单次最多押 50 分、一天最多 200 分,抽水 5%,回收力度是温和的。真要收缩站内积分,得配合消耗品(装扮、道具、下载券)一起上;这个插件负责的是**让积分有个随时能玩两把的去处**。 第二,**真人 PK 的活跃度靠引导**。异步 PK 的特点决定了它需要「有人在列表里挂着」才转得起来——刚上线时空列表很正常。建议先自己挂几局、或者在社区帖子里带一下,让人知道这里有东西可以点。等有人开始赢了发帖晒,这个循环就自己转起来了。 **合规提醒:**这个玩法的积分**只能靠站内行为获得,不可提现、不可兑换现金、不可转让**;页面上的规则(彩池分成、抽水比例、额度上限、平局退款、超时退款)建议保持可见;不要引入付费购买积分再参与对战的通路。积分透明 + 没有现金出口 + 规则公示,这三条能挡掉绝大多数麻烦。 演示和下载地址:[https://8maoku.com/article/3432](https://8maoku.com/article/3432) **Comments:** **春哥:** 老哥真高产啊,我去弄个插件上传功能,你可以上传到官网👍 ---