L-Systems , từ những gì tôi có thể nói *, là một tập hợp các quy tắc thay thế giống như ngữ pháp mà bạn có thể áp dụng đệ quy để có được kết quả "hữu cơ" thú vị.
Thực vật là nơi L-Systems thường được sử dụng, vì chúng cho thấy rất nhiều sự tăng trưởng đệ quy (tức là nhánh tách ra thành nhiều nhánh hơn). Ví dụ đơn giản, tôi sẽ hiển thị cây "kẹo mút" được tạo bằng Hệ thống L:
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)
Vì vậy, ở thế hệ 1, chúng ta chỉ có sự khởi đầu:
o
|
Ở thế hệ 2, chúng tôi tuân theo từng quy tắc và thay thế các phần hiện có theo quy tắc. Chúng tôi thay thế "quả bóng" bằng "hai gậy và bóng":
o o
\ /
|
Thế hệ 3:
o o o o
\| |/
\ /
|
Chẳng mấy chốc chúng ta sẽ có một cái cây to (crappy)!
Để thực hiện điều này trong mã, bạn có thể thực hiện điều này một cách đệ quy (ví dụ DFS), liên tục áp dụng các quy tắc trên cùng các phần cho đến khi bạn đạt được một kết thúc tùy ý hoặc bạn có thể thực hiện điều này lặp đi lặp lại (ví dụ BFS) như chúng ta đã làm trong ví dụ này , thực hiện một quy tắc "vượt qua" trên tất cả các yếu tố và lặp lại một số bước. Đó là:
Đệ quy:
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')
Lặp lại:
tree = start
for a number of iterations
for each part in tree
if part is 'o':
replace with 'o\/o'
Rất nhiều việc sử dụng L-Systems thực hiện bước "phát triển" bằng cách sử dụng phân ngành - nghĩa là các bộ phận tiếp tục nhỏ hơn khi chúng được "phát triển", các phần lớn hơn chỉ bị chia. Nếu không, hệ thống đang phát triển của bạn có thể bắt đầu chồng chéo lên nhau. Bạn sẽ thấy trong ví dụ về cây kẹo mút của mình, tôi đã bảo đảm một cách kỳ diệu hai nhánh không trùng nhau ở giữa bằng cách thay đổi hình dạng của các nhánh mới. Hãy làm ví dụ thành phố bằng cách sử dụng phân khu:
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)
Điều này sẽ có ý nghĩa trong một phút.
Thế hệ 1:
+--------------------+
| |
| |
| |
| V |
| |
| |
| |
+--------------------+
Một khối dọc đơn, nhàm chán. (Chữ V là viết tắt của dọc.)
Thế hệ 2: chúng tôi thay thế khối dọc bằng khối ngang bằng đường dọc ở giữa
+--------------------+
| r |
| r |
| r |
| H r H |
| r |
| r |
| r |
+--------------------+
Các r là viết tắt của đường! Tôi đã ngẫu nhiên tách ra, chúng tôi không muốn các phần thông thường nhàm chán trong PCG.
Thế hệ 3: chúng tôi thay thế các khối ngang bằng các khối dọc tách ra bằng các đường ngang. Những con đường hiện có ở lại; không có quy tắc cho họ.
+--------------------+
| V r |
| r |
|rrrrrrrr |
| r V |
| V r |
| rrrrrrrrrrrrr|
| r V |
+--------------------+
Chú ý cách các con đường kết nối với nhau, điều này thật tuyệt. Lặp lại đủ số lần này và bạn sẽ kết thúc với một cái gì đó như thế này (ngang nhiên gạt ra một câu trả lời liên quan ):
Lưu ý rằng có rất nhiều chi tiết tôi chưa đề cập và kết quả này trông "rõ ràng" được tạo ra - các thành phố thực sự trông hơi khác. Đó là những gì làm cho PCG vui / khó. Có vô số điều bạn có thể làm để điều chỉnh và cải thiện kết quả của mình, nhưng không liên quan đến L-Systems, tôi sẽ để lại câu trả lời này tại đây; hy vọng điều này sẽ giúp bạn bắt đầu.
* - Tôi chưa nghiên cứu chính thức về L-Systems, mặc dù tôi đã gặp các loại cụ thể như ngữ pháp và thảm thực vật PCG; vui lòng sửa cho tôi nếu tôi nhận được bất kỳ định nghĩa hoặc khái niệm sai