Ejemplo n.º 1
0
        /// <summary>
        /// Given an action, a dictionary of character priorities, and whether or not an action is considered an
        /// offensive action, gets the maximum possible priority of the action and it's target.
        /// </summary>
        /// <param name="action">The action to get the max priority target for.</param>
        /// <param name="priorities">A dictionary containing the priorities for each character target.</param>
        /// <param name="isOffensive">Whether or not an action is considered an offensive action.</param>
        /// <returns>A struct containing the max priority and it's target position.</returns>
        protected virtual MaxPriorityTarget GetMaxPriorityTarget(ActionBase action, Dictionary <Character, int> priorities, bool isOffensive = false)
        {
            int maxPriority        = 0;
            int maxPotentialTarget = 0;

            if (!action.CanSwitchTargetPosition)
            {
                var characterTargets = GetSelectionTargets(action, action.CenterOfTargetsPosition);
                maxPotentialTarget = AITargets.GetModifiedCenter(action.CenterOfTargetsPosition);

                foreach (var character in characterTargets.MyCharacters)
                {
                    maxPriority += isOffensive ? -priorities[character] : priorities[character];
                }
                foreach (var character in characterTargets.PlayerCharacters)
                {
                    maxPriority += isOffensive ? priorities[character] : -priorities[character];
                }
            }
            else
            {
                // Loops through all possible target positions and find the highest priority for this action
                for (int i = 0; i <= 18; i++)
                {
                    int totalPriority    = 0;
                    var characterTargets = GetSelectionTargets(action, i);

                    foreach (var character in characterTargets.MyCharacters)
                    {
                        totalPriority += isOffensive ? -priorities[character] : priorities[character];
                    }
                    foreach (var character in characterTargets.PlayerCharacters)
                    {
                        totalPriority += isOffensive ? priorities[character] : -priorities[character];
                    }

                    // If the current target's total priority is greater than the previous highest priority, or if equal,
                    // change highest priority with 50% chance
                    if (totalPriority > maxPriority || (totalPriority == maxPriority && _rand.Next(0, 2) == 1))
                    {
                        maxPriority        = totalPriority;
                        maxPotentialTarget = i;
                    }
                }
            }

            return(new MaxPriorityTarget()
            {
                TotalPriority = maxPriority,
                TargetPosition = maxPotentialTarget
            });
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Given an ActionBase and a selection position, gets the characters that
        /// action will target seperated by AI characters and player characters.
        /// </summary>
        /// <param name="action">The action to check the targets for.</param>
        /// <param name="selectionPosition">A number representing the position the action targets.</param>
        /// <returns>A struct containing two IReadOnlyList of Characters, one for AI characters and another for player characters.</returns>
        protected SelectionCharacters GetSelectionTargets(ActionBase action, int selectionPosition)
        {
            var myCharacters     = new List <Character>();
            var playerCharacters = new List <Character>();

            // If selection is in left column and something is in the middle or right column on the same row, can't select this position
            bool leftColumnBlocked = selectionPosition % 3 == 1 &&
                                     LivingPlayerCharacters.Where(
                character =>
                (selectionPosition + 1 == character.Position || selectionPosition + 2 == character.Position) &&
                character.CurrentHealth > 0).Any();

            // If selection is in middle column and something is in the right column on the same row, can't select this position
            bool middleColumnBlocked = selectionPosition % 3 == 2 &&
                                       LivingPlayerCharacters.Where(
                character =>
                (selectionPosition + 1 == character.Position && character.CurrentHealth > 0)).Any();

            if (!action.CanSwitchTargetPosition)
            {
                var targets = AITargets.GetModifiedTargets(action);
                myCharacters.AddRange(AICharacters.Where(character => targets.Contains(character.Position)));
                playerCharacters.AddRange(LivingPlayerCharacters.Where(character => targets.Contains(character.Position)));
                return(new SelectionCharacters()
                {
                    MyCharacters = myCharacters,
                    PlayerCharacters = playerCharacters
                });
            }
            // If the action can't target through units and the selection is on the player's field
            else if (!action.CanTargetThroughUnits && selectionPosition <= 9 &&
                     (leftColumnBlocked || middleColumnBlocked))
            {
                myCharacters.Clear();
                playerCharacters.Clear();
                return(new SelectionCharacters()
                {
                    MyCharacters = myCharacters,
                    PlayerCharacters = playerCharacters
                });
            }
            else
            {
                var modifiedSelection = AITargets.GetModifiedSelection(action, selectionPosition);

                foreach (var position in modifiedSelection)
                {
                    if (position >= 10)
                    {
                        Character selectedCharacter = AICharacters.FirstOrDefault(character => character.Position == position);
                        if (selectedCharacter != null)
                        {
                            myCharacters.Add(selectedCharacter);
                        }
                    }
                    else if (position <= 9)
                    {
                        Character selectedCharacter = LivingPlayerCharacters.FirstOrDefault(character => character.Position == position);
                        if (selectedCharacter != null)
                        {
                            playerCharacters.Add(selectedCharacter);
                        }
                    }
                }

                return(new SelectionCharacters()
                {
                    MyCharacters = myCharacters,
                    PlayerCharacters = playerCharacters
                });
            }
        }