כיתות ואובייקטים בקוטלין

ב-codelabs במסלול הזה, תיצרו אפליקציה לקוביות עם קוביות קוביות. כשהמשתמש "מטיל קוביות,&quot, נוצרת תוצאה אקראית. התוצאה מביאה בחשבון את מספר צידי הקוביות. לדוגמה, אפשר להעביר רק ערכים מ-1 עד 6 מקוביות בעלות 6 פאות.

כך תיראה האפליקציה הסופית.

כדי לעזור לכם להתמקד בקונספטים החדשים של התכנות של האפליקציה הזו, תצטרכו להשתמש בכלי התכנות המבוסס על דפדפן Kotlin כדי ליצור פונקציונליות מרכזית של האפליקציה. התוכנית תייצא את התוצאות למסוף. לאחר מכן תטמיעו את ממשק המשתמש ב-Android Studio.

במעבדת הקוד הראשונה הזו תיצרו תוכנית Kotlin שמדמה קוביות מתגלגלות ופלטת מספר אקראי, בדיוק כמו בקוביות.

דרישות מוקדמות

  • איך לפתוח, לערוך ולהפעיל קוד בכתובת https://try.kotlinlang.org/
  • יצירה והפעלה של תוכנת Kotlin שמשתמשת במשתנים ובפונקציות, ומדפיסה תוצאה במסוף.
  • עיצוב מספרים בתוך טקסט באמצעות תבנית מחרוזת עם ההערה ${variable}.

מה תלמדו

  • כיצד ליצור באופן תכליתי מספרים אקראיים כדי לדמות גלילות.
  • כדי לבנות את הקוד צריך ליצור כיתה Dice עם משתנה ושיטה.
  • איך יוצרים מופע של אובייקט בכיתה, משנים את המשתנים שלו וקוראים לשיטות שלו?

מה תפתחו

  • תוכנית Kotlin בכלי התכנות המבוססת על דפדפן Kotlin שיכולה לבצע קובייה אקראית.

מה צריך?

  • מחשב עם חיבור לאינטרנט

לעיתים קרובות יש במשחקים רכיב אקראי. אתם יכולים לזכות בפרס אקראי או לקדם מספר אקראי של שלבים בלוח המשחק. בחיי היומיום, אתם יכולים להשתמש במספרים אקראיים ובאותיות כדי ליצור סיסמאות בטוחות יותר!

במקום לכתוב קוביות בפועל, אתם יכולים לכתוב תוכנית שמדמה קוביות מתגלגלות. בכל פעם חדירה של קוביות, התוצאה יכולה להיות כל מספר בטווח הערכים האפשריים. למרבה המזל, אין צורך ליצור מחולל מספרים אקראיים עבור תוכנית כזו. לרוב שפות התכנות, כולל Kotlin, יש דרך מובנית ליצור מספרים אקראיים. במשימה הזו, תשתמשו בקוד של Kotlin כדי ליצור מספר אקראי.

הגדרת הקוד למתחילים

  1. בדפדפן, פותחים את האתר https://try.kotlinlang.org/.
  2. מוחקים את כל הקוד הקיים בעורך הקוד ומחליפים אותו בקוד שבהמשך. זוהי הפונקציה main() שעבדת עליה במעבדות קוד קודמות (ראה כתיבת תוכנית Kotlin הראשונה שלך).
fun main() {

}

שימוש בפונקציה הרנדומלית

כדי להטיל קוביות, נדרשת דרך לייצג את כל הערכים החוקיים של הקוביות. בקוביות רגילות בעלות 6 פאות, המכפלות בגודל קוביות הן: 1, 2, 3, 4, 5 ו-6.

בעבר למדת שיש סוגים של נתונים כמו Int למספרים שלמים ו-String לטקסט. IntRange הוא סוג נתונים נוסף, והוא מייצג טווח של מספרים שלמים החל מנקודת התחלה ועד לנקודת קצה. IntRange הוא סוג נתונים מתאים לייצוג הערכים האפשריים שניתן לייצר באמצעות קוביות.

  1. בפונקציה main(), מגדירים משתנה כ-val בשם diceRange. יש להקצות אותה לערך IntRange בין 1 ל-6, מייצג את הטווח של מספרים שלמים שיש לה 6 פאות.
val diceRange = 1..6

אפשר לציין שטווח 1..6 הוא קוטן כי יש לו מספר התחלה, שתי נקודות ולאחר מכן מספר סיום (אין רווחים בין התווים). דוגמאות נוספות לטווחים של מספרים שלמים הן 2..5 עבור המספרים 2 עד 5 ו-100..200 עבור המספרים 100 עד 200.

בדומה לאופן שבו המערכת של println() מורה למערכת להדפיס את הטקסט הנתון, ניתן להשתמש בפונקציה שנקראת random() כדי להפיק ולהחזיר מספר אקראי בטווח נתון. כמו קודם, אפשר לאחסן את התוצאה במשתנה.

  1. בתוך main(), מגדירים משתנה כ-val בשם randomNumber.
  2. הערך של randomNumber יכול להיות הערך של ביצוע הקריאה ל-random() בטווח diceRange, כמוצג למטה.
 val randomNumber = diceRange.random()

חשוב לציין שאת/ה מתקשר/ת אל random() ברחוב diceRange באמצעות נקודה או נקודה, בין המשתנה לקריאה לפונקציה. אפשר לקרוא זאת כ-"יצירת מספר אקראי מ-diceRange" והתוצאה מאוחסנת לאחר מכן במשתנה randomNumber.

  1. כדי לראות את המספר שנוצר באופן אקראי, ניתן להשתמש בפורמט הפורמט של מחרוזת (שנקרא גם "string&" ) ${randomNumber} כדי להדפיס אותו, כפי שמוצג בהמשך.
println("Random number: ${randomNumber}")

הקוד הסופי אמור להיראות כך.

fun main() {
    val diceRange = 1..6
    val randomNumber = diceRange.random()
    println("Random number: ${randomNumber}")
}
  1. מריצים את הקוד מספר פעמים. בכל פעם אמורה להופיע פלט בהמשך, עם מספרים אקראיים שונים.
Random number: 4

כשמטילים קוביות, הם אובייקטים אמיתיים ביד. הקוד שכתבתם עובד ללא בעיה, אבל קשה לדמיין שמדובר בקוביות אמיתיות. ארגון תוכנית באופן שדומה יותר למה שהיא מייצגת מאפשר לכם להבין אותה בקלות. איזה כיף שיש לך קוביות פרוגרמטיות שאפשר להקצות!

כל הקוביות פועלות באותו אופן. יש להם מאפיינים זהים, למשל לצדדים, וההתנהגות שלהם זהה לזו של הגרסה. בקוטלין אפשר ליצור שרטוט פרוגרמטי של קוביות שעולה הקוביות, ולשייך מספר אקראי. התרשים הזה נקרא כיתה.

לאחר מכן אתם יכולים ליצור אובייקטים של קוביות בפועל שנקרא אובייקטים של אובייקט. לדוגמה, אפשר ליצור קוביות עם 12 פאות או קוביות דו-צדדיות.

הגדרה של רמת קוביות

בשלבים הבאים עליך להגדיר כיתה חדשה בשם Dice כדי לייצג קוביות מתגלגלות.

  1. כדי להתחיל מחדש, צריך לנקות את הקוד בפונקציה main() כדי לקבל את הקוד כפי שמוצג בהמשך.
fun main() {

}
  1. מתחת לפונקציה main(), צריך להוסיף שורה ריקה ואז להוסיף קוד כדי ליצור את הכיתה Dice. כפי שמוצג למטה, התחילו עם מילת המפתח class, ולאחר מכן את שם הכיתה, ואחריו סוגריים פותחים וסוגרים. יש להשאיר רווח בין הסוגריים המסולסלים כדי למקם את הקוד של הכיתה.
class Dice {

}

בתוך הגדרת כיתה, אפשר לציין מאפיין אחד או יותר לכיתה באמצעות משתנים. לקוביות אמיתיות יכול להיות מספר צד, צבע או משקל. במשימה הזו תתמקדו בנכס של מספר צידי הקוביות.

  1. בתוך הכיתה Dice, יש להוסיף var בשם sides למספר הקוביות שיתקבלו. יש להגדיר את sides ל-6.
