Skip to content

Scribble assignment - Syamala#112

Open
Syamala053 wants to merge 5 commits into
everest-engineering:mainfrom
Syamala053:assignment
Open

Scribble assignment - Syamala#112
Syamala053 wants to merge 5 commits into
everest-engineering:mainfrom
Syamala053:assignment

Conversation

@Syamala053

Copy link
Copy Markdown
Member

Summary

Full implementation of a multiplayer Pictionary-style drawing game ("Scribble") with an Express + TypeScript backend and React 18 + Vite frontend. Sync uses HTTP polling (~2s), no WebSockets. All game state lives in-memory on the backend.

Architecture

  • Backend: backend/src/api/rooms.ts — Express router with 6 endpoints. All request validation via Zod schemas in backend/src/api/schemas.ts. Room model types in backend/src/models/game.ts. Core game logic in backend/src/services/roomStore.ts using an in-memory Map<string, Room>.
  • Frontend: frontend/src/services/api.ts — typed HTTP client. State managed by a React class-based store (roomStore.ts) with useSyncExternalStore. Components in frontend/src/components/, pages in frontend/src/pages/.

Room Setup & Lobby

  • Creating a room auto-assigns you as host; only the host can start the game
  • Empty/whitespace-only names are rejected on both create and join with clear errors
  • Room codes are 4-character alphanumeric, auto-generated, and collision-free
  • Lobby auto-polls every 2s so the participant list stays up to date
  • "Start Game" button visible only to host, disabled until 2+ players
  • Each room is fully isolated from others

Game Start & Drawer Flow

  • Host clicks "Start Game" → room transitions to playing status
  • First participant (by join order) is assigned as the drawer
  • Secret word is deterministically selected from a sorted word list
  • Drawer sees the word on screen; guessers see nothing in its place
  • Non-host, non-lobby, and <2 player conditions are all blocked

Gameplay Interaction

  • Drawer gets an interactive canvas with mouse and touch support, plus a Clear button
  • Strokes are debounced (500ms) and sent to the backend; guessers see a read-only canvas updated via polling
  • Guessers can submit text guesses; they are trimmed and compared case-insensitively
  • Correct guess → +100 points and the round ends immediately
  • Incorrect guess → 0 points, no penalty
  • Drawer cannot submit guesses
  • All players see the full guess history and live scores via polling

Result, Restart & Final Validation

  • On correct guess, the secret word is revealed to everyone
  • Result screen shows the word, final scores, and complete guess history
  • Only the host sees a "Restart Game" button
  • Restart clears canvas, guesses, and scores but preserves participants, returning everyone to the lobby
  • Non-host players cannot trigger a restart

Key Design Decisions

  • Deterministic gameplay: word selection and drawer assignment use index-based rules, no Math.random() in game logic (only for room code generation)
  • Word visibility: toRoomSnapshot() returns currentWord: null for non-drawers during active play; reveals to all on roundEnd
  • Error handling: Service functions throw Error, router catches and wraps in HttpError(400); ZodError passes through to Express error handler
  • Scoring: +100 for correct, incorrect guesses get 0 points. Multiple guessers can all score +100 independently
  • Canvas format: Stroke[] where each stroke is { points: {x,y}[] }, serialized to JSON string. Polling replaces full stroke array on each fetch

Contributor

- Add hostId to Room model and expose in RoomSnapshot
- Fix API base URL typo (/bug -> /)
- Add name validation: reject empty/whitespace names (Zod + frontend)
- Add auto-polling to LobbyPage (~2s interval)
- Show Start Game button only for host, disabled until >=2 players
- Remove dead saveRoom code
- Add POST /rooms/:code/start endpoint (host-only, validation)
- Implement room status transition lobby -> playing
- Assign first participant as drawer (join order)
- Deterministic word selection (index-based from sorted words)
- Show secret word only to drawer in snapshot
- Add startGame to API client and room store
- Wire Start Game button in LobbyPage to call API, navigate on success
- Update GamePage with role detection, word visibility, and polling
- Add POST /rooms/:code/guess endpoint with validation and scoring
- Add POST /rooms/:code/draw endpoint for canvas sync
- Implement interactive canvas (drawer) and read-only canvas (guessers)
- Wire GuessForm to API with empty-guess validation
- Disable GuessForm for drawer
- Populate Scoreboard dynamically from snapshot scores
- Add specs/003-gameplay-interaction/{spec.md,plan.md,tasks.md}
- POST /rooms/:code/restart endpoint (host-only, clears state, preserves participants)
- Restart button on roundEnd screen for host; Exit to Lobby for all
- Fill constitution.md with real project rules
- Add reflection.md

Specs: specs/004-result-restart/{spec.md,plan.md,tasks.md}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant