[O] Cleanup code

This commit is contained in:
2024-12-16 14:41:58 -05:00
parent abef73ab9f
commit a7f09a3de3
3 changed files with 54 additions and 61 deletions
+40 -57
View File
@@ -2,33 +2,46 @@
import svelteLogo from './assets/svelte.svg'
import viteLogo from '/vite.svg'
import Number from './lib/Number.svelte'
import { cfg, eStates, JsonTy, nStates, randInt, range } from "./utils";
import { cfg, eStates, JsonTy, nStates, randInt, range, zero8 } from "./utils";
import Line from "./lib/Line.svelte";
import { cat } from "./examples";
import { solve } from "./solver";
type i8s = Int8Array
// Main variables
const [rows, cols] = [40, 40]
const [eRows, eCols] = [rows + 1, cols + 1]
let numbers = Int8Array.from({ length: rows * cols }, () => 0)
let numberMask = Int8Array.from({ length: rows * cols }, () => 0)
let numberState = Int8Array.from({ length: rows * cols }, () => 0)
let hStates = Int8Array.from({ length: eRows * eCols }, () => 0)
let vStates = Int8Array.from({ length: eRows * eCols }, () => 0)
const solutionHStates = hStates.slice()
const solutionVStates = vStates.slice()
let [numbers, numberMask, numberState] = [zero8(rows * cols), zero8(rows * cols), zero8(rows * cols)]
let [hStates, vStates] = [zero8(eRows * eCols), zero8(eRows * eCols)]
const [solutionHStates, solutionVStates] = [zero8(eRows * eCols), zero8(eRows * eCols)]
// Colors
let [hColors, vColors] = [zero8(eRows * eCols), zero8(eRows * eCols)]
let colors = ["#90A4AEFF"]
// Editing controls
let grid: HTMLDivElement
const editMode = true
let maskMode = false
interface Checkpoint {
hStates: Int8Array
vStates: Int8Array
numbers: Int8Array
numberMask: Int8Array
// Checkpoints
interface Checkpoint { hStates: i8s, vStates: i8s, hColors: i8s, vColors: i8s, numbers: i8s, numberMask: i8s }
const ckpt = () => ({hStates, vStates, numbers, numberMask, hColors, vColors})
const loadPt = () => JsonTy.parse(localStorage.getItem('slitherlink-checkpoints') ?? "[]")
let ckpts: Checkpoint[] = loadPt()
const savePt = (fn: () => any) => () => { fn()
localStorage.setItem('slitherlink-checkpoints', JsonTy.stringify(ckpts))
ckpts = loadPt()
}
const restorePt = (pt: Checkpoint) => {
pt.hStates.forEach((st, idx) => hStates[idx] = st)
pt.vStates.forEach((st, idx) => vStates[idx] = st)
pt.numbers.forEach((n, idx) => numbers[idx] = n)
pt.numberMask.forEach((n, idx) => numberMask[idx] = n)
pt.hColors.forEach((n, idx) => hColors[idx] = n)
pt.vColors.forEach((n, idx) => vColors[idx] = n)
}
let checkpoints: Checkpoint[] = JsonTy.parse(localStorage.getItem('slitherlink-checkpoints') ?? "[]")
const saveCheckpoints = () => localStorage.setItem('slitherlink-checkpoints', JsonTy.stringify(checkpoints))
// Run something on the edges of a cell
function updateEdges(x: number, y: number, condition: (st: number) => boolean, op: (st: number) => number) {
@@ -179,19 +192,18 @@
bind:this={grid}>
{#each range(rows) as y}
{#each range(cols) as x}
<Number x={x} y={y} n={numbers[y * cols + x]}
masked={numberMask[y * cols + x] === 1} state={numberState[y * cols + x]}
on:click={(e) => editModeClickNumber(e, x, y)}/>
<Number x={x} y={y} n={numbers[y * cols + x]} on:click={(e) => editModeClickNumber(e, x, y)}
masked={numberMask[y * cols + x] === 1} state={numberState[y * cols + x]}/>
{/each}
{/each}
{#each range(eRows) as y}
{#each range(cols) as x}
<Line sx={x} sy={y} state={hStates[y * eCols + x]} />
<Line sx={x} sy={y} state={hStates[y * eCols + x]} colorIdx="{hColors[y * eCols + x]}"/>
{/each}
{/each}
{#each range(rows) as y}
{#each range(eCols) as x}
<Line sx={x} sy={y} vertical state={vStates[y * eCols + x]} />
<Line sx={x} sy={y} vertical state={vStates[y * eCols + x]} colorIdx="{vColors[y * eCols + x]}"/>
{/each}
{/each}
</div>
@@ -201,7 +213,6 @@
{#if maskMode}
<button on:click={() => {
solve(rows, cols, numbers, numberMask).then(({horiStates, vertStates}) => {
console.log(horiStates, vertStates)
horiStates.forEach((st, idx) => hStates[idx] = st)
vertStates.forEach((st, idx) => vStates[idx] = st)
})
@@ -210,26 +221,12 @@
<button on:click={() => editModeReduce()}>Reduce</button>
{:else}
<button on:click={() => {
numbers = Int8Array.from({ length: rows * cols }, () => 0)
[numbers, numberState] = [zero8(rows * cols), zero8(rows * cols)]
numberMask = Int8Array.from({ length: rows * cols }, () => 1)
numberState = Int8Array.from({ length: rows * cols }, () => 0)
}}>Clear Numbers</button>
<button on:click={() => {
alert("TODO")
}}>Gen Numbers</button>
<button on:click={() => {
// Download a json of the current hStates, vStates, numbers, numberMask
const data = {hStates, vStates, numbers, numberMask}
const blob = new Blob([JSON.stringify(data)], {type: 'application/json'})
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'slitherlink.json'
a.click()
URL.revokeObjectURL(url)
}}>Save Routes</button>
<button on:click={() => alert("TODO")}>Gen Numbers</button>
<button on:click={() => JsonTy.download(ckpt(), 'slitherlink-checkpoint.json')}>Download</button>
{/if}
<button on:click={() => maskMode = !maskMode}>Toggle Mask Mode ({maskMode ? "off" : "on"})</button>
</div>
@@ -237,27 +234,13 @@
<div>Checkpoints</div>
<!-- Add Checkpoint -->
<div class="btn-div">
<button on:click={() => {
checkpoints.push({hStates: hStates.slice(), vStates: vStates.slice(), numbers: numbers.slice(), numberMask: numberMask.slice()})
saveCheckpoints()
}}>Add</button>
<button on:click={() => {
checkpoints[checkpoints.length - 1] = {hStates: hStates.slice(), vStates: vStates.slice(), numbers: numbers.slice(), numberMask: numberMask.slice()}
saveCheckpoints()
}}>Overwrite</button>
<button on:click={() => {
checkpoints.pop()
saveCheckpoints()
}}>Remove</button>
<button on:click={savePt(() => ckpts.push(ckpt()))}>Add</button>
<button on:click={savePt(() => ckpts[ckpts.length - 1] = ckpt())}>Overwrite</button>
<button on:click={savePt(() => ckpts.pop())}>Remove</button>
</div>
<div class="btn-div">
{#each checkpoints as checkpoint, i}
<button on:click={() => {
checkpoint.hStates.forEach((st, idx) => hStates[idx] = st)
checkpoint.vStates.forEach((st, idx) => vStates[idx] = st)
checkpoint.numbers.forEach((n, idx) => numbers[idx] = n)
checkpoint.numberMask.forEach((n, idx) => numberMask[idx] = n)
}}>{i + 1}</button>
{#each ckpts as cp, i}
<button on:click={() => restorePt(cp)}>{i + 1}</button>
{/each}
</div>
{/if}
+3 -3
View File
@@ -1,15 +1,15 @@
<script lang="ts">
import { cfg, pos } from "../utils";
interface Props { sx: number, sy: number, vertical?: boolean, state: number }
let { sx, sy, vertical, state }: Props = $props()
interface Props { sx: number, sy: number, vertical?: boolean, state: number, colorIdx: number }
let { sx, sy, vertical, state, colorIdx }: Props = $props()
let left = cfg.totalW * sx
let top = cfg.totalW * sy
let styles = pos(left, top)
</script>
<div class="grid-line" style="{styles}"
<div class="grid-line c{colorIdx}" style="{styles}"
class:vertical={vertical}
class:selected={state === 1} class:crossed={state === 2} class:auto-crossed={state === 5}>
</div>
+11 -1
View File
@@ -22,6 +22,7 @@ export const sty = (styles: any) => Object.entries(styles).map(([k, v]) => `${k}
export const pos = (x: number, y: number) => `top:${y}px;left:${x}px;`
export const randInt = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min
export const range = (n: number) => Array.from({length: n}, (_, i) => i)
export const zero8 = (n: number) => new Int8Array(n).fill(0)
// Json with TypedArray serialization
export const JsonTy = {
@@ -39,5 +40,14 @@ export const JsonTy = {
return new globalThis[v.type](v.data);
}
return v; // For all other data types, keep it as is
})
}),
download: (obj: any, name: string) => {
const blob = new Blob([JsonTy.stringify(obj)], {type: 'application/json'})
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = name
a.click()
URL.revokeObjectURL(a.href)
}
}