Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -0,0 +1,6 @@
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^
#| +2%\1-*30g+\1\40g1-:v0+v2?1#<v>+:00g%!55+*>:#0>#,_^>:!|>\#%"P"v#:*+*g00g0<>1
02!:++`\0\`-1g01:\+`\< !46v3<^$$<^1,g2+1%2/2,g1+1<v%g00:\<*g01,<>:30p\:20p:v^3g
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%+#^_

View file

@ -0,0 +1,146 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#define DOUBLE_SPACE 1
#if DOUBLE_SPACE
# define SPC " "
#else
# define SPC " "
#endif
wchar_t glyph[] = L""SPC"│││─┘┐┤─└┌├─┴┬┼"SPC"┆┆┆┄╯╮ ┄╰╭ ┄";
typedef unsigned char byte;
enum { N = 1, S = 2, W = 4, E = 8, V = 16 };
byte **cell;
int w, h, avail;
#define each(i, x, y) for (i = x; i <= y; i++)
int irand(int n)
{
int r, rmax = n * (RAND_MAX / n);
while ((r = rand()) >= rmax);
return r / (RAND_MAX/n);
}
void show()
{
int i, j, c;
each(i, 0, 2 * h) {
each(j, 0, 2 * w) {
c = cell[i][j];
if (c > V) printf("\033[31m");
printf("%lc", glyph[c]);
if (c > V) printf("\033[m");
}
putchar('\n');
}
}
inline int max(int a, int b) { return a >= b ? a : b; }
inline int min(int a, int b) { return b >= a ? a : b; }
static int dirs[4][2] = {{-2, 0}, {0, 2}, {2, 0}, {0, -2}};
void walk(int x, int y)
{
int i, t, x1, y1, d[4] = { 0, 1, 2, 3 };
cell[y][x] |= V;
avail--;
for (x1 = 3; x1; x1--)
if (x1 != (y1 = irand(x1 + 1)))
i = d[x1], d[x1] = d[y1], d[y1] = i;
for (i = 0; avail && i < 4; i++) {
x1 = x + dirs[ d[i] ][0], y1 = y + dirs[ d[i] ][1];
if (cell[y1][x1] & V) continue;
/* break walls */
if (x1 == x) {
t = (y + y1) / 2;
cell[t][x+1] &= ~W, cell[t][x] &= ~(E|W), cell[t][x-1] &= ~E;
} else if (y1 == y) {
t = (x + x1)/2;
cell[y-1][t] &= ~S, cell[y][t] &= ~(N|S), cell[y+1][t] &= ~N;
}
walk(x1, y1);
}
}
int solve(int x, int y, int tox, int toy)
{
int i, t, x1, y1;
cell[y][x] |= V;
if (x == tox && y == toy) return 1;
each(i, 0, 3) {
x1 = x + dirs[i][0], y1 = y + dirs[i][1];
if (cell[y1][x1]) continue;
/* mark path */
if (x1 == x) {
t = (y + y1)/2;
if (cell[t][x] || !solve(x1, y1, tox, toy)) continue;
cell[t-1][x] |= S, cell[t][x] |= V|N|S, cell[t+1][x] |= N;
} else if (y1 == y) {
t = (x + x1)/2;
if (cell[y][t] || !solve(x1, y1, tox, toy)) continue;
cell[y][t-1] |= E, cell[y][t] |= V|E|W, cell[y][t+1] |= W;
}
return 1;
}
/* backtrack */
cell[y][x] &= ~V;
return 0;
}
void make_maze()
{
int i, j;
int h2 = 2 * h + 2, w2 = 2 * w + 2;
byte **p;
p = calloc(sizeof(byte*) * (h2 + 2) + w2 * h2 + 1, 1);
p[1] = (byte*)(p + h2 + 2) + 1;
each(i, 2, h2) p[i] = p[i-1] + w2;
p[0] = p[h2];
cell = &p[1];
each(i, -1, 2 * h + 1) cell[i][-1] = cell[i][w2 - 1] = V;
each(j, 0, 2 * w) cell[-1][j] = cell[h2 - 1][j] = V;
each(i, 0, h) each(j, 0, 2 * w) cell[2*i][j] |= E|W;
each(i, 0, 2 * h) each(j, 0, w) cell[i][2*j] |= N|S;
each(j, 0, 2 * w) cell[0][j] &= ~N, cell[2*h][j] &= ~S;
each(i, 0, 2 * h) cell[i][0] &= ~W, cell[i][2*w] &= ~E;
avail = w * h;
walk(irand(2) * 2 + 1, irand(h) * 2 + 1);
/* reset visited marker (it's also used by path finder) */
each(i, 0, 2 * h) each(j, 0, 2 * w) cell[i][j] &= ~V;
solve(1, 1, 2 * w - 1, 2 * h - 1);
show();
}
int main(int c, char **v)
{
setlocale(LC_ALL, "");
if (c < 2 || (w = atoi(v[1])) <= 0) w = 16;
if (c < 3 || (h = atoi(v[2])) <= 0) h = 8;
make_maze();
return 0;
}

