استفاده از کلاس رندوم جاوا در حلقه ها در قالب پروژه ی برادر بدشانس


در این آموزش، قصد داریم تا نحوه به کار گیری کلاس Random در زبان برنامه نویسی جاوا را مورد بررسی قرار دهیم. در واقع در این آموزش علاوه بر نحوه تولید یک عدد تصادفی توسط کلاس Random به استفاده از مباحث if و همچنین Loop یی از جنس for هم خواهیم پرداخت. در این جلسه هم همچون برخی جلسات گذشته نیاز به یک سناریو داریم:

فرض کنیم که ما برادری داریم که همواره بر سر این مسئله که چه کسی امروز برود و نان بخرد با او مشاجره می کنیم و هر دفعه هم که شیر یا خط می اندازیم تا این که ببینیم قرعه به چه کسی می افتد، او بهانه می آورد که تو سکه را از قصد طوری انداختی که قرعه به نامت نیفتد! از آنجا که ما یک برنامه نویس هستیم، این پیشنهاد را به او می دهیم که می توانیم برنامه ای طراحی کنیم که به صورت کاملاً تصادفی شماره ای را به یکی از ما دو نفر اختصاص خواهد داد. حال هر کس که از نفر دیگری امتیاز کمتری کسب کرد می بایست این کار را انجام دهد. در نهایت این پیشنهاد مورد قبول طرفین واقع می شود و شروع به نوشتن برنامه می کنیم (البته از آنجا که نگارنده این آموزش تنها پسر خانواده است، این وظیفه خطیر در هر صورت به عهده خودش است!)

پروژه ای جدید در محیط اکلیپس ایجاد می کنیم تحت عنوان Unlucky Brother به معنی "برادر بد شانس" ایجاد کرده سپس کلاسی تحت عنوان RandomNumber به معنی "شماره ی تصادفی" ایجاد می کنیم. اولین مرحله برای ایجاد این برنامه دسترسی به عددی تصادفی است. برای همین منظور از کلاسی که در API جاوا توسط طراحان این زبان برنامه نویسی تحت عنوان Random گنجانده شده استفاده خواهیم کرد. در حقیقت نحوه به کار گیری این کلاس تا حدودی مشابه کلاس Scanner است که در آموزش های قبلی به تفصیل مورد بررسی قرار گرفته است. حال کد خود را به شکل زیر تکمیل می کنیم:

public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
    }
}

در کد فوق با نوشتن کلمه Random این کلاس را از API زبان برنامه نویسی جاوا فرا خواهیم خواند. حال بایستی مانند دیگر کلاس ها و یا متغیر ها نامی برای آن در نظر بگیریم که در این مثال نام randomNumber به معنی "شماره تصادفی" را در نظر می گیریم. پس از علامت مساوی کلید واژه ی new را نوشته و سپس مجدداً نام کلاس Random را می نویسیم. در واقع ما با این کار اقدام به ایجاد Instance یا نمونه ای از این کلاس در برنامه خود می کنیم (یا بهتر بگوییم یک شیء از روی این کلاس.) همان طور که مشاهده می شود دور دو واژه Random نقطه چین قرار گرفته است به این معنی که برای نرم افزار اکلیپس ناشناخته هستند. برای رفع این مشکل همانند روشی که در آموزش های پیشین استفاده شد، نشانگر موس خود را روی یکی از آن ها قرار داده و پس از آنک ه اکلیپس پنجره ای زرد رنگ باز کرد که حاوی تعدادی پیشنهاد برای رفع این مشکل بود گزینه ی (Import 'Random' (java.util را انتخاب می کنیم:

به محض این که روی این گزینه کلیک کنیم خطی از کد به شکل ;import java.util.Random به اول سورس کد اضافه خواهد شد.

به خاطر داشته باشید
لازم به ذکر است دو روش دیگر نیز برای وارد کردن یک کلاس به برنامه وجود دارد. روش اول به این شکل است که خط اول از کدی که در بالا مشاهده می شود را به صورت دستی وارد کنیم که این کار تا حدودی وقت گیر خواهد بود. راه دوم این است که از کلید های میانبر استفاده کنیم که برای این منظور می توان از ترکیب کلید های Ctrl + Shift + O استفاده کرد. البته به خاطر داشته باشیم که احتمال دارد این کلید های میانبر در نسخه های متفاوت اکلیپس متفاوت باشند.

در ادامه، کد خود را به شکل زیر تکمیل می کنیم:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        randomNumber.nextInt();
    }
}

