3d labyrint

Tags:    c++

Her er et lille stykke kode jeg har skrevet, det er naturligvis lang fra færdigt, men jeg har et par spørgsmål til hvordan det kan gøres, har nogle problemer der mangler løsninger osv.

Fold kodeboks ind/udKode 

1)
Jeg har lavet en struct 'cell' med 4 boole variabler der hver fylder én bit, altså 4 bit total pr celle, nu forholder det sig sådan at selvom jeg reelt kun har brug for en halv byte pr celle, bruger den 1 byte. Om den bruger 8 eller 16 MB for en sådan 256^3 struktur, gør ikke den helt store forskel, men jeg kunne godt tænkte mig at få løst problemet alligevel hvis det kan lade sig gøre.

2)
I 'new_grid()' tildeler den værdier (0 eller 1) til til alle xy/xz/yz variablerne i cellerne. disse xy/xz/yz skal forstås som vægge i en 3d_labyrint; hvis værdien er 0 er der ingen væg og er den 1 er der en væg.
Det første problem er naturligvis at jeg har brug for en 'ikke pseudo' rand_bit(), men der er et lille problem, her på test stadiet fungerer denne fint nok.
Nu kommr den lumske del
Hver celle har 6 vægge. 3 af disse vægge er defineret i cellen, og de resterende vægge er defineret af de omkring liggende celler.
dvs.
celle xyz har væggene:
GRID[x][y][z].xy
GRID[x][y][z].xz
GRID[x][y][z].yz
GRID[x][y][z-1].xy
GRID[x][y-1][z].xz
GRID[x-1][y][z].yz

strukturen er uendelig/endelig hvilket vil sige hvis man skulle være så uheldig at befinde sig i 257,257,257, befinder man sig i hvirkeligheden i 1,1,1.
det er lidt kringle, men det virker.

Problemet består i at disse celler skal opfylde nogle krav:
De må ikke være lukkede, dvs. der skal være mindst én manglende væg pr celle.
Det skal være muligt at bevæge sig fra en given celle til en anden, uanset placering.

Dette er noget jeg grubler over.

3)
Jeg ønsker at høre en masse gpde idéer til forbedringer o.lign.
Jeg ønsker at høre om fejl og mangler.
Jeg ønsker en interessant diskution om hvorledes man kan/bør løse dette problem, det stykke kode jeg har postet er kun et oplæg, det kan meget vel gøres smartere.

4)
Jeg kan forestille mig at der måske er nogle der grubler over hvad meningen med galskaben er og det er jo naturligvis meningen at der skal skrives et grafisk interface med tiden og derefter kan jeg se adskillige muligheder for hvad det kan bruges til.

5)
I skal vide at jeg er nubegynder og faktisk ikke har været i gang i meget over en uge, jeg har dog lavet en del php scripts osv. men altså stadig en c++ n00b ;-)
Jeg er klar over at meget af dette ville tage sig rigtig godt ud i classes, men jeg har aldrig brug dem før og selv om jeg er igang med at læse på sagen, bliver jeg blot mere og mere forviret...

[Redigeret d. 08/02-06 17:12:02 af Felix Nielsen]



41 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 4 karma
Sorter efter stemmer Sorter efter dato
Hvis kompileren overholder standarden må den kun bruge en bit pr bool.
Hvorfor skulle man undgå vector<bool>



Hvis kompileren overholder standarden må den kun bruge en bit pr bool.
Hvorfor skulle man undgå vector<bool>


Jeg har ingen idé, men her er et link der skulle forklare det http://groups.google.dk/group/alt.comp.lang.learn.c-c++/browse_thread/thread/a815206314e44327/1dcb8cb7d76ca247?lnk=st&q=vector%3Cbool%3E&rnum=4&hl=da#1dcb8cb7d76ca247



Så vidt jeg lige kan se gælder de samme forbehold en bit_set.



Så vidt jeg lige kan se gælder de samme forbehold en bit_set.

ok, så er det jo ihvertfald ikke et problem ;-)



fylder ca. 200 MB og tager utrolig lang tid at initialisere.
Fold kodeboks ind/udKode 

Allerede brugte konfiguration fylder kun 16 MB og tager næsten ingen tid at initialisere.
Fold kodeboks ind/udKode 

Man kan jo bruge samme metode med array istedet for vector. Det fylder som udganspunkt næsten eller slet ingen ting, men så snart der bliver puttet data deri, fylder den nogenlunde som ovenstående, måske lidt mere.
Fold kodeboks ind/udKode 

Bitset virker som det skal og fylder hvad det skal, men konfigurationen giver et crash, jeg tror ganske enkelt ikke at bitset er beregnet til så store størrelser.
Fold kodeboks ind/udKode 

