Пример #1
0
    /// <summary>
    /// Convert an object that implements IPossbilityTarget
    /// to a possibility model that is usable by the
    /// Utiltiy calculation static method
    /// </summary>
    public static PossibilityModel GetPossibilityModel(GameObject obj)
    {
        if (obj == null)
        {
            return(null);
        }

        // The interface held by every possible
        // target for an action
        IPossibilityTarget target = obj.GetComponent <IPossibilityTarget>();
        PossibilityModel   model;

        if (target == null)
        {
            return(null);
        }

        // Create an item possibility
        if (target.Type == PossibilityType.APPLY_ITEM)
        {
            Item    targetItem = obj.GetComponent <Item>();
            Vector3 targetPos  = obj.transform.position;

            // Use the default constructor to create
            // a new possibility model for this item
            model = new PossibilityModel(target.Type, targetItem, targetPos);
        }

        // Create an attack possibility
        else if (target.Type == PossibilityType.ATTACK)
        {
            Vector3   targetPos   = obj.transform.position;
            AgentBase targetAgent = obj.GetComponent <AgentBase>();

            // Use the overload constructor to create
            // a new possbility model for this enemy agent
            model            = new PossibilityModel(target.Type, targetPos, targetAgent);
            model.EnergyCost = ENERGY_COST_ATTACK;
            //Debug.Log("Created a new attack possibility for agent: " + obj.name);
        }
        else
        {
            return(null);
        }

        return(model);
    }
Пример #2
0
    /// <summary>s
    /// Returns utility for given state
    /// as a percentage
    /// </summary>
    public static float CalcUtility(PossibilityModel model, AgentBase agent)
    {
        // Calculate the utility percentage
        // of applying an item for this agent
        if (model.Type == PossibilityType.APPLY_ITEM)
        {
            float projectedHealth, projectedEnergy, projectedAttack;
            float healthIncrease, energyIncrease, attackIncrease;
            float weightedHealth, weightedEnergy, weightedAttack;

            // Calculate our potential health, energy
            // and attack power levels after applying
            // an item to given agent

            // Our projected health is the health
            // we should have after applying the item
            projectedHealth = agent.AgentHealth + model.TargetItem.HealthBoost;
            // Limit the health to 100%
            if (projectedHealth > 100)
            {
                projectedHealth = 100;
            }

            // Calculate the percentange of
            // health gained from this item
            healthIncrease = projectedHealth - agent.AgentHealth;

            // Calculate the percentage of
            // energy gained from this item
            projectedEnergy = agent.AgentEnergy + model.TargetItem.EnergyBoost;
            if (projectedEnergy > 100)
            {
                projectedHealth = 100;
            }

            energyIncrease = projectedEnergy - agent.AgentEnergy;

            // Calculate the percentage of
            // attack power gained from item
            projectedAttack = agent.AgentAttack + model.TargetItem.AttackBoost;
            if (projectedAttack > 100)
            {
                projectedAttack = 100;
            }

            attackIncrease = projectedAttack - agent.AgentAttack;

            // Correct our gain with weights
            // that determine the agent's priorities
            weightedHealth = healthIncrease * agent.HealthWeight;
            weightedEnergy = energyIncrease * agent.EnergyWeight;
            weightedAttack = attackIncrease * agent.AttackWeight;

            // Calculate the utility
            float utility = (weightedHealth + weightedEnergy + weightedAttack) / 3;

            // Debug the utility
            if (agent.EnableDebugs)
            {
                Debug.Log("Agent: " + agent.name + " - Calculated utility of: " + utility + " % "
                          + "for an item");
            }

            return(utility);
        }

        // Calculate the utility percentage of
        // an attack for this agent
        else if (model.Type == PossibilityType.ATTACK)
        {
            float projectedHealth, projectedEnergy;
            float enemyProjectedHealth;
            float projectedLoss, enemyProjectedLoss;
            float weightedDamageDealt, weightedHealthLoss;

            // Calculate the amount of health this
            // agent would have left in case it traded
            // damage with another agent
            projectedHealth = agent.AgentHealth - model.TargetAgent.AgentAttack;
            projectedEnergy = agent.AgentEnergy - ENERGY_COST_ATTACK;

            // If energy or health would fall below zero,
            // it has zero utility % for this agent
            if (projectedEnergy <= 0 || projectedHealth < 0)
            {
                return(0f);
            }

            enemyProjectedHealth = model.TargetAgent.AgentHealth - agent.AgentAttack;

            // The loss of each party involved in the
            // damage trade
            projectedLoss      = agent.AgentHealth - projectedHealth;
            enemyProjectedLoss = model.TargetAgent.AgentHealth - enemyProjectedHealth;

            // The loss as a weighted value
            weightedHealthLoss  = (projectedLoss * agent.HealthWeight);
            weightedDamageDealt = (enemyProjectedLoss * agent.DealDamageWeight);

            // Final utiltiy of this
            // attack possibility
            float utility = (weightedHealthLoss + weightedDamageDealt) / 2;
            utility *= DIVISION_CORRECTION;

            // Debug the final utility outcome
            if (agent.EnableDebugs)
            {
                Debug.Log("Agent: " + agent.name + " - Calculated utility of: " + utility + " % "
                          + "for an attack");
            }



            return(utility);
        }

        // The possibility type is unknown and
        // therefore we return a utility % of
        // 0
        return(0f);
    }