Exemple #1
0
        /// <summary>
        /// Obtains the complete path based on directions, start, end and a map.
        /// </summary>
        /// <param name="directions">The directions from start to end</param>
        /// <param name="map">The map to find the path on</param>
        /// <param name="end">The start position of the path</param>
        /// <param name="map">The end position of the path</param>
        /// <returns>An IEnumerable containing the complete path</returns>
        public static IEnumerable <MazePointPos> DeterminePathFromDirections(QuatroStack directions, MazePoint start, MazePoint end, InnerMap map)
        {
            //By first determining max and then returning a yield IEnumerable based on this max we only have to calculate the max value once instead of every time you look through the IEnumerable
            //This is because a yield return is only executed when a foreach is ran. But the parameters are already precalculated in it.

            //One additional note is calling this method to obtain the IEnumerable will instantly execute this max count instead of having this also done later. (This means that when you want to
            //loop through the path once it will still do it one extra time to determine the max count). This shouldn't matter that much though :).
            long max = DeterminePathFromDirectionsInternal(directions, start, end, map).LongCount();

            return(DeterminePathFromDirectionsInternalWithCount(directions, start, end, map, max));
        }
Exemple #2
0
        public static IEnumerable <MazePointPos> DeterminePathFromDirections(QuatroStack directions, MazePoint start, MazePoint end, InnerMap map)
        {
            long current = 0;
            long max     = DeterminePathFromDirectionsInternal(directions, start, end, map).LongCount(); //This needs to happen twice sadly but else it we can't know the complete path length

            foreach (var point in DeterminePathFromDirectionsInternal(directions, start, end, map))
            {
                byte formulathing = (byte)((double)current / (double)max * 255.0);
                current++;
                yield return(new MazePointPos(point.X, point.Y, formulathing));
            }
        }