class Dice {
    var sides = 6
}

זה הכל. עכשיו יש לכם כיתה פשוטה מאוד שמייצגת קוביות.

יצירת מופע של מחלקת הקוביות

בקורס הזה (Dice) יש שרטוט של הקוביות. כדי ליצור קוביות בפועל, עליך ליצור מופע של אובייקט Dice. (אם אתם צריכים לקבל שלוש קוביות, עליכם ליצור שלוש מופעים של אובייקטים.)

  1. כדי ליצור מופע אובייקט של Dice, בפונקציה main() צריך ליצור val בשם myFirstDice ולהפעיל אותו כמופע של הכיתה Dice. שימו לב בסוגריים אחרי שם הכיתה, שמציינים שאתם יוצרים מופע אובייקט חדש מהכיתה.
fun main() {
    val myFirstDice = Dice()
}

עכשיו, אחרי שיש לך אובייקט myFirstDice, פריט שנוצר מהשרטוט, יש לך גישה לתכונות שלו. הנכס היחיד של Dice הוא sides. הגישה לנכס מתבצעת באמצעות &מירכאות ;dot". לכן, כדי לגשת לנכס sides של myFirstDice, אפשר להתקשר ל-myFirstDice.sides. הגייה היא "myFirstDice נקודה sides"

  1. מתחת להצהרה על myFirstDice, יש להוסיף הצהרה מסוג println() כדי להציג את המספר sides של myFirstDice.
println(myFirstDice.sides)

הקוד שלכם אמור להיראות כך.

fun main() {
    val myFirstDice = Dice()
    println(myFirstDice.sides)
}

class Dice {
    var sides = 6
}
  1. יש להפעיל את התוכנית והיא אמורה להציג את מספר ה-sides שהוגדרו במחלקה Dice.
6

יש לך עכשיו מחלקה Dice וקוביות בפועל myFirstDice עם 6 sides.

משחקי קוביות!

משחקי קוביות

השתמשת בעבר בפונקציה כדי לבצע את הפעולה של הדפסת שכבות של עוגה. הטלת קוביות היא גם פעולה שניתן ליישם כפונקציה. ומאחר שניתן להעביר את כל הקוביות, אפשר להוסיף לו פונקציה בתוך הכיתה Dice. פונקציה שמוגדרת בתוך כיתה נקראת גם method.

  1. בכיתה Dice, מתחת למשתנה sides, מזינים שורה ריקה ואז יוצרים פונקציה חדשה כדי להטיל קוביות. התחילו עם מילת המפתח קוטלין fun, ולאחר מכן את שם השיטה, לאחר מכן את הסוגריים (), ולאחר מכן פתחו וסגרו את הסוגריים המסולסלים {}. ניתן להשאיר שורה ריקה בין הסוגריים המסולסלים כדי לפנות מקום לקוד נוסף, כפי שמוצג בהמשך. הכיתה שלך אמורה להיראות כך.
class Dice {
    var sides = 6

    fun roll() {

    }
}

כשמטילים קוביות דו-צדדיות, נוצר מספר אקראי בין 1 ל-6.

  1. בתוך השיטה roll(), יוצרים val randomNumber. יש להקצות מספר אקראי בטווח של 1..6. משתמשים בסימון הנקודה כדי להתקשר אל random() בטווח.
val randomNumber = (1..6).random()
  1. לאחר שיוצרים את המספר האקראי, מדפיסים אותו למסוף. השיטה המסתיימת שלך ב-roll() אמורה להיראות כמו הקוד הבא.
fun roll() {
     val randomNumber = (1..6).random()
     println(randomNumber)
}
  1. כדי להפעיל את myFirstDice בפועל, בmain() צריך להתקשר לשיטה roll() בתאריך myFirstDice. אתם קוראים לשיטה באמצעות "dot point". לכן, כדי לקרוא לשיטה roll() של myFirstDice, עליכם להקליד myFirstDice.roll() שמייצג את ההגייה &"myFirstDice נקודה roll()"
myFirstDice.roll()

הקוד המלא אמור להיראות כך.

fun main() {
    val myFirstDice = Dice()
    println(myFirstDice.sides)
    myFirstDice.roll()
}

