langs a-z
This commit is contained in:
parent
db842d013d
commit
d066446780
11389 changed files with 98361 additions and 1020 deletions
52
Task/Maze-generation/OCaml/maze-generation.ocaml
Normal file
52
Task/Maze-generation/OCaml/maze-generation.ocaml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
let seen = Hashtbl.create 7
|
||||
let mark t = Hashtbl.add seen t true
|
||||
let marked t = Hashtbl.mem seen t
|
||||
|
||||
let walls = Hashtbl.create 7
|
||||
let ord a b = if a <= b then (a,b) else (b,a)
|
||||
let join a b = Hashtbl.add walls (ord a b) true
|
||||
let joined a b = Hashtbl.mem walls (ord a b)
|
||||
|
||||
let () =
|
||||
let nx = int_of_string Sys.argv.(1) in
|
||||
let ny = int_of_string Sys.argv.(2) in
|
||||
|
||||
let rec random_order = function
|
||||
| [] -> []
|
||||
| [a] -> [a]
|
||||
| x -> let i = Random.int (List.length x) in
|
||||
let rec del i = function
|
||||
| [] -> failwith "del"
|
||||
| h::t -> if i = 0 then t else h :: del (i-1) t in
|
||||
(List.nth x i) :: random_order (del i x) in
|
||||
|
||||
let get_neighbours (x,y) =
|
||||
let lim n k = (0 <= k) && (k < n) in
|
||||
let bounds (x,y) = lim nx x && lim ny y in
|
||||
List.filter bounds [(x-1,y);(x+1,y);(x,y-1);(x,y+1)] in
|
||||
|
||||
let rec visit cell =
|
||||
mark cell;
|
||||
let check k =
|
||||
if not (marked k) then (join cell k; visit k) in
|
||||
List.iter check (random_order (get_neighbours cell)) in
|
||||
|
||||
let print_maze () =
|
||||
begin
|
||||
for i = 1 to nx do print_string "+---";done; print_endline "+";
|
||||
let line n j k l s t u =
|
||||
for i = 0 to n do print_string (if joined (i,j) (i+k,j+l) then s else t) done;
|
||||
print_endline u in
|
||||
for j = 0 to ny-2 do
|
||||
print_string "| ";
|
||||
line (nx-2) j 1 0 " " "| " "|";
|
||||
line (nx-1) j 0 1 "+ " "+---" "+";
|
||||
done;
|
||||
print_string "| ";
|
||||
line (nx-2) (ny-1) 1 0 " " "| " "|";
|
||||
for i = 1 to nx do print_string "+---";done; print_endline "+";
|
||||
end in
|
||||
|
||||
Random.self_init();
|
||||
visit (Random.int nx, Random.int ny);
|
||||
print_maze ();
|
||||
87
Task/Maze-generation/Perl-6/maze-generation.pl6
Normal file
87
Task/Maze-generation/Perl-6/maze-generation.pl6
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
constant mapping = :OPEN(' '),
|
||||
:N< ╵ >,
|
||||
:E< ╶ >,
|
||||
:NE< └ >,
|
||||
:S< ╷ >,
|
||||
:NS< │ >,
|
||||
:ES< ┌ >,
|
||||
:NES< ├ >,
|
||||
:W< ╴ >,
|
||||
:NW< ┘ >,
|
||||
:EW< ─ >,
|
||||
:NEW< ┴ >,
|
||||
:SW< ┐ >,
|
||||
:NSW< ┤ >,
|
||||
:ESW< ┬ >,
|
||||
:NESW< ┼ >,
|
||||
:TODO< x >,
|
||||
:TRIED< · >;
|
||||
|
||||
enum Code (mapping.map: *.key);
|
||||
my @code = mapping.map: *.value;
|
||||
|
||||
enum Direction <DeadEnd Up Right Down Left>;
|
||||
|
||||
sub gen_maze ( $X,
|
||||
$Y,
|
||||
$start_x = (^$X).pick * 2 + 1,
|
||||
$start_y = (^$Y).pick * 2 + 1 )
|
||||
{
|
||||
my @maze;
|
||||
push @maze, [ ES, -N, (ESW, EW) xx $X - 1, SW ];
|
||||
push @maze, [ (NS, TODO) xx $X, NS ];
|
||||
for 1 ..^ $Y {
|
||||
push @maze, [ NES, EW, (NESW, EW) xx $X - 1, NSW ];
|
||||
push @maze, [ (NS, TODO) xx $X, NS ];
|
||||
}
|
||||
push @maze, [ NE, (EW, NEW) xx $X - 1, -NS, NW ];
|
||||
@maze[$start_y][$start_x] = OPEN;
|
||||
|
||||
my @stack;
|
||||
my $current = [$start_x, $start_y];
|
||||
loop {
|
||||
if my $dir = pick_direction( $current ) {
|
||||
@stack.push: $current;
|
||||
$current = move( $dir, $current );
|
||||
}
|
||||
else {
|
||||
last unless @stack;
|
||||
$current = @stack.pop;
|
||||
}
|
||||
}
|
||||
return @maze;
|
||||
|
||||
sub pick_direction([$x,$y]) {
|
||||
my @neighbors =
|
||||
(Up if @maze[$y - 2][$x]),
|
||||
(Down if @maze[$y + 2][$x]),
|
||||
(Left if @maze[$y][$x - 2]),
|
||||
(Right if @maze[$y][$x + 2]);
|
||||
@neighbors.pick or DeadEnd;
|
||||
}
|
||||
|
||||
sub move ($dir, @cur) {
|
||||
my ($x,$y) = @cur;
|
||||
given $dir {
|
||||
when Up { @maze[--$y][$x] = OPEN; @maze[$y][$x-1] -= E; @maze[$y--][$x+1] -= W; }
|
||||
when Down { @maze[++$y][$x] = OPEN; @maze[$y][$x-1] -= E; @maze[$y++][$x+1] -= W; }
|
||||
when Left { @maze[$y][--$x] = OPEN; @maze[$y-1][$x] -= S; @maze[$y+1][$x--] -= N; }
|
||||
when Right { @maze[$y][++$x] = OPEN; @maze[$y-1][$x] -= S; @maze[$y+1][$x++] -= N; }
|
||||
}
|
||||
@maze[$y][$x] = 0;
|
||||
[$x,$y];
|
||||
}
|
||||
}
|
||||
|
||||
sub display (@maze) {
|
||||
for @maze -> @y {
|
||||
for @y -> $w, $c {
|
||||
print @code[abs $w];
|
||||
if $c >= 0 { print @code[$c] x 3 }
|
||||
else { print ' ', @code[abs $c], ' ' }
|
||||
}
|
||||
say @code[@y[*-1]];
|
||||
}
|
||||
}
|
||||
|
||||
display gen_maze( 29, 19 );
|
||||
136
Task/Maze-generation/PureBasic/maze-generation.purebasic
Normal file
136
Task/Maze-generation/PureBasic/maze-generation.purebasic
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
Enumeration
|
||||
;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
|
||||
#maze ;used to index maze() in a given direction from current maze cell
|
||||
#wall ;used to index walls in maze() in a given direction from current maze cell
|
||||
#numOffsets = #wall
|
||||
;direction indexes
|
||||
#dir_ID = 0 ;identity value, produces no changes
|
||||
#firstDir
|
||||
#dir_N = #firstDir
|
||||
#dir_E
|
||||
#dir_S
|
||||
#dir_W
|
||||
#numDirs = #dir_W
|
||||
EndEnumeration
|
||||
|
||||
DataSection
|
||||
;maze(x,y) offsets for visited, maze, & walls for each direction
|
||||
Data.i 1, 1, 0, 0, 0, 0 ;ID
|
||||
Data.i 1, 0, 0, -1, 0, 0 ;N
|
||||
Data.i 2, 1, 1, 0, 1, 0 ;E
|
||||
Data.i 1, 2, 0, 1, 0, 1 ;S
|
||||
Data.i 0, 1, -1, 0, 0, 0 ;W
|
||||
Data.i %00, %01, %10, %01, %10 ;wall values for ID, N, E, S, W
|
||||
EndDataSection
|
||||
|
||||
#cellDWidth = 4
|
||||
|
||||
Structure mazeOutput
|
||||
vWall.s
|
||||
hWall.s
|
||||
EndStructure
|
||||
|
||||
|
||||
;setup reference values indexed by type and direction from current map cell
|
||||
Global Dim offset.POINT(#numOffsets, #numDirs)
|
||||
Define i, j
|
||||
For i = 0 To #numDirs
|
||||
For j = 0 To #numOffsets
|
||||
Read.i offset(j, i)\x: Read.i offset(j, i)\y
|
||||
Next
|
||||
Next
|
||||
|
||||
Global Dim wallvalue(#numDirs)
|
||||
For i = 0 To #numDirs: Read.i wallvalue(i): Next
|
||||
|
||||
|
||||
Procedure makeDisplayMazeRow(Array mazeRow.mazeOutput(1), Array maze(2), y)
|
||||
;modify mazeRow() to produce output of 2 strings showing the vertical walls above and horizontal walls across a given maze row
|
||||
Protected x, vWall.s, hWall.s
|
||||
Protected mazeWidth = ArraySize(maze(), 1), mazeHeight = ArraySize(maze(), 2)
|
||||
|
||||
vWall = "": hWall = ""
|
||||
For x = 0 To mazeWidth
|
||||
If maze(x, y) & wallvalue(#dir_N): vWall + "+ ": Else: vWall + "+---": EndIf
|
||||
If maze(x, y) & wallvalue(#dir_W): hWall + " ": Else: hWall + "| ": EndIf
|
||||
Next
|
||||
mazeRow(0)\vWall = Left(vWall, mazeWidth * #cellDWidth + 1)
|
||||
If y <> mazeHeight: mazeRow(0)\hWall = Left(hWall, mazeWidth * #cellDWidth + 1): Else: mazeRow(0)\hWall = "": EndIf
|
||||
EndProcedure
|
||||
|
||||
Procedure displayMaze(Array maze(2))
|
||||
Protected x, y, vWall.s, hWall.s, mazeHeight = ArraySize(maze(), 2)
|
||||
Protected Dim mazeRow.mazeOutput(0)
|
||||
|
||||
For y = 0 To mazeHeight
|
||||
makeDisplayMazeRow(mazeRow(), maze(), y)
|
||||
PrintN(mazeRow(0)\vWall): PrintN(mazeRow(0)\hWall)
|
||||
Next
|
||||
EndProcedure
|
||||
|
||||
Procedure generateMaze(Array maze(2), mazeWidth, mazeHeight)
|
||||
Dim maze(mazeWidth, mazeHeight) ;Each cell specifies walls present above and to the left of it,
|
||||
;array includes an extra row and column for the right and bottom walls
|
||||
Dim visited(mazeWidth + 1, mazeHeight + 1) ;Each cell represents a cell of the maze, an extra line of cells are included
|
||||
;as padding around the representative cells for easy border detection
|
||||
|
||||
Protected i
|
||||
;mark outside border as already visited (off limits)
|
||||
For i = 0 To mazeWidth
|
||||
visited(i + offset(#visited, #dir_N)\x, 0 + offset(#visited, #dir_N)\y) = #True
|
||||
visited(i + offset(#visited, #dir_S)\x, mazeHeight - 1 + offset(#visited, #dir_S)\y) = #True
|
||||
Next
|
||||
For i = 0 To mazeHeight
|
||||
visited(0 + offset(#visited, #dir_W)\x, i + offset(#visited, #dir_W)\y) = #True
|
||||
visited(mazeWidth - 1 + offset(#visited, #dir_E)\x, i + offset(#visited, #dir_E)\y) = #True
|
||||
Next
|
||||
|
||||
;generate maze
|
||||
Protected x = Random(mazeWidth - 1), y = Random (mazeHeight - 1), cellCount, nextCell
|
||||
visited(x + offset(#visited, #dir_ID)\x, y + offset(#visited, #dir_ID)\y) = #True
|
||||
PrintN("Maze of size " + Str(mazeWidth) + " x " + Str(mazeHeight) + ", generation started at " + Str(x) + " x " + Str(y))
|
||||
|
||||
NewList stack.POINT()
|
||||
Dim unvisited(#numDirs - #firstDir)
|
||||
Repeat
|
||||
cellCount = 0
|
||||
For i = #firstDir To #numDirs
|
||||
If Not visited(x + offset(#visited, i)\x, y + offset(#visited, i)\y)
|
||||
unvisited(cellCount) = i: cellCount + 1
|
||||
EndIf
|
||||
Next
|
||||
|
||||
If cellCount
|
||||
nextCell = unvisited(Random(cellCount - 1))
|
||||
visited(x + offset(#visited, nextCell)\x, y + offset(#visited, nextCell)\y) = #True
|
||||
maze(x + offset(#wall, nextCell)\x, y + offset(#wall, nextCell)\y) | wallvalue(nextCell)
|
||||
|
||||
If cellCount > 1
|
||||
AddElement(stack())
|
||||
stack()\x = x: stack()\y = y
|
||||
EndIf
|
||||
x + offset(#maze, nextCell)\x: y + offset(#maze, nextCell)\y
|
||||
ElseIf ListSize(stack()) > 0
|
||||
x = stack()\x: y = stack()\y
|
||||
DeleteElement(stack())
|
||||
Else
|
||||
Break ;end maze generation
|
||||
EndIf
|
||||
ForEver
|
||||
|
||||
; ;mark random entry and exit point
|
||||
; x = Random(mazeWidth - 1): y = Random(mazeHeight - 1)
|
||||
; maze(x, 0) | wallvalue(#dir_N): maze(mazeWidth, y) | wallvalue(#dir_E)
|
||||
ProcedureReturn
|
||||
EndProcedure
|
||||
|
||||
If OpenConsole()
|
||||
Dim maze(0, 0)
|
||||
Define mazeWidth = Random(5) + 7: mazeHeight = Random(5) + 3
|
||||
generateMaze(maze(), mazeWidth, mazeHeight)
|
||||
displayMaze(maze())
|
||||
|
||||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
|
||||
CloseConsole()
|
||||
EndIf
|
||||
29
Task/Maze-generation/Rascal/maze-generation.rascal
Normal file
29
Task/Maze-generation/Rascal/maze-generation.rascal
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import IO;
|
||||
import util::Math;
|
||||
import List;
|
||||
|
||||
public void make_maze(int w, int h){
|
||||
vis = [[0 | _ <- [1..w]] | _ <- [1..h]];
|
||||
ver = [["| "| _ <- [1..w]] + ["|"] | _ <- [1..h]] + [[]];
|
||||
hor = [["+--"| _ <- [1..w]] + ["+"] | _ <- [1..h + 1]];
|
||||
|
||||
void walk(int x, int y){
|
||||
vis[y][x] = 1;
|
||||
|
||||
d = [<x - 1, y>, <x, y + 1>, <x + 1, y>, <x, y - 1>];
|
||||
while (d != []){
|
||||
<<xx, yy>, d> = takeOneFrom(d);
|
||||
if (xx < 0 || yy < 0 || xx >= w || yy >= w) continue;
|
||||
if (vis[yy][xx] == 1) continue;
|
||||
if (xx == x) hor[max([y, yy])][x] = "+ ";
|
||||
if (yy == y) ver[y][max([x, xx])] = " ";
|
||||
walk(xx, yy);
|
||||
}
|
||||
}
|
||||
|
||||
walk(arbInt(w), arbInt(h));
|
||||
for (<a, b> <- zip(hor, ver)){
|
||||
println(("" | it + "<z>" | z <- a));
|
||||
println(("" | it + "<z>" | z <- b));
|
||||
}
|
||||
}
|
||||
44
Task/Maze-generation/XPL0/maze-generation.xpl0
Normal file
44
Task/Maze-generation/XPL0/maze-generation.xpl0
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
code Ran=1, CrLf=9, Text=12; \intrinsic routines
|
||||
def Cols=20, Rows=6; \dimensions of maze (cells)
|
||||
int Cell(Cols+1, Rows+1, 3); \cells (plus right and bottom borders)
|
||||
def LeftWall, Ceiling, Connected; \attributes of each cell (= 0, 1 and 2)
|
||||
|
||||
proc ConnectFrom(X, Y); \Connect cells starting from cell X,Y
|
||||
int X, Y;
|
||||
int Dir, Dir0;
|
||||
[Cell(X, Y, Connected):= true; \mark current cell as connected
|
||||
Dir:= Ran(4); \randomly choose a direction
|
||||
Dir0:= Dir; \save this initial direction
|
||||
repeat case Dir of \try to connect to cell at Dir
|
||||
0: if X+1<Cols & not Cell(X+1, Y, Connected) then \go right
|
||||
[Cell(X+1, Y, LeftWall):= false; ConnectFrom(X+1, Y)];
|
||||
1: if Y+1<Rows & not Cell(X, Y+1, Connected) then \go down
|
||||
[Cell(X, Y+1, Ceiling):= false; ConnectFrom(X, Y+1)];
|
||||
2: if X-1>=0 & not Cell(X-1, Y, Connected) then \go left
|
||||
[Cell(X, Y, LeftWall):= false; ConnectFrom(X-1, Y)];
|
||||
3: if Y-1>=0 & not Cell(X, Y-1, Connected) then \go up
|
||||
[Cell(X, Y, Ceiling):= false; ConnectFrom(X, Y-1)]
|
||||
other []; \(never occurs)
|
||||
Dir:= Dir+1 & $03; \next direction
|
||||
until Dir = Dir0;
|
||||
];
|
||||
|
||||
int X, Y;
|
||||
[for Y:= 0 to Rows do
|
||||
for X:= 0 to Cols do
|
||||
[Cell(X, Y, LeftWall):= true; \start with all walls and
|
||||
Cell(X, Y, Ceiling):= true; \ ceilings in place
|
||||
Cell(X, Y, Connected):= false; \ and all cells disconnected
|
||||
];
|
||||
Cell(0, 0, LeftWall):= false; \make left and right doorways
|
||||
Cell(Cols, Rows-1, LeftWall):= false;
|
||||
ConnectFrom(Ran(Cols), Ran(Rows)); \randomly pick a starting cell
|
||||
for Y:= 0 to Rows do \display the maze
|
||||
[CrLf(0);
|
||||
for X:= 0 to Cols do
|
||||
Text(0, if X#Cols & Cell(X, Y, Ceiling) then "+--" else "+ ");
|
||||
CrLf(0);
|
||||
for X:= 0 to Cols do
|
||||
Text(0, if Y#Rows & Cell(X, Y, LeftWall) then "| " else " ");
|
||||
];
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue