HearthBuddy Ai 调试实战2 在使用海巨人的时候,少召唤了一个图腾(费用是对的)

问题

游戏面板

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里面的后续操作。

 

posted @ 2019-08-31 21:06  ChuckLu  阅读(456)  评论(0编辑  收藏  举报