You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
AdLike2048/docs/需求-背包刷新.md

10 KiB

需求:背包刷新

状态:已落地核心实现(含连败组合字保底)
日期:2026-09-16
关联:需求-新项目概述.md、开发规范.md

1. 目标与范围

项 说明
目标 玩家局内背包:全新刷新算法 + 复用老交互/动画;组合仅横向
对象 仅玩家背包
槽位 固定 5
刷新入口 仅普通刷新(扣桃);不做广告刷新
字池 Text.type ∈ {1, 2, 4}(基础字 / 组合字 / 铲子)
本期不做 段位升降玩法、type=3 入池、老项目 P2·P3·P4 保底;AI 字池/背包见 需求-AI决策.md(复用加权抽字,不含 §4.3 连败保底)

1.1 与老项目关系

维度 策略
刷新算法 全新实现;禁止参考或沿用老 BagWeaponPool / P2·P3·P4 保底 / 章节解锁权重 / 地图降权等
拖动与放置 行为与老项目一致,实现时可复用现有视图与 Merge 落子
刷新/放置动画 表现与老项目一致,实现时可复用现有动画类
文字组合 读 Hero.text;仅横向,禁止竖向

2. 存档前置:当前段位 id

刷新算法依赖玩家 当前段位 id 查 Rank.charactersweight。

项 约定
存档字段 须持有当前段位 id(现有 GameDoc.rankId,默认 1;另有 rankStars 本期不消费)
读档 缺失或非法时修正为合法默认(如 1),方向对齐现有 ConfigProjectData.repairRankOnDocLoad
读取入口 实现阶段经统一入口读取(如 RankDataManager.getPlayerRankId())
局内 开战时用存档 rankId 作为本局选档依据;整局不变
段位模块 升星/掉星/匹配等后续实现;本期只保证字段可读写,不写段位玩法规则

3. 配表契约

3.1 Text(字池)

路径:assets/bundles/first/config/Text.json

字段 含义
id 文字 id
icon 展示用字/资源名
type 1 基础字 / 2 武将组合字 / 3 buff(不入池)/ 4 铲子
quality 品质:0 白 / 1 绿 / 2 蓝 / 3 紫 / 4 橙(AI 空位取舍见 需求-AI决策.md §6.4)
weight 基础权重
number1 ~ number20 对应档位下该字在局内池中的 最大数量

3.2 Rank(段位)

路径:assets/bundles/first/config/Rank.json

字段 含义
id 段位 id(与存档 rankId 对应)
charactersweight 本局选档数组:元素为整数 N,表示使用 Text.numberN;玩家读己方段位,AI 读对手段位(算法相同)

说明:

  • N 不是 Text.id,也不是直接权重值。
  • 样例:低段 [1];中段滑动窗口如 [4,5,6];高段如 [9,10]。
  • 玩家与 AI 共用本字段算法;AI 建池时传入对手段位,见 需求-AI决策.md。

3.3 Hero(组合)

路径:assets/bundles/first/config/Hero.json

字段 含义
text 组成文字的 Text id 有序列表
  • 单字英雄:如 [1]。
  • 组合神将:如悟空 [11,12];顺序参与匹配,[11,12] ≠ [12,11]。
  • 概述中的 characters 命名以配表 text 为准。

3.4 Const(刷新消耗)

路径:assets/bundles/first/config/Const.json

id 含义
4 战斗初始刷新消耗(桃子)
5 战斗刷新消耗递增值
30 连败组合字保底:para1 万分比(现 2500=25%),概率 = 连败次数 × 该值;胜利后连败清零

4. 刷新算法

4.1 流程

flowchart TD
    startBattle[开战读存档rankId] --> pickN["从 Rank.charactersweight 等概率随机一个 N"]
    pickN --> initPool["每字 remaining = Text.numberN"]
    initPool --> onRefresh[每次刷新填满5槽]
    onRefresh --> calcW["最终权重 = weight * remaining"]
    calcW --> pick[加权随机选一字]
    pick --> dec["该字 remaining -= 1"]
    dec --> more{槽未满?}
    more -->|是| onRefresh
    more -->|否| done[本轮结束]

4.2 规则细则

  1. 开局确定档位 N(整局一次)

    • 用存档 rankId 取 Rank 行。
    • 从 charactersweight 等概率随机一个整数 N。
    • 本局所有刷新共用该 N,不再重 roll。
  2. 初始化局内池(整局一次)

    • 候选范围:Text.type ∈ {1,2,4},且 weight > 0,且对应 numberN > 0。
    • 对每个候选字:remaining[id] = Text.numberN。
    • 不含 type = 3。
  3. 最终权重

    • 最终权重 = weight × remaining(remaining 为 当前剩余数量)。
    • remaining == 0 的字不进入本次抽取候选。
  4. 抽取与扣减

    • 每次普通刷新:向背包 5 个槽逐槽加权随机填字(或等价地连续抽满 5 次)。
    • 每抽出一字:该字 remaining -= 1。
    • 扣减 整局累计,跨多次刷新 不重置。
    • 首次刷新必须至少 1 个可攻击单字(落下即普攻:刀/枪/棍/弓;不含营、铲、桃、组合碎字)。否则开局打不到来敌、没桃、无法再刷,卡死。池里没有任何攻击字时 warn,不瞎填。
  5. 异常

    • 某次抽槽时候选全空(或权重总和 ≤ 0):须 warn 暴露问题并按失败处理。
    • 禁止静默用默认字/随便挑一个掩盖错误(见开发规范)。
  6. 刷新费用

    • 普通刷新扣桃:读 Const id 4 / 5。
    • 无广告刷新;产品与实现均不提供广告刷入口。