حال همان طور که در کد فوق مشاهده می شود، در خط بعدی نیاز است تا نوع داده ورودی این کلاس تصادفی را تعریف کنیم که در اینجا از متدی به اسم ()nextInt استفاده خواهیم کردکه ایجاد کننده یک عدد صحیح است. برای آن که بتوانیم روی برنامه خود تسلط بیشتری داشته باشیم می بایست یک Range یا طیفی از اعداد را برای برنامه خود مشخص کنیم که از میان آن ها یک عدد به صورت تصادفی انتخاب گردد. برای همین منظور، داخل پرانتز مقابل ()nextInt عدد 101 را وارد می کنیم به این معنی که کامپیوتر یک عدد تصادفی از صفر تا صد را انتخاب خواهد کرد.

نکته
در حقیقت علت این که عدد 101 را به عنوان Range تعریف کردیم این است که در این متد آخرین عدد که خود عدد 101 است جزو طیف محسوب نمی شود از این رو طیف ما در برگیرنده اعدادی از صفر تا صد خواهد بود.

در ادامه نیاز است تا دو متغیر از جنس int به نام هر دو برادر تعریف کنیم. در این مثال نام های hesamNumber و hadiNumber را در نظر می گیریم. تا اینجای کار کد ما به شکل زیر خواهد بود:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        randomNumber.nextInt(101);
        int hesamNumber;
        int hadiNumber;
    }
}

در ادامه می بایست تا یک Loop از جنس for وارد برنامه خود کنیم. در واقع وظیفه ای که این Loop بر عهده دارد این است که اعداد تصادفی که ما وارد آن می کنیم را بارها و بارها تکرار کند تا در نهایت عدد مرتبط به یکی از برادران به نقطه پایانی برسد و بازنده معلوم گردد. در این مرحله کد ما به شکل زیر خواهد بود:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        randomNumber.nextInt(101);
        int hesamNumber;
        int hadiNumber;
        for(){
        }
    }
}

پیش از این یاد گرفتیم که داخل پرانتز مقابل for می بایست سه پارامتر قرار گیرد، به این شکل که پارامتر اول مقدار اولیه متغیرها است، پارامتر دوم نقطه پایانی متغیرها است و پارامتر سوم تعیین کننده مقداری است که در هر بار Loop شدن می بایست به متغیر ها اضافه گردد. در ادامه، کد خود را به شکل زیر تکمیل می کنیم:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        randomNumber.nextInt(101);
        int hesamNumber;
        int hadiNumber;
        for (hesamNumber = randomNumber.nextInt(101), hadiNumber = randomNumber.nextInt(101)) {
        }
    }
}

به طور خلاصه، عبارت (hesamNumber = randomNumber.nextInt(101 به منزله نشان دادن نقطه آغازین متغیر است و از آنجا که می خواهیم این برنامه کلاً بر پایه شانس یا بهتر بگوییم بد شانسی باشد، تعیین مقدار اولیه متغیرهای مرتبط به هر دو برادر را به عهده کلاس Random می گذاریم. از همین رو Instance یا نمونه ای از کلاس Random را که قبلاً ایجاد کرده بودیم را به متغیر برادر اول نسبت می دهیم. از آنجا که در این برنامه ما دو متغیر داریم، پس نیاز است تا نقطه آغازین هر دو متغیر را در داخل for تعیین کنیم از این رو یک کاما پس از اولین متغیر قرار داده سپس نام متغیر دوم و همچنین مقدار اولیه آن را نیز مشخص می کنیم و در نهایت یک علامت ; قرار می دهیم.

در این مرحله از کار، نوبت به نوشتن کدی مربوط به نقطه پایانی Loop می رسد که در اینجا ما عدد 1000 را در نظر می گیریم. برای این منظور کد خود را به شکل زیر تکمیل می کنیم:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        randomNumber.nextInt(101);
        int hesamNumber;
        int hadiNumber;
        for (hesamNumber = randomNumber.nextInt(101), hadiNumber = randomNumber.nextInt(101); hesamNumber <= 1000 || hadiNumber <= 1000;) {
        }
    }
}

