public opposite(CardDB.cardName name, int value, Handcard hc, BoardObj target) { this.name = name; this.value = value; this.hc = hc; this.target = target; }
public Handcard getOppositeCard(Playfield p, BoardObj attacker, int canWaitMissingMana = 3) { Handcard bestCard = null; if (OppositeDB.ContainsKey(attacker.Name)) { Dictionary <CardDB.cardName, int> tmp = OppositeDB[attacker.Name]; int bestCardVal = -1; CardDB.cardName name; foreach (Handcard hc in p.ownHandCards) { name = hc.card.name; if (canWaitMissingMana >= hc.manacost - p.ownMana) { if (tmp.ContainsKey(name)) { if (tmp[name] > bestCardVal) { bestCardVal = tmp[name]; bestCard = hc; bestCard.val = bestCardVal; bestCard.missingMana = hc.manacost - p.ownMana; } if (bestCardVal == 100) { break; } } } } } return(bestCard); }
private void copyCards(List <Handcard> source, Handcard nxtCard) { foreach (Handcard hc in source) { this.ownHandCards.Add(new Handcard(hc)); } this.nextCard = new Handcard(nxtCard); }
private Handcard getHCfromHeader(string[] line) { Handcard hc = new Handcard(line[2], Convert.ToInt32(line[3])); hc.position = Convert.ToInt32(line[1]); hc.manacost = Convert.ToInt32(line[4]); return(hc); }
public VectorAI getBackPosition(Handcard hc, int line = 1) { if (hc.card.Transport == transportType.GROUND) { return(getDeployPosition(line == 1 ? deployDirectionAbsolute.behindKingsTowerLine1 : deployDirectionAbsolute.behindKingsTowerLine2)); } else { return(getDeployPosition(line == 1 ? deployDirectionAbsolute.cornerLine1 : deployDirectionAbsolute.cornerLine2)); } }
private Handcard getHCfromHeader(string[] line) { Handcard hc = new Handcard(line[2], Convert.ToInt32(line[3])); hc.position = Convert.ToInt32(line[1]); hc.manacost = Convert.ToInt32(line[4]); if (line.Length > 5) { hc.mirror = (line[5] == "mirror"); } return(hc); }
public VectorAI getBackPosition(Handcard hc, int line = 1) { if (hc.card.Transport == transportType.GROUND) { if (home) { if ((line == 1)) { return(new VectorAI(10337, 1370, 12)); //1 } else { return(new VectorAI(8290, 1270, 12)); //2 } } else { if ((line == 1)) { return(new VectorAI(10000, 31000, 12)); //1 } else { return(new VectorAI(9000, 31000, 12)); //2 } } } else { if (home) { if ((line == 1)) { return(new VectorAI(17000, 2600, 30)); //1 } else { return(new VectorAI(800, 2100, 12)); //2 } } else { if ((line == 1)) { return(new VectorAI(17450, 30080, 30)); //1 } else { return(new VectorAI(550, 30050, 40)); //2 } } } }
public Handcard getTankCard() { Handcard retval = null; foreach (Handcard hc in ownHandCards) { if (hc.card.type == boardObjType.MOB && (retval == null || hc.card.MaxHP > retval.card.MaxHP)) { retval = hc; } } if (retval != null && retval.card.MaxHP > 800) { return(retval); } return(null); }
public Handcard getPatnerForMobInPeace(BoardObj bo) { if (bo == null) { return(null); } Handcard retval = null; List <Handcard> air = new List <Handcard>(); List <Handcard> troops = new List <Handcard>(); bool needDamager = false; bool needAir = false; if (bo.HP > 600) { needDamager = true; } if (bo.TargetType != targetType.ALL) { needAir = true; } foreach (Handcard hc in ownHandCards) { if (hc.card.type != boardObjType.MOB) { continue; } troops.Add(hc); if (hc.card.Transport == transportType.AIR) { air.Add(hc); } } if (needAir) { retval = getMobCardByCondition(air, needDamager); } if ((needAir && retval == null) || !needAir) { retval = getMobCardByCondition(troops, needDamager); } return(retval); }
/* * private Handcard getFinisher(BoardObj bo, bool canWait) //useful for Towers * { * Handcard retval = null; * Handcard hc; * * Handcard projectile = null; * Handcard aoe = null; * Handcard mob = null; * int count = this.ownHandCards.Count; * for (int i = 1; i < count; i++) * { * hc = ownHandCards[i]; * switch (hc.card.type) * { * case boardObjType.PROJECTILE: * if (bo.HP <= hc.card.Atk) * { * if (projectile == null || hc.card.Atk > projectile.card.Atk) projectile = hc; * } * continue; * case boardObjType.AOE: * int towerDmg = hc.card.towerDamage; * if (hc.card.name == CardDB.cardName.poison) towerDmg *= 8; * if (bo.HP <= towerDmg) * { * if (aoe == null || towerDmg > aoe.extraVal) * { * aoe = hc; * aoe.extraVal = towerDmg; * } * } * continue; * case boardObjType.MOB: * if (bo.type == boardObjType.BUILDING) * { * if (KnowledgeBase.Instance.) * //TODO: calc online * if (hc.card.TargetType == targetType.BUILDINGS) * { * int val; * if (bo.HP <= hc.card.Atk) * { * * } * else * { * int dmg = hc.card.Atk * hc.card.SummonNumber; * int restHp = bo.HP - dmg; * double timeForDestroy = restHp / (dmg * 1000 / hc.card.HitSpeed); * double timeToDestruction = hc.card.MaxHP / (bo.Atk * 1000 / bo.card.HitSpeed); * double delta = timeToDestruction - timeForDestroy; * if (hc.card.SummonNumber > 1) * { * double hitPerMob = Math.Ceiling((double)hc.card.MaxHP / bo.Atk); * timeToDestruction = hc.card.SummonNumber * hitPerMob * 1000 / bo.card.HitSpeed; * * } * if (delta > 0) * { * if (mob == null || hc.card.Atk > mob.card.Atk) * { * mob = hc; * mob.extraVal = delta; * } * } * } * } * * * } * } * if (ownHandCards[i].card.MaxHP > retval.card.MaxHP) retval = ownHandCards[i]; * } * return retval; * }*/ private Handcard getMobCardByCondition(List <Handcard> list, bool needDamager) //!needDamager mean needTank { Handcard retval = null; int mobsCount = list.Count; if (mobsCount > 0) { retval = list[0]; if (needDamager) { for (int i = 1; i < mobsCount; i++) { if (list[i].card.Atk > retval.card.Atk) { if (list[i].card.DamageRadius >= retval.card.DamageRadius) { retval = list[i]; //-TODO: DamageRadius - collect it } } else { if (list[i].card.SpawnNumber > retval.card.SpawnNumber || list[i].card.SummonNumber > retval.card.SummonNumber || list[i].card.DamageRadius > retval.card.DamageRadius) { retval = list[i]; //TODO: check this val for troops like minionhorde } } } } else { for (int i = 1; i < mobsCount; i++) { if (list[i].card.MaxHP > retval.card.MaxHP) { retval = list[i]; } } } } return(retval); }
public Handcard getCheapestCard(boardObjType type, targetType tgtType) { Handcard retval = null; List <Handcard> tmp = new List <Handcard>(); foreach (Handcard hc in ownHandCards) { if ((hc.card.type == type || type == boardObjType.NONE) && (hc.card.TargetType == targetType.NONE || hc.card.TargetType == tgtType)) { tmp.Add(hc); } } foreach (Handcard hc in tmp) { if (retval == null || hc.card.cost < retval.card.cost) { retval = hc; } } return(retval); }
private void LogHandCard(Handcard hc) { Logger.Debug("Hand {position} {name} {lvl} {manacost}{mirror:l}{extraData:l}", hc.position, hc.card.name, hc.lvl, hc.manacost, (hc.mirror ? " mirror" : ""), (hc.extraData == "" ? "" : " ed:" + hc.extraData)); }
public opposite getOppositeToAll(Playfield p, BoardObj defender, int canWaitMissingMana = 3) { opposite bestOpposite = null; List <attackDef> attackersList = defender.getPossibleAttackers(p); if (attackersList.Count < 1) { return(bestOpposite); } List <attackDef> defendersList; CardDB.cardName aName; CardDB.cardName dName; Dictionary <CardDB.cardName, int> aopp; Dictionary <CardDB.cardName, opposite> allOpposite = new Dictionary <CardDB.cardName, opposite>(); foreach (attackDef ad in attackersList) { if (OppositeDB.ContainsKey(ad.attacker.Name)) { aopp = OppositeDB[ad.attacker.Name]; //-1.Get all obj on board defendersList = ad.attacker.getPossibleAttackers(p); foreach (var def in defendersList) { dName = def.attacker.Name; if (aopp.ContainsKey(dName)) { if (!allOpposite.ContainsKey(dName)) { allOpposite.Add(dName, new opposite(dName, aopp[dName], def.attacker, ad.attacker)); } else { allOpposite[dName].value += aopp[dName]; } } } //-2.Get all cards //TODO - enemy have opposite - it depends on his mana if (defender.own) { foreach (Handcard hc in p.ownHandCards) { dName = hc.card.name; if (canWaitMissingMana >= hc.manacost - p.ownMana && aopp.ContainsKey(dName)) { hc.missingMana = hc.manacost - p.ownMana; if (!allOpposite.ContainsKey(dName)) { allOpposite.Add(dName, new opposite(dName, aopp[dName], hc, ad.attacker)); } else { allOpposite[dName].value += aopp[dName]; } } } } } else { Handcard tmp = null; int count = p.ownHandCards.Count; //TODO automatic creation opposite list if (ad.attacker.Transport == transportType.AIR) { foreach (Handcard hc in p.ownHandCards) { if (canWaitMissingMana >= hc.manacost - p.ownMana) { if (hc.card.TargetType == targetType.ALL) { if (ad.attacker.card.DamageRadius > 1000) { if (hc.card.MaxHP > ad.attacker.Atk) { if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP) { tmp = hc; } } } else { if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3) { tmp = hc; break; } } } } } } else { if (ad.attacker.TargetType == targetType.ALL) { foreach (Handcard hc in p.ownHandCards) { if (canWaitMissingMana >= hc.manacost - p.ownMana) { if (ad.attacker.card.DamageRadius > 1000 && hc.card.MaxHP > ad.attacker.Atk) { if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP) { tmp = hc; } } else { if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3) { tmp = hc; break; } } } } } else if (ad.attacker.TargetType == targetType.BUILDINGS) { foreach (Handcard hc in p.ownHandCards) { if (canWaitMissingMana >= hc.manacost - p.ownMana) { if (hc.card.Atk > ad.attacker.HP * 5 || hc.card.SpawnNumber > 3) { tmp = hc; break; } } } } else { foreach (Handcard hc in p.ownHandCards) { if (canWaitMissingMana >= hc.manacost - p.ownMana) { if (hc.card.Transport == transportType.AIR) { if (tmp == null || tmp.card.SpawnNumber < hc.card.SpawnNumber || tmp.card.SummonNumber < hc.card.SummonNumber) { tmp = hc; } } } } if (tmp == null) { foreach (Handcard hc in p.ownHandCards) { if (canWaitMissingMana >= hc.manacost - p.ownMana) { if (ad.attacker.card.DamageRadius > 1000) { if (hc.card.MaxHP > ad.attacker.Atk) { if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP) { tmp = hc; } } } else { if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3) { tmp = hc; break; } } } } } } } if (tmp == null) { foreach (Handcard hc in p.ownHandCards) { if (hc.card.type == boardObjType.PROJECTILE) { if (tmp == null || tmp.card.Atk < hc.card.Atk) { tmp = hc; } } } } if (tmp == null && p.ownMana >= 9) { tmp = p.getCheapestCard(boardObjType.NONE, targetType.NONE); } if (tmp != null && !allOpposite.ContainsKey(tmp.card.name)) { tmp.missingMana = tmp.manacost - p.ownMana; allOpposite.Add(tmp.card.name, new opposite(tmp.card.name, 10, tmp, ad.attacker)); } } } int oppCount = allOpposite.Count; if (oppCount > 0) { foreach (opposite opp in allOpposite.Values) { if (OppositeDB.ContainsKey(opp.name)) { aopp = OppositeDB[opp.name]; foreach (attackDef ad in attackersList) { aName = ad.attacker.Name; if (aopp.ContainsKey(aName)) { opp.value -= aopp[aName]; //TODO: test - repeat for each or break; } } } else { Logger.Debug("!OppositeDB.ContainsKey"); } if (bestOpposite != null) { if (bestOpposite.value < opp.value) { bestOpposite = opp; } } else { bestOpposite = opp; } } if (bestOpposite != null && bestOpposite.target != null && bestOpposite.hc != null && bestOpposite.hc.card != null) { bestOpposite.target.attacker = new BoardObj(bestOpposite.hc.card.name, bestOpposite.hc.lvl); } } return(bestOpposite); }
public sealed override CastRequest GetNextCast() { List <BoardObj> ownMinions = new List <BoardObj>(); List <BoardObj> enemyMinions = new List <BoardObj>(); List <BoardObj> ownAreaEffects = new List <BoardObj>(); List <BoardObj> enemyAreaEffects = new List <BoardObj>(); List <BoardObj> ownBuildings = new List <BoardObj>(); List <BoardObj> enemyBuildings = new List <BoardObj>(); BoardObj ownKingsTower = new BoardObj(); BoardObj ownPrincessTower1 = new BoardObj(); BoardObj ownPrincessTower2 = new BoardObj(); BoardObj enemyKingsTower = new BoardObj(); BoardObj enemyPrincessTower1 = new BoardObj(); BoardObj enemyPrincessTower2 = new BoardObj(); List <Handcard> ownHandCards = new List <Handcard>(); var battle = ClashEngine.Instance.Battle; if (battle == null || !battle.IsValid) { return(null); } var om = ClashEngine.Instance.ObjectManager; if (om == null) { return(null); } var lp = ClashEngine.Instance.LocalPlayer; if (lp == null || !lp.IsValid) { return(null); } var spells = ClashEngine.Instance.AvailableSpells; if (spells == null) { return(null); } StringBuilder sb = new StringBuilder(); using (new PerformanceTimer("GetNextCast entrance")) { foreach (var spell in spells) { if (spell != null && spell.IsValid) { int lvl = 1; Handcard hc = new Handcard(spell.Name.Value, lvl); //hc.lvl = ??? TODO hc.manacost = spell.ManaCost; //hc.position = ??? TODO //TODO:for all objects - if (new name) get actual params ownHandCards.Add(hc); } } var aoes = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.AreaEffectObject>(); foreach (var aoe in aoes) { if (aoe != null && aoe.IsValid) { //TODO: get static data for all objects //Here we get dynamic data only BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(aoe.LogicGameObjectData.Name.Value)); bo.GId = aoe.GlobalId; bo.Position = new VectorAI(aoe.StartPosition); bo.Line = bo.Position.X > 8700 ? 1 : 2; //bo.level = TODO real value //bo.Atk = TODO real value bo.LifeTime = aoe.HealthComponent.RemainingTime; //TODO check this value bo.ownerIndex = (int)aoe.OwnerIndex; bool own = bo.ownerIndex == lp.OwnerIndex ? true : false; //TODO: replace it on Friendly (for 2x2 mode) bo.own = own; if (own) { ownAreaEffects.Add(bo); } else { enemyAreaEffects.Add(bo); } //hc.position = ??? TODO } } var chars = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.Character>(); foreach (var @char in chars) { //sb.Clear(); //i++; //BoardObj bo = new BoardObj(); var data = @char.LogicGameObjectData; if (data != null && data.IsValid) { //TODO: get static data for all objects //Here we get dynamic data only BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(data.Name.Value)); bo.GId = @char.GlobalId; bo.Position = new VectorAI(@char.StartPosition); bo.Line = bo.Position.X > 8700 ? 1 : 2; //bo.level = TODO real value //bo.Atk = TODO real value //this.frozen = TODO //this.startFrozen = TODO bo.HP = @char.HealthComponent.CurrentHealth; //TODO: check it bo.Shield = @char.HealthComponent.CurrentShieldHealth; //TODO: check it bo.LifeTime = @char.HealthComponent.LifeTime - @char.HealthComponent.RemainingTime; //TODO: check it of data.LifeTime, - find real value for battle stage bo.ownerIndex = (int)@char.OwnerIndex; bool own = bo.ownerIndex == lp.OwnerIndex ? true : false; //TODO: replace it on Friendly (for 2x2 mode) int tower = 0; switch (bo.Name) { case CardDB.cardName.princesstower: tower = bo.Line; if (bo.own) { if (tower == 1) { ownPrincessTower1 = bo; } else { ownPrincessTower2 = bo; } } else { if (tower == 1) { enemyPrincessTower1 = bo; } else { enemyPrincessTower2 = bo; } } break; case CardDB.cardName.kingtower: tower = 10 + bo.Line; if (bo.own) { if (lp.OwnerIndex == bo.ownerIndex) { ownKingsTower = bo; } } else { enemyKingsTower = bo; } break; case CardDB.cardName.kingtowermiddle: tower = 100; break; } if (tower == 0) { if (bo.own) { ownBuildings.Add(bo); } else { enemyBuildings.Add(bo); } } bo.own = own; if (own) { switch (bo.type) { case boardObjType.MOB: ownMinions.Add(bo); break; case boardObjType.BUILDING: if (bo.Tower > 0) { if (bo.Tower > 9 && bo.ownerIndex == lp.OwnerIndex) { ownKingsTower = bo; } } else { ownBuildings.Add(bo); } break; } } else { switch (bo.type) { case boardObjType.MOB: enemyMinions.Add(bo); continue; case boardObjType.BUILDING: if (bo.Tower == 0) { if (bo.Tower > 9) { enemyKingsTower = bo; } } else { enemyBuildings.Add(bo); } break; } } } } } Playfield p; using (new PerformanceTimer("Initialize playfield.")) { p = new Playfield { BattleTime = ClashEngine.Instance.Battle.BattleTime, ownerIndex = (int)lp.OwnerIndex, ownMana = (int)lp.Mana, ownHandCards = ownHandCards, ownAreaEffects = ownAreaEffects, ownMinions = ownMinions, ownBuildings = ownBuildings, ownKingsTower = ownKingsTower, ownPrincessTower1 = ownPrincessTower1, ownPrincessTower2 = ownPrincessTower2, enemyAreaEffects = enemyAreaEffects, enemyMinions = enemyMinions, enemyBuildings = enemyBuildings, enemyKingsTower = enemyKingsTower, enemyPrincessTower1 = enemyPrincessTower1, enemyPrincessTower2 = enemyPrincessTower2, //TODO: Add next card //nextCard = }; p.home = p.ownKingsTower.Position.Y < 15250 ? true : false; p.initTowers(); int i = 0; foreach (BoardObj t in p.ownTowers) { if (t.Tower < 10) { i += t.Line; } } int kingsLine = 0; switch (i) { case 0: kingsLine = 3; break; case 1: kingsLine = 2; break; case 2: kingsLine = 1; break; } foreach (BoardObj t in p.ownTowers) { if (t.Tower > 9) { t.Line = kingsLine; } } p.print(); } Cast bc; using (new PerformanceTimer("GetBestCast")) { bc = this.GetBestCast(p); CastRequest retval = null; if (bc != null && bc.Position != null) { Logger.Information("Cast {bc}", bc.ToString()); retval = new CastRequest(bc.SpellName, bc.Position.ToVector2()); } else { Logger.Information("Waiting for cast, maybe next tick..."); } return(retval); } }
private void LogHandCard(Handcard hc) { Logger.Information("Hand {position} {name} {lvl} {manacost}", hc.position, hc.card.name, hc.lvl, hc.manacost); }
public Handcard getOppositeCard(Playfield p, group Group, int canWaitMissingMana = 3, int gangSize = 5) { Handcard bestCard = null; int bestVal = int.MinValue; int tmpVal; foreach (Handcard hc in p.ownHandCards) { if (canWaitMissingMana >= hc.manacost - p.ownMana) { tmpVal = 0; int numAirTransport = Group.lowHPboAirTransport + Group.avgHPboAirTransport + Group.hiHPboAirTransport; int groupSize = Group.lowHPbo.Count + Group.avgHPbo.Count + Group.hiHPbo.Count; if (hc.card.aoeAir) { tmpVal += 3; } if (hc.card.type == boardObjType.MOB) { tmpVal += 2; } if (hc.card.Transport == transportType.AIR) { tmpVal += 3; } if (numAirTransport > 0) { if (hc.card.TargetType == targetType.ALL) { tmpVal += 20; } if (Group.lowHPboAirTransport >= gangSize && hc.card.aoeAir) { tmpVal += 5; } } if (groupSize > numAirTransport) { if (Group.lowHPbo.Count - Group.lowHPboAirTransport >= gangSize) { if (hc.card.aoeAir) { tmpVal += 15; } if (hc.card.aoeGround) { tmpVal += 15; } } if (hc.card.TargetType == targetType.GROUND) { tmpVal += 15; } if (hc.card.TargetType == targetType.ALL) { tmpVal += 15; } } foreach (BoardObj tmp in Group.hiHPbo) { if (OppositeDB.ContainsKey(tmp.card.name)) { var opp = OppositeDB[tmp.card.name]; if (opp.ContainsKey(hc.card.name)) { tmpVal += opp[hc.card.name] / 10; } } } foreach (BoardObj tmp in Group.avgHPbo) { if (OppositeDB.ContainsKey(tmp.card.name)) { var opp = OppositeDB[tmp.card.name]; if (opp.ContainsKey(hc.card.name)) { tmpVal += opp[hc.card.name] / 10; } } } foreach (BoardObj tmp in Group.lowHPbo) { if (OppositeDB.ContainsKey(tmp.card.name)) { var opp = OppositeDB[tmp.card.name]; if (opp.ContainsKey(hc.card.name)) { tmpVal += opp[hc.card.name] / 15; } } } if (bestVal < tmpVal) { bestVal = tmpVal; bestCard = hc; bestCard.val = tmpVal; bestCard.missingMana = hc.manacost - p.ownMana; } } } return(bestCard); }
public sealed override CastRequest GetNextCast() { Logger.Debug(""); if (statNumSuccessfulEntrances > 0) { statTimeOutsideRoutine = DateTime.Now - statTimerRoutine; } statTimerRoutine = DateTime.Now; List <BoardObj> ownMinions = new List <BoardObj>(); List <BoardObj> enemyMinions = new List <BoardObj>(); List <BoardObj> ownAreaEffects = new List <BoardObj>(); List <BoardObj> enemyAreaEffects = new List <BoardObj>(); List <BoardObj> ownBuildings = new List <BoardObj>(); List <BoardObj> enemyBuildings = new List <BoardObj>(); BoardObj ownKingsTower = new BoardObj(); BoardObj ownPrincessTower1 = new BoardObj(); BoardObj ownPrincessTower2 = new BoardObj(); BoardObj enemyKingsTower = new BoardObj(); BoardObj enemyPrincessTower1 = new BoardObj(); BoardObj enemyPrincessTower2 = new BoardObj(); List <Handcard> ownHandCards = new List <Handcard>(); Handcard prevHandCard = new Handcard(); Logger.Debug("#####Stats##### Inint BO {0}", (statTimerRoutine - DateTime.Now).TotalSeconds); var battle = ClashEngine.Instance.Battle; if (battle == null || !battle.IsValid) { return(null); } var om = ClashEngine.Instance.ObjectManager; if (om == null) { return(null); } var lp = ClashEngine.Instance.LocalPlayer; if (lp == null || !lp.IsValid) { return(null); } var spellButtons = ClashEngine.Instance.AvailableSpellButtons; if (spellButtons == null) { return(null); } var spells = ClashEngine.Instance.AvailableSpells; if (spells == null) { return(null); } if (ownKingsTowerPos.Y == -1) { List <Tuple <int, int> > towersIndY = new List <Tuple <int, int> >(); bool needFriendlyIndex = false; var chars = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.Character>(); foreach (var @char in chars) { if ([email protected]) { continue; } var data = @char.LogicGameObjectData; if (data == null || !data.IsValid) { continue; } var name = data.Name; if ((MemPtr)name == MemPtr.Zero) { continue; } switch (CardDB.Instance.cardNamestringToEnum(name.Value.ToString(), "0")) { case CardDB.cardName.kingtower: int OwnerIndex = (int)@char.OwnerIndex; int charY = @char.StartPosition.Y; towersIndY.Add(new Tuple <int, int>(OwnerIndex, charY)); if (OwnerIndex == lp.OwnerIndex) { ownKingsTowerPos.Y = charY; } break; case CardDB.cardName.kingtowermiddle: ownKingsTowerPos.X = @char.StartPosition.X; needFriendlyIndex = true; break; } } if (needFriendlyIndex) { foreach (var t in towersIndY) { if (ownKingsTowerPos.Y == t.Item2 && lp.OwnerIndex != t.Item1) { friendlyOwnerIndex = t.Item1; } } } } Logger.Debug("#####Stats##### Inint BO+engine {0}", (statTimerRoutine - DateTime.Now).TotalSeconds); using (new PerformanceTimer("GetNextCast entrance")) { Handcard Mirror = null; Dictionary <string, int> AvailableSpells = new Dictionary <string, int>(); foreach (var spell in spells) { if (spell == null || !spell.IsValid) { continue; } var name = spell.Name; if ((MemPtr)name == MemPtr.Zero) { continue; } AvailableSpells.Add(name.Value.ToString(), 0); } foreach (var spellBtn in spellButtons) { if (spellBtn == null || !spellBtn.IsValid) { continue; } if (spellBtn.SpellDeckSpell == null || !spellBtn.SpellDeckSpell.IsValid) { continue; } if (spellBtn.SpellDeckSpell.Spell == null || !spellBtn.SpellDeckSpell.Spell.IsValid) { continue; } var name = spellBtn.SpellDeckSpell.Spell.Name; if ((MemPtr)name == MemPtr.Zero) { continue; } if (!AvailableSpells.ContainsKey(name.Value.ToString())) { continue; } int lvl = spellBtn.SpellDeckSpell.LevelIndex; Handcard hc = new Handcard(name.Value.ToString(), lvl); if (hc.card.name == CardDB.cardName.unknown) { CardDB.Instance.collectNewCards(spellBtn); } hc.manacost = spellBtn.SpellDeckSpell.Spell.ManaCost; if (hc.card.name == CardDB.cardName.mirror) { Mirror = hc; } //if (hc.card.needUpdate) CardDB.Instance.cardsAdjustment(spell); ownHandCards.Add(hc); } if (ownHandCards.Count == 4) { if (prevHandCards.Count != 4) { prevHandCards = new List <Handcard>(ownHandCards); } else { for (int i = 0; i < 4; i++) { if (ownHandCards[i].card.name == prevHandCards[i].card.name) { continue; } if (ownHandCards[i].card.name == CardDB.cardName.unknown) { continue; } prevHandCard = prevHandCards[i]; if (Mirror != null) { Mirror.transformTo(prevHandCard); Mirror.mirror = true; } break; } } } var qSpells = ClashEngine.Instance.QueuedSpells; if (qSpells != null) { if (qSpells.Count() == 0) { if (CastRequestDB.Count != 0) { CastRequestDB.Clear(); } } else { if (CastRequest != null && !CastRequestDB.ContainsKey(CastRequest.SpellName)) { CastRequestDB.Add(CastRequest.SpellName, CastRequest); } if (CastRequestDBtmp.Count != 0) { CastRequestDBtmp.Clear(); } foreach (var qs in qSpells) { if (qs == null || !qs.IsValid) { continue; } string name = qs.Name.Value.ToString(); if (!CastRequestDBtmp.ContainsKey(name)) { CastRequestDBtmp.Add(name, 0); } if (CastRequestDB.ContainsKey(name)) { //add to pf //TODO: real lvl BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(name, "21"), 6); bo.Position = new VectorAI(CastRequestDB[name].Position); bo.ownerIndex = (int)lp.OwnerIndex; bo.frozen = true; bo.GId = getNextGId(); switch (bo.type) { case boardObjType.MOB: int nums = bo.card.SummonNumber; if (nums == 0) { nums = 1; } else { if (bo.card.SpawnCharacter != "") { bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(bo.card.SpawnCharacter, "22"), 6); bo.Position = new VectorAI(CastRequestDB[name].Position); bo.ownerIndex = (int)lp.OwnerIndex; bo.frozen = true; bo.GId = getNextGId(); } } for (int i = 0; i < nums; i++) { ownMinions.Add(bo); if (nums > 1) { bo = new BoardObj(bo); bo.GId = getNextGId(); } } break; case boardObjType.BUILDING: ownBuildings.Add(bo); break; case boardObjType.AOE: break; } } } foreach (var kvp in CastRequestDB.ToArray()) { if (!CastRequestDBtmp.ContainsKey(kvp.Key)) { CastRequestDB.Remove(kvp.Key); } } } } //var projs = om.OfType<Clash.Engine.NativeObjects.Logic.GameObjects.Projectile>(); //foreach (var proj in projs) //{ // if (proj != null && proj.IsValid) // { // //TODO: get static data for all objects // //Here we get dynamic data only // CardDB.Instance.collectNewCards(proj); // } //} var aoes = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.AreaEffectObject>(); foreach (var aoe in aoes) { if (!aoe.IsValid) { continue; } var data = aoe.LogicGameObjectData; if (data == null || !data.IsValid) { continue; } var name = data.Name; if ((MemPtr)name == MemPtr.Zero) { continue; } BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(name.Value.ToString(), "1")); //if (bo.card.needUpdate) CardDB.Instance.cardsAdjustment(aoe); if (bo.card.name == CardDB.cardName.unknown) { CardDB.Instance.collectNewCards(aoe); } bo.GId = aoe.GlobalId; bo.Position = new VectorAI(aoe.StartPosition); bo.Line = bo.Position.X > 8700 ? 2 : 1; //bo.level = TODO real value //bo.Atk = TODO real value bo.LifeTime = aoe.HealthComponent.RemainingTime; //bo.extraData = data.Field10.ToString();//!!TEST bo.ownerIndex = (int)aoe.OwnerIndex; bool own = bo.ownerIndex == lp.OwnerIndex ? true : (bo.ownerIndex == friendlyOwnerIndex ? true : false); bo.own = own; if (own) { ownAreaEffects.Add(bo); } else { enemyAreaEffects.Add(bo); } } var chars = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.Character>(); foreach (var @char in chars) { if ([email protected]) { continue; } var data = @char.LogicGameObjectData; if (data == null || !data.IsValid) { continue; } var name = data.Name; if ((MemPtr)name == MemPtr.Zero) { continue; } BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(name.Value.ToString(), "2"), (int)@char.TowerLevel); bo.ownerIndex = (int)@char.OwnerIndex; bool own = bo.ownerIndex == lp.OwnerIndex ? true : (bo.ownerIndex == friendlyOwnerIndex ? true : false); bo.own = own; if (bo.card.name == CardDB.cardName.unknown) { CardDB.Instance.collectNewCards(@char); } else if (bo.ownerIndex == lp.OwnerIndex && bo.card.needUpdate) { CardDB.Instance.cardsAdjustment(@char); } bo.GId = @char.GlobalId; bo.Position = new VectorAI(@char.StartPosition); bo.Line = bo.Position.X > 8700 ? 2 : 1; bo.level = 1 + (int)@char.TowerLevel; //this.frozen = TODO //this.startFrozen = TODO bo.HP = @char.HealthComponent.CurrentHealth; bo.Shield = @char.HealthComponent.CurrentShieldHealth; bo.LifeTime = @char.HealthComponent.LifeTime - @char.HealthComponent.RemainingTime; //TODO: - find real value for battle stage int tower = 0; switch (bo.Name) { case CardDB.cardName.princesstower: CardDB.Instance.setPrincessTowerMaxHP(bo); tower = bo.Line; if (bo.own) { if (tower == 1) { ownPrincessTower1 = bo; } else { ownPrincessTower2 = bo; } } else { if (tower == 1) { enemyPrincessTower1 = bo; } else { enemyPrincessTower2 = bo; } } break; case CardDB.cardName.kingtower: CardDB.Instance.setKingsTowerMaxHP(bo); tower = 10 + bo.Line; if (bo.own) { if (ownKingsTower.HP == 0) { ownKingsTower = bo; } else if (bo.HP < ownKingsTower.HP) { ownKingsTower = bo; } if (ownKingsTowerPos.X != -1) { ownKingsTower.Position.X = ownKingsTowerPos.X; } ownKingsTower.ownerIndex = (int)lp.OwnerIndex; } else { if (enemyKingsTower.HP == 0) { enemyKingsTower = bo; } else if (bo.HP < enemyKingsTower.HP) { enemyKingsTower = bo; } if (ownKingsTowerPos.X != -1) { enemyKingsTower.Position.X = ownKingsTowerPos.X; } } break; case CardDB.cardName.kingtowermiddle: tower = 100; break; default: bo.Atk = (int)(bo.card.Atk * lvlToCoef[bo.level]); //TODO: need value from core if (own) { switch (bo.type) { case boardObjType.MOB: ownMinions.Add(bo); break; case boardObjType.BUILDING: ownBuildings.Add(bo); break; } } else { switch (bo.type) { case boardObjType.MOB: enemyMinions.Add(bo); break; case boardObjType.BUILDING: enemyBuildings.Add(bo); break; } } break; } } } Playfield p; Logger.Debug("#####Stats##### before Initialize playfield {0}", (statTimerRoutine - DateTime.Now).TotalSeconds); using (new PerformanceTimer("Initialize playfield.")) { Logger.Debug("################################Routine v.0.8.6 Behavior:{Name:l} v.{Version:l}", Name, Version); p = new Playfield { BattleTime = battle.BattleTime, suddenDeath = battle.BattleTime.TotalSeconds > 180, ownerIndex = (int)lp.OwnerIndex, ownMana = (int)(lp.Mana - lp.ReservedMana), ownHandCards = ownHandCards, ownAreaEffects = ownAreaEffects, ownMinions = ownMinions, ownBuildings = ownBuildings, ownKingsTower = ownKingsTower, ownPrincessTower1 = ownPrincessTower1, ownPrincessTower2 = ownPrincessTower2, enemyAreaEffects = enemyAreaEffects, enemyMinions = enemyMinions, enemyBuildings = enemyBuildings, enemyKingsTower = enemyKingsTower, enemyPrincessTower1 = enemyPrincessTower1, enemyPrincessTower2 = enemyPrincessTower2, prevCard = prevHandCard, //nextCard = //TODO: Add next card }; p.home = p.ownKingsTower.Position.Y < 15250 ? true : false; if (p.ownPrincessTower1.Position == null) { p.ownPrincessTower1.Position = p.getDeployPosition(deployDirectionAbsolute.ownPrincessTowerLine1); } if (p.ownPrincessTower2.Position == null) { p.ownPrincessTower2.Position = p.getDeployPosition(deployDirectionAbsolute.ownPrincessTowerLine2); } if (p.enemyPrincessTower1.Position == null) { p.enemyPrincessTower1.Position = p.getDeployPosition(deployDirectionAbsolute.enemyPrincessTowerLine1); } if (p.enemyPrincessTower2.Position == null) { p.enemyPrincessTower2.Position = p.getDeployPosition(deployDirectionAbsolute.enemyPrincessTowerLine2); } p.initTowers(); p.print(); battleLogs.Add(p); } Logger.Debug("#####Stats##### after Initialize playfield {0}", (statTimerRoutine - DateTime.Now).TotalSeconds); statTimeInitPlayfield = DateTime.Now - statTimerRoutine; statTimerRoutine = DateTime.Now; Cast bc; using (new PerformanceTimer("GetBestCast")) { //DateTime statBehaviorCalcStart = DateTime.Now; bc = this.GetBestCast(p); CastRequest = null; if (bc != null && bc.Position != null) { if (p.ownMana + 1 >= bc.hc.manacost) { CastRequest = new CastRequest(bc.SpellName, bc.Position.ToVector2f(true)); } Logger.Debug("CastRequest {SpellName:l} {Position:l}", bc.SpellName, CastRequest == null ? bc.Position?.ToString() : CastRequest.Position.ToString()); } else { Logger.Debug("Waiting for cast, maybe next tick..."); } statTimeInsideBehavior = DateTime.Now - statTimerRoutine; //stat info statSumTimeOutsideRoutine += statTimeOutsideRoutine; statSumTimeInitPlayfield += statTimeInitPlayfield; statSumTimeInsideBehavior += statTimeInsideBehavior; statNumSuccessfulEntrances++; int objsCount = ownAreaEffects.Count + enemyAreaEffects.Count + ownMinions.Count + enemyMinions.Count + ownBuildings.Count + enemyBuildings.Count; //without HandCards if (objsCount == 0) { objsCount = 2; } Logger.Debug("Hint: ne:NumberEntrances CT:CalculationTime aCT:AverageCalculationTimePer1Game tpo:TimePer1Object ToR:TimeOutsideRoutine"); Logger.Debug("#####Stats### ne:{NumberEntrances} Behavior(CT/aCT/tpo):{BehaviorCalcTime}/{averageBCT}/{timePer1Object} Playfield(CT/aCT/tpo):{PlayfieldCreationTime}/{averagePCT}/{timePer1Object} outsideRoutine(ToR/aToR/tpo):{timeOutsideRoutine}/{averageToR}/{timePer1Object}", statNumSuccessfulEntrances, statTimeInsideBehavior.TotalSeconds, (statSumTimeInsideBehavior / statNumSuccessfulEntrances).TotalSeconds, (statTimeInsideBehavior / objsCount).TotalSeconds, statTimeInitPlayfield.TotalSeconds, (statSumTimeInitPlayfield / statNumSuccessfulEntrances).TotalSeconds, (statTimeInitPlayfield / objsCount).TotalSeconds, statTimeOutsideRoutine.TotalSeconds, (statSumTimeOutsideRoutine / (statNumSuccessfulEntrances > 1 ? statNumSuccessfulEntrances - 1 : 1)).TotalSeconds, (statTimeOutsideRoutine / objsCount).TotalSeconds); statTimerRoutine = DateTime.Now; return(CastRequest); } }
public Cast(string spellName, VectorAI position, Handcard handCard) { this.SpellName = spellName; this.Position = position; this.hc = handCard; }