mirror of
https://github.com/tiennm99/rubik.git
synced 2026-05-14 04:58:51 +00:00
eb592e5c98
- Solver: cubejs-backed two-phase solver, lazy-loaded chunk so the ~80 KB table-init cost stays out of the main bundle. New cube-to-facelets converter (3D model -> 54-char URFDLB string) verified bit-for-bit against cubejs's own move() output. - Solve button in ControlsPanel with disabled "Solving..." state, wired through the CubeView controller; animates each move sequentially. - Rewrite solved-check to the WCA face-uniformity definition. The old strict "identity quaternion per cubie" check rejected center spins (invisible) and whole-cube rotations, both of which are still solved per WCA / Kociemba. - Vitest specs under tests/ cover cubie-model, move-definitions, move-parser, apply-move (4x turns, inverses, sune order=6, R2 == R R), scrambler, solved-check, algorithm-runner, cube-to-facelets, solver. 39 tests, ~3 s. Adds npm test / npm run test:watch scripts.
47 lines
1.7 KiB
JavaScript
47 lines
1.7 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
||
import { createSolvedCube } from '../src/lib/core/cubie-model.js';
|
||
import { applyMove } from '../src/lib/core/apply-move.js';
|
||
import { parseAlgorithm } from '../src/lib/core/move-parser.js';
|
||
import { isSolved } from '../src/lib/core/solved-check.js';
|
||
import { solve } from '../src/lib/core/solver.js';
|
||
|
||
function run(cubies, algo) {
|
||
for (const m of parseAlgorithm(algo)) applyMove(cubies, m);
|
||
}
|
||
|
||
describe('solver', () => {
|
||
// 4–5 s init for cubejs Kociemba tables on first call. Set a generous bound.
|
||
it('returns an algorithm that brings a scrambled cube to solved', async () => {
|
||
const scramble = "R U R' F' R U R' U' R' F R2 U' R'";
|
||
const c = createSolvedCube();
|
||
run(c, scramble);
|
||
expect(isSolved(c)).toBe(false);
|
||
|
||
const solution = await solve(c);
|
||
expect(typeof solution).toBe('string');
|
||
expect(solution.length).toBeGreaterThan(0);
|
||
|
||
run(c, solution);
|
||
expect(isSolved(c)).toBe(true);
|
||
}, 30000);
|
||
|
||
it('solves a deeper scramble', async () => {
|
||
const scramble = "F R U' B2 D L' F' U R2 D' B U L' F2 D B' R U2 L'";
|
||
const c = createSolvedCube();
|
||
run(c, scramble);
|
||
|
||
const solution = await solve(c);
|
||
run(c, solution);
|
||
expect(isSolved(c)).toBe(true);
|
||
}, 30000);
|
||
|
||
it('returns a solution that keeps an already-solved cube solved', async () => {
|
||
// cubejs does not always return '' for solved input — it can return
|
||
// a non-trivial identity-equivalent algorithm. Verify by applying.
|
||
const c = createSolvedCube();
|
||
const solution = await solve(c);
|
||
run(c, solution);
|
||
expect(isSolved(c)).toBe(true);
|
||
}, 30000);
|
||
});
|