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);
        }
Ejemplo n.º 2
0
        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);
        }