مسئلهای که باید حل میکردم
چهار کارت روی میز با مقایسهٔ سادهٔ عدد برنده نمیشوند. حکم و خال آغاز تعیین میکنند کدوم کارت اصلاً وارد رقابت بشه؛ بعد قدرت رتبه معنی پیدا میکنه.
پیادهسازی در نسخهٔ فعلی
HokmTrickWinnerResolver.ResolveWinner ابتدا وجود حکم در دور را بررسی میکنه. اگر حکم بازی شده باشد آن خال برنده هست؛ وگرنه خال آغاز. سپس با GetRankStrength قویترین کارت همان خال را پیدا میکنه.
تصمیم و هزینهٔ طراحی
خروجی صندلی و تیم برنده را میدهد و قانون قدرت رتبه از config میآید. عدد enum کارت را مستقیماً با قدرت در حکم یکی نگرفتم.
مرزهای فعلی
سرویس تا چهار کارت کامل نشود یا خال آغاز مشخص نباشد نتیجه نمیدهدد. برندهٔ یک دور هم نتیجهٔ کل مسابقه نیست؛ امتیازدهی و رهبر دور بعد در سرویسهای دیگر ادامه پیدا میکنند.
اول خال رقابت، بعد قدرت رتبه
برای فهم مسئله، دوری را تصور کن که با یک آس غیرحکم شروع شده و بعد یک حکم کوچک روی میز آمده هست. مقایسهٔ مستقیم عدد رتبه میتواند آس را برنده بداند، در حالی که ResolveWinner ابتدا وجود خال حکم را بررسی میکنه. اگر حکم حاضر باشد، تنها کارتهای همان خال وارد رقابت میشوند؛ در غیر این صورت خال آغاز دور مبناست. این ترتیب تصمیمها مهمتر از یک مرتبسازی ساده هست. کارت قوی در خال نامربوط، بدون جایگاه قانونی برای رقابت، نباید صرفاً به خاطر رتبهٔ بالا برنده اعلام بشه.
قدرت هر کارت واجد رقابت از config.GetRankStrength خوانده میشود. سرویس هنگام پیدا کردن قدرت بالاتر، bestPlayedCard را عوض میکنه و کارتهایی با قدرت غیرمثبت را کنار میگذارد. نتیجه علاوه بر صندلی و تیم برنده، خال آغاز، خال حکم، وجود حکم و قدرت برنده را نگه میدارد. این داده برای توضیح تصمیم یا ارائهٔ نتیجه قابل استفاده هست؛ مصرفکننده لازم نیست از متن روی کارت رتبه را دوباره تفسیر کنه. البته نتیجهٔ قابل توضیح با اثبات صحت تمام دادههای ورودی برابر نیست؛ پیکربندی رتبهها همچنان باید معتبر باشد.
ResolveWinner تنها یک پرسوجوی بیاثر نیست: پس از تعیین برنده، SetCurrentWinner را روی trickState فراخوانی میکنه. برای هماهنگکنندهٔ بازی این تغییر وضعیت مهم هست، چون بازخوانی یا فراخوانی تکراری باید با اطلاع از اثر متد انجام بشه. در ابتدای مسیر نیز نبودن خال آغاز یا کامل نبودن چهار کارت خطا میدهد. اما سرویس امتیاز مسابقه را زیاد نمیکنه و کارتهای میز را جمع نمیکنه. این مرز اجازه میدهد تعیین برنده، اعلام نتیجه، جمعآوری کارت و انتخاب رهبر بعدی به ترتیب مشخص انجام بشن، بدون اینکه یک متد همهٔ چرخه را پنهان کنه.
چیزی که از این مرحله یاد گرفتم
این مرز جلوی یک اشتباه مفهومی را گرفت: انتخاب برنده باید به کارتهای قابل رقابت محدود بشه. بعداً میشود از همین نتیجه برای امتیاز، جمعکردن کارتها و شروع بعدی استفاده کرد.
مثال عملی برندهٔ دور حکم
اگر بخواهی برندهٔ دور حکم را در یک پروژهٔ کوچک بررسی کنی، بهتر است از یک موقعیت محدود شروع کنی. چهار کارت یک دور را ثبت کن و جداگانه بررسی کن آیا دور با حکم بریده شده است. ورودی را ثابت نگه دار و نتیجهٔ مورد انتظار را پیش از اجرای نسخه بنویس. این کار کمک میکند تفاوت میان رفتار منطقی و چیزی که صرفاً روی صفحه دیده میشود روشن بماند. سناریوی این بخش آموزشی است و ادعای نتیجهٔ واقعی یک آزمایش روی کاربران دلو ندارد.
خطای رایج و علت آن
مقایسهٔ رتبهٔ خام، کارت خال نامرتبط را بالاتر از کارت مجاز حساب میکند. این خطا معمولاً وقتی پنهان میماند که فقط مسیر موفق و ظاهر نهایی را ببینیم. برای پیدا کردن علت، آخرین وضعیت درست را از نخستین وضعیت نادرست جدا کن و ببین تغییر دقیقاً در کدام مرز رخ داده است. برندهٔ دور، برندهٔ دست و برندهٔ مسابقه در سه سطح متفاوت محاسبه میشوند. اگر این تفاوت در قرارداد مشخص نباشد، اصلاح یک نشانه ممکن است همان مسئله را در بخش دیگری دوباره ایجاد کند.
چطور نتیجه را بررسی کنیم؟
خال شروع، خال حکم و ترتیب کارتها را همراه نتیجهٔ مورد انتظار در تست بنویس. اجرای یکباره برای نتیجهگیری کافی نیست؛ یک بار مسیر معمول و بار دیگر همان موقعیت را با ورودی مرزی یا تکرار اقدام بررسی کن. اگر نتیجه فرق دارد، ورودی و شرایط اجرا را همراه خروجی نگه دار تا مقایسه قابل بازسازی باشد. جدول زیر خلاصهٔ مشخصات همین سناریو است و برای ثبت نتیجهٔ بررسی به کار میآید.
| بخش بررسی | آنچه باید ثبت شود |
|---|---|
| موقعیت آزمایشی | چهار کارت یک دور را ثبت کن و جداگانه بررسی کن آیا دور با حکم بریده شده است. |
| ریسک اصلی | مقایسهٔ رتبهٔ خام، کارت خال نامرتبط را بالاتر از کارت مجاز حساب میکند. |
| روش بررسی | خال شروع، خال حکم و ترتیب کارتها را همراه نتیجهٔ مورد انتظار در تست بنویس. |
| مرز نتیجهگیری | برندهٔ دور، برندهٔ دست و برندهٔ مسابقه در سه سطح متفاوت محاسبه میشوند. |
پرسشهای کاربردی دربارهٔ برندهٔ دور حکم
از کجا شروع کنم؟
از همان موقعیت محدود این مطلب شروع کن: چهار کارت یک دور را ثبت کن و جداگانه بررسی کن آیا دور با حکم بریده شده است. ابتدا نتیجهٔ مورد انتظار را مشخص کن و بعد سراغ پیادهسازی یا ابزار برو. وقتی مسیر پایه قابل توضیح و بررسی شد، میتوان حالتهای بیشتری اضافه کرد. ساخت همهٔ حالتها از ابتدا، فهم علت خطا را سختتر میکند.
چه زمانی میتوانم بگویم این بخش درست کار میکند؟
زمانی که رفتار در موقعیت تعریفشده با قرارداد سازگار باشد و محدودیتهای آن روشن بمانند. خال شروع، خال حکم و ترتیب کارتها را همراه نتیجهٔ مورد انتظار در تست بنویس. موفقیت در این آزمون دربارهٔ همان سناریو شاهد میدهد؛ از آن نمیتوان بدون بررسی دربارهٔ همهٔ دستگاهها، همهٔ قوانین محلی یا همهٔ حجمهای داده نتیجه گرفت. برندهٔ دور، برندهٔ دست و برندهٔ مسابقه در سه سطح متفاوت محاسبه میشوند.
برای ادامهٔ همین موضوع، هستهٔ مشترک دلو؛ یک میز برای چند بازی و بازی دلو را ببین. زمینهٔ ساخت این پروژهها و معرفی سازنده در صفحهٔ کیان پاک نعمت آمده است.




