Example #1
0
        protected override IEnumerator Generate()
        {
            links = linkGenerator.Generate(grid.rows, grid.cols);
            pick  = new List <MazeLink>(grid.cellCount);

            MazeCell current = RandomCell();

            AddLinks(current);
            SetFocus(current);
            yield return(OnYield(2));

            while (pick.Count > 0)
            {
                MazeLink link = PickLink();
                MazeCell from = grid[link.row + 1, link.col + 1];
                MazeCell to   = from.next[link.dir];

                if (from.isLocked || to.isLocked)
                {
                    current        = (from.isLocked) ? from : to;
                    from[link.dir] = true;
                    AddLinks(current);
                    SetFocus(current);
                    yield return(OnYield());
                }
            }

            SetComplete();
        }
        /* Construa uma SPANNING TREE com o nó raiz indicado    KRUSKAL ALGORIGHT/*
         * O algoritmo de Kruskal é um algoritmo de amplitude mínima que encontra uma borda com o menor peso possível que conecta quaisquer duas árvores na floresta.
         * É um algoritmo guloso na teoria dos grafos , pois encontra uma árvore geradora mínima para um grafo ponderado conectado, adicionando arcos de custo crescente em cada etapa.
         *  Isso significa que ele encontra um subconjunto das arestas que formam uma árvore que inclui todos os vértices , onde o peso total de todas as arestas da árvore é minimizado.
         *  Se o gráfico não estiver conectado, ele encontrará uma floresta de extensão mínima(uma árvore de abrangência mínima para cada componente conectado.
         * Esse algoritmo apareceu pela primeira vez em Proceedings ofthe American Mathematical Society, pp. 48-50 em 1956, e foi escrito por Joseph Kruskal.*/


        public static void FindSpanningTree(ref MazeNode root)
        {
            Random rand = new Random();


            // Defina o predecessor do nó raiz para que saibamos que ele está na árvore.
            root.Predecessor = root;


            List <MazeLink> links = new List <MazeLink>();


            foreach (MazeNode neighbor in root.Neighbors)
            {
                if (neighbor != null)
                {
                    links.Add(new MazeLink(root, neighbor));
                }
            }


            // Adiciona os outros nós à árvore.
            while (links.Count > 0)
            {
                // Escolha um link aleatório.
                int      link_num = rand.Next(0, links.Count);
                MazeLink link     = links[link_num];
                links.RemoveAt(link_num);


                // Adicione este link à árvore.
                MazeNode to_node = link.ToNode;
                link.ToNode.Predecessor = link.FromNode;


                // Remove quaisquer links da lista desse ponto
                for (int i = links.Count - 1; i >= 0; i--)
                {
                    if (links[i].ToNode.Predecessor != null)
                    {
                        links.RemoveAt(i);
                    }
                }


                // Adiciona os links do to_node à lista
                foreach (MazeNode neighbor in to_node.Neighbors)
                {
                    if ((neighbor != null) && (neighbor.Predecessor == null))
                    {
                        links.Add(new MazeLink(to_node, neighbor));
                    }
                }
            }
        }
Example #3
0
        protected MazeLink PickLink()
        {
            foreach (MazeLink link in pick)
            {
                link.weight += decay;
            }

            pick.Sort((a, b) => (a.weight.CompareTo(b.weight)));
            MazeLink result = pick[0];

            pick.RemoveAt(0);

            return(result);
        }
        private void Visit(MazeCell cell, bool[,] visited)
        {
            visited[cell.X, cell.Y] = true;

            while (true)
            {
                List <MazeLink> potentials = new List <MazeLink>(
                    from dir in Direction.Values
                    where cell[dir].OtherSide != null && !visited[cell[dir].OtherSide.X, cell[dir].OtherSide.Y]
                    orderby Guid.NewGuid()
                    select cell[dir]
                    );

                if (potentials.Count == 0)
                {
                    return;
                }

                MazeLink link = potentials[0];
                link.Wall = false;
                Visit(link.OtherSide, visited);
            }
        }
 void SetExit()
 {
     int x;
     int z;
     MazeNode.Direction d;
     if (Random.value >= .5f) {
         //Use Z Axis
         z = Random.Range(0, nodeHeight - 1);
         if (Random.value >= .5f) {
             //Left
             x = 0;
             d = MazeNode.Direction.left;
         }
         else {
             //Right
             x = nodeWidth - 1;
             d = MazeNode.Direction.right;
         }
     }
     else {
         //Use X Axis
         x = Random.Range(0, nodeWidth - 1);
         if (Random.value >= .5f) {
             //Top
             z = 0;
             d = MazeNode.Direction.up;
         }
         else {
             //Bottom
             z = nodeHeight - 1;
             d = MazeNode.Direction.down;
         }
     }
     exitNode = mazeNodes[x][z];
     exit = exitNode.links[MazeNode.DirectionToIndex(d)];
     startNode = mazeNodes[nodeWidth - 1 - x][nodeHeight - 1 - z];
     playerNode = startNode;
     if (debugColors) {
         exitNode.floorRenderer.material = debugGreen;
         exit.cubeRenderer.material = debugBlack;
         startNode.floorRenderer.material = debugWhite;
     }
 }
Example #6
0
 public void AddLink(Direction direction, MazeLink link)
 {
     links[DirectionToIndex(direction)] = link;
 }