algoritmi clasice pentru generarea de labirinturi
- cum ar fi Forbes, doar mai bine.

prefață
Scrierea de articole mi spodviglo lipsa aproape completă a materialelor în limba rusă despre algoritmi pentru generarea de labirinturi. Habré, din faptul că, în general, este, putem nota două articole: unul și doi. Valoarea și beneficiile care are doar două. Prima - o traducere a algoritmului formal și o explicație mică a acestora. Ceea ce, desigur, este bun, dar foarte slab și nu a cauzat dorința de a explora subiectul în continuare.
Voi da un sfat - nu te uita la codul, atâta timp cât nu scrie realizarea ta. Ai atât de mult mai multă plăcere și să beneficieze de remedieri de erori și depanare, decât în cazul în care tocmai ați traduce dintr-o limbă în alta.
Serios. Ascultați sfatul. Tu, probabil, petrece mai mult timp, dar merită în valoare. Eu, de exemplu, din cauza erorilor pereche aparut generator de texte foarte amuzant „străin“, care pot fi utilizate în diverse jocuri Sci-Fi pentru a crea text. Sper să înveți subiectul pentru ei înșiși și nu se grăbesc.
Voi folosi termenul „compensate“, sugerând părtinire engleză. Ie dependent de modelul de algoritm în orice direcție. De exemplu, dreptul de schimbare - labirinturi algoritm genereaza culoarele lungi drepte.
Colorarea labirinturi are loc în raport cu distanța de la colțul îndepărtat din stânga al câmpului la unele celule. Mai departe de poziția inițială - mai închisă culoarea.
Perfect labirint - un labirint în care o celulă este conectat la o alta printr-o singură. Cu alte cuvinte, un arbore de acoperire.
Când am început să sape în tema labirint, am avut nici o idee că, în cele din urmă va fi scris un articol și a ales limba în care am posibilitatea de a nu-și petreacă prea mult timp de redare și de arhitectură și să se ocupe exclusiv cu logica. Ca rezultat, între C ++ și Lua, alegerea a căzut pe Lua și Love2D.
Nu vă faceți griji dacă nu sunteți familiarizat cu Lua. Ignorarea limbii nu strică să înțeleagă punerea în aplicare, din cauza simplitatea sintaxei. Dacă cel puțin un pic mai știu cum să program, 80% din codul nu va cauza probleme cu înțelegere. Restul de 20% - limbaj specific, despre care voi scrie mereu primul articol, explicând munca lor.
Primul lucru pe care ar trebui să spun:
Lua are doar o singură structură de date - un tabel - un tablou asociativ, cu care am creat structura necesară. De exemplu, clase, seturi, tablouri convenționale, stive, cozi, și altele asemenea. Consultați le putem fie folosind litere mici-chei, sau prin utilizarea de indici.
În mod similar, nu ne limităm masa stocate într-un singur tip de date într-un singur obiect și funcționează ca structuri în C / C ++. Acest cod este absolut corect:
Atribuirea zero elimina domeniu:
în al doilea rând:
Lua nu are nici un mecanism ascuns de tabele de copiere. Codul de mai jos nu va copia și de a crea un nou SomeNewArray obiect, numai copii o referință la SomeArray obiect, și, prin urmare, se va schimba în același mod ca și dacă treci o valoare printr-o referință non-const sau pointer în C / C ++:
Binar copac Algoritmul


Prima și cea mai simplă algoritm pentru a înțelege că voi lua în considerare. Esența ei este de a deschide calea într-o direcție aleatoare din fiecare domeniu de celule: în punerea în aplicare mea sau în sus, sau la dreapta (în funcție de excentricități de tine). Noi procesa doar 1 celulă per unitate de timp, prin urmare, putem genera un labirint de dimensiune infinit, păstrând doar rezultatul final (labirintul) fără a fi nevoie de a stoca orice informație parte.
O astfel de metodă de generare a două efecte secundare:
1. labirinturi au o prejudecată diagonală puternică și lipsa de impasuri în direcția lui. Uită-te la capturi de ecran de mai sus și veți vedea că fiecare dintre coridoare se angajează în dreapta sus al celulei, și, ca urmare, are un mod unic de a-l, și nicăieri pe drum nu există nici un impas:
2. Două coridor gol de pe fiecare parte a labirint. Când algoritmul „dig“ până la sfârșitul rândului / coloanei, el nu are nici o alegere, ci să continue calea într-o singură direcție, creând un gol „limită“.
Apropo, numele nu este la fel ca și structura de date. Rezultatul muncii sale - arbore binar aleator, în care fiecare dintre celule (de sus), există exact o cale spre rădăcină (nodul părinte), și, prin urmare, exact o cale către orice altă celulă. Ca urmare, orice celulă nu este mai mult de 3 conexiuni cu vecinii săi.
Algoritmul formal (pentru partea de nord-est de deplasare):
- Alegeți o celulă inițială;
- Selectați o direcție aleatoare pentru deschizând calea. Dacă celulele învecinate, în acest domeniu, dincolo de limita câmpului, am săpa o celulă în singura direcție posibilă;
- Du-te la celula următoare;
- Se repetă 2-3 până atunci, până când toate celulele au fost prelucrate;
Verde - curent considerate celule, roșii - celule din față, în care relochează.
Începând cu coordonatele (0, 0). Top în această serie nu poate merge, pentru că altfel vin din labirintul graniței. Du-te până la oprire, pe drum luând în jos toate zidurile.