Exemple #3
0
        /// <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 direction from begin to end</returns>
        public static QuatroStack GoFind(MazePoint start, MazePoint end, InnerMap map, Action <int, int, PathFinderAction> callBack)
        {
            if (callBack == null)
            {
                callBack = (x, y, z) => { };
            }


            //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<MazePoint> stackje = new List<MazePoint>();
            //stackje.Add(start);
            QuatroStack quatro = new QuatroStack(); //0 == top, 1 == right, 2 == bot, 3 == left

            MazePoint cur  = start;
            MazePoint prev = new MazePoint(-1, -1);


            Boolean backtracking = false;

            var possibleDirections      = new MazePoint[4];
            int possibleDirectionsCount = 0;
            int maxTimesAtStart         = -1;

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


                if (!backtracking)
                {
                    callBack(x, y, PathFinderAction.Step);
                }
                else
                {
                    callBack(x, y, PathFinderAction.Backtrack);
                }

                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 (maxTimesAtStart == -1)
                {
                    //Only the first time when we are actually at start
                    maxTimesAtStart = possibleDirectionsCount;
                }
                else if (cur.X == start.X && cur.Y == start.Y)
                {
                    maxTimesAtStart--;
                    if (maxTimesAtStart == 0)
                    {
                        Console.WriteLine("No path found...");
                        break;
                    }
                }

                //If we have more then 2 directions we got a junction (only if we're not backtracking) (This is actually 3 directions but we only count 2 because we don't count previous direction)
                //If we are however at the start (which is actually the end because we swap them around) we don't create a direction because you're at the end and don't need directions
                //If we are however at the end (which is the start) we will create a direction if we have more then 2 directions (This is 2 because we don't have a previous one yet)
                if ((possibleDirectionsCount >= 2 && !backtracking && (x != start.X || y != start.Y)) || (possibleDirectionsCount >= 1 && x == end.X && y == end.Y))
                {
                    //Create junction
                    callBack(x, y, PathFinderAction.Junction);

                    int directionWeCameFrom = -1;
                    if (prev.X > cur.X)
                    {
                        directionWeCameFrom = 1; //Previous x was bigger so we came from the right
                    }
                    else if (prev.Y > cur.Y)
                    {
                        directionWeCameFrom = 2;
                    }
                    else if (prev.X < cur.X)
                    {
                        directionWeCameFrom = 3;
                    }
                    else if (prev.Y < cur.Y)
                    {
                        directionWeCameFrom = 0;
                    }
                    quatro.Push(directionWeCameFrom);
                }

                if (x == end.X && y == end.Y)
                {
                    //path found
                    return(quatro);
                }

                if (possibleDirectionsCount > 0)
                {
                    if (backtracking && cur.X == start.X && cur.Y == start.Y)
                    {
                        //This is because we don't have a junction at the start point but we want to stop backtracking anyway
                        backtracking = false;
                    }


                    if (backtracking)
                    {
                        if (possibleDirectionsCount >= 2) //Make sure we don't start searching again in the direction we originally came from
                        {
                            callBack(x, y, PathFinderAction.RefoundJunction);

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

                            var foundJunction = quatro.Peek();

                            int previousDirectionX = 0;
                            int previousDirectionY = 0;
                            switch (foundJunction)
                            {
                            case 0:
                                previousDirectionY = -1;
                                break;

                            case 1:
                                previousDirectionX = 1;
                                break;

                            case 2:
                                previousDirectionY = 1;
                                break;

                            case 3:
                                previousDirectionX = -1;
                                break;
                            }

                            Boolean foundSomething = false;
                            for (int i = 0; i < possibleDirectionsCount; i++)
                            {
                                var probDir = possibleDirections[i];
                                if (probDir.X != x + previousDirectionX || probDir.Y != y + previousDirectionY)
                                {
                                    var directionOfThisDir = -1;
                                    if (probDir.X < cur.X)
                                    {
                                        directionOfThisDir = 0;
                                    }
                                    else if (probDir.Y < cur.Y)
                                    {
                                        directionOfThisDir = 1;
                                    }
                                    else if (probDir.X > cur.X)
                                    {
                                        directionOfThisDir = 2;
                                    }
                                    else if (probDir.Y > cur.Y)
                                    {
                                        directionOfThisDir = 3;
                                    }

                                    if (directionOfThisDir > lastBackTrackDir)
                                    {
                                        prev           = cur;
                                        cur            = probDir;
                                        foundSomething = true;
                                        backtracking   = false;
                                        break;
                                    }
                                }
                            }

                            if (!foundSomething)
                            {
                                callBack(x, y, PathFinderAction.RemovingJunction);
                                quatro.Pop();

                                prev   = cur;
                                cur.X += previousDirectionX;
                                cur.Y += previousDirectionY;
                            }
                        }
                        else
                        {
                            prev = cur;
                            cur  = possibleDirections[0];
                        }
                    }
                    else
                    {
                        prev = cur;
                        cur  = possibleDirections[0];
                    }
                }
                else
                {
                    MazePoint curtemp = cur;
                    cur          = prev;
                    prev         = curtemp;
                    backtracking = true;
                }
            }

            return(new QuatroStack());
        }
Exemple #4
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;
                    }
                }
            }
        }
Exemple #5
0
        private static IEnumerable <MazePointPos> DeterminePathFromDirectionsInternalWithCount(QuatroStack directions, MazePoint start, MazePoint end, InnerMap map, long maxCount)
        {
            long current = 0;

            foreach (var point in DeterminePathFromDirectionsInternal(directions, start, end, map))
            {
                byte formulathing = (byte)((double)current / (double)maxCount * 255.0);
                current++;
                yield return(new MazePointPos(point.X, point.Y, formulathing));
            }
        }
