অপসারণ দ্বীপপুঞ্জ
আমি আমার গেমগুলির একটির আগে এই ধরণের কাজটি করেছি। বাইরের দ্বীপ থেকে মুক্তি পাওয়ার জন্য প্রক্রিয়াটি মূলত:
- প্রথমে অবশ্যই গ্যারান্টি থাকতে হবে মানচিত্রের কেন্দ্রটি সর্বদা মূল জমির অন্তর্গত থাকবে এবং প্রতিটি পিক্সেলটি "ল্যান্ড" বা "জল" (অর্থাত্ বিভিন্ন রঙ) হিসাবে শুরু হয়।
- তারপরে মানচিত্রের কেন্দ্র থেকে শুরু করে কোনও "ল্যান্ড" টাইল জুড়ে ছড়িয়ে একটি চার দিকের বন্যা পূর্ণ করুন । এই বন্যায় পরিদর্শন করা প্রতিটি পিক্সেল চিহ্নিত করুন "মাইনল্যান্ড" এর মতো আলাদা ধরণের হিসাবে।
- অবশেষে পুরো মানচিত্রের ওপরে যান এবং অন্যান্য দ্বীপ থেকে মুক্তি পেতে যে কোনও অবশিষ্ট "ল্যান্ড" পিক্সেলকে "জল" তে রূপান্তর করুন।
হ্রদ সরানো হচ্ছে
দ্বীপের অভ্যন্তরের গর্তগুলি (বা হ্রদ) থেকে মুক্তি পাওয়ার জন্য আপনি একই ধরণের প্রক্রিয়া করছেন তবে মানচিত্রের কোণ থেকে শুরু করে পরিবর্তে "জল" টাইলস দিয়ে ছড়িয়েছেন। এটি আপনাকে অন্যান্য জলের টাইলগুলির থেকে "সমুদ্র" পার্থক্য করতে দেয় এবং তারপরে আপনি পূর্ববর্তী দ্বীপগুলি থেকে যেমন মুক্তি পেয়েছিলেন তেমনই আপনি সেগুলি থেকে পরিত্রাণ পেতে পারেন।
উদাহরণ
আমাকে এখানে আমার কোথাও যে বন্যা ভরাট রয়েছে তার বাস্তবায়ন সন্ধান করতে দাও (অস্বীকৃতি, আমি দক্ষতার কোনও যত্ন নিই না, তাই আমি নিশ্চিত যে এটি বাস্তবায়নের আরও অনেক কার্যকর উপায় আছে):
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>
পরিবর্তে (আমার উত্তরের সাথে মেলে সিতেও, তবে অন্যান্য ভাষাগুলির সাথে খাপ খাইয়ে নেওয়া সহজ হওয়া উচিত) এবং এর উপর অন্যান্য বাস্তবায়ন রয়েছে লিঙ্কটিও)।