public int h(Heuristic heuristic, State state) { var value = 0; // How often should we recalculate matching? For now it's once. if (matching == null) { matching = GreedyMinmatching.FindMatching(state, heuristic.DistancesToGoal); } // How many goals are left? foreach (var(box, goal) in matching) { if (goal == goalToPrioritize) { continue; } if (state.BoxesPositions.ContainsKey(box)) { var boxPosition = state.BoxesPositions[box]; value += heuristic.DistancesToGoal[goal][boxPosition.X, boxPosition.Y]; } } // Is box goal or normal goal? if (goalToPrioritize.IsBoxGoal) { var boxForGoal = goalToPrioritize.BoxForGoal; if (state.BoxesPositions.ContainsKey(boxForGoal)) { var boxPosition = state.BoxesPositions[boxForGoal]; value += state.AgentPosition.GetManhattanDistanceTo(boxPosition); } } else { var boxForGoal = goalToPrioritize.BoxForGoal; // If there is no box in the boxes positions, then // that means we already matched it to the goal and removed it. // So we don't want to increase the heuristic for that case. if (state.BoxesPositions.ContainsKey(boxForGoal)) { var boxPosition = state.BoxesPositions[boxForGoal]; var distanceToGoal = heuristic.DistancesToGoal[goalToPrioritize]; value += state.AgentPosition.GetManhattanDistanceTo(boxPosition); value += distanceToGoal[boxPosition.X, boxPosition.Y]; } } return(value); }
public int h(Heuristic heuristic, State state) { var distancesToGoal = heuristic.DistancesToGoal; var value = 0; // How often should we recalculate matching? For now it's once. if (matching == null) { matching = GreedyMinmatching.FindMatching(state, distancesToGoal); } // Distance from the agent to not matched boxes foreach (var(agent, agentPosition) in state.AgentsPositions) { foreach (var(box, boxPosition) in state.BoxesPositions) { // If the agent can't move the box if (agent.Color != box.Color) { continue; } // If the box doesn't have a goal or is already on the goal position if (!matching.ContainsKey(box) || matching[box].Position.Equals(boxPosition)) { continue; } value += agentPosition.GetManhattanDistanceTo(boxPosition); } } // Make agent-boxes distance heuristic less important than boxes-goals distance heuristic // value /= 2; // Distances from boxes to goals from the matching foreach (var(box, goal) in matching) { var boxPosition = state.BoxesPositions[box]; value += distancesToGoal[goal][boxPosition.X, boxPosition.Y]; } return(value); }