} // End evaluateActionUtility /// <summary> /// Gets the appraisal score. /// </summary> /// <returns>The appraisal score.</returns> /// <param name="factorPlant">Factor plant.</param> private static float getAppraisalScore(FactorPlant factorPlant) { IFactor factor = new FactorAssembler().AssembleFactor(factorPlant); Appraisal appraisal = factor.Evaluate(null); return(appraisal.BasicScore); }
/// <summary> /// Evaluates the utility measures of the given actions by adding up the basic scores /// calculated by all factors (per action). It then picks the action with the highest /// score. /// </summary> /// <param name="actions">Actions.</param> /// /// TODO: the blocks of code for initializing factors and getting the /// appraisals of actions could probably be abstracted into a separate /// method. /// /// TODO: this could be done similarly to the Open Closed Principle /// example in the PluralSight course aboud the SOLID principles of /// Object Oriented Software Design by Steve Smith. private static AIAction evaluateActionUtility(List <AIAction> actions) { float previousScore = 0.0f; AIAction bestScoreAction = null; foreach (AIAction action in actions) { float totalScore = 0.0f; FactorPlant factorPlant = null; factorPlant = new FightingStyleRankFactorPlant("Factor Plant"); IFactor fightingStyleRankFactor = new FactorAssembler().AssembleFactor(factorPlant); // TODO: this assumes that the fighting style rank needed here // is always the first one. In the event the character is proficient // in more than one styles this could prove problematic. // This is also a problem because it creates a dependency of this // class on FightingStyleRankFactor. ((FightingStyleRankFactor)fightingStyleRankFactor).Rank = _input.OpponentRanks[0]; Appraisal appraisal = fightingStyleRankFactor.Evaluate(action); //DebugConsole.Log ("Score for Fighting Style Rank is: " + appraisal.BasicScore); totalScore += appraisal.BasicScore; factorPlant = null; factorPlant = new TechniqueProficiencyFactorPlant("Factor Plant"); IFactor techniqueProficiencyFactor = new FactorAssembler().AssembleFactor(factorPlant); appraisal = techniqueProficiencyFactor.Evaluate(action); //DebugConsole.Log ("Score for Technique Proficiency is: " + appraisal.BasicScore); totalScore += appraisal.BasicScore; factorPlant = null; // Get the action's measure of utility in terms of the character's // physical condition. factorPlant = new PhysicalConditionFactorPlant("Factor Plant"); IFactor physicalConditionFactor = new FactorAssembler().AssembleFactor(factorPlant); appraisal = physicalConditionFactor.Evaluate(action); //DebugConsole.Log ("Score for Physical Condition is: " + appraisal.BasicScore); totalScore += appraisal.BasicScore; factorPlant = null; // Get the action's measure of utility in terms of the character's // attacker body part status. factorPlant = new AttackerBodyPartFactorPlant("Factor Plant"); IFactor attackerBodyPartFactor = new FactorAssembler().AssembleFactor(factorPlant); appraisal = attackerBodyPartFactor.Evaluate(action); //DebugConsole.Log ("Score for Attacker Body Part is: " + appraisal.BasicScore); totalScore += appraisal.BasicScore; // Get the action's measure of utility in terms of the preceding // actions performed by the AI Character. factorPlant = new ActionHistoryFactorPlant("Factor Plant"); IFactor actionHistoryFactor = new FactorAssembler().AssembleFactor(factorPlant); // TODO: this is a problem because it creates a dependency of // this class on ActionHistoryFactor. ((ActionHistoryFactor)actionHistoryFactor).Strategy = _input.Strategy; appraisal = actionHistoryFactor.Evaluate(action); //DebugConsole.Log ("Score for Action History is: " + appraisal.BasicScore); totalScore += appraisal.BasicScore; float randomElement = Random.Range(0.0f, 1.0f); //DebugConsole.Log ("Random element is: " + randomElement); totalScore += randomElement; //DebugConsole.Log ("Total score for action " + ((FightingTechniqueAction)action).Proficiency.name + " is: " + totalScore); if (totalScore > previousScore) { previousScore = totalScore; bestScoreAction = action; } } // End foreach return(bestScoreAction); } // End evaluateActionUtility