rubiks-solver

skill
Guvenlik Denetimi
Gecti
Health Gecti
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 10 GitHub stars
Code Gecti
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
  • Permissions — No dangerous permissions requested
Purpose
This tool is a browser-based 3×3 Rubik's Cube solver that lets users upload a flat-net image of a scrambled cube to receive a step-by-step solution. All image processing and solving algorithms run entirely on the client side.

Security Assessment
Overall Risk: Low. The application does not request any dangerous permissions, execute shell commands, or contain hardcoded secrets. Because the tool is strictly a client-side web application, it does not upload your images to an external server or make suspicious network requests. Furthermore, a code scan of 12 files found no dangerous patterns. Your data stays completely within your browser.

Quality Assessment
Overall Quality: Good. The project is highly transparent about how it works, utilizing standard libraries like `cubejs` and running heavy computations safely inside an isolated Web Worker. It is actively maintained (last pushed to 0 days ago), comes with a clear MIT license, and has earned 10 GitHub stars. The README is thorough and clearly documents its intended functionality.

Verdict
Safe to use.
SUMMARY

Browser-based Rubik's Cube solver — upload a flat-net image, get the step-by-step solution.

README.md

RubikSolver

A browser-based 3×3 Rubik's Cube solver. Upload a flat-net image of a scrambled cube and get a step-by-step solution.

Live demo: https://jeffhuber.github.io/rubiks-solver/

100% client-side: no server, no upload — image processing and solving both run in your browser.

