בשיעור זה נבנה את המשחק איש תלוי
ב-Python. בניית המשחק בשלבים תעזור להבין איך לחשוב על ארגון הקוד לרכיבים וכיצד כל רכיב תורם להיגיון הכללי של המשחק.
במשחק איש תלוי, המטרה היא שהשחקן ינחש מילה מוגדרת מראש בעזרת ניחוש אותיות הנמצאות במילה. השחקן ממשיך לנחש עד שהוא מנחש נכון את כל האותיות במילה, ובכך מנצח, או מגיע למספר מסוים של ניחושים שגויים, וכתוצאה מכך הפסד.
הרכיבים שאנו צריכים#
כדי ליצור את המשחק הזה, נצטרך מספר רכיבים כדי לטפל בהיבטים שונים:
-
אתחול: כדי להגדיר את מצב המשחק הראשוני, כגון הגדרת המילה לניחוש ואתחול רשימה לאחסון אותיות שנוחשו.
-
לולאת משחק ראשית: המנוע של המשחק שבו מתרחשת רוב האקשן, כולל קלט משתמש ועדכוני מצב המשחק. בתוכו יהיו לנו את הבלוקים הבאים:
- תצוגת ניחוש נוכחי: מנגנון להצגת מצבה הנוכחי של המילה שהשחקן מנחש, המסווה את האותיות שלא נוחשו.
- אינטראקציה עם משתמש: דרך ללכוד את ניחושי האותיות של השחקן ולספק משוב אם הניחושים נכונים או שגויים.
- בדיקת מצב סיום: קוד הקובע אם המשחק הגיע למצב סיום, שיכול להיות ניצחון או הפסד.
על ידי פירוק המשחק שלנו לרכיבים אלה, אנו יוצרים מבנה קוד מודולרי ומאורגן, מה שמקל על הבנה, ניפוי באגים והרחבה עתידית.
אתחול#
בתור התחלה נצטרך שהמשחק "יבחר" מילה שצריך לנחש. על מנת לפשט את הבנייה של הקוד, נתחיל מלבחור מילה בעצמנו ונשמור אותה במשתנה בשם word_to_guess
.
בנוסף נאתחל משתנה שיהיה רשימה ריקה שבה נשמור את כל האותיות שהמשתמש ניחש. נקרא למשתנה הזה guessed_letters
.
תמיד נחפש להיות כמה שיותר עצלנים כשאנחנו בונים קוד. אם יש בלוק שאנחנו יכולים לכתוב יותר מאוחר, זה מה שנעשה! (וזה בדיוק מה שעשינו כרגע עם המילה שצריך לנחש).
ולמה זה טוב?
גם אם נתכנן את כל הקוד תיאורתית בתרשימים וגרפים יפים, תמיד נגלה בעיות שלא חשבנו עליהן תוך כדי קידוד, וככל שיהיה לנו קוד עובד בצורה ראשונית יותר מהר, כך נגלה את הבעיות האלה יותר מהר ונוכל להתייחס אליהן לפני שכתבנו יותר מדי קוד שיכול להיות לא רלוונטי.
סגנון עבודה זה נקרא הוכחת היתכנות ( Rapid Prototyping / Proof of Concept - POC).
ב-POC, אתה בדרך כלל מתמקד ב:
- הדגמת ההיבטים הקריטיים או המאתגרים ביותר של התוכנה.
- בנייה מספיקה כדי לאמת את המושג או ההשערה.
- צמצום הזמן המושקע בתכונות שאינן חיוניות עבור ה-POC.
לולאת המשחק הראשית#
המשחק עובד בתורות, כאשר כל תור עובד דומה לקודמו, ולכן מאוד נח לעבוד בתוך לולאה גדולה שבה נגדיר את כל הפעולות שקורות בתור של שחקן:
-
תצוגת ניחוש נוכחי
-
אינטראקציה עם משתמש
-
בדיקת מצב סיום
מכיוון שאנחנו לא יודעים את כמות התורות שיקח לשחקן לנחש את המילה (או להפסל), נכניס את כל המשחק לתוך לולאת
while True
גדולה, שתרוץ לנצח עד שהקוד יגיע למצב בו יש את פקודת הbreak
אוexit
שיעצרו את הלולאה.
תצוגת הניחוש הנוכחי#
בתחילת כל תור נרצה להציג את המצב הנוכחי של הניחוש של המשתמש.
הליבה של רכיב זה טמונה בלולאה,
שבה אנו חוזרים על כל אות בword_to_guess
ובודקים האם זוהי אות שהמשתמש ניחש כבר או לא.
אנו מתחילים עם מחרוזת ריקה בשם current_state
.
הלולאה עוברת על כל letter
ב-word_to_guess
ובודקת אם הletter
הנוכחי קיים ברשימת guessed_letters
.
- True: אם התנאי מתקיים, ה
letter
מתווסף ל-current_state
. - False: אם התנאי אינו מתקיים, נוסיף ממלא מקום (
$
) שיתווסף ל-current_state
.
אינטראקציה עם המשתמש#
בבלוק הזה נבקש input מהמשתמש. נשתמש בגישת הוכחת ההיתכנות ולא נתעסק כרגע בולידציה לאינפוט, ונניח שהמשתמש מכניס אות קטנה אחת שלא נוחשה בעבר.
בדיקת מצב סיום#
בסוף כל תור נרצה לבדוק האם הניחוש של המילה הוא אכן המילה הרנדומלית שצריך לנחש, ואם כן יש ניצחון ולא צריך עוד תורות.
בגלל שזה בסוף התור שלנו נצטרך לחשב שוב את current_state
בשביל להשוות עם האות של הניחוש האחרון.
הקוד הסופי#
הקוד הסופי יראה כך:
סיכום חלק 1#
בשיעור הזה למדנו איך לבנות פרויקטים בשיטת "Rapid Prototyping", כאשר אנחנו בונים POC מהיר וקטן שמציג את עיקרי הפעולה של הפרויקט אותו אנחנו רוצים לבצע. בשלב הבא נאפטם את הקוד ונוסיף לו עוד חלקים לשיפור החוויה.
תרגיל- input validation#
הוסף לקוד שכתבנו עד עכשיו בדיקת input- צריך לוודא שהאינפוט הוא אות אחת. אם לא, הדפס Invalid input. Try again...
ותן למשתמש עוד אפשרות להכניס אינפוט.
בנוסף, אנחנו צריכים לוודא שאותיות גדולות וקטנות נחשבות כאותה אות בקוד שלנו (למשל "w"=="W")
המשימה האחרונה היא לוודא שהמשתמש תמיד מכניס אותיות שלא הכניס בעבר. אם הוא מנחש אות שניחש בעבר הדפס This letter was already used. Try again...
ותן למשתמש עוד אפשרות להכניס אינפוט.
דוגמאת הרצה:
Current state: $$$$
Used letters bank: []
Guess a letter: xx
Invalid input. Try again...
Guess a letter: w
Good guess!
Current state: w$$$
Used letters bank: ['w']
Guess a letter: w
This letter was already used. Try again...
Guess a letter: o
Good guess!
Current state: wo$$
Used letters bank: ['w', 'o']
...