Acabei de iniciar um novo projeto no qual gostaria que o mundo do jogo consistisse em locais gerados processualmente, conectados por teleportadores. Depois de um pouco de pesquisa, descobri que isso é chamado de "teoria dos grafos" ou "muito complicado", dependendo de quem está discutindo. Infelizmente, encontrei muito pouca informação sobre a geração de gráficos; a maioria das ferramentas que vi são direcionadas para o exame de gráficos existentes.
Supondo que eu tenha a terminologia corretamente resolvida, meus requisitos são que o gráfico seja:
- simple - nenhum local (vértice) deve ter um teletransportador (borda) que se conecte de volta a si mesmo, nem dois vértices devem ter várias arestas conectando-os
- conectado - deve ser possível viajar entre dois vértices no gráfico (embora eu não preveja a necessidade de encontrar o caminho; basta saber que o jogador pode encontrar um, se preferir, é suficiente)
- cíclico - deve haver mais de um caminho entre dois vértices
- sem direção - todas as arestas podem ser percorridas em qualquer direção
- infinito - se o jogador desejar, ele poderá viajar indefinidamente, com o gráfico continuando a gerar incrementalmente à medida que se aproxima de
seusvértices inexploradosmais externos - localmente finito - o grau de um vértice nunca deve mudar depois que o jogador o visita
- rotulado de forma estável - cada vértice representa um local que será gerado proceduralmente a partir de uma semente; a mesma semente deve ser atribuída a um vértice, independentemente do caminho que o jogador percorreu até lá ou do tamanho do gráfico ao percorrer
Eu tive algumas idéias (que ainda não tentei implementar) sobre o uso dos máximos locais do ruído perlin 2D como vértices (a entrada x e y poderiam então ser usados como seu rótulo), mas isso parece desajeitado e complicado demais.
Existe uma maneira melhor de gerar um gráfico como este? Estou desenvolvendo no Python 2.6 usando o Panda3D e o numpy e, é claro, gostaria de incluir outras bibliotecas se elas ajudarem com esse problema!
Editar
Acho que fiz um péssimo trabalho explicando alguns dos meus requisitos, então é hora da ilustração! Felizmente, isso vai esclarecer as coisas.
O que quero dizer com rótulos estáveis é que eu quero, por exemplo, que o Jogador A seja capaz de explorar e encontrar, entre outras coisas, um caminho cíclico de volta ao local inicial e uma montanha que parece um gato. Seu jogo agora se parece com o seguinte (os vértices são numerados com suas sementes e arestas com a ordem em que o jogador os atravessou). Ele começou no vértice 8329 (verde) e a Happycat Mountain está no vértice 6745 (azul).
O bom amigo do jogador A, jogador B, é um fã de gatos, então ele quer mostrar a ela. Ele dá a ela a raiz do seu mundo e direções ao longo do caminho mais curto para a montanha de interesse. O jogo dela agora deve ficar assim:
O problema com o qual estou tendo mais dificuldade atualmente é "Como eu gero as mesmas sementes para o Jogador B quando a exploração dela não segue o mesmo caminho?" Foi isso que me levou à ideia de usar o ruído Perlin - desde que a mesma semente de raiz seja usada, o máximo não se moverá, então suas coordenadas poderão ser usadas como sementes de vértice estáveis.
fonte
Respostas:
Você não pode criar um gráfico infinito. Sua memória é finita, portanto, o número de vértices e arestas também é finito. O que você pode fazer é criar um gráfico finito e depois adicionar mais. Você parece ter percebido isso, mas acho importante que seja explicitamente declarado para que você não siga um caminho sem saída.
Você deve ter muito cuidado ao falar sobre "vértices mais externos". Um gráfico é um conjunto de vértices, um conjunto de arestas e uma função que relaciona os dois. Não há interpretação geométrica definida, a menos que você aplique uma. Por exemplo: ambas as imagens mostram exatamente o mesmo gráfico. Na primeira imagem, o vértice 2 poderia ser considerado um vértice "mais externo", mas na segunda imagem o vértice 2 não seria considerado "mais externo". Se você considerasse três dimensões, poderia dizer que todos os vértices são "ultraperiféricos".
Isso significa que você deve ter outras informações para poder saber o que é um vértice "externo". Você pode usar pares (x, y), pois isso lhe dará uma representação geométrica fácil de visualizar, no entanto, acho que você não precisa ir tão longe. Pelo que você diz, tudo que você precisa saber é quais vértices já estão no gráfico.
Se você executou isso toda vez que visitou um vértice:
seu gráfico atenderia a todos os seus requisitos, exceto por ser cíclico. Não sei se você realmente precisa de uma garantia. Se você o fizer, poderá selecionar especificamente um nó não visitado e estabelecer uma conexão, o que garantiria um caminho entre o nó atual e um nó já visitado, pois todos os nós não visitados estão conectados a pelo menos um nó visitado e desde que você tenha visitado um nó visitado para chegar onde você está, agora existem pelo menos dois caminhos.
É simples porque existe uma verificação explícita, conectada porque todos os novos nós obtêm pelo menos uma conexão, localmente finita, porque as arestas são adicionadas apenas antes da sua visita ou na sua primeira visita e apenas para os nós não visitados. Tecnicamente, não é direcionado, mas funcionalmente é o mesmo que você cria uma aresta direcional nas duas direções. Você pode rotular o nó como quiser, eu uso o número aleatório gerado, mas você pode adicionar outros parâmetros ao construtor, sendo um deles sua semente.
fonte
Um método:
Eu deixei muitos detalhes de fora, mas isso deve capturar a ideia geral. Convém manter os vizinhos na memória que estão mais afastados do local atual, dependendo da distância do mundo entre os portais, a quantidade de memória disponível etc.
fonte