I've never finished a game of my own (though there was that one abortion in 2006), yet I still enjoy fiddling around with OHRRPGCE, and I like to sprite and come up with game concepts in my spare time. Since I don't like the crap I produce to go to waste, I thought I'd share it here instead. In particular, I'll be messing with OHRRPGCE and HSS, seeing what fun things I can do with them. I don't have any big concepts in mind just yet, but hey, maybe we'll go with the flow and see what happens?
Today I went about writing a script that randomly generates mazes, also known as "Baby's First Algorithm". Not only am I a greenhorn when it comes to creating complex scripts, I'm also terribly rusty with HSS. Therefore this has been quite an adventure. But somehow I got a working product, which I'm about to show off like a kindergartener with a macaroni-and-glue portrait.
My goal was to create a simple maze: one that covers the entire grid, with where you're able to get from any point in the maze to any other point (i.e. there are no sections completely blocked off from one another). I'll get to script in a minute, but first here's the premade map that I'm working with for this demo:

This is the blank slate that the maze will be chiseled into, complete with hideous placeholder graphics. Right now orange tiles represent solid walls, while black tiles (of which there are none at the moment) represent "excavated" passages. To make this thing a little easier to read:

The green tiles here represent "cells," as I will be calling them. Every single cell will be excavated, and every cell will be connected to every other cell in the end. As you can see, this simple demo map is 6x6 cells. Yellow tiles are the walls that lie between cells. Some of them will be excavated to create paths between cells, while others will remain solid walls. Orange tiles will always be solid. The orange tiles with the black x's designate the border of the map. All the fun stuff will happen in the middle.
That blank map is starting to bug me, so let's get started making a maze.
Code: Select all
variable (CurrentCellEReady)
variable (CurrentCellNReady)
variable (CurrentCellSReady)
variable (CurrentCellWReady)
variable (CurrentCellX)
variable (CurrentCellY)
variable (ExtraPathNumber)
variable (ExtraPaths)
variable (GoodToGo)
variable (MapSize)
variable (RandomNumberGod)
variable (TotalCells)
variable (VisitedCells)
variable (WallCleared)Code: Select all
MapSize := 6
TotalCells := MapSize*MapSizeTotalCells gives the volume of the grid (in cells). Since it's a square map, the math is easy. In the case of my size-6 map, the total number of cells is 6 times 6, or 36.
Code: Select all
CurrentCellX := random(1,MapSize)*2
CurrentCellY := random(1,MapSize)*2Code: Select all
while (VisitedCells < TotalCells) do (
if ((read map block (CurrentCellX,CurrentCellY--2)) == 2) then (CurrentCellNReady := 1) else (CurrentCellNReady := 0)
if ((read map block (CurrentCellX,CurrentCellY+2)) == 2) then (CurrentCellSReady := 1) else (CurrentCellSReady := 0)
if ((read map block (CurrentCellX--2,CurrentCellY)) == 2) then (CurrentCellWReady := 1) else (CurrentCellWReady := 0)
if ((read map block (CurrentCellX+2,CurrentCellY)) == 2) then (CurrentCellEReady := 1) else (CurrentCellEReady := 0)
#Checks to see which neighboring cells are excavated and which aren't.
if (CurrentCellNReady == 1 || CurrentCellSReady == 1 || CurrentCellWReady == 1 || CurrentCellEReady == 1) then (
#If at least one of the neighboring cells is excavated...
while (WallCleared == 0) do (
RandomNumberGod := random(1,4)
if (RandomNumberGod == 1) then (
if (CurrentCellNReady == 1) then (
write map block (CurrentCellX,CurrentCellY--1,0)
write map block (CurrentCellX,CurrentCellY--2,0)
CurrentCellY -= 2
VisitedCells += 1
WallCleared := 1
)
)
if (RandomNumberGod == 2) then (
if (CurrentCellSReady == 1) then (
write map block (CurrentCellX,CurrentCellY+1,0)
write map block (CurrentCellX,CurrentCellY+2,0)
CurrentCellY += 2
VisitedCells += 1
WallCleared := 1
)
)
if (RandomNumberGod == 3) then (
if (CurrentCellWReady == 1) then (
write map block (CurrentCellX--1,CurrentCellY,0)
write map block (CurrentCellX--2,CurrentCellY,0)
CurrentCellX -= 2
VisitedCells += 1
WallCleared := 1
)
)
if (RandomNumberGod == 4) then (
if (CurrentCellEReady == 1) then (
write map block (CurrentCellX+1,CurrentCellY,0)
write map block (CurrentCellX+2,CurrentCellY,0)
CurrentCellX += 2
VisitedCells += 1
WallCleared := 1
)
)
)
#Randomly chooses a neighboring, unexcavated cell and clears out a path to it.
WallCleared := 0
) else (
#If none of the neighboring cells are excavated...
while (GoodToGo == 0) do (
CurrentCellX := random(1,MapSize)*2
CurrentCellY := random(1,MapSize)*2
if ((read map block (CurrentCellX,CurrentCellY)) == 0) then (GoodToGo := 1)
)
#Selects a new, excavated cell to work from.
GoodToGo := 0
)
)(When reading map blocks, 0 is the excavated black tile, 1 is the X-orange border tile, and 2 is the plain orange wall tile. The script will never attempt to excavate a border tile.)
If the script finds that all neighboring cells have been excavated, then it will randomly select another excavated cell and try from there. The script continues until every cell on the grid has been visited.
Code: Select all
ExtraPathNumber := random(1,TotalCells/3)
while (ExtraPaths < ExtraPathNumber) do (
CurrentCellX := random(1,MapSize)*2
CurrentCellY := random(1,MapSize)*2
#Selects a new cell to work from.
RandomNumberGod := random(1,4)
if (RandomNumberGod == 1) then (
if ((read map block (CurrentCellX,CurrentCellY--2)) == 0) then (
write map block (CurrentCellX,CurrentCellY--1,0)
)
)
if (RandomNumberGod == 2) then (
if ((read map block (CurrentCellX,CurrentCellY+2)) == 0) then (
write map block (CurrentCellX,CurrentCellY+1,0)
)
)
if (RandomNumberGod == 3) then (
if ((read map block (CurrentCellX--2,CurrentCellY)) == 0) then (
write map block (CurrentCellX--1,CurrentCellY,0)
)
)
if (RandomNumberGod == 4) then (
if ((read map block (CurrentCellX+2,CurrentCellY)) == 0) then (
write map block (CurrentCellX+1,CurrentCellY,0)
)
)
#Attempts to break down a wall.
ExtraPaths += 1
)That's all there is to the script (for now). When you run it, you'll get something like these:



Pretty nifty, huh? And just for one, here's what a 64x64 randomly-generated maze looks like:

The script works very quickly. Even that 64x64 maze I just posted was generated instantaneously. Still, I'm sure my script is less efficient than it would be had it been written by someone more experience than I; feel free to share criticism.
That's all I have for now. Maybe next time I'll add more features to the generation... perhaps start and finish spots, rooms, different wall types, randomly-placed objects and other features. Share any comments or suggestions you have. Peace out.



