المديات تمثّل فترة بين قيمتين.
أكثر الأنواع شيوعًا التي تدعم المديات هي Int وChar وString.
ويمكن استخدامها في أمور كثيرة، مثل إنشاء مجموعة بسرعة، وتقطيع السلاسل النصية، والتحقق مما إذا كانت قيمة ما تقع ضمن المدى، والتكرار.
وتُنشأ باستخدام عامل المدى .. أو ... (شامل وغير شامل على الترتيب).
1..5 # A range containing 1, 2, 3, 4, 5
1...5 # A range containing 1, 2, 3, 4
السبب في وجود عاملي المدى هو إنشاء مديات شاملة أو غير شاملة لقيمة النهاية، وهو ما يفيد عندما تعمل، على سبيل المثال، مع الفهارس التي تبدأ من الصفر.
ويمكن أيضًا إنشاء المديات باستخدام دالة التهيئة Range.
Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
عند إنشاء مدى في Crystal باستخدام عاملي المدى .. أو ...، ثم رغبت في استدعاء طريقة على المدى، فستحتاج إلى إحاطة المدى بالأقواس الهلالية.
وذلك لأن الطريقة ستُستدعى، بخلاف ذلك، على الوسيط الثاني لعامل المدى.
(1..5).size # => 5
1..5.size # => Error: undefined method 'size' for Int32
عند رغبتك في تقطيع سلسلة نصية، يمكنك استخدام عامل المدى للحصول على سلسلة فرعية. أي بإنشاء مدى بفهرس البداية وفهرس النهاية للسلسلة الفرعية.
"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"
ويمكنك أيضًا استخدام فهارس سالبة للحصول على السلسلة الفرعية من نهاية السلسلة النصية.
"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"
للمديات مجموعة من الطرق التي يمكن استخدامها للتعامل معها. على سبيل المثال، يمكن استخدام هذه الطرق للحصول على مجموع كل القيم في المدى أو للتحقق مما إذا كان المدى يشمل قيمة ما.
| الطريقة | الوصف | المثال |
|---|---|---|
sum |
تُرجع مجموع كل القيم في المدى | (1..5).sum # => 15 |
size |
تُرجع حجم المدى | (1..5).size # => 5 |
includes? |
تُرجع true إذا كان المدى يشمل القيمة المعطاة، وإلا فتُرجع false
|
(1..5).includes?(3) # => true |
يمكن أن يكون المدى لامنتهيًا وبلا بداية.
المدى اللامنتهي أو الذي بلا بداية تكون قيمة بدايته أو نهايته مساوية لـ nil، لكن يمكن حذف nil عند تعريف المدى.
يفيد استخدام المديات التي بلا بداية واللامنتهية عندما تريد، على سبيل المثال، تقطيع سلسلة نصية من البداية أو حتى النهاية.
"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello"
قد يسبب المدى اللامنتهي تسلسلًا لا نهائيًا إذا لم يُستخدم بحذر ولم يُطبَّق على مجموعة.
يمكن استخدام الأحرف في المديات، مما يتيح لك الحصول على فترة من الأحرف بين حرفين. على سبيل المثال، يفيد هذا عندما تريد الحصول على الأبجدية.
'a'..'z' # A range containing ['a', 'b', 'c', ..., 'z']
يمكن أيضًا استخدام السلاسل النصية في المديات، مما يتيح الحصول على فترة من السلاسل النصية بين سلسلتين نصيتين.
لكن سلوكها يختلف قليلًا عن سلوك Char عند استخدام عدة أحرف في مدى من السلاسل النصية.
وقد يصبح سلوكها مربكًا عند التعامل مع مديات نصية أكثر تعقيدًا، لذا توخَّ الحذر.
("aa".."az") # A range containing ["aa", "ab", "ac", ..., "az"]
بصفتك من محبي الشطرنج، تريد كتابة نسختك الخاصة من اللعبة. صحيح، قد توجد بالفعل تطبيقات كثيرة للشطرنج على الإنترنت، لكن نسختك ستكون فريدة!
ستبدأ بتنفيذ نظام حركة أساسي للقطع.
ستُلعب لعبة الشطرنج على رقعة عرضها ثمانية مربعات وطولها ثمانية مربعات. ويُعرَّف كل مربع بحرف ورقم.
سيتعيّن على اللعبة تخزين صفوف الرقعة. الصفوف هي الأسطر الأفقية للرقعة، وتُرقَّم من 1 إلى 8.
سيتعيّن على اللعبة أيضًا تخزين أعمدة الرقعة. الأعمدة هي الأسطر الرأسية للرقعة، وتُعرَّف بالحروف من A إلى H.
عرّف الثابتين Chess::RANKS وChess::FILES اللذين يخزّنان مجال الصفوف والأعمدة على الترتيب.
Chess::RANKS
# => 1..8
Chess::FILES
# => 'A'..'H'
سيتعيّن على اللعبة التحقق مما إذا كان المربع صالحًا. يكون المربع صالحًا إذا كان الصف والعمود ضمن مجالي الصفوف والأعمدة.
عرّف الطريقة Chess.valid_square? التي تأخذ الوسيطين rank الذي يحمل عددًا صحيحًا يمثّل الصف، وfile الذي يحمل حرفًا يمثّل العمود.
يجب أن تُرجع الطريقة true إذا كان الصف والعمود ضمن مجال الصفوف والأعمدة، وأن تُرجع false بخلاف ذلك.
Chess.valid_square?(1, 'A')
# => true
سيتعيّن على اللعبة الحصول على لقب اللاعب. يتكوّن اللقب من أول حرفين من الاسم الأول للاعب وآخر حرفين من الاسم الأخير للاعب. يجب أن يُكتب اللقب بأحرف كبيرة.
عرّف الطريقة Chess.nickname التي تأخذ الوسيطين first_name الذي يحمل سلسلة نصية تمثّل الاسم الأول للاعب، وlast_name الذي يحمل سلسلة نصية تمثّل الاسم الأخير للاعب.
يجب أن تُرجع الطريقة لقب اللاعب على هيئة سلسلة نصية بأحرف كبيرة.
Chess.nickname("John", "Doe")
# => "JOOE"
سيتعيّن على اللعبة إنشاء رسالة لكل نقلة تحدّد أي لاعب انتقل إلى أي مربع. يجب أن تستخدم الرسالة لقب اللاعب والمربع الذي انتقل إليه. يجب على اللعبة أيضًا تحديد ما إذا كانت النقلة صحيحة، من خلال التحقق مما إذا كان عمود المربع وصفّه ضمن مجالي الأعمدة والصفوف.
إذا كانت النقلة صحيحة، وجب أن تكون الرسالة: "{nickname} moved to {square}"
وإذا كانت النقلة غير صحيحة، وجب أن تكون الرسالة: "{nickname} attempted to move to {square}, but that is not a valid square"
عرّف الطريقة Chess.move_message التي تأخذ الوسائط first_name الذي يحمل سلسلة نصية تمثّل الاسم الأول للاعب، وlast_name الذي يحمل سلسلة نصية تمثّل الاسم الأخير للاعب، وsquare الذي يحمل سلسلة نصية تمثّل المربع الذي انتقل إليه اللاعب.
يجب أن تُرجع الطريقة رسالة النقلة على هيئة سلسلة نصية.
Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
سجّل في Exercism لتتعلّم وتتقن Crystal عبر 26 مفهومًا142 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.