mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-17 03:43:26 +08:00
js: 七圣召唤七日历练: 记录各策略的成功率数据,并据此优化策略选择 (#2005)
This commit is contained in:
@@ -2,7 +2,12 @@
|
||||
|
||||
如果某个打牌对手有专用策略时,脚本会使用对应分享码自动导入牌组,并使用对应策略进行打牌;
|
||||
|
||||
如果没有专用策略,或者分享码中使用了你尚未获得的角色卡时,将使用通用性最高的'雷神柯莱刻晴'进行打牌。
|
||||
如果没有专用策略,或者分享码中使用了你尚未获得的角色卡时:
|
||||
|
||||
- 若开启了`自动尝试备用策略`,将按照策略运行记录,按成功率从大到小的顺序逐个尝试备用策略。
|
||||
- 否则,将使用通用性最高的'雷神柯莱刻晴'进行打牌。
|
||||
|
||||
欢迎提交你的策略运行记录(`牌组策略`文件夹下的`各策略胜败记录.json`文件),汇集大家的数据共同提高打牌效率。
|
||||
|
||||
## 脚本配置
|
||||
|
||||
@@ -11,6 +16,7 @@
|
||||
| 默认牌组 | 填写你游戏中'雷神柯莱刻晴'队所在的牌组名 |
|
||||
| 临时牌组 | 填写用来导入分享码的牌组名 |
|
||||
| 自动尝试备用策略 | 打牌失败时自动逐个尝试备用策略。如果你不想亲自打那些脚本打不过的挑战,也不在乎多次尝试的耗时,可以勾选此项 |
|
||||
| 仅使用胜率记录大于该值的备用策略 | 根据运行记录,跳过执行那些胜率太小的备用策略 |
|
||||
| 密码 | 随便填 |
|
||||
|
||||
**注意:**
|
||||
@@ -28,12 +34,10 @@
|
||||
|
||||
## 如何添加或删除备用策略
|
||||
|
||||
脚本自动将`牌组策略`文件夹下,以数字加小数点开头的txt文件识别为备用策略,例如`10.莫娜砂糖琴.txt`
|
||||
脚本自动将`牌组策略`文件夹下,以数字加小数点开头的txt文件识别为备用策略,例如`1.莫娜砂糖琴.txt`
|
||||
|
||||
如果启用了备用策略功能,打牌失败时,按照数字从小到大的顺序自动逐个尝试。
|
||||
|
||||
目前脚本内置了8个备用策略(都是BetterGI内建的策略)。
|
||||
|
||||
如果想要添加更多的备用策略,参考`_策略模板.txt`完成编辑后,将文件命名为数字加`.`开头就行。
|
||||
|
||||
如果觉得尝试次数不用这么多,直接删除备用策略对应的txt文件即可。
|
||||
|
||||
@@ -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("未启用备用策略");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "打牌一条龙",
|
||||
"version": "2.5",
|
||||
"version": "2.6",
|
||||
"description": "完成每周的七圣召唤七日历练(来客挑战)。详见README.md",
|
||||
"tags": [
|
||||
"七圣召唤"
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
"type": "checkbox",
|
||||
"label": "打牌失败时自动逐个尝试备用策略"
|
||||
},
|
||||
{
|
||||
"name": "minFallbackStrategyScore",
|
||||
"type": "input-text",
|
||||
"label": "仅使用胜率记录大于该值的备用策略 (0到1之间的小数)"
|
||||
},
|
||||
{
|
||||
"name": "passWord",
|
||||
"type": "input-text",
|
||||
|
||||
44
repo/js/七圣召唤七日历练全自动/牌组策略/10.皇女白术林尼.txt
Normal file
44
repo/js/七圣召唤七日历练全自动/牌组策略/10.皇女白术林尼.txt
Normal file
@@ -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
|
||||
34
repo/js/七圣召唤七日历练全自动/牌组策略/9.迪希雅八重神子纯水精灵.txt
Normal file
34
repo/js/七圣召唤七日历练全自动/牌组策略/9.迪希雅八重神子纯水精灵.txt
Normal file
@@ -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
|
||||
8
repo/js/七圣召唤七日历练全自动/牌组策略/各策略胜败记录.json
Normal file
8
repo/js/七圣召唤七日历练全自动/牌组策略/各策略胜败记录.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"莱拉": {
|
||||
"2.刻晴雷神甘雨": {
|
||||
"win": 1,
|
||||
"fail": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user