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

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

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

برای پیاده‌سازی سناریوی فوق پروژه‌ای جدید تحت عنوان UnluckyBrother در محیط اکلیپس ایجاد کرده سپس داخل آن کلاسی به نام RandomNumber می‌سازیم. حال به منظور تولید اعداد تصادفی نیاز است تا کلاسی از پیش تعریف‌شده در زبان برنامه‌نویسی جاوا تحت عنوان Random را در برنامۀ خود ایمپورت کنیم که نحوهٔ ایمپورت کردن این کلاس مشابه کلاس Scanner است که در آموزش‌ معرفی کلاس Scanner در زبان برنامه‌نویسی جاوا به تشریح آن پرداختیم. بنابراین ابتدا به صورت زیر آبجکتی از روی کلاس Random می‌سازیم:

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

در کد فوق، با به‌کارگیری کیورد new آبجکتی از روی کلاس Random ساخته و آن را به متغیری تحت عنوان randomNumber منتسب می‌کنیم و در ادامه مشاهده می‌کنیم که آی‌دی‌ای اکلیپس واژۀ Random را با علامت نقطه‌چین مشخص می‌کند که به معنی وجود مشکلی در شناسایی کلاسی به نام Random می‌باشد که برای رفع مشکل به وجود آمده، مشابه آموزش‌های پیشین، کلاس Random را در برنامۀ خود ایمپورت می‌نماییم که برای این منظور نشانگر ماوس خود را روی واژۀ Random قرار داده و از میان گزینه‌های پیشنهادی آیتم اول که مرتبط با ایمپورت کردن کلاس Random است را انتخاب می‌نماییم و به محض کلیک روی گزینۀ مذکور، دستوری به صورت ;import java.util.Random به سطر اول سورس‌کد اضافه می‌شود.

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

در ادامه، به منظور ذخیرۀ دو عدد صحیح تصادفی جهت تعیین امتیاز هر دو برادر، با استفاده از دیتا تایپ int دو متغیر تحت عناوین hesamNumber و hadiNumber تعریف کرده و کدی به صورت زیر خواهیم داشت:

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

در این مرحله نیاز به تعریف یک حلقۀ for داریم تا برنامۀ فوق یکسری عدد تصادفی را تا زمان برقرار بودن برخی شرایط مورد نظر تولید کرده و در نهایت هر یک از افراد برنده و بازنده را مشخص کند به طوری که ابتدا ساختار کلی حلقۀ for را به صورت زیر پیاده‌سازی می‌نماییم:

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

حال همان‌طور که در آموزش‌های پیشین آموختیم، سه پارامتر مرتبط با حلقۀ for را تعریف می‌کنیم به طوری که پارامتر اول مقدار اولیۀ متغیرها، پارامتر دوم نقطۀ پایانی و پارامتر سوم نیز مربوط به مقداری است که در هر بار تکرار حلقه به هر یک از متغیرها اضافه می‌گردد. بنابراین پارامتر اول مربوط مقدار اولیۀ متغیرها را برابر با مقادیر اعداد تصادفی مورد نظر تعریف می‌کنیم که برای این منظور هم نیاز به فراخوانی متد ()nextInt از کلاس Random داریم که آن را روی آبجکت ساخته‌شده از روی کلاس مذکور فراخوانی می‌کنیم و نحوۀ کار این متد بدین صورت است که عددی از نوع دادۀ int به عنوان آرگومان ورودی گرفته و یک عدد تصادفی از نوع دادۀ عدد صحیح در بازۀ 0 تا یکی مانده به عدد مربوط به آرگومان ورودی مذکور را در خروجی ریترن می‌کند.

در همین راستا، برای آنکه بتوانیم روی برنامۀ خود تسلط بیشتری داشته باشیم، متد ()nextInt را فراخوانی کرده و یک به اصطلاح Range یا «بازۀ» مشخص از اعداد صحیح مابین 0 تا 100 را مشخص می‌کنیم تا بدین ترتیب اعداد تصادفی مورد نظر در بازۀ مشخص‌شده تولید شوند. حال با توجه به آنچه در بالا بدان اشاره کردیم و به منظور تولید اعداد صحیح تصادفی در بازۀ 0 تا 100، آرگومان ورودی معادل عدد 101 را به متد ()nextInt پاس می‌دهیم. بنابراین کدی به صورت زیر خواهیم داشت:

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

