001    package aima.search.map;
002    
003    import aima.basic.Percept;
004    import aima.search.framework.StepCostFunction;
005    
006    /**
007     * Implementation of StepCostFunction interface that uses the distance between locations
008     * to calculate the cost in addition to a constant cost, so that it may be used
009     * in conjunction with a Uniform-cost search.
010     */
011    
012    /**
013     * @author Ciaran O'Reilly
014     * 
015     */
016    
017    public class MapStepCostFunction implements StepCostFunction {
018            private Map map = null;
019    
020            //
021            // Used by Uniform-cost search to ensure every step is greater than or equal
022            // to some small positive constant
023            private static double constantCost = 1.0;
024    
025            public MapStepCostFunction(Map aMap) {
026                    this.map = aMap;
027            }
028    
029            public Double calculateStepCost(Object fromCurrentState,
030                            Object toNextState, String action) {
031    
032                    String fromLoc = fromCurrentState.toString();
033                    String toLoc = toNextState.toString();
034                    if (fromCurrentState instanceof Percept) {
035                            fromLoc = (String) ((Percept) fromCurrentState)
036                                            .getAttribute(DynAttributeNames.PERCEPT_IN);
037                            toLoc = (String) ((Percept) toNextState)
038                                            .getAttribute(DynAttributeNames.PERCEPT_IN);
039                    }
040    
041                    Double distance = map.getDistance(fromLoc, toLoc);
042    
043                    if (distance == null || distance <= 0) {
044                            return constantCost;
045                    }
046    
047                    return new Double(distance);
048            }
049    }