داغاز: بداية جديدة

إنه يمتد جنوبًا ويدور شمالًا ، دائريًا ، دائريًا ليركض مع ريح
ووفقًا لداراتها ، تعود الرياح ؛
تجري جميع الأنهار إلى البحر - ولا يفيض البحر ،
إلى المكان الذي تجري فيه الأنهار ، - هناك يواصلون الجري ؛

كتاب الكنسيون

في عام 1998 ، تم تطوير تطبيق فريد تمامًا ، في وقته ، مما يسمح لك بتقليل عملية تطوير لعبة لوحة مجردة (أو لغز) إلى لغة وصف نصية صغيرة ، تذكرنا بشكل غامض بـ Lisp . كان يسمى هذا المشروع Zillions of Games . خلقت ضجة بين عشاق ألعاب الطاولة. حاليا ، تم إنشاء أكثر من 2000 تطبيق باستخدام هذه التكنولوجيا.

سرعان ما أصبح من الواضح أن ZoG لديه العديد من العيوب. لقد كتبت بالفعل عن هذا في هبر ولن أكرر نفسي. اسمحوا لي أن أقول إن المطورين لم يأخذوا في الحسبان ميزات عدد كبير من الألعاب الحالية وأن بعض الخيارات المهمة كانت مشفرة بشكل صارم ، بحيث أصبح تغييرها يمثل مشكلة كبيرة. حاول جريج شميدت ، في عام 2007 ، تصحيح الوضع من خلال إطلاق مجموعة أدوات اكسيوم للتطوير ، لكن دمجها الوثيق مع ZoG لا يسمح بحل جميع المشكلات.

أشار Project Ludi إلى حدود جديدة ، باستخدام "محرك" اللعبة العالمي والخوارزميات الجينية لأتمتة عملية تطوير ألعاب الطاولة الجديدة. لسوء الحظ ، تم تصور هذا النهج في البداية على أنه تبسيط متعمد لميكانيكا اللعبة ومستوى الذكاء الاصطناعي المستخدم. مناقشة أهداف هذا المشروع خارج نطاق هذا المقال ، ولكن بعض الحلول التقنية ، بلا شك ، كانت بمثابة نقطة الانطلاق لتطوير بلدي.

هدفي هو تطوير "محرك" متعدد الاستخدامات وسهل الاستخدام لإنشاء ألعاب لوحية مجردة. منذ ما يقرب من عام ، كنت أدرس إمكانية ZoG و Axiom وتعلمت الكثير عن حدودهما. أعتقد أنه يمكنني حل مشكلاتهم عن طريق إنشاء حل عالمي وعالمي. عن التقدم المحرز في العمل في هذا المشروع سأقدم تقريرا.

الانفتاح والوحدة


ربما العيب الرئيسي ل ZoG هو إغلاقه. تم تجميع المنتج "مرة واحدة وإلى الأبد" تحت منصة واحدة واحدة - ويندوز. إذا كانت الشفرة مفتوحة المصدر ، فيمكنك محاولة نقلها تحت Linux و Android و iOS ... وهناك مشكلة أخرى تتمثل في توحيدها.

في ZoG ، هناك بدايات نمطية ، مما يسمح بالاتصال بألعاب DLL ، بما في ذلك التطبيقات المخصصة لـ AI. يمتد Axiom إلى أبعد من ذلك قليلاً ، مما يتيح لك تشغيل التطبيقات في وضع التشغيل التلقائي للوضع ، دون استخدام ZoG kernel. على الرغم من التقييد الخطير لهذا الحل (دعم التطبيقات فقط للاعبين فقط) ، يوضح هذا المثال كيف ستكون الوحدات النمطية مفيدة! لا يمكن المبالغة في تقدير فرصة تنظيم لعبة تحتوي على روتينين (باستخدام إعدادات مختلفة لمنظمة العفو الدولية) وجمع إحصائيات حول عدد كبير من الألعاب. ولكن كم سيكون أفضل لو كان المنتج وحدات بالكامل!

  • نقل وحدة الجيل
  • نقل وحدة التنفيذ
  • وحدة التحكم
  • وحدة منظمة العفو الدولية
  • وحدة التصور

يتم تنفيذ جميع الأعمال التي تصف الألعاب بواسطة وحدة توليد الحركة. هذا هو "قلب" المشروع. نقل جميع المهام غير المرتبطة بهذه الوظيفة إلى وحدات أخرى سيجعل الأمر بسيطًا قدر الإمكان. يمكنك تحسين هذه الوحدة ، دون النظر إلى مشكلات الذكاء الاصطناعي وتفاعل المستخدم. يمكنك تغيير تنسيق وصف الألعاب تمامًا أو إضافة دعم للأوصاف بتنسيق ZoG و Axiom و Ludi. نمطية هي أساس مرونة الحل!

وحدة تنفيذ الخطوة هي الوصي على حالة اللعبة. يتم نقل المعلومات عن حالة اللعبة الحالية إلى جميع الوحدات الأخرى عند الطلب. للأسباب التي سأقدمها أدناه ، يجب أن يمر تقدم التنفيذ عبر وحدة التوليد ، التي تتمثل مهمتها في تكوين أمر من حيث تنفيذ الوحدة. أيضًا ، تتمثل مهمة وحدة توليد الحركة في التكوين الأساسي لمساحة اللعبة ، بناءً على وصف اللعبة.

وحدة التحكم هي ، في الواقع ، التطبيق نفسه. يسأل وحدة توليد الحركة للحصول على قائمة بالتحركات الممكنة وتغيير حالة اللعبة ، ويمر الانتقال المحدد إلى وحدة تنفيذ النقل. يمكن توصيل وحدة التحكم للعب واحدة أو أكثر من روبوتات الذكاء الاصطناعى. ما تحتاجه (وربما مختلفة)! يتم تحديد نوع وحدة التحكم عن طريق تقسيم المهام. قد يكون هذا تشغيلًا تلقائيًا لجمع إحصائيات اللعبة أو خادم الألعاب (يمكنه التحكم في العديد من المتاجر الحكومية ، مما يؤدي إلى عدد كبير من جلسات الألعاب) أو التطبيقات الفردية للعب دون اتصال بالإنترنت.

القدرة على الاتصال بتطبيقات مختلفة من الذكاء الاصطناعى ستحسن جودة اللعبة. من المفهوم أن وحدات لعبة الشطرنج والذهاب يجب أن تستخدم أساليب مختلفة. تتطلب الألعاب ذات المعلومات غير المكتملة والألعاب التي تستخدم بيانات عشوائية أسلوبًا فرديًا. سوف التنفيذ العالمي لل AI يكون سيئا على قدم المساواة جميع الألعاب! سيسمح الاتصال المعياري AI بمقارنة "قوة" الخوارزميات ، بما في ذلك وضع اللعبة "مع بعضها البعض". نظرًا لأن بنية AI منفصلة عن حالة التخزين في اللعبة ، فيمكن لمثيل واحد من روبوت الألعاب أن يدعم رقمًا غير محدود. من جلسات الألعاب في وقت واحد.

