001    /*
002     * Created on Sep 12, 2004
003     *
004     */
005    package aima.search.eightpuzzle;
006    
007    import aima.basic.XYLocation;
008    import aima.search.framework.HeuristicFunction;
009    
010    /**
011     * @author Ravi Mohan
012     * 
013     */
014    
015    public class ManhattanHeuristicFunction implements HeuristicFunction {
016    
017            public double getHeuristicValue(Object state) {
018                    EightPuzzleBoard board = (EightPuzzleBoard) state;
019                    int retVal = 0;
020                    for (int i = 1; i < 9; i++) {
021                            XYLocation loc = board.getLocationOf(i);
022                            retVal += evaluateManhattanDistanceOf(i, loc);
023                    }
024                    return retVal;
025    
026            }
027    
028            public int evaluateManhattanDistanceOf(int i, XYLocation loc) {
029                    int retVal = -1;
030                    int xpos = loc.getXCoOrdinate();
031                    int ypos = loc.getYCoOrdinate();
032                    switch (i) {
033    
034                    case 1:
035                            retVal = Math.abs(xpos - 0) + Math.abs(ypos - 1);
036                            break;
037                    case 2:
038                            retVal = Math.abs(xpos - 0) + Math.abs(ypos - 2);
039                            break;
040                    case 3:
041                            retVal = Math.abs(xpos - 1) + Math.abs(ypos - 0);
042                            break;
043                    case 4:
044                            retVal = Math.abs(xpos - 1) + Math.abs(ypos - 1);
045                            break;
046                    case 5:
047                            retVal = Math.abs(xpos - 1) + Math.abs(ypos - 2);
048                            break;
049                    case 6:
050                            retVal = Math.abs(xpos - 2) + Math.abs(ypos - 0);
051                            break;
052                    case 7:
053                            retVal = Math.abs(xpos - 2) + Math.abs(ypos - 1);
054                            break;
055                    case 8:
056                            retVal = Math.abs(xpos - 2) + Math.abs(ypos - 2);
057                            break;
058    
059                    }
060                    return retVal;
061            }
062    
063    }