به طور خلاصه دستور ;hesamNumber <= 1000 || hadiNumber <= 1000 به این معنی است که اگر مقدار مرتبط با متغیر ما تحت عنوان hesamNumber کوچکتر یا مساوی با 1000 بود و یا مقدار مرتبط با متغیر ما تحت عنوان hadiNumber کوچکتر یا مساوی با 1000 بود، برنامه از Loop خارج شود (در واقع علامت || به معنی "یا" است.) این قسمت از کد نیز همچون قسمت قبل با یک علامت ; به پایان می رسد. حال می بایست پارامتر سوم را تعریف کنیم که عبارت است از تعیین مقدار افزایشی هر متغیر در هر بار Loop شدن برنامه و برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        randomNumber.nextInt(101);
        int hesamNumber;
        int hadiNumber;
        for (hesamNumber = randomNumber.nextInt(101), hadiNumber = randomNumber.nextInt(101); hesamNumber <= 1000 || hadiNumber <= 1000; hesamNumber += randomNumber.nextInt(11), hadiNumber += randomNumber.nextInt(11)) {
        }
    }
}

به طور خلاصه، دستور (hesamNumber += randomNumber.nextInt(11 به این معنی است که در هر بار Loop شدن مقدار متغیر ما تحت عنوان hesamNumber به مقدار عددی کاملاً تصادفی از صفر تا 10 افزایش یابد. سپس یک علامت کاما قرار داده و مقداری که می بایست متغیر دوم ما هم در هر بار Loop شدن افزایش یابد را تعیین می کنیم که همانند متغیر پیشین می باشد (همان طور که پیش از این آموزش دادیم، خود عدد 11 جزو اعداد محسوب نخواهد شد.) تا اینجای کار کلیه شروطی که برنامه در حین اجرا می بایست از آن تبعیت کند را تعریف کرده ایم و اکنون می بایست به کامپیوتر دستور دهیم تا خروجی برنامه را روی صفحه مانیتور نمایش دهد. برای همین منظور کد فوق را به شکل زیر تکمیل می کنیم:

public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        randomNumber.nextInt(101);
        int hesamNumber;
        int hadiNumber;
        for (hesamNumber = randomNumber.nextInt(101), hadiNumber = randomNumber.nextInt(101); hesamNumber <= 1000 || hadiNumber <= 1000; hesamNumber += randomNumber.nextInt(11), hadiNumber += randomNumber.nextInt(11)) {
            System.out.println("Hesam` number is " + hesamNumber + " and "
            + "Hadi`s number is " + hadiNumber);
        }
    }
} 

در حقیقت هر آنچه در دستور ;()System.out.println قرار گیرد، در پنجره کنسول به نمایش در خواهد آمد. حال ما می خواهیم نشان دهیم که شماره حسام ... است و شماره هادی ... می باشد که برای این منظور، اولین عبارتی که می نویسیم Hesam`s number is است یعنی "شماره حسام هست ..." سپس یک علامت + قرار داده و نام متغیر مرتبط با حسام را می نویسیم. تا اینجای کار عبارت مربوط به حسام تکمیل می شود. در ادامه، می خواهیم عبارت مربوط به هادی را نیز اضافه کنیم که برای این کار یک علامت + قرار داده و عبارت " and " را می نویسیم. اگر توجه کرده باشید هر دو طرف واژه and فضای خالی قرار داده ایم و این برای آن است که خروجی برنامه خوانا تر باشد. سپس یک علامت + دیگر قرار داده و عبارت Hadi`s number is به معنی "شماره هادی هست ..." به علاوه نام متغیر مرتبط با هادی را می نویسیم. اکنون زمان اجرای برنامه رسیده است که با Run کردن برنامه خروجی زیر را مشاهده خواهیم کرد:

