هذا مشروع لرسالة الماجستير الخاصة بي. نرحب بأي شخص مهتم بإنشاء Mahjong AI قوي لتمديد وكيل أعمالي. لمزيد من التفاصيل حول الخوارزميات المطبقة وأسباب استخدام هذه الخوارزميات، يرجى الاتصال بي عبر البريد الإلكتروني.
في حالة رغبتك في تطوير وكيل Mahjong الخاص بك، يمكن أيضًا استخدام Repo هذا كإطار عمل للاختبار في الوقت الفعلي ( مع لاعبين بشريين حقيقيين ). ثم يمكنك توفير كل وقتك للعثور على أفضل استراتيجية لوكيلك. علاوة على ذلك، تتوفر الآن مكتبة تطوير (الزحف والمعالجة المسبقة لسجلات اللعبة وحساب شانتين ونقاط الفوز وما إلى ذلك) على: https://github.com/erreurt/MahjongKit
التحديث القادم قريبا :
هناك حاجة إلى هندسة أفضل للميزات. قرر ما إذا كنت تريد استدعاء دمج/استدعاء Riichi أو عدم استخدام Random Forest (بدلاً من قواعد الشرط).
مستمر : تدريب نموذج التنبؤ ببلاطات الانتظار باستخدام LSTM.
تنبيه : إذا قمت باختبار الروبوت الخاص بك بالتوازي مع أكثر من 4 حسابات تحت نفس عنوان IP، فسيتم حظر عنوان IP الخاص بك بواسطة Tenhou.net لمدة 24 ساعة. (لا أعرف بالضبط قواعد حظر اللاعبين، لكن هذا كله مستنتج من ملاحظتي).
مؤلف | جيانيانغ تانغ (توماس) |
---|---|
بريد إلكتروني | [email protected] |
Mahjong هي لعبة إستراتيجية لأربعة لاعبين بمعلومات غير كاملة. تتمثل التحديات الرئيسية التي تواجه تطوير وكيل Mahjong الذكي على سبيل المثال في قواعد اللعبة المعقدة ومساحة البحث الهائلة وتعدد الخصوم والمعلومات غير الكاملة. حاولت العديد من الأعمال الحالية معالجة هذه المشكلات من خلال محاكاة شجرة مونت كارلو، أو وظيفة المنفعة الملائمة من خلال التعلم الخاضع للإشراف أو نموذج المعارضين من خلال خوارزميات الانحدار. ومع ذلك، فإن أداء عملاء لعب Mahjong الأذكياء لا يزال بعيدًا عن أداء أفضل اللاعبين البشريين. استنادًا إلى التحليل الإحصائي للعبة Mahjong ومعرفة الخبراء البشريين، تم اقتراح وكيل Mahjong الذكي في هذا العمل. لمعالجة مشاكل العمل المتطور، تم تطبيق تقنيات الاستدلال ونموذج المعارضين المعزز الذي تم تحقيقه من خلال اعتماد تعبئة الإدراك الحسي متعدد الطبقات على هذا العمل. أظهرت التجارب أن العامل المقترح يتفوق على العامل الحديث، وأن نموذج المعارضين المطبق له تأثير إيجابي كبير على أداء الوكيل. علاوة على ذلك، يمكن تمييز العديد من النقاط المثيرة للاهتمام من التجارب، والتي تعتبر مفيدة جدًا للعمل المستقبلي.
ارجع إلى https://en.wikipedia.org/wiki/Japanese_Mahjong للتعرف على قواعد لعبة Riichi Mahjong اليابانية.
يسمح العميل المطبق بتشغيل وكيل Mahjong مباشرة من خلال البرنامج، بدلاً من القيام بذلك في متصفح الويب. موقع لعب لعبة Riichi Mahjong اليابانية عبر الإنترنت هو http://tenhou.net/
الجانب الأيسر عبارة عن مشهد نموذجي لطاولة Riichi Mahjong اليابانية. هذه الصورة هي لقطة شاشة من واجهة المستخدم الرسومية التي تم تنفيذها لاستخدام تصحيح الأخطاء.
تم اختبار وكيل Mahjong المقترح على موقع Tenhou.net. تم إجراء الاختبار في نسختين، إحداهما بنموذج دفاعي والأخرى بدونه. يمكن العثور على سجلات اللعبة الأولية ونتائج اللعبة المتوسطة في مستودعي الآخر: https://github.com/erreurt/Experiments-result-of-mahjong-bot. تم إجراء التجارب باستخدام إصدار الوكيل في experience_ai.py .
بالنسبة للنسخة ذات النموذج الدفاعي، تم لعب 526 مباراة، وبالنسبة للنسخة بدون النموذج الدفاعي، تم لعب 532 مباراة. لا يقتصر الأمر على عملين مرتبطين، ولكن كما هو موضح في شكل سلوك التقارب لأداء الوكيل، فإن 526 لعبة كافية.
يمكن اعتبار عمل Mizukami الممتد أفضل وكيل Mahjong وأكثرها موثوقية حاليًا في الأدب الإنجليزي. هنا يتم عرض مقارنة بين أداء وكيل Mahjong الخاص بي وأداء Mizukami:
[1] | [2] | [3] | [4] | |
---|---|---|---|---|
الألعاب التي لعبت | 526 | 532 | 2634 | 1441 |
معدل المركز الأول | 23.95% | 22.65% | 24.10% | 25.30% |
معدل المركز الثاني | 26.62% | 25.92% | 28.10% | 24.80% |
معدل المركز الثالث | 31.75% | 25.71% | 24.80% | 25.10% |
معدل المركز الرابع | 17.68% | 25.71% | 23.00% | 24.80% |
معدل الفوز | 24.68% | 26.50% | 24.50% | 25.60% |
معدل الخسارة | 13.92% | 20.21% | 13.10% | 14.80% |
مستوى ثابت | 2.21 دان | 0.77 دان | 1.14 دان | 1.04 دان |
[1] وكيل Mahjong الخاص بي مع نموذج الدفاع
[2] وكيل Mahjong الخاص بي بدون نموذج دفاع
[3] عمل Mizukami الممتد : Mizukami N., Tsuruoka Y.. بناء لاعب ماهجونغ على الكمبيوتر يعتمد على محاكاة مونتي كارلو ونماذج الخصم. في: مؤتمر IEEE لعام 2015 حول الذكاء الحسابي والألعاب (CIG)، الصفحات من 275 إلى 283. معهد مهندسي الكهرباء والإلكترونيات (2015)
[4] ميزوكامي وآخرون. آل. : N. Mizukami، R. Nakahari، A. Ura، M. Miwa، Y. Tsuruoka، and T. Chikayama. تحقيق برنامج ما جونغ للكمبيوتر لأربعة لاعبين من خلال التعلم الخاضع للإشراف مع جوانب معزولة متعددة اللاعبين. معاملات جمعية معالجة المعلومات في اليابان، المجلد. 55، لا. 11، ص 1-11، 2014، (باللغة اليابانية).
لاحظ أنه أثناء لعب Mahjong، يعد الوصول إلى المركز الرابع أمرًا محظورًا بالتأكيد، حيث سيتم تخفيض نقاط المستوى. ونتيجة لذلك، فإن معدل الوقوع في المركز الرابع للاعب أمر بالغ الأهمية لأدائه العام. يتمتع الروبوت الخاص بي بمستوى ثابت أفضل تمامًا بسبب انخفاض معدل المركز الرابع.
لتشغيل وكيل Mahjong، يتعين على المرء تحديد بعض التكوينات. كما هو موضح في المثال التالي من main.py:
def run_example_ai ():
ai_module = importlib . import_module ( "agents.random_ai_example" )
ai_class = getattr ( ai_module , "RandomAI" )
ai_obj = ai_class () # [1]
player_module = importlib . import_module ( "client.mahjong_player" )
opponent_class = getattr ( player_module , "OpponentPlayer" ) # [2]
user = "ID696E3BCC-hLHNE8Wf" # [3]
user_name = "tst_tio" # [4]
game_type = '1' # [5]
logger_obj = Logger ( "log1" , user_name ) # [6]
connect_and_play ( ai_obj , opponent_class , user , user_name , '0' , game_type , logger_obj ) # play one game
def run_jianyang_ai ():
ai_module = importlib . import_module ( "agents.jianyang_ai" )
waiting_prediction_class = getattr ( ai_module , "EnsembleCLF" )
ensemble_clfs = waiting_prediction_class ()
ai_class = getattr ( ai_module , "MLAI" )
ai_obj = ai_class ( ensemble_clfs ) # [1]
opponent_class = getattr ( ai_module , "OppPlayer" ) # [2]
user = "ID696E3BCC-hLHNE8Wf" # [3]
user_name = "tst_tio" # [4]
game_type = '1' # [5]
logger_obj = Logger ( "log_jianyang_ai_1" , user_name ) # [6]
connect_and_play ( ai_obj , opponent_class , user , user_name , '0' , game_type , logger_obj )
مثيل الذكاء الاصطناعي : مثيل فئة وكيل Mahjong. في هذا المستودع يتم توفير ثلاثة إصدارات من وكيل Mahjong. الأول موجود في agent.random_ai_example.py ، وهو عبارة عن فصل تجريبي يوضح للمطورين المحتملين كيفية تنفيذ وكلائهم. والثاني موجود في agent.experiment_ai.py ويتم إنشاء نتائج التجربة الواردة في الجزء 4 بواسطة هذا الذكاء الاصطناعي. والثالث هو الذكاء الاصطناعي المحدث وهو موجود فيوكلاء.jianyang_ai.py .
فئة اللاعب المنافس : فئة اللاعب المنافس. يمكن للمرء استخدام الفئة الافتراضية OponentPlayer في client.mahjong_player . إذا قام أحدهم بتوسيع فئة OponentPlayer بسبب احتياجات إضافية، فيجب تعيين هذا المتغير إلى فئتك المقابلة.
معرف المستخدم : رمز مميز في النموذج كما هو موضح في المثال الذي حصل عليه بعد التسجيل على موقع Tenhou.net. تنبيه: يرجى استخدام معرف المستخدم الخاص بك. إذا تم استخدام نفس المعرف تحت عنوان IP مختلف في كثير من الأحيان، فسيتم حظر الحساب مؤقتًا بواسطة Tenhou.net.
اسم المستخدم : اسم المستخدم المقابل الذي قمت بإنشائه أثناء التسجيل على Tenhou.net. هذا المتغير مخصص فقط لتحديد سجلات الاختبار الخاصة بك.
نوع اللعبة : يتم ترميز نوع اللعبة كعدد صحيح 8 بت. وفيما يلي وصف لكل بت.
على سبيل المثال:
- Tenhou.net does not provide all possibility of the above specified combinations. Most online players play on configurations for example "1", "137", "193", "9"
المسجل : هناك معلمتان مطلوبتان لتهيئة المسجل. الأول هو معرف المسجل المحدد من قبل المستخدم، بحيث يمكن للمطورين تسمية سجل الاختبار الخاص به بحرية.
بعد تحديد كل هذه التكوينات، ما عليك سوى طرح كل هذه المعلمات إلى Connect_and_play() . إذًا حان الوقت لمشاهدة عرض وكيل Mahjong الخاص بك!!!
يجب تنفيذ أربع وظائف لروبوت Mahjong، كما هو موضح في فئة "الواجهة" فيوكلاء. ai_interface . من المستحسن أن يكون وكيلك وراثة لـ AIInterface. للحصول على شرح أعمق ومثال بسيط لهذه الوظائف، يرجى الاطلاع على الوثائق فيوكلاء .random_ai_example.py .
class AIInterface ( MainPlayer ):
def to_discard_tile ( self ):
raise NotImplementedError
def should_call_kan ( self , tile136 , from_opponent ):
raise NotImplementedError
def try_to_call_meld ( self , tile136 , might_call_chi ):
raise NotImplementedError
def can_call_reach ( self ):
raise NotImplementedError
to_discard_tile : استنادًا إلى جميع المعلومات التي يمكن الوصول إليها حول حالة اللعبة، تقوم هذه الوظيفة بإرجاع مربع لتجاهله. الإرجاع هو عدد صحيح في النطاق 0-135. يوجد إجمالي 136 قطعة في لعبة Mahjong، أي 34 نوعًا من البلاط و4 نسخ لكل نوع. في مناسبات مختلفة نستخدم إما النموذج 34 (كل رقم يتوافق مع نوع واحد من البلاط) أو النموذج 136 (كل رقم يتوافق مع نوع واحد من البلاط). لاحظ أن الإرجاع هنا يجب أن يكون على شكل 136.
ينبغي_الاتصال_كان : https://en.wikipedia.org/wiki/Japanese_Mahjong#Making_melds_by_calling. يجب أن تقرر هذه الوظيفة ما إذا كان يجب على الوكيل استدعاء مزيج kan(Quad). Tile136 يشير إلى القطعة التي تخلص منها بعض الخصم، والتي يمكن استخدامها للوكيل لتشكيل مزيج kan. يشير from_opponent إلى ما إذا كان العميل يقوم بتشكيل kan من خلال تجاهل الخصم (ثلاثة قطع في متناول اليد ويتخلص الخصم من القطعة الرابعة) أو البلاط الخاص (جميع المربعات الأربعة في متناول اليد).
Try_to_call_meld : https://en.wikipedia.org/wiki/Japanese_Mahjong#Making_melds_by_calling. تقرر هذه الوظيفة ما إذا كان يجب على الوكيل استدعاء مزيج Pon(Triplet)/Chi(Sequence). Tile136 يرمز إلى البلاطة ذات الشكل 136 التي تجاهلها بعض المعارضين. may_call_chi يشير إلى ما إذا كان العميل يمكنه استدعاء مزيج الطاقة، حيث أنه لا يمكن استدعاء مزيج الطاقة إلا مع تجاهل الخصم في المقعد الأيسر.
can_call_reach : https://en.wikipedia.org/wiki/Japanese_Mahjong#R%C4%ABchi. تحدد هذه الوظيفة ما إذا كان يجب على الوكيل المطالبة بـ Riichi.
عندما تكون فئة وكيل Mahjong فئة فرعية من فئة AIInterface ، يمكن الوصول إلى المعلومات المدرجة على النحو التالي داخل فئة الوكيل كما هو محدد.
وصول | نوع البيانات | متقلب | الوصف |
---|---|---|---|
self.tiles136 | قائمة الأعداد الصحيحة | ي | بلاط يدوي على شكل 136 |
self.hand34 | قائمة الأعداد الصحيحة | ن | بلاط يدوي على شكل 34 (بلاط 34 = بلاط 136 // 4) |
تجاهل136 | قائمة الأعداد الصحيحة | ي | المرتجعات من الوكيل في 136-من |
تجاهل34 | قائمة الأعداد الصحيحة | ن | مرتجعات الوكيل في 34 نموذجًا |
self.meld136 | قائمة حالات Meld | ي | مجموعات الوكيل التي تم استدعاؤها، ومثيلات الفئة Meld في client.mahjong_meld.py |
self.total_melds34 | قائمة قائمة الأعداد الصحيحة | ن | أمزجة الوكيل المدعوة في 34 شكلاً |
self.meld34 | قائمة قائمة الأعداد الصحيحة | ن | ما يسمى بون / تشاو يمزج العامل في 34 نموذجًا |
self.pon34 | قائمة قائمة الأعداد الصحيحة | ن | يمزج بون المسمى للوكيل في 34 شكلاً |
self.chow34 | قائمة قائمة الأعداد الصحيحة | ن | يمزج الطعام المسمى العامل في 34 شكلاً |
self.minkan34 | قائمة قائمة الأعداد الصحيحة | ن | المنكان المسمى يمزج الوكيل في 34 شكلاً |
ankan34 | قائمة قائمة الأعداد الصحيحة | ن | يسمى أنكان يمزج الوكيل في 34 شكلاً |
self.name | خيط | ي | اسم الحساب |
المستوى الذاتي | خيط | ي | مستوى الحساب |
self.seat | عدد صحيح | ي | معرف المقعد، الوكيل لديه دائمًا 0 |
self.dealer_seat | عدد صحيح | ي | معرف مقعد التاجر |
self.is_dealer | منطقية | ن | سواء كان الوكيل تاجرا أم لا |
self.reach_status | منطقية | ي | يشير إلى ما إذا كان الوكيل قد ادعى Riichi |
self.just_reach() | منطقية | ن | ما إذا كان الوكيل قد ادعى Riichi للتو |
self.tmp_rank | عدد صحيح | ي | رتبة الوكيل في اللعبة الحالية |
self.score | عدد صحيح | ي | نتيجة الوكيل في اللعبة الحالية |
self.is_open_hand | منطقية | ن | ما إذا كان الوكيل قد قام بالفعل باستدعاء عمليات الدمج المفتوحة |
self.turn_num | عدد صحيح | ن | عدد الدورة الحالية |
self.player_wind | عدد صحيح | ن | ريح اللاعب هي نوع واحد من الياكو |
self.round_wind | عدد صحيح | ن | الرياح المستديرة هي نوع واحد من الياكو |
self.bonus_honors | قائمة الأعداد الصحيحة | ي | جميع بلاطات الشخصيات التي تحتوي على ياكو |
يمكن للمرء الوصول إلى مثيل فئة الخصم عن طريق استدعاء self.game_table.get_player(i) بـ i يساوي 1,2,3، مما يشير إلى المعرف المقابل للخصم.
وصول | نوع البيانات | متقلب | الوصف |
---|---|---|---|
.discard136 | قائمة الأعداد الصحيحة | ي | رميات الخصم المرصودة في 136 من |
.discard34 | قائمة الأعداد الصحيحة | ن | رميات الخصم المرصودة في 34 شكلاً |
.meld136 | قائمة حالات Meld | ي | الاختلاط المزعوم للخصم المرصود |
.total_melds34 | قائمة قائمة الأعداد الصحيحة | ن | الدمج المطلوب للخصم المرصود في 34 شكلاً |
.meld34 | قائمة قائمة الأعداد الصحيحة | ن | يمزج ما يسمى بون / تشاو للخصم المرصود في 34 شكلًا |
.pon34 | قائمة قائمة الأعداد الصحيحة | ن | يمزج بون المسمى للخصم المرصود في 34 شكلاً |
.chow34 | قائمة قائمة الأعداد الصحيحة | ن | يختلط الطعام المسمى بالخصم المرصود في 34 شكلاً |
.مينكان34 | قائمة قائمة الأعداد الصحيحة | ن | يختلط المنكان المسمى بالخصم المرصود في 34 شكلًا |
.ankan34 | قائمة قائمة الأعداد الصحيحة | ن | ما يسمى أنكان يمزج بين الخصم المرصود في 34 شكلاً |
.safe_tiles | قائمة الأعداد الصحيحة | ي | قطع على شكل 34 وهي آمنة تمامًا للعميل، أي أن الخصم المرصود لا يمكنه الفوز بهذه البلاطات |
.اسم | خيط | ي | اسم الخصم |
.مستوى | خيط | ي | مستوى الخصم |
.مقعد | عدد صحيح | ي | معرف مقعد الخصم المرصود |
.dealer_seat | عدد صحيح | ي | معرف مقعد التاجر |
.is_dealer | منطقية | ن | ما إذا كان الخصم المرصود هو تاجر أم لا |
.reach_status | منطقية | ي | يشير إلى ما إذا كان الخصم المرصود قد ادعى ريتشي |
.just_reach() | منطقية | ن | ما إذا كان الخصم المرصود قد ادعى ريتشي للتو |
.tmp_rank | عدد صحيح | ي | رتبة الخصم الملاحظ في اللعبة الحالية |
.نتيجة | عدد صحيح | ي | نتيجة الخصم الملاحظ في اللعبة الحالية |
.is_open_hand | منطقية | ن | ما إذا كان الخصم المرصود قد دعا بالفعل إلى عمليات الدمج المفتوحة |
.turn_num | عدد صحيح | ن | عدد الدورة الحالية |
.player_wind | عدد صحيح | ن | ريح اللاعب هي نوع واحد من الياكو |
.round_wind | عدد صحيح | ن | الرياح المستديرة هي نوع واحد من الياكو |
.bonus_honors | قائمة الأعداد الصحيحة | ي | جميع بلاطات الشخصيات التي تحتوي على ياكو |
للوصول إلى معلومات حول طاولة اللعبة، يمكن للمرء الاتصال بـ self.game_table
وصول | نوع البيانات | متقلب | الوصف |
---|---|---|---|
.بوت | مثال فئة الوكيل | ي | مثيل فئة الوكيل |
.get_player(ط) | مثال على فئة الخصم | ي | مثيل فئة الخصم، ط = 1،2،3 |
.dealer_seat | عدد صحيح | ي | معرف مقعد التاجر |
.bonus_indicator | قائمة الأعداد الصحيحة | ي | مؤشرات المكافأة في 136 نموذج |
.round_number | عدد صحيح | ي | رقم الجولة |
.reach_sticks | عدد صحيح | ي | كم عدد أعواد ريتشي الموجودة على الطاولة. اللاعب الذي يفوز بعد ذلك سيحصل على جميع نقاط عصي Riichi هذه |
.honba_sticks | عدد صحيح | ي | كم عدد أعواد الهونبا الموجودة على الطاولة. سيحصل اللاعب على نقاط إضافية وفقًا لعصي الهونبا إذا فاز |
.count_ramaining_tiles | عدد صحيح | ي | عدد البلاطات غير المكشوفة المتبقية |
.مكشوف | قائمة الأعداد الصحيحة | ي | يشير كل عنصر في القائمة إلى عدد نسخ هذا المربع المحدد التي تم الكشف عنها (المستبعدات، والمجموعات المفتوحة، ومؤشرات المكافآت، وما إلى ذلك) |
.round_win | عدد صحيح | ن | الرياح المستديرة هي نوع واحد من الياكو |
.bonus_tiles | قائمة الأعداد الصحيحة | ن | قائمة البلاط المكافأة. يتم اعتبار كل ظهور لبلاطات إضافية في بلاطات اليد بمثابة ياكو |
.last_discard | عدد صحيح | ن | أحدث رمي للخصم، هذا البلاط آمن تمامًا وفقًا للقواعد |
أستاذي يوهانس فورنكرانز (مجموعة هندسة المعرفة بجامعة دارمشتات)
مشرفي توبياس جوبن (مجموعة هندسة المعرفة TU Darmstadt)