private static VectorAI DPTL2(Playfield p, Handcard hc) { BoardObj rPT = p.ownPrincessTower2; if (rPT == null && rPT.Position == null) { return(DKT(p, hc, 2)); } if (hc.card.type == boardObjType.MOB) { return(PrincessTowerCharacterDeploymentCorrection(rPT.Position, p, hc)); } else if (hc.card.type == boardObjType.BUILDING) { //switch ((cardToDeploy as CardBuilding).Type) //{ // case BuildingType.BuildingDefense: // case BuildingType.BuildingSpawning: return(GetPositionOfTheBestBuildingDeploy(p, hc, FightState.DPTL2)); //} } else if (hc.card.type == boardObjType.AOE || hc.card.type == boardObjType.PROJECTILE) { return(GetPositionOfTheBestDamagingSpellDeploy(p)); } return(rPT.Position); }
private static int GetDangerLvlBuilding(Playfield p, int line) { List <BoardObj> enemyBuildings = p.enemyBuildings; if (enemyBuildings?.Count() > 0) { BoardObj bKT = enemyBuildings.FirstOrDefault(n => n.Line == line && n.IsPositionInArea(p, p.ownKingsTower.Position)); BoardObj bPT; if (line == 1) { bPT = enemyBuildings.FirstOrDefault(n => n.IsPositionInArea(p, p.ownPrincessTower1.Position)); } else { bPT = enemyBuildings.FirstOrDefault(n => n.IsPositionInArea(p, p.ownPrincessTower2.Position)); } if (bKT != null || bPT != null) { return(3); } } return(0); }
public override Cast GetBestCast(Playfield p) { //DebugThings(p); Cast bc = null; Logger.Debug("Home = {Home}", p.home); #region Apollo Magic // Highest priority -> Can we kill the enemy with a spell BoardObj finisherTower = Decision.IsEnemyKillWithSpellPossible(p, out Handcard hc); if (finisherTower != null && (hc?.manacost > p.ownMana)) { return(new Cast(hc.name, finisherTower.Position, hc)); } // ------------------------------------------------------ PlayfieldAnalyse.AnalyseLines(p); // Danger- and Chancelevel currentSituation = GetCurrentFightState(p); // Attack, Defense or UnderAttack (and where it is) hc = CardChoosing.GetOppositeCard(p, currentSituation) ?? CardChoosing.GetMobInPeace(p, currentSituation); //hc = CardChoosing.GetMobInPeace(p, currentSituation); if (hc == null) { Logger.Debug("Part: SpellApolloWay"); Handcard hcApollo = SpellMagic(p, currentSituation, out VectorAI choosedPosition); if (hcApollo != null) { hc = hcApollo; if (choosedPosition != null && !(hc?.manacost > p.ownMana)) { return(new Cast(hcApollo.name, choosedPosition, hcApollo)); } } } if (hc == null) { return(null); } Logger.Debug("Part: GetSpellPosition"); VectorAI nextPosition = SpecialPositionHandling.GetPosition(p, hc); if (nextPosition == null) { nextPosition = PositionChoosing.GetNextSpellPosition(currentSituation, hc, p); } bc = new Cast(hc.name, nextPosition, hc); #endregion Logger.Debug("BestCast:" + bc.SpellName + " " + bc.Position.ToString()); if (bc?.hc?.manacost > p.ownMana) { return(null); } return(bc); }
private static VectorAI DPTL1(Playfield p, Handcard hc) { BoardObj lPT = p.ownPrincessTower1; if (lPT?.Position == null) { return(DKT(p, hc, 1)); } switch (hc.card.type) { case boardObjType.MOB: return(PrincessTowerCharacterDeploymentCorrection(lPT.Position, p, hc)); case boardObjType.BUILDING: //switch ((cardToDeploy as CardBuilding).Type) //{ // case BuildingType.BuildingDefense: // case BuildingType.BuildingSpawning: return(GetPositionOfTheBestBuildingDeploy(p, hc, FightState.DPTL1)); //} case boardObjType.AOE: case boardObjType.PROJECTILE: return(GetPositionOfTheBestDamagingSpellDeploy(p)); } return(lPT.Position); }
public static VectorAI GetPositionOfTheBestDamagingSpellDeploy(Playfield p) { // Prio1: Hit Enemy King Tower if health is low // Prio2: Every damaging spell if there is a big group of enemies if (p.enemyKingsTower.HP < Apollo.Settings.KingTowerSpellDamagingHealth) { return(p.enemyKingsTower.Position); } else { int count; BoardObj enemy = EnemyCharacterWithTheMostEnemiesAround(p, out count); if (enemy != null) { if (HowManyCharactersAroundCharacter(p, enemy) >= Apollo.Settings.SpellCorrectionConditionCharCount) { return(enemy.Position); } else { enemy.Position.AddYInDirection(p, 3000); // Position Correction return(enemy.Position); } } } return(new VectorAI(0, 0)); }
public static FightState GameBeginningDecision(Playfield p, out bool gameBeginning) { bool StartFirstAttack = true; gameBeginning = true; StartFirstAttack = (p.ownMana < Setting.ManaTillFirstAttack); if (StartFirstAttack) { if (!p.noEnemiesOnMySide()) { gameBeginning = false; } return(FightState.START); } else { gameBeginning = false; BoardObj obj = Helper.GetNearestEnemy(p); if (obj?.Line == 2) { return(FightState.DPTL2); } else { return(FightState.DPTL1); } } }
public static FightState EnemyIsOnOurSideDecision(Playfield p) { Logger.Debug("Enemy is on our Side!!"); if (p.ownTowers.Count > 2) { BoardObj obj = Helper.GetNearestEnemy(p); if (obj != null && obj.Line == 2) { return(FightState.UAPTL2); } else { return(FightState.UAPTL1); } } else { BoardObj obj = Helper.GetNearestEnemy(p); if (obj != null && obj.Line == 2) { return(FightState.UAKTL2); } else { return(FightState.UAKTL1); } } }
public static BoardObj EnemyCharacterWithTheMostEnemiesAround(Playfield p, out int count) { const int boarderX = 1000; const int boarderY = 1000; IEnumerable <BoardObj> enemies = p.enemyMinions; BoardObj enemy = null; count = 0; foreach (var item in enemies) { var enemiesAroundTemp = enemies.Where(n => n.Position.X > item.Position.X - boarderX && n.Position.X <item.Position.X + boarderX && n.Position.Y> item.Position.Y - boarderY && n.Position.Y < item.Position.Y + boarderY); BoardObj[] aroundTemp = enemiesAroundTemp as BoardObj[] ?? enemiesAroundTemp.ToArray(); if (aroundTemp.Length <= count) { continue; } count = aroundTemp.Length; enemy = item; } return(enemy); }
private static FightState GameBeginningDecision(Playfield p) { if (p.ownMana < Apollo.Settings.ManaTillFirstAttack) { if (!p.noEnemiesOnMySide()) { Apollo.GameBeginning = false; } return(FightState.START); } else { Apollo.GameBeginning = false; BoardObj obj = GetNearestEnemy(p); if (obj.Line == 2) { return(FightState.DRPT); } else { return(FightState.DLPT); } } }
public static FightState AttackDecision(Playfield p) { if (p.enemyTowers.Count < 3) { if (p.enemyPrincessTower1.HP > 0 && p.enemyPrincessTower1.HP < p.enemyKingsTower.HP / 2) { return(FightState.APTL1); } else if (p.enemyPrincessTower2.HP > 0 && p.enemyPrincessTower2.HP < p.enemyKingsTower.HP / 2) { return(FightState.APTL2); } return(FightState.AKT); } BoardObj princessTower = p.enemyPrincessTowers.OrderBy(n => n.HP).FirstOrDefault(); if (princessTower != null && princessTower.Line == 2) { return(FightState.APTL2); } else { return(FightState.APTL1); } }
public static VectorAI GetPositionOfTheBestDamagingSpellDeploy(Playfield p) { // Prio1: Hit Enemy King Tower if health is low // Prio2: Every damaging spell if there is a big group of enemies Logger.Debug("GetPositionOfTheBestDamaingSpellDeploy"); if (p.enemyKingsTower?.HP < Setting.KingTowerSpellDamagingHealth || (p.enemyMinions.Count + p.enemyBuildings.Count) < 1) { return(p.enemyKingsTower?.Position); } BoardObj enemy = Helper.EnemyCharacterWithTheMostEnemiesAround(p, out int count, transportType.NONE); if (enemy?.Position != null) { // Debugging: try - catch is just for debugging try { // ToDo: Use a mix of the HP and count of the Enemy Units // How fast are the enemy units, needed for a better correction if (Helper.HowManyNFCharactersAroundCharacter(p, enemy) >= Setting.SpellCorrectionConditionCharCount) { Logger.Debug("With correction; enemy.Name = {Name}", enemy.Name); if (enemy.Position != null) { Logger.Debug("enemy.Position = {position}", enemy.Position); return(p.getDeployPosition(enemy.Position, deployDirectionRelative.Down, 500)); } } else { Logger.Debug("No correction; enemy.Name = {Name}", enemy.Name); if (enemy.Position != null) { Logger.Debug("enemy.Position = {position}", enemy.Position); return(enemy.Position); } } } catch (Exception) { //enemy.Position.AddYInDirection(p, 3000); // Position Correction VectorAI result = p.getDeployPosition(enemy.Position, deployDirectionRelative.Down, 500); Logger.Debug("enemy.Name = {Name}", enemy.Name); if (enemy.Position != null) { Logger.Debug("enemy.Position = {position}", enemy.Position); } Logger.Debug("result = {position}", result); return(result); } } Logger.Debug("enemy = null?{enemy} ; enemy.position = null?{position}", enemy == null, enemy.Position == null); Logger.Debug("Error: 0/0"); return(new VectorAI(0, 0)); }
public static Handcard GetMobInPeace(Playfield p, FightState currentSituation) { if (PlayfieldAnalyse.lines[0].Danger <= Level.LOW || PlayfieldAnalyse.lines[1].Danger <= Level.LOW) { var tanks = p.ownMinions.Where(n => Classification.IsMobsTankCurrentHP(n)) .OrderBy(n => n.HP).ToArray(); switch (currentSituation) { case FightState.DPTL1: case FightState.APTL1: BoardObj tankL1 = tanks.Where(n => n.Line == 1).OrderBy(n => n.HP).FirstOrDefault(); if (tankL1 != null) { return(p.getPatnerForMobInPeace(tankL1)); } else { return(p.getPatnerForMobInPeace(p.ownMinions.Where(n => n.Line == 1).OrderBy(n => n.Atk).FirstOrDefault())); } case FightState.DPTL2: case FightState.APTL2: BoardObj tankL2 = tanks.Where(n => n.Line == 2).OrderBy(n => n.HP).FirstOrDefault(); if (tankL2 != null) { return(p.getPatnerForMobInPeace(tankL2)); } else { return(p.getPatnerForMobInPeace(p.ownMinions.Where(n => n.Line == 2).OrderBy(n => n.Atk).FirstOrDefault())); } case FightState.DKT: case FightState.AKT: if (tanks.FirstOrDefault() != null) { return(p.getPatnerForMobInPeace(tanks.FirstOrDefault())); } else { return(p.getPatnerForMobInPeace(p.ownMinions.OrderBy(n => n.Atk).FirstOrDefault())); } case FightState.UAPTL1: case FightState.UAPTL2: case FightState.UAKTL1: case FightState.UAKTL2: case FightState.START: case FightState.WAIT: default: break; } } return(null); }
public static bool IsPositionInArea(this BoardObj bo, Playfield p, VectorAI position) { bool isInArea = position.X >= bo.Position.X - bo.Range && position.X <= bo.Position.X + bo.Range && position.Y >= bo.Position.Y - bo.Range && position.Y <= bo.Position.Y + bo.Range; return(isInArea); }
public static bool IsPositionInArea(this BoardObj bo, Playfield p, VectorAI position) { int buildingSizeAddition = 1000; long a = ((bo.Position.X + buildingSizeAddition - position.X) * (bo.Position.X + buildingSizeAddition - position.X)); long b = ((bo.Position.Y + buildingSizeAddition - position.Y) * (bo.Position.Y + buildingSizeAddition - position.Y)); long c = (bo.Range * bo.Range); return((a + b) < c); }
public static int?HowManyCharactersAroundCharacter(Playfield p, BoardObj obj) { int boarderX = 1000; int boarderY = 1000; IEnumerable <BoardObj> playerCharacter = p.ownMinions; var characterAround = playerCharacter.Count(n => n.Position.X > obj.Position.X - boarderX && n.Position.X <obj.Position.X + boarderX && n.Position.Y> obj.Position.Y - boarderY && n.Position.Y < obj.Position.Y + boarderY); return(characterAround); }
private static VectorAI DRPT(Playfield p, Handcard hc) { BoardObj rPT = p.ownTowers.FirstOrDefault(n => n.Line == 2); if (rPT == null) { return(DKT(p, hc)); } VectorAI rPTP = rPT.Position; VectorAI correctedPosition = PrincessTowerCharacterDeploymentCorrection(rPTP, p, hc); return(correctedPosition); }
private static VectorAI DLPT(Playfield p, Handcard hc) { BoardObj lPT = p.ownTowers.FirstOrDefault(n => n.Line == 1); if (lPT == null) { return(DKT(p, hc)); } //Logger.Debug("DLPT: LeftPrincessTower = " + lPT.ToString()); VectorAI lPTP = lPT.Position; VectorAI correctedPosition = PrincessTowerCharacterDeploymentCorrection(lPTP, p, hc); return(correctedPosition); }
private static FightState DefenseDecision(Playfield p) { if (p.ownTowers.Count < 3) { return(FightState.DKT); } BoardObj princessTower = p.enemyTowers.OrderBy(n => n.HP).FirstOrDefault(); if (princessTower.Line == 2) { return(FightState.DRPT); } else { return(FightState.DLPT); } }
private static FightState EnemyHasCharsOnTheFieldDecision(Playfield p) { if (p.enemyTowers.Count > 2) { BoardObj obj = GetNearestEnemy(p); if (obj.Line == 2) { return(FightState.DRPT); } else { return(FightState.DLPT); } } else { return(FightState.DKT); } }
private static FightState EnemyIsOnOurSideDecision(Playfield p) { if (p.ownTowers.Count > 2) // Question: If in ownTowers the KT is not included change to > 1 { BoardObj obj = GetNearestEnemy(p); if (obj.Line == 2) { return(FightState.UARPT); } else { return(FightState.UALPT); } } else { return(FightState.UAKT); } }
public static FightState DefenseDecision(Playfield p) { // There a no dangerous or own important minions on the playfield // This is why we are deciding independent of the minions on the field if (p.ownTowers.Count < 3) { return(FightState.DKT); } BoardObj princessTower = p.enemyPrincessTowers.OrderBy(n => n.HP).FirstOrDefault(); // Because they are going to attack this tower if (princessTower != null && princessTower.Line == 2) { return(FightState.DPTL2); } else { return(FightState.DPTL1); } }
public static BoardObj GetBestDefender(Playfield p) { // TODO: Find better condition BoardObj enemy = Helper.EnemyCharacterWithTheMostEnemiesAround(p, out int count, transportType.NONE); if (enemy == null) { return(p.ownKingsTower); } switch (enemy.Line) { case 2: return(p.ownPrincessTower2); case 1: return(p.ownPrincessTower1); default: return(p.ownKingsTower); } }
public static BoardObj EnemyCharacterWithTheMostEnemiesAround(Playfield p, out int count, transportType tP) { int boarderX = 1000; int boarderY = 1000; IEnumerable <BoardObj> enemies = p.enemyMinions; BoardObj enemy = null; count = 0; foreach (var item in enemies) { BoardObj[] enemiesAroundTemp; if (tP != transportType.NONE) { enemiesAroundTemp = enemies.Where(n => n.Position.X > item.Position.X - boarderX && n.Position.X <item.Position.X + boarderX && n.Position.Y> item.Position.Y - boarderY && n.Position.Y < item.Position.Y + boarderY && n.Transport == tP).ToArray(); } else { enemiesAroundTemp = enemies.Where(n => n.Position.X > item.Position.X - boarderX && n.Position.X <item.Position.X + boarderX && n.Position.Y> item.Position.Y - boarderY && n.Position.Y < item.Position.Y + boarderY).ToArray(); } if (!(enemiesAroundTemp?.Count() > count)) { continue; } count = enemiesAroundTemp.Count(); enemy = item; } return(enemy); }
public override Cast GetBestCast(Playfield p) { Cast bc = null; group ownGroup = p.getGroup(true, 85, boPriority.byTotalNumber, 3000); if (ownGroup != null) { /*if (ownGroup.Position.) * { * * } * else*/ { int airAreaDPSBonus = 1000 - (ownGroup.hiHPboAirAreaDPS + ownGroup.avgHPboAirAreaDPS + ownGroup.lowHPboAirAreaDPS); if (airAreaDPSBonus < 0) { airAreaDPSBonus = 0; } int groundAreaDPSBonus = 800 - (ownGroup.hiHPboGroundAreaDPS + ownGroup.avgHPboAirAreaDPS + ownGroup.lowHPboGroundAreaDPS); if (groundAreaDPSBonus < 0) { groundAreaDPSBonus = 0; } int airDPSBonus = 500 - (ownGroup.hiHPboAirDPS + ownGroup.avgHPboAirDPS + ownGroup.lowHPboAirDPS); if (airDPSBonus < 0) { airDPSBonus = 0; } int flyBonus = 800 - (ownGroup.lowHPboAirTransport + ownGroup.avgHPboAirTransport + ownGroup.hiHPboAirTransport); if (flyBonus < 0) { flyBonus = 0; } int tankBonus = 1600 - ownGroup.hiHPboHP; if (tankBonus < 0) { tankBonus = 0; } int partyBonus = (15 - (ownGroup.lowHPbo.Count + ownGroup.avgHPbo.Count + ownGroup.hiHPbo.Count)) * 10; Handcard retval = null; int val = 0; int tmpval = 0; foreach (Handcard hc in p.ownHandCards) { tmpval = 0; if (hc.card.DamageRadius > 1000) { if (hc.card.TargetType == targetType.ALL) { tmpval += airAreaDPSBonus; } else if (hc.card.TargetType == targetType.GROUND) { tmpval += groundAreaDPSBonus; } } if (hc.card.TargetType == targetType.ALL) { tmpval += airDPSBonus; } if (hc.card.Transport == transportType.AIR && hc.card.TargetType != targetType.BUILDINGS) { tmpval += flyBonus; } if (hc.card.MaxHP > 600) { tmpval += tankBonus + hc.card.MaxHP / 10; } tmpval += hc.card.SpawnNumber * partyBonus; tmpval += hc.card.SpawnNumber * hc.card.Atk; if (tmpval > val) { val = tmpval; retval = hc; } } bc = new Cast(retval.name, ownGroup.Position, retval); } } else if (p.ownMana >= 9) { if (p.noEnemiesOnMySide()) { if (p.ownMinions.Count == 0) { Handcard tank = p.getTankCard(); if (tank != null) { bc = new Cast(tank.name, p.getBackPosition(tank), tank); } else { List <Handcard> BuildingsCard = p.getCardsByType(boardObjType.BUILDING); if (BuildingsCard.Count > 0) { Handcard hut = BuildingsCard[0]; if (hut.card.name != CardDB.cardName.goblinhut && BuildingsCard.Count > 0) { int count = BuildingsCard.Count; for (int i = 1; i < count; i++) { if (BuildingsCard[i].card.name == CardDB.cardName.goblinhut) { hut = BuildingsCard[i]; break; } } } bc = new Cast(hut.name, p.getBackPosition(hut), hut); } else { Handcard CheapestCard = p.getCheapestCard(boardObjType.MOB, targetType.ALL); if (CheapestCard == null) { CheapestCard = p.getCheapestCard(boardObjType.MOB, targetType.NONE); if (CheapestCard == null) { CheapestCard = p.getCheapestCard(boardObjType.BUILDING, targetType.NONE); if (CheapestCard == null) { CheapestCard = p.getCheapestCard(boardObjType.PROJECTILE, targetType.NONE); if (CheapestCard == null) { bc = null; } else { bc = new Cast(CheapestCard.name, p.enemyBuildings[0].Position, CheapestCard); } } } } bc = new Cast(CheapestCard.name, p.getBackPosition(CheapestCard), CheapestCard); } } } else { BoardObj m = p.getFrontMob(); Handcard hc = p.getPatnerForMobInPeace(m); bc = new Cast(hc.name, m.Position, hc); } } else { p.rotateLines(); bc = p.bestCast; } } else { p.rotateLines(); bc = p.bestCast; } Logger.Information("BestCast: {SpellName} {Position}", bc?.SpellName, bc?.Position); return(bc); }
private static bool IsAOEAttackNeeded(Playfield p) { BoardObj obj = EnemyCharacterWithTheMostEnemiesAround(p, out var biggestEnemieGroupCount); return(biggestEnemieGroupCount > 3); }
public override int GetBoValue(BoardObj bo, Playfield p) { return(0); }
public override Cast GetBestCast(Playfield p) { //if you just need coordinates //var targetPosition = p.getDeployPosition(deployDirection.betweenBridges); //or p.getDeployPosition(deployDirection.enemyPrincessTowerLine2, 0); // there random - small int value like a human random for click //int deployDistance = hc.card.DamageRadius; //or any value //var MyTroopsPosition = p.getDeployPosition(targetPosition, deployDirection.borderSideDown); //or //BoardObj harmfulEnemyMinion = new BoardObj(); //int deployDistance = hc.card.DamageRadius; //or any value //p.getDeployPosition(harmfulEnemyMinion, deployDirection.centerSideUp, deployDistance); //for deployDistance you can use hc.card.DamageRadius Cast bc = null; group ownGroup = p.getGroup(true, 85, boPriority.byTotalNumber, 3000); if (ownGroup != null) { /*if (ownGroup.Position.) * { * * } * else*/ { int airAreaDPSBonus = 1000 - (ownGroup.hiHPboAirAreaDPS + ownGroup.avgHPboAirAreaDPS + ownGroup.lowHPboAirAreaDPS); if (airAreaDPSBonus < 0) { airAreaDPSBonus = 0; } int groundAreaDPSBonus = 800 - (ownGroup.hiHPboGroundAreaDPS + ownGroup.avgHPboAirAreaDPS + ownGroup.lowHPboGroundAreaDPS); if (groundAreaDPSBonus < 0) { groundAreaDPSBonus = 0; } int airDPSBonus = 500 - (ownGroup.hiHPboAirDPS + ownGroup.avgHPboAirDPS + ownGroup.lowHPboAirDPS); if (airDPSBonus < 0) { airDPSBonus = 0; } int flyBonus = 800 - (ownGroup.lowHPboAirTransport + ownGroup.avgHPboAirTransport + ownGroup.hiHPboAirTransport); if (flyBonus < 0) { flyBonus = 0; } int tankBonus = 1600 - ownGroup.hiHPboHP; if (tankBonus < 0) { tankBonus = 0; } int partyBonus = (15 - (ownGroup.lowHPbo.Count + ownGroup.avgHPbo.Count + ownGroup.hiHPbo.Count)) * 10; Handcard retval = null; int val = 0; int tmpval = 0; foreach (Handcard hc in p.ownHandCards) { tmpval = 0; if (hc.card.DamageRadius > 1000) { if (hc.card.TargetType == targetType.ALL) { tmpval += airAreaDPSBonus; } else if (hc.card.TargetType == targetType.GROUND) { tmpval += groundAreaDPSBonus; } } if (hc.card.TargetType == targetType.ALL) { tmpval += airDPSBonus; } if (hc.card.Transport == transportType.AIR && hc.card.TargetType != targetType.BUILDINGS) { tmpval += flyBonus; } if (hc.card.MaxHP > 600) { tmpval += tankBonus + hc.card.MaxHP / 10; } tmpval += hc.card.SummonNumber * partyBonus; tmpval += hc.card.SummonNumber * hc.card.Atk; if (tmpval > val) { val = tmpval; retval = hc; } } bc = new Cast(retval.name, ownGroup.Position, retval); } } else if (p.ownMana >= 9) { if (p.noEnemiesOnMySide()) { if (p.ownMinions.Count == 0) { Handcard tank = p.getTankCard(); if (tank != null) { bc = new Cast(tank.name, p.getBackPosition(tank), tank); } else { List <Handcard> BuildingsCard = p.getCardsByType(boardObjType.BUILDING); if (BuildingsCard.Count > 0) { Handcard hut = BuildingsCard[0]; if (hut.card.name != CardDB.cardName.goblinhut && BuildingsCard.Count > 0) { int count = BuildingsCard.Count; for (int i = 1; i < count; i++) { if (BuildingsCard[i].card.name == CardDB.cardName.goblinhut) { hut = BuildingsCard[i]; break; } } } bc = new Cast(hut.name, p.getBackPosition(hut), hut); } else { Handcard CheapestCard = p.getCheapestCard(boardObjType.MOB, targetType.ALL); if (CheapestCard == null) { CheapestCard = p.getCheapestCard(boardObjType.MOB, targetType.NONE); if (CheapestCard == null) { CheapestCard = p.getCheapestCard(boardObjType.BUILDING, targetType.NONE); if (CheapestCard == null) { CheapestCard = p.getCheapestCard(boardObjType.PROJECTILE, targetType.NONE); if (CheapestCard == null) { bc = null; } else { bc = new Cast(CheapestCard.name, p.enemyBuildings[0].Position, CheapestCard); } } } } bc = new Cast(CheapestCard.name, p.getBackPosition(CheapestCard), CheapestCard); } } } else { BoardObj m = p.getFrontMob(); Handcard hc = p.getPatnerForMobInPeace(m); bc = new Cast(hc.name, m.Position, hc); } } else { //p.rotateLines(); bc = p.bestCast; } } else { //p.rotateLines(); bc = p.bestCast; } Logger.Debug("BestCast: {SpellName} {Position}", bc?.SpellName, bc?.Position); return(bc); }
public override int GetBoValue(BoardObj bo, Playfield p) { const int retval = 5; return(retval); }
public static Handcard GetOppositeCard(Playfield p, FightState currentSituation) { if (p.enemyKingsTower.HP < Apollo.Setting.KingTowerSpellDamagingHealth) { Handcard hc = AttackKingTowerWithSpell(p); if (hc != null) { return(hc); } } switch (currentSituation) { case FightState.UAKTL1: case FightState.UAKTL2: case FightState.UAPTL1: case FightState.UAPTL2: case FightState.AKT: case FightState.APTL1: case FightState.APTL2: case FightState.DKT: case FightState.DPTL1: case FightState.DPTL2: { BoardObj defender = Decision.GetBestDefender(p); if (defender == null) { return(null); } Logger.Debug("BestDefender: {Defender}", defender.ToString()); opposite spell = KnowledgeBase.Instance.getOppositeToAll(p, defender, Decision.CanWaitDecision(p, currentSituation)); if (spell != null && spell.hc != null) { Logger.Debug("Spell: {Sp} - MissingMana: {MM}", spell.hc.name, spell.hc.missingMana); if (spell.hc.missingMana == 100) // Oposite-Card is already on the field { return(null); } else if (spell.hc.missingMana > 0) { return(null); } else { return(spell.hc); } } } break; case FightState.START: case FightState.WAIT: default: break; } return(null); }