
لا تزال لقطة شاشة من لعبة الفلاش نفسها ترحب بك في toox.com/jeux/jeux-de-cartes/coinche
بيان المشكلة وأهميتها
Quosh و Belote و Tarot هي ألعاب فرنسية وطنية. وفقًا للقواعد ، هذا يشبه تقريبًا لعب التفضيل في لعبة مغلقة ، ويتم لعب زوج من أجل زوج ، لذلك من خلال عدد الرشاوى وعلى أي ورقة رابحة يقترحها شريكك للإعلان عن اللعبة أثناء المساومة ، يمكنك فهم نوع البطاقات التي لديه تقريبًا. اللعبة طويلة ووجود ذكاء اصطناعي قادر على إنهاء اللعبة بطريقة ما هو أمر حيوي ، لأن أحد اللاعبين يمكنه ببساطة مغادرة الطاولة ليقرر أنه يخسر بشكل ميؤوس منه ، ويريد الفائز بطبيعة الحال دفعه إلى النتيجة النهائية على لوحة النتائج. في هذه الحالة ، سينهي الذكاء الاصطناعي اللعبة للاعب المفقود. ولكن نظرًا لأننا نمتلك الذكاء الاصطناعي ، فلماذا لا نسمح لنا ببدء اللعبة عن طريق إزعاج AI-shki في المساحات الفارغة. لذلك أطلقنا هذه الألعاب الرائعة للجماهير واكتشفنا بسرعة أن هناك خيارين أساسيين للطريقة التي يحب الفرنسيون اللعب بها.ما يقرب من نصف جميع الطاولات تنتظر أن تمتلئ بأشخاص أحياء حتى النصر ، ويأتي نصفها في الأسفل ويبدأ اللعبة ضد ثلاثة ذكاء اصطناعي ، كما في لقطة الشاشة أعلاه.
من حيث المبدأ ، نظرًا لأن اللعبة مغلقة ، فإن الناس على استعداد لمسامحة الروبوتات لسوء التقدير الطفيف والموهبة البديلة. في الأساس لأن بطاقات الروبوت لا يمكن رؤيتها. "تحت المشغل مع simak" ، "تحت المشهد مع الآس" والقواعد البسيطة المماثلة التي هزتها من عميلنا الفرنسي سمحت لنا بعمل الحد الأدنى المقبول للرامي. كان nafigched في غضون أسبوع على الفور. من ناحية أخرى ، يتم لعب اللعبة "اثنان مقابل اثنين" ، ويتم احتساب النقاط للزوج ، وبطبيعة الحال تمامًا لا يريد اللاعب أن يدخل شريكه الغبي "من الملك الثاني" ، أي وجود ملك في يديه وبعض البطاقات الصغيرة الأخرى ، يقوم بالانتقال إلى هذه البدلة ، بدلاً من السماح للخصم بلعب الآس ، والسماح لها بالمرور ببطاقة صغيرة واتخاذ الخطوة التالية في هذه الدعوى مع ملكه. (في الواقع ، ثاني أقدم بطاقة في هذه الألعاب هي 10 ،لكن فيما بعد سأتحدث باللغة الروسية). ولكن إذا ترك الآس اللعبة لسبب ما ، وكان لديك ملكة وشيء آخر صغير ، فهذا يشبه الملك الثاني تقريبًا. خاصة إذا طلبت مسبقًا الأوراق الرابحة. وأنت ، على سبيل المثال ، لا تلعب Belote ، حيث يتم استخدام 32 بطاقة ، ولكن Tarot ، حيث يتم لعب اللعبة بمجموعة من 78 بطاقة (نفس البطاقة التي يخمنها بعض الأشخاص). وهناك ، في بعض الحالات ، لا يمكن حتى للملكة الثالثة ، ولكن جاك الرابع ، أن تلتقط الرشوة. بشكل عام ، كل هذا يؤدي إلى مثل هذا العدد من الحالات الجانبية التي تصبح فيها دمية غبية على ifs معقدة بشكل غير مقبول تمامًا. وعند هذه النقطة قلت: "باه! لقد قرأت كثيراعلى سبيل المثال ، لا تلعب Belote ، حيث يتم استخدام 32 بطاقة ، ولكن Tarot ، حيث يتم لعب اللعبة بمجموعة من 78 بطاقة (نفس البطاقة التي يخمنها بعض الأشخاص). وهناك ، في بعض الحالات ، لا يمكن حتى للملكة الثالثة ، ولكن جاك الرابع ، أخذ الرشوة. بشكل عام ، كل هذا يؤدي إلى مثل هذا العدد من الحالات الجانبية التي تصبح فيها دمية غبية على ifs معقدة بشكل غير مقبول تمامًا. وعند هذه النقطة قلت: "باه! لقد قرأت كثيراعلى سبيل المثال ، لا تلعب Belote ، حيث يتم استخدام 32 بطاقة ، ولكن Tarot ، حيث يتم لعب اللعبة بمجموعة من 78 بطاقة (نفس البطاقة التي يخمنها بعض الأشخاص). وهناك ، في بعض الحالات ، لا يمكن حتى للملكة الثالثة ، ولكن جاك الرابع ، أخذ الرشوة. بشكل عام ، كل هذا يؤدي إلى مثل هذا العدد من الحالات الجانبية التي تصبح فيها دمية غبية على ifs معقدة بشكل غير مقبول تمامًا. وعند هذه النقطة قلت: "باه! لقد قرأت كثيراباختصار ومبهر! " ثم هربت من المكتب لبضعة أيام ، وجلست مع جهاز كمبيوتر محمول في أحد المقاهي ، وبعد بضعة أيام ظهر شيئًا ما.
الأفكار الرئيسية
ما هو Prolog على أساس إعلاني؟ على الحقائق ، على سبيل المثال:
('', '').
('', '').
وبشروط أو قواعد ، على سبيل المثال ، إذا كانت أ هي الأم ب ، فإن أ هي فتاة:
() :- (, ).
بالطبع ، أنا أفهم أنه في عصرنا ليس كل شيء بهذه البساطة ، وبشكل عام من غير اللائق قول هذا ، لكن في الأيام التي كان الناس يؤمنون فيها بالمنطق الرسمي ، لم يكن هناك شيء يستحق الشجب في مثل هذه الأمثلة. دعنا نقول للتسامح:
(A, B) :- (A, B).
(, ) :- (, ), (, ).
ثم تسألني هكذا:
?- (X, '')
والمقدمة المنطقية الرهيبة تجيب عليك:
X = ''
X = ''
كانت الفكرة ألا يسخن المستخدم رأسه بالترتيب الذي وبأي كمية سيطبق نظام المقدمة القواعد على الحقائق للوصول إلى إجابة. لكن ، بالطبع ، الأمر ليس بهذه البساطة. المقدمة ممتلئة بالعكازات والإضافات الوظيفية وقواطع من مختلف فروع التفكير وما شابه ، ولا تزال تهرب بشكل منتظم إلى عودية لا نهائية.
في كتاب براتكو الملهم للغاية ، تم تخصيص فصل كامل لكيفية تحقيق آلة المقدمة في الداخل. باختصار ، يمر عبر شجرة جميع القواعد بعمق ، محاولًا تطبيق كل قاعدة بدورها على مجموعة كل الحقائق والمتغيرات المعروفة لها للحصول على حالة جديدة ، وإذا تعذر تطبيق القاعدة ، فإنها تعود إلى الخطوة السابقة وتحاول تجربة خيار آخر.
علاوة على ذلك ، إذا تمكنت من تجميع شيء مفيد معًا ، فإن الجهاز يأخذ قائمة القواعد ويبدأ في البحث عن القواعد التي سيتم تطبيقها في الخطوة التالية من بداية القائمة. علاوة على ذلك ، إذا حدث متغير في القواعد ، يتذكر الجهاز أي حالات من هذه المتغيرات ، مع مراعاة القواعد المطبقة بالفعل ، يمكن أن تكون. وهذا ما يسمى التفتيت. إذا كان بإمكانه العثور على مثيل للمتغيرات التي تجعل السؤال صحيحًا ، فإنه يطبع هذا إنشاء مثيل. ثم يمكنها البحث عن الخرسانة التالية وما إلى ذلك. في المثال المصطنع أعلاه ، وجد النظام اثنين من الخرسانة التي تفي بالشروط.
أود أن أصيغ قواعد اللعبة بطريقة ما بطريقة مماثلة ، لكن بالطبع ليس حرفياً. لدي بعض الخبرة في برامج تصحيح الأخطاء في Prolog ، لم أكن حريصًا على الإطلاق على مواجهة هذا التصحيح وهذه التكاليف العامة على منتجي.
أولاً ، يجب ألا يعمل كل هذا على مجموعة من الحقائق المتناثرة ، ولكن على شجرة حالة اللعبة - نموذج وتطبيق نتائج عملها على نفس الشجرة أيضًا. ثانيًا ، أريد أن أكتب القواعد بحيث تكون قيمة محددة ومتغيرًا وتعبيرًا حسابيًا في نفس الموضع ، ويجب على النظام التعامل مع هذا وفقًا لذلك دون طرح أسئلة إضافية على المبرمج ودون الحاجة إلى بناء جملة إضافي. ثالثًا ، بالطبع ، من المهم للغاية التخلي عن التكرار اللانهائي ، ولكن لا يزال يتعين ترك بعض التكرار لتطبيق القواعد. رابعًا ، يجب كتابة نظام القواعد بصيغة مريحة للغاية يسهل قراءتها من قبل الإنسان ، بحيث يكون من الواضح للوهلة الأولى ما يريد المؤلف قوله. وأخيرا ، خامسا ،كل هذا يحتاج إلى ثمل في بعض أدوات التسجيل وتصحيح الأخطاء المريحة بحيث يكون من السهل اتباع أسباب هذا النظام وفهم سبب عدم عمل قواعد معينة على عكس التوقعات.
هذا ، بالطبع ، ليس حلاً منطقيًا عالميًا من الدرجة الأولى ، ولكنه مجرد نظام إعلاني مناسب لقواعد اللعبة. وهو أيضًا جيد جدًا من الناحية العملية. لهذا توصلت إلى اسم Logrus لاحقًا في أحد المشاريع التالية. سأصف الإصدار النهائي مرة واحدة ، متجاوزًا جميع المراحل الوسيطة لتطوير المحرك.
الصيغة الناتجة لمكتبة Logrus
سيكون هناك الكثير من بناء الجملة.
1) في وقت التشغيل ، يتم تخزين شجرة القرار في شكل بعض الفئات ، ولكن أول شيء أرفقته بها ، بمجرد نجاحها ، كان الاستيراد والتصدير في JSON. اتضح أنه مناسب أيضًا لأنه إذا لم تتغير بنية البيانات كثيرًا ، يمكنك تحديث القواعد من الملف دون إعادة الترجمة. تبين أن الكتابة في شكل JSON كانت مريحة للغاية لدرجة أنه في أحد المشاريع التالية ، عندما كان المبرمجون في عجلة من أمرهم ، في بعض الأحيان بدلاً من كتابة أمر عادي ، فعلوا ببساطة
state.AplayJSON("...");وفيه تم إدراج الإجراء المطلوب كسلسلة JSON. هذا ، بالطبع ، لم يؤثر على الأداء بشكل جيد للغاية ، ولكن إن لم يكن بشكل منتظم واستجابةً لنقرات المستخدم فقط ، فهذا ليس مخيفًا ... كل ما تبقى سأوضحه على الفور باستخدام JSON. أنا أعيد إنتاج JSONs تقريبًا من الذاكرة ، لأنها كانت فترة طويلة من الجحيم. بالمعنى الدقيق للكلمة ، لا تضمن JSON ترتيب العقد في الكائن ، لكن معظم المكتبات لا تزال تحترمه ، وهنا يتم استخدام ترتيب العقد بنشاط.
2) أصبحت القاعدة هي الوحدة الهيكلية الرئيسية للمحرك. تتكون القاعدة من شرط وإجراء. عادة تأتي القواعد في المصفوفات ويتم تطبيقها واحدة تلو الأخرى في كل مرة:
[{"condition":{}, "action":{}},
{"condition":{}, "action":{}}]
3) تحتوي كل قاعدة على شرط - هذا قالب شجرة ، ربما يحتوي على متغيرات. سيبحث النظام لمعرفة ما إذا كانت شجرة الحالة تطابق قالب أي قيم للمتغيرات. وإذا وجدت مثل هذا التجسيد ، فسيؤدي إلى اتخاذ إجراء. على سبيل المثال:
{"condition":{
"player":{
"$X":{"gold" : "<20", "name":"$NAME"}
}},
"action":{}}
سيعني مثل هذا البناء أنه من أجل إطلاق إجراء في الشجرة ، يجب أن تكون هناك عقدة "لاعب" في المستوى الأعلى فيها واحدة أو عدة عقد فرعية ، لكل منها حقل "ذهب" بقيمة أقل من 20 و "اسم". إذا تم استيفاء مثل هذا الشرط ، فسيتم استدعاء الإجراء ، وكدخل سيتم تمريره في متغير X - مفتاح العقدة ، وفي متغير NAME اسم اللاعب. إذا كان هناك العديد من العقد المناسبة ، وبالتالي ، هناك العديد من عمليات إنشاء مثيل محتملة ، فسيتم استدعاء الإجراء عدة مرات مع كل من عمليات إنشاء مثيل تم العثور عليها عند الإدخال.
4) في البداية ، كان كل شيء أقل مرونة قليلاً هناك ، ولكن بعد ذلك ، قام فاليارد ، الذي يعرفه الكثيرون من خلال العديد من المحادثات في مؤتمرات حول الوحدة ، بتثبيطنا بمحلل يوزع التعبيرات الحسابية في شجرة قرار سريعة وازدهرت المرونة أخيرًا بلون عنيف.
5) تبدأ أسماء المتغيرات C $. يمكن أن تظهر كمفتاح ، مثل $ X ، وبعد ذلك سيتم تحديد عدة عمليات إنشاء مثل قيمة الورقة ، مثل $ NAME ، يمكن إدراجها في التعبيرات الحسابية: على سبيل المثال: {"gold": "<$ X * 10" } وبعد ذلك يمكن استخدامه للتحقق من الشروط ، فقط هؤلاء اللاعبون الذين لديهم ذهب أكثر من رقمهم الترتيبي مضروبًا في 10 سوف يجتازون الشيك ، وأخيرًا يمكن حسابهم بشكل مباشر في بعض التعبيرات ، على سبيل المثال: {"الذهب": "$ X = 3 + $ this "} حيث $ هذا هو قيمة النقطة الحالية التي عندها تم استدعاء الحساب. يؤدي تمرير هذه العقدة إلى تجسيد قيمة المتغير X دولار على أنها 3 + كمية الذهب التي يمتلكها اللاعب. من الاحتمالاتلم يتم تنفيذ ما يتبادر إلى الذهن ، كان هناك واحد فقط - لا يمكن للمتغير أن يظهر أولاً على الجانب الأيمن من التعبير الحسابي ، سيكون هذا خطأ ، بحلول الوقت الذي يتم استخدامه كحجة يجب أن يكون بالفعل ملموسًا بإحدى الطرق العديدة الأخرى.
6) يمكن أن يحدث متغير في تعبير ما قدر ما تشاء ، في حين أن أول ذكر له يحدده ، وسيكون المتغير التالي بمثابة فحص للمساواة. على سبيل المثال ، سيأخذ مثل هذا البناء اللاعب الأول ، ويفحصه بحثًا عن المال ، ثم يبحث عن لاعب آخر سيكون الأول هو الهدف. إذا لم يتم العثور عليه ، فسوف يتراجع إلى نقطة التأسيس ، سيختار X اللاعب التالي ، ويتحقق من الأموال ، وما إلى ذلك حتى يمر بجميع الخيارات الممكنة X و Y. من خلال تبديل السطور ، سيغير المبرمج ترتيب الشيكات ، ولكن ليس النتيجة النهائية:
{ "player":{
"$X":{"gold":">20"},
"$Y":{"target":"$X"}
}}
7) الإجراء هو أيضًا قالب شجرة يمكن أن يحتوي على متغيرات وتعبيرات حسابية ، وسيتم تغيير شجرة حالة اللعبة لمطابقتها. على سبيل المثال ، سيقوم هذا القالب بتعيين اللاعب X إلى خصم في شكل اللاعب Y ، ولكن إذا لم يكن اللاعب Y موجودًا لسبب ما ، فسيتم إنشاؤه. وستتم إزالة اللاعب "الزائد" تمامًا. في وقت إنشاء اللعبة من لقطة الشاشة ، كانت علامة الحذف فارغة ، لكنني استبدلت بعد ذلك بكلمة محجوزة ، في حال احتاج شخص ما إلى إدخال قيمة فارغة بالمفتاح. بشكل عام ، أعتقد أن المبدأ واضح ، ومعنى الإجراءات التي يتم تنفيذها مع اللعبة هو نفسه في الأساس.
{
"condition":{
"player":{
"$X":{"gold":">20"},
"$Y":{"target":"$X"}}},
"action":{
"$X":{"target":"$Y"},
"superfluous":"@remove"}
}
8) لا يمكن أن يكون الإجراء أيضًا قالبًا على شكل شجرة ، بل مجموعة من القواعد. سيتم فحص كل منهم ليس من البداية ، ولكن مع إنشاء مثيل أولي الذي تم استدعاء الإجراء به. بمعنى أنه قد تكون هناك مجموعة كاملة من القواعد ، وستستخدم جميعها المتغير X.
{
"condition":{
"player":{
"$X":{}, "$Y":{"target":"$X"}}},
"action":[
{"condition":{}, "action":{}},
{"condition":{}, "action":{}}]
}
9) يمكن تطبيق القاعدة الفرعية ليس من جذر شجرة الحالة ، ولكن من نقطة ما يتم الوصول إليها أثناء تطبيق الإجراء. في هذه الحالة ، ستستخدم جميع الشروط وجميع الإجراءات هذه النقطة كجذر. تبدو هكذا:
{
"condition":{
"player":{
"$X":{}, "$Y":{"target":"$X"}}},
"action":{
"$X":{"@rules":[
{"condition":{}, "action":{}},
{"condition":{}, "action":{}}]}
}
10) يمكن تحديد تكرار القاعدة كعقدة أخرى ، وهذا يحقق ، إذا لزم الأمر ، تكرارًا بعمق محدود. لكن في الممارسة العملية ، لم يكن مثل هذا القرار ضروريًا في العادة. يمكن أيضًا استخدامه لتكرار مجموعة من القواعد حسب الحاجة عن طريق وضعها في إجراء:
{
"condition":{},
"action":{},
"repeat":5
}
11) يمكن تحميل شجرة القواعد من عدة ملفات JSON ، وقد تم تركيب هيكل الشجرة الخاص بهم على بعضهم البعض. كان من المناسب تقسيم القواعد إلى كتل منفصلة ذات معنى. ربما يكون بعض التضمين مفيدًا أيضًا ، الآن لا أتذكر كيف تم ترتيبها معنا.
12) التسجيل! يمكن أن تحتوي أي قاعدة على "log": العقدة الحقيقية ، مما أدى إلى حقيقة أن هذه القاعدة بدأت تتلاشى بتفصيل كبير في السجل الذي يصف عملية الحل. ما هي التحسينات التي نحاولها ، وما هي فروع التفكير التي يتم قمعها ولماذا. كان التسجيل هرميًا ، أي أن القاعدة المتداخلة يمكن أن تكون "log": خطأ ولن يتم تسجيل كل ما يحدث فيه وما دونه. من الناحية المثالية ، أود أن تكون هذه العقدة قادرة على تركها في أي مكان في شجرة الشروط للنظر فقط إلى ما يحدث في مستوى واحد من القالب ، لكن لا يبدو أنني أكملت هذا الامتداد. ربما سارت عملية التصحيح بشكل جيد بدونها ، لذلك تم تأجيلها حتى "يومًا ما".
13) الكتابة. كانت اللعبة قديمة جدًا لدرجة أن بعض مبرمجي اليوم لم يولدوا حتى. تمت كتابته في ActionScript2 ، والذي كان يحتوي على كتابة ديناميكية ووراثة من خلال النماذج الأولية المتاحة في وقت التشغيل. من بين اللغات الحديثة المسموعة ، تعمل لغة بايثون فقط بهذه الطريقة. ومع ذلك ، فإن الارتباط بهذه الفكرة ليس بالأمر الصعب. سأفعل ذلك باستخدام رمز المفتاح ':' مثل هذا: "$ X: int" ولكن قد يكون الأمر صعبًا إذا لم يكن التواجد الأول للمتغير له نوع محدد. وإلى جانب ذلك ، يمكن أن يكون هناك ارتباك مع عامل التشغيل الثلاثي.
كما يقولون ، كان سلسًا على الورق ، لكن الاستخدام العملي يتطلب عددًا من العكازات المختلفة. هذه هي التي أتذكرها:
14) لا يمكن التحقق من نفس العقدة بواسطة واحدة ، ولكن بعدة شروط. على سبيل المثال ، تحقق هذا الشرط أولاً من وجود أكثر من 20 نقودًا ، ثم حدد المتغير الذي يمثل فيه هذا المبلغ من المال. رمز الخدمة "@" إذا لم يكن في بداية السطر يعني إعادة الدخول إلى العقدة ، فإن معرّف إعادة الدخول الذي يذهب أبعد من ذلك لم يكن مفيدًا بأي شكل من الأشكال. ربما تم استخدام رمز خدمة وبعض الرموز الأخرى ، ولكن لا شيء ، في رأيي ، يمنعك من استخدام هذا الرمز:
{
"player":{
"$X":{"gold":"<20", "gold@cnt":"$COUNT"}
}
}
15) استغرق الأمر عمليات حسابية يمكن إجراؤها دون استخدام أي عقدة على الإطلاق. وفقًا لتقليد المقدمة ، تم تعيينهم "_" ويمكن أن يكون هناك العديد منهم:
{
"_":"$SUM=$A+$B",
"_@check":"@SUM <20"
}
16) نظرًا لوجود عملية تحقق تتجاوز الشجرة ، فقد استغرق الأمر نزولاً إلى أسفل ، وتم ذلك من خلال الكلمة الأساسية "parent". هذا ، بالطبع ، لم يضيف إلى المقروئية ، لكن كان من المستحيل الاستغناء عنه. هنا ، بالطبع ، بعض التناظرية لوظيفة المسار تقترح نفسها مباشرة ، والتي ستعيد التوجيه إلى المكان المحدد في الشجرة ، لكنني لا أتذكر ما إذا كنت قد تمكنت من تنفيذها في النهاية أم لا:
{
"condition":{
"player":{
"$X":{}, "$Y":{"target":"$X"}}},
"action":{
"$X":{"rules":[
{
"condition":{
"@parent":{"@parent":{"…":"…"}}
}
]},
}
}
17) العمل الآن لديه القدرة على سحب بعض طرق الفصل مباشرة. هذه ركلة في المعدة من حيث سهولة القراءة ، وأنا أفضل نوعًا من التناظرية لـ # تضمين ، لكن كما هي ، لا يمكنك التخلص من الكلمات من الأغنية. أتساءل عما إذا كان بإمكاني الاستغناء عن هذا عمليًا إذا قمت بإعادة تنشيط المكتبة الآن في C #؟
18) تحتوي القاعدة الآن على إعداد إضافي لتكرار الإجراء ليس لجميع الكتل الخرسانية التي تم العثور عليها ، ولكن للقاعدة الأولى فقط. لا أتذكر الآن ما كان يسمى ، ولكن لسبب ما كان هذا العكاز مفيدًا لبعض القواعد.
نتائج الاستخدام
بمجرد أن بدأ استخدام المكتبة بشكل نشط ، تم نقل جميع AI-shki إليها بسرعة ، مما جعل من الممكن الحصول على ضعف الذكاء الاصطناعي مع إنفاق موارد برمجة أقل بثلاث مرات. ساعدت حقيقة أن البيانات الوسيطة لمقياس الذكاء الاصطناعي تم تخزينها مباشرة في الشجرة كثيرًا. على وجه الخصوص ، كتبت القواعد نفسها معلومات حول بطاقات كل مجموعة تركت اللعبة تمامًا في شجرة حالة اللعبة.
بالفعل في المشروع التالي ، تم نقل التحقق من قواعد اللعبة وإجراء التحركات الممكنة من كل مركز إلى نفس المحرك. وبشكل عام ، ليس فقط للنماذج الأولية السريعة ، ولكن أيضًا للألعاب التي توجد فيها قواعد كثيرة ، سيكون هذا شيئًا مفيدًا للغاية. في النهاية ، يمكن أن تحل JSONs القابلة للتنزيل مع المنطق محل نصف ما يفعله المبرمجون بالشفرة ، وكذلك الفوز بالمرونة.
بالطبع ، من حيث سرعة التنفيذ ، كان كل هذا أدنى بشكل ملحوظ من فوضى ifs ، خاصة في التنفيذ على AS2 بنماذجها الأولية وكائناتها الديناميكية ، ولكن ليس كثيرًا بحيث لا يمكن طرحها في الإنتاج.
كانت الخطوة التالية هي نقل فحص القواعد وتحديد الإجراء الخاص بالذكاء الاصطناعي إلى جهاز الكمبيوتر العميل. للاعبين للتحقق من بعضهم البعض. وقد توصلت حتى إلى مثل هذه الخوارزمية للقيام بذلك على الرغم من حقيقة أن قيم بطاقات العدو غير معروفة لنا ، لكن تلك كانت قصة مختلفة تمامًا.
مرت سنوات عديدة ، غيرت وظيفتي عشرات المرات ، وفي كل مرة قمت بتحديث سيرتي الذاتية ، ذهبت إلى toox.com وفوجئت عندما وجدت وظيفتي لا تزال في الخدمة. حتى أنني توقفت للعب لعبة أخرى. وبمجرد وصولي إلى Belot ، صادفت مجموعة من البطاقات تعطي أكبر عدد ممكن من النقاط. احتمال الحصول على مثل هذه المجموعة هو واحد في ثلاثة ملايين.
يومًا ما سأجمع إرادتي في حفنة وأقوم بعمل نسخة جديدة من Logrus لـ C # و Unity3d ، على سبيل المثال ، للاستراتيجي السداسي الذي أحلم به. لكنها لن تكون اليوم ، سأخلد إلى الفراش اليوم. إن واجب نشر الأفكار التي تستحق النشر قد تم الوفاء به بنجاح.
في الختام ، زوجان من الحكايات
كنا موجودون في نوفوسيبيرسك أكاديمغورودوك. استأجرنا مكتبًا في المعهد. والعميل فرنسي ، وليس على دراية بالعادات المحلية. وبعد ذلك ، في الشهر الثالث أو الرابع من العمل المشترك ، يأتي لزيارتنا والتعرف علينا. قمت بتسجيل الوصول في عطلة نهاية الأسبوع في الفندق المحلي "Zolotaya Dolina" وفي يوم الاثنين ، قال للمدير ، دعنا نلتقي في سيارة أجرة في الساعة العاشرة صباحًا ، وسنذهب مع المبرمجين للتعرف. وتأخذ فوفشيك وتعال في الساعة العاشرة. بشكل عام ، يقودون سياراتهم إلى المعهد ، ويقرعون الباب ، ومن الجانب الآخر تأتي جدة الحارس وتنظر إليهم تمامًا دون فهم من خلف الباب المغلق. في مثل هذا التاريخ المبكر ، لم يكن هناك علماء أو مبرمجون يستأجرون مكاتب في المبنى. لقد أيقظوها حرفيا.
وهنا حالة أخرى. بطريقة ما ، اتصل سيباستيان بيريرا بالمدير وأخبرهم أنهم تمكنوا بأعجوبة من اقتحام التلفزيون وسرعان ما سنعرض على التلفزيون مع موقعنا على الإنترنت. بعد حوالي 8 ساعات. إذن ما الذي تفعله هناك لجعله يعمل بشكل أكثر موثوقية ... على مدار الساعة في 2 يناير ... لا يهم ما هو الوقت ... وهكذا يأخذ Vovchik سيارة أجرة ، ويبدأ في جمع المبرمجين في مساكن الطلبة والشقق ، تمامًا في حالة سيئة ، ونقلهم إلى المكتب. في ذلك اليوم رأيت مسؤول نظامنا لأول مرة في حياتي. حتى هذه اللحظة ، كان يفعل كل شيء عن بُعد حصريًا. وهكذا قمنا بتلويث كل من يستطيع. على وجه الخصوص ، لقد كسرت هذا النظام بأكمله من خلال وضع مجموعة من ifs في مكانها مرة أخرى وها نحن هنا ، بالنظر إلى الرسم البياني للحضور وفجأة نرى كيف يبدأ في الارتفاع. في مكان ما عند علامة x15 ، تعطل الخادم. لكن المشرف قال أن كل شيء على ما يرام ، سقط بلطف ،الآن سوف يقوم. تعطل الخادم ثلاث مرات أخرى في ذلك اليوم.