تحليل سلسلة نصية بصيغة Smart Game Format.
SGF صيغة معيارية لتخزين ملفات ألعاب الألواح، ولا سيما لعبة الغو.
SGF صيغة بسيطة إلى حد ما. يحتوي ملف SGF عادةً على شجرة واحدة من العقد، حيث تكون كل عقدة قائمة خصائص. وتحتوي قائمة الخصائص على أزواج من المفتاح والقيمة؛ يمكن أن يظهر كل مفتاح مرة واحدة فقط، لكن قد تكون له قيم متعددة.
سيطلب منك التمرين أن تحلّل سلسلة نصية بصيغة SGF وأن تُرجع بنية شجرية من الخصائص.
قد يبدو ملف SGF هكذا:
(;FF[4]C[root]SZ[19];B[aa];W[ab])
هذه شجرة من ثلاث عقد:
وكما تتخيل، يحتوي ملف SGF على الكثير من العقد ذات الابن الواحد، ولهذا توجد صيغة مختصرة لذلك.
يستطيع SGF ترميز تنويعات اللعب. يقوم لاعبو الغو بالكثير من الرجوع إلى الخلف أثناء مراجعاتهم (لنجرّب هذا، لا ينجح، لنجرّب ذاك)، ويدعم SGF تنويعات تسلسلات اللعب. على سبيل المثال:
(;FF[4](;B[aa];W[ab])(;B[dd];W[ee]))
هنا للعقدة الجذر تنويعان. الأول (وهو الذي يشير بحسب العرف إلى ما لُعب فعليًا) هو حيث يلعب الأسود على 1-1. أرسل معلّم الأسود إليه هذا الملف، وأشار إلى لعب أكثر عقلانية في الابن الثاني للعقدة الجذر: B[dd] (النقطة 4-4، وهي افتتاحية قياسية جدًا للاستيلاء على الزاوية).
يمكن أن يكون للمفتاح قيم متعددة مرتبطة به. على سبيل المثال:
(;FF[4];AB[aa][ab][ba])
هنا تُستخدم AB (إضافة أحجار سوداء) لإضافة ثلاث أحجار سوداء إلى اللوح.
ستكون كل قيم الخصائص من نوع النص في SGF. لا تحتاج إلى تنفيذ أي نوع قيمة آخر. ورغم أنه يمكنك قراءة التوثيق الكامل لنوع النص، ففيما يلي ملخّص لأهم النقاط:
\، وإلا فإنها تبقى كما هي.\ هو محرف الهروب.
يُدرَج أي محرف غير مسافة بيضاء بعد \ كما هو.
وأي محرف مسافة بيضاء بعد \ يتبع القواعد أعلاه.
لاحظ أن SGF لا يمتلك متتاليات هروب لمحارف المسافة البيضاء مثل \t أو \n.احرص على ألا تخلط بين:
قد تكون متتاليات الهروب في القيم النصية الحرفية قد عُولجت مسبقًا بواسطة محلّل لغة البرمجة قبل تمريرها إلى محلّل SGF.
هناك بعض التعقيدات الأخرى في SGF (وفي التحليل عمومًا) يمكنك تجاهلها في الغالب. ينبغي أن تفترض أن المدخل مرمّز بـ UTF-8، وأن الاختبارات لن تحتوي على خاصية مجموعة المحارف، فلا تقلق بشأن ذلك. علاوة على ذلك، يمكنك أن تفترض أن جميع فواصل الأسطر بنمط يونكس (\n، ولن يكون في الاختبارات \r ولا \r\n)، وأنه لن توجد في الاختبارات أي مسافات بيضاء اختيارية بين الخصائص والعقد ونحوها.
أحيانًا تحتاج إلى رفع استثناء. وعندما تفعل ذلك، ينبغي أن تُضمّن دائمًا رسالة خطأ ذات معنى تشير إلى مصدر الخطأ. فهذا يجعل الكود أكثر قابلية للقراءة ويساعد كثيرًا في تصحيح الأخطاء. وفي الحالات التي تعرف فيها أن مصدر الخطأ سيكون من نوع معيّن، يمكنك أن تختار رفع أحد أنواع الأخطاء المدمجة، لكن يجب أن تُضمّن معه رسالة ذات معنى.
يتطلب هذا التمرين تحديدًا أن تستخدم عبارة raise لكي "تُطلق" قيمة ValueError إذا كان المُدخل يفتقر إلى المحدِّدات المناسبة، أو لم يكن بأحرف كبيرة، أو لم يُشكّل شجرة لها عُقد، أو لم يُشكّل شجرة على الإطلاق. لن تنجح الاختبارات إلا إذا استخدمت raise مع exception وأضفت معه رسالة.
لكي ترفع ValueError مع رسالة، اكتب الرسالة كوسيط لنوع exception:
# if the tree properties as given do not have proper delimiters.
raise ValueError("properties without delimiter")
# if the tree properties as given are not all in uppercase.
raise ValueError("property must be in uppercase")
# if the input does not form a tree, or is empty.
raise ValueError("tree missing")
# if the input is a tree without any nodes.
raise ValueError("tree with no nodes")
سجّل في Exercism لتتعلّم وتتقن Python عبر 17 مفهومًا146 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.