class Dice {
    var sides = 6

    fun roll() {
        val randomNumber = (1..6).random()
        println(randomNumber)
    }
}
  1. רוצה להריץ את הקוד? אמורה להופיע תוצאה של הטלת קובייה אקראית מתחת למספר הצדדים. מפעילים את הקוד מספר פעמים ושימו לב שמספר הצדדים לא משתנה, וערך הקובייה משתנה.
6
4

מעולה! הגדרת מחלקה Dice עם משתנה sides ופונקציה roll(). בפונקציה main() יצרת מופע חדש של אובייקט Dice, ולאחר מכן התקשרת לשיטה roll() כדי ליצור מספר אקראי.

בשלב זה בחרת להדפיס את הערך של randomNumber בפונקציה roll(), וזה עובד נהדר! אבל לפעמים זה שימושי יותר להחזיר את התוצאה של הפונקציה כלשהי לפונקציה. לדוגמה, אפשר להקצות את התוצאה של השיטה roll() למשתנה, ולאחר מכן להזיז את השחקן לפי הסכום הזה! בואו נראה איך זה עובד.

  1. בmain() צריך לשנות את השורה שבה כתוב myFirstDice.roll(). יצירה של val בשם diceRoll. יש להגדיר אותו שווה לערך שהתקבל בשיטת roll().
val diceRoll = myFirstDice.roll()

הפעולה הזו עדיין לא מתבצעת, כי roll() עדיין לא מחזיר משהו. כדי שהקוד הזה יפעל כראוי, roll() צריך להחזיר משהו.

במעבדות קוד קודמות למדת שעליך לציין סוג נתונים כדי להשתמש בארגומנטים להזנת פונקציות. באותו אופן, צריך לציין סוג נתונים לנתונים שהפונקציה מחזירה.

  1. יש לשנות את הפונקציה roll() כדי לציין את סוג הנתונים שיוחזרו. במקרה הזה, המספר האקראי הוא Int, כך שסוג ההחזרה הוא Int. התחביר של ציון סוג ההחזרה הוא: אחרי שם הפונקציה, אחרי הסוגריים, מוסיפים נקודתיים, רווח ולאחר מכן את מילת המפתח Int עבור סוג ההחזרה. הגדרת הפונקציה צריכה להיראות כמו הקוד הבא.
fun roll(): Int {
  1. הרצת הקוד הזה. תופיע שגיאה בתצוגת הבעיות. כתוב:
A ‘return'  expression is required in a function with a block body. 

שינית את הגדרת הפונקציה כדי להחזיר Int, אבל המערכת מתלוננת על כך

הקוד לא מחזיר בפועל Int. "Block body" או "function body" מתייחס לקוד שבין הסוגריים המסולסלים של פונקציה. כדי לתקן את השגיאה, אפשר להחזיר ערך מפונקציה באמצעות הצהרת return בסוף גוף הפונקציה.

  1. ב-roll(), יש להסיר את ההצהרה println() ולהחליף אותה בהצהרת return עבור randomNumber. הפונקציה roll() צריכה להיראות כמו הקוד הבא.
fun roll(): Int {
     val randomNumber = (1..6).random()
     return randomNumber
}
  1. בmain(), מסירים את הצהרת ההדפסה בצידי הקוביות.
  2. צריך להוסיף הצהרה כדי להדפיס את הערך של sides ושל diceRoll במשפט אינפורמטיבי. הפונקציה main() שהסתיימה אמורה להיראות דומה לקוד שבהמשך.
fun main() {
    val myFirstDice = Dice()
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.sides} sided dice rolled ${diceRoll}!")
}
  1. מריצים את הקוד והפלט אמור להיראות כך.
Your 6 sided dice rolled 4!

הנה כל הקוד שלך עד עכשיו.

fun main() {
    val myFirstDice = Dice()
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.sides} sided dice rolled ${diceRoll}!")
}


class Dice {
    var sides = 6

    fun roll(): Int {
        val randomNumber = (1..6).random()
        return randomNumber
    }
}

