|
1 | 1 | # Doodlebot Educational Platform |
2 | 2 |
|
3 | | -A browser-based multiplayer game that teaches kids pathfinding and autonomous navigation algorithms through a virtual grid game. |
| 3 | +A browser-based multiplayer game that teaches kids pathfinding and autonomous-navigation |
| 4 | +algorithms through a virtual grid game. Built with **Vite + React + TypeScript** and synced |
| 5 | +in real time with **Firebase Realtime Database**. |
| 6 | + |
| 7 | +Live at **https://mitmedialab.github.io/doodlebot-controller/** (deployed from `main` via |
| 8 | +GitHub Pages). |
4 | 9 |
|
5 | 10 | ## What it does |
6 | 11 |
|
7 | | -Players join a shared room and each controls a bot on a 16×16 grid. They progress through a guided tutorial that introduces four movement algorithms in increasing sophistication: |
| 12 | +Two players join a shared room and each controls a bot on a 16×16 grid. Players drag bots, |
| 13 | +coins, and obstacles onto the board, assign their bot a **movement policy**, then start — |
| 14 | +all bots execute simultaneously and the player who collects the most coins wins the phase. |
| 15 | + |
| 16 | +The game runs as **three phases** that introduce planning strategies of increasing |
| 17 | +sophistication: |
| 18 | + |
| 19 | +| Phase | Movement policy available | Notes | |
| 20 | +| ----- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------- | |
| 21 | +| **1** | Goal-based planning (Manhattan) only | The reflex baseline is forced; the utility option is hidden. | |
| 22 | +| **2** | Goal-based + Utility-based (Dijkstra) | Utility-based is a **single-owner claim** — only one player may take it (labelled _unclaimed / yours / taken_). | |
| 23 | +| **3** | Goal-based + Utility-based, free choice | Any player may pick Utility-based; no claim. | |
| 24 | + |
| 25 | +Each phase runs on a **60-second countdown** and ends when the timer expires _or_ all coins |
| 26 | +are collected. A results modal shows the per-player score and advances to the next phase |
| 27 | +(or finishes the game after phase 3). |
| 28 | + |
| 29 | +### Movement policies |
| 30 | + |
| 31 | +The grid model implements three distance strategies: |
8 | 32 |
|
9 | | -1. **Random** — the bot picks a random valid move each turn |
10 | | -2. **Euclidean distance** — the bot greedily moves toward the closest target |
11 | | -3. **Manhattan distance** — same idea, different distance metric |
12 | | -4. **Dijkstra** — full shortest-path that navigates around obstacles |
| 33 | +- **Reflex planning** (Euclidean) — the default fallback; greedy straight-line distance. |
| 34 | +- **Goal-based planning** (Manhattan) — greedy `|dx| + |dy|` distance. |
| 35 | +- **Utility-based planning** (Dijkstra) — true shortest path that routes around obstacles, |
| 36 | + computed from a per-coin weighted graph. It carries a cosmetic memory/heat "cost" in the |
| 37 | + resource panel. |
13 | 38 |
|
14 | | -Each player assigns their bot a **policy** (collect coins, follow another bot, or run away from a bot) and a **movement type**, then watches all bots execute simultaneously. The player who collects the most items wins. |
| 39 | +Only Goal-based and Utility-based are offered as radio options in the UI; Reflex is the |
| 40 | +implicit fallback when a bot has no policy set. |
15 | 41 |
|
16 | 42 | ## Themes |
17 | 43 |
|
18 | | -Four visual themes change sprites and backgrounds: **None** (plain robots), **City** (cars, pizza), **School** (buses, bicycles), **Pacman** (ghosts, maze). |
| 44 | +Three visual themes change sprites and backgrounds: **None / Default** (plain robots), |
| 45 | +**City** (cars, pizza), and **School** (buses, bicycles). The room creator picks the theme; |
| 46 | +it is stored on the room and applied for both players. |
19 | 47 |
|
20 | 48 | ## Getting started |
21 | 49 |
|
22 | | -No installation or build step required. Serve the root directory with any static file server: |
| 50 | +This is a build-based app (Node + npm required). |
23 | 51 |
|
24 | 52 | ```bash |
25 | | -python3 -m http.server 8080 |
| 53 | +npm install |
| 54 | +npm run dev # local dev server (served under base /doodlebot-controller/) |
| 55 | +npm run build # tsc + vite build → dist/ |
| 56 | +npm run preview # serve the production build locally |
| 57 | +npm run test:run # run the vitest suite once |
26 | 58 | ``` |
27 | 59 |
|
28 | | -Then open: |
29 | | - |
30 | | -``` |
31 | | -http://localhost:8080/virtual-board/doodlebotGame.html |
32 | | -``` |
33 | | - |
34 | | -Or open `virtual-board/doodlebotGame.html` directly in your browser. The app is also live at the GitHub Pages URL for this repo. |
| 60 | +Open the dev server URL, which lands on the splash page (`index.html`). |
35 | 61 |
|
36 | 62 | ## Game flow |
37 | 63 |
|
38 | 64 | ``` |
39 | | -doodlebotGame.html splash screen |
40 | | - └─> rooms.html create or join a multiplayer room |
41 | | - └─> tutorial1 watch: Random navigation |
42 | | - └─> game1 play: Random bots |
43 | | - └─> tutorial2 watch: Euclidean distance |
44 | | - └─> game2 play: Euclidean bots |
45 | | - └─> tutorial3 watch: Manhattan distance |
46 | | - └─> game3 play: Manhattan bots + obstacles |
47 | | - └─> tutorial4 watch: Dijkstra |
48 | | - └─> game4 play: Dijkstra bots |
49 | | - └─> tutorial5 |
50 | | - └─> free play (choose theme) |
| 65 | +index.html splash screen → "Play Game" |
| 66 | + └─> rooms.html create a room (share the ID) or join one, creator picks a theme |
| 67 | + └─> game.html both players auto-navigate here once the room has 2 players |
| 68 | + └─> Phase 1 → Phase 2 → Phase 3 → Finish |
51 | 69 | ``` |
52 | 70 |
|
53 | | -The tutor (room creator) controls page progression. All players are automatically navigated together when the tutor advances. |
| 71 | +Room membership drives navigation: when a room reaches 2 players, `RealtimeUpdates` |
| 72 | +redirects everyone to `game.html?room=<id>&option=<theme>&mode=virtual`. |
54 | 73 |
|
55 | 74 | ## Tech stack |
56 | 75 |
|
57 | | -- **Vanilla HTML/CSS/JS** — no framework, no bundler |
58 | | -- **Firebase Realtime Database + Auth** — multiplayer sync and anonymous player identity |
59 | | -- **Bootstrap 5** — UI layout and modals |
60 | | -- **interact.js** — drag-and-drop for placing bots, obstacles, and coins |
| 76 | +- **Vite + React 19 + TypeScript** — multi-page app (`index.html`, `rooms.html`, `game.html`), |
| 77 | + each React page mounted into a single `#root`. |
| 78 | +- **Firebase Realtime Database + Auth** — multiplayer sync and anonymous player identity. |
| 79 | +- **Bootstrap 5** (CSS/markup only; modals are React-controlled, no Bootstrap JS). |
| 80 | +- **Vitest + Testing Library (jsdom)** — unit and DOM component tests. |
61 | 81 |
|
62 | 82 | ## Project structure |
63 | 83 |
|
64 | 84 | ``` |
65 | | -ralcant.github.io/ |
66 | | -├── virtual-board/ # All game HTML, JS, and CSS |
67 | | -│ ├── grid.js # Core grid state machine and movement algorithms |
68 | | -│ ├── grid-graph.js # Graph + Dijkstra implementation |
69 | | -│ ├── game-assets.js # Static asset and object-size data |
70 | | -│ ├── game-setup.js # Grid construction and Firebase callback bridge |
71 | | -│ ├── bot-movement.js # Bot start/stop movement lifecycle |
72 | | -│ ├── grid-render.js # DOM drawing functions |
73 | | -│ ├── phase-manager.js # Tutorial phase and countdown logic |
74 | | -│ └── test-index.js # Entry point: URL params, theme, event wiring |
75 | | -├── assets/ # Sprites and backgrounds per theme |
76 | | -├── firebase-handler.js # Firebase bootstrap shim |
77 | | -├── firebase-init.js # Firebase app init and anonymous auth |
78 | | -├── firebase-sync.js # RealtimeUpdates class — all Realtime Database calls |
79 | | -└── firebase-game-flow.js # Game flow helpers (phase transitions) |
| 85 | +doodlebot-controller/ |
| 86 | +├── index.html / rooms.html / game.html # multi-page entry points |
| 87 | +├── public/assets/ # sprites & backgrounds (per theme) |
| 88 | +├── src/ |
| 89 | +│ ├── main.ts / rooms.ts # per-page entry scripts (mount React roots) |
| 90 | +│ ├── grid/ # VirtualGrid model + graph/Dijkstra (no DOM) |
| 91 | +│ ├── firebase/ # firebase-init (auth) + firebase-sync (RealtimeUpdates) |
| 92 | +│ ├── sync/ # grid ↔ Firebase adapter |
| 93 | +│ ├── game/resource-model.ts # cosmetic battery/CPU/memory sim (local, unsynced) |
| 94 | +│ ├── ui/ # phase-manager, bot-movement, drag-drop, game-setup |
| 95 | +│ ├── ui/react/ # GameApp, GameBoard, Sidebar, Controls, PhaseHud, |
| 96 | +│ │ # Modals, ResourcePanel, Lobby, useGridSnapshot |
| 97 | +│ ├── events.ts # typed event bus (gameEvents) |
| 98 | +│ ├── types.ts # shared types + MOVEMENT_VALUES etc. |
| 99 | +│ └── __tests__/ # vitest suites |
| 100 | +├── vite.config.ts # base: "/doodlebot-controller/" |
| 101 | +└── .github/workflows/deploy.yml # build + deploy to GitHub Pages |
80 | 102 | ``` |
81 | 103 |
|
| 104 | +See [CLAUDE.md](CLAUDE.md) for architecture details (state separation, the event bus, the |
| 105 | +Firebase room schema, and the React island model). |
| 106 | + |
82 | 107 | ## Browser requirements |
83 | 108 |
|
84 | | -Any modern browser (Chrome, Firefox, Safari, Edge) works for virtual mode. |
| 109 | +Any modern browser (Chrome, Firefox, Safari, Edge). |
0 commit comments