View file

@ -0,0 +1,30 @@
defmodule Maze do
def generate(w, h) do
:random.seed(:os.timestamp)
(for i <- 1..w, j <- 1..h, do: {i,j}) |>
Enum.each(fn{i,j} -> Process.put({:vis, i, j}, true) end)
walk(:random.uniform(w), :random.uniform(h))
print(w, h)
end
defp walk(x, y) do
Process.put({:vis, x, y}, false)
Enum.each(Enum.shuffle([[x-1,y], [x,y+1], [x+1,y], [x,y-1]]), fn [i,j] ->
if Process.get({:vis, i, j}) do
if i == x, do: Process.put({:hor, x, max(y, j)}, "+ "),
else: Process.put({:ver, max(x, i), y}, " ")
walk(i, j)
end
end)
end
defp print(w, h) do
Enum.each(1..h, fn j ->
IO.puts (Enum.map(1..w, fn i -> Process.get({:hor, i, j}, "+---") end) |> Enum.join) <> "+"
IO.puts (Enum.map(1..w, fn i -> Process.get({:ver, i, j}, "| ") end) |> Enum.join) <> "|"
end)
IO.puts String.duplicate("+---", w) <> "+"
end
end
Maze.generate(20, 10)

View file

@ -2,7 +2,7 @@ function maze(x,y) {
var n=x*y-1;
if (n<0) {alert("illegal maze dimensions");return;}
var horiz =[]; for (var j= 0; j<x+1; j++) horiz[j]= [],
verti =[]; for (var j= 0; j<y+1; j++) verti[j]= [],
verti =[]; for (var j= 0; j<x+1; j++) verti[j]= [],
here = [Math.floor(Math.random()*x), Math.floor(Math.random()*y)],
path = [here],
unvisited = [];

View file

@ -1,26 +1,27 @@
function walk(maze, cell, visited = {})
function walk(maze, cell, visited = Any[])
push!(visited, cell)
for neigh in shuffle(neighbors(cell, size(maze)))
if !(neigh in visited)
maze[int((cell+neigh)/2)...] = 0
maze[round(Int,(cell+neigh)/2)...] = 0 # ifloor(n/2) == n >> 1
walk(maze, neigh, visited)
end
end
maze
end
neighbors(c,b,d=2) = filter(check(b),map(m->c+d*m, {[0,1],[-1,0],[0,-1],[1,0]}))
neighbors(c,b,d=2)=filter(check(b),map(m->c+d*m, Any[[0,1],[-1,0],[0,-1],[1,0]]))
check(bound) = cell -> all([1,1] .<= cell .<= [bound...])
maze(w, h) = walk([i%2|j%2 for i=1:2w+1,j=1:2h+1], 2*[rand(1:w),rand(1:h)])
pprint(maze) = print(mapslices(x-> [join(x)], maze, [2]))
pprint(matrix) = for i = 1:size(matrix,1) println(join(matrix[i,:])) end
function mprint(maze, wall = CharString("╹╸┛╺┗━┻╻┃┓┫┏┣┳╋"...))
function printmaze(maze, wall = convert(UTF32String, "╹╸┛╺┗━┻╻┃┓┫┏┣┳╋"))
h,w = size(maze)
pprint([ maze[i,j] == 0 ? ' ' :
wall[sum(c-> 2.0^.5(3c[1]+c[2]+3),
wall[Int(sum(c-> 2.0^.5(3c[1]+c[2]+3),
filter(x -> maze[x...] != 0,
neighbors([i,j],[size(maze)...],1)) .- {[i,j]})]
for i = 1:2:size(maze,1), j = 1:size(maze,2)])
neighbors([i,j],[h,w],1)) .- Any[[i,j]]))]
for i = 1:2:h, j = 1:w])
end

View file