التصور من عملية اللعبة يمكن أيضا أن تكون متنوعة. أول ما يتبادر إلى الذهن هو تطبيقات ثنائية وثلاثية الأبعاد. النظام الأساسي الذي يتم تطوير التطبيق له ، مهم أيضًا. أقل وضوحا هو أن التصور قد يكون جزءا هاما من اللعبة! على سبيل المثال ، في لعبة سوراكارتا ، سيكون أخذ القطع غير واضح تمامًا في غياب الرسوم المتحركة المناسبة للحركات.


بشكل عام ، يبدو النموذجية فكرة جيدة لمثل هذا المشروع ، وسيمكّن الكود المفتوح المصدر كل من يرغب في المشاركة في المشروع. في الوقت الحالي ، لا أقوم بتعيين أغراض تجارية بنفسي ، لكنني أعتقد أنه إذا رغبت في ذلك ، فسوف أجد طريقة لكسب المال دون إغلاق الكود المصدري.

مساحة اللعبة


قبل بدء العرض ، تحتاج إلى ضبط المسرح. اللوحة ليست مجرد مكان يتم فيه تجميع القطع. بجانب ذلك ، يمكن تحديد اتجاه حركة القطع (في الواقع ، الروابط بين أوضاع اللوحة) مناطق اللعب (على سبيل المثال ، مناطق تحويل القطع) الحقول الممنوعة ، إلخ. هنا هو كيف يبدو تعريف لوحة الشطرنج في تطبيق ZoG:

تحديد اللوحة في ZoG
(define Board-Definitions (image "images\Chess\SHaag\Chess8x8.bmp" "images\Chess\Chess8x8.bmp") (grid (start-rectangle 5 5 53 53) (dimensions ("a/b/c/d/e/f/g/h" (49 0)) ; files ("8/7/6/5/4/3/2/1" (0 49)) ; ranks ) (directions (n 0 -1) (e 1 0) (s 0 1) (w -1 0) (ne 1 -1) (nw -1 -1) (se 1 1) (sw -1 1) ) ) (symmetry Black (ns)(sn) (nw sw)(sw nw) (ne se)(se ne)) (zone (name promotion-zone) (players White) (positions a8 b8 c8 d8 e8 f8 g8 h8) ) (zone (name promotion-zone) (players Black) (positions a1 b1 c1 d1 e1 f1 g1 h1) ) (zone (name third-rank) (players White) (positions a3 b3 c3 d3 e3 f3 g3 h3) ) (zone (name third-rank) (players Black) (positions a6 b6 c6 d6 e6 f6 g6 h6) ) ) 

قد تلاحظ أنه إلى جانب إعدادات اللعبة ، إليك الإعدادات المرتبطة بالتخيل. أنا مقتنع تمامًا أن هذه الإعدادات لا تنتمي هنا. في تطبيق وحدة التصور ، يمكن استخدام إعدادات متعددة وقد تكون هناك حاجة لإعدادات مختلفة. علاوة على ذلك ، يمكن لألعاب المحاكاة أن تعمل بدون أي وحدة تصوير على الإطلاق (مثل التشغيل التلقائي في اكسيوم). في الواقع ، بما أن اكسيوم يستخدم لتصور ZoG ، فإن التعريف لا يحتوي على أي شيء غير ضروري:

تحديد السبورة في اكسيوم
 {board 8 8 {grid} board} {directions -1 0 {direction} n 1 0 {direction} s 0 1 {direction} e 0 -1 {direction} w -1 -1 {direction} nw 1 -1 {direction} sw -1 1 {direction} ne 1 1 {direction} se directions} {symmetries Black {symmetry} ns Black {symmetry} nw sw Black {symmetry} ne se symmetries} 

لسوء الحظ ، لا تملك اكسيوم أيضًا طريقة لتحديد مناطق اللعبة (يجب تحديد موقع مناطق اللعبة يدويًا في الكود). هذا ليس تبسيط اكسيوم الوحيد. لا يمكن أن يحتوي تعريف اللوحة في هذا المشروع على أكثر من شبكة واحدة ويجب أن تكون هذه الشبكة ثنائية الأبعاد. تعتبر اللوحة ، وبالتالي المعرّفة ، مصفوفة ذات بعد واحد ، ولكن من أجل راحة المبرمج ، يتم تعريف المرادفات لكل مساحة من المساحات كما يلي:


مقارنةً بمخطط تعريف الشبكة الأكثر مرونة في ZoG ، فإن هذه القيود غير مريحة تمامًا (خاصةً بالنظر إلى أن نظام التسمية المفروض يستخدم هذه الحقول لغرض التصور ذاته). لحسن الحظ ، من الممكن تحديد لوحة ذات شكل تعسفي. يوفر كل من اكسيوم و ZoG فرصة لتحديد كل موقف على حدة من ناحية العنصر إلى جانب القدرة على تحديد الروابط بين أزواج المناصب التعسفية. باستخدام هذا النهج ، يمكننا تحديد لوحة من أي طوبولوجيا. العيب الوحيد هو الحرج الشديد وتعقيد الوصف.

بالإضافة إلى موقع القطع على اللوحة وفي الاحتياطي ، يجب أن يتمتع النظام بالقدرة على تخزين سمات الأجزاء الفردية والمسافات الموجودة على اللوحة. مثال جيد على الحاجة إلى استخدام سمات قاعدة " القلاع " في لعبة الشطرنج . هذه خطوة صعبة ، بما في ذلك الحركة المتزامنة للملك والرخ ، المسموح بها ، شريطة ألا يكون أي من هذه القطع قد تحرك قبل تنفيذ هذه الخطوة. يمكن استخدام سمة لتخزين علامة Boolean توضح ما إذا كانت القطعة قد تحركت أم لا. يمكن أن تجد سمات الحقل أيضًا بعض التطبيقات المثيرة للاهتمام.

تجدر الإشارة إلى أن السمات ليست مجرد متغيرات ولكنها جزء من حالة اللعبة. يمكن تغيير قيمة السمة عن طريق تنفيذ دورة (بما في ذلك وحدة AI) ويجب أن تكون متاحة لجميع المنعطفات اللاحقة ، ولكن ليس للتحولات المنجزة في فرع آخر من اللعبة. حاليًا ، تدعم ZoG تخزين السمات المنطقية للقطع. لا تدعم سمات التخزين Axiom ، لكن يمكنك إضافة وصف للمتغيرات والمصفوفات إلى تعريف اللوحة. يمكن استخدام هذه المتغيرات ، مثل عدادات كمية القطع التي تم التقاطها:

 {board 5 18 {grid} {variable} WhitePieces {variable} BlackPieces board} 

