diff --git a/repo/js/七圣召唤七日历练全自动/README.md b/repo/js/七圣召唤七日历练全自动/README.md index 72515db47..dd332502d 100644 --- a/repo/js/七圣召唤七日历练全自动/README.md +++ b/repo/js/七圣召唤七日历练全自动/README.md @@ -2,7 +2,12 @@ 如果某个打牌对手有专用策略时,脚本会使用对应分享码自动导入牌组,并使用对应策略进行打牌; -如果没有专用策略,或者分享码中使用了你尚未获得的角色卡时,将使用通用性最高的'雷神柯莱刻晴'进行打牌。 +如果没有专用策略,或者分享码中使用了你尚未获得的角色卡时: + +- 若开启了`自动尝试备用策略`,将按照策略运行记录,按成功率从大到小的顺序逐个尝试备用策略。 +- 否则,将使用通用性最高的'雷神柯莱刻晴'进行打牌。 + +欢迎提交你的策略运行记录(`牌组策略`文件夹下的`各策略胜败记录.json`文件),汇集大家的数据共同提高打牌效率。 ## 脚本配置 @@ -11,6 +16,7 @@ | 默认牌组 | 填写你游戏中'雷神柯莱刻晴'队所在的牌组名 | | 临时牌组 | 填写用来导入分享码的牌组名 | | 自动尝试备用策略 | 打牌失败时自动逐个尝试备用策略。如果你不想亲自打那些脚本打不过的挑战,也不在乎多次尝试的耗时,可以勾选此项 | +| 仅使用胜率记录大于该值的备用策略 | 根据运行记录,跳过执行那些胜率太小的备用策略 | | 密码 | 随便填 | **注意:** @@ -28,12 +34,10 @@ ## 如何添加或删除备用策略 -脚本自动将`牌组策略`文件夹下,以数字加小数点开头的txt文件识别为备用策略,例如`10.莫娜砂糖琴.txt` +脚本自动将`牌组策略`文件夹下,以数字加小数点开头的txt文件识别为备用策略,例如`1.莫娜砂糖琴.txt` 如果启用了备用策略功能,打牌失败时,按照数字从小到大的顺序自动逐个尝试。 -目前脚本内置了8个备用策略(都是BetterGI内建的策略)。 - 如果想要添加更多的备用策略,参考`_策略模板.txt`完成编辑后,将文件命名为数字加`.`开头就行。 如果觉得尝试次数不用这么多,直接删除备用策略对应的txt文件即可。 diff --git a/repo/js/七圣召唤七日历练全自动/main.js b/repo/js/七圣召唤七日历练全自动/main.js index 1acc62a19..081f5bc06 100644 --- a/repo/js/七圣召唤七日历练全自动/main.js +++ b/repo/js/七圣召唤七日历练全自动/main.js @@ -3,6 +3,9 @@ let textArray = []; let skipNum = 0; let allStrategy = {}; let fallbackStrategyList = []; +const strategyRunRecordFile = "牌组策略/各策略胜败记录.json"; +let strategyRunRecord = {}; +let minFallbackStrategyScore = 0.25; // 切换到指定的队伍 async function switchCardTeam(Name, shareCode) { @@ -200,7 +203,7 @@ async function isTaskRefreshed(filePath, options = {}) { } if (shouldRefresh) { - notification.send(`七圣召唤七日历练周期已经刷新,执行脚本`); + // notification.send(`七圣召唤七日历练周期已经刷新,执行脚本`); return true; } else { @@ -472,6 +475,56 @@ function scanCardStrategy() { return strategyMap; } +function updateRunRecord(charName, strategyName, win) { + if (!strategyRunRecord[charName]) { + strategyRunRecord[charName] = {}; + } + if (!strategyRunRecord[charName][strategyName]) { + strategyRunRecord[charName][strategyName] = { win: 0, fail: 0 }; + } + if (win === true) { + strategyRunRecord[charName][strategyName].win++; + } else if (win === false) { + strategyRunRecord[charName][strategyName].fail++; + } // else : do nothing when null + file.writeTextSync(strategyRunRecordFile, JSON.stringify(strategyRunRecord, null, 2), false); +} + +function sortAndFilterStrategy(charName) { + const atLeastOne = ["雷神柯莱刻晴"]; + if (! settings.useFallbackStrategy) { + return atLeastOne; + } + const toBeCheck = [...atLeastOne, ...fallbackStrategyList]; + const charRecord = strategyRunRecord[charName]; + if (!charRecord) { + return toBeCheck; + } + const scores = {}; + for (const strategyName of toBeCheck) { + const data = charRecord[strategyName]; + if (!data) { + scores[strategyName] = 0.5; // 未尝试过的策略 + continue; + } + if (data.win === 0 && data.fail === 1) { + scores[strategyName] = 0.3; // 仅失败过一次,再给点机会 + } else { + const total = data.win + data.fail; + if (total === 0) { + scores[strategyName] = 0.5; + } else { + scores[strategyName] = data.win / total; + } + } + } + const sortedScores = Object.entries(scores).sort((a, b) => b[1] - a[1]); // 分数从大到小 + log.debug(`各策略胜率分数: ${JSON.stringify(sortedScores)}`); + const sortedKeys = Object.entries(sortedScores) + .filter((entry) => entry[1] >= minFallbackStrategyScore); + return sortedKeys; +} + //检查是否有对应的挑战对手 async function searchAndClickTexts() { middleButtonClick(); @@ -512,14 +565,17 @@ async function searchAndClickTexts() { log.info("使用角色专用策略与{0}对战", charName); success = await Playcards(strategy, settings.overwritePartyName, res); } - if (!success) { - log.info("使用默认策略与{0}对战", charName); - success = await Playcards(allStrategy["雷神柯莱刻晴"], settings.defaultPartyName, res); - } - for (const strategyName of fallbackStrategyList) { + const sortedStrategy = sortAndFilterStrategy(charName); + for (const strategyName of sortedStrategy) { if (!success) { - log.info("使用备用策略{0}与{1}对战", strategyName, charName); - success = await Playcards(allStrategy[strategyName], settings.overwritePartyName, res); + if (strategyName === "雷神柯莱刻晴") { + log.info("使用默认策略{0}与{1}对战", strategyName, charName); + success = await Playcards(allStrategy[strategyName], settings.defaultPartyName, res); + } else { + log.info("使用备用策略{0}与{1}对战", strategyName, charName); + success = await Playcards(allStrategy[strategyName], settings.overwritePartyName, res); + } + updateRunRecord(charName, strategyName, success); } } @@ -603,7 +659,7 @@ async function Playcards(strategy, teamName, pos) { if (!success) { keyPress("ESCAPE"); await sleep(2000); - return success; + return null; } click(1610, 900); //点击挑战 await waitOrCheckMaxCoin(8000); @@ -731,10 +787,16 @@ async function gotoTable6() { async function main() { //主流程 + const nowTime = new Date(); log.info(`前往猫尾酒馆`); await gotoTavern(); await captureAndStoreTexts(); allStrategy = scanCardStrategy(); + try { + strategyRunRecord = JSON.parse(file.readTextSync(strategyRunRecordFile)); + } catch (error) { + log.debug("读取策略运行记录失败"); + } if (settings.useFallbackStrategy) { fallbackStrategyList = Object.keys(allStrategy).filter((key) => { return /^(\d+)\./.test(key); @@ -743,6 +805,16 @@ async function main() { return parseInt(a) - parseInt(b); }); log.info("已启用{0}个备用策略: {1}", fallbackStrategyList.length, fallbackStrategyList.join(", ")); + + try { + const scoreInSetting = parseFloat(settings.minFallbackStrategyScore || -1); + if (scoreInSetting < 0 || scoreInSetting > 1) { + throw new RangeError("无效的输入值范围"); + } + minFallbackStrategyScore = scoreInSetting; + } catch (error) { + log.warn("未设置备用策略胜率阈值或阈值无效,使用默认值{0}", minFallbackStrategyScore); + } } else { log.info("未启用备用策略"); } diff --git a/repo/js/七圣召唤七日历练全自动/manifest.json b/repo/js/七圣召唤七日历练全自动/manifest.json index 3f9db6cd3..3901796cc 100644 --- a/repo/js/七圣召唤七日历练全自动/manifest.json +++ b/repo/js/七圣召唤七日历练全自动/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "打牌一条龙", - "version": "2.5", + "version": "2.6", "description": "完成每周的七圣召唤七日历练(来客挑战)。详见README.md", "tags": [ "七圣召唤" diff --git a/repo/js/七圣召唤七日历练全自动/settings.json b/repo/js/七圣召唤七日历练全自动/settings.json index 3e34ca894..6cd0eb3f7 100644 --- a/repo/js/七圣召唤七日历练全自动/settings.json +++ b/repo/js/七圣召唤七日历练全自动/settings.json @@ -14,6 +14,11 @@ "type": "checkbox", "label": "打牌失败时自动逐个尝试备用策略" }, + { + "name": "minFallbackStrategyScore", + "type": "input-text", + "label": "仅使用胜率记录大于该值的备用策略 (0到1之间的小数)" + }, { "name": "passWord", "type": "input-text", diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/10.莫娜砂糖琴.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/1.莫娜砂糖琴.txt similarity index 100% rename from repo/js/七圣召唤七日历练全自动/牌组策略/10.莫娜砂糖琴.txt rename to repo/js/七圣召唤七日历练全自动/牌组策略/1.莫娜砂糖琴.txt diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/10.皇女白术林尼.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/10.皇女白术林尼.txt new file mode 100644 index 000000000..060d7a0a3 --- /dev/null +++ b/repo/js/七圣召唤七日历练全自动/牌组策略/10.皇女白术林尼.txt @@ -0,0 +1,44 @@ +// shareCode=AnGhuTQMEoGR83oQCCGR9HsQCDGh9bQQDEEx9rUQDFFB97YQDGFR+LcQDHFh+bgQDIEB +// 作者:HZYgrandma + +角色定义: +角色1=皇女 +角色2=白术 +角色3=林尼 +--- +策略定义: +皇女 使用 技能2 +白术 使用 技能2 + +林尼 使用 技能3 +白术 使用 技能2 + +皇女 使用 技能2 +白术 使用 技能1 + +白术 使用 技能2 +林尼 使用 技能3 + +皇女 使用 技能2 +白术 使用 技能2 + +林尼 使用 技能3 +白术 使用 技能2 + +皇女 使用 技能2 +白术 使用 技能1 + +白术 使用 技能2 +林尼 使用 技能3 + +皇女 使用 技能2 +白术 使用 技能2 + +林尼 使用 技能3 +白术 使用 技能2 + +皇女 使用 技能2 +白术 使用 技能1 + +白术 使用 技能2 +林尼 使用 技能3 diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/20.刻晴雷神甘雨.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/2.刻晴雷神甘雨.txt similarity index 100% rename from repo/js/七圣召唤七日历练全自动/牌组策略/20.刻晴雷神甘雨.txt rename to repo/js/七圣召唤七日历练全自动/牌组策略/2.刻晴雷神甘雨.txt diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/30.雷神阿贝多丘丘王.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/3.雷神阿贝多丘丘王.txt similarity index 100% rename from repo/js/七圣召唤七日历练全自动/牌组策略/30.雷神阿贝多丘丘王.txt rename to repo/js/七圣召唤七日历练全自动/牌组策略/3.雷神阿贝多丘丘王.txt diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/40.重云雷神申鹤.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/4.重云雷神申鹤.txt similarity index 100% rename from repo/js/七圣召唤七日历练全自动/牌组策略/40.重云雷神申鹤.txt rename to repo/js/七圣召唤七日历练全自动/牌组策略/4.重云雷神申鹤.txt diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/50.迪希雅白术皇女.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/5.迪希雅白术皇女.txt similarity index 100% rename from repo/js/七圣召唤七日历练全自动/牌组策略/50.迪希雅白术皇女.txt rename to repo/js/七圣召唤七日历练全自动/牌组策略/5.迪希雅白术皇女.txt diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/60.皇女柯莱莫娜.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/6.皇女柯莱莫娜.txt similarity index 100% rename from repo/js/七圣召唤七日历练全自动/牌组策略/60.皇女柯莱莫娜.txt rename to repo/js/七圣召唤七日历练全自动/牌组策略/6.皇女柯莱莫娜.txt diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/70.莫娜白术皇女.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/7.莫娜白术皇女.txt similarity index 100% rename from repo/js/七圣召唤七日历练全自动/牌组策略/70.莫娜白术皇女.txt rename to repo/js/七圣召唤七日历练全自动/牌组策略/7.莫娜白术皇女.txt diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/80.芙芙卡维鲸鱼.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/8.芙芙卡维鲸鱼.txt similarity index 100% rename from repo/js/七圣召唤七日历练全自动/牌组策略/80.芙芙卡维鲸鱼.txt rename to repo/js/七圣召唤七日历练全自动/牌组策略/8.芙芙卡维鲸鱼.txt diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/9.迪希雅八重神子纯水精灵.txt b/repo/js/七圣召唤七日历练全自动/牌组策略/9.迪希雅八重神子纯水精灵.txt new file mode 100644 index 000000000..e39ede131 --- /dev/null +++ b/repo/js/七圣召唤七日历练全自动/牌组策略/9.迪希雅八重神子纯水精灵.txt @@ -0,0 +1,34 @@ +// shareCode=AnGRuSIMBIFR83oQCCGR9HsQCDGh9bQQDEEx9rUQDFFB97YQDGFR+LcQDHFh+bgQDIEB +// 作者: johsang +// 描述: 对面出伤快、元素盾、耐耗王可用,多种召唤物稳定赚费补强生存,应对一些刁钻局有奇效 + + +角色定义: +角色1=迪希雅|火{技能3消耗=1火骰子+2任意,技能2消耗=3火骰子,技能1消耗=4火骰子} +角色2=八重神子|雷{技能3消耗=1雷骰子+2任意,技能2消耗=3雷骰子,技能1消耗=3雷骰子} +角色3=纯水精灵|水{技能4消耗=1水骰子+2任意,技能3消耗=3水骰子,技能2消耗=5水骰子,技能1消耗=3水骰子} + +--- +策略定义: +迪希雅 使用 技能2 +八重神子 使用 技能2 + +八重神子 使用 技能2 +纯水精灵 使用 技能3 + +纯水精灵 使用 技能3 +迪希雅 使用 技能2 + +迪希雅 使用 技能1 +八重神子 使用 技能1 + +纯水精灵 使用 技能3 +纯水精灵 使用 技能1 + +// 后续的内容不太可能执行到,只是为了一些特殊对局 + +纯水精灵 使用 技能3 +迪希雅 使用 技能2 + +八重神子 使用 技能2 +纯水精灵 使用 技能3 \ No newline at end of file diff --git a/repo/js/七圣召唤七日历练全自动/牌组策略/各策略胜败记录.json b/repo/js/七圣召唤七日历练全自动/牌组策略/各策略胜败记录.json new file mode 100644 index 000000000..979cabb48 --- /dev/null +++ b/repo/js/七圣召唤七日历练全自动/牌组策略/各策略胜败记录.json @@ -0,0 +1,8 @@ +{ + "莱拉": { + "2.刻晴雷神甘雨": { + "win": 1, + "fail": 0 + } + } +} \ No newline at end of file