What it does

  1. Get a cube state in — three ways: click Upload net image, drop a net image anywhere on the page, or paste one with ⌘V. Random scramble generates a programmatic state for testing. Share copies a URL that reproduces the exact current state.
  2. The CV pipeline crops the cross, samples each sticker, and snaps every color via per-image calibration: it finds the globally optimal 6-way assignment of the center stickers to the WCA palette, then classifies every other sticker against those calibrated centers (handles palette drift like Ruwix's yellow-shifted orange).
  3. The detected state appears in an editable cube net — click any sticker to fix a wrong color before solving. Any of the 24 rotational orientations is accepted; the centers themselves define which face is which.
  4. Click Solve for an instant ≤22-move Kociemba solution, or Solve (tightest) to spend up to ~9 seconds searching for a shorter one (typically 20 moves — God's Number). A lifetime counter tracks how many moves you've saved across all tight solves.
  5. Step through the solution one move at a time, or hit ▶ Play for auto-advance with slow/normal/fast speeds. The 2D net updates the highlighted face and the 3D cube animates the matching face rotation. Drag the 3D cube to orbit it.

How it works

  • Solver: cubejs — a JS port of Kociemba's two-phase algorithm. Returns the first solution it finds (typically 20-22 moves) in milliseconds after a one-time ~3-second pruning-table init. The optional Solve (tightest) button iteratively re-runs cubejs with progressively tighter maxDepth bounds (down to 20, God's Number) for up to ~9s, recovering whatever shortest solution is found before the budget runs out.
  • Worker isolation: the solver runs in a dedicated Web Worker (src/solver.worker.ts) with a Promise-based main-thread proxy (src/solver.ts). cubejs's solve() calls can take seconds-to-minutes on tight depths and can't be preempted, so the worker is hard-terminate()-ed if it blows past the deadline; the latest progress result is recovered via the onProgress channel. Re-init costs ~3s once, hidden by the next idle window.
  • Cube model (src/cube.ts): the cube state is a 54-character facelet string in URFDLB face order. The PLACEMENTS table maps each sticker index to its (row, col) on the unfolded cross — used by both the renderer and the parser, so the two are guaranteed to agree. The parallel PLACEMENTS_3D (src/cubies.ts) maps each sticker to its cubie position and outward face direction in 3D world coordinates.
  • 2D Renderer (src/CubeNet.tsx, src/render.ts): SVG component for the UI, plus a pure RGBA-buffer renderer used as a deterministic test fixture for the parser.
  • 3D Renderer (src/Cube3D.tsx): react-three-fiber scene with 26 cubie meshes (skipping the unseen core). When the displayed state changes, the component diffs old vs. new across all 18 possible single moves; if it finds a match, it animates the matching face's 9 cubies as a rotating group; otherwise it snaps (used for paste / scramble / reset).
  • Parser (src/parser.ts): finds the cross's bounding box by detecting non-background pixels at the image corners, samples a small patch at each sticker's geometric center, converts to CIE Lab, and assigns each sticker to its nearest reference color. By default the reference palette is calibrated from the six center stickers in the same image, which makes the parser robust to palette differences (e.g. a Ruwix screenshot vs. our own renderer).
  • Validation (src/cube.ts, src/solver-core.ts): basic checks at edit time (9 stickers per color, 6 distinct centers) plus an unreachable-state check at solve time. The solver canonicalizes the input via letter substitution and runs a Cube.fromString(...).asString() round-trip — cubejs silently rewrites parity-violating cubies (a single flipped edge, twisted corner, permuted centers, etc.), so any drift between input and round-trip means the cube isn't reachable from a real solved state. We throw UnsolvableCubeError and show a friendly message instead of returning a partial-solve animation. Already-solved inputs short-circuit to zero moves before invoking cubejs.

The parser round-trips 50 random scrambles at 100% sticker accuracy against the in-app renderer; see src/parser.test.ts.

Run locally

npm install
npm run dev      # http://localhost:5173/rubiks-solver/
npm test         # vitest, ~5s
npm run build    # production bundle

Project structure

src/
├── App.tsx            # top-level UI, state, upload + solve flow
├── CubeNet.tsx        # SVG renderer for the unfolded cross
├── Cube3D.tsx         # react-three-fiber 3D cube + animated face turns
├── cube.ts            # state types, layout, validation, canonicalization
├── cubies.ts          # 3D placement table (sticker -> cubie + face direction)
├── render.ts          # RGBA-buffer renderer (test fixture)
├── parser.ts          # image -> cube state
├── solver.ts          # main-thread Promise proxy + sync utility re-exports
├── solver-core.ts     # synchronous cubejs wrapper (fast + tight, used by tests + worker)
├── solver.worker.ts   # Web Worker that runs the solver off the main thread
├── moves.ts           # move parsing + face-highlight helpers
├── share.ts           # URL hash encoding
├── imageLoader.ts     # File -> ImageBuffer via canvas
└── *.test.ts(x)       # vitest specs
patches/
└── cubejs+1.3.2.patch # one-line fix so cubejs works under Vite ESM

Known limitations

  • The parser is tuned for synthetic flat-net images (in-app renderer or similar tools like Ruwix Cube Solver). Real-cube photos would need perspective correction, lighting normalization, and a 6-face capture flow — see roadmap below.
  • Tightest mode is best-effort, not formally guaranteed. It iteratively re-runs cubejs with tighter maxDepth bounds within a ~9-second hard deadline. Most cubes reach a 20-move solution; some don't fit the budget and fall back to whatever progress was made (often 21 moves). True God's-Number guarantee would require min2phase or Korf's optimal solver — see roadmap.
  • Bundle is ~312 KB gzipped main + 20 KB worker chunk (~332 KB combined), dominated by three.js + react-three-fiber. Could be code-split so the 3D pane loads on demand, but for a cube-solver app the 3D view is most of the point.

Roadmap

  • 3D cube preview with animated solution playback (Three.js)
  • Tighter solutions, Tier 1 (v0.4) — Solve (tightest) button. Iterates Kociemba with maxDepth = baseline−1, baseline−2, …, 20 until either the budget runs out or no shorter solution exists at that depth. Web Worker keeps the UI responsive; hard 9s timeout prevents pathological cubes from hanging.
  • Tighter solutions, Tier 2 — Swap cubejs for a min2phase port (Chen Shuang). Heavier pruning tables and symmetry reduction; almost always 20 moves in milliseconds. ~80 KB gzipped bundle delta.
  • Tighter solutions, Tier 3 — Korf-style optimal IDA* (max of three pruning tables: corners + two halves of edges). Formally guaranteed ≤20 moves. Pattern databases are tens of MB — likely a server-side path rather than a fully-client solver.
  • Real-camera capture flow (six face captures, center-anchored color calibration)
  • iOS native version (Swift / SwiftUI / VisionKit)

Releases

  • v0.4.1 — Solving an already-solved cube now returns 0 moves with an "Already solved" banner. Previously cubejs's iterative-deepening pruning would emit a 14-move "neutral" sequence (e.g. R L U2 R L F2 R2 U2 R2 F2 R2 U2 F2 L2) instead of the empty solution.
  • v0.4.0Solve (tightest) button: iterative-deepening Kociemba aiming at God's Number (20 moves) within a ~9-second hard deadline. Solver moved into a Web Worker so the UI stays responsive while it churns. Lifetime "moves saved" counter tracked in localStorage.
  • v0.3.0 — Interactive 3D cube alongside the 2D net, with mouse orbit controls and animated face rotations during step-through. Detect unreachable cube states (parity violations, permuted centers) and surface a clear error instead of returning a partial solve.
  • v0.2.0 — Paste / drag-and-drop image upload, share-via-URL hash, auto-play step-through with speed control, accept any rotational orientation, smart calibration via globally optimal 6-way assignment.
  • v0.1.0 — Initial MVP: Vite + React + TS, Kociemba solver, flat-net image parser, editable cube net, step-through solution viewer.

Tech stack

Vite · React 19 · TypeScript · Vitest · cubejs (Kociemba) · three.js + react-three-fiber + drei · GitHub Pages

License

MIT — see LICENSE.

Yorumlar (0)

Sonuc bulunamadi