مع ذلك ، هناك قيود أخرى على ZoG و Axiom وهي القاعدة التي تنص على أن كل موقف من اللوحة لا يمكن أن يحتوي على أكثر من قطعة واحدة. إذا اكتملت أي قطعة الانتقال إلى موضع تشغله قطعة أخرى ، فإن القطعة التي كانت تشغل سابقًا للموقف تُعتبر "تؤكل" تلقائيًا. تسير هذه القاعدة بشكل جيد مع مبدأ "الشطرنج" المتمثل في أخذ القطع ، ويعمل على تبسيط وصف هذه اللعبة ، لكنه يعقد تنفيذ الألعاب مثل " مدققي الباشني " و " تافريلي ".



في هذه الألعاب ، يمكن ترتيب القطع في "أعمدة". يمكن نقل مثل هذا "العمود" معًا ، كقطعة واحدة. بعد بعض التفكير ، قررت أنه من الأفضل عدم التخلي عن التنفيذ التلقائي لالتقاط لعبة "الشطرنج" ، ولكن تحسين آليات نقل مجموعات القطع. في الواقع ، لتنفيذ "الركائز" ، يمكنك دائمًا إضافة بعد آخر إلى اللوحة (هذا أمر سهل للغاية ، طالما أن وحدة التصور مفصولة عن وحدة توليد الحركة ومن AI ، يمكنك حينئذٍ استخدام أي منطق على الإطلاق لجعل لوحة ثلاثية الأبعاد في تصورها ثنائي الأبعاد). كانت الحجة الإضافية المؤيدة لهذا القرار هي أن الحركة "عالية التراص" للقطع ليست هي النوع الوحيد من السفر الجماعي. على سبيل المثال ، يمكن تدوير شظايا الألواح " Pentago " مع القطع المركبة عليها.


بإيجاز ، يمكنني القول أنه بالنسبة لإطار لعبتي ، قررت أن أبذل قصارى جهدي في ZoG و Axiom و Ludi ، وأضيف أي شيء ، في رأيي ، ينقصهم.

نقل الجيل


نقل الجيل هو أقرب إلى البرمجة غير حتمية . مهمة مولد الحركة هي توفير ، عند الطلب ، قائمة بجميع التحركات الممكنة من الوضع الحالي. أي الانتقال من هذه القائمة سيتم اختياره من قِبل لاعب أو أن منظمة العفو الدولية ليست وظيفتها. دعونا نرى كيف يتم جيل من التحركات في ZoG. على سبيل المثال ، نأخذ ماكرو توليد الحركات لقطعة طويلة المدى (ملكة أو أسقف). هذه هي الطريقة المستخدمة في تحديد التحركات لهذه القطع:

 (piece (name Bishop) (image White "images\Chess\SHaag\wbishop.bmp" "images\Chess\wbishop.bmp" Black "images\Chess\SHaag\bbishop.bmp" "images\Chess\bbishop.bmp") (moves (slide ne) (slide nw) (slide se) (slide sw) ) ) 

كمعلمة ، يتم تمرير ماكرو اتجاه الحركة على السبورة. إذا لم تفكر في إمكانية تثبيت قطع جديدة على السبورة ، فإن إنشاء خطوة يبدو بسيطًا. لكل قطعة على السبورة ، يتم حساب كل التحركات الممكنة وفقًا للقواعد. ثم يبدأ السحر ...

يمكن لكل من التعاريف إضافة إلى القائمة عدد من التحركات المحتملة! تتم إضافة نقل إلى القائمة من خلال إضافة أمر (في نفس الوقت وضع كل قطعة متحركة على اللوحة). لقد كتبت بالفعل عن كيف أن هذا الحل المعماري سيء للغاية. يجب فصل أمر تشكيل الحركة عن الأوامر التي تتعامل مع القطع (كما حدث في اكسيوم). لنرى كيف يعمل الماكرو:

 (define slide ( $1 (while empty? add $1 ) (verify not-friend?) add )) 


أولاً ، يتم تنفيذ الإزاحة بواسطة خلية واحدة ، في الاتجاه المحدد ، ثم يتم التحقق من الفراغ الذي تم الوصول إليه في دورة ما من عدم وجود القطع الموجودة عليه ، ويتم تشكيل حركة ، ويتواصل الترتيب إلى خلية أخرى في نفس الاتجاه. إذا توقفت هنا ، يمكن للقطعة أن "تنزلق" من خلال خلايا فارغة ، ولكن كيف يمكنك أن تأخذ قطع العدو؟

بسيط جدا بعد تشغيل الأمر للتحقق ، والتحقق من أن الحقل غير مشغول بقطعة مألوفة ، فإننا نشكل أمر إضافة آخر ، مع استكمال الحركة. إذا كانت هذه الخلية موجودة على قطعة معادية ، فسيتم التقاطها تلقائيًا (كما في مساحة واحدة من اللوحة ، في وقت واحد ، لا يمكن أن يكون لديك أكثر من قطعة واحدة). إذا كانت القطعة سهلة ، فسيتم إحباط حساب النقل مع التحقق من الأمر (ينتهك انتهاك الشروط المحددة في هذا الأمر على الفور حساب الحركة الحالية).

n يمكن لكل من ZoG و Axiom تحريك القطع الخاصة بهما فقط (أو بالأحرى ، يمكن تحريك قطع الخصم ، ولكن فقط إذا تم تحديد ذلك في طريقة حساب حركة واحدة من القطع الفردية). أجد أن هذا التقييد غير مريح للغاية ، لأن هناك العديد من الألعاب التي يمكنك من خلالها تحريك قطعة الخصم مباشرة (في " Stavropol Checkers " ، على سبيل المثال). سيكون أكثر اتساقًا لإجراء حساب النقل لجميع القطع ، بغض النظر عن انتمائها. في الماكرو الذي يحدد الخطوة ، يحتاج المرء فقط إلى إضافة فحص واحد للسماح بنقل القطع الخاصة به فقط:

 (define slide ( (verify friend?) $1 (while empty? add $1 ) (verify not-friend?) add )) 


المهم هو القدرة على تنفيذ خطوة تتكون من عدة تحركات "جزئية". في عمليات تنفيذ المسودات ، يتم استخدام هذه القدرة لأداء التقاطات "سلسلة":

 (define checker-jump ($1 (verify enemy?) capture $1 (verify empty?) (if (not-in-zone? promotion-zone) (add-partial jumptype) else (add-partial King jumptype) ) ) ) 


يتم تكوين أمر النقل الجزئي بجزء إضافي (لهذا الأمر ، وكذلك لإضافة الأمر ، هناك تنوع في الحركة ، مع "تحويل" القطع). مثل هذه الخطوة هي دائمًا جزء من حركة أكبر "مركبة". كقاعدة عامة ، بالنسبة للتحركات اللاحقة ، يتم تعيين "الوضع" ، والذي يجب أن يستمر التنفيذ. لذلك ، في لعبة الداما ، يمكن أن يستمر الالتقاط فقط بالتقاطات التالية ولكن ليس بحركة "ناعمة" (غير أسر).

