Window.pipedriveLeadboosterConfig = { القاعدة: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', الإصدار: 2, } ؛(الدالة () { var w = نافذة إذا كان (w.LeadBooster) { console.warn('LeadBooster موجود بالفعل') } وإلا { { w.LeadBooster = { q: [], على: دالة (ن، ح) { { هذا.q.push({ t: 'o'، n: n، n: n، h: h }) }, الزناد: الدالة (n) { هذا.q.push({ t: 't'، n: n: n }) }, } } })() thecodest, Author at The Codest - Page 15 of 18

تصميم اللعبة

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

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

التنفيذ

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

نسخة مطبوعة

كانت تجربتنا الأولى في هذا المجال. كانت تلك الفترة التي آمن فيها الناس بنجاح كوفي سكريبت. تطلّب استخدام TypeScript إدخال جوهرة Typecript-rails. لسوء الحظ، لم يكن هذا هو النهائي، حيث أن لغة Typecript، كونها لغة مكتوبة بشكل ثابت، تطلبت ذلك أيضًا من المكتبات المرفقة افتراضيًا بـ rails.

https://github.com/codesthq/cody_the_game/blob/master/app/assets/javascripts/jquery.d.ts (خاصة عند استخدام نظام إدارة الأصول المدمج مع القضبان).

تطلبت كودي كلعبة الكثير من الديناميكيات على جانب المتصفح، بالإضافة إلى تعديل شجرة DOM. كان استخدام TypeScript بدلًا من جافا سكريبت الفانيليا قفزة كبيرة في جودة الشيفرة، وكان وجود الفصول والتغليف مغريًا جدًا بالنسبة لنا.

واجهة برمجة التطبيقات (API) وSPA

في عام 2019، تتم إدارة تطبيقات SPA باستخدام React الرائع أو Vue المكتبات. ومع ذلك، في عام 2015، قمنا بذلك بطريقة مختلفة. كان النص المكتبي المذكور سابقًا مفيدًا في تنفيذ اللعبة، بينما ألغى jQuery كل العمل المتعلق بطلب xml http. الآن يمكننا استخدام الجلب، بينما في تلك الأيام كان '$ .ajax' هو كل ما كان مطلوبًا للمهمة. ألقِ نظرة على واجهة برمجة التطبيقات الخاصة بالعميل!

https://github.com/codesthq/cody_the_game/blob/master/app/assets/javascripts/services/api_client.js.ts

إذا كان الأمر يتعلق بـ api، فكان عليك حل مشكلة المصادقة بطريقة ما، أليس كذلك؟ حسناً، هذا صحيح. ولكن في هذه الحالة، ذهبنا بعد ذلك (هل من الممكن الكتابة هنا - استخدمنا الفرقة؟!) الفرقة وفي جلسة القضبان أنشأنا ملف تعريف الارتباط_المفتاح ثم حفظناه في قاعدة البيانات. ومن ثم علمنا أن كل شيء كان أكثر من جيد.

https://github.com/codesthq/cody_the_game/search?q=cookie_key&unscoped_q=cookie_key

تم تخزين حالة اللعبة في قاعدة البيانات، وكانت المعلومات حول عدد المستخدمين الذين لديهم نقاط تأتي من قاعدة البيانات (هل هي نفس قاعدة البيانات؟ هل يمكننا تغييرها بضمير؟). يأتي ACID دائمًا في متناول اليد عندما لا يكون هناك تخزين مؤقت على جانب النظام؛)

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

SnapSVG

إذا قمنا بتصميم لعبة، يجب أن يتم إصدارها فقط برسومات وصور متحركة رائعة. في ذلك الوقت كنا نقضي ساعات طويلة نتساءل عن كيفية تلبية هذه المتطلبات في تطبيقنا. من ناحية، يمكن للقماش أن يصنع المعجزات، ومن ناحية أخرى، في html نظيف أسهل بكثير في اللحاق بالركب والجميع يعرف ذلك. بعد بحث مضنٍ عن الحل الأفضل، اكتشفنا أن الجمع بين هذين الحلين هو svg. فهو يسمح لك بتقديم الرسومات بسهولة في متجه، وهو مكتوب بلغة الترميز، والأهم من ذلك أنه يمكن تعديله أثناء التنقل. الأهم من ذلك، هناك مكتبة لملفات svg تعمل بشكل مشابه لـ jQuery وتسمح بإجراء عمليات على الصورة بطريقة موحدة. هذا هو:: http://snapsvg.io لدينا ذكريات جميلة جدًا عن استخدام هذا الحل بالتحديد.

مثال على كيفية استخدامنا لـ snap.svg يمكنك العثور عليه أدناه:

https://github.com/codesthq/cody_the_game/blob/master/app/assets/javascripts/intro.js.ts

ملف هامل نفسه مع الهيكل العظمي الرسومي:

https://github.com/codesthq/cody_the_game/blob/master/app/views/game/show.html.haml

كما ترى، إنها تشبه تقريبًا شجرة DOM العادية وتطبيق القضبان العادية!

TrustedSandbox

حسناً، وأخيراً أصبح لدينا أخيراً واجهة برمجة التطبيقات والرسومات وSPA. ولكن ماذا عن تنفيذ الحلول التي يرسلها المستخدمون؟

أول ما يتبادر إلى الذهن هو طريقة التقييم، لكننا لسنا مجانين؛) في عام 2016، كان الرصيف في ازدياد، لذا بدا الأمر وكأنه خيار طبيعي. لم تكن الحاويات نفسها تضمن العزل والحماية الكاملة، ولهذا السبب استخدمنا حلاً جاهزاً في روبي يسمى https://github.com/vaharoni/trusted-sandbox. فقد سمح بحماية الشيفرة البرمجية بشكل أفضل قبل مغادرة صندوق الرمل وبطريقة موحدة لتكوين متطلبات نظام التشغيل. كان من المهم جدًا تحديد وقت تنفيذ التعليمات البرمجية والذاكرة اللازمة للعمل ودورات وحدة المعالجة المركزية بشكل صحيح. تهيئتنا متاحة أدناه

https://github.com/codesthq/cody_the_game/blob/master/config/trusted_sandbox.yml.example

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

https://github.com/codesthq/cody_the_game/blob/master/app/services/task_runner/base_task.rb

كان لكل مهمة من المهام حالة اختبار خاصة بها، مما سمح لنا بالتحقق من صحة الحل المنفذ. وقد تم ذلك عن طريق حقن كود المستخدم في حالة الاختبار بحيث يتم تشغيل كل شيء بمعزل عن الآخر.

https://github.com/codesthq/cody_the_game/blob/master/app/challenges/challenge/case.rb

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

https://github.com/codesthq/cody_the_game/blob/master/app/assets/javascripts/level_controller.js.ts#L92

ملخص المنافسة

حتى سبتمبر 2011، كانت إحصائيات اللعبة حتى سبتمبر 2011 على النحو التالي:

- عدد الجلسات: 1945 - المهام المرسلة: 4476 - إرسال الإجابات الصحيحة: 1624 - أنهيت اللعبة 31

كما ترى، بدأت أكبر السلالم في المهمة # 2 لأنها لم تعد مثالاً عاديًا لعالم التحية.

اقرأ أيضًا:

غوص سريع في روبي 2.6. ما الجديد؟

لقد أصبحت كتابة الوثائق سهلة بفضل VuePress

 البرنامج التعليمي لأساسيات Vue.js. كيف تبدأ مع هذا الإطار؟

arArabic