问题
游戏面板
8是青玉之爪
13是海巨人
17是恐狼前锋
64是萨满
66是圣骑士
63,99,46,是微型木乃伊【其中99和46都是2血3攻,63是2血1攻】
57是鱼人木乃伊
微型木乃伊 "LocStringZhCn": "<b>复生</b>\n在你的回合结束时,随机使另一个友方随从获得+1攻击力。",
鱼人木乃伊,可以复生
目前的计算出的策略是
value of best board 49
Best actions as following:
Action1:
play id 8 pos 1 青玉之爪
Action2:
play id 13 pos 1 海巨人
Action3:
attacker: 17 enemy: 66 恐狼前锋攻击圣骑士
Action4:
attack with hero, enemy: 99 己方英雄攻击微型木乃伊
问题在于,使用青玉之爪后,可以召唤一个图腾,然后再上海巨人
ai调试
调试1
通过战斗日志,进行ai计算。花了44秒(因为测试使用单线程),并且ai进行了7层计算。
因为silverfish采用了暴力算法进行处理,手牌和场上的随从都会影响计算的复杂度(指数级的增长)。
调试2
因为上面的计算过于复杂,不方便调试。所以可以直接删除2张无用的手牌(火元素和风怒),重新计算。
调整后的计算结果
value of best board 39
Best actions as following:
Action1:
play id 8 pos 1
Action2:
play id 13 pos 1
Action3:
attack with hero, enemy: 99
Action4:
attacker: 17 enemy: 66
和上面的结果相同,但是面板分值减少(这是删除2张手牌导致的)。并且好处是ai的计算,减少到了5层。
ailoops
ailoop1
deep 1 len 7 dones 0
cut to len 7
ailoop2
deep 2 len 32 dones 0
cut to len 23
ailoop3
deep 3 len 72 dones 0
cut to len 36
ailoop4
deep 4 len 78 dones 0
cut to len 27
ailoop5
deep 5 len 0 dones 0
cut to len 0
ailoop1 有效操作7个
### do all moves in Ai start ###
ailoop1
startEnemyTurnSimThread1
start print 7 actions startIndex = 0,endIndex = 1
a1.print(); start
play id 13 pos 1 操作1,使用海巨人
a1.print(); end
start pf.complete = False
end pf.complete = False
a2.print(); start
play id 8 pos 1 操作2,使用青玉之爪
a2.print(); end
start pf.complete = False
end pf.complete = False
a3.print(); start
attacker: 17 enemy: 63 操作3,恐狼前锋攻击微型木乃伊【2血1攻的木乃伊】
a3.print(); end
start pf.complete = False
end pf.complete = False
a4.print(); start
attacker: 17 enemy: 99 操作4,恐狼前锋攻击微型木乃伊 【2血3攻的木乃伊】
a4.print(); end
start pf.complete = False
end pf.complete = False
a5.print(); start
attacker: 17 enemy: 57 操作5,恐狼前锋攻击鱼人木乃伊
a5.print(); end
start pf.complete = False
end pf.complete = False
a6.print(); start
attacker: 17 enemy: 66 操作6,恐狼前锋攻击圣骑士
a6.print(); end
start pf.complete = False
end pf.complete = False
a7.print(); start
useability 操作7,使用英雄技能
a7.print(); end
start pf.complete = False
end pf.complete = False
end print 7 actions startIndex = 0,endIndex = 1,
ailoop4 有效操作27个
使用青玉之爪是必须的,从ailoop4中找这个。【复制ailoop4到ailoop5之间的】
战斗日志筛选起来非常复杂,筛选青玉之爪或者海巨人,都有20多个记录。逐条排查太慢了。
重新分析一下,正确的操作,应该有5个。所以在打印action的时候,显示编号,找到有action5的就可以了。
尝试之后,发现找不到action5,所以需要5个不步骤的操作,在ailoop3里面就被淘汰了?
ailoop2 有效操作23个
搜搜itemPlayfield1 chuck deep2==2,可以看到23个操作。复制出来,然后搜useability,看看是否有这个和青玉之爪配合的。
23个里面,使用英雄技能的,一共找到7个,需要进行淘汰【这个搜索方案不一定正确,有可能影响技能不需要第一个action中使用】
ailoop2里面的1个待考察的,在ailoop3里面的操作。(先使用海巨人,不使用英雄技能召唤图腾的问题) 后面的验证,证实了上面的猜测,不一定要在前两个回合中使用英雄技能
淘汰标准
1.不能海巨人
2.不能击杀敌方随从
淘汰结果是:
1个完美,1个待考察,2个因为海巨人淘汰,3个因为击杀随从淘汰
itemPlayfield2 chuck deep2==2 boardvalue==52 海巨人,淘汰
action1
play id 13 pos 1
action2
useability
itemPlayfield10 chuck deep2==2 boardvalue==42 海巨人,淘汰
action1
useability
action2
play id 13 pos 1
itemPlayfield12 chuck deep2==2 boardvalue==22 待考察,召唤图腾和恐狼前锋攻击圣骑士
action1
attacker: 17 enemy: 66
action2
useability
itemPlayfield13 chuck deep2==2 boardvalue==20 击杀随从,淘汰
action1
attacker: 17 enemy: 63 恐狼前锋攻击2血1攻的微型木乃伊,击杀随从
action2
useability
itemPlayfield14 chuck deep2==2 boardvalue==19 使用青玉之爪和英雄技能,完美
action1
play id 8 pos 1
action2
useability
itemPlayfield15 chuck deep2==2 boardvalue==17 击杀随从淘汰
action1
useability
action2
attacker: 17 enemy: 57 恐狼前锋攻击鱼人木乃伊,击杀随从【虽然会复生,但是目前不支持这个卡牌的sim,以及复生机制】
itemPlayfield19 chuck deep2==2 boardvalue==16 击杀随从,淘汰
action1
attacker: 17 enemy: 99 恐狼前锋攻击2血3攻的微型木乃伊,击杀随从
action2
useability
ailoop3 有36个有效操作
搜索上面完美的那个
action1
play id 8 pos 1
action2
useability
然后有3个结果
itemPlayfield16 chuck deep2==3 boardvalue==33
action1
play id 8 pos 1
action2
useability
action3
attack with hero, enemy: 99 英雄攻击2血3攻的微型木乃伊,淘汰。因为随从死亡,会导致海巨人的后续费用增加
itemPlayfield21 chuck deep2==3 boardvalue==26
action1
play id 8 pos 1
action2
useability
action3
attack with hero, enemy: 63 英雄攻击2血1攻的微型木乃伊,这个也不行。
打印这个的面板数据看看?
itemPlayfield23 chuck deep2==3 boardvalue==25
action1
play id 8 pos 1
action2
useability
action3
attacker: 17 enemy: 63 恐狼前锋攻击2血1攻的木乃伊,这个也不行。
所以这条路不通。应该是计算重复的时候,这个里面的某一个操作和ailoop2里面4个待考察的重叠了。
重新算一次ailoop4
分别搜索上ailoop3里面的3个完美操作,只搜索到了1个
itemPlayfield18 chuck deep2==4 boardvalue==34
action1
play id 8 pos 1 青玉之爪
action2
useability 英雄技能
action3
attack with hero, enemy: 63 英雄攻击
action4
attacker: 17 enemy: 66 恐狼前锋攻击
打印这个的面板18数据,分值34
int chuck1 = 0; foreach (var itemPlayfield in posmoves) { chuck1++; var boardValue = botBase.getPlayfieldValue(itemPlayfield); Helpfunctions.Instance.logg($"itemPlayfield{chuck1} chuck deep2=={deep} boardvalue=={boardValue}"); itemPlayfield.printActions(); if (chuck1 == 18 && deep == 4) { itemPlayfield.printBoard(); } }
+++++++ printBoard start +++++++++
board/hash/turn: 34 / 2620263623306 / 0 ++++++++++++++++++++++
pen 0
mana 3/6
cardsplayed: 1 handsize: 1 enemyhand: 3
ownhero:
ownherohp: 28 + 0
ownheroattac: 2
ownheroweapon: 2 1 jadeclaws CFM_717 0 0
ownherostatus: frozenFalse
enemyherohp: 8 + 0
play id 8 pos 1
useability
attack with hero, enemy: 63
attacker: 17 enemy: 66
OWN MINIONS################ 2
deckpos, name,ang, hp: 1, direwolfalpha, 2, 2 17
deckpos, name,ang, hp: 2, jadegolem, 2, 1 1000
ENEMY MINIONS############ 3
deckpos, name,ang, hp: 1, micromummy, 3, 2 99
deckpos, name,ang, hp: 2, micromummy, 3, 2 46
deckpos, name,ang, hp: 3, murmy, 1, 1 57
DIED MINIONS############
own, entity, cardid: False, 63, ULD_217
Own Handcards:
pos 1 seagiant 5 entity 13 EX1_586 0 0 0
+++++++ printBoard end +++++++++
观察面板,发现法力值剩余是3,而手牌上还有海巨人。是3费可以用的。下一回合,可以使用海巨人
打印面板1的数据 根据下一步的分析,这个面板在经过敌方模拟后,分值最高79
itemPlayfield1 chuck deep2==4 boardvalue==79
action1
play id 8 pos 1 青玉之爪
action2
play id 13 pos 1 海巨人
action3
attack with hero, enemy: 99 英雄攻击
action4
attacker: 17 enemy: 66 恐狼前锋攻击
+++++++ printBoard start +++++++++
board/hash/turn: 79 / 2110573430307 / 0 ++++++++++++++++++++++
pen 0
mana 0/6
cardsplayed: 2 handsize: 0 enemyhand: 3
ownhero:
ownherohp: 26 + 0
ownheroattac: 2
ownheroweapon: 2 1 jadeclaws CFM_717 0 0
ownherostatus: frozenFalse
enemyherohp: 8 + 0
play id 8 pos 1
play id 13 pos 1
attack with hero, enemy: 99
attacker: 17 enemy: 66
OWN MINIONS################ 3
deckpos, name,ang, hp: 1, seagiant, 9, 8 13
deckpos, name,ang, hp: 2, direwolfalpha, 2, 2 17
deckpos, name,ang, hp: 3, jadegolem, 2, 1 1000
ENEMY MINIONS############ 3
deckpos, name,ang, hp: 1, micromummy, 1, 2 63
deckpos, name,ang, hp: 2, micromummy, 3, 2 46
deckpos, name,ang, hp: 3, murmy, 1, 1 57
DIED MINIONS############
own, entity, cardid: False, 99, ULD_217
Own Handcards:
+++++++ printBoard end +++++++++
青玉之爪2费+海巨人4费,水晶用完,但实际上浪费了1个水晶,可以召唤图腾
所以问题在于,为什么ailoop5的时候,没有继续计算?
进行了一次敌方模拟操作后,发现面板数值如下。第18个面板,不知道为啥变成负数了,反而是第一个面板的数值最好?
itemPlayfield1 chuck deep1==5 boardvalue==39
itemPlayfield2 chuck deep1==5 boardvalue==25
itemPlayfield3 chuck deep1==5 boardvalue==24
itemPlayfield4 chuck deep1==5 boardvalue==32
itemPlayfield5 chuck deep1==5 boardvalue==32
itemPlayfield6 chuck deep1==5 boardvalue==32
itemPlayfield7 chuck deep1==5 boardvalue==32
itemPlayfield8 chuck deep1==5 boardvalue==28
itemPlayfield9 chuck deep1==5 boardvalue==26
itemPlayfield10 chuck deep1==5 boardvalue==17
itemPlayfield11 chuck deep1==5 boardvalue==27
itemPlayfield12 chuck deep1==5 boardvalue==20
itemPlayfield13 chuck deep1==5 boardvalue==19
itemPlayfield14 chuck deep1==5 boardvalue==15
itemPlayfield15 chuck deep1==5 boardvalue==-1
itemPlayfield16 chuck deep1==5 boardvalue==-11
itemPlayfield17 chuck deep1==5 boardvalue==-12
itemPlayfield18 chuck deep1==5 boardvalue==-11
itemPlayfield19 chuck deep1==5 boardvalue==-8
itemPlayfield20 chuck deep1==5 boardvalue==-9
itemPlayfield21 chuck deep1==5 boardvalue==-13
itemPlayfield22 chuck deep1==5 boardvalue==-14
itemPlayfield23 chuck deep1==5 boardvalue==-16
itemPlayfield24 chuck deep1==5 boardvalue==-19
itemPlayfield25 chuck deep1==5 boardvalue==-17
itemPlayfield26 chuck deep1==5 boardvalue==-18
itemPlayfield27 chuck deep1==5 boardvalue==-21
打印上面2个的面板状态进行对比
面板1 分值为39(79降低到39)
+++++++ printBoard start +++++++++
board/hash/turn: 39 / 2110573430307 / 1 ++++++++++++++++++++++
pen 0
mana 0/6
cardsplayed: 2 handsize: 0 enemyhand: 3
ownhero:
ownherohp: 26 + 0
ownheroattac: 2
ownheroweapon: 2 1 jadeclaws CFM_717 0 0
ownherostatus: frozenFalse
enemyherohp: 8 + 0
play id 8 pos 1
play id 13 pos 1
attack with hero, enemy: 99
attacker: 17 enemy: 66
OWN MINIONS################ 3
deckpos, name,ang, hp: 1, seagiant, 9, 8 13
deckpos, name,ang, hp: 2, direwolfalpha, 2, 2 17
deckpos, name,ang, hp: 3, jadegolem, 2, 1 1000
ENEMY MINIONS############ 3
deckpos, name,ang, hp: 1, micromummy, 1, 2 63
deckpos, name,ang, hp: 2, micromummy, 3, 2 46
deckpos, name,ang, hp: 3, murmy, 1, 1 57
DIED MINIONS############
own, entity, cardid: False, 99, ULD_217
Own Handcards:
+++++++ printBoard end +++++++++
面板18 这里的board/hash/turn 变成-11(34降到-11)了,虽然还可以3费海巨人
+++++++ printBoard start +++++++++
board/hash/turn: -11 / 2620263623306 / 1 ++++++++++++++++++++++
pen 0
mana 3/6
cardsplayed: 1 handsize: 1 enemyhand: 3
ownhero:
ownherohp: 28 + 0
ownheroattac: 2
ownheroweapon: 2 1 jadeclaws CFM_717 0 0
ownherostatus: frozenFalse
enemyherohp: 8 + 0
play id 8 pos 1
useability
attack with hero, enemy: 63
attacker: 17 enemy: 66
OWN MINIONS################ 2
deckpos, name,ang, hp: 1, direwolfalpha, 2, 2 17
deckpos, name,ang, hp: 2, jadegolem, 2, 1 1000
ENEMY MINIONS############ 3
deckpos, name,ang, hp: 1, micromummy, 3, 2 99
deckpos, name,ang, hp: 2, micromummy, 3, 2 46
deckpos, name,ang, hp: 3, murmy, 1, 1 57
DIED MINIONS############
own, entity, cardid: False, 63, ULD_217
Own Handcards:
pos 1 seagiant 5 entity 13 EX1_586 0 0 0
+++++++ printBoard end +++++++++
可以调试一下,面板18 的 var boardValue = botBase.getPlayfieldValue(itemPlayfield);
分析了一下,为啥没有进入ailoop6。
进入ailoop的条件是while (havedonesomething)
if (this.posmoves.Count > 0)
{
havedonesomething = true;
}
所以问题是,posmoves里面没下一步,所以直接结束了。
新进入循环是自动清空的,然后
断点发现ailoop4里面的27个操作,没有nextPlayfields
if (this.calculated <= this.totalboards)
{
this.posmoves.AddRange(p.nextPlayfields);
//p.nextPlayfields.Clear();
}
最优面板分值很大,也会退出
if (isLethalCheck && bestoldval >= 10000)
{
this.posmoves.Clear();
}
搜索一下nextPlayfieldsRoutines\DefaultRoutine\SilverFish\ai\MiniSimulator.cs中,哪一块代码在添加
英雄血量肯定大于0的,所以应该是进行敌方操作模拟的时候,面板18的EvaluatePenalty>=500导致没有nextPlayfields
if (pf.ownHero.HealthPoints > 0 && pf.EvaluatePenality < 500) { p.nextPlayfields.Add(pf); }
在敌方模拟中设置断点startEnemyTurnSimThread
if (source.Count == 27 && j == 18)
{
Console.WriteLine();
}
上面的断点设置,根本没触发。可能是生成下一步操作的时候,根本没有action
尝试在生成action之前,拦截
else if (!enoughCalculations) { if (source.Count == 27 && i + 1 == 18) { Helpfunctions.Instance.logg("chuck20190901"); p.printBoard(); }
需要弄明白,为啥这里没有生成actions,
面板状态打印如下。???我擦,发现这个并不是最佳面板,因为攻击敌方随从。导致海巨人回到了4费。
chuck20190901
+++++++ printBoard start +++++++++
board/hash/turn: 34 / 2620263623306 / 0 ++++++++++++++++++++++
pen 0
mana 3/6
cardsplayed: 1 handsize: 1 enemyhand: 3
ownhero:
ownherohp: 28 + 0
ownheroattac: 2
ownheroweapon: 2 1 jadeclaws CFM_717 0 0
ownherostatus: frozenFalse
enemyherohp: 8 + 0
play id 8 pos 1
useability
attack with hero, enemy: 63
attacker: 17 enemy: 66
OWN MINIONS################ 2
deckpos, name,ang, hp: 1, direwolfalpha, 2, 2 17
deckpos, name,ang, hp: 2, jadegolem, 2, 1 1000
ENEMY MINIONS############ 3
deckpos, name,ang, hp: 1, micromummy, 3, 2 99
deckpos, name,ang, hp: 2, micromummy, 3, 2 46
deckpos, name,ang, hp: 3, murmy, 1, 1 57
DIED MINIONS############
own, entity, cardid: False, 63, ULD_217
Own Handcards:
pos 1 seagiant 5 entity 13 EX1_586 0 0 0
+++++++ printBoard end +++++++++
发现是上面走了冤枉路,所以要分析ailoop2里面的4个待考察的,在ailoop3里面的后续操作。