ארץ עיר — Categories Game
משחק ארץ עיר מולטיפלייר בזמן אמת עם שיפוט תשובות מבוסס בינה מלאכותית.

סקירה
גרסה דיגיטלית מלאה של משחק ארץ עיר הקלאסי לכמה שחקנים במקביל. השחקנים מתחרים למלא 8 קטגוריות בעברית לפני כל האחרים, ואז מודל AI שופט כל תשובה. השרת עובד לגמרי בזיכרון — MongoDB, Redis ו-OpenAI הם אופציונליים לחלוטין.
סטאק טכנולוגי
הבעיה
למשחק הנייר והעיפרון הישן אין גרסה דיגיטלית טובה שמתמודדת עם הניואנסים של עברית — אותיות סופיות, זיהוי כפילויות, והתאמה לקטגוריה הם דברים שקשה לשפוט מהר באופן הוגן. שיפוט ידני מוביל לוויכוחים; התאמת מחרוזות בלבד היא נוקשה מדי לשפה חיה.
הפתרון
השרת שומר את מצב החדר ב-Map בזיכרון Node.js ודוחף עדכונים דרך Socket.IO. בסיום כל סיבוב, תשובות כל שחקן עוברות שלושה שלבים: ולידציה לפי חוקי האות, ולידציה של התאמה לקטגוריה דרך OpenAI עם פלט JSON מובנה, ואז זיהוי כפילויות בין כל המשתתפים. הניקוד מחושב בשרת מהתוצאות המשולבות.
פיצ'רים מרכזיים
מנוע סיבובים בזמן אמת
השחקן הראשון שסיים מפעיל ספירה לאחור הניתנת להגדרה, ומאפשרת לשאר שחקנים חלון גרייס. כל המעברים — המתנה, סיבוב פעיל, ספירה לאחור, ולידציה, תוצאות — משודרים דרך Socket.IO כך שכל הלקוחות מסונכרנים.
ולידציה חכמה בעברית
ה-API של OpenAI בודק כל תשובה עברית מול הקטגוריה שלה באמצעות JSON schema קשיח. השירות מטפל בנורמליזציה של אותיות סופיות, מגביל לזמן תגובה של 20 שניות, ונסוג לולידציה דטרמיניסטית אם ה-API לא זמין.
עקיפת ולידציה למנחה
לאחר שה-AI סיים, המנחה יכול להעיף ידנית את תוקף כל תשובה לפני חשיפת הניקוד — לטיפול במקרים שהמודל טעה בהם.
מצב קלאסי ומתקדם
במצב קלאסי התשובות חייבות להתחיל באות עברית אקראית אחת; במצב מתקדם נבחרות שתי אותיות שחייבות להופיע איפשהו בתשובה — מה שמגביר משמעותית את הקושי.
תגובות ונוכחות שחקנים
שחקנים יכולים לשגר תגובות אמוג׳י שצפות על המסך של כולם בזמן אמת. הממשק מציג מי מחובר ומד לחץ לכל קטגוריה — כמה שחקנים כבר ענו עליה.
Technical Highlights
- מונורפו npm workspaces — טיפוסי TypeScript ולוגיקת משחק נקייה משותפים בין Next.js ל-Express ללא שלב בנייה
- שלוש שכבות אחסון אופציונליות: Map בזיכרון (תמיד), MongoDB snapshots (אם יש URI), Redis pub/sub (אם יש URL) — השרת עולה ועובד בלעדיהן
- פלט מובנה של OpenAI עם JSON schema קשיח מבטיח שתגובת הולידציה תמיד ניתנת לפענוח, עם timeout של 20 שניות ו-fallback דטרמיניסטי
- מבנה ניקוד שמתגמל מקוריות: תשובה ייחודית מקבלת 15 נקודות, תשובה כפולה רק 5 — מה שמעודד שחקנים לחשוב באופן שונה
- בידוד חדרים ב-Socket.IO — כל חדר משחק הוא ערוץ נפרד; טוקן הסשן ב-localStorage מאמת מחדש את החיבור בעת התחברות מחדש
- פריסה ל-Railway דרך זוג Dockerfiles (Dockerfile.web / Dockerfile.server) עם העלאת קבצים ישירה — ללא צורך ב-git remote
איך להריץ
דרישות מוקדמות
- Node.js גרסה 22 ומעלה
- Docker (עבור MongoDB ו-Redis מקומיים)
- מפתח OpenAI API (אופציונלי — המשחק עובד גם בלעדיו)
הוסף OPENAI_API_KEY לולידציה חכמה; ריק = ולידציה דטרמיניסטית
אופציונלי — השרת עובד לגמרי בזיכרון בלעדיהם
רץ על http://localhost:4000
רץ על http://localhost:3000
