بلاك جاك

بلاك جاك

تمرين تعلّمي

مقدمة

Case (يُشار إليه غالبًا باسم switch في لغات أخرى) هو أحد أشكال تعبيرات التحكم مثل if-else. تتيح جملة case ربط عدة عبارات if-else-if معًا، ويمكن أن تكون أكثر وضوحًا في القراءة مع أنها توفّر التحكم في مسار التنفيذ.

تُعرَّف جملة case بالكلمة المفتاحية case متبوعةً بتعبير اختياري. ثم تُستخدم الكلمة المفتاحية when لكل حالة، متبوعةً بتعبير يُقارَن بتعبير case. ولا ينبغي إزاحة الكلمة المفتاحية when عن الكلمة المفتاحية case. وبعد الكلمة المفتاحية when يأتي الكود الذي يجب تنفيذه إذا طابق تعبير case تعبير when. وتتيح جملة case عبارة else اختيارية تُنفَّذ إذا لم تطابق أي حالة أخرى.

يُقيَّم تعبير case ثم يُقارَن بكل تعبير when. وتُجرى المقارنة باستخدام عامل تساوي case (===).

value = 1
case value
when 1
  "One"
when 2
  "Two"
else
  "Other"
end

# This is the same as:
value = 1
if 1 === value
  "One"
elsif 2 === value
  "Two"
else
  "Other"
end

عامل تساوي case (===)

يختلف عامل تساوي case (===) قليلًا عن عامل المساواة (==). يتحقق هذا العامل مما إذا كان الطرف الأيمن عضوًا في المجموعة التي يصفها الطرف الأيسر. وهذا يعني أن موضع كل طرف مهم. وتتوقف كيفية عمل ذلك على نوع الطرف الأيسر، فمثلًا يتحقق Range مما إذا كان الطرف الأيمن ضمن المدى، ويتحقق Object مما إذا كان الطرف الأيمن نسخةً من Object.

(1..3) == 1  # => false
(1..3) === 1 # => true

String == "foo"  # => false
String === "foo" # => true

case مع تعبيرات متعددة

تتيح جملة case مطابقة عدة تعبيرات في حالة واحدة، مع فصل كل قيمة ممكنة بفاصلة. وسيُنفَّذ الكود إذا طابق أي من التعبيرات. وقد يكون ذلك مفيدًا عندما تريد أن تكون لحالة واحدة عدة قيم ممكنة.

case var
when 1, 2
  "One or two"
else
  "Other"
end

case مع المدى

يمكن لجملة case أيضًا التحقق مما إذا كانت قيمة ما ضمن مدى. ويتم ذلك بوضع مدى كتعبير when.

case var
when 1..3
  puts "One to three"
else
  puts "Other"
end

case بدون تعبير

عندما لا تكون هناك حاجة إلى تعبير case، يمكن حذفه. سيؤدي ذلك إلى تقييم كل تعبير when من حيث كونه صحيحًا أو خطأً، فتصبح جملة case أشبه بعبارات if-else-if.

case
when 1 == 1
  "One is equal to one"
when 1 > 2
  "One is greater than two"
else
  "Other"
end

when في سطر واحد

تتيح Ruby كتابة جمل case في سطر واحد. ويمكن استخدام ذلك عندما تكون لديك عبارة بسيطة في سطر واحد. وتُكتب عبارة when في سطر واحد بالصيغة when <expression> then <statement>. وعند استخدامها في عبارة else تُكتب بالصيغة else <statement>.

case var
when 1 then "One"
when 2 then "Two"
else "Other"
end

case مع الأنواع

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

case var
when Integer
  "Integer"
when String
  "String"
else
  "Other"
end

التعليمات

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

1. احسب قيمة أي بطاقة معطاة.

ستتلقى بطاقتين وستتمكن من رؤية البطاقة المكشوفة للموزّع. تُمثَّل جميع البطاقات بسلسلة نصية مثل "ace" و"king" و"three" و"two" وهكذا. وقيم كل بطاقة هي:

البطاقة القيمة البطاقة القيمة
ace 11 eight 8
two 2 nine 9
three 3 ten 10
four 4 jack 10
five 5 queen 10
six 6 king 10
seven 7 other 0
Note

عادةً، يمكن أن تأخذ بطاقات الآس القيمة 1 أو 11، ولكن للتبسيط سنفترض أنها لا يمكن أن تأخذ سوى القيمة 11.

نفّذ الطريقة Blackjack.parse_card التي تأخذ بطاقة في صورة سلسلة نصية كوسيط. وينبغي أن تُرجع الطريقة قيمة البطاقة كعدد صحيح.

Blackjack.parse_card("ace")
# => 11

2. سمِّ مجالات القيم.

ينبغي تصنيف نقاط اللاعب إلى مجالات من القيم. وتُحسب نقاط اللاعب بجمع قيم بطاقتي اللاعب. والمجالات المستخدمة هي:

المجال القيمة
low [4, 11]
mid [12, 16]
high [17, 20]
blackjack [21]

نفّذ الطريقة Blackjack.card_range التي تأخذ بطاقتين في صورة سلسلة نصية كوسيطين. وينبغي أن تُرجع الطريقة اسم مجال القيم الذي تقع فيه البطاقتان.

Blackjack.card_range("ten", "king")
# => "high"

3. نفّذ منطق اتخاذ القرار للجولة الأولى.

بناءً على بطاقتيك وبطاقة الموزّع، هناك استراتيجية للجولة الأولى من اللعبة، لديك فيها الخيارات التالية:

  • التوقف (S)
  • سحب بطاقة (H)
  • التقسيم (P)
  • الفوز تلقائيًا (W)

على الرغم من أنها ليست مثالية بعد، ستتبع الاستراتيجية التي كان صديقك Alex يطورها، وهي كالتالي:

  • إذا كان لديك زوج من بطاقات الآس، فيجب أن تقسّمه دائمًا.
  • إذا كان لديك بلاك جاك (بطاقتان مجموعهما 21)، ولا يملك الموزّع آسًا أو بطاقة وجهية أو عشرة، فأنت تفوز تلقائيًا. أما إذا كان الموزّع يملك أيًا من هذه البطاقات، فسيتعين عليك التوقف وانتظار الكشف عن البطاقة الأخرى.
  • إذا كان مجموع بطاقاتك قيمة ضمن المجال [17, 20]، فينبغي أن تتوقف دائمًا.
  • إذا كان مجموع بطاقاتك قيمة ضمن المجال [12, 16]، فينبغي أن تتوقف دائمًا إلا إذا كان لدى الموزّع 7 أو أكثر، وفي هذه الحالة ينبغي أن تسحب بطاقة دائمًا.
  • إذا كان مجموع بطاقاتك 11 أو أقل، فينبغي أن تسحب بطاقة دائمًا.

نفّذ الطريقة Blackjack.first_turn التي تأخذ ثلاث بطاقات في صورة سلاسل نصية كوسائط. وينبغي أن تُرجع الطريقة القرار الذي ينبغي أن تتخذه في صورة سلسلة نصية.

Blackjack.first_turn("ace", "ace", "two")
# => "P"
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Ruby Exercism

مستعد لبدء بلاك جاك؟

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