بعضی وقتا یه بازی به نظر ساده، میتونه شما رو به شکل خیلی جدی به چالش بکشه. چند روز پیش یه مطلب خوندم راجع به یه مصاحبه که یه چالش بامزه داشت. بازی Light Memory. بازی ای که توی اون چندتا چراغ وجود داره و شما باید ترتیب روشن شدن چراغ ها یادتون بمونه و بعد همون ترتیب رو وارد کنید که برید مرحله بعد و هر مرحله بازی سخت تر میشه. حالا این سخت تر شدن میتونه روشن شدن چراغ های بیشتر، سرعت روشن شدن چراغ ها یا جابجا شدن اون ها باشه.

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

همه چیز این بازی پیاده سازی نشده. مثلا مکانیزم disable کردن دکمه ها در زمانی که بازی داره اجرا میشه، یا game over شدن، انیمیشن های بهتر، صدا دادن لامپ ها و کلی چیز دیگه...
البته منم کد های کامل این پروژه رو اینجا نشون نمیدم، صرفا میخوایم باهم یه راه حل رو مرور کنیم، پیاده سازی اصل قضیه رو به خودتون میسپرم و میتونید به عنوان یه چالش بامزه آخر هفته ای روش وقت بذارید.
به طور کلی اسکلت اصلی بازی رو من اینطور پیاده سازی کردم:
سه تا کامپوننت اصلی رو من به این شکل پیاده سازی کردم:
برای استایل ها هم که واضحه از tailwind استفاده شده و پروژه هم کلا با vite استارت شده و TS هم هست. اینا دیگه بدیهیات هست دیگه ...
توی Lights یه حلقه است که ۵ تا چراغ رو رندر میکنه. یه Click handler هم داره برای وقتی که کاربر روی لامپ ها کلیک میکنه. اون 5 تا چراغ هم یه لیست ثابت هستن که ۵ تا رنگ دارن و یه id که بیانگر اون رنگ خاصه. این بهمون بعدا کمک میکنه که هم ترتیب روشن شدنشون رو بدونیم هم کلیک های کاربر رو بگیریم.
از روی کد میشه سه تا کامپوننت اصلی پروژه رو دید، برای سادگی من کل State ها رو توی useGame نگهداری میکنم و توی App ازشون استفاده کردم.
اولین راند بازی فقط یه چراغ روشن میشه، بعد دو تا بعد سه تا و همینطوری الی آخر... برای همین یه متغیر Level تعریف کردم که اول کار مقدارش 1 هست. هر مرحله که کاربر بازی رو درست انجام میده یه دونه بهش اضافه میشه.
بر اساس همین Level یه سری از اعداد رندوم بین 0 تا 4 ایجاد میشه که در واقع اشاره میکنه به یکی از چراغ ها. پس بنابراین زمانی که بازی استارت میشه یه آرایه رندوم به طول Level ایجاد میشه و بعد لامپ ها به اون ترتیب روشن میشن.
برای روشن شدن هر کدوم لامپ ها کافیه یه دونه کلاس CSS بهش اضافه و کم کنیم. بعد یه delay بذاریم و بریم سراغ رنگ بعدی. (استفاده از promise اینجا اتفاق میوفته)
بعد هم که کاربر روی لامپ ها کلیک میکنه، ترتیب کلیک ها رو نگه میداریم و مقایسه میکنیم و اگه درست بود یه دونه به Level اضافه میکنیم و یه دونه هم به Score. حالا این Score میتونه ۱۰ تایی اضافه بشه، میتونه یه دونه ای اضافه بشه، میتونه اصلا بر اساس level به صورت تساعدی زیاد بشه... این دیگه میشه business logic.
بعضی وقتا برای یاد گرفتن مفاهیم پایه ای میشه راه حل های خلاقانه تری هم داد. مثلا چرا ما همیشه برای یاد گرفتن Promise و Async/Await میخوایم یه request بزنیم و یه لیستی نشون بدیم؟ خیلی وقتا مسائل بامزه تری هستن که میتونیم ازشون برای یاد گرفتن مفاهیم پایه ای استفاده کنیم. کلا من خیلی طرفدار دیدن چیز ها از زاویه های جدید هستم.
شمام سعی کنید همین بازی یا یه بازی دیگه رو پیاده سازی کنید، مطمئنم بهتون خوش میگذره.
امیدوارم مطلب براتون جالب بوده باشه، دوست داشتید میتونید از طریق لینکدین باهام در ارتباط باشین.