code wiki / _hdl_build / nx_sudoku_wasm.nx
nx_sudoku_wasm.nx
buildroot/runtime/_hdl_build/nx_sudoku_wasm.nx
about
nx_sudoku_wasm.nx -- SOVEREIGN SUDOKU as a browser game: pure-Nishi, NO-FLOAT, BASE-RELATIVE.
The same source is the native binary (base = an mmap'd buffer, provable by a gate) and the
WebAssembly module (base = 0). Exports the estate's established game interface --
init / tick / render / score / ww / hh / fb_off -- so the SAME blit-only HTML packager that serves
nx_wasm_2048 and nx_wasm_craft serves this, and THE PAGE HOLDS NO GAME LOGIC: it copies a
framebuffer and forwards keys.
WHY THIS REPLACES THE JAVASCRIPT. The /games sudoku previously ran hand-written JS: a second
implementation of a ruleset we already had in NishiLang, untestable by any estate gate, and not
sovereign in any sense. Rules, solver, generator, renderer and input now live in one NishiLang
module that a gate can drive natively. There is no bank file, no data format, no host cooperation
and nothing to keep in sync -- the module GENERATES its own proven-unique puzzles in-image.
UNIQUENESS IS COUNTED, NOT ASSUMED, and it is not counted here: the one solver/counter/carver lives
in nx_sudoku_core.nx and is shared with nx_sudoku (the bank tool). Composing it rather than copying
it is the point -- two implementations of one ruleset is the duplicate-ruler defect.
Clue floor 17: McGuire, Tugemann & Civario (2012) proved no 16-clue sudoku has a unique solution.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 2 imports · 1 importers
imports: nx_nishi_font_core.nxnx_sudoku_core.nx
imported by: nx_sudoku_wasm_gate.nx
structs
| none |
consts
| 22 | const O_MAGIC_20260810: i64 = 20260810 |
| 23 | const O_MAGIC_7919: i64 = 7919 |
| 25 | const W: i64 = 288 |
| 26 | const H: i64 = 288 |
| 27 | const MARGIN: i64 = 9 |
| 28 | const CELL: i64 = 30 |
| 31 | const O_FB: i64 = 0 // W*H i64 packed RGB = 663552 |
| 32 | const O_CORE: i64 = 663552 // SC_SIZE (8432): the shared solver's working area |
| 33 | const O_CUR: i64 = 671984 // 81 i64: the player's board (starts as the givens) |
| 34 | const O_ST: i64 = 672632 // 8 i64 state |
| 35 | const O_MSK: i64 = 672696 // 9216 B font glyph scratch |
| 36 | const O_STR: i64 = 681912 // digit string scratch |
| 37 | const O_END: i64 = 681944 // total bytes a host must provide |
| 40 | const S_SEL: i64 = 0 // selected cell 0..80, or -1 |
| 41 | const S_SOLVED: i64 = 1 |
| 42 | const S_SHOW: i64 = 2 // reveal wrong digits (only when the player asks) |
| 43 | const S_CLUES: i64 = 3 |
| 44 | const S_SEED: i64 = 4 |
functions
| 46 | func rgb(r: i64, g: i64, b: i64) -> i64 { return (r & 255) | ((g & 255) << 8) | ((b & 255) << 16) } called by 1: render_impl |
| 48 | func fillr(base: i64, x0: i64, y0: i64, x1: i64, y1: i64, c: i64) -> i64 called by 1: render_impl |
| 65 | func st_get(base: i64, i: i64) -> i64 { let p: *i64 = (base + O_ST) as *i64; return p[i] } |
| 66 | func st_put(base: i64, i: i64, v: i64) -> i64 { let p: *i64 = (base + O_ST) as *i64; p[i]=v; return 0 } |
| 67 | func cur_get(base: i64, i: i64) -> i64 { let p: *i64 = (base + O_CUR) as *i64; return p[i] } |
| 68 | func cur_put(base: i64, i: i64, v: i64) -> i64 { let p: *i64 = (base + O_CUR) as *i64; p[i]=v; return 0 } |
| 70 | func given(base: i64, i: i64) -> i64 { if sc_get(base+O_CORE, SC_G, i)!=0 { return 1 } return 0 } |
| 71 | func soln(base: i64, i: i64) -> i64 { return sc_get(base+O_CORE, SC_SOL, i) } |
| 74 | func load_puzzle(base: i64, clues: i64, seed: i64) -> i64 |
| 91 | func filled(base: i64) -> i64 |
| 97 | func wrong(base: i64) -> i64 |
| 107 | func check_solved(base: i64) -> i64 |
| 115 | func render_impl(base: i64) -> i64 |
| 177 | func init_impl(base: i64) -> i64 |
| 187 | func tick_impl(base: i64, k: i64) -> i64 |
| 235 | func tap_impl(base: i64, px: i64, py: i64) -> i64 |
| 251 | func score_impl(base: i64) -> i64 |
| 265 | func init() -> i64 { return init_impl(0) } calls 1: init_impl |
| 266 | func tick(k: i64) -> i64 { return tick_impl(0, k) } calls 1: tick_impl |
| 267 | func tap(px: i64, py: i64) -> i64 { return tap_impl(0, px, py) } |
| 268 | func render() -> i64 { return render_impl(0) } calls 1: render_impl |
| 269 | func score() -> i64 { return score_impl(0) } calls 1: score_impl |
| 270 | func solved() -> i64 { return st_get(0, S_SOLVED) } |
| 271 | func clues() -> i64 { return st_get(0, S_CLUES) } |
| 272 | func fb_off() -> i64 { return O_FB } |
| 273 | func ww() -> i64 { return W } |
| 274 | func hh() -> i64 { return H } |
| 275 | func mem_end() -> i64 { return O_END } |