// plan.c // // Version Date Author Description // -------------------------------------------------------------------------- // 0.01 24/06/01 BWW Generate a plan #include #include "planner.h" #include "funcprototypes.h" extern UnmetPreconditions_Struct UnmetPreconditions; extern ActionEffects_Struct ActionEffects; extern Route_Struct Route; extern Door_Struct Door[]; extern Effects_Struct Effects; extern SearchGoalNodes_Struct SearchGoalNodes; extern Exit_Struct Exit; extern Agent_Struct Agent; extern Key_Struct Key; extern CausalLinks_Struct CausalLinks; extern Orderings_Struct Orderings; // Global variables for search routines ..... Temporary measure to get over parameter passing problems extern int startx, starty,destinationx, destinationy; extern int BRIDGENUM; extern int DOORNUM; // -------------------------------------------------------------------------- // Initialise the Plan // -------------------------------------------------------------------------- // Description: Initialise the structures that will hold the plan and set the // agent's goals // // Parameters: None // // Returns: None void InitPlan() { // Reset the structures that will hold the plan UnmetPreconditions.numpreconditions = 0; ActionEffects.numeffects = 0; Orderings.numorderings = 0; CausalLinks.numcausallinks = 0; // Set the Agent's ultimate goal as the first Precondition on the plan SetAgentGoal(); } // -------------------------------------------------------------------------- // Build a plan // -------------------------------------------------------------------------- // Description: Build a new plan // // Parameters: None // // Returns: None void BuildPlan() { int index, result = 0; // Initialise the plan InitPlan(); // Find action effects to met each of the plan's goal preconditions for (index=0;((index 0) { // Add the MoveTo action event AddActionEffect(Effects.effect[effect].condition, Effects.effect[effect].parameter1,UnmetPreconditions.condition[UnmetIndex].value1, Effects.effect[effect].parameter2,UnmetPreconditions.condition[UnmetIndex].value2, Effects.effect[effect].parameter3,UnmetPreconditions.condition[UnmetIndex].value3, SearchGoalNodes.lowestcostvalue); // Add a Causal Link to link the index of the Action Effect to the index of the Precondition it meets AddCausalLink((ActionEffects.numeffects-1),UnmetIndex); // Select the best route and determine which other preconditions need to be met SelectRoute(); GetRoutePreconditions(UnmetIndex); } else { effect = -1; } } if (Effects.effect[effect].condition==EFFECT_UNLOCK) { // Add the Unlock action effect AddActionEffect(Effects.effect[effect].condition, Effects.effect[effect].parameter1,UnmetPreconditions.condition[UnmetIndex].value1, Effects.effect[effect].parameter2,UnmetPreconditions.condition[UnmetIndex].value2, Effects.effect[effect].parameter3,UnmetPreconditions.condition[UnmetIndex].value3, DURATION_UNLOCK); // Add a Causal Link to link the index of the Action Effect to the index of the Precondition it meets AddCausalLink((ActionEffects.numeffects-1),UnmetIndex); // The agent must be adjacent to the door to unlock it. Heuristic rule: As the agent will always // start on the left hand side of the door, 'adjacent' will be one square to the left. preconditionindex=AddUnmetPrecondition(PRECON_AT, PARAM_OBJECTAGENT, NULL, PARAM_XPOS, (Door[UnmetPreconditions.condition[UnmetIndex].value1].x-1), PARAM_YPOS, Door[UnmetPreconditions.condition[UnmetIndex].value1].y); // Order which precondition should be met first AddOrdering(preconditionindex,UnmetIndex); // Check that the agent is carrying the key. If not then GETKEY is a precondition if (Agent.gotkey==false) { oldindex = preconditionindex; preconditionindex = AddUnmetPrecondition(PRECON_GETKEY, PARAM_OBJECTKEY, NULL, PARAM_KEYSTATUS, Agent.gotkey, NULL, NULL); // Order which precondition should be met first - Unlock or GetKey AddOrdering(preconditionindex,UnmetIndex); // Also need to order the GetKey and the MoveTo AddOrdering(preconditionindex,oldindex); } } if (Effects.effect[effect].condition==EFFECT_OPEN) { // printf("Effect = OPEN\n"); // Add the Open action effect AddActionEffect(Effects.effect[effect].condition, Effects.effect[effect].parameter1,UnmetPreconditions.condition[UnmetIndex].value1, Effects.effect[effect].parameter2,UnmetPreconditions.condition[UnmetIndex].value2, Effects.effect[effect].parameter3,UnmetPreconditions.condition[UnmetIndex].value3, DURATION_OPEN); // Add a Causal Link to link the index of the Action Effect to the index of the Precondition it meets AddCausalLink((ActionEffects.numeffects-1),UnmetIndex); // The agent must be adjacent to the door to open it. Heuristic rule: As the agent will always // start on the left hand side of the door, 'adjacent' will be one square to the left. preconditionindex = AddUnmetPrecondition(PRECON_AT, PARAM_OBJECTAGENT, NULL, PARAM_XPOS, (Door[UnmetPreconditions.condition[UnmetIndex].value1].x-1), PARAM_YPOS, Door[UnmetPreconditions.condition[UnmetIndex].value1].y); // Order which precondition should be met first AddOrdering(preconditionindex,UnmetIndex); // Check whether the door needs to be unlocked. If it is then add an 'unlock' precondition if (Door[UnmetPreconditions.condition[UnmetIndex].value1].lockstatus==DOORLOCKED) { oldindex = preconditionindex; preconditionindex = AddUnmetPrecondition(PRECON_DOORUNLOCKED, PARAM_OBJECTDOOR, UnmetPreconditions.condition[UnmetIndex].value1, PARAM_LOCKSTATUS, DOORUNLOCKED, NULL, NULL); // Order which precondition should be met first - Unlock or Open AddOrdering(preconditionindex,UnmetIndex); // Also need to order the Unlock and the MoveTo // AddOrdering(preconditionindex,oldindex); } } if (Effects.effect[effect].condition==EFFECT_PICKUP) { // Add the Pickup action effect AddActionEffect(Effects.effect[effect].condition, Effects.effect[effect].parameter1,UnmetPreconditions.condition[UnmetIndex].value1, Effects.effect[effect].parameter2,UnmetPreconditions.condition[UnmetIndex].value2, Effects.effect[effect].parameter3,UnmetPreconditions.condition[UnmetIndex].value3, DURATION_PICKUP); // Add a Causal Link to link the index of the Action Effect to the index of the Precondition it meets AddCausalLink((ActionEffects.numeffects-1),UnmetIndex); // The agent must be at the same location as the KEY to pick it up preconditionindex = AddUnmetPrecondition(PRECON_AT, PARAM_OBJECTAGENT, NULL, PARAM_XPOS, Key.x, PARAM_YPOS, Key.y); // Order which precondition should be met first AddOrdering(preconditionindex,UnmetIndex); } return (effect); } // -------------------------------------------------------------------------- // Get Preconditions from the Route // -------------------------------------------------------------------------- // Description: Search backward along the Agent's route to the Exit to // identify any preconditons that need to be addressed before // it can be traversed. // // Parameters: None // // Returns: None void GetRoutePreconditions(int UnmetIndex) { int index, index2, preconditionindex; // preconditionindex=UnmetIndex; // For each step along the route for (index=(Route.numsteps-1);index>=0;index--) { // Check each of the doors to see whether it is CLOSED and therefore has a precondition of being // OPEN before it can be traversed for (index2=0;index2