diff --git a/README.md b/README.md index a7d0daf..7ac09da 100755 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ - 音效与特效:出牌、不出、炸弹、王炸、同花顺等有局内反馈,可静音。 - 积分系统:可选 MySQL 持久化,斗地主和掼蛋积分榜独立统计。 - Discuz SSO:可选 JWT 单点登录,支持同步 Discuz 用户名和头像。 +- 登录分支:默认首页保留 Discuz 登录/访客入口;普通玩家可访问 `/?auth=guest` 直接输入用户名进入。 - 移动端:大厅可响应式使用;牌桌在手机端要求横屏。 ## 快速开始 diff --git a/config.example.json b/config.example.json index 003436d..9f96cab 100644 --- a/config.example.json +++ b/config.example.json @@ -10,5 +10,6 @@ "DB_TABLE_PREFIX": "pre_", "DB_DISABLE": 0, "SCORE_BASE": 1, - "DISCUZ_AVATAR_BASE": "https://zwwx.club/uc_server/avatar.php?uid={uid}&size=middle" + "DISCUZ_AVATAR_BASE": "https://zwwx.club/uc_server/avatar.php?uid={uid}&size=middle", + "_LOGIN_MODES": "默认首页保留 Discuz 登录/游客。面向普通玩家可使用 /?auth=guest 直接显示游客用户名输入。" } diff --git a/server.js b/server.js index 936fd72..3c67bd5 100755 --- a/server.js +++ b/server.js @@ -276,6 +276,33 @@ function getGuandanCandidates(game, posId, leadOnly) { }); } + +function evaluateDoudizhuHand(cards) { + const groups = groupCardsByValue(cards || []); + const values = Object.keys(groups).map(Number); + let power = 0; + values.forEach(v => { + const n = groups[v].length; + if (v >= 16) power += 4; + else if (v === 15) power += 3 * n; + else if (v >= 13) power += 1.5 * n; + if (n >= 4) power += 7; + else if (n === 3) power += 2; + }); + if (groups[16] && groups[17]) power += 8; + return power; +} + +function shouldCallDoudizhuScore(cards, ctxScore) { + if (!ctxScore || !ctxScore.length) return 0; + const maxScore = Math.max.apply(null, ctxScore); + const power = evaluateDoudizhuHand(cards); + if (power >= 22 && ctxScore.indexOf(3) >= 0) return 3; + if (power >= 16 && ctxScore.indexOf(2) >= 0) return 2; + if (power >= 11 && ctxScore.indexOf(1) >= 0) return 1; + return (power >= 20 && maxScore) ? maxScore : 0; +} + function time() { return (new Date()).toLocaleTimeString(); } @@ -718,9 +745,10 @@ const proto = { const game = this.gameDatas[deskId]; if (!game) return; const ctxScore = game.getContextScore() || []; - let score = 0; - if (Math.random() < 0.65 && ctxScore.length) { - score = ctxScore[Math.floor(Math.random() * ctxScore.length)]; + const hand = game.getCardsByPosId(posId) || []; + let score = shouldCallDoudizhuScore(hand, ctxScore); + if (!score && Math.random() < 0.12 && ctxScore.length) { + score = ctxScore[0]; } const status = game.next(posId, score).getStatus(); if (status == 1) { @@ -757,7 +785,12 @@ const proto = { len: last.len, key: last.key, type: last.type, ctxPos: 'other' }; let picks = []; - try { picks = (AISuggest.suggest(hand, lastInfo)) || []; } catch (e) { picks = []; } + const allOut = game.validate(posId, handRaw); + if (allOut && allOut.status) { + picks = handRaw.map(c => ({ value: c.value, type: c.type })); + } else { + try { picks = (AISuggest.suggest(hand, lastInfo)) || []; } catch (e) { picks = []; } + } // 解析为真实牌实例(按下标占用避免重复) const used = new Set(); let data = []; diff --git a/static/css/style.css b/static/css/style.css index e52a061..7ac673a 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1781,6 +1781,10 @@ button.btn-ghost { font-size: 13px; color: var(--jade-100); } +.guandan-teams { + display: flex; + flex-direction: column; +} .guandan-team-row span { display: block; max-width: 150px; @@ -1842,10 +1846,15 @@ button.btn-ghost { } .room-guandan .player-top { position: fixed; - left: calc(50vw - 400px); - top: calc(var(--table-top-safe) + var(--card-h) + 38px); - transform: scale(0.76); - transform-origin: top left; + left: 50%; + top: calc(var(--table-top-safe) + var(--card-h) + 30px); + transform: translateX(-50%) scale(0.92); + transform-origin: top center; + z-index: 28; +} +.room-guandan .player-top .team-tag { + top: -8px; + right: -14px; } .room-guandan .player-right { right: calc(var(--table-right-safe) - 124px); @@ -1990,11 +1999,11 @@ button.btn-ghost { .player-right { right: calc(var(--table-right-safe) - 118px); top: calc(50vh - 58px); } .player-top { top: calc(var(--table-top-safe) + var(--card-h) + 22px); } .room-guandan .player-top { - display: none; - left: max(190px, calc(50vw - 315px)); - top: calc(var(--table-top-safe) + var(--card-h) + 26px); - transform: scale(0.68); - transform-origin: top left; + display: block; + left: 50%; + top: calc(var(--table-top-safe) + var(--card-h) + 22px); + transform: translateX(-50%) scale(0.78); + transform-origin: top center; } .icon-group-left { top: 20px; diff --git a/static/index.html b/static/index.html index 7b8debd..f16513b 100755 --- a/static/index.html +++ b/static/index.html @@ -3,7 +3,7 @@ - + 雀阁 · 纸牌房 @@ -22,13 +22,13 @@
雀阁
-