תכנות מתקדם ב-Java/פולימורפיזם/תרגילים

מתוך ויקיספר, אוסף הספרים והמדריכים החופשי
קפיצה לניווט קפיצה לחיפוש

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

כללי המשחק[עריכה]

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

מהלך המשחק[עריכה]

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

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

שחקנים[עריכה]

במשחק יכולים להשתתף כמה סוגי שחקנים:

  • אדם: שחקן אנושי.
  • קוף: שחקן ממוחשב. הקוף משחק ללא כל מחשבה - הוא תמיד ינחש מספר כלשהו בטווח המספרים האפשרי. הקוף אינו טורח לזכור מה ניחש בעבר (ייתכן שינחש את אותו מספר כמה פעמים), ואינו מתחשב בתוצאות שמקבלים השחקנים האחרים (כלומר, אפילו אם שחקן אחר ניחש 100 וקיבל תגובה שהמספר קטן מדי - ייתכן שהקוף ינחש מספר קטן מ-100).
  • מחשב מהמר: שחקן ממוחשב. שחקן זה יזכור תמיד מה המספר הגדול ביותר והקטן ביותר האפשרי (אם, למשל, אחד השחקנים ניחש 100 וקיבל תגובה שהמספר גדול מדי - שחקן זה ידע להסיק שהמספר הרצוי קטן מ-100), וינחש מספר אקראי שנמצא ביניהם.
  • מחשב חכם: שחקן ממוחשב. את האסטרטגיה שלו תכננו בעצמכם - נסו לחשוב על צורת התנהגות שתעניק לו סיכויים טובים ככל האפשר לנצח.

הנחיות ורמזים[עריכה]

  • כדי לממש את סוגי השחקנים השונים, השתמשו במחלקה מופשטת או ממשק בשם Player, אותו/ה יממשו סוגי השחקנים השונים, כאשר כל שחקן שמשתתף במשחק ייוצג על ידי אובייקט כזה. בתוכנית הראשית, השתמשו במערך בודד שמכיל אובייקטים מטיפוס Player כדי להכיל את השחקנים השונים (וכל הנתונים הדרושים להם). על פי הצורך, ניתן ליצור תתי-מחלקות נוספת עבור קבוצות שונות של סוגי שחקנים (כאשר אתם באים לשקול זאת, חשבו: האם יש נקודות המשותפות רק לחלק מסוגי השחקנים?).
  • תזכורת: כדי לזהות האם אובייקט מסויים הוא מסוג כלשהו ניתן להשתמש במילה השמורה instanceof, למשל: if (currentPlayer instanceof CrazyPlayer) .... זה יכול לסייע אם תבחרו לממש תתי-מחלקות נוספות ביניהן תצטרכו להבדיל.
  • קרוב לוודאי שתזדקקו ל-switch כלשהו בזמן האתחול. אמנם, קיימות שיטות מתוחכמות יותר שמאפשרות להימנע לחלוטין משימוש ב-switch, אך אין חובה להשתמש בהן כאן (אם המימוש שלכם נכון, השינוי שיידרש במקרה של הוספת שחקן חדש יהיה זניח).
  • הגדירו במחלקה הראשית (זו שמריצה את המשחק) משתנה קבוע מטיפוס int שיגדיר מהו המספר המקסימלי שיכול המחשב לנחש. המספר המינימלי הוא 0.
  • שימוש בשיטות ריקות במחלקה יורשת נחשב במרבית המקרים להרגל רע. השתדלו להימנע מכך.
  • זהו תרגיל שעשוי לקחת זמן רב - הקדישו זמן לתכנון, ונסו לעשות זאת בכוחות עצמכם.


הסבר על המימוש: נעשה כאן שימוש בשתי מחלקות מופשטות: מחלקה אחת היא Player, והיא מייצגת שחקנים באופן כללי. עדיף היה להשתמש במחלקה מופשטת מכיוון שקיימים שדות ושיטות שמאפיינים את כל סוגי השחקנים השונים - שם וניקוד. מחלקה נוספת היא AIPlayer, שמייצגת שחקני מחשב בעלי בינה (כלשהי). גם היא הכילה רכיב משותף: היכולת לבחון את התוצאות שניתנו לשחקנים האחרים ולהסיק מכך מה הטווח האפשרי עבור ניחושיהם. מימוש המחלקה הראשית - GuessGame - פשוט למדיי. במהלך המשחק עצמו אנו רצים בתוך שתי לולאות מקוננות: לולאה אחת היא עבור הסיבוב הנוכחי, הלולאה הבאה היא עבור המשחק כולו. בכל סיבוב אנו מאתחלים את נתוני המשחק (המספר שהמחשב ניחש, ומה שהשחקנים השונים יודעים לגביו), ואז עוברים בין השחקנים בלולאה. תכונת הפולימורפיזם מנוצלת כאן על מנת לבחור את פעולות השחקנים - הניחוש של כל השחקנים מתבצע בעזרת השיטה guess

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