Random distribution in zones
Aus EnigmaWiki
Available languages: Deutsch, English, Русский
Inhaltsverzeichnis |
Random Distribution of objects in zones
The Problem
Someone wants to put some objects randomly. The problem is: you can only put objects in exact positions. The simplest example is a stone which must be in a rectangle-shaped zone. This is very simple, but if the zone is not rectangular it is more complicated.
Summary
You divide the zone into as few rectangles as possible without overlapping rectangles. If the rectangles overlap, the probability of an object being found in these "doubled" areas is higher.
You first select a random rectangle from the list of all rectangles and then a random position within the selected rectangle.
Note 1: With several objects the problem of the overwriting always exists! We must determine somehow whether the position just selected has already been used. You could ignore this, but you no longer have a fixed number of objects. A good example are Oxyd stones - if one is missing because it has been overwritten, the level is unsolvable! But there are 2 approaches: either you remove each position after use from the array, or you examine each position immediately before use to check whether an object is already present. Method 1 is not applicable here, as we must always examine ...
Note 2: The zone consists of to many separate, not connected pieces, in the extreme case only from few separate 1-field positions, this approach becomes inefficient. You should prefer then a position list.
Example solution
rectangulars = {{{0,0},{2,12}},{{17,0},{19,12}},{{3,1},{16,2}},{{3,10},{16,12}}} function set_obstacle(akt_rect) local left_border = akt_rect[1][1] local right_border = akt_rect[2][1] local top_border = akt_rect[1][2] local bottom_border = akt_rect[2][2] repeat x = random(left_border, right_border) y = random(top_border, bottom_border) until enigma.GetStone(x,y) == nil -- So that we inadvertently do not overwrite another stone set_stone("st-woven",x,y) end function obstacle_wrapper() local n = table.getn(rectangulars) local r = random(1,n) set_obstacle(rects[r]) end
Analysis
The variable rectangulars contains the data of all rectangles, in which each field may be used.
It is simply a list of rectangle data, listing the coordinates of the upper-left and the lower-right corners.
The function set_obstacle takes exactly the data over a rectangle. Then an object (here a st-woven) is placed at random coordinates within this rectangle.
So far that is all not really interesting.
Now however the function comes obstacle_wrapper. It selects one of the rectangles by random rectangulars and calls the function set_obstacle.
Concerning the example above st-woven must appear in a three field wide frame along the border of the level.

