উপরের টাইটেল দেখে যারা পোস্টটা দেখছেন তারা সকলে নিশ্চই প্রোগ্রামার বা প্রোগ্রামিং সম্পর্কে জানতে আগ্রহী। আশাকরি ঈদের দিনে আমার প্রচেষ্টা বিফল হয়নি। তারপরও সামান্য বলতেই হয়ঃ
যেসকল সংখ্যায় দশমিক নাই অথবা ভগ্নাংশ নাই সেগুলো integer এবং যেগুলোতে আছে সেগুলো float । যেমন ১২ হল integer এবং ১০.০১ হল float । integer কে সংক্ষেপে int লেখা হয়। যদি বাইনারী রিপ্রেজেন্টেশন দেখেন তাহলে দেখবেন যে int কে মেমোরীতে রাখা খুবই সহজ বা float অপেক্ষা সহজ। অপরদিকে দেখবেন যে float কে রাখার জন্য একগাদা কাজ করতে হচ্ছে। কিন্তু বাস্তবে আমাদের বেশিরভাগ float নিয়েই গণনা করতে হয় [গেমে তো লাইফ আর অস্ত্রের এ্যারে ছাড়া সবই float]। আর int সাধারনত আমরা মুখে মুখে বলি [আমার ধারনা না এটা গেম ডেভেলপাররা বলে] যেমন "একজন মানুষ একটা কলা একহাতে ধরে এক কামড় দিল"। আপনারা যারা এ্যাসিম্বলি প্রোগ্রাম করেছেন তারা নিশ্চই জানেন যে float নিয়ে হিসাব করতে কতটা ঝামেলাই না পোহাতে হয়। আমাকেও হয়েছে। তবে আমি পরেরদিকে ম্যাক্রো তৈরী করে নিয়েছিলাম যেজন্য সহজ হয়ে গিয়েছিল। তবে ম্যাক্রো তৈরী করার সময় আমাকেও ঝামেলা পোহাতে হয়েছে। আপনি নেটে খুজলে অন্যের তৈরী এরকম কিছু ম্যাক্রো লাইব্রেরীও পেয়ে যাবেন।
ধরুন Turbo C++ এর কথা। এটাতে int এর জন্য ২ বাইট মেমোরী এ্যালোকেশন করতে হয় অপরদিকে float এর জন্য ৪ বাইট। gcc তে সামান্য পার্থক্য আছে তবুও int এ সবসময়ই float এর চেয়ে কম মেমোরী লাগবে। যদি একটা ইন্সট্রাকশনে int কে হ্যান্ডেল করা যায় তবে float কে হ্যান্ডেল করতে লাগবে কমপক্ষে এর দ্বি-গুন। গেম বা গ্রাফিক্স প্রোগ্রামের একেবারে লো-লেভেলে সবসময়ই চেষ্টা করা হয় যেন float না ব্যবহার করতে হয়। অনেকেই হয়ত ভাববেন যে তাহলে কনভার্ট করে দিলেই হল। যেমন C++ এঃ
float a = 1.1;
int b = (int) a;
চিন্তা করাটা স্বাভাবিক। কিন্তু একবার চিন্তা করেন যে এই কনভার্ট করতে কি কি ইন্ট্রাকশন এক্সিকিউট করতে হবে। কেননা ১১.৯ মানে ১১ না ১২। আবার ১১.১ মানে ১২ না ১১। এবার চিন্তা করেন যে কনভার্টেই কতটা প্রোসেসিং চলে গেল। ধরলাম যে আপনার মনিটরে রেজুলেশন খুবই কম দিয়ে রেখেছেন ৬৪০x৪৮০ পিক্সেল। আর্থাৎ আপনার মনিটরে ৩০৭২০০ টি পিক্সেল আছে। প্রতিটি পিক্সেলের জন্য যদি আপনি একটা কন্ডিশনাল জাম্প করেন তাহলে আপনি কি মনিটরে তাৎক্ষনিক আউটপুট পাবেন? তাছাড়াও কনভার্ট করার আগ পর্যন্ত তো আপনি float এ হিসাব করছেনই। সেজন্য আরও কিছু এক্সট্রা ইন্সট্রাকশন আপনাকে এক্সিকিউট করতে হয়েছে। আপনি যদি কোন এনিমেশনের ফ্রেমরেট ৩০ চান তাহলে তো আপনাকে সেকেন্ডে ৬৪০x৪৮০x৩০ টা জাম্প করতে হবে। এজন্য আপনাকে সবসময় float ত্যাগ করতে হবে।
মনে করি draw(x, y) একটা ফাংশন যা কালো স্ক্রিনে x, y বিন্দুতে একটা পিক্সেলকে সাদা রং করে দিবে। এখন আমরা যদি x1, y1 থেকে x2, y2 বিন্দুতে দাগ টানতে চাই তাহলে অনেকটা এমন প্রোগ্রাম করতে হবেঃ
public void lineSimple(int x0, int y0, int x1, int y1, Color color)
{
int pix = color.getRGB();
int dx = x1 - x0;
int dy = y1 - y0;
raster.setPixel(pix, x0, y0);
if (dx != 0)
{
float m = (float) dy / (float) dx;
float b = y0 - m*x0;
dx = (x1 > x0) ? 1 : -1;
while (x0 != x1)
{
x0 += dx;
y0 = Math.round(m*x0 + b);
raster.setPixel(pix, x0, y0);
}
}
}
অথবা আপনি এদিক সেদিক সামান্য অথবা অনেক পরিবর্তন করতে পারেন। তবে যাই করেন এভাবে এ্যালগরিদম লিখলে বেশ সমস্যা হবে। যেমন একটু খেয়াল করেন যে প্রোগ্রামটাতে আপনাকে কতটা float এর অপারেশন করতে হয়েছে। তাছাড়াও আবার একটা লাইব্রেরী ফাংশন ব্যবহার করা হয়েছে। এভাবেই যদি প্রোগ্রাম লেখা হয় তাহলে বৃত্ত আঁকতে তো একটা sine আর একটা cosine একটি লুপের ভেতরে দিতে হবে। তাদের আবার নিজস্ব ফাংশন আছে যা সিরিজ থেকে বের করতে হয়। এভাবে আগাতে থাকলে আমরা সেকেন্ডে একটা ফ্রেম রেন্ডার করতে পারব কিনা তার যথেষ্ট পরিমানে সন্দেহ আছে। আসুন দেখি কিভাবে একই কাজ শুধু int ব্যবহার করে করা যায়। আমি একটা এ্যালগরিদম দিলাম। এটা ডেভেলপ করেছেন Bresenham নামের একজন। এই এ্যালগরিদম যদিও গ্রাফিক্স কার্ডের ভেতরে দেয়াই আছে এবং এটা খুবই লো-লেভেলের একটা কাজ তবুও আপনি কম্পিউটার গ্রাফিক্স নিয়ে কাজ [আমি প্রোগ্রামিং এর কথা বুঝিয়েছি (ডাইরেক্ট এক্স বা ওপেন জি এল প্রোগ্রামিং না)] করতে গেলে অথবা আপনি যদি কোন রেন্ডারিং ইন্জিন বানাতে যান তাহলে আপনাকে বেসিক হিসেবে এগুলো জানতে হবে।
function line(x0, x1, y0, y1)
boolean steep := abs(y1 - y0) > abs(x1 - x0)
if steep then
swap(x0, y0)
swap(x1, y1)
if x0 > x1 then
swap(x0, x1)
swap(y0, y1)
int deltax := x1 - x0
int deltay := abs(y1 - y0)
int error := deltax / 2
int ystep
int y := y0
if y0 < y1 then ystep := 1 else ystep := -1
for x from x0 to x1
if steep then plot(y,x) else plot(x,y)
error := error - deltay
if error < 0 then
y := y + ystep
error := error + deltax
এখানে তো দেখা গেল যে int দিয়ে কাজ চালানো গেল কোন Error ছাড়াই। কেননা মনিটর আসলে একগাদা পিক্সেলের সমষ্টি। বর্তমানে যে Physics ব্যবহার হয় তাতে এভাবেই int দিয়েই কাজ চালানোর চেষ্টা করা হয়। কখনও কখনও আবার সামান্য Error কে মেনে নিয়ে কাজ করা হয়। আবার দেখা গেল যে একটা সিরিজ এমনঃ
y = 1/x + 1/x.x + 1/x.x.x + ..... ..... .....
সেখানে আমরা বেশিরভাগই দেখা যায় হয় তিন-চার ধাপ নিই অথবা রেজাল্টাকে ২-৩ দশমিক পর্যন্ত শুদ্ধ করে নিই। আর যদি আমরা মোবাইলে গেম ডেভেলপ করতে যাই তাহলে তো কথাই নাই। এক ধাপ নিয়েই খালাশ করতে হয় এবং int ব্যবহার করতেই হবে। তারপরও দেখা যায় মোবাইলগুলোর 3D গেমের ফ্রেমরেট হয় ২ না হয় ৩। আবার আরও একটা কাজ করা হয় তা হল সামনের বস্তু এবং গেমের প্রধান ক্যারেক্টারগুলোকে দরদ দিয়ে বানানো হয় আর বাকিগুলো খুবই সাদামাটাভাবে বানানো হয়।
আপনারা বলতে পারবেন কি যে nVIDIA, Havok, Uphoria এরা সবাই তাদের Physics নিয়ে খুবই মাতামাতি করে কিন্তু তারপরেও কেন Fight Night Round 4 এরমত একটা সিমুলেশন গেমে কেন মাঝেমাঝেই দড়ির ভেতরে হাত ঢুকে যায়? আবার এমনও হয় যে দড়ির সামান্য উপরেই হাতটা বেধে গেছে? এর একমাত্রই কারন যেটুকো Error হয়েছে তা সবই হয়েছে সেই float থেকে int এর কনভার্সনের কারনে।
আমার মাঝেমাঝেই হাসি পায় যে এত স্পিডের যুগেও আমরা একটা পারফেক্ট ফিজিক্সের জন্য কোন প্লাটফর্ম বানাতে পারিনা [মাইক্রো সিস্টেম]। তবে একটা কথা বলতেই হবে যে PS3 তে ফিজিক্স অনেক শক্তিশালি কেননা এতে ৮টা প্রোসেসর আছে। সেদিক থেকে আমার ড্রিম প্লাটফর্ম হচ্ছে PS3 । আবার আশা আছে PC এর ক্ষেত্রেও কেননা আমার জানা মতে পিসির শক্তিও বৃদ্ধি হবে শীগ্রই। তবে PS3 এর কোন তুলনা না করাই ভাল। আশাকরি একদিন এমন প্লাটফর্মও হবে যেখানে ১০০% ফিজিক্সের সিমুলেশন করা যাবে [মাইক্রো সিস্টেম]। এবং যাতে int এবং float এর কোন পার্থক্য থাকবে না সবই হবে number, real number।
সর্বশেষ এডিট : ২৮ শে নভেম্বর, ২০০৯ বিকাল ৪:৫১