期望通过ai的调试,来搞明白出牌的逻辑。

55是投火无面者
63是恐狼前锋
34是风怒
36是自动漩涡打击装置
13是空灵召唤者, "LocStringZhCn": "<b>亡语:</b>\n随机将一张恶魔牌从你的手牌置入战场。",
64是对方英雄,术士

目前的输出结果是:【少了召唤图腾】

value of best board 66
Best actions as following:
Action1:
attacker: 63 enemy: 64
Action2:
play id 34 target 55 pos 1
Action3:
attacker: 55 enemy: 64
Action4:
attacker: 55 enemy: 64

ailoop汇总

在ai loop的时候计算了可能的操作
deep 1 len 8 dones 0
cut to len 8

deep 2 len 41 dones 0
cut to len 29

deep 3 len 90 dones 0
cut to len 49

deep 4 len 85 dones 0
cut to len 40

deep 5 len 31 dones 0
cut to len 13

deep 6 len 0 dones 0
cut to len 0

ailoop1

deep 0 len 8 dones 0
cut to len 8

ai计算了8个单次操作【根据反馈,风怒其实还可以给敌方随从的,这个直接被HearthBuddy排除了】

start print 8 actions startIndex = 0,endIndex = 1
a.print(); start
play id 34 target 55 pos 1 操作1,风怒给无面投火者
a.print(); end

a.print(); start
play id 34 target 63 pos 1 操作2,风怒给恐狼前锋
a.print(); end

a.print(); start
play id 36 pos 3 操作3,使用卡牌,自动漩涡打击装置
a.print(); end

a.print(); start
attacker: 55 enemy: 13 操作4,无面投火者攻击空灵召唤者
a.print(); end

a.print(); start
attacker: 55 enemy: 64 操作5,无面投火者攻击术士
a.print(); end

a.print(); start
attacker: 63 enemy: 13 操作6,恐狼前锋攻击空灵召唤者

a.print(); end
a.print(); start
attacker: 63 enemy: 64 操作7,恐狼前锋攻击术士
a.print(); end

a.print(); start
useability 操作8,使用英雄技能,召唤图腾
a.print(); end

end print 8 actions startIndex = 0,endIndex = 1,

ailoop2 在ailoop1的基础上,计算后续单次操作

start print 5 actions startIndex = 0,endIndex = 8  所以这里会循环8次,这里的8上ailoop1的8个操作

ailoop1里的8个单次操作,每个对应的后续可能单次操作分别为
 5+7+5+5+5+5+5+4 =41

deep 1 len 8 dones 0
cut to len 8

deep 2 len 41 dones 0
cut to len 29

41中操作,经过 cuttingposibilities(isLethalCheck);,剩下29种操作

deep 3 len 90 dones 0
cut to len 49

deep 4 len 85 dones 0
cut to len 40

deep 5 len 31 dones 0
cut to len 13

deep 6 len 0 dones 0
cut to len 0

 

startEnemyTurnSimThread1  对应ailoop1里面的操作1:风怒给无面投火者,剩下1费

a1.print(); start
attacker: 55 enemy: 13   操作1,投火无面者攻击空灵召唤者
a1.print(); end

a2.print(); start
attacker: 55 enemy: 64  操作2,投火无面者攻击术士
a2.print(); end

a3.print(); start
attacker: 63 enemy: 13   操作3,恐狼前锋攻击空灵召唤者
a3.print(); end

a4.print(); start
attacker: 63 enemy: 64  操作4,恐狼前锋攻击术士
a4.print(); end

a5.print(); start
useability              操作5,使用英雄技能
a5.print(); end

end print 5 actions startIndex = 0,endIndex = 8,

这里的操作4,经过cut,会被后面的操作取代。因为属于重复操作。

itemPlayfield9 chuck deep==2
play id 34 target 55 pos 1
attacker: 55 enemy: 64

itemPlayfield12 chuck deep==2
play id 34 target 55 pos 1
useability

itemPlayfield23 chuck deep==2
play id 34 target 55 pos 1
attacker: 63 enemy: 13

itemPlayfield24 chuck deep==2
play id 34 target 55 pos 1
attacker: 55 enemy: 13

itemPlayfield15 chuck deep==2
attacker: 63 enemy: 64        恐狼前锋攻击术士
play id 34 target 55 pos 1     风怒给无面投火者

调试之后的发现

ai本身在第五回合,是计算出最优解的【但是在第六回合,模拟敌方操作后,分数反而输给了一个第四回个的一个】

 itemPlayfield1 chuck deep==5 boardvalue==118
