// an A* shortest path algorithm public APath shortestPath(int startIpos, int startJpos, int destIpos, int destJpos, MapCell[] Visited, int VisitedLength, ref Boolean PathFound) { int i; int newVisitedLength = VisitedLength + 1; MapCell[] newVisited = new MapCell[newVisitedLength]; APath shortestpath = null; // first checking whether we are in /out of map bounds if ((startIpos < 0) || (startIpos >= mappingFSM.MapDim) || (startJpos < 0) || (startJpos >= mappingFSM.MapDim)) PathFound = false; else if (mappingFSM.Map[startIpos][startJpos] == MappingFSM.cellBLOCK) PathFound = false; else if (inPath(startIpos, startJpos, Visited, VisitedLength)) PathFound = false; else if ((mappingFSM.ipos == startIpos) && (mappingFSM.jpos == startJpos)) PathFound = false; else { // copying map of visited cells for (i = 0; i < VisitedLength; i++) newVisited[i] = Visited[i]; // visited cells list copied // now adding current position newVisited[newVisitedLength - 1].ipos = startIpos; newVisited[newVisitedLength - 1].jpos = startJpos; // checking northern cell if ((startIpos - 1 == destIpos) && (startJpos == destJpos)) { PathFound = true; shortestpath = new APath(1); shortestpath.amoves[0] = APath.instGO_NORTH; } // checking eastern cell else if ((startIpos == destIpos) && (startJpos + 1 == destJpos)) { PathFound = true; shortestpath = new APath(1); shortestpath.amoves[0] = APath.instGO_EAST; } // checking southern cell else if ((startIpos + 1 == destIpos) && (startJpos == destJpos)) { PathFound = true; shortestpath = new APath(1); shortestpath.amoves[0] = APath.instGO_SOUTH; }// checking western cell else if ((startIpos == destIpos) && (startJpos - 1 == destJpos)) { PathFound = true; shortestpath = new APath(1); shortestpath.amoves[0] = APath.instGO_WEST; }// recursively checking paths now... else { // sorting out euclidean distances of neighboring cells double[] distances = new double[4]; // 0-north, 1-east, 2-south, 3-west for (i = 0; i < 4; i++) distances[i] = Math.Sqrt(Math.Pow((double)(startIpos - destIpos), 2) + Math.Pow((double)(startJpos - destJpos), 2)); // now repeating until we find a valid path Boolean pfound = false; PathFound = false; int counter = 0; double mindistance = 100000; int mindistanceindex = 0; APath newpath; while ((!pfound) && (counter < 4)) { mindistance = 100000; // large enough value for minimum euclidean distance for (i = 0; i < 4; i++) if ((distances[i] < mindistance) && (distances[i] >= 0)) { mindistance = distances[i]; mindistanceindex = i; } if (mindistance < 100000) { distances[mindistanceindex] = -1; switch (mindistanceindex) { case 0: // North newpath = shortestPath(startIpos - 1, startJpos, destIpos, destJpos, newVisited, newVisitedLength, ref pfound); if (pfound) { PathFound = true; shortestpath = new APath(1); shortestpath.amoves[0] = APath.instGO_NORTH; shortestpath.appendPath(newpath); } break; case 1: // East newpath = shortestPath(startIpos, startJpos + 1, destIpos, destJpos, newVisited, newVisitedLength, ref pfound); if (pfound) { PathFound = true; shortestpath = new APath(1); shortestpath.amoves[0] = APath.instGO_EAST; shortestpath.appendPath(newpath); } break; case 2: // South newpath = shortestPath(startIpos + 1, startJpos, destIpos, destJpos, newVisited, newVisitedLength, ref pfound); if (pfound) { PathFound = true; shortestpath = new APath(1); shortestpath.amoves[0] = APath.instGO_SOUTH; shortestpath.appendPath(newpath); } break; case 3: // South newpath = shortestPath(startIpos, startJpos - 1, destIpos, destJpos, newVisited, newVisitedLength, ref pfound); if (pfound) { PathFound = true; shortestpath = new APath(1); shortestpath.amoves[0] = APath.instGO_WEST; shortestpath.appendPath(newpath); } break; } } counter++; } } // recursion else ends } // big else ends return shortestpath; }
public Boolean inPath(int ipos, int jpos, MapCell[] path, int pathlen) { int i; Boolean found = false; i = 0; while ((i < pathlen) && (!found)) { found = (path[i].ipos == ipos) && (path[i].jpos == jpos) ? true : found; i++; } return found; }