nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

commit 9df6811626d11ecb6b0cb15cb3a4be6d7ad479a1
parent 2e122bdffbe7524f5ed6f7cb704bbd1b778a6b41
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Wed, 28 May 2025 16:26:47 +0200

Revert memory64 and improve frontend for web version

Diffstat:
Mbuild | 17++++++++++++-----
Mweb/adapter.cpp | 3++-
Mweb/http/index.html | 9++++++---
Mweb/http/nissyapp.mjs | 26+++++++++++++++++++++++---
Mweb/worker.mjs | 16+++++++++++++++-
5 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/build b/build @@ -126,13 +126,20 @@ DFLAGS="-DDEBUG -g3 $(parsesanitize "$SANITIZE")" MFLAGS="-DTHREADS=$THREADS -D$ARCH" CPPFLAGS="-std=c++20 -pthread" +# TODO: +# MEMORY64 is supported on Firefox (from version 134) and Chrome (from 133), +# but not on Safari (nor on e.g. Firefox 128 ESR, current default on Debian). +# See also https://webassembly.org/features +# When it becomes widely available, we can support it by adding -sMEMORY64 +# to the WASMCFLAGS, WASMCPPFLAGS and WASMLINKFLAGS variables below, and +# -sMAXIMUM_MEMORY=10737418240 to WASMLINKFLAGS. This way we can enable +# solvers larger than h48h6k2 in the web version. + # Build flags for emscripten (WASM target) -WASMCFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L -pthread \ - -sMEMORY64 -sMAXIMUM_MEMORY=10737418240 -sASSERTIONS" -WASMCPPFLAGS="-std=c++20 -pthread -sMEMORY64 -sMAXIMUM_MEMORY=10737418240 \ - -sASSERTIONS" +WASMCFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L -pthread" +WASMCPPFLAGS="-std=c++20 -pthread" WASMMFLAGS="-DTHREADS=$THREADS -DWASMSIMD" -WASMLINKFLAGS="--no-entry -sEXPORT_NAME='Nissy' -sMODULARIZE -sMEMORY64 \ +WASMLINKFLAGS="--no-entry -sEXPORT_NAME='Nissy' -sMODULARIZE -sALLOW_MEMORY_GROWTH -sSTACK_SIZE=5MB -sPTHREAD_POOL_SIZE=$THREADS \ -sFETCH -sASYNCIFY -sLINKABLE -sEXPORT_ALL" diff --git a/web/adapter.cpp b/web/adapter.cpp @@ -23,7 +23,8 @@ const std::set<std::string> available_solvers "h48h1k2", "h48h2k2", "h48h3k2", - "h48h7k2", + "h48h4k2", + "h48h5k2", }; std::map<std::string, nissy::solver> loaded_solvers; diff --git a/web/http/index.html b/web/http/index.html @@ -9,9 +9,12 @@ <body> <input id="scrambleText" placeholder="Type the scramble here..."> <select id="solverSelector"> - <option value="h48h0k4">h48 h=0 k=4 (59Mb)</option> - <option value="h48h3k2" selected="selected">h48 h=3 k=2 (283Mb)</option> - <option value="h48h7k2">h48 h=7 k=2 (3.6Gb)</option> + <option value="h48h3k2" selected="selected"> + h48 h=4 k=2 (300 Mb) - light + </option> + <option value="h48h5k2" selected="selected"> + h48 h=5 k=2 (1 Gb) - fastest + </option> </select> <button id="solveButton">Solve</button> <div id="confirmDownload" style="display:none"> diff --git a/web/http/nissyapp.mjs b/web/http/nissyapp.mjs @@ -30,8 +30,8 @@ worker.onmessage = (event) => { function updateResults(label, results, enable) { resultsLabel.innerText = label; resultsText.innerText = results; - solveButton.disable = !enable; - solverSelector.disable = !enable; + solveButton.disabled = !enable; + solverSelector.disabled = !enable; } var logVisible = false; @@ -49,7 +49,27 @@ toggleLog.addEventListener("click", () => { solveButton.addEventListener("click", () => { const solver = solverSelector.options[solverSelector.selectedIndex].value; const scramble = scrField.value; - loadDataThenSolve(solver, scramble); + + const callbackId = ++lastCallbackId; + callbacks.set(callbackId, { + f: (callbackArg, validateResult) => { + if (validateResult) { + loadDataThenSolve(callbackArg.solver, callbackArg.scramble); + } else { + updateResults("Scramble is invalid", "", true); + } + }, + arg: { + solver: solver, + scramble: scramble + } + }); + + worker.postMessage({ + command: "validate scramble", + id: lastCallbackId, + arg: scramble + }); }); function loadDataThenSolve(solver, scramble) { diff --git a/web/worker.mjs b/web/worker.mjs @@ -8,6 +8,7 @@ const commands = [ { name: "load solver data", exec: loadSolverDataFromStorage }, { name: "download solver data", exec: downloadSolverData }, { name: "generate solver data", exec: generateSolverData }, + { name: "validate scramble", exec: validateScramble }, { name: "solve", exec: solve }, ]; @@ -45,7 +46,7 @@ async function loadSolverDataFromStorage(id, solver) { }); if (!(await nissy.isSolverAvailable(solver))) { - async_return(false, "Error: solver " + arg.solver + + async_return(false, "Error: solver " + solver + " is not available in this version of nissy."); return; } @@ -113,6 +114,19 @@ async function generateSolverData(id, solver) { } } +// Check if the scramble is valid. +// Argument: string (the scramble). +async function validateScramble(id, arg) { + const async_return = (success) => postMessage({ + command: "validate scramble", + id: id, + arg: success + }); + + var cube = new nissy.Cube(); + async_return(cube.move(arg).ok()); +} + // Solve the cube with the given options. // Argument: { // solver: string