play id 34 target 55 pos 1
useability 
attacker: 55 enemy: 64
attacker: 55 enemy: 64
attacker: 63 enemy: 64 

ai在第六回合,会模拟敌方的操作,对上面第五回合的palyfield做一些操作。然后重新评分。

itemPlayfield1 chuck deep2==5 boardvalue==118
itemPlayfield2 chuck deep2==5 boardvalue==97
itemPlayfield3 chuck deep2==5 boardvalue==88
itemPlayfield4 chuck deep2==5 boardvalue==71
itemPlayfield5 chuck deep2==5 boardvalue==58
itemPlayfield6 chuck deep2==5 boardvalue==53
itemPlayfield7 chuck deep2==5 boardvalue==50
itemPlayfield8 chuck deep2==5 boardvalue==50
itemPlayfield9 chuck deep2==5 boardvalue==46
itemPlayfield10 chuck deep2==5 boardvalue==43
itemPlayfield11 chuck deep2==5 boardvalue==37
itemPlayfield12 chuck deep2==5 boardvalue==29
itemPlayfield13 chuck deep2==5 boardvalue==23

模拟敌方操作之后

itemPlayfield1 chuck deep1==6 boardvalue==63   上面的118评分变成只有63了。
itemPlayfield2 chuck deep1==6 boardvalue==38
itemPlayfield3 chuck deep1==6 boardvalue==32
itemPlayfield4 chuck deep1==6 boardvalue==22
itemPlayfield5 chuck deep1==6 boardvalue==8
itemPlayfield6 chuck deep1==6 boardvalue==-2
itemPlayfield7 chuck deep1==6 boardvalue==1
itemPlayfield8 chuck deep1==6 boardvalue==1
itemPlayfield9 chuck deep1==6 boardvalue==-16
itemPlayfield10 chuck deep1==6 boardvalue==-9
itemPlayfield11 chuck deep1==6 boardvalue==-15
itemPlayfield12 chuck deep1==6 boardvalue==-23
itemPlayfield13 chuck deep1==6 boardvalue==-29

模拟敌方操作后的最优秀的评分记录是,itemPlayfield2 chuck deep1==5 boardvalue==66

对应的模拟敌方操作前的记录是,itemPlayfield2 chuck deep2==4 boardvalue==111

具体操作是

itemPlayfield2 chuck deep2==4 boardvalue==111
attacker: 63 enemy: 64

play id 34 target 55 pos 1

attacker: 55 enemy: 64

attacker: 55 enemy: 64

第六回合对第五回合的结果进行敌方模拟

这里的temp中有13个元素

startEnemyTurnSimThread(temp, 0, temp.Count);

执行以下这段代码

Ai.Instance.enemyTurnSim[threadnumber].simulateEnemysTurn(p, this.simulateSecondTurn, playaround, false, playaroundprob, playaroundprob2);

然后再计算botBase.getPlayfieldValue(p)就发现这个数值,从118变成63了。

Routines\DefaultRoutine\Silverfish\ai\EnemyTurnSimulator.cs

public void simulateEnemysTurn(Playfield rootfield, bool simulateTwoTurns, bool playaround, bool print, int pprob, int pprob2)

打印board

 foreach (var itemPlayfield in temp)
{
chuck2++;
var boardValue = botBase.getPlayfieldValue(itemPlayfield);
Helpfunctions.Instance.logg($"itemPlayfield{chuck2} chuck deep1=={deep} boardvalue=={boardValue}");
if (deep == && chuck2 == )
{
itemPlayfield.printBoard();
} if (deep == && chuck2 == )
{
itemPlayfield.printBoard();
}
}

itemPlayfield1 chuck deep1==6 boardvalue==63

+++++++ printBoard start +++++++++
board/hash/turn: 63 / 5571393420105 / 1 ++++++++++++++++++++++
pen 3
mana 0/5
cardsplayed: 1 handsize: 4 enemyhand: 8
ownhero:
ownherohp: 30 + 0
ownheroattac: 0
ownheroweapon: 0 0 unknown None 0 0
ownherostatus: frozenFalse
enemyherohp: 4 + 0
play id 34 target 55 pos 1
useability
attacker: 55 enemy: 64
attacker: 55 enemy: 64
attacker: 63 enemy: 64
OWN MINIONS################ 2
deckpos, name,ang, hp: 1, flamewreathedfaceless, 8, 7 55
deckpos, name,ang, hp: 2, direwolfalpha, 2, 2 63
ENEMY MINIONS############ 1
deckpos, name,ang, hp: 1, voidcaller, 3, 4 13
Own Handcards:
pos 1 thelichking 8 entity 56 ICC_314 0 0 0
pos 2 jadelightning 4 entity 46 CFM_707 0 0 0
pos 3 whirlingzapomatic 2 entity 36 GVG_037 0 0 0
pos 4 genngreymane 6 entity 45 GIL_692 0 0 0
+++++++ printBoard end +++++++++

