Esempio n. 1
0
    public static Coord[] GetEndCells()
    {
        var coords = new Maze.Coord[Maze.EndSize.x * Maze.EndSize.y];

        var endCoord = Maze.GetEndCoord();

        int i = 0;

        for (int xAux = 0; xAux < Maze.EndSize.x; xAux++)
        {
            for (int yAux = 0; yAux < Maze.EndSize.y; yAux++)
            {
                coords[i] = new Maze.Coord(endCoord.x + xAux, endCoord.y + yAux);
                i++;
            }
        }

        return(coords);
    }
Esempio n. 2
0
    public static Wall GetWallBetween(Maze.Coord currentCell, Maze.Coord nextCell)
    {
        Maze.Cell cellA = Maze.Cells[currentCell.x, currentCell.y];
        Maze.Cell cellB = Maze.Cells[nextCell.x, nextCell.y];

        if (cellA.x + 1 == cellB.x)
        {
            if (cellA.HasWall(Maze.Wall.East) && cellB.HasWall(Maze.Wall.West))
            {
                return(Maze.Wall.East);
            }
        }

        if (cellB.x + 1 == cellA.x)
        {
            if (cellA.HasWall(Maze.Wall.West) && cellB.HasWall(Maze.Wall.East))
            {
                return(Maze.Wall.West);
            }
        }

        if (cellA.y + 1 == cellB.y)
        {
            if (cellA.HasWall(Maze.Wall.North) && cellB.HasWall(Maze.Wall.South))
            {
                return(Maze.Wall.North);
            }
        }

        if (cellB.y + 1 == cellA.y)
        {
            if (cellA.HasWall(Maze.Wall.South) && cellB.HasWall(Maze.Wall.North))
            {
                return(Maze.Wall.South);
            }
        }

        return(Maze.Wall.None);
    }
Esempio n. 3
0
    Maze.Coord chooseUnvisitedNeighbor(Maze.Coord currentCell)
    {
        int x = currentCell.x;
        int y = currentCell.y;

        Maze.Coord[] candidates = new Maze.Coord[4];
        int          found      = 0;

        // left
        if (x > 0 && Maze.Cells[x - 1, y].visited == false)
        {
            candidates[found++] = new Maze.Coord(x - 1, y);
        }
        // right
        if (x < Maze.MazeSize.x - 1 && Maze.Cells[x + 1, y].visited == false)
        {
            candidates[found++] = new Maze.Coord(x + 1, y);
        }
        // down
        if (y > 0 && Maze.Cells[x, y - 1].visited == false)
        {
            candidates[found++] = new Maze.Coord(x, y - 1);
        }
        // up
        if (y < Maze.MazeSize.y - 1 && Maze.Cells[x, y + 1].visited == false)
        {
            candidates[found++] = new Maze.Coord(x, y + 1);
        }

        if (found == 0)
        {
            return(null);
        }

        // choose a random candidate
        int choice = (int)(UnityEngine.Random.Range(0f, 1f) * found);

        return(candidates[choice]);
    }
Esempio n. 4
0
    private void CalculateModifiedFloodFill(params Maze.Coord[] targetCells)
    {
        var currentStack = new Stack <Maze.Coord>();

        int columns = (int)Maze.MazeSize.x;
        int rows    = (int)Maze.MazeSize.y;

        currentStack.Push(new Maze.Coord(xPos, yPos));

        for (int y = 0; y < rows; y++)
        {
            for (int x = 0; x < columns; x++)
            {
                floodFill[x, x].queued = false;
            }
        }

        while (currentStack.Count > 0)
        {
            Maze.Coord coord = currentStack.Pop();
            int        neighborMinimumFloodValue = Int32.MaxValue;

            // left
            if (coord.x > 0 && !cells[coord.x, coord.y].HasWall(Maze.Wall.West))
            {
                neighborMinimumFloodValue = Math.Min(neighborMinimumFloodValue, floodFill[coord.x - 1, coord.y].value);
            }

            // right
            if (coord.x < columns - 1 && !cells[coord.x, coord.y].HasWall(Maze.Wall.East))
            {
                neighborMinimumFloodValue = Math.Min(neighborMinimumFloodValue, floodFill[coord.x + 1, coord.y].value);
            }

            // down
            if (coord.y > 0 && !cells[coord.x, coord.y].HasWall(Maze.Wall.South))
            {
                neighborMinimumFloodValue = Math.Min(neighborMinimumFloodValue, floodFill[coord.x, coord.y - 1].value);
            }

            // up
            if (coord.y < rows - 1 && !cells[coord.x, coord.y].HasWall(Maze.Wall.North))
            {
                neighborMinimumFloodValue = Math.Min(neighborMinimumFloodValue, floodFill[coord.x, coord.y + 1].value);
            }

            if (floodFill[xPos, yPos].value != neighborMinimumFloodValue + 1)
            {
                floodFill[xPos, yPos].value = neighborMinimumFloodValue + 1;
                floodFill[coord.x, coord.y].textMesh.text = "" + floodFill[coord.x, coord.y].value;

                // left
                if (coord.x > 0 && !floodFill[coord.x - 1, coord.y].queued && !cells[coord.x, coord.y].HasWall(Maze.Wall.West))
                {
                    currentStack.Push(new Maze.Coord(coord.x - 1, coord.y));
                    floodFill[coord.x - 1, coord.y].queued = true;
                }

                // right
                if (coord.x < columns - 1 && !floodFill[coord.x + 1, coord.y].queued && !cells[coord.x, coord.y].HasWall(Maze.Wall.East))
                {
                    currentStack.Push(new Maze.Coord(coord.x + 1, coord.y));
                    floodFill[coord.x + 1, coord.y].queued = true;
                }

                // down
                if (coord.y > 0 && !floodFill[coord.x, coord.y - 1].queued && !cells[coord.x, coord.y].HasWall(Maze.Wall.South))
                {
                    currentStack.Push(new Maze.Coord(coord.x, coord.y - 1));
                    floodFill[coord.x, coord.y - 1].queued = true;
                }

                // up
                if (coord.y < rows - 1 && !floodFill[coord.x, coord.y + 1].queued && !cells[coord.x, coord.y].HasWall(Maze.Wall.North))
                {
                    currentStack.Push(new Maze.Coord(coord.x, coord.y + 1));
                    floodFill[coord.x, coord.y + 1].queued = true;
                }
            }
        }
    }
Esempio n. 5
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);
                }
            }
        }
    }
Esempio n. 6
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();
        }
    }