মূল বিষয়বস্তু
কম্পিউটার প্রোগ্রামিং
Course: কম্পিউটার প্রোগ্রামিং > Unit 5
Lesson 2: দৈবভাবেএলোমেলো চলমান অবজেক্ট
ভেক্টর এবং পদার্থবিজ্ঞানের গতিবিদ্যার জটিলতায় জড়াবার আগে, পর্দায় কোন বস্তু কীভাবে চলমান হয় সেটা জানা দরকার। সবচেয়ে সহজ এবং সরল সিমুলেশন দিয়ে শুরু করা যাক—এলোমেলোভাবে চলা (random walk)।
ধরি, একটি কাঠের উপর মাঝামাঝি দাড়িয়ে আছি। প্রতি দশ সেকেন্ডে, একটি মুদ্রা নিক্ষেপ করা হয়। Heads (হেডস হল মুদ্রার একপিঠ) হলে, একধাপ সম্মুখে যেতে হবে। Tails (টেইলস হল মুদ্রার অপরপিঠ) হলে, একধাপ পেছনে যেতে হবে। এটাই হল এলোমেলোভাবে চলা—যে কোন ধাপের সমষ্টি নিয়ে একটি পথ সংজ্ঞায়িত করা। আমরা কাঠ থেকে মাটিতে নেমে, ঐ একই মুদ্রা দুইবার নিক্ষেপ করে এলোমেলো করে দ্বিমাত্রিকভাবে চললে নিচের ফলাফল পাই:
নিক্ষেপ 1 | নিক্ষেপ 2 | ফলাফল |
---|---|---|
হেডস | হেডস | একধাপ সম্মুখে চলা। |
হেডস | টেইলস | একধাপ ডানদিকে চলা। |
টেইলস | হেডস | একধাপ বামদিকে চলা। |
টেইলস | টেইলস | একধাপ পেছনে চলা। |
ঠিক আছে, এটা দেখে মনে হচ্ছে একটি সহজ অ্যালগোরিদম। যাই হোক, এলোমেলোভাবে চলাকে ব্যবহার করে অনেক ঘটনার মডেল তৈরি করা যায়, গ্যাসীয় অণুর চলাচল থেকে শুরু করে একজন মানুষের দৈনিক বিচরণ ইত্যাদি বিভিন্ন ক্ষেত্রের সিমুলেশন তৈরি করার জন্য এটা ব্যবহার করা হয়। আমাদের ক্ষেত্রে, এটা শেখার তিনটি মূল উদ্দেশ্য আছে।
এলোমেলোভাবে চলার জন্য Walker (চলমান) অবজেক্ট
অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং (OOP) ব্যবহার করে
Walker
অবজেক্ট তৈরি করি। এটা অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং সম্পর্কে সামান্য পর্যালোচনা। অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং সম্পর্কে কোন ধারণা না থাকলে, আগে অবজেক্ট-অরিয়েন্টেড জাভাস্ক্রিপ্ট দেখা উচিৎ।জাভাস্ক্রিপ্টে একটি অবজেক্ট হল এমন ধরনের ডাটা (উপাত্ত) যার বৈশিষ্ট্য এবং কার্যকারিতা উভয়ই এটার সাথেই অথবা এটার প্রোটোটাইপে সংযুক্ত থাকে। আমরা একটি
Walker
অবজেক্ট তৈরি করতে চাই যা নিজের ডাটা সংরক্ষণ করে (এটা পর্দার যেখানে থাকে সেটার ডাটা) এবং কতিপয় কাজ করার ক্ষমতা রাখে (যেমন নিজেকে আঁকা অথবা একধাপ চলা)।Walker
অবজেক্টের অস্তিত্ব (instance) তৈরি করার জন্য, আমাদের একটি Walker
অবজেক্ট সংজ্ঞায়িত করতে হবে। আমরা এই অবজেক্টকে বিস্কুট কাটার হিসেবে ব্যবহার করব এবং বিস্কুটগুলো হল প্রত্যেকটি নতুন Walker
এর অস্তিত্ব।এখন
Walker
অবজেক্ট সংজ্ঞায়িত করে শুরু করা যাক। Walker
এর দুইটি ডাটা দরকার—এটার x-অবস্থানের জন্য একটি সংখ্যা এবং y-অবস্থানের জন্য আরেকটি সংখ্যা। কন্সট্রাক্টর ফাংশনে এগুলো নির্দিষ্ট করব, তাদেরকে ক্যানভাসের কেন্দ্রে নির্দিষ্ট করে দেবো।var Walker = function() {
this.x = width/2;
this.y = height/2;
};
এর সাথে x এবং y এর হিসাব রাখার জন্য,
Walker
অবজেক্টে মেথড থাকবে যা আমরা কল করতে পারব। প্রথম মেথডটি অবজেক্টকে একটি কালো বিন্দু হিসেবে আঁকবে। লক্ষ্য করি, জাভাস্ক্রিপ্টের অবজেক্টে মেথড যোগ করার জন্য অবজেক্টের prototype
(প্রোটোটাইপে) মেথড যোগ করতে হয়।Walker.prototype.display = function() {
stroke(0, 0, 0);
point(this.x, this.y);
};
দ্বিতীয় মেথডটি
Walker
অবজেক্টকে যে কোন দিকে একধাপ চলমান হতে সাহায্য করে। এখানে, মজার একটি বিষয় আছে। মাটিতে এলোমেলোভাবে চলার কথা মনে আছে কি? আসলে, এখন আমরা ক্যানভাসকে সেই মাটির মত ব্যবহার করতে পারি। চারটি সম্ভাব্য পদক্ষেপ রয়েছে। ডানদিকে একধাপ যাওয়ার জন্য x
কে বৃদ্ধি করতে হবে (x++
); বামদিকে যাওয়ার জন্য x
কে হ্রাস করতে হবে (x--
); সম্মুখ যাওয়ার জন্য এক পিক্সেল নিচে (y++
); এবং পেছনে যাওয়ার জন্য এক পিক্সেল উপরে (y--
) যেতে হবে। চারটি সম্ভাব্য পদক্ষেপ থেকে কীভাবে একটি পদক্ষেপ বাছাই করব? আগেই বলা হয়েছে যে আমরা দুইটি মুদ্রা নিক্ষেপ করতে পারি। কিন্তু প্রসেসিং জেএসে, যখন আমরা সম্ভাব্য পদক্ষেপের কোন তালিকা থেকে যে কোন একটি বাছাই করব, তখন সংখ্যা বাছাইয়ের জন্য random()
ব্যবহার করব।Walker.prototype.walk = function() {
var choice = floor(random(4));
};
উপরের কোডটি 0 থেকে 4 এর মধ্যে যে কোন একটি ফ্লোটিং (floating) সংখ্যা বাছাই করে এটিকে
floor()
ব্যবহার করে পূর্ণ সংখ্যায় পরিণত করে, যার ফলাফল 0, 1, 2, অথবা 3 হয়। কলাকৌশল সম্পর্কে চিন্তা করলে দেখা যায়, সবচেয়ে বড় সংখ্যাটি 4.0 হবে না, কিন্তু 3.999999999 (দশমিক সংখ্যার যত স্থান পর্যন্ত 9 হয়) হবে; যেহেতু floor()
নিকটতম সমান অথবা নিচের মান রিটার্ন করে, এজন্য সবচেয়ে বড় সংখ্যা হিসেবে 3 পাওয়া যাবে। তারপর, বাছাই করা সংখ্যার উপর ভিত্তি করে উপযুক্ত পদক্ষেপ (বাম, ডান, উপর, অথবা নিচে) নেওয়া যাবে।Walker.prototype.walk = function() {
var choice = floor(random(4));
if (choice === 0) {
this.x++;
} else if (choice === 1) {
this.x--;
} else if (choice === 2) {
this.y++;
} else {
this.y--;
}
};
যেহেতু class (ক্লাস) লেখা শেষ, এখন আমরা
Walker
অবজেক্ট তৈরি করতে পারি। ধরি, আমরা একধাপ চলার সিমুলেশন করতে চাই, এজন্য কন্সট্রাক্টর ফাংশন new দিয়ে কল করে আমরা একটি সার্বজনীন চলক Walker
তৈরি করব।var w = new Walker();
এখন, walker কে দিয়ে কিছু করানোর জন্য, আমরা
draw()
ফাংশন সংজ্ঞায়িত করব এবং walker কে একধাপ চলমান করতে এবং প্রতি কলে নিজেকে আঁকানোর জন্য কোড করব:draw = function() {
w.walk();
w.display();
};
যেহেতু আমরা
background()
ফাংশনকে আঁকানোর ফাংশনে কল করি নাই, ক্যানভাসে অবজেক্টটির গমনপথ দেখতে পাই:এলোমেলোভাবে চলাকে আরও উন্নত করা
এলোমেলোভাবে চলাকে আমরা আরও উন্নত করতে পারি। একটি হল, এই walker এর পদক্ষেপ চারটি ধাপের মধ্যেই সীমাবদ্ধ—উপর, নিচ, বাম এবং ডান। উইন্ডোর যে কোন পিক্সেলের আটটি সম্ভাব্য পদক্ষেপ আছে এবং নবম সম্ভাব্যতা হল একই স্থানে থাকা।
একটি
Walker
অবজেক্ট তৈরি করার জন্য যা নিকটতম স্থানগুলোতে যেতে পারে (অথবা নিজের স্থানেই থাকতে পারে), আমাদের 0 থেকে 8 (নয়টি সম্ভাব্য পদক্ষেপ) এর মধ্যে যে কোন একটি সংখ্যা বাছাই করতে হবে। কিন্তু, দক্ষভাবে কোড করার উপায় হল সম্ভাব্য তিনটি x-অক্ষের (-1, 0, অথবা 1) ধাপ এবং তিনটি y-অক্ষের ধাপ নিয়ে কাজ করা।Walker.prototype.walk = function() {
var stepx = floor(random(3))-1;
var stepy = floor(random(3))-1;
this.x += stepx;
this.y += stepy;
};
এটাকে আরও উন্নত করার জন্য, আমরা
x
এবং y
এর জন্য দশমিক ব্যবহার করতে পারি এবং -1 থেকে 1 এর মধ্যে যে কোন মানের উপর ভিত্তি করে চলতে পারি - যদি "2.2" এবং "2.4" এর মধ্যে পার্থক্য দেখা যায়:Walker.prototype.walk = function() {
var stepx = random(-1, 1);
var stepy = random(-1, 1);
this.x += stepx;
this.y += stepy;
};
All of these variations on the “traditional” random walk have one thing in common: at any moment in time, the probability that the
Walker
will choose to take a step in a given direction (or not move at all) is equal to the probability that the Walker
will make any other given choice. In other words, if there are four possible steps, there is a 1 in 4 (or 25%) chance the Walker
will take any given step. With nine possible steps, it’s a 1 in 9 (or 11.1%) chance.মুলত,
random()
ফাংশনটি এভাবেই কাজ করে থাকে। এর দৈব সংখ্যার উৎপাদকটি এখানে এমন একটি সংখ্যা উৎপাদন করে যা সংখ্যার “সুষম” ডিস্ট্রিবিউশন হিসেবে আমাদের কাছে পরিচিত। আমরা এই ডিস্ট্রিবিউশনটি একটি প্রোগ্রাম ব্যবহার করে পরীক্ষা করে দেখতে পারি, যে প্রোগ্রামটি প্রতিবার একটি দৈব সংখ্যা নির্বাচন করলে সেই দৈব সংখ্যাটি গণনা করবে এবং একটি চতুর্ভুজের উচ্চতা অনুযায়ী গ্রাফ করবে:কয়েক মিনিট চলার পর, বারগুলোর উচ্চতা কি সমান হয়? সম্ভবত না। আমাদের নমুনা (যেমন বাছাইকৃত যে কোন সংখ্যা) অনেক ছোট এবং একটি নির্দিষ্ট সংখ্যা বেশিবার বাছাই হবার কারণে অনেক সময় পার্থক্য থাকতে পারে। যে কোন সংখ্যা উৎপন্ন করার প্রক্রিয়াটি উন্নত হলে, সময়ের সাথে সাথে এটা সমান হয়ে যেত।
আমরা
random()
ফাংশন থেকে যে সংখ্যাগুলো পাই তা আসলে কিন্তু এলোমেলো (random) নয়; এজন্য তাদের “সুডো-র্যানডম” বলা হয়। তারা দৈব (random) সংখ্যা সিমুলেশন করে এমন গাণিতিক ফাংশনের ফলাফল মাত্র। কিছু সময় পর এই ফাংশনটি একটি প্যাটার্ন মেনে চলবে, কিন্তু এই সময়টি এতই বড় যে, এটা এলোমেলোভাবে যে কোন সংখ্যাকে সঠিকভাবে বাছাই করার মতই!পরবর্তী অংশে, আমরা বিভিন্ন উপায়ে এমন walker তৈরি করা শিখব যার নির্দিষ্ট দিকে চলার "প্রবণতা" আছে। এটা করার আগে, একটি চ্যালেঞ্জ রয়েছে!
এই "প্রাকৃতিক সিমুলেশন" কোর্সটি নেওয়া হয়েছে Daniel Shiffman (ড্যানিয়েল শিফম্যান) এর লেখা "The Nature of Code" (কোডের প্রকৃতি) থেকে এবং এটি ক্রিয়েটিভ কমন্সের এট্রিবিউশন-নন কমার্শিয়াল 3.0 আনপোরটেড লাইসেন্সের অধিনস্ত।
আলোচনায় অংশ নিতে চাও?
কোন আলাপচারিতা নেই।