示例#1
0
        private static IEnumerable <MazePointPos> DeterminePathFromDirectionsInternal(QuatroStack directions, MazePoint start, MazePoint end, InnerMap map)
        {
            int currentDirectionPos = directions.Count - 1;

            var possibleDirections      = new MazePointPos[4];
            int possibleDirectionsCount = 0;

            MazePointPos prev = new MazePointPos();
            MazePointPos cur  = new MazePointPos(start.X, start.Y, 0);

            int width  = map.Width;
            int height = map.Height;

            while (true)
            {
                yield return(cur);

                if (cur.X == end.X && cur.Y == end.Y)
                {
                    //We found the path
                    break;
                }

                int x = cur.X;
                int y = cur.Y;

                possibleDirectionsCount = 0;
                if ((prev.X != x - 1 || prev.Y != y) && x - 1 > 0 && map[x - 1, y])
                {
                    possibleDirections[possibleDirectionsCount].X = x - 1;
                    possibleDirections[possibleDirectionsCount].Y = y;
                    possibleDirectionsCount++;
                }
                if ((prev.X != x || prev.Y != y - 1) && y - 1 > 0 && map[x, y - 1])
                {
                    possibleDirections[possibleDirectionsCount].X = x;
                    possibleDirections[possibleDirectionsCount].Y = y - 1;
                    possibleDirectionsCount++;
                }
                if ((prev.X != x + 1 || prev.Y != y) && x + 1 < width - 1 && map[x + 1, y])
                {
                    possibleDirections[possibleDirectionsCount].X = x + 1;
                    possibleDirections[possibleDirectionsCount].Y = y;
                    possibleDirectionsCount++;
                }
                if ((prev.X != x || prev.Y != y + 1) && y + 1 < height - 1 && map[x, y + 1])
                {
                    possibleDirections[possibleDirectionsCount].X = x;
                    possibleDirections[possibleDirectionsCount].Y = y + 1;
                    possibleDirectionsCount++;
                }

                if (possibleDirectionsCount == 1)
                {
                    prev = cur;
                    cur  = possibleDirections[0];
                }
                else if (possibleDirectionsCount > 1)
                {
                    int directionToGo = directions.InnerList[currentDirectionPos];
                    currentDirectionPos--;

                    prev = cur;
                    switch (directionToGo)
                    {
                    case 0:
                        cur.Y -= 1;
                        break;

                    case 1:
                        cur.X += 1;
                        break;

                    case 2:
                        cur.Y += 1;
                        break;

                    case 3:
                        cur.X -= 1;
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Finds the path between the start and the endpoint in a maze
        /// </summary>
        /// <param name="start">The start point</param>
        /// <param name="end">The end point</param>
        /// <param name="map">The maze.InnerMap</param>
        /// <param name="callBack">The callback that can be used to see what the pathfinder is doing (or null), the boolean true = a new path find thingy or false when it determined that path is not correct</param>
        /// <returns>The shortest path in a list of points</returns>
        public static List <MazePointPos> GoFind(MazePoint startBefore, MazePoint endBefore, InnerMap map, Action <int, int, bool> callBack)
        {
            if (callBack == null)
            {
                callBack = (x, y, z) => { };
            }

            var start = new MazePointPos(startBefore.X, startBefore.Y);
            var end   = new MazePointPos(endBefore.X, endBefore.Y);

            //Callback won't work nice with this since it will find its path from back to front
            //Swap them so we don't have to reverse at the end ;)
            //MazePoint temp = start;
            //start = end;
            //end = temp;



            int width  = map.Width;
            int height = map.Height;


            List <MazePointPos> stackje = new List <MazePointPos>();

            stackje.Add(start);

            MazePointPos cur  = new MazePointPos();
            MazePointPos prev = new MazePointPos(-1, -1);


            var lastBackTrackDir = -1;

            while (stackje.Count != 0)
            {
                cur = stackje[stackje.Count - 1];
                var x = cur.X;
                var y = cur.Y;


                MazePointPos target = new MazePointPos(-1, -1);
                //Make sure the point was not the previous point, also make sure that if we backtracked we don't go to a direction we already went to, also make sure that the point is white
                if ((prev.X != x + 1 || prev.Y != y) && lastBackTrackDir < 0 && x + 1 < width - 1 && map[x + 1, y])
                {
                    target = new MazePointPos(x + 1, y);
                }
                else if ((prev.X != x || prev.Y != y + 1) && lastBackTrackDir < 1 && y + 1 < height - 1 && map[x, y + 1])
                {
                    target = new MazePointPos(x, y + 1);
                }
                else if ((prev.X != x - 1 || prev.Y != y) && lastBackTrackDir < 2 && x - 1 > 0 && map[x - 1, y])
                {
                    target = new MazePointPos(x - 1, y);
                }
                else if ((prev.X != x || prev.Y != y - 1) && lastBackTrackDir < 3 && y - 1 > 0 && map[x, y - 1])
                {
                    target = new MazePointPos(x, y - 1);
                }
                else
                {
                    var prepoppy = stackje[stackje.Count - 1];
                    stackje.RemoveAt(stackje.Count - 1);

                    if (stackje.Count == 0)
                    {
                        //No path found
                        break;
                    }

                    var newcur = stackje[stackje.Count - 1];

                    //Set the new previous point
                    if (stackje.Count == 1)
                    {
                        prev = new MazePointPos(-1, -1);
                    }
                    else
                    {
                        prev = stackje.ElementAt(stackje.Count - 2);
                    }

                    //Console.WriteLine("Backtracking to X: " + newcur.X + " Y: " + newcur.Y);
                    //Console.WriteLine("Setting new prev: " + prev.X + " Y: " + prev.Y);

                    callBack.Invoke(prepoppy.X, prepoppy.Y, false);

                    //Set the direction we backtracked from
                    if (prepoppy.X > newcur.X)
                    {
                        lastBackTrackDir = 0;
                    }
                    else if (prepoppy.Y > newcur.Y)
                    {
                        lastBackTrackDir = 1;
                    }
                    else if (prepoppy.X < newcur.X)
                    {
                        lastBackTrackDir = 2;
                    }
                    else if (prepoppy.Y < newcur.Y)
                    {
                        lastBackTrackDir = 3;
                    }

                    //Console.WriteLine("Lastbacktrackdir: " + lastBackTrackDir);
                    continue;
                }

                lastBackTrackDir = -1;

                //Console.WriteLine("Going to X: " + target.X + " Y: " + target.Y);

                callBack.Invoke(x, y, true);
                stackje.Add(target);

                if (target.X == end.X && target.Y == end.Y)
                {
                    //Path found
                    break;
                }

                prev = cur;
            }

            for (int i = 0; i < stackje.Count; i++)
            {
                byte formulathing        = (byte)((double)i / (double)stackje.Count * 255.0);
                var  currentStackjeThing = stackje[i];
                stackje[i] = new MazePointPos(currentStackjeThing.X, currentStackjeThing.Y, formulathing);
            }

            return(stackje);
        }
        /// <summary>
        /// Finds the path between the start and the endpoint in a maze
        /// </summary>
        /// <param name="start">The start point</param>
        /// <param name="end">The end point</param>
        /// <param name="map">The maze.InnerMap</param>
        /// <param name="callBack">The callback that can be used to see what the pathfinder is doing (or null), the boolean true = a new path find thingy or false when it determined that path is not correct</param>
        /// <returns>The shortest path in a list of points</returns>
        public static List<MazePointPos> GoFind(MazePoint startBefore, MazePoint endBefore, InnerMap map, Action<int, int, Boolean> callBack)
        {
            if (callBack == null)
            {
                callBack = (x, y, z) => { };
            }

            var start = new MazePointPos(startBefore.X, startBefore.Y);
            var end = new MazePointPos(endBefore.X, endBefore.Y);

            //Callback won't work nice with this since it will find its path from back to front
            //Swap them so we don't have to reverse at the end ;)
            //MazePoint temp = start;
            //start = end;
            //end = temp;

            int width = map.Width;
            int height = map.Height;

            List<MazePointPos> stackje = new List<MazePointPos>();
            stackje.Add(start);

            MazePointPos cur = new MazePointPos();
            MazePointPos prev = new MazePointPos(-1, -1);

            var lastBackTrackDir = -1;

            while (stackje.Count != 0)
            {

                cur = stackje[stackje.Count - 1];
                var x = cur.X;
                var y = cur.Y;

                MazePointPos target = new MazePointPos(-1, -1);
                //Make sure the point was not the previous point, also make sure that if we backtracked we don't go to a direction we already went to, also make sure that the point is white
                if ((prev.X != x + 1 || prev.Y != y) && lastBackTrackDir < 0 && x + 1 < width - 1 && map[x + 1, y])
                {
                    target = new MazePointPos(x + 1, y);
                }
                else if ((prev.X != x || prev.Y != y + 1) && lastBackTrackDir < 1 && y + 1 < height - 1 && map[x, y + 1])
                {
                    target = new MazePointPos(x, y + 1);
                }
                else if ((prev.X != x - 1 || prev.Y != y) && lastBackTrackDir < 2 && x - 1 > 0 && map[x - 1, y])
                {
                    target = new MazePointPos(x - 1, y);
                }
                else if ((prev.X != x || prev.Y != y - 1) && lastBackTrackDir < 3 && y - 1 > 0 && map[x, y - 1])
                {
                    target = new MazePointPos(x, y - 1);
                }
                else
                {
                    var prepoppy = stackje[stackje.Count - 1];
                    stackje.RemoveAt(stackje.Count - 1);

                    if (stackje.Count == 0)
                    {
                        //No path found
                        break;
                    }

                    var newcur = stackje[stackje.Count - 1];

                    //Set the new previous point
                    if (stackje.Count == 1)
                    {
                        prev = new MazePointPos(-1, -1);
                    }
                    else
                    {
                        prev = stackje.ElementAt(stackje.Count - 2);
                    }

                    //Console.WriteLine("Backtracking to X: " + newcur.X + " Y: " + newcur.Y);
                    //Console.WriteLine("Setting new prev: " + prev.X + " Y: " + prev.Y);

                    callBack.Invoke(prepoppy.X, prepoppy.Y, false);

                    //Set the direction we backtracked from
                    if (prepoppy.X > newcur.X)
                    {
                        lastBackTrackDir = 0;
                    }
                    else if (prepoppy.Y > newcur.Y)
                    {
                        lastBackTrackDir = 1;
                    }
                    else if (prepoppy.X < newcur.X)
                    {
                        lastBackTrackDir = 2;
                    }
                    else if (prepoppy.Y < newcur.Y)
                    {
                        lastBackTrackDir = 3;
                    }

                    //Console.WriteLine("Lastbacktrackdir: " + lastBackTrackDir);
                    continue;

                }

                lastBackTrackDir = -1;

                //Console.WriteLine("Going to X: " + target.X + " Y: " + target.Y);

                callBack.Invoke(x, y, true);
                stackje.Add(target);

                if (target.X == end.X && target.Y == end.Y)
                {
                    //Path found
                    break;
                }

                prev = cur;

            }

            for (int i = 0; i < stackje.Count; i++)
            {
                byte formulathing = (byte)((double)i / (double)stackje.Count * 255.0);
                var currentStackjeThing = stackje[i];
                stackje[i] = new MazePointPos(currentStackjeThing.X, currentStackjeThing.Y, formulathing);
            }

            return stackje;
        }