3d-maze
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
A model to demonstrate / work with netlogo 3d programming
A model to demonstrate creating basic mazes in netlogo
A model to demonstrate a simple maze-traversing algorithm
A model to demonstrate smooth vs coarse movement of turtles in a model.
HOW IT WORKS
A recursive routine creates a maze.
The maze routine shown here seems more complex than it is because it allows for varying path widths and wall (gap between paths) widths.
For many uses, an simply 1 unit maze routine will do as well.
THINGS TO NOTICE
If the maze paths are more than 3 units wide, the auto-navigate routine will never find the goal, because the routing only checks the current patch and the path to the immediate left of the walker.
THINGS TO TRY
EXTENDING THE MODEL
This section could give some ideas of things to add or change in the procedures tab to make the model more complicated, detailed, accurate, etc.
RELATED MODELS
This model is kin to maze-maker-2004.nlogo.
Comments and Questions
globals [ start goal walker auto-mode ] to setup ca let path maze-path let gap maze-gap set goal set-goal path gap set start set-start path gap set auto-mode 0 ask patches with [ pzcor <= 0 ] [ set pcolor gray - 10 * pzcor - 2 + 2 * pzcor + ((pycor + pxcor) mod 2) ] ;; create a turtle ;; toss in the center. ;; clear space around it ;; start carving maze from surface crt 1 [ setxyz 0 0 0 set pcolor 0 big-stamp path 0 ; make-maze ; make-maze-2 make-maze-3 path gap (timer + 2) die ] ;; create, label, and clear goal block ask goal [ big-stamp path 0 set plabel "XX" ask patch-at 0 0 -1 [ set pcolor green ] ifelse maze-style = "garden" [ big-stamp (1 + 2 * int ((path + gap) / 2)) 0 ] [sprout 1 [ set heading 180 fd int( path / 2) + 1 while [ pcolor != 0 ] [ big-stamp path 0 fd path ] die ] ] ] ;; create, label, and clear start block ask start [ big-stamp path 0 set plabel "SS" ask patch-at 0 0 -1 [ set pcolor blue ] sprout 1 [ set heading 0 fd int( path / 2) + 1 while [ pcolor != 0 ] [ big-stamp path 0 fd path ] die ] ] crt 1 [ set walker self set xcor [pxcor] of start set ycor [pycor] of start set heading 0 set color yellow ] end to zoom-in-on-walker if is-living-turtle? walker [ ask walker [ hide-turtle ] ride walker ] end to zoom-out-from-walker if is-living-turtle? walker [ reset-perspective watch walker ask walker [ show-turtle ] ] end to make-maze ;; recursive maze making procedure. ;; uses multiple turtles to carve the maze ;; could be made more memory efficient by using only one turtle ;; that keeps a "stack" in list, and uses the stack ;; to retrace back to junction points. ;; but using turtles is easier ;; could also make this a reporter, and pass the current location is and out, ;; so that the turtle ;; pops back to the spot reported.. oo i like that... see make-maze-2 let unused-paths wall-blocks-in-neighborhood-nowrap ;; while any unused-paths in the neighborhood ;; dig maze paths though the blocks while [ any? unused-paths ] [ let selected one-of unused-paths set heading towards selected ;; carve patch to new spot jump 3 big-stamp 3 0 jump 3 big-stamp 3 0 ;; hatch new turtle to continue maze making from here hatch 1 [ make-maze ] ;; update unused-pathsopen blocks set unused-paths wall-blocks-in-neighborhood-nowrap ] ;; can't go any father, die die end to make-maze-2 ;; recursive maze making procedure. ;; remembers the current location ;; so that the turtle ;; pops back to the spot ;; remember where I am now let location patch-here ;; are there any possible paths out of here? let unused-paths wall-blocks-in-neighborhood-nowrap ;; while there are unused-paths from here, ;; dig maze paths though the blocks while [ any? unused-paths ] [ let selected one-of unused-paths set heading towards selected ;; carve patch to new spot jump 3 big-stamp 3 0 jump 3 big-stamp 3 0 ;; hatch new turtle to continue maze making from here make-maze-2 ;; update unused-paths set unused-paths wall-blocks-in-neighborhood-nowrap ] ;; can't go any father, and since I probably moved around in that while loop, ;; I have to jump back to my starting location setxy [pxcor] of location [pycor] of location end to make-maze-3 [ path gap timeout ] ;; recursive maze making procedure. ;; remembers the current location ;; so that the turtle ;; pops back to the spot let dist path + gap ;; remember where I am now let location patch-here ;; while there are unused-paths from here, ;; dig maze paths though the blocks ;; There are at most 4 paths repeat 4 [ ;; are there any possible paths out of here? let unused-paths wall-blocks-in-neighborhood-nowrap-3 path gap if any? unused-paths and timer < timeout [ let selected one-of unused-paths set heading towards selected ;; carve patch to new spot repeat (path + gap ) [ jump 1 big-stamp path 0 ] ; jump ((gap + path) / 2) big-stamp path 0 jump ((gap + path) / 2) big-stamp path 0 ;; hatch new turtle to continue maze making from here make-maze-3 path gap timeout ] ;; update unused-paths set unused-paths wall-blocks-in-neighborhood-nowrap-3 path gap ] ;; can't go any father, and since I probably moved around in that while loop, ;; I have to jump back to my starting location setxy [pxcor] of location [pycor] of location end to-report wall-blocks-in-neighborhood-nowrap report far-neighbors-nowrap with [ pcolor != 0 ;; a wall, not carved yet and abs pxcor <= (int (max-pxcor / 6) * 6 - 3 ) ;; within the boundries, not on or overlapping the edge and abs pycor <= (int (max-pycor / 6) * 6 - 3 ) ;; within the boundries, not on or overlapping the edge ] end to-report far-neighbors-nowrap let points [[0 -6][0 6][6 0][-6 0]] report (patches at-points points ) ;; the 4 patches, path + gap units away with [ pxcor - [pxcor] of myself <= 6 ;; not wrapped, ie, dist or less units away and pycor - [pycor] of myself <= 6 ;; not wrapped ] end to-report wall-blocks-in-neighborhood-nowrap-3 [ path gap ] let dist gap + path report (far-neighbors-nowrap-3 dist) with [ pcolor != 0 ;; a wall, not carved yet and abs pxcor <= (int (max-pxcor / dist) * dist - path ) ;; within the boundries, not on or overlapping the edge and abs pycor <= (int (max-pycor / dist) * dist - path ) ;; within the boundries, not on or overlapping the edge ] end to-report far-neighbors-nowrap-3 [ dist ] let points (list list 0 (- dist) list 0 dist list dist 0 list (- dist) 0 ) report (patches at-points points ) ;; the 4 patches, path + gap units away with [ pxcor - [pxcor] of myself <= dist ;; not wrapped, ie, dist or less units away and pycor - [pycor] of myself <= dist ;; not wrapped ] end to big-stamp [ side hue ] let edge (side - 1) / 2 let points n-values (side * side) [ list ((? mod side) - edge) (int (? / side) - edge) ] ask patches at-points points [ set pcolor 0 ] end to move-walker [ dir ] if not is-living-turtle? walker [ stop ] ask walker [ if path-ahead-clear? [ ifelse smooth-movement? [ repeat 5 [ jump .2 * dir wait move-delay ] ] [ jump 1 * dir wait move-delay ] ] ] end to turn-walker [ dir ] ;; dir = -1 (left) or +1 (right) if not is-living-turtle? walker [ stop ] ;; if required, walker will move forward, then turn ;; otherwise, walker will just turn ask walker [ if not path-turn-clear? dir and path-turn-ahead-clear? dir [ move-walker 1 ] ifelse smooth-movement? [ repeat 5 [ rt 18 * dir wait move-delay ] ] [ rt 90 * dir wait move-delay ] ] end to reverse-walker if not is-living-turtle? walker [ stop ] ask walker [ let dir -1 repeat 2 [ ifelse smooth-movement? [ repeat 5 [ rt 18 * dir wait move-delay ] ] [ rt 90 * dir wait move-delay ] ] ] end to auto-navigate ifelse auto-mode = 1 [ set auto-mode 0 stop ] [ set auto-mode 2 ] ifelse auto-mode != 1 [ set auto-mode 2 ] [ stop ] if not is-living-turtle? walker [ stop ] ifelse [ patch-here = goal and continuously? ] of walker [ wait 5 setup ] [ ifelse [ patch-here != goal ] of walker [ ask walker [ ifelse patch-left-and-ahead 90 1 = goal [ turn-walker -1 move-walker 1 ] [ ifelse not any? neighbors with [ pcolor != 0 ] ;; out in the open! [ ;; step sideways turn-walker 1 move-walker 1 turn-walker -1 ] [ ifelse path-turn-ahead-clear? 1 [ turn-walker 1 ] [ ifelse path-ahead-clear? [ move-walker 1 ] [ ifelse path-turn-clear? -1 [ turn-walker -1 ] [ reverse-walker ] ] ] ] ] ] ] [ stop ] ] end to stop-auto-mode if auto-mode != 0 [ set auto-mode 1 stop ] end to-report is-living-turtle? [ variable] report (is-turtle? variable and variable != nobody ) end to-report path-ahead-clear? report [pcolor] of patch-ahead 1 = black end to-report path-turn-clear? [ dir ] report [pcolor] of patch-right-and-ahead (90 * dir) 1 = black end to-report path-turn-ahead-clear? [ dir ] report [pcolor] of patch-right-and-ahead (45 * dir) 1.41 = black end to-report set-start [ path gap ] let dist gap + path let row-edge-y ( int (max-pycor / dist) * dist ) - path let col-edge-x ( int (max-pxcor / dist) * dist ) - dist let row patches with [ pzcor = 0 and pycor = (- row-edge-y) and abs pxcor <= col-edge-x and pxcor mod dist = 0 ] report (switch-hack maze-style row (- col-edge-x) ;; need to pass local variables values [ "random" [ "random-one-of v1" ] ; random bottom row "direct" [ "one-of v1 with [ pxcor = 0 ]" ] ;; center bottom "diagonal" [ "one-of v1 with [ pxcor = v2 ]" ] ;; bottom left "garden" [ "one-of v1 with [ pxcor = 0 ]" ] ;; center bottom [] [] ] ) end to-report set-goal [ path gap ] let dist gap + path let row-edge-y (int (max-pycor / dist) * dist ) - path let col-edge-x (int (max-pxcor / dist) * dist ) - dist let row patches with [ pzcor = 0 and pycor = ( row-edge-y) and abs pxcor <= col-edge-x and pxcor mod dist = 0 ] report (switch-hack maze-style row col-edge-x ;; need to pass local variables values [ "random" [ "random-one-of v1" ] ;; random top row "direct" [ "one-of v1 with [ pxcor = 0 ]" ] ; center-top "diagonal" [ "one-of v1 with [ pxcor = v2]" ] ; top right "garden" [ "patch3d 0 0 0" ] ;; center [] [] ] ) end to-report switch-hack [ switch-value v1 v2 switch-array ] ;; see if value can be found in the switch-array ;; built short-list of values from array let switch-list (n-values (length switch-array / 2) [ item (? * 2) switch-array ]) let selection position switch-value switch-list ;; was the value found? if is-boolean? selection [ ;; no. value not found in switch array, ;; so invoke the "otherwise" clause, the last row. ;; if no otherwise clause is desired, ;; enter an unlikely/impossible value. ;; for example, a blank "", 0, the empty list [] ;; especially an entry of a type different from the type being switched. set selection (length switch-list ) ] set switch-list (n-values (length switch-array / 2) [ item (? * 2 + 1) switch-array ]) let reporter first item selection switch-list let result 0 carefully [ set result run-result reporter ] [ user-message (word "The switch-array reporter in line # " selection ": '" reporter "' produced an error." error-message ) ] report result end to overhead-view ifelse is-living-turtle? walker [ zoom-out-from-walker ] [ reset-perspective setxyz 0 0 (world-width * 3) face patch 0 0 0 ] end to in-maze-view ifelse is-living-turtle? walker [ zoom-in-on-walker ] [ overhead-view ] end
There are 2 versions of this model.
Attached files
No files
This model does not have any ancestors.
This model does not have any descendants.