An Amazing Data Structure - Programming a Maze in C++

Filled under:

An Amazing Data Structure - Programming a Maze in C++


In this article, we will investigate the development of a labyrinth of rectangular shape in C++ and we will propose a calculation that will highlight the answer for experiencing and escaping the labyrinth. Our goal here is to make an impeccable labyrinth, the most straightforward kind of labyrinth for a PC to create and explain. An impeccable labyrinth is characterized as a labyrinth which has one and just a single way from any indicate in the labyrinth some other point. This implies the labyrinth has no difficult to reach segments, no roundabout ways, no open zones. Obviously simple to be unraveled, this issue requires the utilization of a few information structures: exhibits, heaps and records. Our objective comprises in utilizing C++ classes keeping in mind the end goal to characterize half breed structures.
Catchphrases: labyrinth, information structure, heap, exhibit, connected rundown, way.

Introduction

When concentrate a programming dialect, one frequently experiences information structures, for example, heaps, connected rundown and trees, in addition to other things. As per the worldview, the information structure possesses a place of skeleton in the program, though the calculations reflect just a method for controlling the information. Lamentably, in many reports alluding to this subject, one presents these structures straightforwardly, with cases of a ghastly detail. We will hereinafter take a gander at an intriguing illustration, though marginally complex: making a labyrinth and finding an exit plan. Give us a chance to consider the accompanying case. We begin with a lattice comprised of a few lines and sections of rectangular cells (see figure 1). By breaking a couple dividers of a couple of cells, we can manufacture a labyrinth (see figure 2). One thing left to do is to figure out which dividers ought to be crushed, at the exact instant where we have wrapped up the labyrinth or if there is a way between the ingoing cell and the active cell.
To answer the past inquiries, we will give our program three sorts of structure. The exhibit starts things out. It is the least complex structure. It comprises of a rectangle of cells made out of a specific number of lines and sections. In the event that the cluster is not numerical, there is very little we can do with the exception of perusing and composing its information. By the by, it is fairly advantageous for speaking to information in a minimal shape, even outwardly esthetical. Inside the system of this article, we utilize it to allude to our labyrinth inside the class of a similar name. Concerning matter, we should concentrate our consideration on the variable Puzzle situated in the postings 5 and 6. Perplex is really a direct cluster put in memory, what we can permit since we picked a rectangular-formed labyrinth. In this specific situation, we give the clients of the activated class with an ordering administrator of the frame: Puzzle (i,j). In the event that this administrator essentially demonstrates the cell put in line i and section j, the entrance in memory to that cell will be completed by moving from i * add up to number of segments + j spaces in the memory.

Here comes the second structure and the rundown (doubly-connected rundown, for our situation). It comprises of a few hubs, every one containing an information component free of any usage, including two pointers (whose qualities relate to the locations of the following and past hubs). By tradition, the "head" of a rundown is the hub having no past hub. Also, the "tail", the one that has no next hub. Numerous operations on records can be completed, the most common one being the addition (in the main, center or last place) of new components. So far as that is concerned, given us a chance to focus on the code of the posting 3. We can see that the rundown structure for the classroom is executed. Here the capacity Glue gives the main operation, we are keen on: it does the expansion of two records containing given rooms. To play out this undertaking, we search for the head in one rundown and the tail in another. At that point we only "paste" the two hubs being referred to one upon the other. Plainly, as for the cluster, the rundown gives the obvious favorable position of developing. It is accordingly futile to know its size ahead of time.
Give us now a chance to proceed onward to the third structure: the heap. It is an impossible to miss instance of rundown that one can imagine as a store of articles. It has just a single pointer and thusly, we can't get to uninhibitedly to its components since we can remove just the one that is situated at first glance. We compress these properties by calling the heap a structure LIFO in which the Last Input is the First Output. In a heap, the main conceivable operations are to heap up another component (work push ()) and pull back (when conceivable) the last heaped up component (work pop ()). This property makes correctly the heap intriguing for our situation. Actually, when lost in the labyrinth, we will dependably move the likelihood of in reverse. Along these lines, on the off chance that we store our direction into the heap, the last heaped up component will dependably be a "withdraw arrangement". We execute this structure in the postings 3 and 4. The information of our structure is the directions of the cell (room) of the present area.
1. Encoding the openings and closings

Making a labyrinth is made by methods for a class which acknowledges any number of lines and sections. It assigns a variety of the sort lines * sections = rooms. The information of each room depends for the most part on two whole numbers. One indicates the set it has a place with and the other one determines the condition of its entryways. Aside from the edges, all cells have four entryways (down, ideal, up and left). In any case, as an entryway is shared by two compared rooms, we will consider that each room oversees just the entryways Down and Right that it contains (in light of the fact that they are at the down and right sides of the cells, in our drawings). Obviously, the edges make an exemption. We speak to the condition of the entryways (open, shut and, we should be insane, bolted) by the bits with the accompanying tradition:
00 : the entryway is shut
01 : the entryway is open
11 : the entryway is bolted

