collapse / src / lib / Grid.svelte
Grid.svelte
Raw
<script lang="ts">
    import cell from "./cell";
    import vector from "./vector";
    import grid from "./grid";
    const getCircularReplacer = () => {
        const seen = new WeakSet();
        return (key, value) => {
            if (typeof value === "object" && value !== null) {
            if (seen.has(value)) {
                return;
            }
            seen.add(value);
            }
            return value;
        };
    };

    const colors = {
        0: "blue",
        1: "yellow",
        2: "green",
        3: "gray",
        4: "white"
    };
    export let w: number = 4;
    export let h: number = 4;
    export let s: number = 1.0;
    export let delay: number = 0.0;
    export let showWhileGenerating = false;
    let data: grid = new grid(w, h);
    $: data = new grid(w, h);

    let to;
    let generating = false;
    function delayedSolve(){
        if(to){
            clearInterval(to);
            to = null;
            generating = false;
        }
        else{
            to = setInterval( () => {
                if(data.curatedsolve() && to){
                    clearInterval(to);
                    to = null;
                    generating = false;
                }
                else{
                    generating = true;
                }
                data = data;
            }, delay );
        }
        data = data;
    }
</script>

<!-- title={JSON.stringify(cell, getCircularReplacer())} -->

<main>
    {#if !generating || showWhileGenerating}
        <div class="data" style="--s:{s}em;--w:{w};">
            {#each data.cells as group}
                    {#each group as cell}
                        <button 
                            on:click={ ()=>{console.log(cell);data.collapse( new vector(cell.x, cell.y) );data.evaluate();data=data;} } 
                            class="cell" 
                            style="--bg:{colors[cell.possible[0]]};" 
                            class:collapsed={cell.possible.length == 1}
                            
                        >
                            {cell.possible.length == 1 ? "" : cell.possible.length}
                        </button>
                    {/each}
            {/each}
        </div>
    {:else if generating}
        <progress min={0} max={w*h} value={(w*h)-data.getUncollapsed().length} />
        {(w*h)-data.getUncollapsed().length}/{w*h}
    {/if}
    <div>
        <button on:click={ ()=>{data.solve();data.evaluate();data=data;}}>Solve One</button>
        <button on:click={ delayedSolve }>{to ? "Stop Solving" : "Solve All"}</button>
    </div>
</main>

<style>
    main {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        font-size: 3em;
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    .data {
        display: grid;
        font-size: var(--s);
        grid-template-columns: repeat(var(--w), 1fr);
    }
    button {
        display: inline-block;
        color: var(--fg);
        cursor: pointer;
        background: var(--bg-secondary);
        border: 1px solid var(--bg-border);

        font-size: .5em;
        padding: 0.5em 1em;
        transition: all .2s;
    }
    button:hover {
        background: var(--bg);
    }
    button:active {
        background: var(--bg-border);
    }
    .cell {
        height: 2.5em;
        width: 2.5em;
        margin: 2px;
        font-size: 1em;

        display: flex;
        justify-content: center;
        align-items: center;
    }
    .cell.collapsed {
        background: var(--bg);
        text-shadow: 0 0 2px black;
        margin: 0;
        border-color: var(--bg);
    }
</style>