در کد فوق، داخل پرانتزهای مقابل کیورد for مقدار اولیۀ متغیر hesamNumber را برابر با عدد صحیح تصادفی در بازۀ 0 تا 100 قرار داده سپس یک علامت , قرار داده و در ادامه با فراخوانی متد ()nextInt روی آبجکت ساخته‌شده از این کلاس عدد صحیح تصادفی دیگری در همین بازه را به متغیر hadiNumber منتسب کرده‌ایم. بنابراین نقطۀ آغازین هر دو متغیر را یک عدد صحیح تصادفی در بازۀ 0 تا 100 قرار داده‌ایم. در ادامه، نقطۀ پایانی برنامه را برابر با عدد صحیح 1000 تعریف می‌کنیم تا چنانچه مقدار عدد تصادفی تولیدشده و منتسب به هر دو متغیر بزرگ‌تر از عدد 1000 بود، اجرای برنامه متوقف شود که برای این منظور کد فوق را به صورت زیر تکمیل می‌کنیم:

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

با به‌کارگیری اپراتور || پارامتر دوم مربوط به نقطۀ پایانی برنامه را در حلقۀ for بدین صورت تعریف می‌کنیم تا اجرای حلقه تا زمانی ادامه یابد که مقدار منتسب به یکی از متغیرهای hesamNumber یا hadiNumber برابر با عدد 1000 یا کوچک‌تر از آن باشد؛ به عبارت بهتر، اجرای حلقه زمانی متوقف می‌شود که مقدار منتسب به هر دو متغیر hesamNumber و hadiNumber بزرگ‌تر از 1000 باشد. در ادامه، پارامتر سوم به منظور تعیین مقدار افزایشی هر یک از متغیرها در هر بار تکرار حلقه را تعریف می‌کنیم به طوری که داریم:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        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 و hadiNumber را برابر با عددی تصادفی در بازۀ 0 تا 10 قرار داده‌ایم بدین معنی که در هر بار اجرای حلقه، دو عدد صحیح تصادفی در بازۀ 0 تا 10 تولید شده و به هر یک از مقادیر قبلیِ منتسب به متغیرهای hesamNumber و hadiNumber افزوده می‌شود (توجه داشته باشیم که در پارامتر سوم نیز به منظور تعریف دو متغیر، آن‌ها را با علامت , از هم جدا کرده‌ایم.)

تا به این مرحله کلیۀ پارامترهای مرتبط با حلقۀ for را تعریف کرده‌ایم و در ادامه می‌باید دستوری بنویسیم تا اعداد تصادفی تولیدشده در حلقه را در کنسول چاپ کند که برای این منظور کد فوق را به شکل زیر تکمیل می‌کنیم:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        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`s number is " + hesamNumber + " and " + "Hadi`s number is " + hadiNumber);
        }
    }
} 

با اجرای برنامۀ فوق دو عدد صحیح تصادفی در بازۀ 0 تا 100 تولید شده و به هر یک از متغیرهای hesamNumber و hadiNumber اختصاص داده می‌شوند سپس شرط حلقه چک می‌شود تا اگر عدد تولیدشده برای یکی از متغیرها کوچک‌تر از 1000 یا برابر با آن بود، شرط true بوده و دستورات داخلی آن مبنی بر چاپ استرینگ‌های مربوطه به همراه عدد تصادفیِ متناظرشان اجرا شود. در ادامه، مقادیر اعداد تصادفی دیگری در بازۀ 0 تا 10 تولیدشده و به اعداد تصادفی منتسب به متغیرهای hesamNumber و hadiNumber افزوده می‌شوند سپس مجدداً شرط حلقه چک می‌شود که اگر عدد منتسب به متغیرها بزرگ‌تر از 1000 باشد، حلقه متوقف می‌شود و در غیر این صورت هر یک از استرینگ‌های «Hadi`s number is» و «Hadi`s number is» با استفاده از اپراتور + با عدد صحیحِ تصادفیِ تولیدشدۀ متناظرشان و همچنین استرینگ «and» کانکت شده و در کنسول چاپ می‌شوند.

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

