Exemple #1
0
        /// <summary>
        /// Returns a pair of points that are farthest in distance from each other
        /// </summary>
        /// <param name="points"></param>
        /// <returns></returns>
        public static Point[] MaxDistanceNaive(Point[] points)
        {
            Point[] selectedPoints = { points[0], points[1] };
            double  minDistance    = MiscMethods.DistanceFormula(points[0], points[1]);

            for (int i = 0; i < points.Length; i++)
            {
                for (int j = i + 1; j < points.Length; j++)
                {
                    if (MiscMethods.DistanceFormula(points[i], points[j]) < minDistance)
                    {
                        minDistance       = MiscMethods.DistanceFormula(points[i], points[j]);
                        selectedPoints[0] = points[i];
                        selectedPoints[1] = points[j];
                    }
                }
            }

            return(selectedPoints);
        }
Exemple #2
0
        //public static void PathFind_AvoidPlayers(Enemy attacker, Character target, List<Player> players, int range)
        //{
        //    int spacesLeft = attacker.CurrentStats[4];
        //    Point attackerPoint = attacker.BattleFieldLocation;
        //    Point oldLocation = attackerPoint;
        //    Point targetPoint = target.BattleFieldLocation;

        //    //Divide BattleField into two parts based on number of players in either side of the field.
        //    //The attacker would want to move in the direction with the least amount of players while still being within range of attack
        //    List<Player> playersOnLeft = new List<Player>(), playersOnRight = new List<Player>();

        //    foreach (Player player in players)
        //    {
        //        if (targetPoint.X > player.BattleFieldLocation.X)
        //        {
        //            playersOnLeft.Add(player);
        //        }
        //        else if (targetPoint.X < player.BattleFieldLocation.X)
        //        {
        //            playersOnRight.Add(player);
        //        }
        //    }

        //    Gets in range the first time
        //    while (MiscMethods.DistanceFormula(attackerPoint, targetPoint) > range && spacesLeft > 1)
        //    {
        //        if (attackerPoint.X > targetPoint.X)
        //        {
        //            Attacker is right of target.Move left.
        //            attackerPoint.X--;
        //        }
        //        else if (attackerPoint.X < targetPoint.X)
        //        {
        //            Attacker is left of target.Move right.
        //            attackerPoint.X++;
        //        }
        //        else if (attackerPoint.Y > targetPoint.Y)
        //        {
        //            Attacker is above of target.Move down.
        //            attackerPoint.Y--;
        //        }
        //        else
        //        {
        //            Attacker is below of target.Move up.
        //            attackerPoint.Y++;
        //        }
        //        spacesLeft--;
        //    }

        //    Back up until the attacker is just out of range from the target
        //    while (MiscMethods.DistanceFormula(attackerPoint, targetPoint) < range && spacesLeft > 1)
        //    {
        //        if (attackerPoint.X > targetPoint.X)
        //        {
        //            Attacker is right of target.Move right.
        //            attackerPoint.X++;
        //        }
        //        else if (attackerPoint.X < targetPoint.X)
        //        {
        //            Attacker is left of target.Move left.
        //            attackerPoint.X--;
        //        }
        //        else if (attackerPoint.Y > targetPoint.Y)
        //        {
        //            Attacker is above of target.Move up.
        //            attackerPoint.Y++;
        //        }
        //        else
        //        {
        //            Attacker is below of target.Move down.
        //            attackerPoint.Y--;
        //        }
        //        spacesLeft--;
        //    }

        //    Get in range again
        //    while (MiscMethods.DistanceFormula(attackerPoint, targetPoint) > range && spacesLeft > 0)
        //    {
        //        if (attackerPoint.X > targetPoint.X)
        //        {
        //            Attacker is right of target.Move left.
        //            attackerPoint.X--;
        //        }
        //        else if (attackerPoint.X < targetPoint.X)
        //        {
        //            Attacker is left of target.Move right.
        //            attackerPoint.X++;
        //        }
        //        else if (attackerPoint.Y > targetPoint.Y)
        //        {
        //            Attacker is above of target.Move down.
        //            attackerPoint.Y--;
        //        }
        //        else
        //        {
        //            Attacker is below of target.Move up.
        //            attackerPoint.Y++;
        //        }
        //        spacesLeft--;
        //    }

        //    if (oldLocation == attackerPoint)
        //    {
        //        throw new DidNotMoveException($"Enemy {attacker.Name} did not move. Try to attack?");
        //    }
        //    else
        //    {
        //        attacker.BattleFieldLocation = attackerPoint;
        //        GameBase.CurrentGame.CurrentBattleField.FinalizeMovement(attacker, oldLocation);
        //    }
        //}

        public static void PathFind_RunFromPlayers(Enemy attacker, List <Player> players, int spacesLeft)
        {
            Point attackerPoint = attacker.BattleFieldLocation;
            Point oldLocation   = attackerPoint;

            //Divide BattleField into two parts based on number of players in either side of the field.
            //The attacker would want to move in the direction with the least amount of players while still being within range of attack
            List <Player> playersOnLeft = new List <Player>(), playersOnRight = new List <Player>();

            foreach (Player player in players)
            {
                if (attacker.BattleFieldLocation.X > player.BattleFieldLocation.X)
                {
                    playersOnLeft.Add(player);
                }
                else if (attacker.BattleFieldLocation.X < player.BattleFieldLocation.X)
                {
                    playersOnRight.Add(player);
                }
            }

            if (playersOnLeft.Count > playersOnRight.Count)
            {
                attackerPoint.X = Math.Max(0, attackerPoint.X - spacesLeft);
            }
            else
            {
                attackerPoint.X = Math.Min(BattleField.BattleFieldWidth, attackerPoint.X + spacesLeft);
            }

            spacesLeft -= Math.Abs(oldLocation.X - attackerPoint.X);

            if (spacesLeft > 0)
            {
                Player closestPlayer = players[0];
                double minDistance   = double.PositiveInfinity;

                foreach (Player player in players)
                {
                    if (player == null)
                    {
                        continue;
                    }

                    double distance = MiscMethods.DistanceFormula(attackerPoint, player.BattleFieldLocation);

                    if (minDistance < distance)
                    {
                        closestPlayer = player;
                        minDistance   = distance;
                    }
                }

                Point playerPoint = closestPlayer.BattleFieldLocation;

                while (spacesLeft > 0)
                {
                    if (attackerPoint.Y > playerPoint.Y)
                    {
                        //Attacker is above of target. Move up.
                        attackerPoint.Y++;

                        if (attackerPoint.Y == BattleField.BattleFieldHeight - 1)
                        {
                            break;
                        }
                    }
                    else
                    {
                        //Attacker is below of target. Move down.
                        attackerPoint.Y--;
                    }
                    spacesLeft--;
                }
            }

            if (oldLocation == attackerPoint)
            {
                throw new DidNotMoveException($"Enemy {attacker.Name} did not move. Try to attack?");
            }
            else
            {
                attacker.BattleFieldLocation = attackerPoint;
                GameBase.CurrentGame.CurrentBattleField.FinalizeMovement(attacker, oldLocation);
            }
        }
