package rules; import com.solution.rule.domain.ultimately.fact.DroolsFact; import java.util.Map; import static com.solution.rule.utils.RuleFunction.equipmentRule; global java.util.Map globalParams; /** * 构建装备匹配所需的全部可调参数(会 merge 进 globalParams,覆盖 Java 侧同名默认值)。 * * ========== 总体运算逻辑(与 RuleFunction.equipmentRule 一致)========== * 1)先拼「蓝方文本串」blueBlob:任务 drawName、dataType、taskWeapons 下各武器的 name/supportType/equipmentId、组件 deviceName。 * 2)对每个红方装备拼「红方文本串」redBlob:name、platform_type、SupportType。 * 3)每件红装得分 score = 规则槽得分(scoreRuleSlots) + 兼容层得分(scoreLegacyLayer),均为整数。 * - 规则槽:对 i=1..ruleSlotCount,若 blueBlob 命中 blueRuleKeywords_i 且 redBlob 命中 redRuleKeywords_i, * 则加上 ruleScore_i * weight。 * - 兼容层:多组「蓝关键词 + 红关键词 + 对应分数」,见下方各键说明;每组条件同时满足则加上 对应Score * weight。 * 4)在池中取 score 最大者;若多人并列,由 tieBreak 决定(见 tieBreak)。 * 5)若 maxScore < minSelectedScore,视为未匹配:不往 fireRuleInputs 追加行,redWeapons 输出仍为当前池。 * 6)若匹配成功:从池中 remove 该件;fireRuleInputs 追加一行,drawName 后接 outputDrawNameSuffix;taskWeapons 填选中红装映射。 * * 关键词格式:英文逗号分隔,子串包含即算命中(contains),不要求整词匹配。 */ function Map buildParam(){ Map param = new java.util.HashMap(); // ---------- 全局倍率与门槛 ---------- // weight:对上述所有「基础分数」的统一乘数(规则槽的 ruleScore_i、兼容层的 *Score 都会乘 weight)。 param.put("weight", 1); // minSelectedScore:单件红装总分达到该值及以上才会被选中并写入 fireRuleInputs;否则本任务视为未匹配到装备。 param.put("minSelectedScore", 1); // tieBreak:并列最高分时的决胜方式。当前实现仅支持 "equipmentId":装备 ID 字典序更小的优先。 param.put("tieBreak", "equipmentId"); // outputDrawNameSuffix:匹配成功写入 fireRuleInputs 时,在蓝方原 drawName 后面拼接的后缀(如「打击任务」)。 param.put("outputDrawNameSuffix", "打击任务"); // ---------- 规则槽(可配置条数,便于只改本文件而不改 Java)---------- // ruleSlotCount:启用几条槽规则;第 i 条使用 blueRuleKeywords_i、redRuleKeywords_i、ruleScore_i。 param.put("ruleSlotCount", 3); // 槽1:蓝方文本中出现任一子串 且 红方文本中出现任一子串 → 加 ruleScore_1 * weight。 param.put("blueRuleKeywords_1", "F-16,F-35"); param.put("redRuleKeywords_1", "防空,导弹,无人机"); param.put("ruleScore_1", 5); param.put("blueRuleKeywords_2", "坦克,装甲"); param.put("redRuleKeywords_2", "反坦克"); param.put("ruleScore_2", 4); param.put("blueRuleKeywords_3", "地面,突击"); param.put("redRuleKeywords_3", "远火,榴弹,炮"); param.put("ruleScore_3", 2); // ---------- 兼容层:按「场景关键词」配对加分(与 RuleFunction.scoreLegacyLayer 一一对应)---------- // 以下每组均为:蓝方文本命中第一列关键词 且 红方文本命中第二列关键词 → 加 第三列分数 * weight。 // // ① 空中平台类:蓝方像「对空/机型」且红方像对空装备 → + airScore * weight param.put("bluePlatformKeywords_air", "F-16,J-10,F-35"); param.put("redPreferredWhenBlueAir", "防空,导弹,无人机,直升机,空空"); param.put("airScore", 2); // ② 任务文案像空中任务 且 红方偏好对空 → + airTaskScore * weight(可与①叠加) param.put("airTaskKeywords", "空中,制空,拦截,空战"); param.put("airTaskScore", 10); // ③ 任务文案像地面任务 且 红方偏好地面火力 → + groundScore * weight param.put("groundTaskKeywords", "地面,突击,登陆"); param.put("redPreferredWhenGround", "远火,榴弹,炮,火箭"); param.put("groundScore", 1); // ④ 蓝方像坦克/装甲目标 且 红方文本命中 redMatchKeywords_tank → + tankScore * weight param.put("tankKeywords", "坦克,装甲"); param.put("redMatchKeywords_tank", "反坦克"); param.put("tankScore", 1); // ⑤ 蓝方像导弹类 且 红方文本命中 redMatchKeywords_missile → + missileScore * weight param.put("missileKeywords", "导弹,火箭弹,巡航"); param.put("redMatchKeywords_missile", "防空,导弹,导弹发射"); param.put("missileScore", 1); return param; } rule "装备匹配" salience 100 when $fact : DroolsFact(task != null) then // 以本文件 buildParam 为真源覆盖同名键,再执行 Java 侧匹配逻辑 globalParams.putAll(buildParam()); equipmentRule($fact, globalParams); end