4.3 连败组合字保底(仅玩家)

连败次数复用存档 matchLoseStreak(MatchStreakStats,胜清零、跨天不清)。AI 刷新不走本段。

完整组合英雄: 玩家已持有某 herotype=2 英雄 text 中的全部字(地图散字或已激活均可)。两半都在但没拼上,也算完整英雄,不算碎字。

碎字: 地图上未纳入完整英雄的组合字(Text.type=2)+ 本次刷新已抽出的组合字。即将被刷掉的旧背包不算。

触发: 本局尚未出现完整组合英雄,且碎字已有 4 个时,抽出的第 5 个及之后每个组合字都做判定。保底失败则下一个组合字继续 roll,不是只判一次。

概率: min(10000, 连败次数 × Const30.para1) 万分比。连败 4 次 → 100%。连败 0 则不会命中。

给字: 命中后不看第 5 个字本身该配谁,从已有碎字所缺的另一半里去重后等概率随机一个(悟 可缺 空/能/净)。扣字池 remaining,归还原抽中字。候选为空或 remaining 耗尽则跳过并打日志,不瞎填。

本局停止: 刷新凑齐一对、或地图已有完整英雄后,本局不再判定(含之后把将铲掉)。GM 固定/预设刷新不走保底。

4.4 新号第一局神将字(仅玩家)

详见 需求-首局神将字.md。GM 固定/预设不走。AI 不走。

开战时若尚无对局痕迹:第一次普通刷新必含哪吒/杨戬/悟空六字之一;记下配对另一半;第二次必给该另一半(与是否拖上地图无关)。第一次已抽出完整一对则第二次不补。替换时不得拿掉本批唯一攻击字。


5. 交互与放置

行为与老项目一致(实现可复用现有拖放与 Merge):

能力 要求
拖动 拉线、ghost、落点引导、拖动时战斗画面弱化等既有表现;不对局暂停/慢放
背包 ↔ 背包 空槽移动;同字可合则升级;否则互换
背包 ↔ 地图 落子、升级、互换;铲子开挖等既有逻辑
地图 ↔ 地图 与现网一致
刷新按钮 仅普通刷新;费用不足不可刷

不在本期改变放置规则本身;本期差异仅在「刷出什么字」与「组合方向」。


6. 文字组合

项 约定
配置源 Hero.text(Text id 有序序列)
匹配 地图连续格序列与 text 精确相等
方向 仅横向(左 → 右)
禁止 竖向组合(上 → 下不再生效)

7. 动画表现

场景 要求
刷新入场 与老项目一致(如抛物线入场 + 落地 squash)
放置跳入 与老项目一致(松手后跳入目标格/槽)
验收 观感对齐现网;实现阶段复用现有动画组件即可

8. 明确不做

  • 老项目 P2·P3·P4 刷新保底 / 脸黑脸白 / 强制格子·铲 id。新产品只做 §4.3 连败组合字保底与 §4.4 新号首局神将字。
  • Text.type = 3 进入刷新池。
  • 广告刷新。
  • 将 §4.3 / §4.4 保底套到 AI 背包。
  • 段位升星、掉星、匹配、每日俸禄等局外段位玩法。

9. 验收清单

  • 存档可读当前段位 id;非法时有明确修正;开战用该 id 查 Rank
  • 开局从 charactersweight 只随机一次 N,整局固定
  • 池初始 remaining = numberN;仅 type 1/2/4 且 weight>0 且 numberN>0
  • 最终权重 = weight × remaining;抽中后 remaining 减一且整局累计
  • 每次刷新填满 5 槽;无广告刷新
  • 首次刷新至少 1 个可攻击单字(刀/枪/棍/弓)
  • 候选耗尽有告警/失败,无静默兜底
  • 组合只认 Hero.text,仅横向,竖向不成
  • 拖放交互与刷新/放置动画与老项目表现一致
  • 范围不含 AI 背包
  • 连败组合字保底:4 个碎字后第 5 个及之后组合字按连败×Const30 判定;凑齐一对本局停止;仅玩家
  • 新号第一局神将字:前两次刷新凑齐哪吒/杨戬/悟空之一;仅玩家;见 需求-首局神将字.md

10. 实现阶段提示(非本期交付)

审查通过后的实现方向(供后续方案引用,本文不要求改代码):

  • 新建玩家局内字池/刷新服务,替换旧权重池与保底算法调用链。
  • 组合匹配去掉竖向扫描;配表桥接统一读 Hero.text。
  • 去掉广告刷新入口与相关会话 API。
  • 同步修正概述文档中 charactersweight / Hero.characters 与本文不一致处。