Experimenting with Binary Space Partitioning on the ZX81


I tried a simple binary partitioning experiment on the ZX81 to see if I could build a room-based map generator.

I thought I’d try something a bit different this month. I’d been looking at different ways to build maps for years but never really did much with them. After watching a video on binary partitioning, I decided to see if I could build a simple map builder on the ZX81.
This is the result.

# Watching It Run.
Rooms started as a way to build a map of rooms. Simple enough. But as I worked on the program, I added a few debugging lines to help me watch what it was doing. This made the demo a bit more interesting to watch. I could have easily run it in FAST mode and printed the final output, but where’s the fun in that?

In a departure from what I normally do, I left the debugging routines in the version I’m sharing. It may not be obvious at first, but there are two debugging routines. The first shows vertical (SV) and horizontal (SH) splits for each room.

The second is after Rooms clears the screen and displays room numbers. For each room, it prints its screen position, width, and height. Following that, the rooms are drawn on the screen. More on that later.

Rooms, Building, ZX81 Screenshot, 2025 by Steven ReidRooms, Building, ZX81 Screenshot, 2025 by Steven Reid

# Getting Ready.
With the premise complete, let’s dive into the program. The general idea is that you start with a room and divide it. That division could be vertical or horizontal. Easy, right? Not quite. First, you need a little math—and a data structure.

To keep things simple, I used an array to hold the rooms. I start with a single room. The routine looks like this:

1000 REM **INIT
1010 LET NR=1
1020 LET NM=10
1030 LET RM=5
1040 DIM R(NM,4)
1050 LET R(1,1)=0
1060 LET R(1,2)=0
1070 LET R(1,3)=63
1080 LET R(1,4)=43

The variable NR tracks the number of rooms. R holds each room’s position and dimensions. Two constants give me flexibility in adjusting the map creation. The NM variable holds the maximum number of rooms to create. The RM variable contains the minimum room size. With that in place, I can start building the map.

# Building Rooms.
The next step is to walk through each room and try to split it. Using a FOR loop, I pick a split direction. I used a little trick to do that in a single line:

2060 GOSUB 3000+100*INT (RND*2)

This lets me jump to one of two routines—vertical split or horizontal split—without extra conditionals.

The general algorithm:

  • Divide the room randomly.
  • Calculate the new room’s screen coordinates.
  • Adjust the original room’s width and height.
  • Calculate the new room’s width and height.

After the split, the main routine performs two checks:

  • Is each room big enough?
  • Are we still below the room limit?

If either fails, it skips the update and moves on. If both pass, the original room is updated, NR increases, and the new room is inserted at the end of the array.

Rooms, Finding, ZX81 Screenshot, 2025 by Steven ReidRooms, Finding, ZX81 Screenshot, 2025 by Steven Reid

# Building a Map.
There’s a larger loop that keeps dividing rooms until we reach our target count. Ten seemed like a good start. Inside this loop, the program prints out the rooms created so far and then draws them to the screen.

I originally planned to turn off debugging and just show the final rooms, but I ended up liking the look, so it stayed.

You may notice that rooms print in a strange order. That’s because new rooms are appended to the array and aren’t always next to the room that generated them. I could have created a tree structure, linking parent to child. I didn’t need that for this demo, but maybe in the future.

Rooms, Final, ZX81 Screenshot, 2025 by Steven ReidRooms, Final, ZX81 Screenshot, 2025 by Steven Reid

# What’s Next.
The rooms generated here work fine, but they could use more variety. For the next version, I plan to add connections and vary the room sizes. That should give the map more personality—especially for dungeons or caves.

I’ll likely convert the whole thing to machine code as well, since speed becomes an issue as complexity grows.

Once I have the core engine working, the real challenge begins: what do I use it for? I have some old game ideas from my teenage years that would fit nicely. I had monsters and such built out in earlier projects, but everything was quite static. This system would give me a proper world to drop them into.

Looking forward to sharing more as it grows.

---

Want to try it out? You can run the program, or view the code if you’d like to see how it works.



Comments on this article:

No comments so far.

Write a comment:

Type The Letters You See.
[captcha image][captcha image][captcha image][captcha image][captcha image][captcha image]
not case sensitive