द्वीपों को हटाना
मैंने इस तरह का काम अपने एक खेल से पहले किया है। बाहरी द्वीपों से छुटकारा पाने के लिए, प्रक्रिया मूल रूप से थी:
- पहले गारंटी होनी चाहिए कि मानचित्र का केंद्र हमेशा मुख्य भूमि से संबंधित होगा, और प्रत्येक पिक्सेल "भूमि" या "जल" (यानी अलग-अलग रंग) के रूप में शुरू होता है।
- फिर एक चार दिशा की बाढ़ भरें जो केंद्र से नक्शे से शुरू होकर किसी भी "लैंड" टाइल में फैल जाए। इस बाढ़ से जाने वाले प्रत्येक पिक्सेल को एक अलग प्रकार जैसे "मेनलैंड" के रूप में चिह्नित करें।
- अंत में पूरे मानचित्र पर जाएं और अन्य द्वीपों से छुटकारा पाने के लिए किसी भी शेष "लैंड" पिक्सेल को "पानी" में परिवर्तित करें।
झीलों को हटाना
द्वीप के अंदर छेद (या झीलों) से छुटकारा पाने के लिए, आप एक समान प्रक्रिया करते हैं, लेकिन नक्शे के कोनों से शुरू करते हैं और इसके बजाय "पानी" टाइल से फैलते हैं। यह आपको "सागर" को अन्य पानी की टाइलों से अलग करने की अनुमति देगा, और फिर आप उनसे छुटकारा पा सकते हैं जैसे कि आप पहले द्वीपों से छुटकारा पा गए थे।
उदाहरण
मुझे बाढ़ के अपने कार्यान्वयन को खोदने दें जो मैंने यहां कहीं है (अस्वीकरण, मुझे दक्षता के बारे में परवाह नहीं है, इसलिए मुझे यकीन है कि इसे लागू करने के कई और अधिक कुशल तरीके हैं):
private void GenerateSea()
{
// Initialize visited tiles list
visited.Clear();
// Start generating sea from the four corners
GenerateSeaRecursive(new Point(0, 0));
GenerateSeaRecursive(new Point(size.Width - 1, 0));
GenerateSeaRecursive(new Point(0, size.Height - 1));
GenerateSeaRecursive(new Point(size.Width - 1, size.Height - 1));
}
private void GenerateSeaRecursive(Point point)
{
// End recursion if point is outside bounds
if (!WithinBounds(point)) return;
// End recursion if the current spot is a land
if (tiles[point.X, point.Y].Land) return;
// End recursion if this spot has already been visited
if (visited.Contains(point)) return;
// Add point to visited points list
visited.Add(point);
// Calculate neighboring tiles coordinates
Point right = new Point(point.X + 1, point.Y);
Point left = new Point(point.X - 1, point.Y);
Point up = new Point(point.X, point.Y - 1);
Point down = new Point(point.X, point.Y + 1);
// Mark neighbouring tiles as Sea if they're not Land
if (WithinBounds(right) && tiles[right.X, right.Y].Empty)
tiles[right.X, right.Y].Sea = true;
if (WithinBounds(left) && tiles[left.X, left.Y].Empty)
tiles[left.X, left.Y].Sea = true;
if (WithinBounds(up) && tiles[up.X, up.Y].Empty)
tiles[up.X, up.Y].Sea = true;
if (WithinBounds(down) && tiles[down.X, down.Y].Empty)
tiles[down.X, down.Y].Sea = true;
// Call the function recursively for the neighboring tiles
GenerateSeaRecursive(right);
GenerateSeaRecursive(left);
GenerateSeaRecursive(up);
GenerateSeaRecursive(down);
}
मैंने अपने खेल में झीलों से छुटकारा पाने के लिए पहले कदम के रूप में इसका इस्तेमाल किया। कॉल करने के बाद, मुझे बस इतना करना होगा:
private void RemoveLakes()
{
// Now that sea is generated, any empty tile should be removed
for (int j = 0; j != size.Height; j++)
for (int i = 0; i != size.Width; i++)
if (tiles[i, j].Empty) tiles[i, j].Land = true;
}
संपादित करें
टिप्पणियों के आधार पर कुछ अतिरिक्त जानकारी जोड़ना। यदि आपका खोज स्थान बहुत बड़ा है, तो एल्गोरिथ्म के पुनरावर्ती संस्करण का उपयोग करने पर आपको स्टैक ओवरफ़्लो का अनुभव हो सकता है। एल्गोरिथ्म के एक गैर पुनरावर्ती संस्करण के लिए स्टैकओवरफ़्लो (दंडित इरादा :-)) पर एक लिंक दिया गया है, Stack<T>
इसके बजाय मेरे उत्तर का मिलान करने के लिए (सी # में भी) का उपयोग करते हुए , लेकिन अन्य भाषाओं के लिए अनुकूल होना आसान है, और उस पर अन्य कार्यान्वयन भी हैं लिंक भी)।