Author Topic: Recursively maze creation  (Read 3591 times)

0 Members and 1 Guest are viewing this topic.

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Recursively maze creation
« on: June 21, 2020, 03:26:37 pm »
Hi !

I was looking at maze solutions lately.
He started to get interested and I wanted something that has a beginning and an end and can only be walked through in 1 way.

The algorithm was not invented by me, I found it online, its name is recursively maze creation.

Code: QB64: [Select]
  1.  
  2. maze_x = 50 'maze size X
  3. maze_y = 25 'maze size Y
  4.  
  5. 'preparation -------------------------------------------------------------------------------------------------------------------------------------------
  6. IF maze_x / 2 = INT(maze_x / 2) THEN maze_x = maze_x + 1
  7. IF maze_y / 2 = INT(maze_y / 2) THEN maze_y = maze_y + 1
  8. monx = (maze_x + 10) * 8: mony = (maze_y + 5) * 16: kep = _NEWIMAGE(monx, mony, 32): SCREEN kep
  9. d(0, 0) = 0: d(0, 1) = -1: d(1, 0) = 0: d(1, 1) = 1: d(2, 0) = -1: d(2, 1) = 0: d(3, 0) = 1: d(3, 1) = 0
  10. k$(0) = "±" 'fal / adjustable wall
  11. k$(1) = " " 'nem bejart ureg / non walked road
  12. k$(2) = "W" 'lehetoseg / possible way
  13. k$(3) = "Ű" 'szilard fal / standard wall
  14. k$(4) = "." 'bejart ureg  / walked road
  15. k$(5) = "." 'belepesi pont  / entry point
  16. DIM maze(maze_x - 1, maze_y - 1) AS _BYTE '0-fal 1-ureg 2-lehetoseg
  17.  
  18.  
  19. 'create empty maze --------------------------------------------------------------------------------------------------------------------------------------
  20. FOR tx = 0 TO maze_x - 1: FOR ty = 0 TO maze_y - 1: k = 0
  21.         IF tx = 0 OR ty = 0 OR tx = maze_x - 1 OR ty = maze_y - 1 THEN k = 3
  22.         IF tx AND 1 AND ty AND 1 THEN k = 1
  23. maze(tx, ty) = k: NEXT ty, tx
  24.  
  25. 'start position -----------------------------------------------------------------------------------------------------------------------------------------
  26. DO: sx = INT(maze_x * RND(1)): sy = INT(maze_y * RND(1)): LOOP WHILE maze(sx, sy) <> 1: maze(sx, sy) = 4
  27.  
  28.  
  29. 'way searching ------------------------------------------------------------------------------------------------------------------------------------------
  30. DO: REDIM way(9999, 2): wdb = 0
  31.     FOR tx = 0 TO maze_x - 1: FOR ty = 0 TO maze_y - 1
  32.             IF maze(tx, ty) = 4 THEN
  33.                 van = 0
  34.                 FOR t = 0 TO 3
  35.                     vpx1 = tx + d(t, 0): vpy1 = ty + d(t, 1): vpx2 = tx + d(t, 0) * 2: vpy2 = ty + d(t, 1) * 2
  36.                     f = (vpx2 > maze_x - 1 OR vpx2 < 0) OR (vpy2 > maze_y - 1 OR vpy2 < 0)
  37.                     IF NOT f THEN
  38.                         IF maze(vpx1, vpy1) = 0 AND maze(vpx2, vpy2) = 1 THEN
  39.                             FOR t2 = 0 TO 3: vpx3 = vpx2 + d(t2, 0): vpy3 = vpy2 + d(t2, 1): IF maze(vpx3, vpy3) = 4 THEN GOTO kovi
  40.                             NEXT t2
  41.                             maze(vpx1, vpy1) = 2: way(wdb, 0) = tx: way(wdb, 1) = ty: way(wdb, 2) = t: wdb = wdb + 1
  42.                             kovi:
  43.                         END IF
  44.                     END IF
  45.                 NEXT t
  46.             END IF
  47.     NEXT ty, tx
  48.  
  49.     IF wdb THEN
  50.         aw = INT(wdb * RND(1))
  51.         FOR t = 0 TO 2
  52.             hovax = way(aw, 0) + d(way(aw, 2), 0) * t: hovay = way(aw, 1) + d(way(aw, 2), 1) * t
  53.             IF (maze(hovax, hovay) = 2) OR (maze(hovax, hovay) = 1) THEN maze(hovax, hovay) = 4
  54.         NEXT t
  55.  
  56.         FOR tx = 0 TO maze_x - 1: FOR ty = 0 TO maze_y - 1: IF maze(tx, ty) = 2 THEN maze(tx, ty) = 0
  57.         NEXT ty, tx
  58.     END IF
  59.  
  60.  
  61. 'entry point 1
  62. sx = 0: sy = 3: IF maze(sx + 1, sy) <> 4 THEN sy = sy + 1
  63. maze(sx, sy) = 4
  64.  
  65. 'entry point 2
  66. sx = maze_x - 1: sy = maze_y - 3: IF maze(sx - 1, sy) <> 4 THEN sy = sy - 1
  67. maze(sx, sy) = 4
  68.  
  69. ' it has taken so far to build the maze. contained in the maze array ------------------------------------------------------------------------------------------------
  70.  
  71. 'drawing
  72. sy = INT((mony / 16 - maze_y) / 2) + 1: sx = INT((monx / 8 - maze_x) / 2) + 1
  73. FOR tx = 0 TO maze_x - 1: FOR ty = 0 TO maze_y - 1: LOCATE sy + ty, sx + tx: PRINT k$(maze(tx, ty)): NEXT ty, tx
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  [attachment=1]

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Recursively maze creation
« Reply #1 on: June 21, 2020, 05:24:10 pm »
I made a mini-game out of it in my boredom