לא לכל הקוביות יש 6 פאות! הקוביות זמינות בכל צורה ובכל גודל: 4 צדדים, 8 צדדים, עד 120 צדדים!

  1. בשיעור Dice, בשיטת roll(), יש לשנות את 1..6 לקוד בתוך הקוד כך שישתמש במקום זאת, כך שהטווח, כלומר המספר האקראי, יהיה תמיד תואם למספר הצדדים.
val randomNumber = (1..sides).random()
  1. בפונקציה main(), אחרי ואחרי הדפסת הקובייה, משנים את הערך של sides בFirstDice ל-20.
myFirstDice.sides = 20
  1. עליך להעתיק ולהדביק את הצהרת ההדפסה הקיימת למטה, אחרי התקופה שבה שינית את מספר הצדדים.
  2. יש להחליף את ההדפסה של diceRoll בהדפסה של תוצאת הקריאה לשיטה roll() במכשיר myFirstDice.
println("Your ${myFirstDice.sides} sided dice has rolled a ${myFirstDice.roll()}!")

התוכנית שלכם אמורה להיראות כך.

fun main() {
   
    val myFirstDice = Dice()
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.sides} sided dice rolled ${diceRoll}!")

    myFirstDice.sides = 20
    println("Your ${myFirstDice.sides} sided dice rolled ${myFirstDice.roll()}!")
}

class Dice {
    var sides = 6

    fun roll(): Int {
        val randomNumber = (1..sides).random()
        return randomNumber
    }
}
  1. הפעל את התוכנית שלך. אמורה להופיע הודעה עם קוביות דו-צדדיות, והודעה שנייה עם קוביות דו-צדדיות.
Your 6 sided dice rolled 3!
Your 20 sided dice rolled 15!

הרעיון של כיתה הוא לייצג משהו, לעיתים קרובות משהו פיזי בעולם האמיתי. במקרה כזה, סיווג Dice מייצג קוביות פיזיות. בעולם האמיתי, קוביות לא יכולות לשנות את מספר הצדדים שלהן. אם רוצים מספר צד אחר, יש לבחור קוביות אחרות. ב

במשימה הזו צריך לשנות את המחלקה Dice כדי לציין את מספר הצדדים כשיוצרים מכונה חדשה. צריך לשנות את הגדרת הכיתה Dice כדי לקבל ארגומנט של מספר הצדדים. היא דומה לאופן שבו פונקציה יכולה לקבל ארגומנטים לקלט.

  1. יש לשנות את הגדרת הכיתה Dice כדי לקבל ארגומנט מספר שלם בשם numSides. הקוד של הכיתה לא משתנה.
class Dice(val numSides: Int) {
   // Code inside does not change.
}
  1. בתוך המחלקה Dice, מוחקים את המשתנה sides, מפני שעכשיו אפשר להשתמש ב-numSides.
  2. בנוסף, יש לתקן את הטווח כדי להשתמש ב-numSides.

הכיתה שלך ב-Dice אמורה להיראות כך.

class Dice (val numSides: Int) {

    fun roll(): Int {
        val randomNumber = (1..numSides).random()
        return randomNumber
    }
}

אם הקוד הזה יופעל, יופיעו שגיאות רבות, כי עליכם לעדכן את main() כדי לעבוד עם השינויים בכיתה Dice.

  1. בעוד main(), כדי ליצור את myFirstDice עם 6 צדדים, עליך להעביר את מספר הצדדים כארגומנט לכיתה Dice, כפי שמוצג למטה.
    val myFirstDice = Dice(6)
  1. בהצהרת ההדפסה, יש לשנות את sides ל-numSides.
  2. לאחר מכן, צריך למחוק את הקוד שמשנים את sides ל-20, כי המשתנה הזה כבר לא קיים.
  3. גם ההצהרה println תימחק מתחתיה.

הפונקציה main() אמורה להיראות כמו הקוד הבא. אם הפעלת אותה, לא אמורות להיות שגיאות.

fun main() {
    val myFirstDice = Dice(6)
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.numSides} sided dice rolled ${diceRoll}!")
}
  1. אחרי שמדפיסים את הטלת הקובייה הראשונה, מוסיפים את הקוד כדי ליצור ולהדפיס אובייקט Dice נוסף בשם mySecondDice עם 20 צדדים.
    val mySecondDice = Dice(20)
  1. מוסיפים הצהרה מודפסת שמגלשת ומחזירה את הערך שהוחזר.
