https://hsreplay.net/replay/mtfuHbJevGSTnGcvcthZem
Maelstrom Portal
大漩涡传送门
Deal 1 damage to all enemy minions. Summon a random 1-Cost minion.
对所有敌方随从造成1点伤害。随机召唤一个法力值消耗为1点的随从。
#######################################################################
start calculations, current time: 22:09:06 V117.178 控场模式 10000 face 15 berserk:1 womob:3 ets 40 secret iC 1 aA 0
#######################################################################
turn 15/1
mana 6/8
emana 8
own secretsCount: 0
enemy secretsCount: 0
player:
0 1 0 0 2
ownhero:
unknown 24 30 0 False False 66 False 0 False 0 0 False
weapon: 0 0 unknown None 0 0
ability: True CS2_049_H3
osecrets:
cthunbonus: 0 0 0
jadegolems: 0 0
elementals: 0 0 0
quests: None 0 1000 None 0 1000
advanced: 0 0
enemyhero:
mage 12 30 0 False False 64 False
weapon: 0 0 unknown None 0 0
ability: True CS2_034
fatigue: 19 0 18 0
OwnMinions:
EnemyMinions:
unknown DRG_107 zp:1 e:90 A:1 H:1 mH:1 rdy:False ptt
wisp CS2_231 zp:2 e:8 A:1 H:1 mH:1 rdy:False ptt
鱼人木乃伊 ULD_723 zp:3 e:27 A:1 H:1 mH:1 rdy:False ptt
Own Handcards:
pos 1 maelstromportal 2 entity 36 KAR_073 0 0 0
pos 2 maelstromportal 2 entity 62 KAR_073 0 0 0
Enemy cards: 3
ownDiedMinions:
enemyDiedMinions:
otg: CFM_696,44;
etg:
og: GIL_530,2;GIL_586,1;GIL_692,1;EX1_244,1;OG_254,1;CFM_696,1;ULD_413,1;ULD_276,1;
eg: EX1_287,1;ULD_726,1;FP1_018,1;ULD_239,1;ULD_240,1;GAME_005,1;
od:
entity 36和62都是大漩涡传送门
ailoop1
有2个面板
面板1
使用英雄技能
面本2
使用大漩涡传送门
deep 0 len 2 dones 0
cut to len 2
itemPlayfield1 with 1 actions
Action1
useability
itemPlayfield2 with 1 actions
Action1
play id 36 pos 1
ailoop2
有2个面板
面板1
1.使用英雄技能
2.使用大漩涡传送门
面板2
1.使用大漩涡传送门36
2.使用大漩涡传送门62
deep 1 len 3 dones 0
cut to len 2
itemPlayfield1 with 2 actions
Action1
useability
Action2
play id 36 pos 1
itemPlayfield2 with 2 actions
Action1
play id 36 pos 1
Action2
play id 62 pos 1
ailoop3
只有一个面板
1.使用大漩涡传送门36
2.使用大漩涡传送门62
3.使用英雄技能
deep 2 len 2 dones 0
cut to len 1
itemPlayfield1 with 3 actions
Action1
play id 36 pos 1
Action2
play id 62 pos 1
Action3
useability
ailoop4
没有可用的面板,导致空过
deep 3 len 0 dones 0
cut to len 0
action的惩罚值来源
BeeSilverFish\SilverFish\Routines\DefaultRoutine\Silverfish\ai\Movegenerator.cs
foreach (Minion trgt in trgts)
{
if (usePenalityManager) cardplayPenality = pen.getPlayCardPenality(c, trgt, p);
if (cardplayPenality <= 499)
{
Action a = new Action(actionEnum.playcard, hc, null, bestplace, trgt, cardplayPenality, choice);
ret.Add(a);
}
}
public List<Action> getMoveList(Playfield p, bool usePenalityManager, bool useCutingTargets, bool own)
{
//generates only own moves
List<Action> ret = new List<Action>();
List<Minion> trgts = new List<Minion>();
if (p.complete || p.ownHero.Hp <= 0)
{
return ret;
}
//play cards:
if (own)
{
List<string> playedcards = new List<string>();
System.Text.StringBuilder cardNcost = new System.Text.StringBuilder();
foreach (Handmanager.Handcard hc in p.owncards)
{
int cardCost = hc.card.getManaCost(p, hc.manacost);
if ((p.nextSpellThisTurnCostHealth && hc.card.type == CardDB.cardtype.SPELL) || (p.nextMurlocThisTurnCostHealth && (TAG_RACE)hc.card.race == TAG_RACE.MURLOC))
{
if (p.ownHero.Hp > cardCost || p.ownHero.immune) { }
else continue; // if not enough Hp
}
else if (p.mana < cardCost) continue; // if not enough manna
CardDB.Card c = hc.card;
cardNcost.Clear();
cardNcost.Append(c.name).Append(hc.manacost);
if (playedcards.Contains(cardNcost.ToString())) continue; // dont play the same card in one loop
playedcards.Add(cardNcost.ToString());
int isChoice = (c.choice) ? 1 : 0;
bool choiceDamageFound = false;
for (int choice = 0 + 1 * isChoice; choice < 1 + 2 * isChoice; choice++)
{
if (isChoice == 1)
{
c = pen.getChooseCard(hc.card, choice); // do all choice
if (p.ownFandralStaghelm > 0)
{
if (choiceDamageFound) break;
for (int i = 1; i < 3; i++)
{
CardDB.Card cTmp = pen.getChooseCard(hc.card, i); // do all choice
if (pen.DamageTargetDatabase.ContainsKey(cTmp.name) || (p.anzOwnAuchenaiSoulpriest > 0 && pen.HealTargetDatabase.ContainsKey(cTmp.name)))
{
choice = i;
choiceDamageFound = true;
c = cTmp;
break;
}
//- Draw a card must be at end in the Sim_xxx - then it will selected!
}
}
}
if (p.ownMinions.Count > 6 && (c.type == CardDB.cardtype.MOB || hc.card.type == CardDB.cardtype.MOB)) continue;
trgts = c.getTargetsForCard(p, p.isLethalCheck, true);
if (trgts.Count == 0) continue;
int cardplayPenality = 0;
int bestplace = p.getBestPlace(c.type == CardDB.cardtype.MOB ? c : hc.card, p.isLethalCheck);
foreach (Minion trgt in trgts)
{
if (usePenalityManager) cardplayPenality = pen.getPlayCardPenality(c, trgt, p);
if (cardplayPenality <= 499)
{
Action a = new Action(actionEnum.playcard, hc, null, bestplace, trgt, cardplayPenality, choice);
ret.Add(a);
}
}
}
}
}
BeeSilverFish\SilverFish\Routines\DefaultRoutine\Silverfish\ai\PenalityManager.cs
public int getPlayCardPenality(CardDB.Card card, Minion target, Playfield p)
{
int retval = ai.botBase.getPlayCardPenality(card, target, p);
if (retval < 0 || retval > 499) return retval;
CardDB.cardName name = card.name;
//there is no reason to buff HP of minon (because it is not healed)
int abuff = getAttackBuffPenality(card, target, p);
int tbuff = getTauntBuffPenality(card, target, p);
if (name == CardDB.cardName.markofthewild && ((abuff >= 500 && tbuff == 0) || (abuff == 0 && tbuff >= 500)))
{
retval = 0;
}
else
{
retval += abuff + tbuff;
}
retval += getHPBuffPenality(card, target, p);
retval += getSilencePenality(name, target, p);
retval += getDamagePenality(card, target, p);
retval += getHealPenality(name, target, p);
retval += getCardDrawPenality(card, target, p);
retval += getCardDrawofEffectMinions(card, p);
retval += getCardDiscardPenality(name, p);
retval += getDestroyOwnPenality(name, target, p);
retval += getDestroyPenality(name, target, p);
retval += getSpecialCardComboPenalitys(card, target, p);
retval += getRandomPenaltiy(card, p, target);
retval += getBuffHandPenalityPlay(name, p);
if (!p.isLethalCheck)
{
retval += cb.getPenalityForDestroyingCombo(card, p);
retval += cb.getPlayValue(card.cardIDenum);
}
retval += playSecretPenality(card, p);
retval += getPlayCardSecretPenality(card, p);
return retval;
}
最后发现是因为大漩涡传送门,在经过以下函数的时候,返回了惩罚值60。
BeeSilverFish\SilverFish\Routines\DefaultRoutine\Silverfish\ai\PenalityManager.cs
private int getDamagePenality(CardDB.Card card, Minion target, Playfield p)
getDamagePenality里面的计算逻辑过于复杂,没时间排查。
简单粗暴地解决方案是,在这个函数开头,判断卡牌是大漩涡传送门,直接返回0。虽然可能会导致其他问题
if (name == CardDB.cardName.maelstromportal) return 0;
来源:oschina
链接:https://my.oschina.net/u/4264644/blog/3307352