Monthly Archives: April 2011

Revisiting a Program from the Past: Maze Generation

I was playing Minecraft with a few like-minded people the other day, and grew weary of excavating huge, deep holes and falling into lava pits. So, I decided to create my own little island reserve. I scouted a likely location: a small insignificant island off the coast from our main base and began construction.

Once my fort and light house were constructed, I tried to think of something else fun to do. I hit upon the idea of generating a maze, and then planting a garden on top. I recall that over thirty years ago, I wrote a series of programs for my Atari 400 to generate simple mazes on the screen. The basic idea was to create an array the size of the maze you wanted. In each square, you’d store one of three codes: it’s either a block, a square you’ve visited, or a square that has not yet been visited. Initially, you start in an unvisited square, and mark it as visited. You then pick a random starting direction, and see if the square in that direction has been visited. If it hasn’t, erase wall that connects you to it and recurse. If not, then proceed to the next direction until you’ve tried all four directions, then return.

It’s a simple recursive algorithm, which wasn’t really all that attractive on the Atari, which had limited ability for recursion (stack depth is severely limited on the 6502). So, instead of recursion, I stored the stack in the array itself: each square could hold a breadcrumb that told it where it should “back up to” when it had exhausted the current list of directions. But on modern computers, there really isn’t any need to complicate the code with that: I simply use ordinary recursion.

And… here’s the code. It was written in haste, so to write the .PNG it doesn’t even link with libpng: it simply opens a pipe to some of the netpbm utilities to rescale and convert the bitmap to a larger .png file.

[sourcecode lang=”C”]
#include <stdio .h>
#include <stdlib .h>
#include <unistd .h>

#define SIZE 80
#define ASIZE (2*SIZE+1)

char maze[ASIZE][ASIZE] ;

static int dx[] = {-1, 0, 0, 1} ;
static int dy[] = { 0, -1, 1, 0} ;

void
traverse(int i, int j)
{
int w, worig, x, y ;
maze[2*i+1][2*j+1] = ‘ ‘ ;

w = worig = lrand48() & 3 ;

do {
x = i + dx[w] ;
y = j + dy[w] ;

if (x>=0 && y>=0 && x<size && y<SIZE && maze[2*x+1][2*y+1]==’_’) {
maze[2*i+1+dx[w]][2*j+1+dy[w]] = ‘ ‘ ;
traverse(x, y) ;
}
w = (w + 1) & 3 ;
} while (w != worig) ;
}

