Example #1
0
    /**
     * build a list of walls in the maze, cells in the maze, and how they connect to each other.
     * @param out
     * @throws IOException
     */
    public void GenerateMaze()
    {
        // build the cells
        Maze.Cells = new Maze.Cell[Maze.MazeSize.x, Maze.MazeSize.y];

        for (int y = 0; y < Maze.MazeSize.y; ++y)
        {
            for (int x = 0; x < Maze.MazeSize.x; ++x)
            {
                Maze.Cells[x, y] = new Maze.Cell(x, y, Maze.Wall.All);
            }
        }

        int unvisitedCells = Maze.Cells.Length;         // -1 for initial cell.
        int cellsOnStack   = 0;

        // Make the initial cell the current cell and mark it as visited
        Maze.Coord currentCell = new Maze.Coord(0, 0);
        Maze.Cells[0, 0].visited = true;
        --unvisitedCells;

        // While there are unvisited cells
        while (unvisitedCells > 0)
        {
            // If the current cell has any neighbours which have not been visited
            // Choose randomly one of the unvisited neighbours
            Maze.Coord nextCell = chooseUnvisitedNeighbor(currentCell);
            if (nextCell != null)
            {
                int cx = currentCell.x;
                int cy = currentCell.y;

                int nx = nextCell.x;
                int ny = nextCell.y;

                // Push the current cell to the stack
                Maze.Cells[cx, cy].onStack = true;
                ++cellsOnStack;

                // Remove the wall between the current cell and the chosen cell
                Maze.Wall wall = Maze.GetWallBetween(currentCell, nextCell);
                if (wall != Maze.Wall.None)
                {
                    Maze.Cells[cx, cy].RemoveWall(wall);
                    Maze.Cells[nx, ny].RemoveWall(Maze.GetOppositeWall(wall));
                }

                // Make the chosen cell the current cell and mark it as visited
                currentCell = nextCell;
                cx          = currentCell.x;
                cy          = currentCell.y;

                Maze.Cells[cx, cy].visited = true;
                --unvisitedCells;
            }
            else if (cellsOnStack > 0)
            {
                // else if stack is not empty pop a cell from the stack
                for (int y = 0; y < Maze.MazeSize.y; ++y)
                {
                    for (int x = 0; x < Maze.MazeSize.x; ++x)
                    {
                        if (Maze.Cells[x, y].onStack)
                        {
                            // Make it the current cell
                            currentCell = new Maze.Coord(x, y);
                            Maze.Cells[x, y].onStack = false;
                            --cellsOnStack;
                            goto breakLoops;
                        }
                    }
                }

                breakLoops :;
            }
        }

        // remove the walls between the end squares
        Maze.Coord auxCurrentCell, auxNextCell;
        Maze.Wall  auxWall;

        var endCoord = Maze.GetEndCoord();

        for (int xAux = 0; xAux < Maze.EndSize.x; xAux++)
        {
            for (int yAux = 0; yAux < Maze.EndSize.y - 1; yAux++)
            {
                currentCell    = new Maze.Coord(endCoord.x + xAux, endCoord.y + yAux);
                auxCurrentCell = currentCell; auxNextCell = new Maze.Coord(currentCell.x, currentCell.y + 1);

                auxWall = Maze.GetWallBetween(auxCurrentCell, auxNextCell);
                if (auxWall != Maze.Wall.None)
                {
                    Maze.Cells[auxCurrentCell.x, auxCurrentCell.y].walls ^= auxWall;
                    Maze.Cells[auxNextCell.x, auxNextCell.y].walls       ^= Maze.GetOppositeWall(auxWall);
                }
            }
        }

        for (int xAux = 0; xAux < Maze.EndSize.x - 1; xAux++)
        {
            for (int yAux = 0; yAux < Maze.EndSize.y; yAux++)
            {
                currentCell    = new Maze.Coord(endCoord.x + xAux, endCoord.y + yAux);
                auxCurrentCell = currentCell; auxNextCell = new Maze.Coord(currentCell.x + 1, currentCell.y);

                auxWall = Maze.GetWallBetween(auxCurrentCell, auxNextCell);
                if (auxWall != Maze.Wall.None)
                {
                    Maze.Cells[auxCurrentCell.x, auxCurrentCell.y].walls ^= auxWall;
                    Maze.Cells[auxNextCell.x, auxNextCell.y].walls       ^= Maze.GetOppositeWall(auxWall);
                }
            }
        }
    }
Example #2
0
        public static void Generate(int width, int height)
        {
            int NumberOfCells,
                        NumberOfWalls,
                        NumberOfSets;
            int         i,
                        j,
                        z,
                        w;
            Cell[] cells;
            Wall[] walls;
            Room[] rooms;

            NumberOfCells = width * height;
            NumberOfWalls = ((width * (height - 1)) + (height * (width - 1)));
            NumberOfSets = NumberOfCells;

            cells = new Cell[NumberOfCells];
            walls = new Wall[NumberOfWalls];
            rooms = new Room[NumberOfSets];

            // Create each Cell with its default ID in the Cells array
            for (i = 0; i < NumberOfCells; i++)
            {
                cells[i] = new Cell(i);
                //debug
                // Console.WriteLine(cells[i]);
            }

            // Create each with its default ID in the Sets array
            for (i = 0; i < NumberOfSets; i++)
            {
                rooms[i] = new Room(i, NumberOfCells);
                rooms[i].Cells[0] = cells[i];
                // debug
                // Console.WriteLine(rooms[i]);
            }

            // Create each wall with its default ID in the walls array
            for (i = 0; i < NumberOfWalls; i++)
            {
                walls[i] = new Wall(i);
            }

            // Algorithm discovers if a wall is vertical
            // based on that each row starts by a multiple
            // of (width * 2) - 1
            for (i = 0; i < NumberOfWalls; i++)
            {
                if (i == 0 || (i % ((width * 2) - 1) == 0))
                {
                    for (j = 0; j < (width - 1); j++)
                    {
                        walls[i + j].isFloor = false;
                    }
                }
                // debug
                // Console.WriteLine(walls[i]);
            }

            // Now add two rooms to each wall
            // based on if it's a floor or not
            // need refactoring
            for (i = 0, z = 0, j = 0, w = width; i < NumberOfWalls; i++)
            {
                // Checks if it's a floor
                // and then, floor walls will begin
                // to increase from 0 and width
                // by 1 each time (width = 4 -> 0,4 (+1,+1) -> 1,5)
                if (walls[i].isFloor)
                {
                    walls[i].Cells[0] = cells[j];
                    walls[i].Cells[1] = cells[w];
                    // debug
                    // Console.WriteLine(walls[i] + " received " + j + " and " + w);
                    j++;
                    w++;
                }

                // And if it's not
                // it starts as 0 and 0+1
                // but on the beginning of it each new row
                // (multiple of width*2 -1)
                // it increases +1
                else
                {
                    if (i != 0 && (i % ((width * 2) - 1) == 0))
                    {
                        z++;
                    }
                    walls[i].Cells[0] = cells[z];
                    walls[i].Cells[1] = cells[z + 1];
                    // debug
                    // Console.WriteLine(walls[i] + " received " + z + " and " + (z + 1));
                    z++;
                }
            }

            for (i = 0; i < width; i++)
            {
                Console.Write(" " + "_");
            }

            foreach (Cell cell in cells)
            {
                if (cell.id % width == 0)
                {
                    Console.WriteLine(" ");
                    Console.Write("|");
                }
                if (cell.id > (width * (height - 1)) || cell.id == NumberOfCells - 1)
                {
                    Console.Write("_");
                }
                foreach (Wall wall in walls)
                {
                    if (wall.Contains(cell))
                    {
                        if (wall.isFloor)
                        {
                            Console.Write("_");
                        }
                        else
                        {
                            Console.Write("|");
                        }
                    }
                }
                //if (cell.id % width == 1)
                //{
                //    Console.Write("|");
                //}
            }
        }
Example #3
0
    public void ToggleWall(RaycastHit hit, bool insert)
    {
        var pillar1 = GetClosestPillar(hit.point);
        var pillar2 = GetClosestPillar(hit.point, pillar1);

        Vector3 bottomLeftPosition = new Vector3(Math.Min(pillar1.position.x, pillar2.position.x), 0, Math.Min(pillar1.position.z, pillar2.position.z));
        Vector3 topRightPosition   = new Vector3(Math.Max(pillar1.position.x, pillar2.position.x), 0, Math.Max(pillar1.position.z, pillar2.position.z));

        var distanceToWallCenter = Vector3.Distance(hit.point, (topRightPosition + bottomLeftPosition) / 2);

        if (distanceToWallCenter > distanceToWallThreshold)
        {
            return;
        }

        Maze.Coord bottomLeftCoord = new Maze.Coord(0, 0);
        bottomLeftCoord.x = (int)Math.Round((bottomLeftPosition.x) * Maze.MazeSize.x / (Camera.main.transform.position.x * 2));
        bottomLeftCoord.y = (int)Math.Round((bottomLeftPosition.z) * Maze.MazeSize.y / (Camera.main.transform.position.z * 2));

        Vector3 diffPillar = pillar2.position - pillar1.position;

        Maze.Coord c0   = null;
        Maze.Coord c1   = null;
        Maze.Wall  wall = Maze.Wall.None;

        // vertical wall
        if (diffPillar.x == 0 &&
            bottomLeftCoord.x > 0 && bottomLeftCoord.y >= 0 &&
            bottomLeftCoord.x < Maze.MazeSize.x && bottomLeftCoord.y < Maze.MazeSize.y)
        {
            c0 = new Maze.Coord(bottomLeftCoord.x - 1, bottomLeftCoord.y);
            c1 = new Maze.Coord(bottomLeftCoord.x, bottomLeftCoord.y);

            wall = Maze.Wall.East;
        }
        // horizontal wall
        else if (diffPillar.z == 0 &&
                 bottomLeftCoord.x >= 0 && bottomLeftCoord.y > 0 &&
                 bottomLeftCoord.x < Maze.MazeSize.x && bottomLeftCoord.y < Maze.MazeSize.y)
        {
            c0 = new Maze.Coord(bottomLeftCoord.x, bottomLeftCoord.y - 1);
            c1 = new Maze.Coord(bottomLeftCoord.x, bottomLeftCoord.y);

            wall = Maze.Wall.North;
        }

        if (c0 != null && c1 != null)
        {
            if (insert)
            {
                Maze.Cells[c0.x, c0.y].InsertWall(wall);
                Maze.Cells[c1.x, c1.y].InsertWall(Maze.GetOppositeWall(wall));
            }
            else
            {
                Maze.Cells[c0.x, c0.y].RemoveWall(wall);
                Maze.Cells[c1.x, c1.y].RemoveWall(Maze.GetOppositeWall(wall));
            }

            MazeSerializer.ResetMazeName();
            FindObjectOfType <MazeBuilder>().Render();
        }
    }