আমি কীভাবে আমার গেমটিতে এলোমেলো হ্রদ এবং নদী তৈরি করতে পারি?


19

আমার একটি 2 ডি ব্লক বিল্ডিং গেম রয়েছে এবং এলোমেলোভাবে উত্পাদিত হ্রদ এবং নদী তৈরি করার চেষ্টা করছি। আমি পার্লিনের শব্দের অ্যালগরিদমের দিকে নজর রেখেছি, কিন্তু, আমি এলোমেলো এবং দুর্দান্ত ফলাফল উত্সাহ পেতে পাইনি।

আমি অজগর শব্দ গ্রন্থাগারটি ব্যবহার করার চেষ্টা করছি , কিন্তু, এটি খুব এলোমেলোভাবে মানচিত্র তৈরি করে নি।

এটিকে আরও এলোমেলো করে তুলতে আমি কি কোনও বীজ ফাংশন মিস করছি library আমি যদি আরও এলোমেলোভাবে যেতে চাই তবে আমি কোন পরিবর্তনশীল পরিবর্তন করব? যদি সম্ভব হয় তবে কম গণিত এবং আরও অজগর শর্তাবলী সহ আমাকে একটি কম প্রযুক্তিগত উত্তর দিন।

মানচিত্রটি 2D টাইলড মানচিত্র। অন্যান্য অ্যালগরিদমের অ-এলোমেলোতার কয়েকটি উদাহরণ এখানে। নিম্নলিখিত কোডটি পরপর 3 বার আউটপুট করা হয়েছিল। আমি এই জাতীয় কিছু দিয়ে অক্টাভ এবং ফ্রিকোয়েন্সিটিকে এলোমেলো করেছিলাম:freq = 16.0 * random.randint(1, 500000) * 0.000001 + 0.5

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1
1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1

এটি সেই কোড যা উপরের আউটপুটটি তৈরি করেছে:

"""Writes a 256x256 grayscale simplex noise texture file in pgm format
(see http://netpbm.sourceforge.net/doc/pgm.html)
"""
# $Id: 2dtexture.py 21 2008-05-21 07:52:29Z casey.duncan $

import sys
from noise import pnoise2
import random
octaves = random.randint(1, 500000) * 0.000001 + 0.5
freq = 16.0 * octaves
for y in range(30):
    for x in range(40):
        n = int(pnoise2(x/freq, y / freq, 1)*10+3)
        if n>=1:
            n=1
        else:
            n=0
        print n,
    print

আরও তথ্য, দয়া করে। এই প্রশ্নের বর্তমান অবস্থাতে উত্তর দেওয়া যাবে না।
গুস্তাভো ম্যাকিয়েল

আমি আরও কিছু যোগ করেছি, তবে, আপনার কী জানা দরকার।
জুলিয়ান

আপনি ভাল তথ্য যোগ করেছেন, তবে আমাদের আরও কিছু দরকার। "খুব এলোমেলোভাবে না" কি? আমাদের কাছে যে কোনও স্ক্রিন শট দেওয়া তা দেখতে পাবে যে প্রদত্ত ফলাফল কী এবং এর ফলাফল কী? আপনি এটি কিভাবে চেষ্টা করে? আমাদের দেখানোর জন্য কোনও কোড? আপনার প্রসঙ্গ কি? 2 ডি বা 3 ডি? টাইল্ড বা বহুভুজ? দুঃখিত যদি এগুলি খুব বেশি হয় তবে আমি কেবল সাহায্য করার চেষ্টা করছি। -1 আমার ছিল না, আপনি তথ্য না দিলে প্রশ্নটি সাইটের পক্ষে অযোগ্য হয়ে যাবে এবং তারা এটি বন্ধ করে দেবে। তাই আবারও, আমি সাহায্য করার চেষ্টা করছি।
গুস্তাভো ম্যাকিয়েল

2
+1, এখন এটি একটি ভাল প্রশ্ন :) পার্লিন শোরগোল এবং সমস্ত প্রক্রিয়াজাত প্রজন্মের সাথে আমি ভাল নই, তবে, আপনি কি এলোমেলো জিনিসটি বানাচ্ছেন? যদি আমি ভুল না হয়ে থাকি random.seed()তবে এর সময় সিস্টেম সময়টি বীজ হিসাবে ব্যবহৃত হবে। এবং এর পরিবর্তে octaves = random.randint(1,500000)*.000001+.5আপনি চেষ্টা করতে পারেন: octaves = random.random() (এর একই ফলাফল রয়েছে, আপনি 0 এবং 1 এর মধ্যে একটি সংখ্যা পাবেন তবে এটি কেবল 500000 সংখ্যার চেয়ে অনেক বেশি সম্ভাবনা))
গুস্তাভো ম্যাকিয়েল

ধন্যবাদ +1 :) :) আরও 1 টি মন্তব্যে চেষ্টা করার চেষ্টা করেও আমি করতে পারি না
জুলিয়ান

উত্তর:


7

ঠিক আছে, যেমনটি মনে হচ্ছে আপনি এলোমেলো নম্বর জেনারেটরটি বদ্ধ করছেন না । পাইথনে এটি কেবল একটি এলোমেলো.সীড () দিয়ে সহজেই করা যায় ।