main(int argc, char *argv[])
{
int i, j ;
int cnt ;

srand48(getpid()) ;

for (i=0; i<ASIZE; i++)
for (j=0; j<ASIZE; j++)
maze[i][j] = ‘#’ ;

for (i=0; i<SIZE; i++)
for (j=0; j<SIZE; j++)
maze[2*i+1][2*j+1] = ‘_’ ;

/* generate the maze */
traverse(0, 0) ;

for (i=0, cnt = 0; i<ASIZE; i++)
for (j=0; j<ASIZE; j++)
if (maze[i][j] == ‘#’)
cnt ++ ;

printf("%d blocks needed.\n", cnt) ;

FILE *fp = popen("pnmenlarge 4 | pnmtopng > maze.png", "w") ;
fprintf(fp, "P1\n%d %d\n", ASIZE, ASIZE) ;

for (i=0; i<asize ; i++) {
for (j=0; j<ASIZE; j++) {
fprintf(fp, maze[i][j] == ‘#’ ? "1 " : "0 ") ;
}
}

pclose(fp) ;

#ifdef MINECRAFT
/* now, print out the directions. */

for (i=0; i<ASIZE; i++) {
printf("begin row %d\n", i+1) ;

char ch = maze[i][0] ;
int chcnt = 1 ;
for (j=1; j<ASIZE; j++) {
if (maze[i][j] != ch) {
printf("[ ] %d %s%s\n", chcnt, ch == ‘#’ ? "block" : "space", chcnt > 1 ? "s" : "") ;
chcnt = 1 ;
ch = maze[i][j] ;
} else {
chcnt ++ ;
}
}
printf("[ ] %d %s%s\n", chcnt, ch == ‘#’ ? "block" : "space", chcnt > 1 ? "s" : "") ;
}
#endif

return 0 ;
}
[/sourcecode]

And here’s an example of the resulting maze:

Of course a maze of this size would take years for me to complete in Minecraft, so I designed a much smaller one (the total size is about 15×15). I also added some code (which is ifdef’ed out above) to generate a list of instructions on how to reproduce the maze by constructing it in rows. If you define MINECRAFT before compiling, it will dump a list of instructions that look like…

begin row 1
[ ] 15 blocks
begin row 2
[ ] 1 block
[ ] 13 spaces
[ ] 1 block
begin row 3
[ ] 13 blocks
[ ] 1 space
[ ] 1 block
...

Using this, I constructed a small 15×15 maze which took 256 cobblestones (not including the roof):

Thinking about the program as I was driving in this morning, I thought about generating a maze that was suitable for poster size, maybe 1000×1000 in size or larger. I probably should go ahead an implement the recursion optimization I described, then the size of the mazes that could be generated would be limited only by memory. And, of course, I could implement some quick and easy “virtual memory” to allow generation of mazes that were as large as disk space could allow. I could also implement a number of other optimizations.

I was also thinking that this program didn’t really suggest method that would work with a functional programming language.

Tom suggested that one way to tackle it might be to create a graph with all the possible links and random weights connecting each pair of adjacent nodes. You could then solve it by any method that can solve the minimum spanning tree. Tom recently wrote similar code, so that’s probably why he thought of it. It just makes my head hurt.

Demonstrating the Effect of Decoupling Capacitors

I’ve been interested in LOWFER radio (low frequency radio operation) for quite some time. Under Part 15, unlicensed experimenters can transmit signals in the frequency band between 160khz and 190khz, subject to certain regulations on power and antennas. You can read more about it here.

I was bored the other day, so I decided to breadboard the oscillator section of K0LR’s Simple LOWFER Transmitter. It’s basically a crystal oscillator that is tied to a 74HC4060 Oscillator/Divider. To transmit on LOWFER frequencies, you might use a 6Mhz crystal and divide it by 32, creating an output around 187khz. I didn’t have a 6Mhz crystal (or really any of the other right components), but I had close values, so I put the circuit together with what I had.

And saw lots of noise in the output waveform. The high and low values were probably wavering by several tens of millivolts. I then remembered that I hadn’t installed a decoupling capacitor. Since I hadn’t seen anyone demonstrate the effect of decoupling capacitors, I thought it was interesting enough to tack together a quick video.

K0LR’s Simple LOWFER transmitter

Gutenberg Gem: Blacker’s Art of Flymaking, by William Blacker.

I’m pretty much a city slicker. I’m more comfortable ordering take out than farming, fishing or hunting. My dad grew up on a farm, and went hunting and fishing for food. He used to tell stories of how his bicycle had a mount for his rifle across the handlebars. When I was a kid, he used to go hunt for deer and elk. We ate venison, not really out of need, but as a nod to my father’s humbler beginnings. We went fishing for trout and salmon. And we used to go camping. I haven’t been camping in twenty years. But sometimes I admit: I do kind of miss it. And fishing. It makes me think of quieter, slower times. The sound of running water. Of waking up early with dad and my brother to catch trout, and cook them for breakfast.

All of that is an aside. We did most of our trout fishing with just worms or fish eggs for bait, but I do remember a bit of fly fishing. Today’s Gutenberg Gem is a manual for tying flies. It seems like an quaint anachronism now, to spend hours tying flies, or writing books about them, carefully illustrated with beautiful water colors. It probably seems like a pointless activity to most of us, but it seems oddly appealing to me. The blog motto is, after all, “there is much pleasure in useless knowledge”.

The Project Gutenberg eBook of Blacker’s Art of Flymaking, by William Blacker..

How is PWM modulation like AM modulation?

In thinking about the 555 timer AM transmitter that I constructed last night and trying to understand how it might work, I eventually ended up with a basic question about PWM modulation. It boiled down to this: if you are generating a pulse width modulation signal with a rate of (say 540khz) but pulses whose duty cycle varies from 0 to 100%, how does this implement AM modulation?

If we consider the rectangular pulse centered inside an interval of running from -1 to 1, then a pulse with a duty cycle of D percent runs from -D/100 to +D/100. (From now on, we’ll find it convenient to express D as a fraction and not as a percent). We can use Fourier analysis to decompose this square wave into a series of sines and cosines at multiples of the base rate. For our application, we can ignore the DC component (it’ll be trimmed off by a DC blocking cap anyway) and we can assume that all higher multiples of the carrier frequency will be low pass filtered. The only thing we really need to look at is the component right at the carrier frequency.

We can do this analytically without too much trouble. To compute the Fourier coefficient, we compute 1/L * integral(cos(n * pi * t / L), dt, -D, D). (Sorry, WordPress isn’t all that good at this, and I wasn’t able to get MathJax to work). If we think of the the complete cycle as going from -1 to 1, then L = 1, and we can work this out: the amplitude of the carrier turns out to be 2.0 * sin(π * D) / π. We can make a graph, showing what the amplitude of the sine wave at the carrier frequency will be for varying duty cycles.

What does this mean? If we shift the duty cycle of our PWM waveform, we actually are modifying the amplitude (and therefore the power) of the transmitter output at the carrier frequency. As we deviate more from 0.5, we get more and more energy in the higher harmonics of the carrier frequency.

I’m sure that was about as opaque an explanation as possible, but it suggests to me a simple software simulation that I might code up this weekend to test my understanding.

Stay tuned.

Addendum: We can work out the relative amplitudes of the first three multiples of the carrier frequency: