If you take a look at the day 3 post below, you’ll no doubt see that the DefaultCorridorGenerator function was pretty unwieldy (> 200 lines).  While a lot of that was comments, about 50 lines of it was dedicated to “ensuring variety” when placing corridors by including both possible corridor directions – e.g. in a case like

                //        _____
                //   X____|   |
                //    |   | R |
                //    |   |___|
                //  __|__
                //  |   |
                //  | L |
                //  |___|
                tunnelMeetX = RandomValueBetween(leftChild.BoundingRect.Left + 1, leftChild.BoundingRect.Right);
                tunnelMeetY = RandomValueBetween(rightChild.BoundingRect.Top + 1, Math.Min(rightChild.BoundingRect.Bottom - 1, leftChild.BoundingRect.Top));
                DigDownRightCorridor(tunnelMeetX, tunnelMeetY);

The corridor could actually exit the lower region from the top or the right edge of the region. I was worried that if I only chose one, then the map might seem to favor particular corridor orientations (granted, no one would really notice it, but I would 😉 ).

The problem with that ill-conceived sense of purity was that it resulted in a large and quite repetitive looking (and error-prone) function. Case in point – the above code snippet is hit in the case of a horizontal partition (dungeonNode.SplitOrientation == DungeonBSPNode.Orientation.Horizontal), and the vertical partition case had a similar, but different chunk of code with the child nodes reversed –

                 //        _____
                 //   X____|   |
                 //    |   | L |
                 //    |   |___|
                 //  __|__
                 //  |   |
                 //  | R |
                 //  |___|
                 tunnelMeetX = RandomValueBetween(rightChild.BoundingRect.Left + 1, Math.Min(rightChild.BoundingRect.Right - 1, leftChild.BoundingRect.Left));
                 tunnelMeetY = RandomValueBetween(leftChild.BoundingRect.Top + 1, leftChild.BoundingRect.Bottom);
                 DigDownRightCorridor(tunnelMeetX, tunnelMeetY);

The end result to the user is similar, and the code looks similar, but it’s sufficiently different that I couldn’t easily refactor it into down.

Well, turns out I don’t need to worry about it. It occurred to me on my (45 minute – oy!) drive into work that the partitioning approach gave just as much odds to vertical as horizontal splits, so as long as I ensured that one of them (Horiz, in my case) dug Down/Right corridors & Down/Left corridors, and the other (Vert) dug Up/Right & Up/Left corridors, then I’d have an equally random chance of having each different type of corridor in the level. Obvious in hindsight, but I’ll take pleasure from getting to remove some of that code instead :).

Code!

I picked up a DropBox account and put the source code up there. Consume at your own risk – it’s butt uhhhh-gly right now (hey, I’m doing this for me, not you 🙂 ) – but it might shed more light on what I’m talking about in these posts. I’ll try to include code each time I make a new post.

Code for 4-12 Post

Cheers,
Jeff

Advertisements