public AttackResult BestAttack(UnitMapPath currentUnitMapPath, BattleMap battleMap, Unit currentUnit) { Vector2 bestTarget = currentUnitMapPath.Enemies.First(); Vector2 tileToMove = new Vector2(); var maxDamagePerDeath = 0; foreach (var enemy in currentUnitMapPath.Enemies) { var neigh = BattleMap.GetNeighbours(enemy.X, enemy.Y, true); foreach (var free in currentUnitMapPath.FreeTiles) { if (neigh.Contains(free)) { var enemyUnitData = battleMap.GetUnitData((int)enemy.X, (int)enemy.Y); var remainEnemyUnits = ((enemyUnitData.Health * enemyUnitData.StackSize) - (currentUnit.UnitData.MinimumDamage * currentUnit.UnitData.StackSize)) / enemyUnitData.Health; var enemyUnitsKilledForce = (enemyUnitData.StackSize - remainEnemyUnits) * enemyUnitData.MinimumDamage; if (enemyUnitsKilledForce > maxDamagePerDeath) { bestTarget = enemy; tileToMove = free; maxDamagePerDeath = enemyUnitsKilledForce; } break; } } } return(new AttackResult() { AttackTile = tileToMove, AttackBenefict = maxDamagePerDeath, Target = bestTarget }); }
private void NextTurn() { do { currentUnit = unitActionOrder.Peek(); if (currentUnit.UnitStatus == UnitStatus.Dying) { unitActionOrder.Enqueue(unitActionOrder.Dequeue()); } } while (currentUnit.UnitStatus == UnitStatus.Dying); currentUnit.UnitStatus = UnitStatus.WaitingForAction; currentUnitMapPath = battleMap.GetUnitMapPath(currentUnit.UnitData); tileManager.ShowUnitMapPath(currentUnitMapPath); }
private void NextTurn() { do { currentUnit = unitActionOrder.Peek(); if (currentUnit.UnitStatus == UnitStatus.Dying) { unitActionOrder.Enqueue(unitActionOrder.Dequeue()); } } while (currentUnit.UnitStatus == UnitStatus.Dying); currentUnit.UnitStatus = UnitStatus.WaitingForAction; currentUnitMapPath = battleMap.GetUnitMapPath(currentUnit.UnitData); tileManager.ShowUnitMapPath(currentUnitMapPath); if (unitActionOrder.Where(it => !it.UnitData.LeftFaction).All(it => it.UnitData.StackSize <= 0)) { YouWon = true; return; } if (unitActionOrder.Where(it => it.UnitData.LeftFaction).All(it => it.UnitData.StackSize <= 0)) { YouLost = true; return; } if (player2Faction.Units.Contains(currentUnit.UnitData)) { AttackResult bestAttack = null; if (currentUnitMapPath.Enemies.Any()) { bestAttack = bot.BestAttack(currentUnitMapPath, battleMap, currentUnit); MoveUnit(bestAttack.AttackTile); currentAttackedUnit = unitActionOrder.First(it => it.UnitData == battleMap.GetUnitData((int)bestAttack.Target.X, (int)bestAttack.Target.Y)); } else { var bestDefense = bot.BestDefensePosition(currentUnitMapPath, battleMap, currentUnit, player1Faction.Units.Where(it => it.StackSize > 0).ToList()); MoveUnit(bestDefense.Tile); } } }
public void ShowUnitMapPath(UnitMapPath unitMapPath) => this.unitMapPath = unitMapPath;
public DefenseResult BestDefensePosition(UnitMapPath currentUnitMapPath, BattleMap battleMap, Unit currentUnit, List <UnitData> enemies) { var damagePerTile = new Dictionary <Vector2, int>(); var maxBenefict = 0; Vector2 bestEnemy = new Vector2(); foreach (var enemy in enemies) { var enemyPos = new Vector2(); try { battleMap.GetUnitPositionOnBattle(enemy); } catch (Exception e) { continue; } enemyPos = battleMap.GetUnitPositionOnBattle(enemy); var enemyMathPath = battleMap.GetUnitMapPath(enemy); foreach (var enemyFreeTile in enemyMathPath.FreeTiles) { if (!damagePerTile.ContainsKey(enemyFreeTile)) { damagePerTile.Add(enemyFreeTile, enemy.Health * enemy.MinimumDamage); } else { damagePerTile[enemyFreeTile] += enemy.Health * enemy.MinimumDamage; } } var remainUnitHP = (enemy.Health * enemy.StackSize) - (currentUnit.UnitData.StackSize * currentUnit.UnitData.MinimumDamage); var attackBenefict = (int)Math.Ceiling((float)remainUnitHP / enemy.Health) * enemy.MinimumDamage; if (attackBenefict > maxBenefict) { maxBenefict = attackBenefict; bestEnemy = enemyPos; } } var current = battleMap.GetUnitPositionOnBattle(currentUnit.UnitData); var min = 10000f; var minDamageTaken = 10000; var bestTile = current; var possibleToAttack = false; foreach (var free in currentUnitMapPath.FreeTiles) { int damageTaken = 0; if (damagePerTile.ContainsKey(free)) { damageTaken = damagePerTile[free]; } if (Vector2.Distance(free, bestEnemy) <= currentUnit.UnitData.Speed && damageTaken < minDamageTaken) { min = Vector2.Distance(bestEnemy, free); bestTile = free; minDamageTaken = damageTaken; possibleToAttack = true; continue; } if (Vector2.Distance(free, bestEnemy) == min && !possibleToAttack && damageTaken < minDamageTaken) { min = Vector2.Distance(bestEnemy, free); bestTile = free; minDamageTaken = damageTaken; continue; } if (Vector2.Distance(free, bestEnemy) < min && !possibleToAttack) { min = Vector2.Distance(bestEnemy, free); bestTile = free; minDamageTaken = damageTaken; } } return(new DefenseResult() { PosibleDamageTaken = minDamageTaken, Tile = bestTile }); }