Password: CubeTutor-iwant2study-2026 (keystore + key, alias cubetutor)

# Rubik's Cube — 3D Interactive with Auto Solver

A fully interactive 3D Rubik's Cube in a single HTML5 page, with a real
**Kociemba two-phase auto-solver** that can solve *any* cube state — including
one you paint in yourself to match a real scrambled cube on your desk.

## Run it

Open `index.html` through any web server (it loads three.js and cubejs from
CDNs, so you need an internet connection on first load):

```
cd games/rubricCube
python -m http.server 5183
# then open http://localhost:5183
```

## Features

| Feature | How |
|---|---|
| Turn a face | Drag any face on the cube |
| Rotate the view | Drag the background (wheel = zoom) |
| Keyboard turns | `U D L R F B` keys, hold **Shift** for the reverse turn |
| Undo | `Z` key or **Undo** button |
| Scramble | **Scramble** button (25 random moves, starts the timer on your first move) |
| Auto-solve | **Solve** button — Kociemba two-phase solver, ~20 moves, animated |
| **Set your own cube** | **Edit** button → pick a colour → click stickers → **Done** → **Solve** |
| **📷 Scan a real cube** | **Scan** button — 6 guided camera shots rebuild your physical cube in the app (colours classified relative to the photographed centres, so it works in any lighting); then Solve/Tutor guides you on the real cube |
| **🎓 Tutor mode** | **Tutor** button — guided beginner-method lessons (see below) |
| Stats | Move counter, timer, best time (saved in `localStorage`) |
| Settings | ⚙ — turn-speed slider, face labels, turn **sound** 🔊 and **vibration** 📳 toggles |
| Move arrows | chevrons drawn **on the stickers** of the moving layer show exactly which slice turns and which way (plus an orbit ring for whole-cube re-grips) |

