UmamusumeResponseAnalyzer
UmamusumeResponseAnalyzer copied to clipboard
育成结束计算最大技能点时若干问题
在育成时候点了单圈技能,最后结束算最大评价点时仍选择已选过的单圈技能(如:在育成中选择了根干距离单圈,而育成结束程序给出的技能列表中仍然出现了根干距离单圈)即使要选,也应该显示为选择双圈,而非单圈。但程序没有。
并且你的背包dp代码貌似仅仅只是把金技能和其下位技能看作两个独立技能,在dp时没有考虑 如果要选择金技能,就必须选择其下位技能
这种情况,同样绿技能也是,我怀疑这样算出来的最大值是错误的。我没有仔细看具体代码,但如果真如此,我怀疑如右回的鬼这种金绿技能,程序也没有做对应的处理。
以及我点完技能后貌似是没有算有切者的情况,点完还多了几百点
这是我用https://github.com/MiddleRed/UmaSkillMaximize 算出来的结果
用这个算出来的还多了17点,对着右边的点也是正好是18117。还是希望修一下吧
算最大评价点时仍选择已选过的单圈技能
现在确实没有考虑之前学过技能的情况,只简单计算了他们的评价点
仅仅只是把金技能和其下位技能看作两个独立技能,在dp时没有考虑 如果要选择金技能,就必须选择其下位技能 这种情况
对于赛马娘来说,金右、双圈右、单圈右、右×共享同一个GroupId 20001,如果同一个GroupId出现了多次会删掉下位技能(通常是删掉打折下位技能,双圈绿按理来说也会被删掉但是他毛分效率太低了,不常出现,也不好debug)后重新计算。因为直接按“没有那个hint”计算,上位金技能也包含了学下位技能所需的技能点,所以一般不会出现错误(至少我debug的那几把都没出现)
foreach (var i in learn.GroupBy(x => x.GroupId).Where(x => x.Count() > 1))
{
var duplicated = learn.Where(x => x.GroupId == i.Key);
foreach (var j in duplicated)
if (j.Superior != null)
tips.Remove(j);
}
以及我点完技能后貌似是没有算有切者的情况,点完还多了几百点
private void ApplyHint(Gallop.SingleModeChara chara_info, int level)
{
if (chara_info.chara_effect_id_array.Contains(7))
Cost = Cost * 90 / 100;
var off = level switch
{
1 => 10,
2 => 20,
3 => 30,
4 => 35,
5 => 40
};
Cost = Cost * (100 - off) / 100;
}
if (chara_info.chara_effect_id_array.Contains(7)) Cost = Cost * 90 / 100;
7是依据数据库内信息的推测,应该是会正常计算的,但这玩意毕竟可遇不可求,只能等我什么时候恰好有切了才能验证
双圈确实在绝大部分情况下性价比过于低下,一般不点,不过如果是打满Hint有时候还真不一定不点双圈。 并且有的时候会出现金技能没Hint而其下位技能Hint很高的情况(金技能和下位技能Hint相互独立),先前遇到这种情况用UmaSkillMaximize算出来都是只点下位不点金技。而且前几周我在借ntr冲ug的时候,育成结束后没有一把算出来是要点金良场的,所以应该也不能直接无视下位技能。
只有在确认要学上位技能的时候才会无视下位技能,这样就不需要改背包算法了, 我会优先解决https://github.com/EtherealAO/UmamusumeResponseAnalyzer/issues/6 Win7不能用的问题,你有空的话可以开一个PR
关于切者的通信包数据chara_info.chara_effect_id_array数组值如下
练习上手与切者为[10,7]
练习下脚与单切为[3,7]
除不会考虑已点过的技能外,结算时打印出来的技能点数仍与游戏中有部分偏差,切者应为当前折扣+10%而不是直接打九折
照着我写的计算器改了一下 正确的计算打折后技能评价点的公式应该是这样的
private void ApplyHint(Gallop.SingleModeChara chara_info, int level)
{
bool isCutted = chara_info.chara_effect_id_array.Contains(7);
var off = level switch
{
1 => 10,
2 => 20,
3 => 30,
4 => 35,
5 => 40
};
Cost = Cost * (100 - off) / 100 - (isCutted ? 1 : 0) * Cost / 10;
}
[#] 修复有切者时技能点计算错误的BUG
[#] 修复计算技能评价点时会剩余大量技能点的BUG
[#] 修复连续计算技能评价点时价格异常的BUG
[#] 修复计算技能评价点时会忽略天赋技能的BUG
修了几个BUG,但还是会出现这种用更多的技能点点更少的评价点的情况,剩下的就要靠各位发PR了
我把我自己的算法尝试着移植过来了,基本上就是照抄这个从825行开始。不过实际测试时候总是出点岔子,不知道哪里出了问题,可以的话还请帮忙看看
https://pastebin.com/wBbWwrXY
可能因为Inferior/Superior并没有Apply吧(因为金技能和白技能的hint不一定相同 debug的时候可以把
public SkillData Apply(Gallop.SingleModeChara chara_info, int level)
{
var instance = Clone();
instance.ApplyHint(chara_info, level);
instance.ApplyProper(chara_info);
return instance;
}
改成
public SkillData Apply(Gallop.SingleModeChara chara_info, int level)
{
//var instance = Clone();
//instance.ApplyHint(chara_info, level);
//instance.ApplyProper(chara_info);
//return instance;
ApplyHint(chara_info, level);
ApplyProper(chara_info);
return this;
}
,这样应用的时候会直接作用在数据库里,虽然只有第一次调用是正确的,但是调试时足够了。此时也应该注释掉29~38行(单独为天赋技能计算TotalCost)
算法的话,
if (s.Superior != null && s.Name.Contains("○") && s.Superior.Name.Contains("◎"))
显然是错的,应该是
if (s.Superior != null && (s.Name.Contains("○") || s.Superior.Name.Contains("◎")))
紧接着的
tips.Add(s.Superior);
应该加一个防止重复添加的检测(但是不加可能也不影响?
if (!tips.Any(x => x.Id == s.Superior.Id)) tips.Add(s.Superior);
再有就是Cost只代表学习此技能所需要的技能点,不包括学习前置技能所需要的,在不考虑已学习技能的条件下,绝大部分时候都应该是TotalCost
但尽管如此在我这里的输出仍然有极大的偏差( 我也不太清楚了就
算法的话,
if (s.Superior != null && s.Name.Contains("○") && s.Superior.Name.Contains("◎"))
显然是错的
这里是为了防止コーナー巧者○
这种名字里有圈但实际上没有双圈的技能混进去,预想中这个if只会让有单双圈之分的单圈技能通过。至于重复检测,只要保证最开始的tips里边不会同时出现同一技能的单圈和双圈就不需要检测重复了。
改成
public SkillData Apply(Gallop.SingleModeChara chara_info, int level)
{
//var instance = Clone();
//instance.ApplyHint(chara_info, level);
//instance.ApplyProper(chara_info);
//return instance;
ApplyHint(chara_info, level);
ApplyProper(chara_info);
return this;
}
这貌似对像長距離コーナー○
这样的有系数的单双圈技能不适用,通过上位技能读取Inferior.Grade读,单圈评价点对的,双圈就不对了
因为我自己的测试样本挺简单的,没几个Hint,再来个复杂点的估计找出的问题更多(
现在算法修好没问题了,只要确保所有技能通过Inferior/Superior读到的技能Cost都apply上hint和Grade乘上系数就解决了
不过这个只适合育成结束后什么技能都没有点的情况,如果点了的话还得特判一下,但是应该很好解决
算法的话,
if (s.Superior != null && s.Name.Contains("○") && s.Superior.Name.Contains("◎"))
显然是错的这里是为了防止
コーナー巧者○
这种名字里有圈但实际上没有双圈的技能混进去,预想中这个if只会让有单双圈之分的单圈技能通过。至于重复检测,只要保证最开始的tips里边不会同时出现同一技能的单圈和双圈就不需要检测重复了。改成
public SkillData Apply(Gallop.SingleModeChara chara_info, int level) { //var instance = Clone(); //instance.ApplyHint(chara_info, level); //instance.ApplyProper(chara_info); //return instance; ApplyHint(chara_info, level); ApplyProper(chara_info); return this; }
这貌似对像
長距離コーナー○
这样的有系数的单双圈技能不适用,通过上位技能读取Inferior.Grade读,单圈评价点对的,双圈就不对了 因为我自己的测试样本挺简单的,没几个Hint,再来个复杂点的估计找出的问题更多(现在算法修好没问题了,只要确保所有技能通过Inferior/Superior读到的技能Cost都apply上hint和Grade乘上系数就解决了 不过这个只适合育成结束后什么技能都没有点的情况,如果点了的话还得特判一下,但是应该很好解决
在你那边发PR了