namespace MazeGen { /// /// Abstract base class for all agent decisions. Each decision encapsulates: /// - A precondition check (CanExecute) /// - An action to perform (Execute) /// - A narration of the decision (Think) /// /// The key insight: keeping CanExecute, Execute, and Think together ensures that /// every action the agent takes is explained to the observer. Adding a new decision /// without narration makes the agent's behavior unexplainable. /// /// Decisions are evaluated in order by AgentDecisionTree, which returns the first /// one whose CanExecute() returns true. /// public abstract class AgentDecision { /// /// Check if this decision can be executed given the agent's current state. /// Return true if this decision should be considered. /// public abstract bool CanExecute(MazeAgent agent); /// /// Execute the decision. This modifies the agent's state or the world. /// Returns true if the decision consumed the agent's decision this tick, /// false if the agent should continue to the next decision in the tree. /// public abstract bool Execute(MazeAgent agent); /// /// Narrate this decision to the agent's thought log. /// Called after Execute() if Execute() returned true. /// This is what the HUD's "Agent thoughts" panel shows. /// /// Keep this synchronized with Execute(): if Execute() does something, /// Think() must explain it. Otherwise the observer sees an agent doing /// things for no explained reason. /// public abstract void Think(MazeAgent agent); /// /// Human-readable name for debugging/logging. /// public abstract string DecisionName { get; } } }