Additionally, we choose that the two first bits (at the correct side of the standard composition of a twofold number) symbolize the condition of the entryway Down and the two after bits (setting off to one side of the typical written work of a parallel number) speak to the one of the entryway Right. So here are the equivalences of some decimal numbers:
0 = 00
? the entryways Down and Right are shut.
7 = 01 11
? the entryway Down is bolted, the entryway Right is open.
Every single conceivable state are identified in the sort DoorStates of the posting 5. So as to recollect that them all the more effectively, we utilize D for (D)own, C for (C)losed, L for (L)ocked, O for (O)pen. With this tradition, it demonstrates fairly simple to compose the schedules permitting to change the condition of the entryways. To satisfy this undertaking, we should alter a little bit at a time their present condition by utilizing the administrators | and.
The distinctive capacities are actualized in the postings 5 and 6. By method for outline, consider the usage of the capacity LockRight(). It just applies the disjunctive administrator " | " a tiny bit at a time. For example, realizing that 12 (decimal) = 11 00 (twofold), the capacity bolts the entryway Right and does not touch the one of Down.
2. Laying the openings and closings
This initial step being characterized, we need now our labyrinth to be flawless or, at the end of the day, we need one and just a single way between two unspecified rooms. In a specialized perspective, it is along these lines an issue of speaking to all the conceivable directions by a tree. In a down to earth perspective, the lead will comprise in not making an entryway between two rooms on the off chance that they can as of now associate by another way. Here is, for instance, what could be the announcement of the production of a labyrinth: "Stamp each room separately, with an identifier. For whatever length of time that the labyrinth is not finished, put yourself - haphazardly - in a room. In the event that you discover an entryway shut, take a gander at the identifier of the neighbor room. In the event that the identifiers of the two rooms are distinctive, open their regular entryway and bind together their identifiers and furthermore their rundowns. Something else, bolt the entryway (for that implies that both rooms are as of now associated; open that entryway would make up a little island). The labyrinth will be considered as total when all rooms have a similar identifier".
When all is said in done, the many-sided quality of a labyrinth can be measured by its tree. The more it is "adjusted" (a tree is said to be "adjusted" if every one of its branches has roughly a similar size), the more mind boggling the labyrinth gets to be. It ought to be noticed that, rather than taking cells arbitrarily, one can likewise move by chance in the labyrinth.
The calculation is executed in the constructor of the class Maze. This constructor takes measurements as info. We begin the development by picking haphazardly a few cells. This operation empowers us to embed a few passages in order to make troublesome the look for the great way. At that point we embed a last circle doing a similar assignment toward the end. This circle is there just to watch that all rooms are truly associated.
3. Also, now... getting out !
Give us a chance to consider a virtual robot which, put in a room, must experience the exhibit keeping in mind the end goal to discover the exit plan. The robot can just satisfy four sorts of developments: up, down, left and right. On the off chance that we begin from the rule that it is situated at the position (i, j), here is the best approach to plan them:
Right : we move to (i + 1, j)
Left : we move to (i - 1, j)
Down : we move to (i, j + 1)
Up : we move to (i, j - 1)
Presently it is prudent to apply the traditional administer of the correct hand (or left hand), which comprises in continually taking after with one hand the mass of the labyrinth. It works extremely well on the off chance that one begins from an edge of the labyrinth. Be that as it may, if our robot gets tossed in wherever of the labyrinth, it risks pivoting, in light of the fact that it didn't pick the correct hand ! Here we see all the enthusiasm of putting away the direction completed in the heap : it empowers us to get back and search for another bifurcation as opposed to retaking boundlessly a similar way in a similar course. The calculation for escaping the labyrinth has the accompanying appearance :
Put into the heap (push) the beginning position
While we don't discover the exit plan
Assess the opening of the entryways of the space for each opened entryway
On the off chance that the entryway has not been crossed
Go ahead
Store (push) the new position
Else we are in a deadlock
Backpedal (pop)
In the usage, clearly we should take after a strict request when searching for opened entryways from the one by which we came into the room toward the needles of a watch (instance of the left hand) or the other way (instance of the correct hand). The last calculation is executed in the posting 8.

Subsequent to gathering the source code and running the program, you will acquire something like the figure 6. It ought to be noticed that the introduced source code could actualize more mind boggling labyrinths, similar to those in a pentagonal, hexagonal shape et cetera. Truth be told, just the show will essentially have the effect.
4. How to visualize the maze
Utilizing Shell, you should sort in :
:$ make - f Show
:$ make 30 60 10 and
These charges will empower to draw a labyrinth with a measurement of 30 lines and 60 segments with cells having ten pixels as an afterthought (nine, really, since a pixel is utilized for drawing the divider). You will in this way acquire something like the figure 5.

Rodrigue S. Mompelat has educated and done examines in French (Universities of Paris III Sorbonne Nouvelle and Paris V René Descartes, University of Cergy-Pontoise) and at Copenhagen Business School, the University of Aaalborg and RISØ National Laboratory in Denmark. His exploration fields are Artificial Intelligence and Neurocybernetics.