در این مقاله با نوشتن یک بازی حدس عدد با حلقه ها و کاربرد آنها در زبان آشنا میشویم.
#include <iostream>
#include <time.h>
using namespace std;
int main() {
// generate a random number from 1 to 100
srand(time(0));
int number = rand() % 100 + 1;
int guess = -1;
while (guess != number) {
cout << "Enter your guess ";
cin >> guess;
if (guess == number) {
cout << "You won" << endl;
} else if (guess > number) {
cout << "Too High" << endl;
} else { // is smaller
cout << "Too Low" << endl;
}
}
}
Enter your guess 50
Too High
Enter your guess 30
Too Low
Enter your guess 40
Too Low
Enter your guess 45
Too Low
Enter your guess 47
Too High
Enter your guess 46
You won
حلقهها برای تکرار فرایندها در اپلیکیشنهای ما کاربرد دارند. به عنوان مثال یک بازی که مداوم مراحل و یا چالشهای خاصی را به شما ارائه میکند برای تکرار این مراحل از حلقه استفاده میکند.
اولین کاری که برنامه ما باید انجام دهد انتخاب یک عدد به صورت تصادفی و random هست که میتوان با استفاده از rand()
این کار را انجام داد. خروجی rand
چیزی شبیه موارد زیر خواهد بود.
1551150669
630691387
2082729975
1893002664
1716791593
448654597
برای این برنامه هدف ما انتخاب اعداد در بازه ۰ تا ۱۰۰ خواهد بود تا حدی منطقی برای سختی بازی در نظر بگیریم.
برای رسیدن به اعداد در رنج ۱ تا ۱۰۰ یک راه ساده استفاده از باقیمانده است، زیرا میدانیم که حاصل تقسیم بر ۱۰۰ قطعا باقیماندهای در بازه ۰ تا ۹۹ دارد. حال اگر این عدد را به علاوه ۱ یک کنیم رنج آن به ۱ تا ۱۰۰ تغییر پیدا میکند. در زبان باقیمانده را با % نشان میدهیم:
// generate a random number from 1 to 100
int number = rand() % 100 + 1;
خط اول یک کامنت است؛ کامنت ها در اجرا برنامه شما تاثیری ندارند و کاربرد آنها معمولا نوشتن توضیحاتی برای خود شما و یا برنامهنویسان دیگر است٬ فرض کنید شما این برنامه را مینویسید و چند روز٬ ماه یا حتی سال دیگر به آن بر میگردید تا تغییری در آن اعمال کنید و یا برای آن update بدهید؛ داشتن توضیحاتی که به شما بگویند که برنامه چطور کار میکند کمک بزرگی خواهد بود.
این کامنتها در دو نوع تک خطی (single-line) مانند خط اول قطعه کد بالا و چندخطی (multi-line) مانند زیر موجودند:
/* This
is
multi-line
comment
*/
کل محتوای بین /*
و */
کامنت محسوب شده و در نظر گرفته نمیشود.
حالا با توجه به مفاهیمی که تا اینجا با آنها آشنا شدیم، مثل شرطها میتوان منطق کلی برنامه را به شکل زیر نوشت:
#include <iostream>
using namespace std;
int main() {
// generate a random number from 1 to 100
int number = rand() % 100 + 1;
int guess;
cin >> guess;
if (guess == number) {
cout << "You won" << endl;
} else if (guess > number) {
cout << "Too High" << endl;
} else { // is smaller
cout << "Too Low" << endl;
}
}
5
Too Low
اگر حدس کاربر (مقدار متغیر guess که با cin دریافت کردیم) برابر با عدد انتخابی ما بود به او میگوییم که برنده بازی شده٬ در غیر این صورت اگر حدس او بزرگتر عدد ما بود به پیامی مبنی بر بزرگ بودن عدد پرینت شده و اگر هیچ کدام از این حالت ها برقرار نبود (نه برابر و نه بزرگتر بود) یعنی حدس کاربر کوچکتر از عدد انتخابی برنامه بوده و پیام مربوط به کوچک بودن عدد را پرینت میکنیم.
اما مشکلی که با این کد به وجود میآید این است که پس وارد شدن اولین حدس کاربر برنامه متوقف شده و به اجرا ادامه نمیدهد. درواقع کاربر فقط یک شانس برای حدس عدد صحیح دارد!
|(⊙_⊙’)|
برای حل این مشکل باید برنامه ما بخش مربوط به پرسیدن حدس کاربر و بررسی مقدار ورودی را تکرار کند و تا وقتی که به جواب درست نرسیده است به پرسیدن ادامه دهد.
برای این کار میتوان از حلقهها استفاده کرد٬ کاربرد حلقه ها انجام یک کار برای چند بار و تکرار آن است. اولین حلقه در زبان که با آن آشنا میشویم حلقه while است که یک شرط را بررسی و تا زمانیکه آن شرط برقرار و صحیح است به اجرای کد نوشته شده درون حلقه ادامه میدهد.
در این برنامه هدف این است که تا وقتی که کاربر جواب درست را ننوشته به پرسیدن ادامه دهیم؛ پس شرط حلقه ما نابرابری حدس کاربر و عدد مدنظر است (تا وقتی کاربر همان عدد را وارد نکرده ادامه میدهیم)
#include <iostream>
using namespace std;
int main() {
// generate a random number from 1 to 100
int number = rand() % 100 + 1;
int guess = -1;
while (guess != number) {
cin >> guess;
if (guess == number) {
cout << "You won" << endl;
} else if (guess > number) {
cout << "Too High" << endl;
} else { // is smaller
cout << "Too Low" << endl;
}
}
}
20
Too High
10
Too High
5
Too Low
8
Too High
7
You won
10
Too High
6
Too Low
7
You won
9
Too High
6
Too Low
7
You won
همینطور که میبینید برنامه درست عمل میکند و تا وقتی که کاربر حدس درست را وارد نکرده به اجرا ادامه میدهد.
درواقع برنامه ابتدا عدد رندوم را انتخاب و آن را با حدس کاربر مقایسه میکند (مقدار اولیه متغیری که حدس کاربر را در آن نگه داری میکنیم را نیز منفی یک در نظر گرفتهایم تا در بررسی اول با عدد انتخاب شده که بین ۱ تا ۱۰۰ خواهد بود نابرابر باشد) چون حاصل این مقایسه بار اول حتما صحیح است برنامه کد داخل حلقه وایل را اجرا میکند؛ یعنی از کاربر حدسش را پرسیده و راهنماییاش میکند. در پایان این حلقه مجددا به بالا برمیگردد و شرط را بررسی میکند و اگر حدس کاربر با عدد انتخابی نبود مجددا کد داخل وایل را اجرا کرده و از کاربر حدسش را میپرسد. نهایتا وقتی که کاربر مقدار صحیح را وارد کند یعنی guess با number برابر شود شرط حلقه دیگر برقرار نخواهد بود و برنامه به اتمام میرسد.
مشکلی که باقی میماند این است که اگر دقت کنید برنامه ما هر دفعه یک عدد ثابت (در مثال من ۷) را انتخاب کرده که طبعا انتظاری نیست که ما از برنامهمان داریم. مسألهای که وجود دارد این است که کامپیوترها درواقع توانایی انتخاب یک عدد رندوم را ندارند و ساخته شدهاند تا کار هایی با ترتیب و شکل مشخص و تکراری انجام دهند و به خودی خود توان انجام کار شانسی ندارند به همین دلیل rand
درواقع با یک منطق مشخص هر بار یک عدد ظاهراً شانسی بر میگرداند، راه حل این مشکل این است که به rand
یک مقدار به عنوان seed بدهیم تا بر مبنای آن عدد به ساخت این الگو بپردازد؛ اصولا باید این seed یک پارامتر محیطی و شانسی باشد٬ معروف ترین این پارامتر ها زمان اجرای برنامه شما است؛ چون لحظه اجرای برنامه شما توسط کاربر یک پارامتر غیرقابل حدس است (الزاما این مورد در اپلیکیشن هایی که احتیاج مقادیر رندوم دارند مطمئن ترین راه حل نیست ولی برای این مثال قطعا کافیست).
srand(time(0));
میتوان با srand
مقدار این seed را تنظیم کرد و با این کد مقدار time
یا زمان لحظه اجرای برنامه را به عنوان seed تنظیم کرد.
یک پیام هم برای راهنمایی کاربر هم مینویسیم تا بگوییم که از او حدسش برای عدد را میخواهیم:
cout << "Enter your guess ";
و این کد نهایی ما خواهد بود:
#include <iostream>
#include <time.h>
using namespace std;
int main() {
// generate a random number from 1 to 100
srand(time(0));
int number = rand() % 100 + 1;
int guess = -1;
while (guess != number) {
cout << "Enter your guess ";
cin >> guess;
if (guess == number) {
cout << "You won" << endl;
} else if (guess > number) {
cout << "Too High" << endl;
} else { // is smaller
cout << "Too Low" << endl;
}
}
}
Enter your guess 50
Too High
Enter your guess 30
Too Low
Enter your guess 40
Too Low
Enter your guess 45
Too Low
Enter your guess 47
Too High
Enter your guess 46
You won
در این پروژه یک بازی حدس عدد با زبان نوشتیم و با کاربردهای حلقهها به ویژه حلقه While آشنا شدیم.
#include <iostream>
#include <time.h>
using namespace std;
int main() {
// generate a random number from 1 to 100
srand(time(0));
int number = rand() % 100 + 1;
int guess = -1;
while (guess != number) {
cout << "Enter your guess ";
cin >> guess;
if (guess == number) {
cout << "You won" << endl;
} else if (guess > number) {
cout << "Too High" << endl;
} else { // is smaller
cout << "Too Low" << endl;
}
}
}
Enter your guess 50
Too High
Enter your guess 30
Too Low
Enter your guess 40
Too Low
Enter your guess 45
Too Low
Enter your guess 47
Too High
Enter your guess 46
You won