public void Execute(EventResults result, Game game, EventContext context) { Character chosen = context.CurrentCharacter.ChooseCharacter(game.FilterCharacters(requirements, context), operation, context, scopeName); context.PushScope(chosen, scopeName); operation.Execute(result, game, context); context.PopScope(); }
public double Evaluate(Game game, EventContext context, Weights weights) { //Get the weights for the character that will be choosing the character. Weights charWeights = context.CurrentCharacter.GetWeights(weights.Perspective); Character[] availableCharacters = game.FilterCharacters(requirements, context).ToArray(); bool[] allowed = new bool[availableCharacters.Length]; if (context.CurrentCharacter is AICharacter) { //AICharacter will only select characters from his important character's list. var important = (context.CurrentCharacter as AICharacter).GetImportantCharacters().Select(pair => pair.Key).ToList(); for (int i = 0; i < availableCharacters.Length; ++i) { allowed[i] = important.Contains(availableCharacters[i]); } } else { //The player could select anything. We don't know anything about his preferences. for (int i = 0; i < availableCharacters.Length; ++i) { allowed[i] = true; } } //Figure out which ones we think he will choose. int[] bestIndices = AIHelper.GetBest(availableCharacters, allowed, charWeights, (character, localWeights) => { //We are only considering things theoretically: Don't make any changes to the context //we are given. We want a new local context for each character so variable changes for //one character don't influence the others. EventContext localContext = new EventContext(context); localContext.PushScope(character, scopeName); double directResult = operation.Evaluate(game, localContext, localWeights); //We need to take into account any prestige modifiers because we are throwing away //the local context now. return directResult + localWeights.MeasureAfter(localContext, game); }); //Evaluate each of those character using our weights double result = 0.0; foreach(var bestIndex in bestIndices) { Character best = availableCharacters[bestIndex]; //We are only considering things theoretically: Don't make any changes to the context //we are given. We want a new local context for each character so variable changes for //one character don't influence the others. EventContext localContext = new EventContext(context); localContext.PushScope(best, scopeName); result += operation.Evaluate(game, localContext, weights); //We need to take into account any prestige modifiers because we are throwing away //the local context now. result += weights.MeasureAfter(localContext, game); } return result / bestIndices.Length; }