itemPlayfield2 chuck deep1==5 boardvalue==66

+++++++ printBoard start +++++++++
board/hash/turn: 66 / 4571393421105 / 1 ++++++++++++++++++++++
pen 0
mana 1/5
cardsplayed: 1 handsize: 4 enemyhand: 8
ownhero:
ownherohp: 30 + 0
ownheroattac: 0
ownheroweapon: 0 0 unknown None 0 0
ownherostatus: frozenFalse
enemyherohp: 4 + 0
attacker: 63 enemy: 64
play id 34 target 55 pos 1
attacker: 55 enemy: 64
attacker: 55 enemy: 64
OWN MINIONS################ 2
deckpos, name,ang, hp: 1, flamewreathedfaceless, 8, 7 55
deckpos, name,ang, hp: 2, direwolfalpha, 2, 2 63
ENEMY MINIONS############ 1
deckpos, name,ang, hp: 1, voidcaller, 3, 4 13
Own Handcards:
pos 1 thelichking 8 entity 56 ICC_314 0 0 0
pos 2 jadelightning 4 entity 46 CFM_707 0 0 0
pos 3 whirlingzapomatic 2 entity 36 GVG_037 0 0 0
pos 4 genngreymane 6 entity 45 GIL_692 0 0 0
+++++++ printBoard end +++++++++

比较之后,发现更好的选择,有3个pen。惩罚值?

Helpfunctions.Instance.logg("pen " + this.evaluatePenality);

设置断点,发现惩罚值设置的地方

// its using the hero power--------------------------------
if (a.actionType == actionEnum.useHeroPower)
{
playHeroPower(a.target, a.penalty, this.isOwnTurn, a.druidchoice);
}

在movegenerate的时候加的惩罚值

if (cardPlayPenalty <= 499)
{
Action a = new Action(actionEnum.playcard, hc, null, bestPlace, targetMinion, cardPlayPenalty,
choice);
ret.Add(a);
}

List<Action> actions = movegen.GetMoveList(p, usePenalityManager, useCutingTargets, true);

cardPlayPenalty = pen.getPlayCardPenality(p.ownHeroAblility.card, targetMinion, p);

// use own ability
if (own)
{
if (p.ownAbilityReady
&& p.mana >= p.ownHeroAblility.card.getManaCost(p, p.ownHeroAblility.manacost)) // if ready and enough manna
{
CardDB.Card c = p.ownHeroAblility.card;
int isChoice = (c.choice) ? : ;
for (int choice = + * isChoice; choice < + * isChoice; choice++)
{
if (isChoice == )
{
c = pen.getChooseCard(p.ownHeroAblility.card, choice); // do all choice
} int cardPlayPenalty = ;
int bestPlace = p.ownMinions.Count + ; //we can not manage it
targetMinions = p.ownHeroAblility.card.getTargetsForHeroPower(p, true);
foreach (Minion targetMinion in targetMinions)
{
if (usePenalityManager)
{
cardPlayPenalty = pen.getPlayCardPenality(p.ownHeroAblility.card, targetMinion, p);
} if (cardPlayPenalty <= )
{
Action a = new Action(actionEnum.useHeroPower, p.ownHeroAblility, null, bestPlace, targetMinion,
cardPlayPenalty, choice);
ret.Add(a);
}
}
}
}
}

retval += getRandomPenaltiy(card, p, target);

