Esempio n. 1
0
        // The actual maze generation is adaptible to any topology
        private static void MakeMaze(GenerationCell start)
        {
            GenerationCell current = start, exit = start, next;
            ulong          depth = 0, max = 0; // To find the farthest exit, we keep track of “tree” depth

            // Potential improvement: Store this information in the cell itself, for fancy stuff later on

            while (true) // This ain't Lisp, I ain't recursin'
            {
                current.Visited = true;

                if (Randomize)
                {
                    Shuffle <Cell>(current.Links); // This is a destructive function. May want to rewrite to use a temporary clone list for iteration
                }
                bool natural = true;
                for (int i = 0; i < current.Links.Count; i++)
                {
                    next = (GenerationCell)current.Links[i]; // We cast for access to .Previous, which regular cells do not have
                    // Note: This incurs no extra penalty so using it in the main body of a loop is A-OK

                    if (next.Previous == current) // We obviously don't want to mess with a link if we've already gone that way
                    {
                        continue;
                    }

                    if (next.Visited) // It was already visited via some other route, so this is not what we're looking for
                    {
                        current.Links.RemoveAt(i--);
                        continue;
                    }

                    // It's an unexplored link
                    current.ClassState = CLASS_STATE.VISITED;

                    if (++depth > max) // Since we're exploring, and want to keep track of the highest later on
                    {
                        exit = next;
                        max  = depth;
                    }

                    next.Previous = current;
                    current       = next;
                    natural       = false; // Ugly helper variable since we can't continue out of multiple loops that easily
                    break;
                }

                if (!natural) // The loop didn't terminate naturally, so we found a new node and are considering from there
                {
                    continue;
                }

                // We explored all links and found none - dead end cell
                if (current.Previous == null) // The starting cell has no previous cell
                {
                    // The function can safely end here, since if we've backtraced all the way to the
                    // starting cell and found no more link, the entire maze has been explored.
                    exit.ExitCell = true;
                    return;
                }

                current = current.Previous;
                depth--;
            }   // The endless loop repeats here
        }
Esempio n. 2
0
        // Generates an array of cells, and a maze to go with them
        public static Cell[,] GenerateOrthogonal(int Width, int Height, int XEntrance, int YEntrance, bool Cyclic)
        {
            if (XEntrance >= Width || YEntrance >= Height)
            {
                throw new ArgumentOutOfRangeException("Starting coordinates out of range.");
            }

            GenerationCell[,] maze = new GenerationCell[Width, Height];

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    maze[x, y]            = new GenerationCell(); // initialize with non-connected cells
                    maze[x, y].ClassState = CLASS_STATE.OPEN;
                }
            }

            // Generate links to adjacent cells, since this is an orthogonal maze
            // To-do: Maybe encapsulate the bounds-checking and link generation process inside a small function,
            // and call it on a list of locations instead?
            // Not going to bother right now since it won't significantly reduce SLOC count, but for non-2D
            // mazes this would be nice
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    if (x > 0)
                    {
                        maze[x, y].Links.Add(maze[x - 1, y]);
                    }
                    else if (Cyclic)
                    {
                        maze[x, y].Links.Add(maze[Width - 1, y]);
                    }

                    if (y > 0)
                    {
                        maze[x, y].Links.Add(maze[x, y - 1]);
                    }
                    else if (Cyclic)
                    {
                        maze[x, y].Links.Add(maze[x, Height - 1]);
                    }

                    if (x + 1 < Width)
                    {
                        maze[x, y].Links.Add(maze[x + 1, y]);
                    }
                    else if (Cyclic)
                    {
                        maze[x, y].Links.Add(maze[0, y]);
                    }

                    if (y + 1 < Height)
                    {
                        maze[x, y].Links.Add(maze[x, y + 1]);
                    }
                    else if (Cyclic)
                    {
                        maze[x, y].Links.Add(maze[x, 0]);
                    }
                }
            }

            MakeMaze(maze[XEntrance, YEntrance]);

            return(maze);
        }