private bool FindPath_Sub(Cell cell, Cell cellDest, ArrayList path, CellPartEnum direction, ArrayList deadPath, bool ignoreDestCharacter, bool ignoreObstacle, bool useStraightAngle) { Debug.WriteLine(string.Format("Find cell at {0}", direction)); Cell cellNext = null; if (direction == CellPartEnum.Center) cellNext = null; else cellNext = cell._adjacentCells[direction]; if (cellNext == null) { // no more cell found Debug.WriteLine(string.Format("No cell")); // get new direction CellPartEnum direction2 = FindDirection(cell.GetCenterPoint(), cellDest.GetCenterPoint()); if (direction == direction2) { switch (direction2) { case CellPartEnum.LowerRight: direction2 = CellPartEnum.LowerLeft; break; case CellPartEnum.LowerLeft: direction2 = CellPartEnum.LowerRight; break; case CellPartEnum.UpperLeft: direction2 = CellPartEnum.UpperRight; break; case CellPartEnum.UpperRight: direction2 = CellPartEnum.UpperLeft; break; } } direction = direction2; //Debug.WriteLine(string.Format("Find cell on {0}", direction)); return FindPath_Sub(cell, cellDest, path, direction, deadPath, ignoreDestCharacter, ignoreObstacle, useStraightAngle); } if (!cellNext.HasPassability() || deadPath.Contains(cellNext)) { // has character or dead cell //Debug.WriteLine(string.Format("Obstacle found")); if (ignoreDestCharacter) { if (cellNext.Equals(cellDest)) { path.Add(cellNext); // end return true; } } if (ignoreObstacle) { return FindPath_Good(cellNext, cellDest, direction, path, deadPath, ignoreDestCharacter, ignoreObstacle, useStraightAngle); } else { // change direction Cell cellNextTest = GetPathNextCell(cell, cellDest, direction, deadPath); if (cellNextTest != null) { // if go backward, remove unwanted (dead) cell if (path.Contains(cellNextTest)) { int index = path.IndexOf(cellNextTest); while (path.Count - 1 > index) { Cell deadCell = (Cell)path[path.Count - 1]; deadPath.Add(deadCell); path.RemoveAt(path.Count - 1); } } //Debug.WriteLine(string.Format("ChangeDir, {0},{1},{2}", direction, cellNextTest._row, cellNextTest._col)); cellNext = cellNextTest; path.Add(cellNext); // continue to find next cell cell = cellNext; } else { // cannot move // end Debug.WriteLine(string.Format("No more move")); return false; } return FindPath_Sub(cell, cellDest, path, direction, deadPath, ignoreDestCharacter, ignoreObstacle, useStraightAngle); } } return FindPath_Good(cellNext, cellDest, direction, path, deadPath, ignoreDestCharacter, ignoreObstacle, useStraightAngle); }
private bool FindPath_Good(Cell cellNext, Cell cellDest, CellPartEnum direction, ArrayList path, ArrayList deadPath, bool ignoreDestCharacter, bool ignoreObstacle, bool useStraightAngle) { //Debug.WriteLine(string.Format("Accept cell {0},{1}", cellNext._row, cellNext._col)); path.Add(cellNext); if (cellNext.Equals(cellDest)) { // end //Debug.WriteLine("Reach Destination"); return true; } if (useStraightAngle) direction = CellPartEnum.Center; else { // change direction if has whole/direct angle double degree = FindDegree(cellNext.GetCenterPoint(), cellDest.GetCenterPoint()); if (Math.Abs(degree) <= 0.05) direction = CellPartEnum.CenterRight; else if (Math.Abs(degree - DIGONAL_ANGLE) <= 0.05) direction = CellPartEnum.LowerRight; else if (Math.Abs(degree - (180 - DIGONAL_ANGLE)) <= 0.05) direction = CellPartEnum.LowerLeft; else if (Math.Abs(degree - 180) <= 0.05) direction = CellPartEnum.CenterLeft; else if (Math.Abs(degree - (180 + DIGONAL_ANGLE)) <= 0.05) direction = CellPartEnum.UpperLeft; else if (Math.Abs(degree - (360 - DIGONAL_ANGLE)) <= 0.05) direction = CellPartEnum.UpperRight; } return FindPath_Sub(cellNext, cellDest, path, direction, deadPath, ignoreDestCharacter, ignoreObstacle, useStraightAngle); }
public bool FindPath(Cell cellSrc, Cell cellDest, ArrayList path, bool ignoreDestCharacter, bool ignoreObstacle) { ArrayList directions = null; FindDirection(cellSrc.GetCenterPoint(), cellDest.GetCenterPoint(), out directions); return FindPath(cellSrc, cellDest, path, (CellPartEnum)directions[0], ignoreDestCharacter, ignoreObstacle, false, false); }
public bool FindPathAdjBest(Cell cellSrc, Cell cellDest, bool ignoreDestCharacter, bool ignoreObstacle, out ArrayList path) { path = null; ArrayList directions = new ArrayList(); FindDirection(cellSrc.GetCenterPoint(), cellDest.GetCenterPoint(), out directions); // use fine path foreach (CellPartEnum direction in directions) { ArrayList path3 = new ArrayList(); if (FindPathAdj(cellSrc, cellDest, direction, ignoreDestCharacter, ignoreObstacle, false, out path3)) { if (path == null || path3.Count < path.Count) { path = path3; } } } //// use straight path //ArrayList path2 = null; //if (FindPathAdj(cellSrc, cellDest, (CellPartEnum)directions[0], // ignoreDestCharacter, ignoreObstacle, true, // out path2)) //{ // if (path == null || path2.Count < path.Count) // { // path = path2; // } //} return true; }
private Cell GetPathNextCell(Cell cell, Cell cellDest, CellPartEnum direction, ArrayList deadPath) { double degree = FindDegree(cell.GetCenterPoint(), cellDest.GetCenterPoint()); switch (direction) { case CellPartEnum.CenterRight: { // get preferred directions ArrayList directions = GetPathFavourDirections(degree, direction); foreach (CellPartEnum direction2 in directions) { Cell cellNextTest = GetNextCell(cell, direction2); if (cellNextTest != null && cellNextTest.HasPassability() && !deadPath.Contains(cellNextTest)) { //Debug.WriteLine(string.Format("Change direction to {0},{1},{2}", direction2, cellNextTest._row, cellNextTest._col)); return cellNextTest; } } } break; case CellPartEnum.CenterLeft: { // get preferred directions ArrayList directions = GetPathFavourDirections(degree, direction); foreach (CellPartEnum direction2 in directions) { Cell cellNextTest = GetNextCell(cell, direction2); if (cellNextTest != null && cellNextTest.HasPassability() && !deadPath.Contains(cellNextTest)) { //Debug.WriteLine(string.Format("Change direction to {0},{1},{2}", direction2, cellNextTest._row, cellNextTest._col)); return cellNextTest; } } } break; case CellPartEnum.LowerRight: { // get preferred directions ArrayList directions = GetPathFavourDirections(degree, direction); foreach (CellPartEnum direction2 in directions) { Cell cellNextTest = GetNextCell(cell, direction2); if (cellNextTest != null && cellNextTest.HasPassability() && !deadPath.Contains(cellNextTest)) { //Debug.WriteLine(string.Format("Change direction to {0},{1},{2}", direction2, cellNextTest._row, cellNextTest._col)); return cellNextTest; } } } break; case CellPartEnum.LowerLeft: { // get preferred directions ArrayList directions = GetPathFavourDirections(degree, direction); foreach (CellPartEnum direction2 in directions) { Cell cellNextTest = GetNextCell(cell, direction2); if (cellNextTest != null && cellNextTest.HasPassability() && !deadPath.Contains(cellNextTest)) { //Debug.WriteLine(string.Format("Change direction to {0},{1},{2}", direction2, cellNextTest._row, cellNextTest._col)); return cellNextTest; } } } break; case CellPartEnum.UpperLeft: { // get preferred directions ArrayList directions = GetPathFavourDirections(degree, direction); foreach (CellPartEnum direction2 in directions) { Cell cellNextTest = GetNextCell(cell, direction2); if (cellNextTest != null && cellNextTest.HasPassability() && !deadPath.Contains(cellNextTest)) return cellNextTest; } } break; case CellPartEnum.UpperRight: { // get preferred directions ArrayList directions = GetPathFavourDirections(degree, direction); foreach (CellPartEnum direction2 in directions) { Cell cellNextTest = cell._adjacentCells[direction2]; if (cellNextTest != null && cellNextTest.HasPassability() && !deadPath.Contains(cellNextTest)) { //Debug.WriteLine(string.Format("Change direction to {0},{1},{2}", direction2, cellNextTest._row, cellNextTest._col)); return cellNextTest; } } } break; } Debug.WriteLine("Change direction but no cell found."); return null; }