مذكرة
في ZoG ، يكون تنفيذ الحركات الجزئية ضعيفًا. محاولة تنفيذ الأمر الوظيفة الإضافية في دورة تسبب خطأ. نتيجة لذلك ، لا يمكن تحقيق الالتقاط الذي قام به ملك المدقق إلا بالطريقة التالية غير المألوفة للغاية:

 (define king-jump-1 ($1 (while empty? $1 ) (verify enemy?) capture $1 (verify empty?) (add-partial jumptype) ) ) (define king-jump-2 ($1 (while empty? $1 ) (verify enemy?) capture $1 (verify empty?) $1 (verify empty?) (add-partial jumptype) ) ) 

وهكذا ، حتى king-jump-7! واسمحوا لي أن أذكرك بأنه في معظم أصناف لعبة الداما ذات الملك "بعيد المدى" ، يمكن للملك ، بعد كل لقطة ، أن يتوقف عند أي مساحة لسلسلة مستمرة من المساحات الفارغة بعد القطعة الملتقطة. هناك ، بالمناسبة ، متغير واحد من هذه اللعبة يتم فيها صياغة قاعدة "السلسلة" بشكل مختلف. هذا هو ما يعجبني في لعبة الداما - حيث يمكن للجميع العثور على شكل يرضي المرء.

نظام وصف القواعد هذا مرن للغاية ، لكن في بعض الأحيان يكون المنطق الأكثر تعقيدًا مطلوبًا. على سبيل المثال ، إذا لم يتم إعادة تمرير القطعة ، خلال التقدم "الجزئي" عبر حقل تم اجتيازه مسبقًا ، فمن المنطقي استخدام الإشارات المرتبطة بالمواقع على اللوحة. بعد زيارة مسافة ، وضعنا علامة ، وبالتالي لا نذهب إلى هذه المساحة مرة أخرى:

 (verify (not-position-flag? my-flag)) (set-position-flag my-flag true) 

بالإضافة إلى العلامات "الموضعية" ، في ZoG ، يمكنك استخدام الأعلام العالمية. لا ينبغي الخلط بين هذه القدرات وسمات القطع. على عكس الأخير ، هذه ليست جزءًا من حالة اللعبة. لسوء الحظ ، يمكن أن تكون كل من سمات القطع والأعلام في ZoG منطقية فقط (في سمات Axiom غير مدعومة). هذا القيد يجعل من الصعب إجراء العمليات المرتبطة بأنواع مختلفة من العد. على سبيل المثال ، في هذا اللغز الصغير ، اضطررت إلى استخدام "عدّ القطع" ، التي تم صيدها في "شوكة" ، زوج من الأعلام المنطقية (العدد الدقيق الذي لم أحتاج إليه ، طالما كانت القطع أكثر من واحدة).

شيء آخر لإصلاح هو عدم وجود "دورة حياة" واضحة في تنفيذ هذه الخطوة. تتم إعادة تعيين جميع العلامات تلقائيًا قبل بدء الحركة ، ولكن سيكون من الأسهل تحديد مرحلة التهيئة بوضوح. في رأيي ، عند حساب الحركة ، يجب أن تحدث المراحل التالية:

  1. تهيئة المتغيرات والتحقق من الشروط المسبقة للحركة المركبة
  2. تهيئة المتغيرات والتحقق من الشروط المسبقة لهذه الخطوة الجزئية
  3. جيل من التحرك الجزئي
  4. التحقق من الشروط البريدية للحركة الجزئية
  5. إنشاء ، إكمال ، والتحقق من postconditions الحركة المركبة
  6. التحقق من شروط إنهاء اللعبة

يمكن تكرار مجموعة الخطوات من الثانية إلى الرابعة ، في الحركة المركبة الكاملة ، عدة مرات. فكرة ما قبل وما بعد الظروف ، والتي أسميها المتحولين ، أخذت من مشروع Ludi. اقول لكم المزيد عن استخدام المتغيرات في وقت لاحق.

على أهمية التدوين


جيل جميع الحركات الممكنة من الموقف هو نصف القصة فقط. للسيطرة على حالة اللعبة يتطلب عرضا مضغوطا من التحركات ولدت. في ZoG ، لهذا الغرض ، يتم استخدام تدوين ZSG. فيما يلي سرد ​​لبداية محتملة للعبة الشطرنج بهذا الشكل:

 1. Pawn e2 - e4 1. Pawn e7 - e5 2. Knight g1 - f3 2. Knight b8 - c6 3. Bishop f1 - c4 3. Knight g8 - f6 4. King e1 - g1 Rook h1 - f1 @ f1 0 0 @ g1 0 0 4. Pawn d7 - d5 5. Pawn e4 x d5 5. Knight f6 x d5 

هذا البرنامج النصي قريب من تدوين الشطرنج المعتاد وسهل الاستخدام بشكل عام. الخطوة الرابعة البيضاء فقط قد تسبب بعض الالتباس. لذلك في ZSG يبدو مثل القلعة . جزء وصف الخطوة قبل الحرف "@" واضح تمامًا ؛ إنها الحركة المتزامنة للرخ والملك ، ولكن ماذا بعد؟ وبالتالي ، في ZSG ، يبدو أن إعادة تعيين سمات القطع مطلوبة من أجل منع احتمال تكرار القلاع.

مذكرة
يستخدم ZoG ترميز ZSG الخاص به بشكل خاص من أجل إظهار مسار اللعبة بشكل يمكن فهمه للاعب. على يمين اللوحة ، قد يتم فتح نافذة فرعية "Moves List". يمكن استخدام هذه القائمة للتنقل خلال اللعبة المسجلة. هذه القائمة ليست مريحة للغاية ، نظرًا لأن طريقة العرض المتفرعة للألعاب البديلة غير مدعومة. لا يتم عرض جزء المنعطفات المسجلة المرتبطة بالتغييرات في سمات القطع للمستخدم.

يجب أن يحتوي تسجيل أي خطوة في ZSG-notation على معلومات كاملة كافية لتغيير حالة اللعبة بشكل صحيح. إذا فقدت معلومات حول تغيير السمات ، في إحدى الألعاب وفقًا لهذا السجل ، فقد تتكرر هذه الخطوة بشكل غير صحيح (على سبيل المثال ، ستتاح للاعب الفرصة لإعادة تنفيذ اللعبة). لسوء الحظ ، في DLL ملحقات (مثل اكسيوم) ، لا يمكن أن تنتقل المعلومات الموسعة.

