المسارات
/
Crystal
Crystal
/
التمارين
/
دوري السلة في Bellebrook
دوري السلة في Bellebrook

دوري السلة في Bellebrook

تمرين تعلّمي

مقدمة

الوحدات في Crystal تخدم غرضين:

الغرض الأول هو إنشاء فضاء أسماء لتجنّب تعارض الأسماء. لكنه يجمع الكود أيضًا، مما يسهّل فهم الغرض من الكود.

الغرض الثاني هو تعريف مزائج لمشاركة الكود مع الأنواع.

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

لتعريف وحدة، تستخدم الكلمة المفتاحية module متبوعة باسم الوحدة.

module Foo
end

فضاء الأسماء

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

module Foo
  class Bar
  end
end

Foo::Bar.new

استخدامه كمزيج

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

هناك أسلوبان مختلفان لاستخدام وحدة كمزيج: الأول هو استخدام الكلمة المفتاحية include، والثاني هو استخدام الكلمة المفتاحية extend.

سيتيح كلا الأسلوبين الثوابت للنوع الذي يضم أو يوسّع الوحدة.

Include

ستجعل include جميع الطرق في الوحدة متاحة كطرق نسخة على النوع الذي يضم الوحدة. ينبغي أن تكون الكلمة المفتاحية include في أعلى النوع، متبوعة باسم الوحدة.

module Foo
  def foo
    "foo"
  end
end

class Bar
  include Foo
end

Bar.new.foo # => "foo"

Extend

تعمل extend بشكل مشابه لـ include، لكن بدلًا من جعل الطرق متاحة كطرق نسخة، فإنها تجعلها متاحة كطرق صنف. ينبغي أن تُكتب الكلمة المفتاحية extend في أعلى النوع، متبوعة باسم الوحدة.

module Foo
  def foo
    "foo"
  end
end

class Bar
  extend Foo
end

Bar.foo # => "foo"

Extend self

ثمة نمط شائع في Crystal يستخدم نمط extend self داخل وحدة. سيجعل هذا جميع الطرق في الوحدة متاحة كطرق صنف على الوحدة نفسها. هذا يعني أنك لست مضطرًا لربط كل طريقة بالوحدة باستخدام صيغة def self.method_name.

module Foo
  extend self

  def foo
    "foo"
  end
end

Foo.foo # => "foo"

التعليمات

‏Bellebrook Basketball League دوري يضم عدة فرق، ولكل فريق قائمة من اللاعبين. يوشك موسم جديد على البدء، ويحتاجون إلى إنشاء نظام تذاكر جديد لبيع تذاكر المباريات. في الموسم الماضي، باعوا التذاكر عند مدخل الملعب، لكن الشعبية ارتفعت بشكل كبير، فقرروا بيع التذاكر عبر الإنترنت هذا الموسم للتعامل مع الطلب المتزايد.

تواصل معك الدوري وطلب منك إنشاء نظام للتعامل مع بيع التذاكر.

1. إنشاء نظام تذاكر

أولًا، تحتاج إلى إنشاء نظام تذاكر للتعامل مع بيع التذاكر. يحتاج نظام التذاكر إلى تحديد عدد التذاكر المتاحة لمباراة.

يجب إنشاء نسخة من صنف يُسمى TicketSystem لكل مباراة. يجب أن تحمل الحالة المُهيّأة المعلومات التالية:

  1. عدد التذاكر المتاحة للمباراة.
  2. الملعب الذي تُلعب فيه المباراة.

أنشئ حالة مُهيّأة من وسائط تشير إلى عدد التذاكر المتاحة والملعب الذي تُلعب فيه المباراة. يجب أن تتكون الحالة المُهيّأة من متغيرات المثيل @tickets_available و @stadium. يجب أن تحتوي هاتان على الوسيطين الأول والثاني المُعطيين، على التوالي.

TicketSystem.new(100, "Bellebrook")
# => #<TicketSystem:0x10f0b8 @tickets_available=100, @stadium="Bellebrook">

2. الحصول على عدد التذاكر المتاحة

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

عرّف وحدة تُسمى TicketingReservation فوق الصنف المُعرَّف مسبقًا. يجب تضمين هذه الوحدة في صنف TicketSystem.

داخل الوحدة، عرّف طريقة تُسمى tickets_available. يجب أن تُرجع هذه الطريقة عدد التذاكر المتاحة.

ticket_system = TicketSystem.new(100)
ticket_system.tickets_available
#=> 100

3. طلب التذاكر

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

داخل الوحدة TicketingReservation، عرّف طريقة تُسمى order_ticket?. يجب أن تُرجع الطريقة true إذا كانت 100 تذكرة على الأقل متاحة و false خلاف ذلك. وإذا كانت 100 تذكرة على الأقل متاحة، يجب أن تُقلل الطريقة أيضًا عدد التذاكر المتاحة بمقدار 1.

ticket_system = TicketSystem.new(100)
ticket_system.order_ticket?
#=> true

4. رسالة الطلب

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

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

إذا نجح الشراء، يجب أن تبدو الرسالة هكذا: {name}, your purchase was successful, your ticket number is #{ticket_number}, and the game is played at the {stadium_name} stadium.. وإذا لم ينجح الشراء، يجب أن تبدو الرسالة هكذا: {name}, your purchase was unsuccessful, there are not enough tickets available..

داخل الوحدة TicketingReservation, عرّف طريقة تُسمى order_message تتلقى وسيطًا name يحتوي على اسم المشتري. يجب أن تُرجع الطريقة سلسلة نصية تحتوي على الرسالة.

ticket_system = TicketSystem.new(100, "Bellebrook")
ticket_system.order_message("John")
#=> "John, your purchase was successful, your ticket number is #100, and the game is played at the Bellebrook stadium."
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Crystal Exercism

مستعد لبدء دوري السلة في Bellebrook؟

سجّل في Exercism لتتعلّم وتتقن Crystal عبر 26 مفهومًا142 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.