Code: QB64: [Select]
  1. settings$ = "maze.set": GOSUB re
  2.  
  3. 'preparation -------------------------------------------------------------------------------------------------------------------------------------------
  4. IF maze_x / 2 = INT(maze_x / 2) THEN maze_x = maze_x + 1
  5. IF maze_y / 2 = INT(maze_y / 2) THEN maze_y = maze_y + 1
  6. monx = (maze_x + 10) * 8: mony = (maze_y + 9) * 16: kep = _NEWIMAGE(monx, mony, 32): SCREEN kep
  7. d(0, 0) = 0: d(0, 1) = -1: d(1, 0) = 0: d(1, 1) = 1: d(2, 0) = -1: d(2, 1) = 0: d(3, 0) = 1: d(3, 1) = 0
  8. k$(0) = "±" 'fal / adjustable wall
  9. k$(1) = " " 'nem bejart ureg / non walked road
  10. k$(2) = "W" 'lehetoseg / possible way
  11. k$(3) = "Ű" 'szilard fal / standard wall
  12. k$(4) = " " 'bejart ureg  / walked road
  13. k$(5) = " " 'belepesi pont  / entry point
  14. k$(6) = "X" 'enemies
  15. k$(7) = "<" 'me left
  16. k$(8) = ">" 'me right
  17. mea = 8
  18. DIM maze(maze_x - 1, maze_y - 1) AS _BYTE '0-fal 1-ureg 2-lehetoseg
  19. DIM en(enemies - 1, 2) '0-x 1-y 2-vector (d-array)
  20.  
  21. 'create empty maze --------------------------------------------------------------------------------------------------------------------------------------
  22. FOR tx = 0 TO maze_x - 1: FOR ty = 0 TO maze_y - 1: k = 0
  23.         IF tx = 0 OR ty = 0 OR tx = maze_x - 1 OR ty = maze_y - 1 THEN k = 3
  24.         IF tx AND 1 AND ty AND 1 THEN k = 1
  25. maze(tx, ty) = k: NEXT ty, tx
  26.  
  27. 'start position -----------------------------------------------------------------------------------------------------------------------------------------
  28. DO: sx = INT(maze_x * RND(1)): sy = INT(maze_y * RND(1)): LOOP WHILE maze(sx, sy) <> 1: maze(sx, sy) = 4
  29.  
  30.  
  31. 'way searching ------------------------------------------------------------------------------------------------------------------------------------------
  32. DO: REDIM way(9999, 2): wdb = 0
  33.     FOR tx = 0 TO maze_x - 1: FOR ty = 0 TO maze_y - 1
  34.             IF maze(tx, ty) = 4 THEN
  35.                 van = 0
  36.                 FOR t = 0 TO 3
  37.                     vpx1 = tx + d(t, 0): vpy1 = ty + d(t, 1): vpx2 = tx + d(t, 0) * 2: vpy2 = ty + d(t, 1) * 2
  38.                     f = (vpx2 > maze_x - 1 OR vpx2 < 0) OR (vpy2 > maze_y - 1 OR vpy2 < 0)
  39.                     IF NOT f THEN
  40.                         IF maze(vpx1, vpy1) = 0 AND maze(vpx2, vpy2) = 1 THEN
  41.                             FOR t2 = 0 TO 3: vpx3 = vpx2 + d(t2, 0): vpy3 = vpy2 + d(t2, 1): IF maze(vpx3, vpy3) = 4 THEN GOTO kovi
  42.                             NEXT t2
  43.                             maze(vpx1, vpy1) = 2: way(wdb, 0) = tx: way(wdb, 1) = ty: way(wdb, 2) = t: wdb = wdb + 1
  44.                             kovi:
  45.                         END IF
  46.                     END IF
  47.                 NEXT t
  48.             END IF
  49.     NEXT ty, tx
  50.  
  51.     IF wdb THEN
  52.         aw = INT(wdb * RND(1))
  53.         FOR t = 0 TO 2
  54.             hovax = way(aw, 0) + d(way(aw, 2), 0) * t: hovay = way(aw, 1) + d(way(aw, 2), 1) * t
  55.             IF (maze(hovax, hovay) = 2) OR (maze(hovax, hovay) = 1) THEN maze(hovax, hovay) = 4
  56.         NEXT t
  57.  
  58.         FOR tx = 0 TO maze_x - 1: FOR ty = 0 TO maze_y - 1: IF maze(tx, ty) = 2 THEN maze(tx, ty) = 0
  59.         NEXT ty, tx
  60.     END IF
  61.  
  62. 'entry point 1
  63. sx = 0: sy = 3: IF maze(sx + 1, sy) <> 4 THEN sy = sy + 1
  64. maze(sx, sy) = 5
  65. mex = sx: mey = sy 'my start position
  66.  
  67.  
  68. 'entry point 2
  69. sx = maze_x - 1: sy = maze_y - 3: IF maze(sx - 1, sy) <> 4 THEN sy = sy - 1
  70. maze(sx, sy) = 5
  71. endx = sx: endy = sy
  72.  
  73. ' it has taken so far to build the maze. contained in the maze array ------------------------------------------------------------------------------------------------
  74.  
  75. 'create enemies
  76. FOR t = 0 TO enemies - 1: DO: sx = INT(maze_x * RND(1)): sy = INT(maze_y * RND(1)): LOOP WHILE maze(sx, sy) <> 4
  77. en(t, 0) = sx: en(t, 1) = sy: en(t, 2) = INT(4 * RND(1)): maze(sx, sy) = 6: NEXT t
  78.  
  79.  
  80. DO: _LIMIT speed
  81.     'inkey-commands
  82.     CASE "n": RUN: CASE "r": KILL settings$: RUN
  83.     CASE "a": maze_x = maze_x - 2: GOTO wr: CASE "s": maze_x = maze_x + 2: GOTO wr
  84.     CASE "y": maze_y = maze_y - 2: GOTO wr: CASE "x": maze_y = maze_y + 2: GOTO wr
  85.     CASE "q": enemies = enemies - 1: GOTO wr: CASE "w": enemies = enemies + 1: GOTO wr
  86.     CASE "-": speed = speed - 1: GOTO wr: CASE "+": speed = speed + 1: GOTO wr
  87.     END SELECT
  88.  
  89.     'moving enemies
  90.     FOR t = 0 TO enemies - 1
  91.        10: IF uj THEN en(t, 2) = INT(4 * RND(1))
  92.         vpx = en(t, 0) + d(en(t, 2), 0): vpy = en(t, 1) + d(en(t, 2), 1): f1 = (vpx > maze_x - 2 OR vpx < 1) OR (vpy > maze_y - 2 OR vpy < 1)
  93.         IF f1 THEN uj = 1: GOTO 10
  94.         f2 = (maze(vpx, vpy) = 0 OR maze(vpx, vpy) = 3) OR INT(5 * RND(1)) = 0
  95.         'f2 = (maze(vpx, vpy) <> 4) AND (maze(vpx, vpy) <> 6)
  96.         IF f2 THEN uj = 1: GOTO 10
  97.         maze(en(t, 0), en(t, 1)) = 4: en(t, 0) = en(t, 0) + d(en(t, 2), 0): en(t, 1) = en(t, 1) + d(en(t, 2), 1): maze(en(t, 0), en(t, 1)) = 6
  98.     NEXT t
  99.     GOSUB death
  100.     'moving me
  101.     t = 4 't is my array vector
  102.     IF _KEYDOWN(CVI(CHR$(0) + "P")) THEN t = 1 '_KEYDOWN(20480)
  103.     IF _KEYDOWN(CVI(CHR$(0) + "H")) THEN t = 0 '_KEYDOWN(18432)
  104.     IF _KEYDOWN(CVI(CHR$(0) + "K")) THEN t = 2: mea = 7 '_KEYDOWN(19200)
  105.     IF _KEYDOWN(CVI(CHR$(0) + "M")) THEN t = 3: mea = 8 '_KEYDOWN(19712)
  106.  
  107.     vpx = mex + d(t, 0): vpy = mey + d(t, 1)
  108.     IF (vpx > maze_x - 1 OR vpx < 0) OR (vpy > maze_y - 1 OR vpy < 0) THEN GOTO 12
  109.     IF maze(vpx, vpy) = 0 OR (maze(vpx, vpy) = 3) THEN GOTO 12
  110.     maze(mex, mey) = 4: mex = mex + d(t, 0): mey = mey + d(t, 1): maze(mex, mey) = mea
  111.    12:
  112.  
  113.     GOSUB drawing
  114.     IF mex = endx AND mey = endy THEN LOCATE 10, 5: PRINT "YOU WIN !": _DISPLAY: END
  115.     GOSUB death
  116.  
  117.  
  118.  
  119. drawing: 'drawing
  120. sx = INT((monx / 8 - maze_x) / 2) + 1: sy = 2
  121. FOR tx = 0 TO maze_x - 1: FOR ty = 0 TO maze_y - 1: LOCATE sy + ty, sx + tx: PRINT k$(maze(tx, ty)): NEXT ty, tx
  122. LOCATE 1, 1: PRINT " Go through the maze !"
  123. LOCATE maze_y + sy, 1
  124. PRINT "N   - new track": PRINT "Q/W - pieces of enemies"; enemies: PRINT "A/S - maze X"; maze_x
  125. PRINT "Y/X - maze Y"; maze_y: PRINT "+/- - speed"; speed: PRINT "R   - reset settings"
  126.  
  127. death: FOR t = 0 TO enemies - 1: IF en(t, 0) = mex AND en(t, 1) = mey THEN LOCATE 10, 5: PRINT "YOU DEATH !": _DISPLAY: END
  128.  
  129. wr:
  130. IF maze_x < 17 THEN maze_x = 17
  131. IF maze_y < 5 THEN maze_y = 5
  132. IF enemies < 0 THEN enemies = 0
  133. IF speed < 5 THEN speed = 5
  134. OPEN settings$ FOR OUTPUT AS 1: PRINT #1, maze_x, maze_y, enemies, speed: CLOSE 1: RUN
  135.  
  136. re: IF _FILEEXISTS(settings$) = 0 THEN maze_x = 30: maze_y = 12: enemies = 3: speed = 10: GOTO wr
  137. OPEN settings$ FOR INPUT AS 1: INPUT #1, maze_x, maze_y, enemies, speed: CLOSE 1: RETURN
  138.  
  139.  