عند العمل مع امتدادات DLL ، تضطر ZoG إلى التعامل مع الماكرة تمامًا عند تحديد موضع حركة محددة (على سبيل المثال ، عند استرجاع الخطوة). من [كل] موقع سابق [العمل من بداية اللعبة] ، يتم إنشاء جميع الحركات الممكنة ، وبعد ذلك ، داخل تلك القائمة ، يجب على المرء أن يبحث عن تحرك مع تمثيل [ZSG] المقابل. يتم تطبيق [الآثار الجانبية لكل حركة تم إنشاؤها] على [كل حالة لعبة متتالية] ، لأنه من الممكن إجراء آثار جانبية لا تنعكس في تمثيل ZSG لهذه الحركة.

يتفاقم الموقف من حقيقة أن الطريقة الوحيدة للوصول إلى حالة اللعبة في وقت التحرك في الماضي ، هو التطبيق الثابت لجميع التحركات من بداية اللعبة ، إلى الحالة الأولية للوحة. في الحالات المعقدة حقًا ، لا يحدث هذا النوع من التنقل بسرعة. يمكن توضيح عيب آخر من تدوين ZSG من خلال تسجيل الخطوة التالية في لعبة Go :

 1. White Stone G19 x A19 x B19 x C19 x D19 x E19 x F19 

هنا ، في الموضع G19 ، يتم وضع حجر أبيض يلتقط مجموعة من الحجارة السوداء. نظرًا لأنه يجب ذكر جميع القطع المشاركة في أداء الموضع في أداء ZSG ، فقد يبدو سجل المنعطف طويلًا جدًا (في Go ، قد تسقط قطرة واحدة ما يصل إلى 360 حجرًا). إلى ما قد يؤدي هذا ، كتبت في وقت سابق . قد لا يكون حجم المخزن المؤقت المخصص لتسجيل نقل ZoG كافيًا. علاوة على ذلك ، إذا تغير ترتيب إزالة الأحجار لسبب ما (في عملية تطوير اللعبة التي تحدث) ، فستفشل محاولة لتطبيق خطوة ، من ترتيب قديم من الالتقاطات.

لحسن الحظ ، هناك طريقة بسيطة للتعامل مع كل هذه المشاكل. دعونا نلقي نظرة على كيفية تحديد تحركات القطع في ZRF:

 (piece (name Pawn) (image White "images\Chess\SHaag\wpawn.bmp" "images\Chess\wpawn.bmp" Black "images\Chess\SHaag\bpawn.bmp" "images\Chess\bpawn.bmp") (moves (Pawn-capture nw) (Pawn-capture ne) (Pawn-move) (En-Passant e) (En-Passant w) ) ) 

لا يمكن الوصول إلى أسماء التحركات ، المعرّفة في وحدات ZoG ، كمولد للتحركات. ولكن ما الذي يمنعنا من التخلي عن وحدات الماكرو وعمل أوصاف للحركات بأسمائها؟ إليك كيف سيبحث السجل عن لعبة الشطرنج:

 1. e2 - e4 Pawn-move 1. e7 - e5 Pawn-move 2. g1 - f3 leap2 n nw 2. b8 - c6 leap2 n ne 3. f1 - c4 slide nw 3. g8 - f6 leap2 n nw 4. e1 - g1 OO 4. d7 - d5 Pawn-move 5. e4 x d5 Pawn-capture nw 5. f6 x d5 leap2 w nw 

مذكرة
قد يلاحظ القراء المخضرمون أنه في التحركات لـ "الأسود" استخدمت اتجاهات غير مناسبة للاتجاهات الفعلية على رقعة الشطرنج. هذا مرتبط بحقيقة أن "التماثلات" محددة باللون الأسود:

 (symmetry Black (ns)(sn) (nw sw)(sw nw) (ne se)(se ne)) 

بمعنى تقريبي ، إذن ، ما هو للأبيض هو "الشمال" ، أما الأسود فهو "الجنوب" ، والعكس بالعكس.

فوائد مثل هذا السجل ليست واضحة ، ولكن لديها ميزة واحدة مهمة. يتم وصف جميع الحركات بطريقة موحدة ولا تحتوي هذه الأوصاف على أي شيء إضافي (يمكن أن تكون أسماء أوصاف الحركات ، "بالطبع وصفية"). في وصف castling ، تمكن الشخص من التخلص من كل من تغييرات السمات ووصف تحرك rook (هذا الوصف لم يعد يعتمد على تفاصيل تنفيذ الخطوة). توجد فائدة أوضح لهذه السجلات في حالة لعبة Go:

 1. G19 drop-to-empty White Stone 

وهذا كل شيء! إذا تم أخذ أحجار الخصم وفقًا لقواعد اللعبة ، فليست هناك حاجة لسردها جميعًا في وصف الخطوة. يكفي الإشارة إلى المساحة الأولية والنهائية للتشريد (ربما مع وجود علامة للإشارة) ، واسم الحركة المنفذة وسلسلة المعلمات التي تم تمريرها إليها. بالطبع ، من أجل القيام بحركة وفقًا لهذا الوصف ، من أجل فك التشفير ، من الضروري الوصول إلى وحدة توليد الحركة ، لكن ZoG تفعل ذلك!

هناك احتمال آخر ، والذي يجب دعمه ، يظهر في وظيفة التحركات "الجزئية". فيما يلي مثال من " لعبة الداما الروسية ":

 1. Checker g3 - f4 1. Checker f6 - g5 2. Checker e3 - d4 2. partial 2 Checker g5 - e3 = XChecker on f4 2. Checker e3 - c5 = XChecker on d4 x d4 x f4 

هنا يأخذ السود ، في حركتهم الثانية ، قطعتين على d4 و f4. يعد "التحويل" الأولي لهذه القطع إلى XChecker أحد ميزات هذا التطبيق ويعمل على منع إعادة أخذ القطع "المهزومة" في نفس الخطوة. تصف العبارة "جزئي 2" بداية الدورة التدريبية "المركبة" ، والتي تتكون من حركتين "جزئية". هذا النوع من الوصف غير مريح ، لأنه في وقت إنشاء الحركة الأولى ، قد لا يكون طول تسلسل الحركات "الجزئية" معروفًا. إليك كيف سيبدو هذا الوصف بتنسيق جديد:

 1. g3 - f4 checker-shift nw 1. f6 - g5 checker-shift ne 2. e3 - d4 checker-shift nw 2. + g5 - e3 checker-jump nw 2. + e3 - c5 checker-jump sw 2. + 

تفاصيل التنفيذ المتعلقة بـ "تحويل" القطع غير مهمة. لا يتم تحديد التقاط القطع أيضًا ، كما هو الحال في لعبة الداما ، يحدث الالتقاط ك "تأثير جانبي" لحركة القطعة وليس وفقًا "لمبدأ الشطرنج". سيتم تشفير التقدم الجزئي بالرمز "+" في البداية من الخط. تشير الإشارة "+" المنفردة إلى إكمال "النقل المركب" (في الواقع ، هذه هي الخطوة "الجزئية" المعتادة ، التي تحتوي على خطوة مفقودة ، سلسلة فارغة).

