ב-codelabs במסלול הזה, תיצרו אפליקציה לקוביות עם קוביות קוביות. כשהמשתמש "מטיל קוביות,", נוצרת תוצאה אקראית. התוצאה מביאה בחשבון את מספר צידי הקוביות. לדוגמה, אפשר להעביר רק ערכים מ-1 עד 6 מקוביות בעלות 6 פאות.
כך תיראה האפליקציה הסופית.
כדי לעזור לכם להתמקד בקונספטים החדשים של התכנות של האפליקציה הזו, תצטרכו להשתמש בכלי התכנות המבוסס על דפדפן Kotlin כדי ליצור פונקציונליות מרכזית של האפליקציה. התוכנית תייצא את התוצאות למסוף. לאחר מכן תטמיעו את ממשק המשתמש ב-Android Studio.
במעבדת הקוד הראשונה הזו תיצרו תוכנית Kotlin שמדמה קוביות מתגלגלות ופלטת מספר אקראי, בדיוק כמו בקוביות.
דרישות מוקדמות
- איך לפתוח, לערוך ולהפעיל קוד בכתובת https://try.kotlinlang.org/
- יצירה והפעלה של תוכנת Kotlin שמשתמשת במשתנים ובפונקציות, ומדפיסה תוצאה במסוף.
- עיצוב מספרים בתוך טקסט באמצעות תבנית מחרוזת עם ההערה
${variable}
.
מה תלמדו
- כיצד ליצור באופן תכליתי מספרים אקראיים כדי לדמות גלילות.
- כדי לבנות את הקוד צריך ליצור כיתה
Dice
עם משתנה ושיטה. - איך יוצרים מופע של אובייקט בכיתה, משנים את המשתנים שלו וקוראים לשיטות שלו?
מה תפתחו
- תוכנית Kotlin בכלי התכנות המבוססת על דפדפן Kotlin שיכולה לבצע קובייה אקראית.
מה צריך?
- מחשב עם חיבור לאינטרנט
לעיתים קרובות יש במשחקים רכיב אקראי. אתם יכולים לזכות בפרס אקראי או לקדם מספר אקראי של שלבים בלוח המשחק. בחיי היומיום, אתם יכולים להשתמש במספרים אקראיים ובאותיות כדי ליצור סיסמאות בטוחות יותר!
במקום לכתוב קוביות בפועל, אתם יכולים לכתוב תוכנית שמדמה קוביות מתגלגלות. בכל פעם חדירה של קוביות, התוצאה יכולה להיות כל מספר בטווח הערכים האפשריים. למרבה המזל, אין צורך ליצור מחולל מספרים אקראיים עבור תוכנית כזו. לרוב שפות התכנות, כולל Kotlin, יש דרך מובנית ליצור מספרים אקראיים. במשימה הזו, תשתמשו בקוד של Kotlin כדי ליצור מספר אקראי.
הגדרת הקוד למתחילים
- בדפדפן, פותחים את האתר https://try.kotlinlang.org/.
- מוחקים את כל הקוד הקיים בעורך הקוד ומחליפים אותו בקוד שבהמשך. זוהי הפונקציה
main()
שעבדת עליה במעבדות קוד קודמות (ראה כתיבת תוכנית Kotlin הראשונה שלך).
fun main() {
}
שימוש בפונקציה הרנדומלית
כדי להטיל קוביות, נדרשת דרך לייצג את כל הערכים החוקיים של הקוביות. בקוביות רגילות בעלות 6 פאות, המכפלות בגודל קוביות הן: 1, 2, 3, 4, 5 ו-6.
בעבר למדת שיש סוגים של נתונים כמו Int
למספרים שלמים ו-String
לטקסט. IntRange
הוא סוג נתונים נוסף, והוא מייצג טווח של מספרים שלמים החל מנקודת התחלה ועד לנקודת קצה. IntRange
הוא סוג נתונים מתאים לייצוג הערכים האפשריים שניתן לייצר באמצעות קוביות.
- בפונקציה
main()
, מגדירים משתנה כ-val
בשםdiceRange
. יש להקצות אותה לערךIntRange
בין 1 ל-6, מייצג את הטווח של מספרים שלמים שיש לה 6 פאות.
val diceRange = 1..6
אפשר לציין שטווח 1..6
הוא קוטן כי יש לו מספר התחלה, שתי נקודות ולאחר מכן מספר סיום (אין רווחים בין התווים). דוגמאות נוספות לטווחים של מספרים שלמים הן 2..5
עבור המספרים 2 עד 5 ו-100..200
עבור המספרים 100 עד 200.
בדומה לאופן שבו המערכת של println()
מורה למערכת להדפיס את הטקסט הנתון, ניתן להשתמש בפונקציה שנקראת random()
כדי להפיק ולהחזיר מספר אקראי בטווח נתון. כמו קודם, אפשר לאחסן את התוצאה במשתנה.
- בתוך
main()
, מגדירים משתנה כ-val
בשםrandomNumber
. - הערך של
randomNumber
יכול להיות הערך של ביצוע הקריאה ל-random()
בטווחdiceRange
, כמוצג למטה.
val randomNumber = diceRange.random()
חשוב לציין שאת/ה מתקשר/ת אל random()
ברחוב diceRange
באמצעות נקודה או נקודה, בין המשתנה לקריאה לפונקציה. אפשר לקרוא זאת כ-"יצירת מספר אקראי מ-diceRange
" והתוצאה מאוחסנת לאחר מכן במשתנה randomNumber
.
- כדי לראות את המספר שנוצר באופן אקראי, ניתן להשתמש בפורמט הפורמט של מחרוזת (שנקרא גם "string&" )
${randomNumber}
כדי להדפיס אותו, כפי שמוצג בהמשך.
println("Random number: ${randomNumber}")
הקוד הסופי אמור להיראות כך.
fun main() {
val diceRange = 1..6
val randomNumber = diceRange.random()
println("Random number: ${randomNumber}")
}
- מריצים את הקוד מספר פעמים. בכל פעם אמורה להופיע פלט בהמשך, עם מספרים אקראיים שונים.
Random number: 4
כשמטילים קוביות, הם אובייקטים אמיתיים ביד. הקוד שכתבתם עובד ללא בעיה, אבל קשה לדמיין שמדובר בקוביות אמיתיות. ארגון תוכנית באופן שדומה יותר למה שהיא מייצגת מאפשר לכם להבין אותה בקלות. איזה כיף שיש לך קוביות פרוגרמטיות שאפשר להקצות!
כל הקוביות פועלות באותו אופן. יש להם מאפיינים זהים, למשל לצדדים, וההתנהגות שלהם זהה לזו של הגרסה. בקוטלין אפשר ליצור שרטוט פרוגרמטי של קוביות שעולה הקוביות, ולשייך מספר אקראי. התרשים הזה נקרא כיתה.
לאחר מכן אתם יכולים ליצור אובייקטים של קוביות בפועל שנקרא אובייקטים של אובייקט. לדוגמה, אפשר ליצור קוביות עם 12 פאות או קוביות דו-צדדיות.
הגדרה של רמת קוביות
בשלבים הבאים עליך להגדיר כיתה חדשה בשם Dice
כדי לייצג קוביות מתגלגלות.
- כדי להתחיל מחדש, צריך לנקות את הקוד בפונקציה
main()
כדי לקבל את הקוד כפי שמוצג בהמשך.
fun main() {
}
- מתחת לפונקציה
main()
, צריך להוסיף שורה ריקה ואז להוסיף קוד כדי ליצור את הכיתהDice
. כפי שמוצג למטה, התחילו עם מילת המפתחclass
, ולאחר מכן את שם הכיתה, ואחריו סוגריים פותחים וסוגרים. יש להשאיר רווח בין הסוגריים המסולסלים כדי למקם את הקוד של הכיתה.
class Dice {
}
בתוך הגדרת כיתה, אפשר לציין מאפיין אחד או יותר לכיתה באמצעות משתנים. לקוביות אמיתיות יכול להיות מספר צד, צבע או משקל. במשימה הזו תתמקדו בנכס של מספר צידי הקוביות.
- בתוך הכיתה
Dice
, יש להוסיףvar
בשםsides
למספר הקוביות שיתקבלו. יש להגדיר אתsides
ל-6.
class Dice {
var sides = 6
}
זה הכל. עכשיו יש לכם כיתה פשוטה מאוד שמייצגת קוביות.
יצירת מופע של מחלקת הקוביות
בקורס הזה (Dice
) יש שרטוט של הקוביות. כדי ליצור קוביות בפועל, עליך ליצור מופע של אובייקט Dice
. (אם אתם צריכים לקבל שלוש קוביות, עליכם ליצור שלוש מופעים של אובייקטים.)
- כדי ליצור מופע אובייקט של
Dice
, בפונקציהmain()
צריך ליצורval
בשםmyFirstDice
ולהפעיל אותו כמופע של הכיתהDice
. שימו לב בסוגריים אחרי שם הכיתה, שמציינים שאתם יוצרים מופע אובייקט חדש מהכיתה.
fun main() {
val myFirstDice = Dice()
}
עכשיו, אחרי שיש לך אובייקט myFirstDice
, פריט שנוצר מהשרטוט, יש לך גישה לתכונות שלו. הנכס היחיד של Dice
הוא sides
. הגישה לנכס מתבצעת באמצעות &מירכאות ;dot". לכן, כדי לגשת לנכס sides
של myFirstDice
, אפשר להתקשר ל-myFirstDice.sides
. הגייה היא "myFirstDice
נקודה sides
"
- מתחת להצהרה על
myFirstDice
, יש להוסיף הצהרה מסוגprintln()
כדי להציג את המספרsides
שלmyFirstDice.
println(myFirstDice.sides)
הקוד שלכם אמור להיראות כך.
fun main() {
val myFirstDice = Dice()
println(myFirstDice.sides)
}
class Dice {
var sides = 6
}
- יש להפעיל את התוכנית והיא אמורה להציג את מספר ה-
sides
שהוגדרו במחלקהDice
.
6
יש לך עכשיו מחלקה Dice
וקוביות בפועל myFirstDice
עם 6 sides
.
משחקי קוביות!
משחקי קוביות
השתמשת בעבר בפונקציה כדי לבצע את הפעולה של הדפסת שכבות של עוגה. הטלת קוביות היא גם פעולה שניתן ליישם כפונקציה. ומאחר שניתן להעביר את כל הקוביות, אפשר להוסיף לו פונקציה בתוך הכיתה Dice
. פונקציה שמוגדרת בתוך כיתה נקראת גם method.
- בכיתה
Dice
, מתחת למשתנהsides
, מזינים שורה ריקה ואז יוצרים פונקציה חדשה כדי להטיל קוביות. התחילו עם מילת המפתח קוטליןfun
, ולאחר מכן את שם השיטה, לאחר מכן את הסוגריים()
, ולאחר מכן פתחו וסגרו את הסוגריים המסולסלים{}
. ניתן להשאיר שורה ריקה בין הסוגריים המסולסלים כדי לפנות מקום לקוד נוסף, כפי שמוצג בהמשך. הכיתה שלך אמורה להיראות כך.
class Dice {
var sides = 6
fun roll() {
}
}
כשמטילים קוביות דו-צדדיות, נוצר מספר אקראי בין 1 ל-6.
- בתוך השיטה
roll()
, יוצריםval randomNumber
. יש להקצות מספר אקראי בטווח של1..6
. משתמשים בסימון הנקודה כדי להתקשר אלrandom()
בטווח.
val randomNumber = (1..6).random()
- לאחר שיוצרים את המספר האקראי, מדפיסים אותו למסוף. השיטה המסתיימת שלך ב-
roll()
אמורה להיראות כמו הקוד הבא.
fun roll() {
val randomNumber = (1..6).random()
println(randomNumber)
}
- כדי להפעיל את
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)
}
}
- רוצה להריץ את הקוד? אמורה להופיע תוצאה של הטלת קובייה אקראית מתחת למספר הצדדים. מפעילים את הקוד מספר פעמים ושימו לב שמספר הצדדים לא משתנה, וערך הקובייה משתנה.
6 4
מעולה! הגדרת מחלקה Dice
עם משתנה sides
ופונקציה roll()
. בפונקציה main()
יצרת מופע חדש של אובייקט Dice
, ולאחר מכן התקשרת לשיטה roll()
כדי ליצור מספר אקראי.
בשלב זה בחרת להדפיס את הערך של randomNumber
בפונקציה roll()
, וזה עובד נהדר! אבל לפעמים זה שימושי יותר להחזיר את התוצאה של הפונקציה כלשהי לפונקציה. לדוגמה, אפשר להקצות את התוצאה של השיטה roll()
למשתנה, ולאחר מכן להזיז את השחקן לפי הסכום הזה! בואו נראה איך זה עובד.
- ב
main()
צריך לשנות את השורה שבה כתובmyFirstDice.roll()
. יצירה שלval
בשםdiceRoll
. יש להגדיר אותו שווה לערך שהתקבל בשיטתroll()
.
val diceRoll = myFirstDice.roll()
הפעולה הזו עדיין לא מתבצעת, כי roll()
עדיין לא מחזיר משהו. כדי שהקוד הזה יפעל כראוי, roll()
צריך להחזיר משהו.
במעבדות קוד קודמות למדת שעליך לציין סוג נתונים כדי להשתמש בארגומנטים להזנת פונקציות. באותו אופן, צריך לציין סוג נתונים לנתונים שהפונקציה מחזירה.
- יש לשנות את הפונקציה
roll()
כדי לציין את סוג הנתונים שיוחזרו. במקרה הזה, המספר האקראי הואInt
, כך שסוג ההחזרה הואInt
. התחביר של ציון סוג ההחזרה הוא: אחרי שם הפונקציה, אחרי הסוגריים, מוסיפים נקודתיים, רווח ולאחר מכן את מילת המפתחInt
עבור סוג ההחזרה. הגדרת הפונקציה צריכה להיראות כמו הקוד הבא.
fun roll(): Int {
- הרצת הקוד הזה. תופיע שגיאה בתצוגת הבעיות. כתוב:
A ‘return' expression is required in a function with a block body.
שינית את הגדרת הפונקציה כדי להחזיר Int
, אבל המערכת מתלוננת על כך
הקוד לא מחזיר בפועל Int
. "Block body" או "function body" מתייחס לקוד שבין הסוגריים המסולסלים של פונקציה. כדי לתקן את השגיאה, אפשר להחזיר ערך מפונקציה באמצעות הצהרת return
בסוף גוף הפונקציה.
- ב-
roll()
, יש להסיר את ההצהרהprintln()
ולהחליף אותה בהצהרתreturn
עבורrandomNumber
. הפונקציהroll()
צריכה להיראות כמו הקוד הבא.
fun roll(): Int {
val randomNumber = (1..6).random()
return randomNumber
}
- ב
main()
, מסירים את הצהרת ההדפסה בצידי הקוביות. - צריך להוסיף הצהרה כדי להדפיס את הערך של
sides
ושלdiceRoll
במשפט אינפורמטיבי. הפונקציהmain()
שהסתיימה אמורה להיראות דומה לקוד שבהמשך.
fun main() {
val myFirstDice = Dice()
val diceRoll = myFirstDice.roll()
println("Your ${myFirstDice.sides} sided dice rolled ${diceRoll}!")
}
- מריצים את הקוד והפלט אמור להיראות כך.
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 צדדים!
- בשיעור
Dice
, בשיטתroll()
, יש לשנות את1..6
לקוד בתוך הקוד כך שישתמש במקום זאת, כך שהטווח, כלומר המספר האקראי, יהיה תמיד תואם למספר הצדדים.
val randomNumber = (1..sides).random()
- בפונקציה
main()
, אחרי ואחרי הדפסת הקובייה, משנים את הערך שלsides
בFirstDice
ל-20.
myFirstDice.sides = 20
- עליך להעתיק ולהדביק את הצהרת ההדפסה הקיימת למטה, אחרי התקופה שבה שינית את מספר הצדדים.
- יש להחליף את ההדפסה של
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
}
}
- הפעל את התוכנית שלך. אמורה להופיע הודעה עם קוביות דו-צדדיות, והודעה שנייה עם קוביות דו-צדדיות.
Your 6 sided dice rolled 3! Your 20 sided dice rolled 15!
הרעיון של כיתה הוא לייצג משהו, לעיתים קרובות משהו פיזי בעולם האמיתי. במקרה כזה, סיווג Dice
מייצג קוביות פיזיות. בעולם האמיתי, קוביות לא יכולות לשנות את מספר הצדדים שלהן. אם רוצים מספר צד אחר, יש לבחור קוביות אחרות. ב
במשימה הזו צריך לשנות את המחלקה Dice
כדי לציין את מספר הצדדים כשיוצרים מכונה חדשה. צריך לשנות את הגדרת הכיתה Dice
כדי לקבל ארגומנט של מספר הצדדים. היא דומה לאופן שבו פונקציה יכולה לקבל ארגומנטים לקלט.
- יש לשנות את הגדרת הכיתה
Dice
כדי לקבל ארגומנט מספר שלם בשםnumSides
. הקוד של הכיתה לא משתנה.
class Dice(val numSides: Int) {
// Code inside does not change.
}
- בתוך המחלקה
Dice
, מוחקים את המשתנהsides
, מפני שעכשיו אפשר להשתמש ב-numSides
. - בנוסף, יש לתקן את הטווח כדי להשתמש ב-
numSides
.
הכיתה שלך ב-Dice
אמורה להיראות כך.
class Dice (val numSides: Int) {
fun roll(): Int {
val randomNumber = (1..numSides).random()
return randomNumber
}
}
אם הקוד הזה יופעל, יופיעו שגיאות רבות, כי עליכם לעדכן את main()
כדי לעבוד עם השינויים בכיתה Dice
.
- בעוד
main()
, כדי ליצור אתmyFirstDice
עם 6 צדדים, עליך להעביר את מספר הצדדים כארגומנט לכיתהDice
, כפי שמוצג למטה.
val myFirstDice = Dice(6)
- בהצהרת ההדפסה, יש לשנות את
sides
ל-numSides
. - לאחר מכן, צריך למחוק את הקוד שמשנים את
sides
ל-20, כי המשתנה הזה כבר לא קיים. - גם ההצהרה
println
תימחק מתחתיה.
הפונקציה main()
אמורה להיראות כמו הקוד הבא. אם הפעלת אותה, לא אמורות להיות שגיאות.
fun main() {
val myFirstDice = Dice(6)
val diceRoll = myFirstDice.roll()
println("Your ${myFirstDice.numSides} sided dice rolled ${diceRoll}!")
}
- אחרי שמדפיסים את הטלת הקובייה הראשונה, מוסיפים את הקוד כדי ליצור ולהדפיס אובייקט
Dice
נוסף בשםmySecondDice
עם 20 צדדים.
val mySecondDice = Dice(20)
- מוסיפים הצהרה מודפסת שמגלשת ומחזירה את הערך שהוחזר.
println("Your ${mySecondDice.numSides} sided dice rolled ${mySecondDice.roll()}!")
- הפונקציה
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
}
}
- מריצים את התוכנית המוגמרת, והפלט אמור להיראות כך.
Your 6 sided dice rolled 5! Your 20 sided dice rolled 7!
כשכותבים קוד, תמציתי יותר. אפשר להסיר את המשתנה randomNumber
ולהחזיר את המספר האקראי ישירות.
- יש לשנות את ההצהרה
return
כדי להחזיר את המספר האקראי ישירות.
fun roll(): Int {
return (1..numSides).random()
}
בהצהרת ההדפסה השנייה, מגדירים את הקריאה להפעלת המספר האקראי בתבנית המחרוזת. אפשר להסיר את המשתנה diceRoll
באמצעות אותה פעולה בהצהרה הראשונה המודפסת.
- יש להתקשר אל
myFirstDice.roll()
בתבנית המחרוזת ולמחוק את המשתנהdiceRoll
. שתי השורות הראשונות של הקוד הראשי שלכם נראות עכשיו.
val myFirstDice = Dice(6)
println("Your ${myFirstDice.numSides} sided dice rolled ${myFirstDice.roll()}!")
- מפעילים את הקוד ולא אמור להיות הבדל בפלט.
זהו הקוד הסופי לאחר החישוב מחדש שלו .
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
), לתת לה את היכולת להפוך, ליצור מופע של הכיתה ולהפוך כמה מטבעות! איך משתמשים בפונקציה אקראית (בטווח) כדי לקבוע את הטלת המטבע?