Hesam`s number is 83 and Hadi`s number is 75
Hesam`s number is 93 and Hadi`s number is 80
Hesam`s number is 98 and Hadi`s number is 87
Hesam`s number is 102 and Hadi`s number is 89
Hesam`s number is 105 and Hadi`s number is 90
Hesam`s number is 108 and Hadi`s number is 92
Hesam`s number is 111 and Hadi`s number is 98
.
.
.

Hesam`s number is 866 and Hadi`s number is 908
Hesam`s number is 871 and Hadi`s number is 910
Hesam`s number is 871 and Hadi`s number is 917
Hesam`s number is 875 and Hadi`s number is 923
.
.
.
Hesam`s number is 988 and Hadi`s number is 1045
Hesam`s number is 988 and Hadi`s number is 1051
Hesam`s number is 990 and Hadi`s number is 1057
Hesam`s number is 991 and Hadi`s number is 1059
Hesam`s number is 997 and Hadi`s number is 1067
Hesam`s number is 1000 and Hadi`s number is 1070

همان‌طور که می‌بینیم، لیست بلندی از اعداد تصادفی توسط برنامۀ فوق و برای هر یک از دو برادر تولید شده است و با توجه به آنچه که در بالا بدان اشاره کردیم، می‌بینیم که متغیر مرتبط با هادی زودتر از حسام به عدد 1000 رسیده است که همین مسئله فرد برنده را مشخص می‌کند و از همین روی می‌توان گفت که حسام می‌باید خرید نان را بر عهده بگیرد اما برای آنکه با اجرای برنامۀ فوق نام فرد برنده را در کنسول چاپ کنیم، یک دستور if به صورت زیر به برنامۀ فوق اضافه می‌کنیم:

import java.util.Random;
public class RandomNumber {
    public static void main(String[] args) {
        Random randomNumber = new Random();
        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!");
        }
    }
}

در کد فوق، پس از چاپ مقادیر تصادفیِ تولیدشده برای هر متغیر، خارج از بلوک مرتبط با حلقۀ for دستور if چک می‌شود تا چنانچه آخرین مقدار منتسب به متغیر hesamNumber بزرگ‌تر از hadiNumber بود، استرینگی به صورت «.Hesam won the game and Hadi has to buy it» در کنسول چاپ شود و در غیر این صورت دستور else if چک می‌شود تا اگر آخرین مقدار منتسب به متغیر hesamNumber کوچک‌تر از hadiNumber باشد، استرینگ «.Hadi won the game and Hesam has to buy it» در کنسول چاپ شود مضاف بر اینکه یک فرض محال در نظر گرفته و گفته‌ایم در صورت false بودن هر یک از شرایط فوق‌الذکر و برابر بودن آخرین مقادیر منتسب به دو متغیر، دستوری مبنی بر چاپ استرینگ «!Now they have to think about a third solution» اجرا شده و استرینگ مذکور در کنسول چاپ شود. بنابراین با اجرای مجدد برنامه در خروجی خواهیم داشت:

Hesam`s number is 40 and Hadi`s number is 83
Hesam`s number is 48 and Hadi`s number is 87
Hesam`s number is 56 and Hadi`s number is 88
.
.
.
Hesam`s number is 984 and Hadi`s number is 1021
Hesam`s number is 992 and Hadi`s number is 1029
Hesam`s number is 993 and Hadi`s number is 1029
Hesam`s number is 993 and Hadi`s number is 1029
Hadi won the game and Hesam has to buy it.

بدیهی است که با اجرای مجدد برنامه، اعداد تصادفی جدیدی به صورت فوق تولید شده و همان‌طور که می‌بینیم این بار نیز هادی برنده می‌باشد.

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

online-support-icon