وبالتالي ، باستخدام قواعد محددة لتنفيذ الحركات ، تمكن المرء من إنشاء ترميز عالمي ، يلبي متطلباتنا تمامًا. بالطبع ، لا علاقة له بالشطرنج القياسي أو بأي تدوينات أخرى ، لكن يحدث فقط أن الرموز التقليدية للشطرنج والداما وغيرها من الألعاب ، لا علاقة لها ببعضها البعض. يمكن لوحدة التصور دائمًا تحويل سجل النقل إلى نموذج مألوف مقبول في لعبة معينة. يمكن أن يكون التحويل أيضًا في شكل عالمي ، مثل SGF (تنسيق اللعبة الذكية) .

دورة حياة اللعبة


بالإضافة إلى معلومات حول وضع القطع على اللوحة ، فإن تسلسل الأدوار هو جزء متوافق من حالة اللعبة ، وهو متغير في عملية اللعبة. في أبسط الحالات (وأكثرها شيوعًا) ، يكفي لتخزين هذه المعلومات بت واحد ، لكن ZoG توفر فرصًا قليلة لتنفيذ حالات أكثر تعقيدًا. هنا هو كيف يمكن لسلسلة من التحركات أن تبحث عن لعبة Splut! :

 (players South West North East) (turn-order South West West repeat North North North East East East South South South West West West ) 

في هذه اللعبة ، يقوم كل لاعب بثلاث حركات في وقت واحد ، ولكن إذا كنت ستتيح للاعب الأول الفرصة للقيام بثلاث حركات من المركز الأولي ، فسيكون قادرًا على تدمير إحدى قطع الخصم ، مما يمنحه ميزة كبيرة. لهذا السبب ، يجب على اللاعب الأول القيام بخطوة واحدة فقط (يعطي فرصة للتحضير لمهاجمة لاعب معارضة ، ولكن ليس لمهاجمته) ، والثاني - حركتان (هذا لا يكفي أيضًا لمهاجمة لاعب معارض) ، بعد الذي يقوم به كل لاعب دائما ثلاث خطوات.


يشير تكرار التسمية إلى بداية تسلسل التحركات الدورية. إذا لم يظهر ، فسيتم تكرار الوصف بالكامل دوريًا. ZoG لا يسمح باستخدام التسمية تكرار أكثر من مرة. ميزة أخرى مهمة هي تحديد ترتيب الدور. إليك كيف يمكن أن يبدو وصف لتسلسل المنعطفات في إحدى الألعاب التي يؤدي كل لاعب فيها منعطفين (الخطوة الأولى - القطع المتحركة ، والثانية - التقاط قطع المنافس):

 (players White Black) (turn-order (White normal-move) (White capture-move) (Black normal-move) (Black capture-move) ) 

هناك قدرة أخرى مرتبطة بوصف تحريك القطع الخاصة بشخص آخر ، لكن من غير المناسب للغاية استخدامها. المشكلة هي أن مثل هذا الوصف لا يوجد لديه بديل. إذا كان الوصف ينص على أن الخطوة يجب أن تتم بواسطة قطعة العدو ، يجب على اللاعب القيام بهذه الخطوة! في ZoG ، من المستحيل وصف خيار تحريك القطعة الخاصة به أو قطعة شخص آخر. إذا كانت هناك حاجة إلى مثل هذه الإمكانية في لعبة (مثل " Stavropol Chequers ") ، فمن الضروري جعل جميع القطع محايدة (إنشاء لهذا الغرض لاعب لا يشارك في اللعبة) وتحديد الفرصة لجميع اللاعبين لتحريك قطعة محايدة. لقد قلت أعلاه أنه من الأسهل كثيرًا بشكل افتراضي السماح لجميع اللاعبين بالقدرة على تحريك أي قطع (خاصة بهم وكذلك خصومهم) مضيفًا الفحوصات الضرورية في خوارزميات توليد الحركة.

كما ترون ، فإن مجموعة الخيارات التي يوفرها ZoG لوصف تسلسل الأدوار محدودة للغاية. تفشل اكسيوم أيضًا في إضافة ميزات جديدة ، لأنها (عادةً) تعمل على ZoG. لودي ، في هذا الصدد ، هو الأكثر فقراً. من أجل تعظيم توحيد قواعد اللعبة (مطلوب لإمكانية استخدام خوارزميات عامة) ، في هذا المشروع ، تم تبسيط جميع القدرات الوصفية عن عمد ، مما أدى إلى القضاء على طبقات كاملة من الألعاب.


" Bao Swahili " هو مثال جيد على لعبة ذات دورة حياة معقدة. في هذه اللعبة ، هناك مرحلتان مع قواعد لتنفيذ الحركة والتي تختلف اختلافًا كبيرًا. في بداية اللعبة ، جزء من الأحجار هو "في اليد "من كل لاعب. بينما لا تزال هناك أحجار" في متناول اليد "، توضع الحجارة في آبار ، حجر واحد في المرة الواحدة. عندما تنفد الأحجار ، تبدأ المرحلة الثانية من اللعبة ، مع توزيع المدخل لا يمكن للمرء أن يقول أن هذه اللعبة لا يمكن وصفها في ZRF (لغة وصف ZoG) ، ولكن بسبب قيود ZoG ، سيكون هذا التطبيق مربكًا للغاية (وهو بالتأكيد ليس أفضل بالنسبة لجودة عمل الذكاء الاصطناعى). دعونا نرى كيف سيبدو وصف هذه اللعبة في "عالم مثالي":

 (players South North) (turn-order (turn-order (South pi-move) (North pi-move) ) (label phase-ii) (turn-order (South p-ii-move) (North p-ii-move) ) ) 

هنا ، تحدد كل قائمة أوامر تسليم تسلسل متكرر من الحركات (تميز نفسها حسب طريقة تنفيذ النقل). تحدد تسمية الكلمات الرئيسية تسمية يمكن إجراء انتقال إليها أثناء إنشاء آخر خطوة. قد تلاحظ أننا ننتقل هنا من الافتراض الضمني بأن مثل هذا الانتقال يحدث دائمًا بعد انتقال اللاعب الثاني (وإلا فإنه ينتهك تسلسل التحركات). كيفية الانتقال إلى المرحلة التالية في وقت تعسفي؟

 (players South North) (turn-order (turn-order (South pi-move) (North pi-move) ) (turn-order (labels - phase-ii) (South p-ii-move) (labels phase-ii -) (North p-ii-move) ) ) 

هنا ، يتم تنفيذ الملصقات في جسم الحلقة وتتضمن اسمين. تظهر أسماء الملصقات في قوائم التسميات بترتيب نقل اللاعبين في قائمة اللاعبين. يتم تحديد الاسم المستخدم لعملية الانتقال عن طريق اللاعب الذي قام بالخطوة الأخيرة. إذا كان هذا هو الشمال ، فسوف ينتقل إلى الملصق الأول ، وإلا ، إلى الثاني. إذا لم يتم استخدام أي من الأسماء في التسميات ، فيمكن ملء الموضع المقابل بواسطة شرطة.