Jeg ved ikke om det er muligt at lave en 'smart' struktur ved hjælp af 'struct', eller hvor godt det i givet fald vil virke, men jeg ved at der skal en hed del tastearbejde til hvis man skal bruge min fremgangsmåde ;-)
Nedenstående konfiguration virker, den er meget bøvlet og ikke brugbar for mig i denne form, ej heller ved jeg om den løser problemmet. Nedenstående burde kun fylde 32 byte, men det er så lidt at det ikke rigtigt giver udslag i joblisten.
Fold kodeboks ind/udKode 

bit_vector skulle i bund og grund være det samme som vector<bool>, det har dog ikke været mig muligt at teste det da jeg ikke har kunnet regne ud hvordan man laver en multidimesional konstruktion.
deque, virker på nogenlunde samme niveau som vector.

Jeg kender ikke til flere metoder på nuværende tidspunkt men er igang med at læse på sagen.



Jeg kender ikke til flere metoder på nuværende tidspunkt men er igang med at læse på sagen.


Da du jo ved at konstruktionen er den samme hver gang, det er altid en 3d array med elementer af 4 bits, kunne du lave en hjemmelavet container der gemmer data så kompakt som muligt.

Hvis vi for eksemplets skyld laver labyrinten med fast størrelse har vi brug for:

unsigned char Labyrint[256*256*256/2];

Hvis vi så skal have celle [2][3][4] kunne vi hente denne med:
Labyrint[(2*256*256* + 3*256 + 4)/2] & 0x0F
Celle 6, 8, 9 ville være:
(Labyrint[(6*256*256* + 8*256 + 9)/2] >> 4) & 0x0F

Man kunne så putte dette ind i en class og lave nogle simple funktioner til at hente yz, xz, xy og ac.
Hvis du sørger for at det hele er inline vil jeg mene at det burde være lige så effiktivt som diverse std::containere.

Hvilken compiler bruger du?



Jeg kender ikke til flere metoder på nuværende tidspunkt men er igang med at læse på sagen.


Da du jo ved at konstruktionen er den samme hver gang, det er altid en 3d array med elementer af 4 bits, kunne du lave en hjemmelavet container der gemmer data så kompakt som muligt.

Hvis vi for eksemplets skyld laver labyrinten med fast størrelse har vi brug for:

unsigned char Labyrint[256*256*256/2];

Hvis vi så skal have celle [2][3][4] kunne vi hente denne med:
Labyrint[(2*256*256* + 3*256 + 4)/2] & 0x0F
Celle 6, 8, 9 ville være:
(Labyrint[(6*256*256* + 8*256 + 9)/2] >> 4) & 0x0F

Man kunne så putte dette ind i en class og lave nogle simple funktioner til at hente yz, xz, xy og ac.
Hvis du sørger for at det hele er inline vil jeg mene at det burde være lige så effiktivt som diverse std::containere.

Hvilken compiler bruger du?

Din ide lyder meget spændene men også meget inviklet (for mit vedkommende)
Jeg bruger "Bloodshed dev-c++" hvorfor?



Din ide lyder meget spændene men også meget inviklet (for mit vedkommende)
Jeg bruger "Bloodshed dev-c++" hvorfor?


Det bør ikke være specielt besværligt.

Jeg fik det indtryk at nogle af de problemer du havde skyldes at du brugte en ikke så god compiler. Men mingw/gcc burde være ok.



Jeg har lavet lidt tilføjelser til new_grid()
Fold kodeboks ind/udKode 


Den sidste tilføjelse "no closed rows/colums) er på ingen måde nødvendig ved store grids ala 256^3, men ved mindre grids, mener jeg at den kan være en godt tilføjelse.
En del af koden er meget rodet, men jeg kunne ikke lige finde på en smartere måde, så hvis der er nogen der har idéer til hvorledes det kan skrives anderledes lytter jeg ører.
Endvidere løsere dette tiltag ikke problemmet med at det skal være muligt at komme fra en given celle til en anden, men jeg mener at det er et skridt på vejen, ihvert fald i mindre grids.



Ja, så lykkedes det mig at få lavet en container ting der virker:
Header tingeltangel:
Fold kodeboks ind/udKode 

Funktionen write():
Fold kodeboks ind/udKode 

Funktionen read():
Fold kodeboks ind/udKode 


Jeg bruger char istedet for unsigned char, rent teknisk betyder det at den laver en fejl med hensyn til placeringen af bit'en, det gør dog ikke noget da den laver nøjagtigt samme fejl når den læser og skriver og at bit'ende ikke intefererer med hinanden.
Så kan man jo lige så godt spare de 9 tasketryk ;-)

Hvis nogen kan komme med forbedringer, er det tilladt, men det fungerer som sagt fint.



t