المسارات
/
Crystal
Crystal
/
التمارين
/
لعبة الشطرنج
لعبة الشطرنج

لعبة الشطرنج

تمرين تعلّمي

مقدمة

المديات تمثّل فترة بين قيمتين. أكثر الأنواع شيوعًا التي تدعم المديات هي 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
Note

عند إنشاء مدى في 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"
Caution

قد يسبب المدى اللامنتهي تسلسلًا لا نهائيًا إذا لم يُستخدم بحذر ولم يُطبَّق على مجموعة.

مديات Char

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

'a'..'z' # A range containing ['a', 'b', 'c', ..., 'z']

مديات السلاسل النصية

يمكن أيضًا استخدام السلاسل النصية في المديات، مما يتيح الحصول على فترة من السلاسل النصية بين سلسلتين نصيتين. لكن سلوكها يختلف قليلًا عن سلوك Char عند استخدام عدة أحرف في مدى من السلاسل النصية. وقد يصبح سلوكها مربكًا عند التعامل مع مديات نصية أكثر تعقيدًا، لذا توخَّ الحذر.

("aa".."az") # A range containing ["aa", "ab", "ac", ..., "az"]

التعليمات

بصفتك من محبي الشطرنج، تريد كتابة نسختك الخاصة من اللعبة. صحيح، قد توجد بالفعل تطبيقات كثيرة للشطرنج على الإنترنت، لكن نسختك ستكون فريدة!

ستبدأ بتنفيذ نظام حركة أساسي للقطع.

ستُلعب لعبة الشطرنج على رقعة عرضها ثمانية مربعات وطولها ثمانية مربعات. ويُعرَّف كل مربع بحرف ورقم.

1. تعريف مجال الصفوف والأعمدة

سيتعيّن على اللعبة تخزين صفوف الرقعة. الصفوف هي الأسطر الأفقية للرقعة، وتُرقَّم من 1 إلى 8.

سيتعيّن على اللعبة أيضًا تخزين أعمدة الرقعة. الأعمدة هي الأسطر الرأسية للرقعة، وتُعرَّف بالحروف من A إلى H.

عرّف الثابتين Chess::RANKS وChess::FILES اللذين يخزّنان مجال الصفوف والأعمدة على الترتيب.

Chess::RANKS
# => 1..8

Chess::FILES
# => 'A'..'H'

2. التحقق من صلاحية المربع

سيتعيّن على اللعبة التحقق مما إذا كان المربع صالحًا. يكون المربع صالحًا إذا كان الصف والعمود ضمن مجالي الصفوف والأعمدة.

عرّف الطريقة Chess.valid_square? التي تأخذ الوسيطين rank الذي يحمل عددًا صحيحًا يمثّل الصف، وfile الذي يحمل حرفًا يمثّل العمود. يجب أن تُرجع الطريقة true إذا كان الصف والعمود ضمن مجال الصفوف والأعمدة، وأن تُرجع false بخلاف ذلك.

Chess.valid_square?(1, 'A')
# => true

3. الحصول على لقب اللاعب

سيتعيّن على اللعبة الحصول على لقب اللاعب. يتكوّن اللقب من أول حرفين من الاسم الأول للاعب وآخر حرفين من الاسم الأخير للاعب. يجب أن يُكتب اللقب بأحرف كبيرة.

عرّف الطريقة Chess.nickname التي تأخذ الوسيطين first_name الذي يحمل سلسلة نصية تمثّل الاسم الأول للاعب، وlast_name الذي يحمل سلسلة نصية تمثّل الاسم الأخير للاعب. يجب أن تُرجع الطريقة لقب اللاعب على هيئة سلسلة نصية بأحرف كبيرة.

Chess.nickname("John", "Doe")
# => "JOOE"

4. إنشاء رسالة النقلة

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

إذا كانت النقلة صحيحة، وجب أن تكون الرسالة: "{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"
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Crystal Exercism

مستعد لبدء لعبة الشطرنج؟

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