جانب مهم في إدارة الحركات بالتناوب ، هو القدرة على أداء منعطف متكرر. في ألعاب عائلة Tables ، مثل Nard ، أو Backgammon ، أو Ur ، على سبيل المثال ، تعد القدرة على أداء المنعطفات المتكررة عنصرا هاما في تكتيكات اللعبة. في ZoG ، يمكن للمرء استخدام تمرير دور لمضاهاة هذه الميزة ، ولكن هذا النهج يعقد بشكل كبير وصف اللعبة (خاصة مع المزيد من اللاعبين). سيكون من المنطقي استخدام تسمية لتكرار منعطف:

 (players South North) (turn-order (label repeat) South (label repeat) North ) 

بعد أن قفزت اللعبة إلى تكرار التسمية ، سيلعب اللاعب دوره مرة أخرى (ستصبح التسمية الأقرب إلى الموضع الحالي في قائمة المنعطفات سارية المفعول). أحب نهج بيرل في تعريفاته الضمنية. يمكن للجيل الضمني من هياكل التحكم تبسيط وصف اللعبة بشكل كبير. نظرًا لأنه يمكن استخدام التحركات المتكررة في العديد من الألعاب ، تتكرر التسميات ، متوقعًا أن التكرار المحتمل لأي منعطف قد يكون ضمنيًا:

 (players South North) (turn-order South North ) 

علاوة على ذلك ، نظرًا لأن تسلسل المنعطفات يتوافق تمامًا مع الترتيب المكتوب للاعبين في بنية اللاعبين ، يمكنك إنشاء جملة ترتيب الدور بأكملها تلقائيًا:

 (players South North) 

كلما كان الوصف أسهل في الكتابة ، كان ذلك أفضل.

ثابت قابل للكسر


يمكن التعبير عن الشيء الرئيسي الذي لا يعجبني في ZoG بكلمة واحدة - كشيك. للوهلة الأولى ، إنها مجرد حالة (شائعة جدًا في ألعاب عائلة الشطرنج ) تربط نهاية اللعبة بتشكيل وضع رفيق. للأسف ، عند الفحص الدقيق ، تظهر البساطة على أنها خادعة. لا يعني استخدام هذه الكلمة الرئيسية فقط ، بعد كل خطوة ، إجراء فحص لاستكمال اللعبة ، ولكن أيضًا يفرض على اللاعب "سلوك" معين.


من لعبة Shogi المعتادة ، تختلف هذه اللعبة فقط في عدد اللاعبين. لسوء الحظ ، هذا الاختلاف يكفي لجعل مهمة تحديد كشمير (وكل ما يرتبط بهذه الكلمة "السحرية") غير صحيح. يتم التحقق من أن يكون قيد الفحص فقط فيما يتعلق بأحد اللاعبين. نتيجة لذلك ، قد يتعرض الملك للهجوم ، ويؤكل [بمزيج من تحولات الخصوم حتى عند عدم تركهم "قيد الفحص"]! أن هذا ليس الأمثل سينعكس في عمل منظمة العفو الدولية.

إذا كانت هذه المشكلة تبدو غير مهمة ، فمن الجدير بالذكر أن الائتلافات تتشكل عادةً في ألعاب أربعة لاعبين "زوج مقابل زوج". في حالة تشكيل الائتلافات ، يجب أن نعتبر أن القطع الصديقة للملك لا تهدده! لذلك ، على سبيل المثال ، قد يقيم ملوك ودودان على المساحات المجاورة للوحة.


يصبح الأمر أكثر تعقيدًا من أي وقت مضى إذا كان للاعب عدة ملوك. في " شطرنج تامرلين " ، يتحول البيدق الملكي إلى أمير (في الواقع ، ملك ثان). إذا حدث هذا ، يمكنك الفوز فقط عن طريق الاستيلاء على الملك الأول (أي من الاثنين) ، وتزاوج الثاني. في هذه اللعبة ، يمكنك الحصول على ملك ثالث ، وهو ضعف الإنفاق على تحول "بيدق البيادق"! القدرات التعبيرية لـ "checkmated" ليست كافية لوصف هذا الموقف بشكل مناسب.

صعوبة أخرى قد تكون عملية إعطاء رفيقه. لذلك في لعبة الشطرنج المنغولية ( Shatar ) ، تعتمد نتيجة محاولة رفيقه على الترتيب الذي يتم به تنفيذ "الشيكات" المتسلسلة. يمكن أن تكون النتيجة إما الفوز أو السحب (مثل رفيقة بيدق) ، أو حتى هزيمة (رفيق الخيل محظور ، لكن يمكنك إعطاء شيك). أقل غرابة بقليل ، في هذا الصدد ، هو Shogi اليابانية. في هذه اللعبة ، يُمنع إعطاء رفيق مع بيدق إسقاط ، ولكن يمكنك التحقق من بيدق إسقاط وإعطاء رفيق الشيك مع بيدق متحرك.

مذكرة
هناك نقطة واحدة أكثر أهمية تستحق الذكر. في بعض الألعاب ، مثل Rhythmomagic ، يمكن أن يكون هناك عدة طرق مختلفة لإنهاء اللعبة. الطريقة الأكثر وضوحا للفوز ، والتي تنطوي على تدمير قطع الخصم ، هي أيضا الأقل تفضيلا. لتحقيق انتصار أكبر ، يجب على المرء أن يرتب قطعًا على أرض العدو بنمط معين.

ينبغي التمييز بين أنواع الانتصارات (والهزائم والسحوبات) على مستوى وصف اللعبة ، لأن نوع انتهاء اللعبة قد يكون مهمًا للاعب. بالإضافة إلى ذلك ، يجب أن يكون من الممكن تعيين الأولويات العددية لنهايات اللعبة المختلفة. عند الإكمال المتزامن لشروط الإنجاز المتعددة ، يجب مراعاة الشرط الذي له الأولوية القصوى.

من الواضح ، يجب على المرء أن يفصل منطق التحقق من نهاية اللعبة عن الاختبار لأن الملك قد وقع تحت المراقبة ، وهي قاعدة ثابتة يتم فحصها بعد كل منعطف. انتهاك القاعدة يجعل من المستحيل القيام بهذه الخطوة (تتم إزالة الخطوة من قائمة التحركات المتاحة). لذلك قد يبدو الاختبار (المبسَّط) لكون الملك قيد الفحص كما لو كان "لعبة شطرنج تامرلان":

 (verify (or (> (count (pieces my? (is-piece? King))) 1) (= (count (pieces my? (is-piece? King) is-attacked?)) 0) ) ) 

