Ejemplo n.º 1
0
 public NeighborCell(int x, int y, int z, CellEdge edge)
 {
     X          = x;
     Y          = y;
     Z          = z;
     SharedEdge = edge;
 }
Ejemplo n.º 2
0
        private void InitializeEdges()
        {
            //Initialize all edges
            for (int x = 0; x < mEdgesX.GetLength(0); x++)
            {
                for (int y = 0; y < mEdgesX.GetLength(1); y++)
                {
                    for (int z = 0; z < mEdgesX.GetLength(2); z++)
                    {
                        CellEdge e = new CellEdge(x, y, z, CellEdgeAlignment.X);
                        mEdges.Add(e);
                        mEdgesX[x, y, z] = e;
                    }
                }
            }

            for (int x = 0; x < mEdgesY.GetLength(0); x++)
            {
                for (int y = 0; y < mEdgesY.GetLength(1); y++)
                {
                    for (int z = 0; z < mEdgesY.GetLength(2); z++)
                    {
                        CellEdge e = new CellEdge(x, y, z, CellEdgeAlignment.Y);
                        mEdges.Add(e);
                        mEdgesY[x, y, z] = e;
                    }
                }
            }

            for (int x = 0; x < mEdgesZ.GetLength(0); x++)
            {
                for (int y = 0; y < mEdgesZ.GetLength(1); y++)
                {
                    for (int z = 0; z < mEdgesZ.GetLength(2); z++)
                    {
                        CellEdge e = new CellEdge(x, y, z, CellEdgeAlignment.Z);
                        mEdges.Add(e);
                        mEdgesZ[x, y, z] = e;
                    }
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Finds neighboring cells around a node which are not occupied by other nodes.
        /// </summary>
        /// <param name="grid">Cell grid</param>
        /// <param name="node">Node to search around</param>
        /// <param name="results">Vacant cells found</param>
        private void FindVacantNeighborCells(Node[,,] grid, Node node, List <NeighborCell> results)
        {
            //North edges
            if (node.PositionY > 0)
            {
                for (int i = node.PositionX; i < node.PositionX + node.Width; i++)
                {
                    CellEdge e = mEdgesY[i, node.PositionY - 1, node.PositionZ];
                    results.Add(new NeighborCell(i, node.PositionY - 1,
                                                 node.PositionZ, e));
                }
            }

            //South edges
            if (node.PositionY + node.Length - 1 < mEdgesY.GetLength(1))
            {
                for (int i = node.PositionX; i < node.PositionX + node.Width; i++)
                {
                    CellEdge e = mEdgesY[i, node.PositionY - 1 + node.Length, node.PositionZ];
                    results.Add(new NeighborCell(i, node.PositionY + node.Length,
                                                 node.PositionZ, e));
                }
            }

            //West edges
            if (node.PositionX > 0)
            {
                for (int i = node.PositionY; i < node.PositionY + node.Length; i++)
                {
                    CellEdge e = mEdgesX[node.PositionX - 1, i, node.PositionZ];
                    results.Add(new NeighborCell(node.PositionX - 1, i,
                                                 node.PositionZ, e));
                }
            }

            //East edges
            if (node.PositionX + node.Width - 1 < mEdgesX.GetLength(0))
            {
                for (int i = node.PositionY; i < node.PositionY + node.Length; i++)
                {
                    CellEdge e = mEdgesX[node.PositionX - 1 + node.Width, i, node.PositionZ];
                    results.Add(new NeighborCell(node.PositionX + node.Width, i,
                                                 node.PositionZ, e));
                }
            }

            //Down edges
            if (node.PositionZ > 0)
            {
                for (int ix = node.PositionX; ix < node.PositionX + node.Width; ix++)
                {
                    for (int iy = node.PositionY; iy < node.PositionY + node.Length; iy++)
                    {
                        CellEdge e = mEdgesZ[ix, iy, node.PositionZ - 1];
                        results.Add(new NeighborCell(ix, iy, node.PositionZ - 1, e));
                    }
                }
            }

            //Up edges
            if (node.PositionZ < mEdgesZ.GetLength(2))
            {
                for (int ix = node.PositionX; ix < node.PositionX + node.Width; ix++)
                {
                    for (int iy = node.PositionY; iy < node.PositionY + node.Length; iy++)
                    {
                        CellEdge e = mEdgesZ[ix, iy, node.PositionZ];
                        results.Add(new NeighborCell(ix, iy, node.PositionZ + 1, e));
                    }
                }
            }

            // Removed occupied cells
            for (int i = results.Count - 1; i >= 0; i--)
            {
                if (grid[results[i].X, results[i].Y, results[i].Z] != null)
                {
                    results.RemoveAt(i);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Generates a seeded randomized dungeon
        /// </summary>
        /// <param name="seed"></param>
        public void Generate(int seed)
        {
            mNodes = new List <Node>(Width * Length * Floors);
            mEdges = new List <CellEdge>(Width * Length * Floors * 3
                                         - Width - Length - Floors);
            InitializeEdges();

            Random rnd = new Random(seed);

            //Use this list for fetching walls along nodes and picking node walls at random
            List <CellEdge>     nodeWalls     = new List <CellEdge>();
            List <NeighborCell> neighborCells = new List <NeighborCell>();

            //Backtracking stack
            List <Node> nodeStack = new List <Node>();

            //Also, remember which 'cells' are occupied, and which node
            //Since a node can vary in size, it may occupy multiple cells
            Node[,,] nodeGrid = new Node[Width, Length, Floors];

            //Create start node
            Node startNode = new Node(rnd.Next(Width), rnd.Next(Length),
                                      rnd.Next(Floors), 1, 1);

            GetCellEdges(startNode, nodeWalls);
            SetEdges(nodeWalls, CellEdgeType.Unused, CellEdgeType.Wall);
            PlaceNodeOnGrid(nodeGrid, startNode);
            mNodes.Add(startNode);

            Node currentNode = startNode;
            bool mazeFilled  = false;

            while (!mazeFilled)
            {
                neighborCells.Clear();
                nodeWalls.Clear();
                FindVacantNeighborCells(nodeGrid, currentNode, neighborCells);

                if (neighborCells.Count > 0)
                {
                    //Pick an empty space
                    NeighborCell target = neighborCells[rnd.Next(neighborCells.Count)];

                    //...create an opening to this new space
                    CellEdge openEdge = target.SharedEdge;
                    openEdge.ConnectionType = CellEdgeType.Door;

                    //...and create another node on the other side
                    Node newNode = null;
                    while (newNode == null)
                    {
                        NodeConfiguration size = PickRandomNodeConfiguration(rnd);
                        newNode = TryNodePlacement(nodeGrid, rnd, target.X,
                                                   target.Y, target.Z, size.Width, size.Length);
                    }

                    GetCellEdges(newNode, nodeWalls);
                    SetEdges(nodeWalls, CellEdgeType.Unused, CellEdgeType.Wall);

                    //Move into the new room, push old room onto stack
                    nodeStack.Add(currentNode);
                    currentNode = newNode;
                }
                else
                {
                    //Else, pop back to previous room, and find new walls
                    if (nodeStack.Count > 0)
                    {
                        currentNode = nodeStack[nodeStack.Count - 1];
                        nodeStack.RemoveAt(nodeStack.Count - 1);
                    }
                    else
                    {
                        //If there are no new places to go to, the maze is filled
                        mazeFilled = true;
                    }
                }
            }
            Console.WriteLine("Created " + mNodes.Count + " node dungeon.");
        }