Maze generation: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
Line 20: | Line 20: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">F make_maze(w = 16, h = 8) |
||
V vis = [[0] * w [+] [1]] * h [+] [[1] * (w + 1)] |
V vis = [[0] * w [+] [1]] * h [+] [[1] * (w + 1)] |
||
V ver = [[‘| ’] * w [+] [String(‘|’)]] * h [+] [[String]()] |
V ver = [[‘| ’] * w [+] [String(‘|’)]] * h [+] [[String]()] |
||
Line 49: | Line 49: | ||
R s |
R s |
||
print(make_maze())</ |
print(make_maze())</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 74: | Line 74: | ||
=={{header|Action!}}== |
=={{header|Action!}}== |
||
Action! language does not support recursion. Therefore an iterative approach with a stack has been proposed. |
Action! language does not support recursion. Therefore an iterative approach with a stack has been proposed. |
||
< |
<syntaxhighlight lang="action!">DEFINE TOP="0" |
||
DEFINE RIGHT="1" |
DEFINE RIGHT="1" |
||
DEFINE BOTTOM="2" |
DEFINE BOTTOM="2" |
||
Line 188: | Line 188: | ||
DO UNTIL CH#$FF OD |
DO UNTIL CH#$FF OD |
||
CH=$FF |
CH=$FF |
||
RETURN</ |
RETURN</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Maze_generation.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Maze_generation.png Screenshot from Atari 8-bit computer] |
||
Line 196: | Line 196: | ||
{{works with|GNAT}} |
{{works with|GNAT}} |
||
mazes.ads: |
mazes.ads: |
||
< |
<syntaxhighlight lang="ada">generic |
||
Height : Positive; |
Height : Positive; |
||
Width : Positive; |
Width : Positive; |
||
Line 222: | Line 222: | ||
type Maze_Grid is array (Height_Type, Width_Type) of Cells; |
type Maze_Grid is array (Height_Type, Width_Type) of Cells; |
||
end Mazes;</ |
end Mazes;</syntaxhighlight> |
||
mazes.adb: |
mazes.adb: |
||
< |
<syntaxhighlight lang="ada">with Ada.Numerics.Discrete_Random; |
||
with Ada.Text_IO; |
with Ada.Text_IO; |
||
Line 397: | Line 397: | ||
end Put; |
end Put; |
||
end Mazes; |
end Mazes; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Example main.adb: |
Example main.adb: |
||
< |
<syntaxhighlight lang="ada">with Mazes; |
||
procedure Main is |
procedure Main is |
||
package Small_Mazes is new Mazes (Height => 8, Width => 11); |
package Small_Mazes is new Mazes (Height => 8, Width => 11); |
||
Line 406: | Line 406: | ||
Small_Mazes.Initialize (My_Maze); |
Small_Mazes.Initialize (My_Maze); |
||
Small_Mazes.Put (My_Maze); |
Small_Mazes.Put (My_Maze); |
||
end Main;</ |
end Main;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Starting generation at 3 x 7 |
<pre>Starting generation at 3 x 7 |
||
Line 428: | Line 428: | ||
=={{header|Aime}}== |
=={{header|Aime}}== |
||
< |
<syntaxhighlight lang="aime">grid_maze(data b, integer N) |
||
{ |
{ |
||
data d; |
data d; |
||
Line 501: | Line 501: | ||
0; |
0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>+---+---+---+---+---+---+---+---+---+---+ |
<pre>+---+---+---+---+---+---+---+---+---+---+ |
||
Line 527: | Line 527: | ||
=={{header|APL}}== |
=={{header|APL}}== |
||
<syntaxhighlight lang="apl"> |
|||
<lang APL> |
|||
This example shows how to use GNU APL scripting. |
This example shows how to use GNU APL scripting. |
||
Line 633: | Line 633: | ||
doMaze 9 9 |
doMaze 9 9 |
||
)OFF |
)OFF |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 660: | Line 660: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
For a challenge, this maze generation is entirely string based. That is to say, all operations including the wall removal and retrieval of cell states are done on the output string. |
For a challenge, this maze generation is entirely string based. That is to say, all operations including the wall removal and retrieval of cell states are done on the output string. |
||
< |
<syntaxhighlight lang="ahk">; Initially build the board |
||
Width := 11 |
Width := 11 |
||
Height := 8 |
Height := 8 |
||
Line 724: | Line 724: | ||
If (A_Index = Y) |
If (A_Index = Y) |
||
return SubStr(A_LoopField, x, 1) |
return SubStr(A_LoopField, x, 1) |
||
}</ |
}</syntaxhighlight> |
||
{{out|Sample output}} |
{{out|Sample output}} |
||
<pre>+-+-+-+-+-+-+-+-+-+-+-+ |
<pre>+-+-+-+-+-+-+-+-+-+-+-+ |
||
Line 750: | Line 750: | ||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
< |
<syntaxhighlight lang="awk">#!/usr/bin/awk -f |
||
# Remember: AWK is 1-based, for better or worse. |
# Remember: AWK is 1-based, for better or worse. |
||
Line 937: | Line 937: | ||
srand(t); |
srand(t); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Example output: |
Example output: |
||
Line 987: | Line 987: | ||
==={{header|QB64}}=== |
==={{header|QB64}}=== |
||
This implementation was written using QB64. It should also be compatible with Qbasic, as it uses no QB64-exclusive features. |
This implementation was written using QB64. It should also be compatible with Qbasic, as it uses no QB64-exclusive features. |
||
< |
<syntaxhighlight lang="qb64">OPTION BASE 0 |
||
RANDOMIZE TIMER |
RANDOMIZE TIMER |
||
Line 1,054: | Line 1,054: | ||
REM wait |
REM wait |
||
DO: LOOP WHILE INKEY$ = ""</ |
DO: LOOP WHILE INKEY$ = ""</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,081: | Line 1,081: | ||
==={{header|BASIC256}}=== |
==={{header|BASIC256}}=== |
||
< |
<syntaxhighlight lang="basic256">global size_x, size_y |
||
size_x = 25 |
size_x = 25 |
||
size_y = 15 |
size_y = 15 |
||
Line 1,144: | Line 1,144: | ||
print |
print |
||
next i |
next i |
||
end subroutine</ |
end subroutine</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,182: | Line 1,182: | ||
{{works with|Windows NT}} |
{{works with|Windows NT}} |
||
< |
<syntaxhighlight lang="dos">:amaze Rows Cols [wall char] |
||
:: A stack-less, iterative, depth-first maze generator in native WinNT batch. |
:: A stack-less, iterative, depth-first maze generator in native WinNT batch. |
||
:: Rows and Cols must each be >1 and Rows*Cols cannot exceed 2096. |
:: Rows and Cols must each be >1 and Rows*Cols cannot exceed 2096. |
||
Line 1,276: | Line 1,276: | ||
ENDLOCAL |
ENDLOCAL |
||
EXIT /B 0 |
EXIT /B 0 |
||
</syntaxhighlight> |
|||
</lang> |
|||
Example output: |
Example output: |
||
Line 1,307: | Line 1,307: | ||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
< |
<syntaxhighlight lang="bbcbasic"> MazeWidth% = 11 |
||
MazeHeight% = 9 |
MazeHeight% = 9 |
||
MazeCell% = 50 |
MazeCell% = 50 |
||
Line 1,348: | Line 1,348: | ||
ENDIF |
ENDIF |
||
NEXT |
NEXT |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
'''Sample output:''' |
'''Sample output:''' |
||
<br> |
<br> |
||
Line 1,358: | Line 1,358: | ||
Also note that this requires an interpreter with working read-write memory support, which is suprisingly rare in online implementations. Padding the code page with extra blank lines or spaces can sometimes help. Using smaller dimensions might also be preferable, especially on slower implementations. |
Also note that this requires an interpreter with working read-write memory support, which is suprisingly rare in online implementations. Padding the code page with extra blank lines or spaces can sometimes help. Using smaller dimensions might also be preferable, especially on slower implementations. |
||
< |
<syntaxhighlight lang="befunge">45*28*10p00p020p030p006p0>20g30g00g*+::"P"%\"P"/6+gv>$\1v@v1::\+g02+*g00+g03-\< |
||
0_ 1!%4+1\-\0!::\-\2%2:p<pv0<< v0p+6/"P"\%"P":\+4%4<^<v-<$>+2%\1-*20g+\1+4%::v^ |
0_ 1!%4+1\-\0!::\-\2%2:p<pv0<< v0p+6/"P"\%"P":\+4%4<^<v-<$>+2%\1-*20g+\1+4%::v^ |
||
#| +2%\1-*30g+\1\40g1-:v0+v2?1#<v>+:00g%!55+*>:#0>#,_^>:!|>\#%"P"v#:*+*g00g0<>1 |
#| +2%\1-*30g+\1\40g1-:v0+v2?1#<v>+:00g%!55+*>:#0>#,_^>:!|>\#%"P"v#:*+*g00g0<>1 |
||
Line 1,364: | Line 1,364: | ||
0#$g#<1#<-#<`#<\#<0#<^#_^/>#1+#4<>"P"%\"P"/6+g:2%^!>,1-:#v_$55+^|$$ "JH" $$>#<0 |
0#$g#<1#<-#<`#<\#<0#<^#_^/>#1+#4<>"P"%\"P"/6+g:2%^!>,1-:#v_$55+^|$$ "JH" $$>#<0 |
||
::"P"%\"P"/6+g40p\40g+\:#^"P"%#\<^ ::$_,#!0#:<*"|"<^," _"<:g000 <> /6+g4/2%+#^_ |
::"P"%\"P"/6+g40p\40g+\:#^"P"%#\<^ ::$_,#!0#:<*"|"<^," _"<:g000 <> /6+g4/2%+#^_ |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,387: | Line 1,387: | ||
=={{header|C}}== |
=={{header|C}}== |
||
Generation/solver in one. Requires UTF8 locale and unicode capable console. If your console font line-drawing chars are single width, define DOUBLE_SPACE to 0. |
Generation/solver in one. Requires UTF8 locale and unicode capable console. If your console font line-drawing chars are single width, define DOUBLE_SPACE to 0. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <string.h> |
#include <string.h> |
||
Line 1,532: | Line 1,532: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out|Sample output}} |
{{out|Sample output}} |
||
<pre>┌───┬─────┬─────────┬───────┬───┐ |
<pre>┌───┬─────┬─────────┬───────┬───┐ |
||
Line 1,554: | Line 1,554: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
using System.Diagnostics; |
using System.Diagnostics; |
||
Line 1,678: | Line 1,678: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 1,726: | Line 1,726: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
[[File:maze_cpp.png|300px]] |
[[File:maze_cpp.png|300px]] |
||
< |
<syntaxhighlight lang="cpp"> |
||
#include <windows.h> |
#include <windows.h> |
||
#include <iostream> |
#include <iostream> |
||
Line 1,996: | Line 1,996: | ||
} |
} |
||
//-------------------------------------------------------------------------------------------------- |
//-------------------------------------------------------------------------------------------------- |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
< |
<syntaxhighlight lang="clojure">(ns maze.core |
||
(:require [clojure.set :refer [intersection |
(:require [clojure.set :refer [intersection |
||
select]] |
select]] |
||
Line 2,092: | Line 2,092: | ||
;;Task |
;;Task |
||
(println (maze->str (create-random-maze 10 10)))</ |
(println (maze->str (create-random-maze 10 10)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,120: | Line 2,120: | ||
Written in Commodore BASIC V2 and tested on Commodore 64 and Commodore 128 hardware. (It will also run on the unexpanded Commodore VIC-20 if you reduce the maze size to 8x8.) Due to stack size limitations in the operating systems, this solution eschews recursive subroutine calls. Recursion is accomplished by conditional branching within the maze build routine and the use of an array-based stack for data elements. |
Written in Commodore BASIC V2 and tested on Commodore 64 and Commodore 128 hardware. (It will also run on the unexpanded Commodore VIC-20 if you reduce the maze size to 8x8.) Due to stack size limitations in the operating systems, this solution eschews recursive subroutine calls. Recursion is accomplished by conditional branching within the maze build routine and the use of an array-based stack for data elements. |
||
< |
<syntaxhighlight lang="basic">100 MS=10:REM MAZE SIZE |
||
110 DIM S(MS+1,MS+1):REM SOUTH WALLS |
110 DIM S(MS+1,MS+1):REM SOUTH WALLS |
||
120 DIM W(MS+1,MS+1):REM WEST WALLS |
120 DIM W(MS+1,MS+1):REM WEST WALLS |
||
Line 2,178: | Line 2,178: | ||
670 NEXT R |
670 NEXT R |
||
680 REM PRINT#4:CLOSE 4:REM CLOSE PRINTER DEVICE |
680 REM PRINT#4:CLOSE 4:REM CLOSE PRINTER DEVICE |
||
690 RETURN</ |
690 RETURN</syntaxhighlight> |
||
{{out|Output example (for 10x10 maze)}} |
{{out|Output example (for 10x10 maze)}} |
||
<pre>+--+--+--+--+--+--+--+--+--+--+ |
<pre>+--+--+--+--+--+--+--+--+--+--+ |
||
Line 2,205: | Line 2,205: | ||
The remove-wall function has been written so as to be as close as possible to the specification. The walls are made from a single unicode character, specified by the block keyword, e. g. (maze 20 6 :block #\X). The BOX_DRAWINGS_LIGHT_DIAGONAL_CROSS character is used by default. |
The remove-wall function has been written so as to be as close as possible to the specification. The walls are made from a single unicode character, specified by the block keyword, e. g. (maze 20 6 :block #\X). The BOX_DRAWINGS_LIGHT_DIAGONAL_CROSS character is used by default. |
||
< |
<syntaxhighlight lang="lisp">(defun shuffle (list) ;; Z not uniform |
||
(sort list '> :key (lambda(x) (random 1.0)))) |
(sort list '> :key (lambda(x) (random 1.0)))) |
||
Line 2,234: | Line 2,234: | ||
do (princ (aref maze i j)))))) |
do (princ (aref maze i j)))))) |
||
(draw-maze 20 6)</ |
(draw-maze 20 6)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,252: | Line 2,252: | ||
Another solution using unicode line drawing chars. Assumes they are single width on console. Code pretty horribly unreadable. |
Another solution using unicode line drawing chars. Assumes they are single width on console. Code pretty horribly unreadable. |
||
< |
<syntaxhighlight lang="lisp">(setf *random-state* (make-random-state t)) |
||
(defun 2d-array (w h) |
(defun 2d-array (w h) |
||
Line 2,308: | Line 2,308: | ||
(show)))) |
(show)))) |
||
(make-maze 20 20)</ |
(make-maze 20 20)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>┼───┴───┼───┴───┴───┼───┴───┴───┼ |
<pre>┼───┴───┼───┴───┴───┼───┴───┴───┼ |
||
Line 2,329: | Line 2,329: | ||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">void main() @safe { |
||
import std.stdio, std.algorithm, std.range, std.random; |
import std.stdio, std.algorithm, std.range, std.random; |
||
Line 2,350: | Line 2,350: | ||
foreach (const a, const b; hor.zip(ver ~ [])) |
foreach (const a, const b; hor.zip(ver ~ [])) |
||
join(a ~ "+\n" ~ b).writeln; |
join(a ~ "+\n" ~ b).writeln; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
<pre>+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
||
Line 2,374: | Line 2,374: | ||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+</pre> |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+</pre> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="pascal">program MazeGen_Rosetta; |
||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
Line 2,485: | Line 2,485: | ||
Main; |
Main; |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
<pre>+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
||
Line 2,516: | Line 2,516: | ||
[https://easylang.online/apps/_r_maze0.html Run it] |
[https://easylang.online/apps/_r_maze0.html Run it] |
||
<lang>size = 20 |
<syntaxhighlight lang="text">size = 20 |
||
n = 2 * size + 1 |
n = 2 * size + 1 |
||
endpos = n * n - 2 |
endpos = n * n - 2 |
||
Line 2,568: | Line 2,568: | ||
. |
. |
||
call make_maze |
call make_maze |
||
call show_maze</ |
call show_maze</syntaxhighlight> |
||
=={{header|EGL}}== |
=={{header|EGL}}== |
||
< |
<syntaxhighlight lang="egl">program MazeGen |
||
// First and last columns/rows are "dead" cells. Makes generating |
// First and last columns/rows are "dead" cells. Makes generating |
||
Line 2,720: | Line 2,720: | ||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
{{out|Output example (for 10x10 maze)}} |
{{out|Output example (for 10x10 maze)}} |
||
<pre> |
<pre> |
||
Line 2,748: | Line 2,748: | ||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="elixir">defmodule Maze do |
||
def generate(w, h) do |
def generate(w, h) do |
||
maze = (for i <- 1..w, j <- 1..h, into: Map.new, do: {{:vis, i, j}, true}) |
maze = (for i <- 1..w, j <- 1..h, into: Map.new, do: {{:vis, i, j}, true}) |
||
Line 2,778: | Line 2,778: | ||
end |
end |
||
Maze.generate(20, 10)</ |
Maze.generate(20, 10)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,806: | Line 2,806: | ||
=={{header|Elm}}== |
=={{header|Elm}}== |
||
< |
<syntaxhighlight lang="elm">import Maybe as M |
||
import Result as R |
import Result as R |
||
import Matrix |
import Matrix |
||
Line 3,054: | Line 3,054: | ||
, update = update |
, update = update |
||
, subscriptions = subscriptions |
, subscriptions = subscriptions |
||
}</ |
}</syntaxhighlight> |
||
Link to live demo: http://dc25.github.io/mazeGenerationElm/ |
Link to live demo: http://dc25.github.io/mazeGenerationElm/ |
||
Line 3,061: | Line 3,061: | ||
{{libheader|cl-lib}} |
{{libheader|cl-lib}} |
||
< |
<syntaxhighlight lang="lisp">(require 'cl-lib) |
||
(cl-defstruct maze rows cols data) |
(cl-defstruct maze rows cols data) |
||
Line 3,253: | Line 3,253: | ||
(print-maze maze solution))) |
(print-maze maze solution))) |
||
(generate 20 20)</ |
(generate 20 20)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,284: | Line 3,284: | ||
===Using multiple processes=== |
===Using multiple processes=== |
||
<syntaxhighlight lang="erlang"> |
|||
<lang Erlang> |
|||
-module( maze ). |
-module( maze ). |
||
Line 3,428: | Line 3,428: | ||
[Pid ! {Key, My_pid} || {_Position, Pid} <- Position_pids], |
[Pid ! {Key, My_pid} || {_Position, Pid} <- Position_pids], |
||
[{Position, read_receive(Pid, Key)} || {Position, Pid} <- Position_pids]. |
[{Position, read_receive(Pid, Key)} || {Position, Pid} <- Position_pids]. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,464: | Line 3,464: | ||
Usage: start with generate_default/0. Use generate_MxN() to test other maze sizes. |
Usage: start with generate_default/0. Use generate_MxN() to test other maze sizes. |
||
<syntaxhighlight lang="erlang"> |
|||
<lang Erlang> |
|||
-module(maze). |
-module(maze). |
||
-record(maze, {g, m, n}). |
-record(maze, {g, m, n}). |
||
Line 3,579: | Line 3,579: | ||
generate_default() -> |
generate_default() -> |
||
generate_MxN(9, 9). |
generate_MxN(9, 9). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,607: | Line 3,607: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
Using mutable state in the form of 2D arrays: |
Using mutable state in the form of 2D arrays: |
||
< |
<syntaxhighlight lang="fsharp">let rnd : int -> int = |
||
let gen = new System.Random() |
let gen = new System.Random() |
||
fun max -> gen.Next(max) |
fun max -> gen.Next(max) |
||
Line 3,663: | Line 3,663: | ||
let m = new Maze(10,10) |
let m = new Maze(10,10) |
||
m.Print()</ |
m.Print()</syntaxhighlight> |
||
{{out|Output example}} |
{{out|Output example}} |
||
<pre>+-+-+-+-+-+-+-+-+-+-+ |
<pre>+-+-+-+-+-+-+-+-+-+-+ |
||
Line 3,692: | Line 3,692: | ||
The solution uses the following library <tt>bits.fs</tt>, which implements bit-arrays: |
The solution uses the following library <tt>bits.fs</tt>, which implements bit-arrays: |
||
<br> |
<br> |
||
< |
<syntaxhighlight lang="forth">\ Bit Arrays |
||
: to-bits ( c -- f f f f f f f f ) |
: to-bits ( c -- f f f f f f f f ) |
||
Line 3,802: | Line 3,802: | ||
else |
else |
||
drop |
drop |
||
then ;</ |
then ;</syntaxhighlight> |
||
<br> |
<br> |
||
The solution uses three bit-arrays: one to track whether a cell has been visited, one for "East"-walls (walls to the right of a cell) and one for "South"-walls (walls to the bottom of a cell). |
The solution uses three bit-arrays: one to track whether a cell has been visited, one for "East"-walls (walls to the right of a cell) and one for "South"-walls (walls to the bottom of a cell). |
||
<br> |
<br> |
||
< |
<syntaxhighlight lang="forth">#! /usr/bin/gforth |
||
\ Maze Generation |
\ Maze Generation |
||
Line 3,927: | Line 3,927: | ||
: maze ( width height -- ) build-maze maze. ; |
: maze ( width height -- ) build-maze maze. ; |
||
maze cr bye</ |
maze cr bye</syntaxhighlight> |
||
{{out}}<pre> |
{{out}}<pre> |
||
Line 4,007: | Line 4,007: | ||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">' version 04-12-2016 |
||
' compile with: fbc -s console |
' compile with: fbc -s console |
||
' when generating a big maze it's possible to run out of stack space |
' when generating a big maze it's possible to run out of stack space |
||
Line 4,136: | Line 4,136: | ||
Loop |
Loop |
||
End</ |
End</syntaxhighlight> |
||
=={{header|Fōrmulæ}}== |
=={{header|Fōrmulæ}}== |
||
Line 4,147: | Line 4,147: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 4,265: | Line 4,265: | ||
m.gen() |
m.gen() |
||
fmt.Print(m) |
fmt.Print(m) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,280: | Line 4,280: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">{-# LANGUAGE FlexibleContexts #-} |
||
{-# LANGUAGE TypeFamilies #-} |
{-# LANGUAGE TypeFamilies #-} |
||
Line 4,357: | Line 4,357: | ||
main :: IO () |
main :: IO () |
||
main = getStdGen >>= stToIO . maze 11 8 >>= printMaze</ |
main = getStdGen >>= stToIO . maze 11 8 >>= printMaze</syntaxhighlight> |
||
{{out|Sample output}} |
{{out|Sample output}} |
||
+---+---+---+---+---+---+---+---+---+---+---+ |
+---+---+---+---+---+---+---+---+---+---+---+ |
||
Line 4,378: | Line 4,378: | ||
=={{header|Huginn}}== |
=={{header|Huginn}}== |
||
< |
<syntaxhighlight lang="huginn">import Algorithms as algo; |
||
import Mathematics as math; |
import Mathematics as math; |
||
import Terminal as term; |
import Terminal as term; |
||
Line 4,448: | Line 4,448: | ||
maze = Maze( rows, cols ); |
maze = Maze( rows, cols ); |
||
print( "{}".format( maze ) ); |
print( "{}".format( maze ) ); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
[[File:Mazegen-unicon-20x30-1321112170.gif|thumb|right|20x30 with two random openings]] |
[[File:Mazegen-unicon-20x30-1321112170.gif|thumb|right|20x30 with two random openings]] |
||
[[File:Mazegen-unicon-20x30-1321060467.gif|thumb|right|20x30 with opposite openings]] |
[[File:Mazegen-unicon-20x30-1321060467.gif|thumb|right|20x30 with opposite openings]] |
||
< |
<syntaxhighlight lang="icon">link printf |
||
procedure main(A) # generate rows x col maze |
procedure main(A) # generate rows x col maze |
||
Line 4,545: | Line 4,545: | ||
return mazeinfo(&window,maze,sprintf("maze-%dx%d-%d.gif",r,c,&now)) |
return mazeinfo(&window,maze,sprintf("maze-%dx%d-%d.gif",r,c,&now)) |
||
end</ |
end</syntaxhighlight> |
||
Note: The underlying maze structure (matrix) is uni-directional from the start |
Note: The underlying maze structure (matrix) is uni-directional from the start |
||
{{libheader|Icon Programming Library}} |
{{libheader|Icon Programming Library}} |
||
Line 4,555: | Line 4,555: | ||
{{trans|PicoLisp}} |
{{trans|PicoLisp}} |
||
But without any relevant grid library: |
But without any relevant grid library: |
||
< |
<syntaxhighlight lang="j">maze=:4 :0 |
||
assert.0<:n=.<:x*y |
assert.0<:n=.<:x*y |
||
horiz=. 0$~x,y-1 |
horiz=. 0$~x,y-1 |
||
Line 4,585: | Line 4,585: | ||
'hdoor vdoor'=. 2 4&*&.>&.> (#&,{@;&i./@$)&.> y |
'hdoor vdoor'=. 2 4&*&.>&.> (#&,{@;&i./@$)&.> y |
||
' ' (a:-.~0 1;0 2; 0 3;(2 1-~$text);(1 4&+&.> hdoor),,vdoor+&.>"0/2 1;2 2;2 3)} text |
' ' (a:-.~0 1;0 2; 0 3;(2 1-~$text);(1 4&+&.> hdoor),,vdoor+&.>"0/2 1;2 2;2 3)} text |
||
)</ |
)</syntaxhighlight> |
||
The result of <code>maze</code> is a pair of arrays: one for open "doors" in the horizontal direction and the other for open "doors" in the vertical direction. The entry and exit doors are not represented by <code>maze</code> -- they are implicitly defined and are implemented in <code>display</code>. (The sequences of coordinates in <code>display</code> are the relative coordinates for the doors. For example, <code>2 1;2 2;2 3</code> are where we put spaces for each vertical door. The variable <code>text</code> is an ascii representation of the maze grid before the doors are placed.) |
The result of <code>maze</code> is a pair of arrays: one for open "doors" in the horizontal direction and the other for open "doors" in the vertical direction. The entry and exit doors are not represented by <code>maze</code> -- they are implicitly defined and are implemented in <code>display</code>. (The sequences of coordinates in <code>display</code> are the relative coordinates for the doors. For example, <code>2 1;2 2;2 3</code> are where we put spaces for each vertical door. The variable <code>text</code> is an ascii representation of the maze grid before the doors are placed.) |
||
{{out|Example use (with ascii box drawing enabled)}} |
{{out|Example use (with ascii box drawing enabled)}} |
||
< |
<syntaxhighlight lang="j"> display 8 maze 11 |
||
+ +---+---+---+---+---+---+---+---+---+---+ |
+ +---+---+---+---+---+---+---+---+---+---+ |
||
| | | | | |
| | | | | |
||
Line 4,606: | Line 4,606: | ||
+ + + + + + + + +---+ + + |
+ + + + + + + + +---+ + + |
||
| | | | | |
| | | | | |
||
+---+---+---+---+---+---+---+---+---+---+---+</ |
+---+---+---+---+---+---+---+---+---+---+---+</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{works with|Java|1.5+}} |
{{works with|Java|1.5+}} |
||
< |
<syntaxhighlight lang="java5">package org.rosettacode; |
||
import java.util.Collections; |
import java.util.Collections; |
||
Line 4,700: | Line 4,700: | ||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>+---+---+---+---+---+---+---+---+---+---+ |
<pre>+---+---+---+---+---+---+---+---+---+---+ |
||
Line 4,726: | Line 4,726: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
{{trans|J}} |
{{trans|J}} |
||
< |
<syntaxhighlight lang="javascript">function maze(x,y) { |
||
var n=x*y-1; |
var n=x*y-1; |
||
if (n<0) {alert("illegal maze dimensions");return;} |
if (n<0) {alert("illegal maze dimensions");return;} |
||
Line 4,788: | Line 4,788: | ||
} |
} |
||
return text.join(''); |
return text.join(''); |
||
}</ |
}</syntaxhighlight> |
||
Variable meanings in function <code>maze</code>: |
Variable meanings in function <code>maze</code>: |
||
# <code>x</code>,<code>y</code> — dimensions of maze |
# <code>x</code>,<code>y</code> — dimensions of maze |
||
Line 4,806: | Line 4,806: | ||
{{out|Example use}} |
{{out|Example use}} |
||
< |
<syntaxhighlight lang="html"><html><head><title></title></head><body><pre id="out"></pre></body></html> |
||
<script type="text/javascript"> |
<script type="text/javascript"> |
||
/* ABOVE CODE GOES HERE */ |
/* ABOVE CODE GOES HERE */ |
||
document.getElementById('out').innerHTML= display(maze(8,11)); |
document.getElementById('out').innerHTML= display(maze(8,11)); |
||
</script></ |
</script></syntaxhighlight> |
||
produced output: |
produced output: |
||
<pre>+ +---+---+---+---+---+---+---+---+---+---+ |
<pre>+ +---+---+---+---+---+---+---+---+---+---+ |
||
Line 4,832: | Line 4,832: | ||
For example, change replace the line <code>while (0<n) {</code> with: |
For example, change replace the line <code>while (0<n) {</code> with: |
||
< |
<syntaxhighlight lang="javascript"> function step() { |
||
if (0<n) {</ |
if (0<n) {</syntaxhighlight> |
||
And replace the closing brace for this while loop with: |
And replace the closing brace for this while loop with: |
||
< |
<syntaxhighlight lang="javascript"> document.getElementById('out').innerHTML= display({x: x, y: y, horiz: horiz, verti: verti, here: here}); |
||
setTimeout(step, 100); |
setTimeout(step, 100); |
||
} |
} |
||
} |
} |
||
step();</ |
step();</syntaxhighlight> |
||
To better see the progress, you might want a marker in place, showing the position being considered. To do that, replace the line which reads <code>if (0 == k%4) {</code> with |
To better see the progress, you might want a marker in place, showing the position being considered. To do that, replace the line which reads <code>if (0 == k%4) {</code> with |
||
< |
<syntaxhighlight lang="javascript"> if (m.here && m.here[0]*2+1 == j && m.here[1]*4+2 == k) |
||
line[k]= '#' |
line[k]= '#' |
||
else if (0 == k%4) {</ |
else if (0 == k%4) {</syntaxhighlight> |
||
Note however that this leaves the final '#' in place on maze completion, and that the function <code>maze</code> no longer returns a result which represents a generated maze. |
Note however that this leaves the final '#' in place on maze completion, and that the function <code>maze</code> no longer returns a result which represents a generated maze. |
||
Note also that this display suggests an optimization. You can replace the line reading <code>path.push(here= next);</code> with: |
Note also that this display suggests an optimization. You can replace the line reading <code>path.push(here= next);</code> with: |
||
< |
<syntaxhighlight lang="javascript"> here= next; |
||
if (1 < neighbors.length) |
if (1 < neighbors.length) |
||
path.push(here);</ |
path.push(here);</syntaxhighlight> |
||
And this does indeed save a negligible bit of processing, but the maze algorithm will still be forced to backtrack through a number of locations which have no unvisited neighbors. |
And this does indeed save a negligible bit of processing, but the maze algorithm will still be forced to backtrack through a number of locations which have no unvisited neighbors. |
||
===HTML Table=== |
===HTML Table=== |
||
Using HTML, CSS and table cells for maze. |
Using HTML, CSS and table cells for maze. |
||
< |
<syntaxhighlight lang="html"><html><head><title>Maze maker</title> |
||
<style type="text/css"> |
<style type="text/css"> |
||
table { border-collapse: collapse } |
table { border-collapse: collapse } |
||
Line 4,967: | Line 4,967: | ||
<a href="javascript:make_maze()">Generate</a> |
<a href="javascript:make_maze()">Generate</a> |
||
<a id='solve' style='display:none' href='javascript:solve(); void(0)'>Solve</a> |
<a id='solve' style='display:none' href='javascript:solve(); void(0)'>Solve</a> |
||
</fieldset></form><table id='maze'/></body></html></ |
</fieldset></form><table id='maze'/></body></html></syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 4,973: | Line 4,973: | ||
'''Generating functions''' |
'''Generating functions''' |
||
< |
<syntaxhighlight lang="julia">using Random |
||
check(bound::Vector) = cell -> all([1, 1] .≤ cell .≤ bound) |
check(bound::Vector) = cell -> all([1, 1] .≤ cell .≤ bound) |
||
neighbors(cell::Vector, bound::Vector, step::Int=2) = |
neighbors(cell::Vector, bound::Vector, step::Int=2) = |
||
Line 4,992: | Line 4,992: | ||
firstcell = 2 * [rand(1:w), rand(1:h)] |
firstcell = 2 * [rand(1:w), rand(1:h)] |
||
return walk(maze, firstcell) |
return walk(maze, firstcell) |
||
end</ |
end</syntaxhighlight> |
||
'''Printing functions''' |
'''Printing functions''' |
||
< |
<syntaxhighlight lang="julia">pprint(matrix) = for i = 1:size(matrix, 1) println(join(matrix[i, :])) end |
||
function printmaze(maze) |
function printmaze(maze) |
||
walls = split("╹ ╸ ┛ ╺ ┗ ━ ┻ ╻ ┃ ┓ ┫ ┏ ┣ ┳ ╋") |
walls = split("╹ ╸ ┛ ╺ ┗ ━ ┻ ╻ ┃ ┓ ┫ ┏ ┣ ┳ ╋") |
||
Line 5,008: | Line 5,008: | ||
printmaze(maze(10, 10)) |
printmaze(maze(10, 10)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 5,025: | Line 5,025: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang="scala">import java.util.* |
||
class MazeGenerator(val x: Int, val y: Int) { |
class MazeGenerator(val x: Int, val y: Int) { |
||
Line 5,091: | Line 5,091: | ||
display() |
display() |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
{{Works with|Lua|5.1}} |
{{Works with|Lua|5.1}} |
||
<syntaxhighlight lang="lua"> |
|||
<lang Lua> |
|||
math.randomseed( os.time() ) |
math.randomseed( os.time() ) |
||
Line 5,169: | Line 5,169: | ||
print(make_maze()) |
print(make_maze()) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre>################################# |
<pre>################################# |
||
Line 5,204: | Line 5,204: | ||
INT((currentx% + oldx%) / 2) return a double, because has 2 as double so we get (integer+integer)/double or integer/double or double. Int(0.5) return. |
INT((currentx% + oldx%) / 2) return a double, because has 2 as double so we get (integer+integer)/double or integer/double or double. Int(0.5) return. |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Maze { |
Module Maze { |
||
width% = 40 |
width% = 40 |
||
Line 5,261: | Line 5,261: | ||
} |
} |
||
Maze |
Maze |
||
</syntaxhighlight> |
|||
</lang> |
|||
===Depth-first search=== |
===Depth-first search=== |
||
Line 5,271: | Line 5,271: | ||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Maze2 { |
Module Maze2 { |
||
\\ depth-first search |
\\ depth-first search |
||
Line 5,342: | Line 5,342: | ||
} |
} |
||
Maze2 |
Maze2 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">MazeGraphics[m_, n_] := |
||
Block[{$RecursionLimit = Infinity, |
Block[{$RecursionLimit = Infinity, |
||
unvisited = Tuples[Range /@ {m, n}], maze}, |
unvisited = Tuples[Range /@ {m, n}], maze}, |
||
Line 5,359: | Line 5,359: | ||
RandomSample@{# + {0, 1}, # - {0, 1}, # + {1, 0}, # - {1, |
RandomSample@{# + {0, 1}, # - {0, 1}, # + {1, 0}, # - {1, |
||
0}}}]} &@RandomChoice@unvisited; maze]; |
0}}}]} &@RandomChoice@unvisited; maze]; |
||
maze = MazeGraphics[21, 13]</ |
maze = MazeGraphics[21, 13]</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
[[File:MathematicaMazeGraphics.png]] |
[[File:MathematicaMazeGraphics.png]] |
||
Line 5,365: | Line 5,365: | ||
{{Works with|Mathematica|9.0}} |
{{Works with|Mathematica|9.0}} |
||
Here I generate a maze as a graph. Vertices of the graph are cells and edges of the graph are removed walls. This version is mush faster and is convenient to solve. |
Here I generate a maze as a graph. Vertices of the graph are cells and edges of the graph are removed walls. This version is mush faster and is convenient to solve. |
||
< |
<syntaxhighlight lang="mathematica">MazeGraph[m_, n_] := |
||
Block[{$RecursionLimit = Infinity, grid = GridGraph[{m, n}], |
Block[{$RecursionLimit = Infinity, grid = GridGraph[{m, n}], |
||
unvisitedQ}, unvisitedQ[_] := True; |
unvisitedQ}, unvisitedQ[_] := True; |
||
Line 5,375: | Line 5,375: | ||
RandomChoice@VertexList@grid][[2, 1]], |
RandomChoice@VertexList@grid][[2, 1]], |
||
GraphLayout -> {"GridEmbedding", "Dimension" -> {m, n}}]]; |
GraphLayout -> {"GridEmbedding", "Dimension" -> {m, n}}]]; |
||
maze = MazeGraph[13, 21]</ |
maze = MazeGraph[13, 21]</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
[[File:MathematicaMazeGraph.png]] |
[[File:MathematicaMazeGraph.png]] |
||
=={{header|MATLAB}} / {{header|Octave}}== |
=={{header|MATLAB}} / {{header|Octave}}== |
||
< |
<syntaxhighlight lang="matlab">function M = makeMaze(n) |
||
showProgress = false; |
showProgress = false; |
||
Line 5,432: | Line 5,432: | ||
image(M-VISITED); |
image(M-VISITED); |
||
axis equal off;</ |
axis equal off;</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="nim">import random, sequtils, strutils |
||
randomize() |
randomize() |
||
Line 5,466: | Line 5,466: | ||
walk rand(0..<w), rand(0..<h) |
walk rand(0..<w), rand(0..<h) |
||
for a,b in zip(hor, ver & @[""]).items: |
for a,b in zip(hor, ver & @[""]).items: |
||
echo join(a & "+\n" & b)</ |
echo join(a & "+\n" & b)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,497: | Line 5,497: | ||
This difers of the basic Javascript in that in NodeJS we take advantage of the asynchronous behaviour. This code was modified from the plain Javascript section to make it '''Asynchronous''' and able to run under ''strict mode''. |
This difers of the basic Javascript in that in NodeJS we take advantage of the asynchronous behaviour. This code was modified from the plain Javascript section to make it '''Asynchronous''' and able to run under ''strict mode''. |
||
< |
<syntaxhighlight lang="javascript"> |
||
'use strict'; |
'use strict'; |
||
/* |
/* |
||
Line 5,597: | Line 5,597: | ||
display: display |
display: display |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out|Example use}} |
{{out|Example use}} |
||
Line 5,603: | Line 5,603: | ||
Here is a basic example of what your main file should contain: |
Here is a basic example of what your main file should contain: |
||
< |
<syntaxhighlight lang="javascript"> |
||
'use strict'; |
'use strict'; |
||
Line 5,620: | Line 5,620: | ||
}, (err) => console.error(err)); |
}, (err) => console.error(err)); |
||
</syntaxhighlight> |
|||
</lang> |
|||
Sample Output: |
Sample Output: |
||
Line 5,651: | Line 5,651: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang="ocaml">let seen = Hashtbl.create 7 |
||
let mark t = Hashtbl.add seen t true |
let mark t = Hashtbl.add seen t true |
||
let marked t = Hashtbl.mem seen t |
let marked t = Hashtbl.mem seen t |
||
Line 5,697: | Line 5,697: | ||
Random.self_init(); |
Random.self_init(); |
||
visit (Random.int nx, Random.int ny); |
visit (Random.int nx, Random.int ny); |
||
print_maze ();</ |
print_maze ();</syntaxhighlight> |
||
Output from 'ocaml gen_maze.ml 10 10':<pre>+---+---+---+---+---+---+---+---+---+---+ |
Output from 'ocaml gen_maze.ml 10 10':<pre>+---+---+---+---+---+---+---+---+---+---+ |
||
| | | | |
| | | | |
||
Line 5,722: | Line 5,722: | ||
=={{header|Ol}}== |
=={{header|Ol}}== |
||
< |
<syntaxhighlight lang="scheme"> |
||
; maze generation |
; maze generation |
||
(import (otus random!)) |
(import (otus random!)) |
||
Line 5,760: | Line 5,760: | ||
(loop nx ny))) |
(loop nx ny))) |
||
(try)))))) |
(try)))))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
< |
<syntaxhighlight lang="scheme"> |
||
; maze printing: |
; maze printing: |
||
(display "+") |
(display "+") |
||
Line 5,784: | Line 5,784: | ||
maze) |
maze) |
||
(print) |
(print) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out|Sample 30 x 8 output}} |
{{out|Sample 30 x 8 output}} |
||
<pre>+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
<pre>+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||
Line 5,805: | Line 5,805: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">use List::Util 'max'; |
||
my ($w, $h) = @ARGV; |
my ($w, $h) = @ARGV; |
||
Line 5,840: | Line 5,840: | ||
print @{$hor[$_]}, "+\n"; |
print @{$hor[$_]}, "+\n"; |
||
print @{$ver[$_]}, "|\n" if $_ < $h; |
print @{$ver[$_]}, "|\n" if $_ < $h; |
||
}</ |
}</syntaxhighlight> |
||
Run as <code>maze.pl [width] [height]</code> or use default dimensions. |
Run as <code>maze.pl [width] [height]</code> or use default dimensions. |
||
{{out|Sample 4 x 1 output}} |
{{out|Sample 4 x 1 output}} |
||
Line 5,850: | Line 5,850: | ||
Adapted a couple of techniques from the excellent D submission<br> |
Adapted a couple of techniques from the excellent D submission<br> |
||
(however this holds the grid as an array of complete lines) |
(however this holds the grid as an array of complete lines) |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #000080;font-style:italic;">-- |
<span style="color: #000080;font-style:italic;">-- |
||
Line 5,898: | Line 5,898: | ||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">grid</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">))</span> |
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">grid</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">))</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 5,922: | Line 5,922: | ||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
Code inspired by the D and Python solutions (with the implementation of backtracking, or sometimes it wouldn't work). Could have been done procedurally or fully OO (with cells as class too). A debug flag has been provided to allow following the inner workings. Works on PHP > 5.6. |
Code inspired by the D and Python solutions (with the implementation of backtracking, or sometimes it wouldn't work). Could have been done procedurally or fully OO (with cells as class too). A debug flag has been provided to allow following the inner workings. Works on PHP > 5.6. |
||
< |
<syntaxhighlight lang="php"><?php |
||
class Maze |
class Maze |
||
{ |
{ |
||
Line 6,069: | Line 6,069: | ||
$maze = new Maze(10,10); |
$maze = new Maze(10,10); |
||
$maze->printOut();</ |
$maze->printOut();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 6,096: | Line 6,096: | ||
=={{header|Picat}}== |
=={{header|Picat}}== |
||
< |
<syntaxhighlight lang="picat">main => |
||
gen_maze(8,8). |
gen_maze(8,8). |
||
Line 6,156: | Line 6,156: | ||
end, |
end, |
||
println("+"). |
println("+"). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 6,180: | Line 6,180: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
This solution uses 'grid' from "lib/simul.l" to generate the two-dimensional structure. |
This solution uses 'grid' from "lib/simul.l" to generate the two-dimensional structure. |
||
< |
<syntaxhighlight lang="picolisp">(load "@lib/simul.l") |
||
(de maze (DX DY) |
(de maze (DX DY) |
||
Line 6,209: | Line 6,209: | ||
(de display (Maze) |
(de display (Maze) |
||
(disp Maze 0 '((This) " ")) )</ |
(disp Maze 0 '((This) " ")) )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>: (display (maze 11 8)) |
<pre>: (display (maze 11 8)) |
||
Line 6,233: | Line 6,233: | ||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
{{trans|REXX}} |
{{trans|REXX}} |
||
< |
<syntaxhighlight lang="pli">*process source attributes xref or(!); |
||
mgg: Proc Options(main); |
mgg: Proc Options(main); |
||
/* REXX *************************************************************** |
/* REXX *************************************************************** |
||
Line 6,449: | Line 6,449: | ||
End; |
End; |
||
End;</ |
End;</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 6,468: | Line 6,468: | ||
=={{header|Processing}}== |
=={{header|Processing}}== |
||
< |
<syntaxhighlight lang="java">int g_size = 10; |
||
color background_color = color (80, 80, 220); |
color background_color = color (80, 80, 220); |
||
color runner = color (255, 50, 50); |
color runner = color (255, 50, 50); |
||
Line 6,594: | Line 6,594: | ||
if(wall[3]) line((j+1)*c_size, i*c_size, j*c_size, i*c_size); |
if(wall[3]) line((j+1)*c_size, i*c_size, j*c_size, i*c_size); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
'''It can be played on line''' :<BR> [https://www.openprocessing.org/sketch/880778/ here.] |
'''It can be played on line''' :<BR> [https://www.openprocessing.org/sketch/880778/ here.] |
||
==={{header|Processing Python mode}}=== |
==={{header|Processing Python mode}}=== |
||
< |
<syntaxhighlight lang="python"> |
||
g_size = 10 |
g_size = 10 |
||
background_color = color(80, 80, 220) |
background_color = color(80, 80, 220) |
||
Line 6,722: | Line 6,722: | ||
if wall[2]: line((j + 1) * c_size, (i + 1) * c_size, (j + 1) * c_size, i * c_size) |
if wall[2]: line((j + 1) * c_size, (i + 1) * c_size, (j + 1) * c_size, i * c_size) |
||
if wall[3]: line((j + 1) * c_size, i * c_size, j * c_size, i * c_size) |
if wall[3]: line((j + 1) * c_size, i * c_size, j * c_size, i * c_size) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
Works with SWI-Prolog and XPCE. |
Works with SWI-Prolog and XPCE. |
||
< |
<syntaxhighlight lang="prolog">:- dynamic cell/2. |
||
maze(Lig,Col) :- |
maze(Lig,Col) :- |
||
Line 6,816: | Line 6,816: | ||
\+cell(L, C1). |
\+cell(L, C1). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
[[File:Prolog-Maze.jpg]] |
[[File:Prolog-Maze.jpg]] |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">Enumeration |
||
;indexes for types of offsets from maze coordinates (x,y) |
;indexes for types of offsets from maze coordinates (x,y) |
||
#visited ;used to index visited(x,y) in a given direction from current maze cell |
#visited ;used to index visited(x,y) in a given direction from current maze cell |
||
Line 6,956: | Line 6,956: | ||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input() |
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input() |
||
CloseConsole() |
CloseConsole() |
||
EndIf</ |
EndIf</syntaxhighlight> |
||
The maze is represented by an array of cells where each cell indicates the walls present above (#dir_N) and to its left (#dir_W). Maze generation is done with a additional array marking the visited cells. Neither an entry nor an exit are created, these were not part of the task. A simple means of doing so is included but has been commented out. |
The maze is represented by an array of cells where each cell indicates the walls present above (#dir_N) and to its left (#dir_W). Maze generation is done with a additional array marking the visited cells. Neither an entry nor an exit are created, these were not part of the task. A simple means of doing so is included but has been commented out. |
||
Line 6,980: | Line 6,980: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python">from random import shuffle, randrange |
||
def make_maze(w = 16, h = 8): |
def make_maze(w = 16, h = 8): |
||
Line 7,006: | Line 7,006: | ||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
print(make_maze())</ |
print(make_maze())</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
<pre>+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||
Line 7,029: | Line 7,029: | ||
Maze generator |
Maze generator |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
Line 7,060: | Line 7,060: | ||
; return the result |
; return the result |
||
(maze N M tbl)) |
(maze N M tbl)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Printing out the maze |
Printing out the maze |
||
< |
<syntaxhighlight lang="racket"> |
||
;; Shows a maze |
;; Shows a maze |
||
(define (show-maze m) |
(define (show-maze m) |
||
Line 7,084: | Line 7,084: | ||
(displayln "+")) |
(displayln "+")) |
||
(newline)) |
(newline)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Example: |
Example: |
||
Line 7,111: | Line 7,111: | ||
{{works with|rakudo|2015-09-22}} |
{{works with|rakudo|2015-09-22}} |
||
Supply a width and height and optionally the x,y grid coords for the starting cell. If no starting cell is supplied, a random one will be selected automatically. 0,0 is the top left corner. |
Supply a width and height and optionally the x,y grid coords for the starting cell. If no starting cell is supplied, a random one will be selected automatically. 0,0 is the top left corner. |
||
<lang |
<syntaxhighlight lang="raku" line>constant mapping = :OPEN(' '), |
||
:N< ╵ >, |
:N< ╵ >, |
||
:E< ╶ >, |
:E< ╶ >, |
||
Line 7,197: | Line 7,197: | ||
} |
} |
||
display gen_maze( 29, 19 );</ |
display gen_maze( 29, 19 );</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<small><pre style="font-family: consolas, inconsolata, monospace; line-height: normal;">┌ ╵ ────────────────────────────┬───────────────────────────────────────────┬───────────┬───────────────────────────┐ |
<small><pre style="font-family: consolas, inconsolata, monospace; line-height: normal;">┌ ╵ ────────────────────────────┬───────────────────────────────────────────┬───────────┬───────────────────────────┐ |
||
Line 7,241: | Line 7,241: | ||
=={{header|Rascal}}== |
=={{header|Rascal}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="rascal">import IO; |
||
import util::Math; |
import util::Math; |
||
import List; |
import List; |
||
Line 7,269: | Line 7,269: | ||
println(("" | it + "<z>" | z <- b)); |
println(("" | it + "<z>" | z <- b)); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre>rascal>make_maze(10,10) |
<pre>rascal>make_maze(10,10) |
||
Line 7,298: | Line 7,298: | ||
=={{header|Red}}== |
=={{header|Red}}== |
||
< |
<syntaxhighlight lang="red">Red ["Maze generation"] |
||
size: as-pair to-integer ask "Maze width: " to-integer ask "Maze height: " |
size: as-pair to-integer ask "Maze width: " to-integer ask "Maze height: " |
||
Line 7,345: | Line 7,345: | ||
] |
] |
||
print "" |
print "" |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Maze width: 15 |
<pre>Maze width: 15 |
||
Line 7,371: | Line 7,371: | ||
In order to preserve the aspect ratio (for most display terminals), several '''changestr''' invocations and |
In order to preserve the aspect ratio (for most display terminals), several '''changestr''' invocations and |
||
<br>some other instructions were added to increase the horizontal dimension (cell size). |
<br>some other instructions were added to increase the horizontal dimension (cell size). |
||
< |
<syntaxhighlight lang="rexx">/*REXX program generates and displays a rectangular solvable maze (of any size). */ |
||
parse arg rows cols seed . /*allow user to specify the maze size. */ |
parse arg rows cols seed . /*allow user to specify the maze size. */ |
||
if rows='' | rows==',' then rows= 19 /*No rows given? Then use the default.*/ |
if rows='' | rows==',' then rows= 19 /*No rows given? Then use the default.*/ |
||
Line 7,467: | Line 7,467: | ||
otherwise nop |
otherwise nop |
||
end /*select*/ |
end /*select*/ |
||
end /*k*/; return</ |
end /*k*/; return</syntaxhighlight> |
||
Some older REXXes don't have a '''changestr''' BIF, so one is included here ──► [[CHANGESTR.REX]]. |
Some older REXXes don't have a '''changestr''' BIF, so one is included here ──► [[CHANGESTR.REX]]. |
||
Line 7,527: | Line 7,527: | ||
The above REXX version had a quite of bit of code to "dress up" the maze presentation, so a slimmed-down version |
The above REXX version had a quite of bit of code to "dress up" the maze presentation, so a slimmed-down version |
||
<br>was included here for easier reading and understanding of the program's logic. |
<br>was included here for easier reading and understanding of the program's logic. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program generates and displays a rectangular solvable maze (of any size). */ |
||
parse arg rows cols seed . /*allow user to specify the maze size. */ |
parse arg rows cols seed . /*allow user to specify the maze size. */ |
||
if rows='' | rows=="," then rows= 19 /*No rows given? Then use the default.*/ |
if rows='' | rows=="," then rows= 19 /*No rows given? Then use the default.*/ |
||
Line 7,580: | Line 7,580: | ||
if hood(rr,cc)==1 then do; r!= rr; c!= cc; @.r!.c!= 0; return 1; end |
if hood(rr,cc)==1 then do; r!= rr; c!= cc; @.r!.c!= 0; return 1; end |
||
end /*c*/ /* [↑] r! and c! are used by invoker.*/ |
end /*c*/ /* [↑] r! and c! are used by invoker.*/ |
||
end /*r*/; return 0</ |
end /*r*/; return 0</syntaxhighlight> |
||
{{out|output|text= when using input: <tt> 10 10 </tt>}} |
{{out|output|text= when using input: <tt> 10 10 </tt>}} |
||
Line 7,610: | Line 7,610: | ||
===version 3=== |
===version 3=== |
||
< |
<syntaxhighlight lang="rexx">/* REXX *************************************************************** |
||
* 04.09.2013 Walter Pachl |
* 04.09.2013 Walter Pachl |
||
**********************************************************************/ |
**********************************************************************/ |
||
Line 7,777: | Line 7,777: | ||
End |
End |
||
End |
End |
||
Return is js /* return the new start point*/</ |
Return is js /* return the new start point*/</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 7,798: | Line 7,798: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">class Maze |
||
DIRECTIONS = [ [1, 0], [-1, 0], [0, 1], [0, -1] ] |
DIRECTIONS = [ [1, 0], [-1, 0], [0, 1], [0, -1] ] |
||
Line 7,892: | Line 7,892: | ||
# Demonstration: |
# Demonstration: |
||
maze = Maze.new 20, 10 |
maze = Maze.new 20, 10 |
||
maze.print</ |
maze.print</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 7,921: | Line 7,921: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Uses the [https://crates.io/crates/rand rand] library |
Uses the [https://crates.io/crates/rand rand] library |
||
< |
<syntaxhighlight lang="rust">use rand::{thread_rng, Rng, rngs::ThreadRng}; |
||
const WIDTH: usize = 16; |
const WIDTH: usize = 16; |
||
Line 8,057: | Line 8,057: | ||
maze.open_doors(); |
maze.open_doors(); |
||
maze.paint(); |
maze.paint(); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 8,095: | Line 8,095: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<syntaxhighlight lang="scala">import scala.util.Random |
||
object MazeTypes { |
object MazeTypes { |
||
Line 8,180: | Line 8,180: | ||
private def openInDirection(loc: Loc, dir: Direction): Boolean = |
private def openInDirection(loc: Loc, dir: Direction): Boolean = |
||
doors.contains(Door(loc, loc + dir)) || doors.contains(Door(loc + dir, loc)) |
doors.contains(Door(loc, loc + dir)) || doors.contains(Door(loc + dir, loc)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 8,218: | Line 8,218: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang="ruby">var(w:5, h:5) = ARGV.map{.to_i}... |
||
var avail = (w * h) |
var avail = (w * h) |
||
Line 8,250: | Line 8,250: | ||
say (ver[i].join('') + '|') |
say (ver[i].join('') + '|') |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 8,267: | Line 8,267: | ||
=={{header|SuperCollider}}== |
=={{header|SuperCollider}}== |
||
<syntaxhighlight lang="supercollider"> |
|||
<lang SuperCollider> |
|||
// some useful functions |
// some useful functions |
||
( |
( |
||
Line 8,324: | Line 8,324: | ||
w.front.refresh; |
w.front.refresh; |
||
) |
) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
{{works with|Swift|3}} |
{{works with|Swift|3}} |
||
< |
<syntaxhighlight lang="swift">import Foundation |
||
extension Array { |
extension Array { |
||
Line 8,496: | Line 8,496: | ||
let y = 10 |
let y = 10 |
||
let maze = MazeGenerator(x, y) |
let maze = MazeGenerator(x, y) |
||
maze.display()</ |
maze.display()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 8,523: | Line 8,523: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{trans|Javascript}} |
{{trans|Javascript}} |
||
< |
<syntaxhighlight lang="tcl">package require TclOO; # Or Tcl 8.6 |
||
# Helper to pick a random number |
# Helper to pick a random number |
||
Line 8,619: | Line 8,619: | ||
# Demonstration |
# Demonstration |
||
maze create m 11 8 |
maze create m 11 8 |
||
puts [m view]</ |
puts [m view]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 8,647: | Line 8,647: | ||
Legend: cu = current location; vi = boolean hash of visited locations; pa = hash giving a list neighboring cells to which there is a path from a given cell. |
Legend: cu = current location; vi = boolean hash of visited locations; pa = hash giving a list neighboring cells to which there is a path from a given cell. |
||
< |
<syntaxhighlight lang="txr">@(bind (width height) (15 15)) |
||
@(do |
@(do |
||
(defvar *r* (make-random-state nil)) |
(defvar *r* (make-random-state nil)) |
||
Line 8,701: | Line 8,701: | ||
@;; |
@;; |
||
@(bind m @(make-maze width height)) |
@(bind m @(make-maze width height)) |
||
@(do (print-maze m width height))</ |
@(do (print-maze m width height))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 8,766: | Line 8,766: | ||
At the user interface level, the straightness parameter is represented as a percentage. This percentage is converted to a number of cells based on the width and height of the maze. For instance if the straightness parameter is 15, and the maze size is 20x20, it means that 15% out of 400 cells, or 60 cells will be traversed before the queue is scrambled. Then another 60 will be traversed and the queue will be scrambled, and so forth. |
At the user interface level, the straightness parameter is represented as a percentage. This percentage is converted to a number of cells based on the width and height of the maze. For instance if the straightness parameter is 15, and the maze size is 20x20, it means that 15% out of 400 cells, or 60 cells will be traversed before the queue is scrambled. Then another 60 will be traversed and the queue will be scrambled, and so forth. |
||
< |
<syntaxhighlight lang="txrlisp">(defvar vi) ;; visited hash |
||
(defvar pa) ;; path connectivity hash |
(defvar pa) ;; path connectivity hash |
||
(defvar sc) ;; count, derived from straightness fator |
(defvar sc) ;; count, derived from straightness fator |
||
Line 8,845: | Line 8,845: | ||
(set h (max 1 h)) |
(set h (max 1 h)) |
||
(print-maze (make-maze w h s) w h)) |
(print-maze (make-maze w h s) w h)) |
||
(else (usage))))</ |
(else (usage))))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 8,960: | Line 8,960: | ||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">code Ran=1, CrLf=9, Text=12; \intrinsic routines |
||
def Cols=20, Rows=6; \dimensions of maze (cells) |
def Cols=20, Rows=6; \dimensions of maze (cells) |
||
int Cell(Cols+1, Rows+1, 3); \cells (plus right and bottom borders) |
int Cell(Cols+1, Rows+1, 3); \cells (plus right and bottom borders) |
||
Line 9,003: | Line 9,003: | ||
Text(0, if Y#Rows & Cell(X, Y, LeftWall) then "| " else " "); |
Text(0, if Y#Rows & Cell(X, Y, LeftWall) then "| " else " "); |
||
]; |
]; |
||
]</ |
]</syntaxhighlight> |
||
Output: |
Output: |
||
Line 9,025: | Line 9,025: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|Kotlin}} |
{{trans|Kotlin}} |
||
< |
<syntaxhighlight lang="ecmascript">import "random" for Random |
||
import "os" for Process |
import "os" for Process |
||
Line 9,111: | Line 9,111: | ||
var mg = MazeGenerator.new(x, y) |
var mg = MazeGenerator.new(x, y) |
||
mg.generate(0, 0) |
mg.generate(0, 0) |
||
mg.display()</ |
mg.display()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 9,138: | Line 9,138: | ||
Generate a maze without marked entry or exit points. |
Generate a maze without marked entry or exit points. |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="zkl"> |
||
fcn make_maze(w = 16, h = 8){ |
fcn make_maze(w = 16, h = 8){ |
||
// make arrays with lists of lists (all mutable) |
// make arrays with lists of lists (all mutable) |
||
Line 9,159: | Line 9,159: | ||
return(ver,hor); |
return(ver,hor); |
||
} |
} |
||
make_maze();</ |
make_maze();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |