コード例 #1
0
ファイル: Bot.cs プロジェクト: KangJiYoung/Heroes3
        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
            });
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
                }
            }
        }
コード例 #4
0
ファイル: TileManager.cs プロジェクト: KangJiYoung/Heroes3
 public void ShowUnitMapPath(UnitMapPath unitMapPath) => this.unitMapPath = unitMapPath;
コード例 #5
0
ファイル: Bot.cs プロジェクト: KangJiYoung/Heroes3
        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
            });
        }