Exemple #6
0
 /// <summary>
 /// Obtains the complete path based on directions and a map
 /// </summary>
 /// <param name="directions">The directions from start to end</param>
 /// <param name="map">The map to find the path on</param>
 /// <returns>An IEnumerable containing the complete path</returns>
 public static IEnumerable <MazePointPos> DeterminePathFromDirections(QuatroStack directions, InnerMap map)
 {
     return(DeterminePathFromDirections(directions, new MazePoint(1, 1), new MazePoint(map.Width - 3, map.Height - 3), map));
 }
        private void GoGenerate(InnerMap map, Maze maze, Random r, Action<int, int, long, long> pixelChangedCallback)
        {
            long totSteps = (((long)maze.Width - 1L) / 2L) * (((long)maze.Height - 1L) / 2L);
            long currentStep = 1;

            int width = maze.Width;
            int height = maze.Height;
            int x = 1;
            int y = 1;

            //Stack<MazePoint> stackje = new Stack<MazePoint>();
            //stackje.Push(new MazePoint(x, y));
            map[x, y] = true;
            pixelChangedCallback.Invoke(x, y, currentStep, totSteps);

            MazePoint[] targets = new MazePoint[4];

            QuatroStack quatro = new QuatroStack(); //0 == top, 1 == right, 2 == bot, 3 == left

            Boolean backtracking = false;
            int prex = 0;
            int prey = 0;

            while (true)
            {
                //Console.WriteLine(quatro.Count + ", X: " + x + " Y: " + y);

                int targetCount = 0;
                if (x - 2 > 0 && !map[x - 2, y])
                {
                    targets[targetCount].X = x - 2;
                    targets[targetCount].Y = y;
                    targetCount++;
                }
                if (x + 2 < width - 1 && !map[x + 2, y])
                {
                    targets[targetCount].X = x + 2;
                    targets[targetCount].Y = y;
                    targetCount++;
                }
                if (y - 2 > 0 && !map[x, y - 2])
                {
                    targets[targetCount].X = x;
                    targets[targetCount].Y = y - 2;
                    targetCount++;
                }
                if (y + 2 < height - 1 && !map[x, y + 2])
                {
                    targets[targetCount].X = x;
                    targets[targetCount].Y = y + 2;
                    targetCount++;
                }

                //Thread.Sleep(1000);

                if (targetCount > 0)
                {

                    var target = targets[r.Next(targetCount)];

                    if (backtracking)
                    {
                        backtracking = false;

                        targetCount = 0;

                        if (map[x - 1, y]) //Wall open at the left
                        {
                            targets[targetCount].X = x - 2;
                            targets[targetCount].Y = y;
                            targetCount++;
                        }
                        if (map[x + 1, y]) //Wall open at the right
                        {
                            targets[targetCount].X = x + 2;
                            targets[targetCount].Y = y;
                            targetCount++;
                        }
                        if (map[x, y - 1]) //Wall open at the top
                        {
                            targets[targetCount].X = x;
                            targets[targetCount].Y = y - 2;
                            targetCount++;
                        }
                        if (map[x, y + 1]) //Wall open at the bottom
                        {
                            targets[targetCount].X = x;
                            targets[targetCount].Y = y + 2;
                            targetCount++;
                        }

                        if (targetCount <= 2) //If currently only 2 exist at this tile, create junction
                        {
                            for (int i = 0; i < targetCount; i++)
                            {
                                var curMazePoint = targets[i];
                                if (curMazePoint.X != prex || curMazePoint.Y != prey)
                                {
                                    if (curMazePoint.Y < y)
                                    {
                                        quatro.Push(0);
                                        //g.FillRectangle(Brushes.Green, x * 5, y * 5, 5, 5);
                                    }
                                    else if (curMazePoint.X > x)
                                    {
                                        quatro.Push(1);
                                        //g.FillRectangle(Brushes.Violet, x * 5, y * 5, 5, 5);
                                    }
                                    else if (curMazePoint.Y > y)
                                    {
                                        quatro.Push(2);
                                        //g.FillRectangle(Brushes.Blue, x * 5, y * 5, 5, 5);
                                    }
                                    else if (curMazePoint.X < x)
                                    {
                                        quatro.Push(3);
                                        //g.FillRectangle(Brushes.Brown, x * 5, y * 5, 5, 5);
                                    }

                                    break;
                                }
                            }
                        }
                    }

                    //stackje.Push(target);
                    map[target.X, target.Y] = true;

                    currentStep++;

                    if (target.X < x)
                    {
                        map[x - 1, y] = true;
                        pixelChangedCallback.Invoke(x - 1, y, currentStep, totSteps);
                    }
                    else if (target.X > x)
                    {
                        map[x + 1, y] = true;
                        pixelChangedCallback.Invoke(x + 1, y, currentStep, totSteps);
                    }
                    else if (target.Y < y)
                    {
                        map[x, y - 1] = true;
                        pixelChangedCallback.Invoke(x, y - 1, currentStep, totSteps);
                    }
                    else if (target.Y > y)
                    {
                        map[x, y + 1] = true;
                        pixelChangedCallback.Invoke(x, y + 1, currentStep, totSteps);
                    }

                    x = target.X;
                    y = target.Y;

                    prex = -1;
                    prey = -1;

                    pixelChangedCallback.Invoke(target.X, target.Y, currentStep, totSteps);
                }
                else
                {
                    backtracking = true;

                    if (map[x - 1, y]) //Wall open at the left
                    {
                        targets[targetCount].X = x - 2;
                        targets[targetCount].Y = y;
                        targetCount++;
                    }
                    if (map[x + 1, y]) //Wall open at the right
                    {
                        targets[targetCount].X = x + 2;
                        targets[targetCount].Y = y;
                        targetCount++;
                    }
                    if (map[x, y - 1]) //Wall open at the top
                    {
                        targets[targetCount].X = x;
                        targets[targetCount].Y = y - 2;
                        targetCount++;
                    }
                    if (map[x, y + 1]) //Wall open at the bottom
                    {
                        targets[targetCount].X = x;
                        targets[targetCount].Y = y + 2;
                        targetCount++;
                    }

                    if (targetCount > 2) //Junction
                    {
                        prex = x;
                        prey = y;

                        int whereToGo = quatro.Pop();
                        if (whereToGo == 0)
                        {
                            y -= 2;
                        }
                        else if (whereToGo == 1)
                        {
                            x += 2;
                        }
                        else if (whereToGo == 2)
                        {
                            y += 2;
                        }
                        else if (whereToGo == 3)
                        {
                            x -= 2;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < targetCount; i++)
                        {
                            var curMazePoint = targets[i];
                            if (curMazePoint.X != prex || curMazePoint.Y != prey)
                            {
                                prex = x;
                                prey = y;
                                x = curMazePoint.X;
                                y = curMazePoint.Y;
                                break;
                            }
                        }
                    }

                    pixelChangedCallback.Invoke(x, y, currentStep, totSteps);

                }

                if (x == 1 && y == 1)
                {
                    break;
                }
            }
        }
