في هذا الدرس العملي حول الترميز بلغة Kotlin، ستنشئ لعبة أخرى باستخدام النرد، وهي Lucky Dice Roll، وستحاول الحصول على رقم الحظ. سيحدّد البرنامج رقمًا محظوظًا ثم سيرمي النرد. بعد ذلك، يمكنك مقارنة الرمية بالرقم المحظوظ وطباعة رسالة مناسبة في الناتج. ولتحقيق ذلك، ستتعرّف على كيفية مقارنة القيم واتّخاذ قرارات مختلفة في برنامج Kotlin.
لمساعدتك في التركيز على مفاهيم البرمجة بدون الحاجة إلى القلق بشأن واجهة مستخدم التطبيق، ستستخدم أداة برمجة Kotlin المستندة إلى المتصفّح وستعرض نتائجك في وحدة التحكّم.
المتطلبات الأساسية
- كيفية فتح الرمز البرمجي وتعديله وتشغيله في https://try.kotlinlang.org/
- القدرة على إنشاء برنامج Kotlin وتشغيله يستخدم متغيرات ودوال مع وسيطات وفئات مع طرق، ويعرض نتيجة في وحدة التحكّم
أهداف الدورة التعليمية
- كيفية استخدام عبارتَي
if
وelse
- كيفية مقارنة القيم باستخدام عوامل مثل أكبر من (
>
) وأصغر من (<
) ويساوي (==
) - كيفية استخدام عبارات
when
لاختيار أحد الخيارات استنادًا إلى قيمة معيّنة - ما هو نوع البيانات
Boolean
وكيفية استخدام القيمتينtrue
وfalse
لاتخاذ القرارات
ما ستنشئه
- لعبة النرد المستندة إلى Kotlin، Lucky Dice Roll، والتي تتيح لك تحديد رقم الحظ. يفوز اللاعب إذا حصل على الرقم المحظوظ.
ما تحتاج إليه
- جهاز كمبيوتر متصل بالإنترنت
يجب أن يحدّد برنامج Lucky Dice Roller ما إذا كان المستخدم قد حصل على رقم الحظ وتلقّى رسالة تهنئة، أو تلقّى رسالة تطلب منه إعادة المحاولة.
بصفتك مطوّر تطبيقات، عليك اتّخاذ قرارات بشأن طريقة عمل التطبيق وإنشاء نتائج مختلفة للمستخدمين.
إذا كنت بصدد إنشاء تطبيق تسوّق، يمكنك عرض شاشات مختلفة استنادًا إلى خيارات التسليم التي يختارها المستخدم. في لعبة اختبار، يمكنك عرض شاشات مختلفة استنادًا إلى ما إذا كانت إجابة اللاعب صحيحة. اعتمادًا على التطبيق، قد تكون هناك العديد من النتائج المحتملة التي يجب أخذها في الاعتبار في التعليمات البرمجية.
في برنامج "رمي النرد"، يجب أن يتعامل التطبيق مع حالات مختلفة، مثل:
- إذا كان رمي النرد هو الرقم المحظوظ، اعرض رسالة تهنئة.
- في حال لم يكن رمي النرد هو الرقم المحظوظ، اعرض رسالة لإعادة المحاولة.
لإضافة هذه المنطق إلى الرمز البرمجي، استخدِم كلمات رئيسية خاصة بلغة Kotlin، مثل if
وelse
وwhen
.
لنلقِ نظرة على بعض الأمثلة.
استخدِم عبارة if
لإعداد شرط يتم استيفاؤه
- راجِع الرمز البرمجي أدناه. هل يمكنك تخمين الناتج؟
fun main() {
val num = 5
if (num > 4) {
println("The variable is greater than 4")
}
}
- انسخ الرمز والصقه في محرّر برنامج Kotlin وشغِّل البرنامج لمراقبة الناتج.
The variable is greater than 4
تتم عملية اتخاذ القرار في هذا البرنامج على النحو التالي:
- أنشئ متغيّرًا
num
واضبطه على5.
- إذا كان
num
أكبر (>
) من 4,
، اطبع"The variable is greater than 4"
. - في جميع الحالات الأخرى، لا تتّخذ أي إجراء.
في المثال أعلاه، تم ضبط num
على 5. تقارن عبارة if
ما إذا كان المتغيّر أكبر من 4. بما أنّ هذا الشرط صحيح، سينفّذ النظام بعد ذلك التعليمات الواردة بين الأقواس المتعرّجة ويطبع الرسالة.
لاحظ التنسيق العام لعبارة if
:
- ابدأ بالكلمة الرئيسية
if
. - أضِف قوسَين
()
. يتم وضع الشرط داخل الأقواس. الشرط هو أي شيء يمكن أن يكونtrue
أوfalse
. على سبيل المثال، ما إذا كان رقم أكبر من رقم آخر. - أضِف بعد ذلك علامتَي قوسَين معقوفَين
{}
. داخل الأقواس المعقوفة، يمكنك وضع الرمز المراد تنفيذه إذا كان الشرطtrue
.
if (condition-is-true) { execute-this-code }
استخدِم عبارة if
لإعداد شرط لم يتم استيفاؤه
- غيِّر قيمة
num
إلى 3، كما هو موضّح أدناه. ماذا تتوقّع أن يحدث إذا شغّلت هذه الرمز؟
fun main() {
val num = 3
if (num > 4) {
println("The variable is greater than 4")
}
}
- انسخ الرمز والصقه في محرّر برنامج Kotlin وشغِّل البرنامج لمراقبة الناتج.
عند ضبط num
على 3، لا تتم طباعة أي شيء لأنّ قيمة num
أقل من 4. إذًا، الشرط الذي ينص على أنّ num
أكبر من 4 هو false
، ولن يتم تنفيذ الرمز بين الأقواس المتعرّجة، ولن تتم طباعة أي شيء.
استخدِم else
لإنشاء بديل للشروط التي لم يتم استيفاؤها
بدلاً من عدم اتّخاذ أي إجراء، يمكنك أن تقدّم للمستخدمين بديلاً عندما لا يتم استيفاء أحد الشروط. كما هو الحال مع اللغة العادية، يمكنك إجراء ذلك باستخدام عبارة else
.
- أضِف عبارة
else
لطباعة رسالة عندما لا تكون قيمةnum
أكبر من 4، كما هو موضّح أدناه. ماذا تتوقّع أن يحدث إذا شغّلت هذه الرمز؟
fun main() {
val num = 3
if (num > 4) {
println("The variable is greater than 4")
} else {
println("The variable is less than 4")
}
}
- انسخ الرمز والصقه في محرّر برنامج Kotlin وشغِّل البرنامج لمراقبة الناتج.
The variable is less than 4
- لاحظ أنّه عندما تكون قيمة
num
هي 3، يعرض البرنامج الرسالة"The variable is less than 4"
المرتبطة بالعبارةelse
لأنّnum
ليست أكبر من 4 . - غيِّر قيمة
num
إلى 5 وشغِّل البرنامج مرة أخرى. الآن، من الصحيح أنّnum
أكبر من 4، وسيطبع البرنامج "The variable is greater than 4
". - غيِّر قيمة
num
إلى 4 وشغِّل البرنامج. الآن، 4 ليس أكبر من 4، ويطبع البرنامج "The variable is less than 4
".
على الرغم من أنّ "The variable is less than 4
" هو الناتج الصحيح للشروط التي حدّدتها في الرمز، فإنّ العبارة المطبوعة ليست دقيقة، لأنّ 4 ليس أقل من 4. يمكنك إضافة شرط آخر يتحقّق من الاحتمال الثالث، أي ما إذا كانت قيمة num
تساوي 4 بالضبط، وطباعة عبارة صحيحة عندما يكون هذا الشرط صحيحًا.
استخدِم تركيبة else
+ if
لإضافة شروط بديلة
يمكنك إضافة أكثر من شرط واحد. بالنسبة إلى المثال الذي قدّمته، إليك كيفية تغطية جميع الاحتمالات الخاصة بـ num
:
- إذا كان
num
أكبر من 4، اطبع "The variable is greater than 4
". - إذا كان
num
يساوي 4، اطبع"The variable is equal to 4"
. - بخلاف ذلك، اطبع
"The variable is less than 4"
.
ويُشار إلى هذه الحالات باسم حالات مختلفة في عبارة if-else. هناك 3 طلبات مُدرَجة.
يبدو الرمز المعدَّل على النحو التالي:
fun main() {
val num = 4
if (num > 4) {
println("The variable is greater than 4")
} else if (num == 4) {
println("The variable is equal to 4")
} else {
println("The variable is less than 4")
}
}
لاحظ التغييرات التالية:
- تم الآن ضبط قيمة
num
على 4 حتى تتمكّن من اختبار الشرط الجديد. - بين عبارتَي
if
وelse
الأصليتَين، توجد عبارةelse if
جديدة للحالة التي تكون فيها قيمةnum
تساوي 4 بالضبط.
- انسخ الرمز أعلاه والصقه في محرّر برنامج Kotlin وشغِّل البرنامج لمراقبة الناتج.
The variable is equal to 4
- جرِّب تغيير قيمة
num
، واطّلِع على تأثير ذلك في الناتج. غيِّرnum
إلى 2 و6، حتى تتمكّن من رؤية كل شرطtrue
.
التحكّم في التدفق
عند النظر إلى عبارات if-else أعلاه، سيتم تنفيذ الرمز أو تدفقه، كما هو محدّد بالشروط. لذا، تُعرف الطريقة التي توجّه بها التنفيذ باستخدام هذه العبارات الشرطية باسم "تدفّق التحكّم" في البرنامج.
- لنفترض أنّ نتيجة رمية النرد
num
هي 3. يتحقّق البرنامج من الشرط الأول (num > 4). هذا الشرط غير صحيح، لذا يتحقّق البرنامج من الشرط التالي (num == 4) الذي يكون أيضًا غير صحيح. بعد ذلك، ينفّذ البرنامج الرمز البرمجي لعبارة else، وهو الخيار الأخير. - إذا كان رقم رمية النرد هو 6، يكون الشرط الأول (num > 4) صحيحًا. يطبع البرنامج الرسالة
"The variable is greater than 4"
. بما أنّ هذا الشرط صحيح، ليس عليه التحقّق من الباقي، وينتهي من عبارة if-else. - استخدِم تركيبة else + if لإضافة شروط بديلة.
في هذا القسم، وباستخدام ما تعلّمته في المهمة السابقة، ستعدّل برنامج "رمي النرد" للتحقّق مما إذا كنت قد حصلت على رقم حظ محدّد مسبقًا. إذا كان لديك، فقد فزت!
إعداد الرمز الأوّلي
ستبدأ لعبة Lucky Dice Roller باستخدام رمز مشابه لرمز الحلّ في برنامج Dice Roller السابق بلغة Kotlin. يمكنك تعديل الدالة main()
في الرمز السابق لتتطابق مع الرمز أدناه، أو يمكنك نسخ الرمز أدناه ولصقه للبدء.
fun main() {
val myFirstDice = Dice(6)
val diceRoll = myFirstDice.roll()
println("Your ${myFirstDice.numSides} sided dice rolled ${diceRoll}!")
}
class Dice (val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
التحقّق مما إذا تم طرح الرقم المحظوظ
أنشئ رقم حظ أولاً، ثم قارِن رمية النرد بهذا الرقم.
.
- في
main()
، احذف عبارةprintln()
. - في
main()
، أضِفval
باسمluckyNumber
واضبط قيمته على 4. يجب أن تبدو التعليمات البرمجية على النحو التالي.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
}
- في ما يلي، أضِف عبارة
if
مع شرط داخل الأقواس()
يتحقّق مما إذا كانrollResult
يساوي (==
)luckyNumber
. اترك بعض المساحة بين الأقواس المتعرّجة{}
لتتمكّن من إضافة المزيد من الرموز.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
}
}
- داخل الأقواس المتعرّجة
{}
، أضِف عبارةprintln
لطباعة"You win!"
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
}
}
- تشغيل برنامجك قد تحتاج إلى تشغيله عدة مرات قبل أن يحالفك الحظ وتظهر الرسالة الفائزة في الناتج.
You win!
الردّ عندما لم يتم طرح الرقم المحظوظ
قد يؤدي عدم تلقّي أي ملاحظات من البرنامج في حال عدم فوز المستخدم إلى التساؤل عمّا إذا كان البرنامج معطّلاً. من الممارسات الجيدة تقديم ردّ دائمًا عندما ينفّذ المستخدم إجراءً ما. بالنسبة إلى برنامج Lucky Dice Roller، يمكنك إعلامهم بأنّهم لم يفوزوا باستخدام عبارة else
.
- أضِف عبارة
else
لطباعة"You didn't win, try again!"
.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
} else {
println("You didn't win, try again!")
}
}
- نفِّذ البرنامج، وسيتم إعلام المستخدمين دائمًا بالنتيجة بغض النظر عن طبيعتها.
في هذه المرحلة، يعرف المستخدمون ما إذا كانوا قد فازوا أم لا، ولكنهم لا يعرفون السبب. احرص دائمًا على تزويد المستخدمين بمعلومات ليفهموا نتيجة إجراءاتهم. لنفترض أنّ برنامجك كان عبارة عن طلب للحصول على قرض. "لم تتم الموافقة على طلبك لأنّ تقييمك الائتماني ضعيف"، هذه الجملة تقدّم معلومات أكثر بكثير من "عذرًا، لا يمكننا منحك قرضًا، يُرجى إعادة المحاولة". بالنسبة إلى لعبة Lucky Dice Roller، يمكنك عرض رسالة إعلامية مختلفة للمستخدمين في كل رمية إذا خسروا. استخدِم عبارات else if
متعددة لإجراء ذلك.
- أضِف عبارات
else if
لطباعة رسالة مختلفة لكل عملية دحرجة. راجِع التنسيق الذي تعلّمته في المهمة السابقة، إذا لزم الأمر.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
} else if (rollResult == 1) {
println("So sorry! You rolled a 1. Try again!")
} else if (rollResult == 2) {
println("Sadly, you rolled a 2. Try again!")
} else if (rollResult == 3) {
println("Unfortunately, you rolled a 3. Try again!")
} else if (rollResult == 4) {
println("No luck! You rolled a 4. Try again!")
} else if (rollResult == 5) {
println("Don't cry! You rolled a 5. Try again!")
} else {
println("Apologies! you rolled a 6. Try again!")
}
}
في الرمز أعلاه، يمكنك
- تحقَّق مما إذا كانت
rollResult
هيluckyNumber
. - إذا كان
rollResult
هوluckyNumber
، اطبع رسالة الفوز. - في ما عدا ذلك، تحقَّق مما إذا كانت قيمة
rollResult
هي 1، وإذا كان الأمر كذلك، اطبع رسالة "أعِد المحاولة". - بخلاف ذلك، تحقَّق مما إذا كانت قيمة
rollResult
هي 2، وإذا كان الأمر كذلك، اطبع رسالة مختلفة لإعادة المحاولة. - وبخلاف ذلك، استمر في التحقّق من خلال الرقم 5.
- إذا لم يكن الرقم أيًا من 1 إلى 5، يكون الخيار المتبقي هو 6 فقط، لذا لا حاجة إلى اختبار آخر باستخدام
else if
، ويمكنك فقط الحصول على هذا الخيار الأخير باستخدام عبارةelse
النهائية.
بما أنّ وجود عدة حالات else if
أمر شائع جدًا، توفّر Kotlin طريقة أبسط لكتابتها.
يُعدّ اختبار العديد من النتائج أو الحالات المختلفة أمرًا شائعًا جدًا في البرمجة. في بعض الأحيان، يمكن أن تكون قائمة النتائج المحتملة طويلة جدًا. على سبيل المثال، إذا كنت تستخدم نردًا ذا 12 وجهًا، سيكون لديك 11 عبارة else if
بين النجاح وelse
النهائي. لتسهيل كتابة وقراءة هذه الأنواع من العبارات، ما يساعد في تجنُّب الأخطاء، تتيح لغة Kotlin عبارة when
.
ستغيّر برنامجك لاستخدام عبارة when
. تبدأ عبارة when
بالكلمة الأساسية when
، متبوعة بأقواس ()
. داخل الأقواس، يتم وضع القيمة المطلوب اختبارها. يلي ذلك أقواس معقوفة {}
للتعليمات البرمجية التي سيتم تنفيذها في حال توفّر شروط مختلفة.
- في برنامجك، في
main()
، اختَر الرمز من عبارةif
الأولى إلى القوس المعقوف}
الذي يغلق عبارةelse
الأخيرة واحذفه.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
}
- في
main()
، أسفل تعريفluckyNumber
، أنشئ عبارةwhen
. بما أنّwhen
يجب أن يتم اختباره مقابل النتيجة التي تم طرحها، ضَعrollResult
بين الأقواس()
. أضِف أقواسًا معقوفة{}
مع بعض المسافات الإضافية، كما هو موضّح أدناه.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
}
}
كما كان من قبل، اختبِر أولاً ما إذا كان rollResult
هو نفسه luckyNumber
.
- داخل الأقواس المتعرّجة
{}
لعبارةwhen
، أضِف عبارة تختبرrollResult
مقابلluckyNumber
، وإذا كانا متطابقَين، اطبع الرسالة الفائزة. يبدو البيان على النحو التالي:
luckyNumber -> println("You win!")
وهذا يعني ما يلي:
- عليك أولاً وضع القيمة التي تريد مقارنتها بـ
rollResult
. هذا هوluckyNumber
. - أضِف بعد ذلك سهمًا (
->
). - بعد ذلك، أضِف الإجراء الذي سيتم تنفيذه في حال العثور على تطابق.
يمكن قراءة ذلك على النحو التالي: "إذا كان rollResult
هو luckyNumber
، اطبع الرسالة "You win!"
".
وسيبدو رمز main()
على النحو التالي.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You win!")
}
}
- استخدِم النمط نفسه لإضافة أسطر ورسائل للأرقام المحتملة من 1 إلى 6، كما هو موضّح أدناه. يجب أن تبدو دالة
main()
المكتملة على النحو التالي.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You won!")
1 -> println("So sorry! You rolled a 1. Try again!")
2 -> println("Sadly, you rolled a 2. Try again!")
3 -> println("Unfortunately, you rolled a 3. Try again!")
4 -> println("No luck! You rolled a 4. Try again!")
5 -> println("Don't cry! You rolled a 5. Try again!")
6 -> println("Apologies! you rolled a 6. Try again!")
}
}
- تشغيل برنامجك لا يوجد فرق في الناتج، ولكن التعليمات البرمجية تكون أكثر إيجازًا وأسهل في القراءة.
تهانينا! لقد تعلّمت طريقتَين لطباعة الرسائل استنادًا إلى شرط معيّن. هذه أداة فعّالة لكتابة برامج مثيرة للاهتمام.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You won!")
1 -> println("So sorry! You rolled a 1. Try again!")
2 -> println("Sadly, you rolled a 2. Try again!")
3 -> println("Unfortunately, you rolled a 3. Try again!")
4 -> println("No luck! You rolled a 4. Try again!")
5 -> println("Don't cry! You rolled a 5. Try again!")
6 -> println("Apologies! you rolled a 6. Try again!")
}
}
class Dice(val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
- استخدِم عبارة
if
لضبط شرط لتنفيذ بعض التعليمات. على سبيل المثال، إذا حصل المستخدم على الرقم المحظوظ، اطبع رسالة فوز. - يحتوي نوع البيانات
Boolean
على القيمتينtrue
وfalse
ويمكن استخدامه لاتخاذ القرارات. - مقارنة القيم باستخدام عوامل التشغيل، مثل أكبر من (
>
) وأصغر من (<
) ويساوي (==
) - استخدِم سلسلة من عبارات
else if
لضبط شروط متعدّدة. على سبيل المثال، اطبع رسالة مختلفة لكل رمية نرد محتملة. - استخدِم عبارة
else
في نهاية سلسلة من الشروط لرصد أي حالات قد لا يتمّ تغطيتها بشكل صريح. إذا كنت تغطي حالات النرد ذي 6 أوجه، ستلتقط عبارةelse
الرقمَين 7 و8 اللذين تم رميهما بنرد ذي 8 أوجه. - استخدِم عبارة
when
كشكل مضغوط لتنفيذ الرمز البرمجي استنادًا إلى مقارنة قيمة.
يُرجى اتّباع الخطوات التالية:
- غيِّر
myFirstDice
ليتضمّن 8 أضلاع وشغِّل الرمز. الإجراء
ملاحظة: عند زيادة عدد الأضلاع، لن تغطّي عبارة when
جميع الحالات بعد الآن، لذا لن تتم طباعة أي شيء للحالات غير المغطّاة.
- أصلِح عبارة
when
لتشمل جميع الجوانب الثمانية. يمكنك إجراء ذلك عن طريق إضافة حالات للأرقام الإضافية. التحدي: بدلاً من إضافة حالة جديدة لكل رقم، استخدِم عبارةelse
لتغطية جميع الحالات التي لم يتم تناولها بشكل صريح.
ملاحظة: يمكنك إضافة المزيد من الحالات لتغطية المزيد من الجوانب. هذه طريقة جيدة لإجراء ذلك، إذا كنت تريد رسالة مختلفة لكل رقم يمكن طرحه. أو يمكنك استخدام عبارة else
وطباعة الرسالة نفسها لجميع الجوانب الأكبر من 6 التي يغطيها الرمز الحالي.
- غيِّر عدد أوجه النرد إلى 4 فقط.
myFirstDice
الإجراء
ملاحظة: لن يكون لتغيير عدد أوجه النرد إلى أقل من العدد الذي تغطيه عبارة when
أي تأثير ملحوظ، لأنّ جميع الحالات التي يمكن أن تحدث مشمولة.