Les L-Systems , d'après ce que je peux dire *, sont un ensemble de règles de substitution de type grammatical que vous pouvez appliquer récursivement pour obtenir des résultats «organiques» intéressants.
Les plantes sont les endroits où les L-Systems sont souvent utilisés, car ils montrent beaucoup de croissance récursive (c'est-à-dire que les branches se divisent en plusieurs branches). Pour un exemple simple, je vais montrer un arbre "sucette" généré à l'aide d'un L-System:
variables : | o (these are the things that will grow)
start : o
| (this is what we start with)
rules : (o → o o) (these are the substitution rules that we apply
\ / one step at a time)
Donc à la génération 1, nous avons juste le début:
o
|
À la génération 2, nous suivons chacune des règles et substituons les parties existantes selon les règles. Nous remplaçons les «balles» par «deux bâtons et balles»:
o o
\ /
|
Génération 3:
o o o o
\| |/
\ /
|
Bientôt, nous aurons un joli grand arbre (merde)!
Pour ce faire dans le code, vous pouvez le faire récursivement (c'est-à-dire DFS), en appliquant continuellement les règles sur les mêmes parties jusqu'à ce que vous atteigniez une fin arbitraire, ou vous pouvez le faire de manière itérative (c'est-à-dire BFS) comme nous l'avons fait dans cet exemple , en exécutant une règle "passer" sur tous les éléments et en répétant un certain nombre d'étapes. C'est:
Récursivement:
tree = start
grow(tree, start)
func grow(tree, part)
if this part of the tree is big enough
stop
if part is 'o'
replace part with 'o\/o'
grow(tree, the left 'o')
grow(tree, the right 'o')
Itérativement:
tree = start
for a number of iterations
for each part in tree
if part is 'o':
replace with 'o\/o'
Un grand nombre d'utilisations des L-Systems effectuent l'étape de «croissance» en utilisant la subdivision - c'est-à-dire que les pièces deviennent de plus en plus petites au fur et à mesure qu'elles sont «cultivées», les plus grosses pièces sont simplement divisées. Sinon, votre système en croissance peut commencer à se chevaucher sur lui-même. Vous verrez dans mon exemple d'arbre à sucettes, j'ai magiquement veillé à ce que les deux branches ne se chevauchent pas au milieu en changeant la forme des nouvelles branches. Faisons l' exemple de la ville en utilisant la subdivision:
variables: block_vertical block_horizontal road_vertical road_horizontal
start: block_vertical
rules: (block_vertical → block_horizontal road_vertical block_horizontal)
(block_horizontal → block_vertical road_horizontal block_vertical)
Cela aura du sens dans une minute.
Génération 1:
+--------------------+
| |
| |
| |
| V |
| |
| |
| |
+--------------------+
Un seul bloc vertical ennuyeux. (Le V signifie vertical.)
Génération 2: nous remplaçons le bloc vertical par des blocs horizontaux avec une route verticale au milieu
+--------------------+
| r |
| r |
| r |
| H r H |
| r |
| r |
| r |
+--------------------+
Le r signifie route! J'ai espacé aléatoirement la séparation, nous ne voulons pas de parties régulières ennuyeuses dans PCG.
Génération 3: nous remplaçons les blocs horizontaux par des blocs verticaux séparés par des routes horizontales. Les routes existantes restent; il n'y a pas de règles pour eux.
+--------------------+
| V r |
| r |
|rrrrrrrr |
| r V |
| V r |
| rrrrrrrrrrrrr|
| r V |
+--------------------+
Remarquez comment les routes se connectent entre elles, ce qui est bien. Répétez cela suffisamment de fois et vous vous retrouverez avec quelque chose comme ça (arraché ouvertement une réponse connexe ):
Notez qu'il y a beaucoup de détails que je n'ai pas couverts, et que ce résultat semble généré "évidemment" - les vraies villes semblent quelque peu différentes. C'est ce qui rend PCG amusant / difficile. Il y a d'innombrables choses que vous pouvez faire pour modifier et améliorer vos résultats, mais n'étant pas lié aux L-Systems, je laisse cette réponse ici; j'espère que cela vous aidera à démarrer.
* - Je n'ai pas étudié les L-Systems de manière formelle, bien que j'aie rencontré des types spécifiques comme les grammaires et la végétation PCG; veuillez me corriger si je me trompe de définitions ou de concepts