یادداشت بازیساز: کدنویسی به کمک ماشین حالت در Quiz of Kings
خیلی از ما برنامهنویسها عادت کردهایم بدون برنامهریزی و طرح و نقشه شروع به کد زدن کنیم. درست است که این روش برای خیلی از موقعیتها جواب میدهد؛ اما جاهایی هم هست که اگر این ...
خیلی از ما برنامهنویسها عادت کردهایم بدون برنامهریزی و طرح و نقشه شروع به کد زدن کنیم. درست است که این روش برای خیلی از موقعیتها جواب میدهد؛ اما جاهایی هم هست که اگر این طوری عمل کنیم، واقعا نمیتوانیم برنامه را دیباگ کرده و در نتیجه دست و بالمان حسابی بسته میشود.
امروز میخواهم شما را با یک روش به شدت کاربردی آشنا کنم که در طراحی و حل مسئله، قبل از کد زدن کمک حالتان باشد و این چیزی نیست جز به کار گرفتن «ماشین حالت» در حل مسئله. برای اینکه مسئله ملموس و قابل درک باشد، مثالی از «کوییز آو کینگز» آوردم که آن را به کمک ماشین حالت بازنویسی کردیم.
در کوییز آو کینگز ما بخشی داریم به اسم ثبت پاسخ به سوالات در بازی ۲ نفره. این قسمت از پیچیدهترین بخشهای کوییز است که بالغ بر ۳ هزار خط کد برایش زده شده (بدون در نظر گرفتن تعداد خطوط ماژولهای به کار گرفته شده).
کد این بخش به قدری پیچیده است که با خواندن کد نمیتوان راجع به اتفاقاتی که میافتد نظر داد و حتی ویرایش کد برای کسی که از حالتها خبر ندارد، واقعا دشوار خواهد بود. ما برای بازنویسی چنین لاجیکی و همینطور برای راحتی شناخت بخشهای مختلف آن از یک ماشین حالت کمک گرفتیم. قبل از توضیح ماشین حالت، ابتدا توضیح میدهم که یک بازی در کوییز به چه شکل است و ثبت پاسخ در هر راند کوییزی از چه روشی انجام میشود:
- هر بازی از ۶ دست (راند) تشکیل شده.
- نفر اول (Challenger) بازی رو شروع، یک دستهبندی رو انتخاب میکند و جواب میدهد.
- نفر دوم (Acceptor) به دستی که حریفش بازی کرده پاسخ میدهد و بازی به راند بعدی میرود.
- در راند بعدی، نفر دوم موضوع رو انتخاب کرده، پاسخ میدهد و دست به نفر اول منتقل میشود. همینطور بازی ادامه پیدا میکند تا در راند ۶ به پایان برسد. یعنی طرفین بازی به صورت یکی در میان موضوعها رو انتخاب میکنند.
خب حالا که مسئله رو توضیح دادم، برویم سراغ مدلسازی با استفاده از ماشین حالت.
در مدلسازی مسئلهی فوق به کمک ماشین حالت، از یک سری متغیر کمک گرفتهایم که عبارتند از:
- Turn که دو مقدار دارد : Challenger و Acceptor که Challenger به معنی شروعکنندهی بازی (کسی که بازی رو ساخته) و Acceptor به معنی کسی است که به عنوان حریف (فرد دوم) به بازی اضافه شده است.
- category_selected که یک مقدار Boolean بوده و به معنی این است که آیا برای راند فعلی موضوعی انتخاب شده یا خیر.
- half_round_played که یک مقدار Boolean بوده و به این معنی است که آیا یک طرف این راند، دست خود را بازی کرده یا خیر.
- round_number که نشاندهنده راند جاری بوده و بیانگر این است که بازی در حال حاضر در چه راندی قرار دارد.
ما برای نمایش هر State از چهارتایی مرتب زیر کمک گرفتهایم:
(turn,category_selected,half_round_played,round_number)
در دیاگرام فوق، ch به معنای Challenger و ac به معنای Acceptor است.
با رسم دیاگرام فوق به راحتی میتوان دید که به ازای هر عمل، در چه Stateی قرار میگیریم و نهایتا با رسیدن به نقطهی پایان بازی، کدهای Logic مربوط به محاسبات جوایز و امتیازات مربوط به بازی اجرا خواهند شد.
به این ترتیب و با استفاده از ماشین حالت، اولا فضای مسئله برای طراحی اولیه (یا بازنویسی) به طور کامل روشن میشود، ثانیا به کمک همین روشن شدن فضای حالت به راحتی میتوان Test Caseهای مسئله را شناسایی و این قسمت را به صورت TDD یا همان Test Driven Development پیادهسازی کرد. ثالثا ویرایش کد برای شخص جدیدی که به پروژه اضافه میشود، بسیار آسان خواهد شد.
نکتهای که باید در طراحی ماشین حالت رعایت شود، این است که تعداد متغیرها باید کمترین مقدار ممکنی باشد که کل فضای حالت را برای ما مدلسازی کند. بنابراین از اضافه کردن متغیرهای دیگری که مسئله را پیچیده میکنند و با استفاده از سایر متغیرها قابل محاسبه هستند، خودداری میکنیم.
این بود یک مثال ساده از ماشین حالت یا همان Automota که در علم هوش مصنوعی به شدت از آن استفاده میشود؛ اما در برنامهنویسیهای روزمرهی ما جای خالی آن حس میشود.
دیدگاهها و نظرات خود را بنویسید
برای گفتگو با کاربران ثبت نام کنید یا وارد حساب کاربری خود شوید.
جالب بود