Exemple #3
0
        /// <summary>
        /// Simple path finding algorithm.
        /// </summary>
        /// <param name="attacker">The enemy doing the attack</param>
        /// <param name="target">The character the enemy is navigating to</param>
        /// <param name="range">The range of the attack the enemy is going to use</param>
        /// <param name="keepDistance">If true, then attacker will move away from target until it can barely hit the target.</param>
        /// <exception cref="DidNotMoveException"></exception>
        public static void PathFind_Direct(Enemy attacker, Character target, int range, bool keepDistance = false)
        {
            int   spacesLeft    = attacker.CurrentStats[4];
            Point attackerPoint = attacker.BattleFieldLocation;
            Point oldLocation   = attackerPoint;
            Point targetPoint   = target.BattleFieldLocation;

            //Gets in range
            while (MiscMethods.DistanceFormula(attackerPoint, targetPoint) > range && spacesLeft > 0)
            {
                if (attackerPoint.X > targetPoint.X)
                {
                    //Attacker is right of target. Move left.
                    attackerPoint.X--;
                }
                else if (attackerPoint.X < targetPoint.X)
                {
                    //Attacker is left of target. Move right.
                    attackerPoint.X++;
                }
                else if (attackerPoint.Y > targetPoint.Y)
                {
                    //Attacker is above target. Move down.
                    attackerPoint.Y--;
                }
                else
                {
                    //Attacker is below target. Move up.
                    attackerPoint.Y++;
                }
                spacesLeft--;
            }

            //Backs off
            if (keepDistance)
            {
                while (MiscMethods.DistanceFormula(attackerPoint, targetPoint) < range - 1 && spacesLeft > 0)
                {
                    if (attackerPoint.X > targetPoint.X)
                    {
                        //Attacker is right of target. Move right.
                        attackerPoint.X++;
                    }
                    else if (attackerPoint.X < targetPoint.X)
                    {
                        //Attacker is left of target. Move left.
                        attackerPoint.X--;
                    }
                    else if (attackerPoint.Y > targetPoint.Y)
                    {
                        //Attacker is above of target. Move up.
                        attackerPoint.Y++;
                    }
                    else
                    {
                        //Attacker is below of target. Move down.
                        attackerPoint.Y--;
                    }
                    spacesLeft--;
                }
            }

            if (oldLocation == attackerPoint)
            {
                throw new DidNotMoveException($"Enemy {attacker.Name} did not move. Try to attack?");
            }
            else
            {
                attacker.BattleFieldLocation = attackerPoint;
                GameBase.CurrentGame.CurrentBattleField.FinalizeMovement(attacker, oldLocation);
            }
        }
        public static void AIStyle_Timid(Enemy attacker, Player[] activePlayers)
        {
            double[] percentStats = attacker.PercentStats;

            List <Player> playersWithinRange = CharactersWithinRange(attacker, attacker.AllAttacks, activePlayers);

            //Step 1: Find closest player and select that as target
            Player target      = activePlayers[0];
            double minDistance = int.MaxValue;

            foreach (Player player in playersWithinRange)
            {
                if (player == null)
                {
                    continue;
                }

                double distance = target.DirectDistanceFrom(player);
                if (minDistance < distance)
                {
                    target      = player;
                    minDistance = distance;
                }
            }

            //Step 2: Find longest ranged attack.
            Attack longestRangeAttack = attacker.AllAttacks.FindMax(t => t.Range);

            //Start logic for AI Style

            if (attacker.IsWellOff(statPercentages_Timid1))
            {
                if (playersWithinRange.Count < 1)
                {
                    //No players within range.
                    //Path find towards players

                    Pathfinding.PathFind_Direct(attacker, target, longestRangeAttack.Range, false);
                    return;
                }
                else
                {
                    //Attack weakest player
                    target = playersWithinRange.FindMin(t => t.CurrentStats[0]);
                    Attack selectedAttack = attacker.FindStrongestAttack(target, GameBase.Stats.HP);
                    attacker.DoAttack(selectedAttack, target);
                    return;
                }
            }
            else if (attacker.IsWellOff(statPercentages_Timid2))
            {
                RandomEventChooser chooser = new RandomEventChooser
                                             (
                    new List <RandomEvent>
                {
                    new RandomEvent("Attack", percentStats[0]),
                    new RandomEvent("Heal", 0.5)
                }
                                             );

                string selectedEvent = chooser.GetSelected().ToString();

                if (selectedEvent.Equals("Attack") && target != null)
                {
                    Attack selectedAttack = attacker.FindStrongestAttack(target, GameBase.Stats.HP);

                    //Find distance between attacker and target
                    double targetDistance = MiscMethods.DistanceFormula(target.BattleFieldLocation, attacker.BattleFieldLocation);

                    //If distance between targetDistance and range of selected attack is negligible, attack
                    if (selectedAttack.Range - targetDistance < 2)
                    {
                        //Attack weakest player
                        target = playersWithinRange.FindMin(t => t.CurrentStats[0]);

                        if (target != null)
                        {
                            attacker.DoAttack(selectedAttack, target);
                            return;
                        }
                        else if (AutoConsume(attacker, statPercentages_Timid1))
                        {
                            return;
                        }
                        else
                        {
                            //Change to something else?
                            attacker.RecoverMana();
                        }
                    }
                    //Else, move away
                    else
                    {
                        try
                        {
                            Pathfinding.PathFind_Direct(attacker, target, selectedAttack.Range, true);
                        }
                        catch (DidNotMoveException)
                        {
                            //Attack weakest player
                            target = playersWithinRange.FindMin(t => t.CurrentStats[0]);

                            if (target != null)
                            {
                                attacker.DoAttack(selectedAttack, target);
                                return;
                            }
                            else if (AutoConsume(attacker, statPercentages_Timid1))
                            {
                                return;
                            }
                            else
                            {
                                //Change to something else?
                                attacker.RecoverMana();
                            }
                        }

                        return;
                    }
                }
                else
                {
                    HealWithItemsOrAttacks(attacker, statPercentages_Timid1);
                    return;
                }
            }
            else
            {
                RandomEventChooser chooser = new RandomEventChooser
                                             (
                    new List <RandomEvent>
                {
                    new RandomEvent("Heal", 0.75),
                    new RandomEvent("RunFromPlayer", 0.25),
                    new RandomEvent("RunFromBattleField", 0.25)
                }
                                             );

                string eventSelector = chooser.GetSelected().ToString();

                switch (eventSelector)
                {
                case "Heal":
                    HealWithItemsOrAttacks(attacker, statPercentages_Timid1);
                    return;

                case "RunFromPlayer":
                    Pathfinding.PathFind_RunFromPlayers(attacker, activePlayers.ToList());
                    return;

                case "RunFromBattleField":
                    attacker.Run(GameBase.CurrentGame.CurrentBattleField);
                    return;
                }
            }
        }