Witam.
Piszę małą gierkę i muszę wygenerować planszę do rozgrywki.
Plansza ma się składać z (również losowo wygenerowanych), sąsiadujących ze sobą (stykających się brzegami przynajmniej w 1 punkcie) pól, o różnym kształcie i różnej wielkości. Podstawowym budulcem każdego takiego pola, ma być "cegiełka" w postaci sześciokąta (hexa). Przykład graficzny:
Problem mam taki, że nie bardzo mam pomysł na jakiś sensowny algorytm generujący takie pola. Na obecną chwilę robię coś takiego:
- Tworzę sobie tablicę dwuwymiarową, w której przechowuję siatkę hexów (tablica zawiera współrzędne wszystkich 6 wierzchołków każdego sześciokąta).
- Wybieram sobie dany hex w tej siatce - np. [X = 5, Y = 5] i sprawdzam z jakimi sześciokątami sąsiaduje
- Sprawdzam które z sąsiadujących hexów są dla mnie atrakcyjne, czyli nie zostały już przyporządkowane do innego pola. Jeżeli zostały, wyrzucam je z puli.
- Po dokonaniu powyższej selekcji, losuję z puli sąsiadów któryś z pozostałych sześciokątów.
- Przeskakuję na hexa którego właśnie wylosowałem, włączam go do pola i rozpoczynam algorytm od nowa (rozpoczynając od tego właśnie hexa).
- Powyższe czynności powtarzam określoną ilość razy (np. 20, gdy chcę aby pole składało się z 20 hexów).
Niestety przy tak skonstruowanym algorytmie często dochodziło do sytuacji, gdy swoisty "wężyk" zaganiał się w kozi róg, dochodząc do sześciokąta, który nie miał już wolnych, nadających się do "wchłonięcia" sąsiadów, na których można by przeskoczyć (wywalało błąd).
Dodałem więc modyfikację:
Gdy algorytm dojdzie do sytuacji, w której brak jest wolnych sąsiadów (a nadal musi powtórzyć operację jeszcze określoną ilość razy), cofa się o 1 sześciokąt i próbuje ponownie. W razie porażki (nadal nie ma wolnych sąsiadów) znowu cofa się o 1 hexa, próbuje i tak aż do skutku.
Problem teoretycznie został rozwiązany, choć oczywiście jest to rozwiązanie bardzo "chałupnicze" i mało wydajne.
Pozostaje też drugi problem - koncentracja hexów. Zdając się na zupełną losowość, zbyt często dochodzi do sytuacji gdy sklecone z sześciokątów pole ma strasznie nieregularny kształt (jest zbyt szerokie, wąskie, za bardzo rozciągnięte, wężykowate, ma w środku dziury itd).
Dodałem więc coś na kształt priorytetów. Działa to tak, że algorytm losując np. ruch w prawo (przeskakując na sąsiada po prawej), automatycznie obniża priorytet dla ruchu wprawo i podnosi priorytet dla ruchu w lewo, dół i górę. Dzięki temu po np. 4 następujących po sobie ruchach w prawo, szansa na wykonanie piątego ruchu w prawo wynosi już tylko 0.6, natomiast dla pozostałych kierunków jest to 1.4 (modyfikator 0.1).
Trochę to pomogło ale nadal efekt nie jest zbyt dobry (nadal powstają dziwne potworki).
Doszedłem też do wniosku, że generując pola w ten sposób, będę miał zbyt duży problem w ich regularnym sąsiedztwie. To znaczy pola nie będą się ładnie i równo stykać krawędziami i będą miały jedynie (w najlepszym razie) kilka sąsiadujących ze sobą sześciokątów.
Szczerze mówiąc nie mam już pomysłu na modyfikację mojego pierwotnego pomysłu, dlatego zwracam się z prośbą o podsunięcie jakiejś koncepcji. Nie pytam o gotowy kod tylko o pomoc w skleceniu bardziej wydajnego algorytmu. Mile widziana byłaby możliwość kontroli wielkości pola (minimalna i maksymalna szerokość oraz wysokość).
Preferowany język programowania : Delphi