Exemple #8
0
        private void GoGenerate(InnerMap map, Maze maze, Random r, Action <int, int, long, long> pixelChangedCallback)
        {
            long totSteps    = (((long)maze.Width - 1L) / 2L) * (((long)maze.Height - 1L) / 2L);
            long currentStep = 1;

            int width  = maze.Width;
            int height = maze.Height;
            int x      = 1;
            int y      = 1;

            //Stack<MazePoint> stackje = new Stack<MazePoint>();
            //stackje.Push(new MazePoint(x, y));
            map[x, y] = true;
            pixelChangedCallback.Invoke(x, y, currentStep, totSteps);

            MazePoint[] targets = new MazePoint[4];

            QuatroStack quatro = new QuatroStack(); //0 == top, 1 == right, 2 == bot, 3 == left

            Boolean backtracking = false;
            int     prex         = 0;
            int     prey         = 0;

            while (true)
            {
                //Console.WriteLine(quatro.Count + ", X: " + x + " Y: " + y);

                int targetCount = 0;
                if (x - 2 > 0 && !map[x - 2, y])
                {
                    targets[targetCount].X = x - 2;
                    targets[targetCount].Y = y;
                    targetCount++;
                }
                if (x + 2 < width - 1 && !map[x + 2, y])
                {
                    targets[targetCount].X = x + 2;
                    targets[targetCount].Y = y;
                    targetCount++;
                }
                if (y - 2 > 0 && !map[x, y - 2])
                {
                    targets[targetCount].X = x;
                    targets[targetCount].Y = y - 2;
                    targetCount++;
                }
                if (y + 2 < height - 1 && !map[x, y + 2])
                {
                    targets[targetCount].X = x;
                    targets[targetCount].Y = y + 2;
                    targetCount++;
                }

                //Thread.Sleep(1000);

                if (targetCount > 0)
                {
                    var target = targets[r.Next(targetCount)];

                    if (backtracking)
                    {
                        backtracking = false;

                        targetCount = 0;

                        if (map[x - 1, y]) //Wall open at the left
                        {
                            targets[targetCount].X = x - 2;
                            targets[targetCount].Y = y;
                            targetCount++;
                        }
                        if (map[x + 1, y]) //Wall open at the right
                        {
                            targets[targetCount].X = x + 2;
                            targets[targetCount].Y = y;
                            targetCount++;
                        }
                        if (map[x, y - 1]) //Wall open at the top
                        {
                            targets[targetCount].X = x;
                            targets[targetCount].Y = y - 2;
                            targetCount++;
                        }
                        if (map[x, y + 1]) //Wall open at the bottom
                        {
                            targets[targetCount].X = x;
                            targets[targetCount].Y = y + 2;
                            targetCount++;
                        }

                        if (targetCount <= 2) //If currently only 2 exist at this tile, create junction
                        {
                            for (int i = 0; i < targetCount; i++)
                            {
                                var curMazePoint = targets[i];
                                if (curMazePoint.X != prex || curMazePoint.Y != prey)
                                {
                                    if (curMazePoint.Y < y)
                                    {
                                        quatro.Push(0);
                                        //g.FillRectangle(Brushes.Green, x * 5, y * 5, 5, 5);
                                    }
                                    else if (curMazePoint.X > x)
                                    {
                                        quatro.Push(1);
                                        //g.FillRectangle(Brushes.Violet, x * 5, y * 5, 5, 5);
                                    }
                                    else if (curMazePoint.Y > y)
                                    {
                                        quatro.Push(2);
                                        //g.FillRectangle(Brushes.Blue, x * 5, y * 5, 5, 5);
                                    }
                                    else if (curMazePoint.X < x)
                                    {
                                        quatro.Push(3);
                                        //g.FillRectangle(Brushes.Brown, x * 5, y * 5, 5, 5);
                                    }

                                    break;
                                }
                            }
                        }
                    }



                    //stackje.Push(target);
                    map[target.X, target.Y] = true;

                    currentStep++;

                    if (target.X < x)
                    {
                        map[x - 1, y] = true;
                        pixelChangedCallback.Invoke(x - 1, y, currentStep, totSteps);
                    }
                    else if (target.X > x)
                    {
                        map[x + 1, y] = true;
                        pixelChangedCallback.Invoke(x + 1, y, currentStep, totSteps);
                    }
                    else if (target.Y < y)
                    {
                        map[x, y - 1] = true;
                        pixelChangedCallback.Invoke(x, y - 1, currentStep, totSteps);
                    }
                    else if (target.Y > y)
                    {
                        map[x, y + 1] = true;
                        pixelChangedCallback.Invoke(x, y + 1, currentStep, totSteps);
                    }

                    x = target.X;
                    y = target.Y;

                    prex = -1;
                    prey = -1;

                    pixelChangedCallback.Invoke(target.X, target.Y, currentStep, totSteps);
                }
                else
                {
                    backtracking = true;

                    if (map[x - 1, y]) //Wall open at the left
                    {
                        targets[targetCount].X = x - 2;
                        targets[targetCount].Y = y;
                        targetCount++;
                    }
                    if (map[x + 1, y]) //Wall open at the right
                    {
                        targets[targetCount].X = x + 2;
                        targets[targetCount].Y = y;
                        targetCount++;
                    }
                    if (map[x, y - 1]) //Wall open at the top
                    {
                        targets[targetCount].X = x;
                        targets[targetCount].Y = y - 2;
                        targetCount++;
                    }
                    if (map[x, y + 1]) //Wall open at the bottom
                    {
                        targets[targetCount].X = x;
                        targets[targetCount].Y = y + 2;
                        targetCount++;
                    }

                    if (targetCount > 2) //Junction
                    {
                        prex = x;
                        prey = y;

                        int whereToGo = quatro.Pop();
                        if (whereToGo == 0)
                        {
                            y -= 2;
                        }
                        else if (whereToGo == 1)
                        {
                            x += 2;
                        }
                        else if (whereToGo == 2)
                        {
                            y += 2;
                        }
                        else if (whereToGo == 3)
                        {
                            x -= 2;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < targetCount; i++)
                        {
                            var curMazePoint = targets[i];
                            if (curMazePoint.X != prex || curMazePoint.Y != prey)
                            {
                                prex = x;
                                prey = y;
                                x    = curMazePoint.X;
                                y    = curMazePoint.Y;
                                break;
                            }
                        }
                    }

                    pixelChangedCallback.Invoke(x, y, currentStep, totSteps);
                }

                if (x == 1 && y == 1)
                {
                    break;
                }
            }
        }