Toate impas. Nicăieri pentru a merge. Ne trece la rândul următor și a vedea că este posibil acum să mergem sus și spre dreapta.

Am arunca o monedă și selectați ... Top. Scoateți perete și du-te la celula următoare.

Excelent. Cazul ne spune să meargă la dreapta. Scoateți perete și pentru a muta la celula următoare.



Nu avem de ales, stânga nu poate merge, atunci vom elimina peretele de la partea de sus și du-te la rândul următor.


Moneda ne convinge spre dreapta. Ei bine, ascultă. Scoateți perete și du-te la celula sleuduyuschey.


Ride metru, piesa noastră nefericită din metal cade și spune că era timpul să meargă la etaj. Demolarea zidului, pasul spre cușca următoare, și, deoarece este extrem în acest rând, eliminați peretele superior. Maze terminat.



Pro:
- O implementare simplă;
- Viteza mare;
- Capacitatea de a genera un labirint fără sfârșit;
contra:
- model de complexitate redusă;
- schimbare puternică în diagonală;
- Lipsa deadlocks asupra deplasării;
- Monotonie generat labirinturi;
«Sidewinder» Algoritmul


Algoritmul nume intraductibil Sidewinder pentru munca sa este foarte similar cu algoritmul unui arbore binar, în contrast, că nu are caracteristica de compensare în diagonală, una coridoare și celule goale, noi nu considerăm separat, și seturi. Labirinturi obținute cu predominant verticale sau orizontale de compensare (în funcție de implementare), cu absența impasuri în direcția lor. În comparație cu colegii ei mai primitiv, diferența nu este atât de vizibil și mai mult ca o „spirala“, care înlocuiește treptat coridoarele verticale și orizontale.
În ceea ce privește efectele secundare, The Sidewinder creează un singur coridor gol pe o parte în loc de două. De la crearea seturilor din primul rând al câmpului, nu avem posibilitatea de a săpa o cale spre partea de sus, așa cum suntem în poziția verticală cea mai extremă și să încerce să meargă mai sus conduc la ieșirea limitelor. Dar dacă organizăm seturi, fără a părăsi verticală, vom crea câteva zone izolate unele de altele.
Pentru Exemplul 9 primul rând de celule pot fi împărțite în trei seturi, care sunt amplasate între pereți. Fiecare set de-al doilea rând se va săpa o cale la una dintre cele trei „blocuri“ de mai sus. Al treilea rând ar deschide calea către „blocuri“ de-al doilea. Și așa mai departe, până la sfârșitul câmpului. Ca rezultat, vom transforma 3 ramificat izolate unul față de celălalt câmp vertical, care nu este potrivit pentru un labirint perfect, în care fiecare dintre punctele de câmp are exact o cale spre oricare alta.
Algoritmul formal (pentru standardul de offset):
- Selectați un număr inițial;
- Selectați linia celulară inițială și să-l curent;
- Inițializare un set gol;
- Adăugați celula curentă din set;
- Decideți dacă pentru a deschide calea spre dreapta;
- Dacă netezit, apoi trece la o nouă celulă și să-l curent. Repetați pașii 3-6;
- Dacă nu pavate, vom selecta un set aleator de celule și deschizând drumul spre partea de sus de acolo. Mergem la rândul următor și se repetă 2-7;
- Continuați până când fiecare rând vor fi prelucrate;
Celulele rosii - o multitudine de elemente.
Noi pornim de la primul rând și să vedem că deasupra noastră - în afara limitelor. Demolarea zidurilor și du-te direct la al doilea rând, de a crea un set de gol.


Deci, și aici interesant. Să adăugăm la setul primelor două serii de celule.

Alegeți una dintre aceste celule și elimina legate de acestea un perete superior, în primul rând.

set Null, adăugați-l pe rândul de celule următoare.

De data aceasta, cu nimeni care să combine, doar deschizând calea spre dreapta sus a acestei singure celule.

Repetăm acțiunile noastre. Set Null, muta la celula următoare, adauga ... Și ea a fost ultimul din serie, apoi scoateți doar partea de sus a peretelui și du-te la numărul de mai jos.


Acum, combina doar primele trei celule într-un singur set.

Aleatoriu selectați celula, în acest caz, al doilea perete și îndepărtați partea superioară a rândului precedent.

Ei bine, aici, din nou, nu avem de ales, scoateți partea superioară a peretelui și du-te la numărul de mai jos.


În acest moment, cele mai multe celule Pervan vom face doar unul. Scoateți peretele de la rândul anterior, și trece la celula următoare.


Să presupunem că ne-am dorit să combine cele trei în celulele de capăt.

Din nou, a atras o medie dintr-o multitudine de celule din care peretele și îndepărtați sus. Tot labirint nostru este gata.

- Capacitatea de a genera un labirint fără sfârșit;
- Doar un singur coridor gol;
- O imagine mai complexă, în contrast cu algoritmul arborelui binar;
contra:
- O implementare mai complicată;
- Lipsa deadlocks asupra deplasării;
- deplasare verticală puternică;