تبلیغات

آموزش ساخت بازی سنگ کاغذ قیچی ساده در پایتون

آموزش ساخت بازی سنگ کاغذ قیچی ساده در پایتون

سنگ-کاغذ-قیچی، یکی از نوستالژی‌ترین بازی‌هاییست که تقریبا همه‌ی ما در دوران بچگی آن را تجربه کرده و حتی گاهی برای موارد مختلف در زندگیمان، آن را انجام می‌دهیم. مثلا دو دوست که کاری را به یکدیگر محول می‌کنند؛ اما در نهایت با یک بازی ساده، هرکس که ببازد، آن کار را انجام می‌دهد. 😀 (بسوزه پدر تجربه)

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

فرضیه

فرض ما بر این است که با اجرای بازی، کاربر بتواند انتخاب خود را نوشته و پس از زدن Enter، کامپیوتر نیز انتخاب خود را انجام داده و در نتیجه، برنده مشخص شود. اما توجه داشته باشید که ممکن است انتخاب کاربر صحیح نباشد؛ چراکه ورودی به‌‍شکل متن بوده و ما بایستی آن را  Validate یا ارزیابی کنیم. همچنین قصد داریم تا پس از اتمام یک دور از بازی، کاربر بتواند بطور مجدد بازی را انجام داده و برنامه بسته نشود. طبیعتا برای رسیدن به این هدف، بایستی از یک حلقه‌ی بی‌نهایت استفاده کرد.

حالا بیایید شروع کنیم.

منطق کلی بازی

کد زیر را در نظر بگیرید تا در ادامه، توضیحات لازم داده شود: (بخش‌های مختلف توسط کامنت، جهت توضیح شماره‌گذاری شده‌اند)

  1. ابتدا پیام‌های خوش‌آمدگویی و راهنما نمایش داده شده است.
  2. یک حلقه‌ی بی‌نهایت نوشته شده است.
  3. توسط  تابع input، یک پیام نمایش داده شده و از کاربر درخواست ورودی شده است. این ورودی بایستی انتخاب کاربر باشد؛ که آن را در متغیر player قرار می‌دهیم.
  4. توسط تابع optimizeChoice که بعدا آن را می‌نویسیم، ورودی کاربر بهینه شده است! یعنی چه؟! مثلا فرض کنید کاربر، انتخابش را با حروف بزرگ وارد کند؛ یا آنکه بجای rock، حرف r را وارد کند؛ لذا داخل تابع optimizeChoice، این موارد را تشخیص داده و به انتخاب متنظار با آن تبدیل می‌کنیم. بنابراین پس از بهینه‌کردن، خروجی را در همان متغیر player قرار می‌دهیم.
  5. اگر ورودی کاربر، exit باشد، از برنامه خارج خواهد شد. بنابراین حلقه شکسته می‌شود.
  6. ورودی کاربر باید اعتبارسنجی شود؛ یعنی اگر انتخاب غیرمجازی داشته باشد، از او مجددا انتخاب دیگری تقاضا شود. برای انجام این کار نیز از تابع validateInput که بعدا آن را خواهیم نوشت، استفاده شده است. در بدنه‌ی این شرط، از continue برای تکرار مجدد while استفاده شده است. همچنین توجه داشته باشید که می‌توانستیم طی یک روش دیگری، به کمک تابع optimizeChoice نیز معتبر بودن دستور را تشخیص دهیم؛ ما این کار را به‌صورت جدا انجام دادیم تا کد تمیزتری داشته باشیم.
  7. تایع generateComputerChoince نیز که بعدا آن را می‌نویسیم، یک انتخاب جدید برای کامپیوتر (که بازیکن مقابل است) برمی‌گرداند. این انتخاب به‌طور تصادفی خواهد بود.
  8. تایع getWinner نیز که آن را هم بعدا خواهیم نوشت، با دریافت انتخاب بازیکن و کامپیوتر، نتیجه برنده شدن را تشخیص می‌دهد. نتیجه می‌تواند یکی از موارد این موارد باشد: تساوی، بازیکن، کامپیوتر
  9. نتیجه‌ی بازی بررسی شده و پیام متناظر با آن نیز چاپ شده است. همچنین ثابت‌هایی مثل WINNER_PLAYER را هم بعدا تعریف خواهیم کرد که به نتایج مختلفی اشاره دارند.
  10. کاربر یا همان بازیکن، توسط یک پیامی که چاپ شده، به انجام مجدد بازی سنگ-کاغذ-قیچی فراخوانی شده است.
  11. در نهایت نیز در صورت خروج از حلقه، از کاربر خداحافظی می‌شود.

تبریک! منطق اصلی بازی نوشته شد و حالا نوبت به پیاده‌سازی توابعیست که در کد بالا استفاده شدند؛ ولی هنوز وجود خارجی ندارند!

ثابت‌ها

ثابت‌های زیر را در نظر بگیرید:

این موارد را در ابتدای فایل تعریف کنید. سه مورد اول، مقادیر انتخاب‌هایی که کاربر می‌تواند انجام دهد را دربرمی‌گیرند و CHOICEABLES نیز کل این انتخاب‌ها را در یک لیست قرار داده است؛ تا بعدا از آن در هنگام اعتبارسنجی استفاده شود.

