private IEnumerable <int> FindMoves(int state) { var(x, y, j, p) = NavigationUtils.DecodeState(state); foreach (var findWalkMove in FindWalkMoves(x, y, j, p)) { yield return(findWalkMove); } foreach (var findUsualFlyUpMove in FindUsualFlyUpMoves(x, y, j, p)) { yield return(findUsualFlyUpMove); } foreach (var findUsualFlyDownMove in FindUsualFlyDownMoves(x, y, j, p)) { yield return(findUsualFlyDownMove); } }
public List <int> FindPath(int s, int fx, int fy, int dist = 0) { if (_lastPath != null && fx == _lastFx && fy == _lastFy && _lastPath.Count > 0) { var(sx, sy, jj, pp) = NavigationUtils.DecodeState(s); var(sx1, sy1, jj1, pp1) = NavigationUtils.DecodeState(_lastPath[0]); if (sx == sx1 && sy == sy1) { _lastPath.RemoveAt(0); return(_lastPath); } } var order = new LinkedList <int>(); order.AddLast(s); var parent = new Dictionary <int, int>(); parent.Add(s, s); int f = -1; while (order.Count > 0) { var currentCode = order.First.Value; order.RemoveFirst(); var(x, y, j, p) = NavigationUtils.DecodeState(currentCode); if (Math.Abs(x - fx) <= dist && Math.Abs(y - fy) <= dist) { f = currentCode; break; } var currentPoint = NavigationUtils.EncodePoint(x, y); for (int move = 0; move < PointMaster.Moves; ++move) { if (!_pointMaster.IsValidMove(currentPoint, move)) { continue; } var newCode = ApplyMove(x, y, j, p, move); if (newCode < 0 || parent.ContainsKey(newCode)) { continue; } var(nx, ny, nj, np) = NavigationUtils.DecodeState(newCode); parent[newCode] = currentCode; order.AddLast(newCode); } if (j == 1 && p == 1) { var newCode = NavigationUtils.EncodeState(x, y, 0, 0); if (newCode < 0 || parent.ContainsKey(newCode)) { continue; } parent[newCode] = currentCode; order.AddLast(newCode); } } if (f == -1) { return(null); } var path = new List <int>(); var cur = f; while (cur != s) { cur = parent[cur]; if (cur == s) { break; } path.Add(cur); } path.Reverse(); order.Clear(); parent.Clear(); _lastFx = fx; _lastFy = fy; _lastPath = path; return(path); }