من المهم أن نفهم أن هذا الاختبار يجب أن يتم فقط لملوك الفرد (لقد استخدمت المسند الخاص بي؟ لأن الصديق الأصلي ؟، بدعم من الائتلافات ، لن يكون راضيا عن القطع الخاصة به ، ولكن أيضا عن قطع من جميع اللاعبين الودودين). المقبول (والمرغوب فيه ، [إذا كان هناك ملوك ودودون متعددون]) هو الوضع الذي يخضع فيه ملك العدو للمراقبة ، بعد خطوة ، ولكن من جانب ملك المرء. يجب أن يكون هذا الموقف مستحيلاً [ما لم يكن هناك ملوك ودودون متعددون]! بعد تقديم الدعم للتحقق من هذه القواعد ، يصبح التحقق من إكمال اللعبة من قِبل checkm تافهاً. إذا لم تكن هناك تحركات محتملة وكان الملك [الوحيد] قيد الفحص ، فقد انتهت اللعبة [إذا كان هذا الملك ينتمي إلى آخر لاعب على قيد الحياة في آخر تحالف على قيد الحياة]:

 (loss-condition (and (= (count moves) 0) (= (count (pieces my? (is-piece? King)) 1) (> (count (pieces my? (is-piece? King) is-attacked?)) 0) ) ) 

ستكون القدرة على تحديد الثوابت مفيدة في الألعاب الأخرى ، مثل لعبة الداما . ترتبط الصعوبة الأكبر في تنفيذ ألعاب هذه العائلة بتنفيذ "حكم الأغلبية". في جميع ألعاب المسودات تقريبًا ، يكون الالتقاط إلزاميًا. أيضًا ، في معظم ألعاب هذه العائلة ، هناك إتمام مميز لـ "التقاطات المتسلسلة" في منعطف واحد. يستمر المدقق ، بعد التقاطه ، في أخذ قطع أخرى ، إن أمكن. في معظم الألعاب ، يتعين على اللاعب تنفيذ سلسلة من الألعاب حتى النهاية ، ولكن هناك استثناءات لهذه القاعدة ، على سبيل المثال ، Fanorona .


باستخدام آلية التحركات الجزئية ، يعد تطبيق "التقاط سلسلة" أمرًا بسيطًا للغاية. تنشأ الصعوبات عندما ، بالإضافة إلى ذلك ، يفرض الشرط الذي بموجبه ، من بين جميع الخيارات الممكنة ، يجب على المرء اختيار سلسلة يتم فيها التقاط أكبر عدد ممكن من القطع. في ZoG ، يجب تنفيذ هذا المنطق من نقطة الصفر على مستوى "القرص الصلب":

 (option "maximal captures" true) 

هذا الإعداد مناسب لـ " لعبة الداما الدولية " ، ولكن في " لعبة الداما الإيطالية " ، يتم صياغة قاعدة الأغلبية بشكل مختلف. في هذا الإصدار من اللعبة ، إذا كان هناك العديد من الخيارات لنفس عدد عمليات الالتقاط ، فيجب عليك تحديد خيار يلتقط أكبر عدد من لعبة الداما المحولة (الملوك). قدم مطورو ZoG هذا. قمت بإدخال الإعداد التالي:

 (option "maximal captures" 2) 

في هذا الإعداد ، لا يحسب المرء فقط عدد القطع التي تم التقاطها ، ولكن أيضًا نوعها. لسوء الحظ ، لا يمكن توقع كل شيء. إليك كيفية صياغة "قاعدة الأغلبية" في "لعبة الداما الفرنسية القديمة":

إذا كان من الممكن من خلال سلسلة من الالتقاط التقاط نفس العدد من لعبة الداما مع رجل بسيط أو مع ملك ، يجب على اللاعب استخدام الملك. ومع ذلك ، إذا كان عدد لعبة الداما هو نفسه في كلتا الحالتين ، ولكن في حالة واحدة يوجد ملك عدو (أو هناك المزيد) ، يجب على اللاعب اختيار هذا الخيار ، حتى لو تم الالتقاط باستخدام المدقق البسيط ، وليس باستخدام الملك.

بالطبع ، في الوقت الحالي ، لا يوجد أحد تقريبًا يلعب هذا الإصدار من لعبة الداما ، ولكن وجوده يدل بوضوح على أوجه القصور في التنفيذ "الثابت". يتيح استخدام آلية المتغيرين لجميع الخيارات الممكنة لـ "قاعدة الأغلبية" بطريقة شاملة. بالنسبة لتطبيق " لعبة الداما الفرنسية القديمة " ، سيكون التنفيذ كما يلي:

 (verify (>= capturing-count max-capturing-count) ) (if (> capturing-count max-capturing-count) (let max-capturing-count capturing-count) (let max-capturing-sum capturing-sum) (let max-attacking-value attacking-value) ) (verify (>= capturing-sum max-capturing-sum) ) (if (> capturing-sum max-capturing-sum) (let max-capturing-sum capturing-sum) (let max-attacking-value attacking-value) ) (verify (>= attacking-value max-attacking-value) ) (let max-attacking-value attacking-value) 

هنا ، نفترض أن قواعد إنشاء الالتقاط تملأ المتغيرات المحلية التالية بشكل صحيح:

  • التقاط العد - مجموع القطع التي تم التقاطها
  • أسر - مجموع الملوك القبض
  • قيمة الهجوم - قيمة التقاط قطعة

يرتبط كل من هذه المتغيرات بتراكم القيمة ، المخزن في متغير مع بادئة كحد أقصى. يتم تنفيذ الشيكات الثلاثة بشكل تسلسلي. يخرق أي من شروط التحقق على الفور إنشاء خيار المنعطف التالي (لا يتم تخزين الالتقاط في قائمة المنعطفات المحتملة). نظرًا لأن الاختبارات التي يتم إجراؤها مرتبطة بقيم متغيرة ، فإنه لا يكفي [لاختبار خيار الالتقاط الجديد الحالي فقط]. يولِّد كل اختبار "قاعدة قابلة للانحناء" مرتبطة بالالتقاط الناتج [والذي قد يراجع القيمة القصوى المتراكمة]. بعد كل تغيير في أي تراكم ، يجب التحقق من جميع القواعد المرتبطة مرة أخرى [لكل خيار في القائمة]. في حالة انتهاك أي من الشروط الخاصة بخيار تم إنشاؤه مسبقًا ، يجب إزالة هذا الخيار من قائمة خيارات الدوران المحتملة.

استنتاج


هذه هي ترجمة مقالتي لعام 2014 العام. منذ ذلك الحين ، أعدت التفكير كثيرًا وأصبح مشروع داغاز حقيقة واقعة ، لكنني لم أغير شيئًا تقريبًا في النص. ترجم هذا المقال صديقي هوارد مكاي وأنا ممتن له على العمل المنجز.

Source: https://habr.com/ru/post/ar481868/


All Articles