diff --git a/apps/web/src/routes/kripke/+page.server.ts b/apps/web/src/routes/kripke/+page.server.ts index cfc8e16..5a1821e 100644 --- a/apps/web/src/routes/kripke/+page.server.ts +++ b/apps/web/src/routes/kripke/+page.server.ts @@ -1,7 +1,11 @@ import type { SeoProps } from "$components/seo"; +import { dailySeed } from "./lib/system"; export async function load() { + const seed = dailySeed(); + return { + seed, seo: { title: "KRIPKE - cannorin.net", description: "KRIPKE - WORDLE, but for Kripke frames!", diff --git a/apps/web/src/routes/kripke/+page.svelte b/apps/web/src/routes/kripke/+page.svelte index a144b5c..fea63c1 100644 --- a/apps/web/src/routes/kripke/+page.svelte +++ b/apps/web/src/routes/kripke/+page.svelte @@ -6,15 +6,17 @@ import LuRotateCw from "lucide-svelte/icons/rotate-cw"; import LuX from "lucide-svelte/icons/x"; import { onMount } from "svelte"; -import FrameInput from "./frame-input.svelte"; -import Game, { type GameStatus, type Move } from "./game.svelte"; -import Rules from "./rules.svelte"; -import Share from "./share.svelte"; +import FrameInput from "./components/frame-input.svelte"; +import Game, { type GameStatus } from "./components/game.svelte"; +import Rules from "./components/rules.svelte"; +import Share from "./components/share.svelte"; +import { getFrameBySeed, getTimeUntilNextGame } from "./lib/system"; import { daily } from "./store"; -import { getDailyFrame, getTimeUntilNextGame } from "./system"; -const { id, frame } = getDailyFrame(); +let { data } = $props(); +const seed = data.seed; +const { id, frame } = getFrameBySeed(seed); const guess = (frameId: number) => isomorphic[frameId] === id; const check = (formula: Formula) => validWorlds(frame, formula).length; const getAnswer = () => id; @@ -46,7 +48,10 @@ onMount(() => { Daily Challenge: {timeUntilNextGame.hours}:{timeUntilNextGame.minutes}:{timeUntilNextGame.seconds} until the next game. - + { dialogOpen = true; }} />
@@ -80,7 +85,7 @@ onMount(() => {
- id: {answerId} + id: {answerId}, seed: {seed}
@@ -88,8 +93,7 @@ onMount(() => {
{:else if status === "lose"} {#await getAnswer() then answerId} -
  • -
    -

    YOU LOSE!

    -

    The answer was:

    -
    -
    - id: {answerId} - -
    +
  • +
  • {/await} {/if} diff --git a/apps/web/src/routes/kripke/rules.svelte b/apps/web/src/routes/kripke/components/rules.svelte similarity index 100% rename from apps/web/src/routes/kripke/rules.svelte rename to apps/web/src/routes/kripke/components/rules.svelte diff --git a/apps/web/src/routes/kripke/share.svelte b/apps/web/src/routes/kripke/components/share.svelte similarity index 96% rename from apps/web/src/routes/kripke/share.svelte rename to apps/web/src/routes/kripke/components/share.svelte index 9f92bb1..36895d3 100644 --- a/apps/web/src/routes/kripke/share.svelte +++ b/apps/web/src/routes/kripke/components/share.svelte @@ -35,7 +35,7 @@ let shareText = $derived.by(() => { ${history} ${status === "win" ? moves.length : "X"}/10 -https://www.cannorin.net/kripke${seed ? `/random?seed=${seed}` : ""}`; +https://www.cannorin.net/kripke${seed ? `/random/${seed}` : ""}`; return encodeURIComponent(text); }); diff --git a/apps/web/src/routes/kripke/system.ts b/apps/web/src/routes/kripke/lib/system.ts similarity index 78% rename from apps/web/src/routes/kripke/system.ts rename to apps/web/src/routes/kripke/lib/system.ts index 044fb3d..ba03763 100644 --- a/apps/web/src/routes/kripke/system.ts +++ b/apps/web/src/routes/kripke/lib/system.ts @@ -20,26 +20,17 @@ function cyrb53(str: string, seed = 0): number { export const date = () => new Date().toISOString().split("T")[0]; -export function getDailyFrame() { - // Use UTC ISO string so it's consistent across time zones +export const dailySeed = () => { const dateStr = date(); - const hash = cyrb53(dateStr); - const index = hash % nontrivials.length; - return { - date: dateStr, - id: nontrivials[index], - frame: getFrame(nontrivials[index]), - }; -} + return cyrb53(dateStr) % 0x100000000; +}; export const randomSeed = () => Math.floor(Math.random() * 0x100000000); -export function getRandomFrame(seed?: number) { - const actualSeed = seed ?? randomSeed(); +export function getFrameBySeed(seed: number) { const hash = cyrb53("random", seed); const index = hash % nontrivials.length; return { - seed: actualSeed, id: nontrivials[index], frame: getFrame(nontrivials[index]), }; diff --git a/apps/web/src/routes/kripke/vector.ts b/apps/web/src/routes/kripke/lib/vector.ts similarity index 100% rename from apps/web/src/routes/kripke/vector.ts rename to apps/web/src/routes/kripke/lib/vector.ts diff --git a/apps/web/src/routes/kripke/random/+page.server.ts b/apps/web/src/routes/kripke/random/+page.server.ts index 12d2f9f..16e8fec 100644 --- a/apps/web/src/routes/kripke/random/+page.server.ts +++ b/apps/web/src/routes/kripke/random/+page.server.ts @@ -1,5 +1,5 @@ -import type { SeoProps } from "$components/seo"; -import { randomSeed } from "../system.js"; +import { redirect } from "@sveltejs/kit"; +import { randomSeed } from "../lib/system"; export async function load({ url }) { const seedStr = url.searchParams.get("seed"); @@ -13,20 +13,5 @@ export async function load({ url }) { return randomSeed(); } })(); - - return { - seed, - seo: { - title: "KRIPKE (random challenge) - cannorin.net", - description: "KRIPKE - WORDLE, but for Kripke frames!", - openGraph: { - title: "KRIPKE (random challenge) - cannorin.net", - description: "KRIPKE - WORDLE, but for Kripke frames!", - }, - twitter: { - title: "KRIPKE (random challenge) - cannorin.net", - description: "KRIPKE - WORDLE, but for Kripke frames!", - }, - } as SeoProps, - }; + redirect(302, `/kripke/random/${seed}`); } diff --git a/apps/web/src/routes/kripke/random/[seed]/+page.server.ts b/apps/web/src/routes/kripke/random/[seed]/+page.server.ts new file mode 100644 index 0000000..197937b --- /dev/null +++ b/apps/web/src/routes/kripke/random/[seed]/+page.server.ts @@ -0,0 +1,31 @@ +import type { SeoProps } from "$components/seo"; +import { error } from "@sveltejs/kit"; + +export async function load({ params }) { + const seedStr = params.seed; + const seed = (() => { + try { + const seed = Number.parseInt(seedStr); + if (!Number.isSafeInteger(seed)) throw error(400); + return seed; + } catch { + throw error(400); + } + })(); + + return { + seed, + seo: { + title: `KRIPKE (seed ${seed}) - cannorin.net`, + description: "KRIPKE - WORDLE, but for Kripke frames!", + openGraph: { + title: `KRIPKE (seed ${seed}) - cannorin.net`, + description: "KRIPKE - WORDLE, but for Kripke frames!", + }, + twitter: { + title: `KRIPKE (seed ${seed}) - cannorin.net`, + description: "KRIPKE - WORDLE, but for Kripke frames!", + }, + } as SeoProps, + }; +} diff --git a/apps/web/src/routes/kripke/random/+page.svelte b/apps/web/src/routes/kripke/random/[seed]/+page.svelte similarity index 81% rename from apps/web/src/routes/kripke/random/+page.svelte rename to apps/web/src/routes/kripke/random/[seed]/+page.svelte index c037e26..fd9b305 100644 --- a/apps/web/src/routes/kripke/random/+page.svelte +++ b/apps/web/src/routes/kripke/random/[seed]/+page.svelte @@ -5,15 +5,15 @@ import { type Formula, isomorphic, validWorlds } from "@cannorin/kripke"; import LuRotateCw from "lucide-svelte/icons/rotate-cw"; import LuX from "lucide-svelte/icons/x"; -import FrameInput from "../frame-input.svelte"; -import Game, { type GameStatus, type Move } from "../game.svelte"; -import Rules from "../rules.svelte"; -import Share from "../share.svelte"; -import { getRandomFrame } from "../system"; +import FrameInput from "../../components/frame-input.svelte"; +import Game, { type GameStatus, type Move } from "../../components/game.svelte"; +import Rules from "../../components/rules.svelte"; +import Share from "../../components/share.svelte"; +import { getFrameBySeed } from "../../lib/system"; let { data } = $props(); const seed = data.seed; -const { id, frame } = getRandomFrame(seed); +const { id, frame } = getFrameBySeed(seed); const guess = (frameId: number) => isomorphic[frameId] === id; const check = (formula: Formula) => validWorlds(frame, formula).length; const getAnswer = () => id; @@ -29,7 +29,7 @@ $effect(() => { {#snippet seedNumber()} - {seed} + {seed} {/snippet}
    @@ -41,7 +41,10 @@ $effect(() => { Random Challenge (seed: {@render seedNumber()}) - + { dialogOpen = true; }}/>
    @@ -76,7 +79,7 @@ $effect(() => {
    - id: {answerId} + id: {answerId}, seed: {seed}
    @@ -84,8 +87,7 @@ $effect(() => {