### Edit mode validation
The app checks painted states before solving and explains exactly what is wrong:
- each colour must appear exactly 9 times,
- the six centre stickers must all be different,
- physically impossible states (twisted corner, flipped edge, swapped stickers
  that create pieces which don't exist on a real cube) are detected and rejected
  with a friendly message instead of a wrong "solution".

## 🎓 Tutor mode — learn to solve, not just watch

The Tutor teaches the classic **beginner (layer-by-layer) method** the way a
human mentor would:

- **8-stage progress checklist**: hold it right → White cross → White corners →
  middle layer → Yellow cross → Yellow edges → position corners → twist corners.
- Every step starts with **what to spot** ("Spot the White–Red edge — it's in
  the bottom layer at the left, but wrong") and **why the trick works**, with the
  target piece **glowing** on the 3D cube.
- Teaches the named tools of the trade: the **right-hand trick** (R U R′ U′),
  left/right middle-edge inserts, the **dot → L → line → cross** pattern, the
  7-move edge cycle, the corner cycle, and the R′ D′ R D corner twist (including
  the classic reassurance that the cube *looks* broken half-way and heals).
- **Self-paced, one move at a time**: **▶ One move** performs a single turn per
  press — the arrows, the 🤲 phrase and a "Move 2 of 7" counter update for each
  move, and finished moves get crossed off the sequence. **▶▶ Play step** plays
  the rest of the step slowly with the same per-move narration. Learners can
  also make the turns themselves: the tutor re-reads the cube after *every*
  move and updates the lesson, so it follows the learner rather than forcing a
  script.
- **Physical scaffolding for novices**: big yellow **3D arrows wrap the exact
  layer to turn** (or the whole cube for re-grips) showing the direction, and a
  🤲 hands line translates notation into body actions ("tip the WHOLE cube
  backward — the front rolls up to the top"). Hovering any notation chip shows
  its plain-language meaning.
- **Shortcut spotting**: if the cube is 1–2 turns from solved (e.g. a layer is
  merely twisted), the tutor teaches the shortcut instead of grinding through
  the method — and the Solve button does the same before falling back to
  Kociemba.
- A collapsible notation legend teaches R / U′ / F2 / x-y-z as they appear.

Implementation: `tutor.js` contains a pure facelet model whose move tables are
auto-generated from the same geometry conventions as the renderer, plus a
planner that *simulates and verifies* every candidate algorithm before showing
it (so a wrong case can never be taught). Verified with 60 random scrambles
through all stages (avg ≈ 21 teaching steps / ≈ 166 moves — normal for the
beginner method).

## Architecture notes

- `index.html` / `style.css` / `app.js` — no build step, no framework.
- Rendering: [three.js r128](https://threejs.org). 26 cubelet groups; each face
  turn re-parents the 9 affected cubelets to a pivot, animates it, then snaps
  positions/rotations back to the lattice (rotation matrices rounded to signed
  permutation matrices, so no drift ever accumulates).
- **The 3D scene is the single source of truth.** The 54-facelet string for the
  solver is derived from sticker world positions + normals, which is why a
  hand-painted cube solves exactly like a scrambled one.
- Solver: [cubejs](https://github.com/ldez/cubejs) (Herbert Kociemba's
  two-phase algorithm in JS). `Cube.initSolver()` runs once at page load
  (~3–5 s) — the "Preparing solver…" toast.
- `window.__rubik` exposes a tiny test/automation hook
  (`isSolved`, `faceletString`, `pickAt`, `paintAt`).

## Monetisation: FREE app + H5 Games Ads (already wired in)

Business model decision: **free with ads** (a paid app can never be made free
later, and "paid + ads" rates poorly).

- **Google Analytics** (`G-S9EWRY1CPJ`) in `index.html`'s head.
- **H5 Games Ads** (Google's Ad Placement API, `ca-pub-0121577198857509`) —
  the current Google-recommended ad form for HTML5 games, in `ads.js`:
  - *interstitials* at natural breaks (`after_auto_solve`,
    `between_scrambles` — every 2nd scramble, ≥60 s apart via
    `data-ad-frequency-hint`),
  - *rewarded ad* behind the ⚙ Settings → "🎬 Support with an ad" button.
  - Everything no-ops gracefully offline or before approval.
  - ⚠ Requires enrolling the site in **AdSense for Games / H5 Games Ads**
    (apply at adsense.google.com → your AdSense account must be approved for
    games). Until approved, `adBreak()` simply never shows anything.
- The legacy `codesforejss/Google AdsMobs` snippet (Ionic 4 + click-event
  bridge, 2020) is **not used** — that pattern only worked inside the old
  Ionic wrapper. If you switch to Capacitor later, use
  `@capacitor-community/admob` instead.

## Store assets (`play_store_assets/`)

All listing images are generated and ready: phone 1080×1920 / 1920×1080,
7-inch tablet 1200×1920 / 1920×1200, 10-inch tablet 1600×2560 / 2560×1600,
Chromebook 1920×1080 — each in a "plain" (cube) and "tutor" (lesson) variant —
plus `feature_graphic_1024x500.png` and copy-paste listing text in
`store_listing.txt`.

Regenerate any size with headless Chrome (the page supports `?shot=plain` and
`?shot=tutor` staging):

```powershell
& "C:\Program Files\Google\Chrome\Application\chrome.exe" --headless=new `
  --user-data-dir=$env:TEMP\shot --enable-unsafe-swiftshader --hide-scrollbars `
  --virtual-time-budget=25000 --force-device-scale-factor=2.5 `
  --window-size=432,768 --screenshot=out.png `
  "http://localhost:5183/index.html?shot=tutor"
```

> Dev note: `sw.js` serves app code network-first (updates always reach
> users) and `lib/`+`icons/` cache-first. **Bump the `CACHE` version string on
> every release.**

## Google Play packaging (files included)

Self-contained pieces already in this folder:

| File | Purpose |
|---|---|
| `lib/three.min.js`, `lib/cube.js`, `lib/solve.js` | local libraries — no CDN needed, works in airplane mode |
| `manifest.json` | PWA manifest (name, colours, icons, standalone display) |
| `icons/icon-512.png`, `icon-192.png`, `icon-512-maskable.png` | launcher icons |
| `sw.js` | cache-first service worker → full offline play |
| `twa-manifest.json` | Bubblewrap config for the Android (TWA) build |

### Build the Android app (TWA route)

1. Upload this folder to `https://iwant2study.org/lookangejss/games/rubricCube/`
   (HTTPS required). Verify the page + manifest load.
2. `npm i -g @bubblewrap/cli`, then in this folder: `bubblewrap build`
   (it reads `twa-manifest.json`; first run installs the Android SDK and asks
   for a signing key — **keep that keystore safe forever**).
3. Bubblewrap prints a SHA-256 fingerprint → put it in
   `https://iwant2study.org/.well-known/assetlinks.json` so the app opens
   full-screen without the browser bar.
4. Upload the generated `app-release-bundle.aab` to the Play Console.

### Play Console checklist ($25 one-time fee)

- **Pricing decision** — a *paid* app must be priced **before first publish**
  (free can never become paid). ⚠ Note: **paid + ads** is allowed but rated
  poorly by users; the common choices are **free with ads** (your AdSense) or
  **paid with no ads**. Pick one before publishing.
- **Ads declaration**: Play Console → App content → Ads → declare "Yes,
  contains ads" (required since AdSense runs inside the TWA).
- **Data safety form**: declare Analytics + AdSense data collection
  (identifiers, ad interaction). A privacy-policy URL is mandatory.
- Store listing: screenshots of the Tutor in action, 512 px icon (included),
  feature graphic 1024×500, category Puzzle, content rating Everyone.

### Nice-to-haves before charging money

Haptic feedback on turns, sound toggle, 2×2 / 4×4 cubes, colour-blind sticker
patterns, daily-challenge scrambles.

## Credits

- Solver: cubejs (MIT) — JS port of Herbert Kociemba's two-phase algorithm.
- 3D engine: three.js (MIT).