HearthBuddy Ai调试实战1-->出牌的时候,少召唤了图腾就结束回合的更多相关文章

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

    问题 游戏面板 8是青玉之爪13是海巨人17是恐狼前锋 64是萨满 66是圣骑士63,99,46,是微型木乃伊[其中99和46都是2血3攻,63是2血1攻]57是鱼人木乃伊 微型木乃伊 "L ...

  2. Unity3D手机斗地主游戏开发实战(03)_地主牌显示和出牌逻辑(不定期更新中~~~)

    Hi,之前有同学说要我把源码发出来,那我就把半成品源码的链接放在每篇文件的最后,有兴趣的话可以查阅参考,有问题可以跟我私信,也可以关注我的个人公众号,互相交流嘛.当然,代码也是在不断的持续改进中~ 上 ...

  3. Unity3D手机斗地主游戏开发实战(04)_出牌判断大小(已完结)

    之前我们实现了叫地主.玩家和电脑自动出牌主要功能,但是还有个问题,出牌的时候,没有有效性检查和比较牌力大小.比如说,出牌3,4,5,目前是可以出牌的,然后下家可以出任何牌如3,6,9. 问题1:出牌检 ...

  4. Unity3D手机斗地主游戏开发实战(04)_出牌判断大小

    之前我们实现了叫地主.玩家和电脑自动出牌主要功能,但是还有个问题,出牌的时候,没有有效性检查和比较牌力大小.比如说,出牌3,4,5,目前是可以出牌的,然后下家可以出任何牌如3,6,9. 问题1:出牌检 ...

  5. K8S(14)监控实战-grafana出图_alert告警

    k8s监控实战-grafana出图_alert告警 目录 k8s监控实战-grafana出图_alert告警 1 使用炫酷的grafana出图 1.1 部署grafana 1.1.1 准备镜像 1.1 ...

  6. [原]调试实战——程序CPU占用率飙升,你知道如何快速定位吗?

    原调试debugwindbghangprocess explorer 前言 如果我们自己的程序的CPU Usage(CPU占用率)飙升,并且居高不下,很有可能陷入了死循环.你知道怎么快速定位并解决吗? ...

  7. CAD调试时抛出“正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码”异常的解决方法

    这些天重装了电脑Win10系统,安装了CAD2012和VS2012,准备进行软件开发.在调试程序的时候,CAD没有进入界面就抛出 “正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain ...

  8. 阿里AI设计师一秒出图,小撒连连惊呼,真相是...

    近期,央视<机智过人>的舞台上来了位“三超设计师”——设计能力超强:出图能力超快:抗压能力超强,成功迷惑嘉宾和现场观众,更让撒贝宁出错三连. 节目一开场,这位“设计师”就为现场嘉宾:主持人 ...

  9. 知物由学 | AI网络安全实战:生成对抗网络

    本文由  网易云发布. “知物由学”是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道.“知物由学” ...

随机推荐

  1. stm32 独立看门狗 IWDG

    独立看门狗IWDG 独立看门狗简单理解就是一个12位递减计数器,当计数器从某一个值递减到0时,系统就会产生一次复位 独立看门狗由专用低速时钟LSI驱动,其频率一般在30-60KHz之间,通常选择40K ...

  2. pkg-config命令

    返回已安装库文件的元信息 pkg-config读取.pc文件获取信息 基本思想 编译的时候-I指定头文件路径:-L指定库文件路径.这样做总感觉很麻烦 事先把库的位置信息等保存起来,需要的时候再通过特定 ...

  3. Scrapy 中常用的中间件和管道组件

    Pipeline用法 储存到MongoDB pipline.py中的代码 import pymongo class MongoPipeline(object): def __init__(self, ...

  4. Django:总结setting中的配置

    一.Django setting配置说明 二.setting配置一览 一.Django setting配置说明 1.基础 DJANGO_SETTING_MODULE环境变量:让settings模块被包 ...

  5. 12.自定义v-过渡动画前缀

    代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

  6. Data truncation: Incorrect datetime value: 'May 15, 2019 4:15:37 PM

    因为系统在windows下测试过是正常的 windows下的jdk+ windows下安装的mysql 全部cases通过 linux下的jdk + windows下安装的mysql 新增和更新,影响 ...

  7. 51Nod - 1714 B君的游戏

    每个数的SG值之和他有多少个1相关 打表复杂度:找K个有序的<n的非负数的复杂度为nk/(k!) 则这题的SG打表复杂度为648/7! 为1e10左右 void dfs(int cur, int ...

  8. 阿里云服务器搭建gitlab

    参考这位大神的博客 https://blog.csdn.net/zhaoyanjun6/article/details/79144175 安装邮件通知服务系统时,报了如下错误:send-mail: f ...

  9. spring replaced method 注入

           replaced method注入是spring动态改变bean里方法的实现.需要改变的方法,使用spring内原有其他类(需要继承接口org.springframework.beans ...

  10. 用python计算最高投标限价

    题目是文绉绉的说法,背景来于群里提问,是一份文件里面关于最高投标限价的确定. 最高投标限价下浮率在开标前在开标现场采取逐标段摇珠方式确定,摇珠操作办法如下:在下浮率摇珠范围内,以0.1%为以一档次增序 ...