@ -0,0 +1,246 @@
<?php
// Convert Hex Color to RGB
function hexrgb(&$h)
{
return(array(hexdec($h[0].$h[1]),hexdec($h[2].$h[3]),hexdec($h[4].$h[5])));
}
// Allocate a color for an image from RGB
function rgbc(&$i, &$c)
{
return(imagecolorallocate($i, $c[0], $c[1], $c[2]));
}
class Maze
{
/*
H : horizontal walls
V : vertical walls
x : number of rows
y : numbers of cols
r : resolve the maze
b : walls thickness
c : cell size
f : background color
m : walls color
e : entrance color
s : exit color
i : gd image identifier
*/
private $H, $V, $x, $y, $r, $b, $c, $f, $m, $e, $s, $i;
// Initialize Maze class
function __construct($x, $y, $r, $b, $c, $f, $m, $e, $s)
{
$this->x = $x;
$this->y = $y;
$this->r = $r;
$this->b = $b;
$this->c = $c;
$this->f = hexrgb($f);
$this->m = hexrgb($m);
$this->e = hexrgb($e);
$this->s = hexrgb($s);
}
// Checks if cell is a closed room
function isroom($x, $y)
{
return((empty($this->H[$x][$y])
&& empty($this->V[$x][$y])
&& empty($this->H[$x][$y+1])
&& empty($this->V[$x+1][$y])) ? true : false);
}
// Save the stack as solution path
function save(&$x, &$y, &$m)
{
if ($this->r == 1 && $x == $this->x - 1 && $y == $this->y - 1)
{
$this->r = $m;
array_push($this->r, array($x, $y));
}
}
// Dig the maze
function dig()
{
$x = 0;
$y = 0;
$cc = $this->x * $this->y;
$v = 1;
$m = array();
while ($v < $cc)
{
$c = '';
if ($y > 0 && $this->isroom($x, $y - 1))
$c .= 'N';
if ($y < $this->y - 1 && $this->isroom($x, $y + 1))
$c .= 'S';
if ($x < $this->x - 1 && $this->isroom($x + 1, $y))
$c .= 'E';
if ($x > 0 && $this->isroom($x - 1, $y))
$c .= 'W';
if ($c)
{
$v++;
array_push($m, array($x, $y));
$d = $c[rand(0, strlen($c) - 1)];
if ($d == 'N')
$this->H[$x][$y--] = true;
if ($d == 'S')
$this->H[$x][$y++ + 1] = true;
if ($d == 'E')
$this->V[$x++ + 1][$y] = true;
if ($d == 'W')
$this->V[$x--][$y] = true;
}
else
list($x, $y) = array_pop($m);
$this->save($x, $y, $m);
}
$this->save($x, $y, $m);
$this->V[0][0] = 1;
$this->V[$this->x][$this->y - 1] = 1;
}
// Draw the maze full grid
function grid(&$m)
{
for ($y = 0; $y <= $this->y; ++$y)
{
imagefilledrectangle($this->i, 0, $y * ($this->c + $this->b),
$this->b + $this->x * ($this->c + $this->b) - 1,
$this->b + $y * ($this->c + $this->b) - 1,
$m);
}
for ($x = 0; $x <= $this->x; ++$x)
{
imagefilledrectangle($this->i, $x * ($this->c + $this->b), 0,
$this->b + $x * ($this->c + $this->b) - 1,
$this->b + $this->y * ($this->c + $this->b) - 1,
$m);
}
}
// Breaks the horizontal walls
function line($x, $y, &$f)
{
imagefilledrectangle($this->i,
$x * ($this->c + $this->b) + $this->b,
$y * ($this->c + $this->b),
$x * ($this->c + $this->b) + $this->b + $this->c - 1,
$y * ($this->c + $this->b) + $this->b,
$f);
}
// Breaks the vertical walls
function col($x, $y, &$f)
{
imagefilledrectangle($this->i,
$x * ($this->c + $this->b),
$y * ($this->c + $this->b) + $this->b,
$x * ($this->c + $this->b) + $this->b,
$y * ($this->c + $this->b) + $this->b + $this->c - 1,
$f);
}
// Breaks the walls
function dot(&$f)
{
for ($x = 0; $x <= $this->x; ++$x)
{
for ($y = 0; $y <= $this->y; ++$y)
{
if (isset($this->H[$x][$y]))
$this->line($x, $y, $f);
if (isset($this->V[$x][$y]))
$this->col($x, $y, $f);
}
}
}
// Fill color cell
function cellfill(&$x, &$y, &$c)
{
imagefilledrectangle($this->i,
$x * ($this->c + $this->b) + $this->b,
$y * ($this->c + $this->b) + $this->b,
$x * ($this->c + $this->b) + $this->b + $this->c - 1,
$y * ($this->c + $this->b) + $this->b + $this->c - 1,
$c);
}
// Draw solution
function path()
{
$l = count($this->r);
for ($i = 0; $i < $l; ++$i)
{
list($x, $y) = $this->r[$i];
$r = ($this->e[0] * ($l - $i) + $this->s[0] * $i) / $l;
$g = ($this->e[1] * ($l - $i) + $this->s[1] * $i) / $l;
$b = ($this->e[2] * ($l - $i) + $this->s[2] * $i) / $l;
if (!isset($c[$r][$g][$b]))
$c[$r][$g][$b] = imagecolorallocate($this->i, $r, $g, $b);
$this->cellfill($x, $y, $c[$r][$g][$b]);
if (isset($ox, $oy))
{
if ($ox - $x == -1)
$this->col($x, $y, $c[$r][$g][$b]);
if ($oy - $y == -1)
$this->line($x, $y, $c[$r][$g][$b]);
if ($ox - $x == 1)
$this->col($ox, $oy, $c[$r][$g][$b]);
if ($oy - $y == 1)
$this->line($ox, $oy, $c[$r][$g][$b]);
}
if ($i == 0)
$this->col(0, 0, $c[$r][$g][$b]);
if ($i == $l - 1)
$this->col($x + 1, $y, $c[$r][$g][$b]);
$ox = $x;
$oy = $y;
}
}
// Call digger and make rendering
function __destruct()
{
$this->dig();
$this->i = imagecreatetruecolor(
$this->b + $this->x * ($this->c + $this->b),
$this->b + $this->y * ($this->c + $this->b));
$f = rgbc($this->i, $this->f);
$m = rgbc($this->i, $this->m);
unset($this->f, $this->m);
imagefill($this->i, 0, 0, $f);
$this->grid($m);
$this->dot($f);
unset($f, $m, $this->H, $this->V);
if ($this->r)
$this->path();
unset($this->r, $this->e, $this->s);
header('content-disposition:inline;filename="maze.png"');
header('cache-control:no-store,no-cache,must-revalidate');
header('content-type:image/png');
imagepng($this->i, NULL, 9, PNG_ALL_FILTERS);
imagedestroy($this->i);
}
}

