پورت هوش مصنوعی از پایتون به جاوااسکریپت و تست تطابق با ۲۰۰ بازی
دموی آنلاین TekTacTok هیچ سروری ندارد: همهچیز داخل مرورگر اجرا میشود. ولی هوش مصنوعی اصلی را با پایتون نوشته بودیم. باید منطق به جاوااسکریپت منتقل میشد، و ترس هر پورت این است: «مطمئنم همان رفتار را دارد؟»
چرا فقط جدول لازم بود
خوشبختانه استنتاج (inference) این هوش مصنوعی ساده است: یک جدول از پیشمحاسبهشده (حدود ۴۳ هزار حالت، حدود ۱٫۱ مگابایت JSON که بعد از فشردهسازی حدود ۱۵۵ کیلوبایت منتقل میشود) و چند تابع کوچک: حرکتهای مجاز، اعمال حرکت، تشخیص برنده و تبدیل حالت به شکل «استاندارد» با در نظر گرفتن تقارن. الگوریتم حل (که سنگین است) در پایتون میماند و فقط نتیجهاش در مرورگر بارگذاری میشود.
جزئیات خطرناک
- تقارن: برای پیدا کردن حالت استاندارد باید همهی ۸ تقارن صفحه (۴ چرخش، با و بدون بازتاب) را به همان ترتیب پایتون امتحان کنیم و کوچکترین نمایش را برداریم. ترتیب مقایسهی آرایهها باید دقیقاً مثل مقایسهی tuple در پایتون باشد.
- کلید جدول: رشتهای از موقعیت مهرهها بهعلاوهی نوبت و دو شمارنده. یک تفاوت کوچک در قالب رشته یعنی «حالت پیدا نشد».
- انتخاب تصادفی بین حرکتهای همارزش: در دو زبان با یک مولد تصادفی یکسان، ترتیب فراخوانی نباید فرق کند.
تست تطابق
بهجای خواندن کد و امیدوار بودن، دو اسکریپت نوشتم: یکی با نسخهی پایتون و یکی با نسخهی جاوااسکریپت، هر دو با همان مولد تصادفی (یک LCG ساده) و همان قوانین انتخاب. هر کدام ۲۰۰ بازی را از ابتدا تا برد بازی میکنند و نتیجه (برنده) ذخیره میشود. بعد دو خروجی مقایسه میشوند.
دو درس از این تست:
- اولین مقایسهی کامل، اختلاف نشان داد، ولی علتش خود تست بود. در نسخهی پایتون رشتهی تصادفی را در هر نوبت مصرف میکردم، اما در جاوااسکریپت عملگر
&&اجازه میداد در حالت «بینقص» اصلاً مصرف نشود. بعد از اصلاح تست، حرکتها همخوان شدند. - حتی با تست درست، حرکتهای دقیق گاهی فرق داشتند (ترتیب حرکتهای همارزش)، ولی برندهی ۲۰۰ بازی کاملاً یکسان بود. چون هر دو حرکت بهینه بودند، نتیجه تغییر نکرد. معیار درست تطابق، «بهینه بودن حرکت» بود، نه برابری بایتبهبایت.
نتیجه: ۰ اختلاف در برندهی ۲۰۰ بازی.
جمعبندی
پورت درست با دقت در خواندن کد به دست نمیآید؛ با تست تطابق خودکار به دست میآید، و گاهی اولین مشکل خودِ تست است. اگر قصد دارید الگوریتمی را به زبان دیگری ببرید: اول معیار تطابق را تعریف کنید (چه چیزی باید دقیقاً برابر باشد؟)، بعد تست را بنویسید، بعد پورت را.