נקודת ההתחלה
הפרויקט hex5 מתחיל ב־Empty Views Activity בשפת Java, עם XML ו־View Binding פעיל. שם החבילה הוא com.example.hex. המורה מספק את המודלים המאומנים; אין במסלול הזה משימת אימון ב־Python או ב־Colab.
לאן אנחנו הולכים?
נבנה משחק מקומי, נוסיף בחירת גודל לוח כבר כשניצור את מחלקת המשחק, ואז נחבר יריב שמשתמש באותם חוקי משחק ובמודל ערך מסופק. האימון מתרחש מראש מחוץ לטלפון. בזמן המשחק האפליקציה משתמשת בקובצי .tflite ששמורים בנכסים שלה.
%% dir: rtl %%
flowchart TB
subgraph preparation["מחוץ לטלפון — המורה מספק"]
training["אימון עצמי מראש"] --> tflite["מודל .tflite"]
end
subgraph app["האפליקציה — משחק אופליין"]
catalog["model_catalog.json<br/>נתיב וגודל לוח"]
assets["קובצי .tflite"]
human["מהלך האדם"] --> game["מצב המשחק וחוקיו"]
game --> candidates["עותק לכל מהלך מחשב חוקי"]
candidates --> values["הערכת המצבים במכשיר"]
catalog --> values
assets --> values
values --> move["בחירת מהלך מחשב"]
end
tflite -->|"העתקה לנכסי האפליקציה"| assets
בפרקים 01–04 נגיע למשחק מקומי שלם, עם לוח 7×7 כברירת מחדל. בפרק 02 מצב המשחק והתצוגה כבר יקבלו גודל לוח; בפרק 07 נוסיף את שתי אפשרויות הגודל ונציג רק מודלים תואמים. בפרקים 05–07 נחבר את המחשב. בפרק 08 נוסיף רמז שלא מניח אבן, ובפרק 09 נוסיף ערכות נושא.
לפני שמתחילים: מה חייב לעבוד במשחק עוד לפני שמודל מאומן יכול להועיל? חשבו על חוקיות המהלך, התור וזיהוי המנצח.
| פרק | נושא | מה עובד בסיום |
|---|---|---|
| 01 — הלוח ושפות היעד | Canvas, משושים, גאומטריה ושפות יעד | לוח 7×7 ריק עם סימון ארבע שפות היעד. |
| 02 — מהלכים ותורות | גודל הלוח, מצב המשחק, callback ומגע | משחק 7×7 כברירת מחדל; HexGame וציור הלוח תומכים גם בגודל אחר. |
| 03 — חיבור מנצח | ששת השכנים וחיפוש רוחב | ניצחון מזוהה לפי גודל הלוח, ומהלך אחרי ניצחון נדחה. |
| 04 — משחק מקומי שלם | Restart, משאבי מסך ו־View Binding | משחק מקומי מלא עם תור, תוצאה וכפתור Restart. |
| 05 — מכינים את המחשב | עותקי מצב, מהלכים חוקיים וקידוד | מצב המשחק מקודד בשלושה ערכים לכל תא; מודל הפתיחה הוא 7×7. |
| 06 — מחשב שעובד ברקע | בחירת מהלך, LiteRT ו־Executor | האדם משחק אדום מול המחשב בכחול; החישוב רץ ברקע. |
| 07 — שחקנים לפי גודל לוח | קטלוג JSON ובחירת מודל קבוע־צורה | ב־7×7 מופיעות האיטרציות 100, 2,620 ו־5,000; ב־11×11 מופיעות 100 ו־7,350. |
| 08 — רמז למהלך הבא | שימוש חוזר ב־HexAi |
המודל מציע מהלך לאדום ומדגיש את התא בלי להניח בו אבן. |
| 09 — ערכות נושא ואייקון | משאבי יום ולילה ואייקון | צבעי המסך מתאימים להגדרת התצוגה של המכשיר. |
מי אחראי על מה באפליקציה?
%% dir: rtl %%
flowchart TB
xml["XML ופקדי המסך"] <-->|"View Binding"| activity["MainActivity<br/>תיאום המסך והעבודה"]
activity -->|"עדכון תצוגה"| board["HexBoardView<br/>ציור ותרגום מגע לתא"]
board -->|"קריאת מצב הלוח"| game["HexGame<br/>גודל, מצב וחוקים"]
activity -->|"החלת מהלך"| game
activity -->|"בקשת מהלך או רמז"| ai["HexAi<br/>בחירה בין מהלכים חוקיים"]
ai -->|"עותק לכל מועמד"| game
ai --> contract["ValueModel<br/>הערכת מצב"]
loader["TfliteValueModel<br/>LiteRT CompiledModel"] -.->|"מממשת"| contract
catalog["ModelCatalog<br/>קריאת הקטלוג"] --> loader
catalog --> assets["מודלים בנכסי האפליקציה"]
HexBoardView עובדת עם פיקסלים ומרכזי משושים; HexGame עובדת עם גודל הלוח, התאים והחוקים. MainActivity מחברת את המסך למשחק, ו־HexAi משתמשת בעותקי משחק וב־ValueModel כדי לבחור מהלך. המודל מעריך עמדה; הוא אינו מחזיר תא מוכן.
שאלת הבנה: איזו מחלקה צריכה לדחות מהלך לתא תפוס, גם כשהמהלך מגיע מהמחשב ולא מנגיעה במסך?
מי עושה מה?
| חלק | אחריות |
|---|---|
| לוח, מגע, חוקים, תורות, ניצחון וחיבור המסך | התלמיד כותב ומסביר |
TfliteValueModel וקובצי המודלים |
המורה מספק; התלמיד לומד את החוזה ומשלב |
model_catalog.json |
התלמיד כותב רשומות שמציינות גודל ונתיב מודל |
| אימון JAX, Colab וייצוא checkpoints | מחוץ למסלול |
בסוף פרק 4 אפשר לשחק משחק מקומי שלם. בפרק 05 נכין את הקידוד ואת הרצת המודל. בפרק 06 נחבר את בחירת המהלך לעבודה ברקע, ובפרק 07 נבחר מודל שמתאים לגודל הלוח. מספר איטרציות גדול יותר אינו מבטיח מודל חזק יותר.
בפרק 08 נוסיף רמז למהלך בלי להניח אבן, ובפרק 09 נוסיף צבעי יום ולילה לאותו מסך.
חבילת המודל היחיד לפרק 5 וחבילת המודלים הנוספים לפרק 7 זמינות בקישורים שבפרקים.