چهار ثابت آخر نیز وضعیت‌های نتیجه‌ی برنده‌شدن را مشخص می‌کنند؛ که برای هرکدام از آنها عددی را در نظر گرفتیم تا بتوانیم مقایسه را انجام دهیم. طبیعتا می‌توانستیم به‌جای اینها، یک Enum تعریف کنیم که وضعیت‌های مختلفی را دربرداشته باشد. اما جهت ساده‌تر بودن هرچه تمام‌تر پروژه، به این شیوه عمل کردیم.

پیاده‌سازی optimizeChoice

تابعی که قرار است ورودی کاربر را بهینه کند. آن را به‌صورت زیر پیاده‌سازی کنید:

طبیعتا این بهتر است که کاربر در مقدار ورودی، بتواند انواع مختلف متن را وارد کرده و سیستم آنها را شناسایی کند. برای مثال، کاربر ممکن است در ورودی، عبارت rock را برای انتخاب سنگ بنویسید؛ اما همچنان نیز ممکن است عبارت stone را نیز بنویسید. اگر بازی بتواند این موارد را به‌طور هوشمند تشخیص دهد، طبیعتا قدرتمندتر خواهد بود. اما ما در اینجا قصد پیچیده‌کردن الگوریتم تشخیص ورودی را نداریم و فقط از آنجایی که کاربر ممکن است از حروف بزرگ نیز استفاده کند، ابتدا ورودی را به حروف کوچک تبدیل کرده و سپس برای هرکدام از انتخاب‌های ممکن، یک حرف اختصاری را نیز بررسی کرده‌ایم. لذا در کد بالا، اگر انتخاب کاربر برای مثال مقدار  r باشد، همان CHOICE_ROCK در نظر گرفته می‌شود و … در نهایت نیز این مقدار، به بیرون برگدانده می‌شود.

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

پیاده‌سازی validateInput

نوبت این است که انتخاب کاربر، اعتبارسنجی شود. بنابراین، تابع validateInput را به شکل زیر پیاده کنید:

در اینجا با دریافت انتخاب کاربر، بررسی می‌شود که آیا در لیست انتخاب‌های مجاز قرار دارد یا خیر. این کار به‌سادگی توسط یک حلقه و لیست CHOICEABLES (انتخاب‌های مجاز) که قبلا در بالا تعریف کردیم، قابل انجام است.

پیاده‌‍سازی generateComputerChoince

انتخاب کامپیوتر، قرار است بصورت تصادفی باشد. برای انجام این کار، از تابع randint موجود در ماژول random استفاده می‌شود. لذا در ابتدا، این تابع را از ماژول فراخوانی کنید:

سپس تابع خودمان را بصورت زیر پیاده کنید:

در ابتدا یک عدد تصادفی، بین 0 تا 2 انتخاب شده است. که در نتیجه، یا 0 یا 1 و یا 2 خواهد بود. ما نیز سه انتخاب داریم (سنگ-کاغذ-قیچی). سپس فرض شده است که اگر مقدار عدد تصادفی، برابر 0 بود، انتخاب کامپیوتر سنگ باشد و اگر 1 بود، انتخاب کامپیوتر کاغذ باشد و اگر هیچکدام از اینها نبود، انتخاب کامپیوتر نیز قیچی باشد.

پیاده‌سازی getWinner

این متد نیز با دریافت انتخا‌ب‌ها، برنده را تشخیص می‌دهد. آن را بصورت زیر پیاده کنید:

در ابتدا بررسی شده است که اگر انتخاب‌ها برابر بودند، نتیجه بازی مساوی باشد. بنابراین ثابت WINNER_TIE برگردانده شده است. سپس در شروط مختلفی، انتخاب‌های کاربر با انتخاب کامپیوتر بررسی شده است. برای مثال، یکی از شروط بررسی کرده است که اگر انتخاب کاربر برابر سنگ بود، در این صورت اگر انتخاب کامپیوتر برابر قیچی بود، پس کاربر برنده است؛ وگرنه، کامپیوتر برنده است! اما چرا کامپیوتر برنده است؟! چون اگر کاربر سنگ باشد و کامپیوتر قیچی نباشد، بنابراین کامپیوتر کاغذ است و کاغذ سنگ را می‌پوشاند 😀

حالا شاید بگویید پس چرا سنگ بودن کاغذ بررس نشده! خب واضح است که برابر بودن در ابتدای تابع بررسی شده است و نیازی نیست در هرکدام از آنها مجدد بررسی شود.

در نهایت نیز اگر هیچ‌کدام درست نبودند، که البته غیر ممکن است، یک مقدار WINNER_UNDEFINED به عنوان برنده‌ی نامشخص برگردانده شده است؛ که جنبه‌ی دکور بودن داشته و طبق الگوریتمی که نوشتیم، مطمئنیم که همچین چیزی رخ نمی‌دهد. 😀

کد نهایی

حالا کد نهایی شما بایستی به شکل زیر باشد.

تبلیغات
0
کانال تلگرام فول کده
تبلیغات

درباره نویسنده

هادی اکبرزاده

[ مدیر فول کده ]

علاقه‌مند به اشتراک گذاری اطلاعات در هر زمینه‌ای / برنامه‌نویس

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

نظرات ثبت شده بدون دیدگاه