اگر به فلش قرمز رنگ داخل تصویر توجه کنیم، خواهیم فهمید که لیست بلندی از اعداد تصادفی توسط نرم افزار برای هر یک از دو برادر ایجاد شده است. نکته ای که در این برنامه از اهمیت بسزایی برخوردار است این است که به هر حال یکی از این دو برادر زودتر از دیگری به عدد 1000 خواهد رسید که همین مسئله فرد برنده و بازنده را مشخص خواهد کرد. در یک Run از برنامه که در تصویر فوق مشاهده می شود، هادی امتیاز کمتری نسبت به برادر خود کسب کرده است پس وی باید خرید نان را بر عهده گیرد!

در حقیقت برنامه ما در اینجا تکمیل شده است اما برای آن که خود برنامه نفر برنده را مشخص کند می توانیم از دستور if نیز کمک بگیریم. برای همین منظور کد فوق را به شکل زیر تکمیل می کنیم:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        randomNumber.nextInt(101);
        int hesamNumber;
        int hadiNumber;
        for (hesamNumber = randomNumber.nextInt(101), hadiNumber = randomNumber.nextInt(101); hesamNumber <= 1000 || hadiNumber <= 1000; hesamNumber += randomNumber.nextInt(11), hadiNumber += randomNumber.nextInt(11)) {
            System.out.println("Hesam` number is " + hesamNumber + " and "
            + "Hadi`s number is " + hadiNumber);
        }
        if (hesamNumber > hadiNumber) {
            System.out.println("Hesam won the game and Hadi has to buy it.");
            } else if (hesamNumber < hadiNumber) {
            System.out.println("Hadi won the game and Hesam has to buy it.");
            } else {
            System.out.println("Now they have to think about a third solution!");
        }
    }
}

در واقع خارج از Block مربوط به Loop مرتبط با for عبارات شرطی if را خواهیم نوشت (علت آن که این عبارات شرطی را خارج از Block مرتبط با for می نویسیم این است که می خواهیم از تکرار عبارات شرطی در هر بار Loop شدن خودداری کرده و صرفاً زمانی که برنامه از Loop خارج شد آنها را اجرا کنیم.)

در ادامه، به بررسی تک تک عبارات شرطی می پردازیم. در عبارت اول به برنامه خود دستور داده ایم که اگر مقدار متغیر مرتبط با حسام بیشتر از مقدار متغیر هادی بود جمله Hesam won the game and Hadi has to buy it. را به معنی "حسام بازی را برد و هادی باید به خرید برود." به نمایش در آید. حال اگر این تنها شرط برنامه ما بود می بایست یک دستور else برای زمانی که جواب به شرط فوق false بود تعریف کنیم اما از آنجا که ما یک شرط دیگر هم داریم از عبارت else if استفاده می کنیم و در آن تعیین می کنیم که اگر مقدار متغیر هادی بیش از مقدار متغیر حسام بود پس جمله Hadi won the game and Hesam has to but it. به معنی "هادی بازی را برد و حسام باید به خرید برود." می بایست در پنجره ی کنسول به نمایش در آید.

یک فرض محال هم ممکن است اتفاق افتد و آن این که مقدار متغیر هر دو برادر معادل با یک عدد شود و نفر برنده و بازنده بازی مشخص نشود که در این صورت در دستور else از برنامه خواسته ایم که چنانچه جواب به شرط if معادل با false بود و همچنین اگر جواب به شرط else if معادل با false بود، دستور !Now they have to think about a third solution به معنی" حالا هر دو برادر می بایست به دنبال یک راه کار سومی بگردند!" اجرا خواهد شد. مجدد برنامه را اجرا می کنیم:

