I learned PostScript several years
ago, but just started to read this newsgroup.
Normally, when I learn the language, I try
to write a program that builds a random maze
(it was the first useful program I wrote).
Well, the following postscript program that
I wrote couple years ago prints a
brand new maze every time you send it
to the printer. (It is also handy when you
want to illustrate that PostScript is
a programming language, rather than
document format). It is in the public domain,
so do whatever you want with it (but
don't blame me if it breaks your printer!).
Peter Sorotokin
P.S. Structured comments are probably wrong,
but they stop pageview complaints.
----- Cut here -----
%!PS
%%Pages: 1
%%EndComments
% Yet Another Maze Maker
% Written by Peter Sorotokin, 1996-1997
% This program is in the public domain.
% Note: do not send this job to the printer until you know
% how to cancel it (it may take a LOT of time on slow printer;
% it takes couple minutes on my LaserJet 4).
%%BeginSetup
% put your sizes here:
/width 57 def
/height 57 def
% seed number here:
0 srand % put your seed number instead of 0 (normally not required)
systemdict /realtime known { realtime srand } if
% initialization
/size width height mul def
/zone size array def
/zsize size array def
/vert height 1 add array def
/hor width 1 add array def
/w1 width 1 sub def
/h1 height 1 sub def
0 1 size 1 sub { dup zsize exch 1 put zone exch dup put } bind for
0 1 width { vert exch height string 0 1 h1
{ 1 index exch 255 put } for put } bind for
0 1 height { hor exch width string 0 1 w1
{ 1 index exch 255 put } for put } bind for
% define subroutines
/db { dup 20 string cvs = } bind def
/find_set { { zone 1 index get dup 3 1 roll eq {exit} if } loop} bind
def
/merge_sets {
2 copy zsize exch get
exch zsize exch get 2 copy gt
3 1 roll add exch
{ zsize 2 index 3 -1 roll put
zone 3 1 roll put }
{ zsize 3 index 3 -1 roll put
zone 3 1 roll exch put }
ifelse } bind def
%%EndSetup
%%Page: maze 1
% building
size 1 sub
{
{
rand 2 mod 0 eq
{
rand height mod
rand w1 mod 2 copy
height mul add
dup height add
find_set exch find_set
2 copy eq
{
pop pop pop pop
}
{
merge_sets vert exch 1 add get exch 0 put exit
}
ifelse
}
{
rand h1 mod
rand width mod 2 copy
height mul add
dup 1 add
find_set exch find_set
2 copy eq
{
pop pop pop pop
}
{
merge_sets exch hor exch 1 add get exch 0 put exit
}
ifelse
}
ifelse
}
loop
} bind repeat
% make entrance and exit
vert 0 get rand height mod 0 put
vert width get rand height mod 0 put
% setup output
clippath pathbbox
2 index sub exch
3 index sub exch
4 2 roll translate
2 copy height 4 add div exch width 4 add div
2 copy gt {exch} if pop /myscale exch def
myscale height mul sub 2 div exch
myscale width mul sub 2 div exch
translate
myscale myscale scale
0.05 setlinewidth
newpath
% render the maze
0 1 width { dup 0 moveto vert exch get 0 1 height 1 sub
{ 1 index exch get 0 eq 0 1 3 -1 roll { rmoveto } { rlineto } ifelse }
for } bind for
0 1 height { dup 0 exch moveto hor exch get 0 1 width 1 sub
{ 1 index exch get 0 eq 1 0 3 -1 roll { rmoveto } { rlineto } ifelse }
for } bind for
stroke
% eject the page
showpage
%%EOF
Nice program; however, I'm having two problems:
1. The stack isn't cleared after the program's finished,
there must be a pop missing somewhere in one of the loops.
The stack contains 2*width+2 entries. (or 2*height+2 entries).
2. If height != width I get a rangecheck error.
Mogens
--
Mogens Kjaer, Carlsberg Laboratory, Dept. of Chemistry
Gamle Carlsberg Vej 10, DK-2500 Valby, Denmark
Phone: +45 33 27 53 25, Fax: +45 33 27 47 08
Email: m...@crc.dk Homepage: http://www.crc.dk
> Nice program;
Thanks
Hopefully this fixes it...
---- Cut here ----
%!PS
%%Pages: 1
%%EndComments
% Yet Another Maze Maker
% Version 2
% Written by Peter Sorotokin, 1996-1998
% This program is in the public domain.
% Note: do not send this job to the printer until you know
% how to cancel it (it may take a LOT of time on slow printer;
% it takes couple minutes on my LaserJet 4).
%%BeginSetup
% put your sizes here:
/width 57 def
/height 57 def
% seed number here:
0 srand % put your seed number instead of 0 (normally not required)
systemdict /realtime known { realtime srand } if
% initialization
/size width height mul def
/zone size array def
/zsize size array def
/vert width 1 add array def
/hor height 1 add array def
% define subroutines
%%EndSetup
%%Page: maze 1
% building
% setup output
newpath
% render the maze
for pop } bind for
0 1 height { dup 0 exch moveto hor exch get 0 1 width 1 sub
{ 1 index exch get 0 eq 1 0 3 -1 roll { rmoveto } { rlineto } ifelse }
for pop } bind for