FellippeHeitor

  • Guest
Re: Recursively maze creation
« Reply #2 on: June 21, 2020, 05:25:57 pm »
Looks cool! I'm sure @Virtusoroca will like looking at this piece too.

Offline Virtusoroca

  • Newbie
  • Posts: 24
    • View Profile
Re: Recursively maze creation
« Reply #3 on: June 21, 2020, 05:50:51 pm »
@MasterGy thanks for this one! And thanks @FellippeHeitor for pointing it out. I was trying to implement the backtrack algorithm but had to stop because of work. Hope to come back to the forum in a couple of weeks. Very excited to run and explore this code! Looks very nice! <3

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Recursively maze creation
« Reply #4 on: June 21, 2020, 06:06:08 pm »
Wow allot less to it than what I was using, nice!

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Recursively maze creation
« Reply #5 on: June 23, 2020, 04:58:37 pm »
I couldn’t wait to have time to integrate the maze into 3D space.
The maze is closed, but only 1 road leads from one place to another.
I had to resolve to skip the location of the towers but leave 1 entrance.
Since the smallest unit in the 3d game is the rectangle, and to save space by filling the maze, I solved it to lay it out with as few rectangles (or rectangles) of different sizes as possible.



Try it
https://drive.google.com/file/d/1bKiKYf_tXS0lkj_zxPycvmN3F-2v-mYe/view?usp=sharing
« Last Edit: June 23, 2020, 05:09:35 pm by MasterGy »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Recursively maze creation
« Reply #6 on: June 24, 2020, 01:25:01 am »
WOW! Beautiful 3D Version!! :D +1
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Recursively maze creation
« Reply #7 on: June 24, 2020, 05:06:34 pm »
thank you very much ! i still have a few ideas i want to try. eg in 2d, if I like 2-3 mazes in 1 space that are separated from each other and connect them with a bridge. Obsession ! so that scheme is supplemented by a 3rd dimension. So theoretically there would be 1 cube with two entrances. and then inside there would be paths like that. like a cave.