println("Your ${mySecondDice.numSides} sided dice rolled  ${mySecondDice.roll()}!")
  1. הפונקציה main() אמורה להיראות כך.
fun main() {
    val myFirstDice = Dice(6)
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.numSides} sided dice rolled ${diceRoll}!")
    
    val mySecondDice = Dice(20)
    println("Your ${mySecondDice.numSides} sided dice rolled ${mySecondDice.roll()}!")
}

class Dice (val numSides: Int) {

    fun roll(): Int {
        val randomNumber = (1..numSides).random()
        return randomNumber
    }
}
  1. מריצים את התוכנית המוגמרת, והפלט אמור להיראות כך.
Your 6 sided dice rolled 5!
Your 20 sided dice rolled 7!

כשכותבים קוד, תמציתי יותר. אפשר להסיר את המשתנה randomNumber ולהחזיר את המספר האקראי ישירות.

  1. יש לשנות את ההצהרה return כדי להחזיר את המספר האקראי ישירות.
    fun roll(): Int {
        return (1..numSides).random()
    }

בהצהרת ההדפסה השנייה, מגדירים את הקריאה להפעלת המספר האקראי בתבנית המחרוזת. אפשר להסיר את המשתנה diceRoll באמצעות אותה פעולה בהצהרה הראשונה המודפסת.

  1. יש להתקשר אל myFirstDice.roll() בתבנית המחרוזת ולמחוק את המשתנה diceRoll. שתי השורות הראשונות של הקוד הראשי שלכם נראות עכשיו.
    val myFirstDice = Dice(6)
    println("Your ${myFirstDice.numSides} sided dice rolled ${myFirstDice.roll()}!")
  1. מפעילים את הקוד ולא אמור להיות הבדל בפלט.

זהו הקוד הסופי לאחר החישוב מחדש שלו .

fun main() {
    val myFirstDice = Dice(6)
    println("Your ${myFirstDice.numSides} sided dice rolled ${myFirstDice.roll()}!")
    
    val mySecondDice = Dice(20)
    println("Your ${mySecondDice.numSides} sided dice rolled ${mySecondDice.roll()}!")
}

class Dice (val numSides: Int) {

    fun roll(): Int {
        return (1..numSides).random()
    }
}
fun main() {
    val myFirstDice = Dice(6)
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.numSides} sided dice rolled ${diceRoll}!")
    
    val mySecondDice = Dice(20)
    println("Your ${mySecondDice.numSides} sided dice rolled ${mySecondDice.roll()}!")
}

class Dice (val numSides: Int) {

    fun roll(): Int {
        return (1..numSides).random()
    }
}
  • יש להתקשר אל הפונקציה random() בIntRange כדי ליצור מספר אקראי: (1..6).random()
  • כיתות דומות לציור של אובייקט. הם יכולים לקבל מאפיינים והתנהגויות, שמוטמעים כמשתנים ופונקציות.
  • מופע של כיתה מייצג אובייקט, לעיתים קרובות אובייקט פיזי, כמו קוביות. ניתן להפעיל את פעולות האובייקט ולשנות את המאפיינים שלו.
  • אפשר להעביר קלט לכיתה כאשר יוצרים מכונה על ידי ציון ארגומנט להגדרת ההגדרה. לדוגמה: class Dice(val numSides: Int) ואז יוצרים מכונה עם Dice(6).
  • הפונקציות יכולות להחזיר משהו. יש לציין את סוג הנתונים שיוחזרו בהגדרת הפונקציה, ולהשתמש בהצהרת return בגוף הפונקציה כדי להחזיר משהו. למשל: fun example(): Int { return 5 }

מבצעים את הפעולות הבאות:

  • יש לתת לכיתה Dice מאפיין צבע נוסף וליצור מופעים מרובים של קוביות עם מספר שונה של פאות וצבעים!
  • אתם יכולים ליצור כיתה אחת (Coin), לתת לה את היכולת להפוך, ליצור מופע של הכיתה ולהפוך כמה מטבעות! איך משתמשים בפונקציה אקראית (בטווח) כדי לקבוע את הטלת המטבע?