এবং আমি দেখতে পাচ্ছি যে আপনি 1 এবং 500000 এর মধ্যে একটি সংখ্যা তৈরি করছেন এবং এটি 0 থেকে 1 এর মধ্যে করছেন It's এটি একটি কার্যকরী পদ্ধতি, তবে এটি কেবল 500000 সম্ভাবনার সাথে আবদ্ধ। আপনি random.random()ইতিমধ্যে 0 এবং 1 এর মধ্যে একটি সংখ্যা তৈরি করে কেবল এটি ব্যবহার করে আরও ভাল , তবে আরও অনেক সম্ভাবনার সাথে! আপনার কোডটি সূচিত হিসাবে আপনার যদি এখনও 0.5 এবং 1.0 এর মধ্যে একটি সংখ্যা প্রয়োজন হয় তবে আপনি ঠিক করতে পারেন:(random.random() * 0.5) + 0.5

আপনার চূড়ান্ত কোডটি নিম্নলিখিত হিসাবে দেখা উচিত:

import sys
from noise import pnoise2
import random
random.seed()
octaves = random.random()
# octaves = (random.random() * 0.5) + 0.5
freq = 16.0 * octaves
for y in range(30):
    for x in range(40):
        n = int(pnoise2(x/freq, y / freq, 1)*10+3)
        if n>=1:
            n=1
        else:
            n=0
        print n,
    print

এখানেই শেষ!


বীজ এর সাথে কীভাবে কিছু করার আছে তা আমি পরিষ্কার করছি না। আপনি বীজ না দিলে এলোমেলো সংখ্যাগুলি এখনও এলোমেলো থাকবে তবে পুনরাবৃত্তি করবে। আপনি যখন প্রোগ্রাম চালাবেন ততবার বীজ বপন না করার একমাত্র লক্ষণটি একই র্যান্ডম ক্রম হওয়া উচিত (ধরে নিই প্রতি বারে একই বীজ ব্যবহৃত হয়)।
টিম হল্ট

1
যদি আপনি আপনার প্রশ্নে উল্লিখিত হিসাবে টানা তিনবার একই আউটপুট পান তবে এটি সম্ভবত সম্ভবত কারণ আপনি এলোমেলো জেনারেটরটি না রেখেছেন। এটি বীজ করুন এবং দেখুন যে এটি সমস্যার সমাধান করে।
ashes999

আহ আমি "একটানা 3 বার" বিটটি দেখিনি - পড়ছিলাম, "আরও বেশি এলোমেলো করে তুলতে আমি সেই লাইব্রেরিতে কিছু বীজ ফাংশন অনুপস্থিত রয়েছি"। হ্যাঁ পুনরাবৃত্তি এলোমেলো জন্য সিডিং :)
টিম হল্ট

8

এটি আপনার নির্দিষ্ট প্রোগ্রামিং প্রশ্নের উত্তর দিচ্ছে না, তবে বিবেচনা করুন যে হ্রদ এবং নদীগুলি তৈরি করা এলোমেলোভাবে জল এবং তাদের মধ্যে জলের ফোঁড়াগুলি স্থাপন করে না। এটি ভূখণ্ডের উচ্চতা সম্পর্কে - হতাশাগুলি (অববাহিকা) যা হ্রদে পরিণত হয় এবং এমন জল যে উচ্চ থেকে নিম্নের দাগে প্রবাহিত হয় about

আপনি যদি হ্রদ এবং নদী তৈরির দুর্দান্ত উদাহরণ চান যা আপনি বুঝতে পারেন তবে আপনি এই ব্লগ পোস্টটি পরীক্ষা করে দেখতে পারেন -> http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html এটি এই ধরণের জিনিসটির জন্য একটি ভাল রেফারেন্স যদি আপনার লক্ষ্যটি যথাযথভাবে বাস্তবসম্মত হাইড্রোগ্রাফি হয়।


2

এটি খুব সহজ: আপনি যদি একই মানচিত্রটি পর পর তিনবার (বা আরও বেশি) পান তবে এটি বীজটিকে এলোমেলো করে না দেওয়ার কারণ।

এটার মানে কি?

কম্পিউটারগুলি সহজাতভাবে নির্বিচারক (নন-এলোমেলো), তাই তারা এলোমেলোভাবে অনুকরণ করে। এটি আসলে পুনরাবৃত্তভাবে এলোমেলো (এজন্য আমরা এটিকে "সিউডো এলোমেলো নম্বর জেনারেটর" বলি)।

কিভাবে কাজ করে?

আপনি যখন একটি এলোমেলো সংখ্যা তৈরি করেন, আপনার কাছে এটি একটি "বীজ" দেওয়ার বিকল্প রয়েছে। গুরুত্বপূর্ণ বিষয় হ'ল আপনি যদি সর্বদা একই বীজ ব্যবহার করেন তবে আপনি সর্বদা একই ক্রমে একই র্যান্ডম সংখ্যার একই ক্রমটি পাবেন। সর্বদা. এটি ভাল বা খারাপ হতে পারে।

আপনার ক্ষেত্রে, দেখে মনে হচ্ছে আপনি র্যান্ডম জেনারেটরটি বপন করছেন না এবং ডিফল্টরূপে আপনি একই বীজ পেয়ে যাচ্ছেন - এটি সম্ভবত আপনার তারিখ / সময়ের কিছু উপাদান ব্যবহার করে। অতএব, আমি আপনাকে এলোমেলো করার পরামর্শ দিচ্ছি।

গুসাতাভো তার উত্তরে যেমন উল্লেখ করেছেন, আপনাকে র্যান্ডম.সীড () কল করতে হবে । দস্তাবেজগুলি জানিয়েছে যে "যদি এক্স [ডিফল্ট প্যারামিটার] বাদ দেওয়া হয় বা None, বর্তমান সিস্টেমের সময় ব্যবহার করা হয়।" এটি যথেষ্ট হওয়া উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.