View file

@ -1,7 +1,7 @@
*process source attributes xref or(!);
mgg: Proc Options(main);
/* REXX ***************************************************************
* 04.09.2013 Walter Pachl translated from REXX version 2
* 04.09.2013 Walter Pachl translated from REXX version 3
**********************************************************************/
Dcl (MIN,MOD,RANDOM,REPEAT,SUBSTR) Builtin;
Dcl SYSIN STREAM INPUT;

View file

@ -17,8 +17,8 @@ constant mapping = :OPEN(' '),
:TODO< x >,
:TRIED< · >;
enum Code (mapping.map: *.key);
my @code = mapping.map: *.value;
enum Sym (mapping.map: *.key);
my @ch = mapping.map: *.value;
enum Direction <DeadEnd Up Right Down Left>;
@ -28,13 +28,13 @@ sub gen_maze ( $X,
$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 ];
push @maze, $[ flat ES, -N, (ESW, EW) xx $X - 1, SW ];
push @maze, $[ flat (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, $[ flat NES, EW, (NESW, EW) xx $X - 1, NSW ];
push @maze, $[ flat (NS, TODO) xx $X, NS ];
}
push @maze, [ NE, (EW, NEW) xx $X - 1, -NS, NW ];
push @maze, $[ flat NE, (EW, NEW) xx $X - 1, -NS, NW ];
@maze[$start_y][$start_x] = OPEN;
my @stack;
@ -75,12 +75,12 @@ sub gen_maze ( $X,
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], ' ' }
for @y.rotor(2) -> ($w, $c) {
print @ch[abs $w];
if $c >= 0 { print @ch[$c] x 3 }
else { print ' ', @ch[abs $c], ' ' }
}
say @code[@y[*-1]];
say @ch[@y[*-1]];
}
}

View file

@ -1,23 +1,27 @@
from random import shuffle, randrange
def make_maze(w = 16, h = 8):
vis = [[0] * w + [1] for _ in range(h)] + [[1] * (w + 1)]
ver = [["| "] * w + ['|'] for _ in range(h)] + [[]]
hor = [["+--"] * w + ['+'] for _ in range(h + 1)]
vis = [[0] * w + [1] for _ in range(h)] + [[1] * (w + 1)]
ver = [["| "] * w + ['|'] for _ in range(h)] + [[]]
hor = [["+--"] * w + ['+'] for _ in range(h + 1)]
def walk(x, y):
vis[y][x] = 1
def walk(x, y):
vis[y][x] = 1
d = [(x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)]
shuffle(d)
for (xx, yy) in d:
if vis[yy][xx]: continue
if xx == x: hor[max(y, yy)][x] = "+ "
if yy == y: ver[y][max(x, xx)] = " "
walk(xx, yy)
d = [(x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)]
shuffle(d)
for (xx, yy) in d:
if vis[yy][xx]: continue
if xx == x: hor[max(y, yy)][x] = "+ "
if yy == y: ver[y][max(x, xx)] = " "
walk(xx, yy)
walk(randrange(w), randrange(h))
for (a, b) in zip(hor, ver):
print(''.join(a + ['\n'] + b))
walk(randrange(w), randrange(h))
make_maze()
s = ""
for (a, b) in zip(hor, ver):
s += ''.join(a + ['\n'] + b + ['\n'])
return s
if __name__ == '__main__':
print(make_maze())