در خروجی برنامه که پس از تکمیل نهایی آن به دست آمد می بینیم که امتیاز هادی بیشتر از برادرش است و برنامه هم برنده را اعلام می کند.

به عنوان سخن پایانی شاید بتوان گفت که می توانستیم این برنامه را به روشی حتی به مراتب کوتاه تر از این نیز بنویسیم و یا حتی راه کارهای منطقی تر به کار بریم، اما از آنجا که قصد ما در این آموزش تلفیق مطالب جدید با مطالب پیشین بود چنین راه کاری اتخاذ گردید.

دانلود فایل‌های تمرین
لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
پویا نظری
پویا نظریتوسعه‌دهنده‌ موبایل اپ، دانشجوی نرم‌افزار
سناریو جالبی بود، نوع آموزشتون خیلی جالب بود
amirimohammad6
amirimohammad6
دستتون درد نکنه واقعا سنگ تموم گذاشتین
خیلی استفاده کردم
نمیدونم چطور ازتون تشکر کنم
ایول دارین
Oganesson
Oganesson
داشتم این آموزش رو میخوندم که یهو قالب سایت از حالت قبلی در اومد و تم بنفش اعمال شد :)
به هرحال ممنون از آموزش های درجه یک تون.
موفق باشید.
Dan
Dan
سلام خسته نباشید
این آموزشتون از همه دوره های تصویری هم بهتر و کامل تره
من تا اینجای آموزش رو خوندم و انجام دادم و مشکلی نداشتم این برنامه رو هم بدون مشکل انجام دادم و بعد از انجامش به ذهنم رسید اعداد اول رو خودم به برنامه بدم (با کلاس اسکنر )این کار رو کردم و تا آخر بلاک for مشکلی ندارم ولی توی خط اول شرط به ارور
dannumber cannot be resolved to a variable
و
rezanumber cannot be resolved to a variable
میخورم برای چی هست و چیکار کنم درست شه
کاربر میهمان
کاربر میهمان
ببخشید. if نه ()system out prinln. تو قسمت دوم
کاربر میهمان
کاربر میهمان
البته برادری که برنامه رو مینویسه میتونه برای تقلب تو قسمت if تو قسمت دوم که پایانه شرطه اسمه خودشو پاک کنه. در این صورت هیچ‌وقت روی ۱۰۰۰ واینمیسه. فقط شماره هادی زیر هزار وایمیسه
کاربر میهمان
کاربر میهمان
البته دستور
;()randomnumber.nextint
رو‌ که اول نوشتید میشه ننوشت و تو همون حلقه if که متغیر و یه شماره رندم تعریف کردید ۱۰۱ همون بسه باشه. اینجا کدی که تو‌خط دوم نوشتید فکر کنم اضافه هست
Mr.Fox
Mr.Fox
(البته از آنجا که نگارنده این آموزش تنها پسر خانواده است، این وظیفه خطیر در هر صورت به عهده خودش است!)
عاشق این طنزات وسط آموزشم که یه لبخند میاره رو لب و آموزش دلچسب تر میشه استاد
کاربر میهمان
کاربر میهمان
با تشکر از شما... سوالی برای من پیش آمده ، اینکه در برنامه ام برای ایجاد نمودار piechart از کتابخانه androplot استفاده کردم که برای دستورات مورد استفاده رسم نمودار، حدود 12 import به برنامه ام وارد کردم ، حال اینکه همان اکتیویتی هم خودش نزدیک 15 import داشت. می دونم که این اصولی نیست و بهتره که هر کلاس فقط یک کار انجام بده، اما آیا ایمپورت های زیاد باعتث کندی اجرای اون اکتیویتی میشه؟؟
اگر برای رسم نمودار دایره ای و میله ای کتابخانه خوبی می شناسید ممنون میشم راهنماییم کنید.
با تشکر از لطف همیشگی شما...
mh.ka
mh.ka
;(randomNumber.nextInt(101 در خط پنجم کاربردش چیه؟ اگر حذفش کنیم مشکلی برای برنامه پیش میاد؟
shayansiamakan
shayansiamakan
آره ظاهرا کار خاصی نمیکنه

در پاسخ به

iman
iman
مگر شرط لوپ این نیست که یکی از دو برادر عدد کوچکتر یا مساوی هزار را دریافت کنند ؟؟!!!
پس چرا در محیط کنسول عددهای بزرگتر از هزار هم دیده میشود ؟
MegaMind
MegaMind
سلام و میخواستم بپرسم که میشه به جای چاپ عبارت " دوبرادر باید به دنبال راهکار سومی باشند!" به برنامه دستور بدیم که هر وقت نه عدد حسام بزرگتر از هادی و نه عدد هادی بزرگتر از عدد حسام بود , لوپ رو از اول اجرا کنه تا یکی از دو حالت اتفاق بیفته؟!
Mahmood
Mahmood
چرا عدد شرط باید کوچکتر یا مساوی ۱۰۰۰ باشه
مگه آرایه ما عددی بین ۰ تا ۱۰۰ رو نشون نمیده؟
کاربر میهمان
کاربر میهمان
سلام و خسته نباشید.
لطفا فایل تمرین همه ی آموزش ها رو دوباره قرار بدین. هیچکدوم رو نمیشه دانلود کرد. آنتی ویروس اجازه شو نمی ده!
خیلی ممنون...
کاربر میهمان
کاربر میهمان
سلام
علامت یا با گرفتن دکمه ی شیفت و پ نوشته میشه
hacker
hacker
این علامت یا رو چجوری باید بنویسم تورو خدا جواب بدین
Aslan
Aslan
Shift +

در پاسخ به

CIna Deuxshiri
CIna Deuxshiri
سلام
چه علامتی؟

در پاسخ به

کاربر میهمان
کاربر میهمان
سلام مگر انتهای برنامه این نیست که یکی از برادر ها امتیازش به 1000 برسد ؟(به خاطر علامت "یا")پس چرا برنامه تا جایی اجرا میشود که امتیاز هر دو برادر به 1000 برسد ؟شاید من درست متوجه تفاوت مفهوم || و && نشده ام.
m.ali
m.ali
سلام. تا وقتی که شرط مربوطه True باشه، Loop ادامه پیدا می کنه. در شرط این Loop ذکر شده که تا وقتی عدد مربوط به حسام "یا" عدد مربوط به هادی، کوچکتر مساوی هزار است، Loop ادامه پیدا کنه. در نتیجه تا وقتی "هر دو عدد" بزرگتر از هزار نشوند، جواب شرط False نشده و Loop ادامه پیدا خواهد کرد.

در پاسخ به

Aslan
Aslan
چون || گذاشتن منظور این هست که هروقت یکیشون ۱۰۰۰ رو رد کرد. || به معنی یا هست و && به معنی و.مثلا اینجا گفته که این برادر از هزار بیشتر بشه یا اون برادر از هزار بیشتر بشه.

در پاسخ به

m.ali
m.ali
اتفاقا به همون دلیل استفاده از علامت "یا"، منظور این می شه که تا وقتی حتی یکی از دو عدد، هنوز هزار رو رد نکرده جواب شرط کماکان True بمونه و Loop ادامه داشته باشه. هر دو عدد باید 1000 رو رد کنن تا متوقف شه.

در پاسخ به

کاربر میهمان
کاربر میهمان
سلام.....چرا مقابل nextInt عدد 101 را میذاریم اگه عدد نگذاریم عیب داره
هاشم همراز
هاشم همراز
سلام
بله اگه عدد نذاریم معلوم نمیشه که عدد تصادفی باید از بین کدوم اعداد انتخاب شود و این احتمال وجود دارد که اصلا عدد اول انتخاب شده بزرگتر از 1000 باشد و حلقه به صورت نامتناهی ادامه دار باشد

در پاسخ به