View file

@ -1,102 +1,103 @@
/*REXX program generates and displays a (rectangular) solvable maze. */
height=0; @.=0 /*default for all cells visited.*/
parse arg rows cols seed . /*allow user to specify maze size*/
if rows='' | rows==',' then rows=19 /*No rows given? Use the default*/
if cols='' | cols==',' then cols=19 /*No cols given? Use the default*/
if seed\=='' then call random ,,seed /*use a seed for repeatability. */
call buildRow ''copies('~',cols-1)'~' /*build the top edge of maze.*/
/*(below) build the maze's grid.*/
/*REXX program generates and displays a rectangular solvable maze (any size).*/
height=0; @.=0 /*default for all cells visited. */
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 cols='' | cols==',' then cols=19 /* " cols " ? " " " " */
if seed\=='' then call random ,,seed /*use a random seed for repeatability.*/
call buildRow ''copies('~',cols-1)'~' /*construct top edge of the maze. */
/* [↓] construct the maze's grid. */
do r=1 for rows; _=; __=; hp= '|'; hj=''
do c=1 for cols; _= _||hp'1'; __=__||hj'~'; hj=''; hp=''
end /*c*/
call buildRow _'' /*build right edge of cells.*/
if r\==rows then call buildRow __'' /* " " " " maze.*/
call buildRow _'' /*construct the right edge of cells.*/
if r\==rows then call buildRow __'' /* " " " " " maze. */
end /*r*/
call buildRow ''copies('~',cols-1)'~' /*build the bottom maze edge.*/
r!=random(1,rows)*2; c!=random(1,cols)*2; @.r!.c!=0 /*choose 1st cell*/
/* [↓] traipse through the maze.*/
do forever; n=hood(r!,c!); if n==0 then if \fcell() then leave
call ?; @._r._c=0 /*get the (next) direction to go.*/
ro=r!; co=c!; r!=_r; c!=_c /*save original cell coordinates.*/
?.zr=?.zr%2; ?.zc=?.zc%2 /*get the row and cell directions*/
rw=ro+?.zr; cw=co+?.zc /*calculate the next row and col.*/
@.rw.cw='·' /*mark the cell as being visited.*/
call buildRow ''copies('~',cols-1)'~' /*construct the bottom maze edge.*/
r!=random(1,rows)*2; c!=random(1,cols)*2; @.r!.c!=0 /*choose the 1st cell.*/
/* [↓] traipse through the maze. */
do forever; n=hood(r!,c!); if n==0 then if \fCell() then leave
call ?; @._r._c=0 /*get the (next) maze direction to go. */
ro=r!; co=c!; r!=_r; c!=_c /*save original maze cell coordinates. */
?.zr=?.zr%2; ?.zc=?.zc%2 /*get the maze row and cell directions.*/
rw=ro+?.zr; cw=co+?.zc /*calculate the next row and column. */
@.rw.cw=. /*mark the maze cell as being visited. */
end /*forever*/
do r=1 for height; _= /*display the maze. */
do c=1 for cols*2 + 1; _=_ || @.r.c; end /*c*/
if \(r//2) then _=translate(_, '\', "·") /*trans to backslash*/
@.r=_ /*save the row in @.*/
end /*r*/
do r=1 for height; _= /*display the maze. */
do c=1 for cols*2 + 1; _=_ || @.r.c; end /*c*/
if \(r//2) then _=translate(_, '\', .) /*trans to backslash*/
@.r=_ /*save the row in @.*/
end /*r*/
do #=1 for height; _=@.# /*display maze to the terminal. */
call makeNice /*make some cell corners prettier*/
_=changestr(1,_,111) /*these four ────────────────────*/
_=changestr(0,_,000) /*─── statements are ────────────*/
_=changestr('·',_," ") /*──────── used for preserving ──*/
_=changestr('~',_,"───") /*──────────── the aspect ratio. */
say translate(_, '', "═|\10") /*make it presentable for screen.*/
end /*#*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────@ subroutine────────────────────────*/
@: parse arg _r,_c; return @._r._c /*a fast way to reference a cell.*/
/*──────────────────────────────────? subroutine────────────────────────*/
?: do forever; ?.=0; ?=random(1,4); if ?==1 then ?.zc=-2 /*north*/
if ?==2 then ?.zr=+2 /* east*/
if ?==3 then ?.zc=+2 /*south*/
if ?==4 then ?.zr=-2 /* west*/
_r=r!+?.zr; _c=c!+?.zc; if @._r._c==1 then return
end /*forever*/
/*──────────────────────────────────BUILDROW subroutine─────────────────*/
buildRow: parse arg z; height=height+1; width=length(z)
do c=1 for width; @.height.c=substr(z,c,1); end; return
/*──────────────────────────────────FCELL subroutine────────────────────*/
fcell: do r=1 for rows; r2=r+r
do c=1 for cols; c2=c+c
if hood(r2,c2)==1 then do; r!=r2; c!=c2; @.r!.c!=0; return 1;end
end /*c*/
end /*r*/
return 0
/*──────────────────────────────────HOOD subroutine─────────────────────*/
hood: parse arg rh,ch; return @(rh+2,ch)+@(rh-2,ch)+@(rh,ch-2)+@(rh,ch+2)
/*──────────────────────────────────MAKENICE subroutine─────────────────*/
makeNice: width=length(_); old=#-1; new=#+1; old_=@.old; new_=@.new
if left(_,2) =='·' then _=translate(_, '|', "")
if right(_,2)=='·' then _=translate(_, '|', "")
/* [↓] handle the top grid row.*/
do k=1 for width while #==1; z=substr(_,k,1) /*maze top row.*/
if z\=='' then iterate
if substr(new_,k,1)=='\' then _=overlay('',_,k)
end /*k*/
do k=1 for width while #==height; z=substr(_,k,1) /*maze bot row.*/
if z\=='' then iterate
if substr(old_,k,1)=='\' then _=overlay('',_,k)
end /*k*/
/* [↓] handle the mid grid rows*/
do k=3 to width-2 by 2 while #//2; z=substr(_,k,1) /*maze mid rows*/
if z\=='' then iterate
le=substr(_,k-1,1)
ri=substr(_,k+1,1)
up=substr(old_,k,1)
dw=substr(new_,k,1)
select
when le=='·' & ri=='·' & up=='' & dw=='' then _=overlay('|',_,k)
when le=='~' & ri=='~' & up=='\' & dw=='\' then _=overlay('',_,k)
when le=='~' & ri=='~' & up=='\' & dw=='' then _=overlay('',_,k)
when le=='~' & ri=='~' & up=='' & dw=='\' then _=overlay('',_,k)
when le=='~' & ri=='·' & up=='\' & dw=='\' then _=overlay('',_,k)
when le=='·' & ri=='~' & up=='\' & dw=='\' then _=overlay('',_,k)
when le=='·' & ri=='·' & up=='' & dw=='\' then _=overlay('|',_,k)
when le=='·' & ri=='·' & up=='\' & dw=='' then _=overlay('|',_,k)
when le=='·' & ri=='~' & up=='\' & dw=='' then _=overlay('',_,k)
when le=='·' & ri=='~' & up=='' & dw=='\' then _=overlay('',_,k)
when le=='~' & ri=='·' & up=='\' & dw=='' then _=overlay('',_,k)
when le=='~' & ri=='·' & up=='' & dw=='\' then _=overlay('',_,k)
when le=='~' & ri=='·' & up=='' & dw=='' then _=overlay('',_,k)
when le=='·' & ri=='~' & up=='' & dw=='' then _=overlay('',_,k)
otherwise nop
end /*select*/
end /*k*/
return
_=changestr(1,_,111) /*──────these four ────────────────────*/
_=changestr(0,_,000) /*───────── statements are ────────────*/
_=changestr( . ,_," ") /*────────────── used for preserving ──*/
_=changestr('~',_,"───") /*────────────────── the aspect ratio. */
say translate(_, '', "═|\10") /*make it presentable for the screen. */
end /*#*/
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
@: parse arg _r,_c; return @._r._c /*a fast way to reference a maze cell. */
/*────────────────────────────────────────────────────────────────────────────*/
?: do forever; ?.=0; ?=random(1,4); if ?==1 then ?.zc=-2 /*north*/
if ?==2 then ?.zr= 2 /* east*/
if ?==3 then ?.zc= 2 /*south*/
if ?==4 then ?.zr=-2 /* west*/
_r=r!+?.zr; _c=c!+?.zc; if @._r._c==1 then return
end /*forever*/
/*────────────────────────────────────────────────────────────────────────────*/
buildRow: parse arg z; height=height+1; width=length(z)
do c=1 for width; @.height.c=substr(z,c,1); end; return
/*────────────────────────────────────────────────────────────────────────────*/
fCell: do r=1 for rows; rr=r+r
do c=1 for cols; cc=c+c
if hood(rr,cc)==1 then do; r!=rr; c!=cc; @.r!.c!=0; return 1; end
end /*c*/
end /*r*/ /* [↑] r! & c! are used by invoker.*/
return 0
/*────────────────────────────────────────────────────────────────────────────*/
hood: parse arg rh,ch; return @(rh+2,ch) + @(rh-2,ch) + @(rh,ch-2) + @(rh,ch+2)
/*────────────────────────────────────────────────────────────────────────────*/
makeNice: width=length(_); old=#-1; new=#+1; old_=@.old; new_=@.new
if left(_,2) =='.' then _=translate(_, '|', "")
if right(_,2)=='.' then _=translate(_, '|', "")
/* [↓] handle the top grid row.*/
do k=1 for width while #==1; z=substr(_,k,1) /*maze top row.*/
if z\=='' then iterate
if substr(new_,k,1)=='\' then _=overlay('',_,k)
end /*k*/
do k=1 for width while #==height; z=substr(_,k,1) /*maze bot row.*/
if z\=='' then iterate
if substr(old_,k,1)=='\' then _=overlay('',_,k)
end /*k*/
/* [↓] handle the mid grid rows*/
do k=3 to width-2 by 2 while #//2; z=substr(_,k,1) /*maze mid rows*/
if z\=='' then iterate
le=substr(_,k-1,1)
ri=substr(_,k+1,1)
up=substr(old_,k,1)
dw=substr(new_,k,1)
select
when le== . & ri== . & up=='' & dw=='' then _=overlay('|',_,k)
when le=='~' & ri=='~' & up=='\' & dw=='\' then _=overlay('',_,k)
when le=='~' & ri=='~' & up=='\' & dw=='' then _=overlay('',_,k)
when le=='~' & ri=='~' & up=='' & dw=='\' then _=overlay('',_,k)
when le=='~' & ri== . & up=='\' & dw=='\' then _=overlay('',_,k)
when le== . & ri=='~' & up=='\' & dw=='\' then _=overlay('',_,k)
when le== . & ri== . & up=='' & dw=='\' then _=overlay('|',_,k)
when le== . & ri== . & up=='\' & dw=='' then _=overlay('|',_,k)
when le== . & ri=='~' & up=='\' & dw=='' then _=overlay('',_,k)
when le== . & ri=='~' & up=='' & dw=='\' then _=overlay('',_,k)
when le=='~' & ri== . & up=='\' & dw=='' then _=overlay('',_,k)
when le=='~' & ri== . & up=='' & dw=='\' then _=overlay('',_,k)
when le=='~' & ri== . & up=='' & dw=='' then _=overlay('',_,k)
when le== . & ri=='~' & up=='' & dw=='' then _=overlay('',_,k)
otherwise nop
end /*select*/
end /*k*/
return

View file

@ -1,57 +1,57 @@
/*REXX program generates and displays a (rectangular) solvable maze. */
height=0; @.=0 /*default for all cells visited.*/
parse arg rows cols seed . /*allow user to specify maze size*/
if rows='' | rows==',' then rows=19 /*No rows given? Use the default*/
if cols='' | cols==',' then cols=19 /*No cols given? Use the default*/
if seed\=='' then call random ,,seed /*use a seed for repeatability. */
call buildRow ''copies('',cols-1)'' /*build the top edge of maze.*/
/*(below) build the maze's grid.*/
/*REXX program generates and displays a rectangular solvable maze (any size).*/
height=0; @.=0 /*default for all cells visited. */
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 cols='' | cols==',' then cols=19 /* " cols " ? " " " " */
if seed\=='' then call random ,,seed /*use a random seed for repeatability.*/
call buildRow ''copies('',cols-1)'' /*build the top edge of the maze. */
/* [↓] construct the maze's grid. */
do r=1 for rows; _=; __=; hp= '|'; hj=''
do c=1 for cols; _= _||hp'1'; __=__||hj''; hj=''; hp=''
end /*c*/
call buildRow _'' /*build right edge of cells.*/
if r\==rows then call buildRow __'' /* " " " " maze.*/
call buildRow _'' /*build the right edge of cells. */
if r\==rows then call buildRow __'' /* " " " " " maze. */
end /*r*/
call buildRow ''copies('',cols-1)'' /*build the bottom maze edge.*/
r!=random(1,rows)*2; c!=random(1,cols)*2; @.r!.c!=0 /*choose 1st cell*/
/* [↓] traipse through the maze.*/
do forever; n=hood(r!,c!); if n==0 then if \fcell() then leave
call ?; @._r._c=0 /*get the (next) direction to go.*/
ro=r!; co=c!; r!=_r; c!=_c /*save original cell coordinates.*/
?.zr=?.zr%2; ?.zc=?.zc%2 /*get the row and cell directions*/
rw=ro+?.zr; cw=co+?.zc /*calculate the next row and col.*/
@.rw.cw='·' /*mark the cell as being visited.*/
call buildRow ''copies('',cols-1)'' /*construct the bottom maze edge. */
r!=random(1,rows)*2; c!=random(1,cols)*2; @.r!.c!=0 /*choose the 1st cell.*/
/* [↓] traipse through the maze. */
do forever; n=hood(r!,c!); if n==0 then if \fCell() then leave
call ?; @._r._c=0 /*get the (next) maze direction to go. */
ro=r!; co=c!; r!=_r; c!=_c /*save the original cell coordinates. */
?.zr=?.zr%2; ?.zc=?.zc%2 /*get the maze row and cell directions.*/
rw=ro+?.zr; cw=co+?.zc /*calculate the next maze row and col. */
@.rw.cw=. /*mark the maze cell as being visited. */
end /*forever*/
do r=1 for height; _= /*display the maze. */
do r=1 for height; _= /*display the maze. */
do c=1 for cols*2 + 1; _=_ || @.r.c; end /*c*/
if \(r//2) then _=translate(_, '\', "·") /*trans to backslash*/
_=changestr(1,_,111) /*these four ────────────────────*/
_=changestr(0,_,000) /*─── statements are ────────────*/
_=changestr('·',_," ") /*──────── used for preserving ──*/
_=changestr('',_,"───") /*──────────── the aspect ratio. */
say translate(_,'',"|\10") /*make it presentable for screen.*/
if \(r//2) then _=translate(_, '\', .) /*trans to backslash*/
_=changestr(1,_,111) /*──────these four ────────────────────*/
_=changestr(0,_,000) /*───────── statements are ────────────*/
_=changestr( . ,_," ") /*────────────── used for preserving ──*/
_=changestr('',_,"───") /*────────────────── the aspect ratio. */
say translate(_,'',"|\10") /*make it presentable for the screen. */
end /*r*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────@ subroutine────────────────────────*/
@: parse arg _r,_c; return @._r._c /*a fast way to reference a cell.*/
/*──────────────────────────────────? subroutine────────────────────────*/
?: do forever; ?.=0; ?=random(1,4); if ?==1 then ?.zc=-2 /*north*/
if ?==2 then ?.zr=+2 /* east*/
if ?==3 then ?.zc=+2 /*south*/
if ?==4 then ?.zr=-2 /* west*/
_r=r!+?.zr; _c=c!+?.zc; if @._r._c==1 then return
end /*forever*/
/*──────────────────────────────────BUILDROW subroutine─────────────────*/
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
@: parse arg _r,_c; return @._r._c /*a fast way to reference a maze cell. */
/*────────────────────────────────────────────────────────────────────────────*/
?: do forever; ?.=0; ?=random(1,4); if ?==1 then ?.zc=-2 /*north*/
if ?==2 then ?.zr= 2 /* east*/
if ?==3 then ?.zc= 2 /*south*/
if ?==4 then ?.zr=-2 /* west*/
_r=r!+?.zr; _c=c!+?.zc; if @._r._c==1 then return
end /*forever*/
/*────────────────────────────────────────────────────────────────────────────*/
buildRow: parse arg z; height=height+1; width=length(z)
do c=1 for width; @.height.c=substr(z,c,1); end; return
/*──────────────────────────────────FCELL subroutine────────────────────*/
fcell: do r=1 for rows; r2=r+r
do c=1 for cols; c2=c+c
if hood(r2,c2)==1 then do; r!=r2; c!=c2; @.r!.c!=0; return 1;end
do c=1 for width; @.height.c=substr(z,c,1); end; return
/*────────────────────────────────────────────────────────────────────────────*/
fCell: do r=1 for rows; rr=r+r
do c=1 for cols; cc=c+c
if hood(rr,cc)==1 then do; r!=rr; c!=cc; @.r!.c!=0; return 1; end
end /*c*/
end /*r*/
end /*r*/ /* [↑] r! & c! are used by invoker.*/
return 0
/*──────────────────────────────────HOOD subroutine─────────────────────*/
hood: parse arg rh,ch; return @(rh+2,ch)+@(rh-2,ch)+@(rh,ch-2)+@(rh,ch+2)
/*────────────────────────────────────────────────────────────────────────────*/
hood: parse arg rh,ch; return @(rh+2,ch) + @(rh-2,ch) + @(rh,ch-2) + @(rh,ch+2)

View file

@ -12,7 +12,8 @@
out))
(defun neigh (loc)
(tree-bind (x . y) loc
(let ((x (from loc))
(y (to loc)))
(list (- x 1)..y (+ x 1)..y
x..(- y 1) x..(+ y 1))))

View file

@ -17,7 +17,8 @@
^(for () (,expr) () ,*body))
(defun neigh (loc)
(tree-bind (x . y) loc
(let ((x (from loc))
(y (to loc)))
(list (- x 1)..y (+ x 1)..y
x..(- y 1) x..(+ y 1))))