diff --git a/README.md b/README.md index 292aa18..d3992e6 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,5 @@

-OpenWordle is a completely open source and lightweight wordle game with no runtime dependencies +OpenWordle is a completely open source and lightweight wordle game with very minimal set of runtime dependencies diff --git a/package.json b/package.json index 872fcb4..8cc50b5 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,9 @@ "typescript": "^5.0.2", "vite": "^4.4.5", "vite-plugin-compression": "^0.5.1" + }, + "dependencies": { + "copy-to-clipboard": "^3.3.3", + "qr-creator": "^1.0.0" } } diff --git a/src/Game.svelte b/src/Game.svelte index 0c6739c..dfd7ee6 100644 --- a/src/Game.svelte +++ b/src/Game.svelte @@ -10,6 +10,8 @@ import { isIn, loadDict } from "./dictionary"; import { onMount } from "svelte"; import Keyboard from "./Keyboard.svelte"; + import GameCreator from "./GameCreator.svelte"; + import { decode } from "./lib/cipher"; let targets = getForNWord(5); @@ -23,12 +25,22 @@ let loading = true; let not_a_word = false; + let game_creator = false; let green_letters: string[] = []; let yellow_letters: string[] = []; let unfit_letters: string[] = []; - console.log(word); + ( + function() { + const urlprops = new URLSearchParams(window.location.search); + const challenge = urlprops.get('challenge'); + if (challenge !== null) { + word = decode(atob(decodeURIComponent(challenge))); + console.log(word) + } + } + )() onMount(async () => { await loadDict(); @@ -130,6 +142,8 @@ } + + {#if not_a_word} @@ -174,6 +188,10 @@ Give up + +

{#each guessed as g1, i} {#each g1 as letter, ii} diff --git a/src/GameCreator.svelte b/src/GameCreator.svelte new file mode 100644 index 0000000..d0bb520 --- /dev/null +++ b/src/GameCreator.svelte @@ -0,0 +1,69 @@ + + +{#if show} + + + Create a game + + +

+ Word: + +

+

+ + + +

+ + + {show = false; word = getRandom(5); upd_qr()}}> + Close + + + Copy link + + +
+{/if} \ No newline at end of file diff --git a/src/app.css b/src/app.css index 08c958c..b2df13c 100644 --- a/src/app.css +++ b/src/app.css @@ -43,6 +43,18 @@ button:active { background: #161616; } +input[type=text] { + background: #181818; + border: 1px solid #343434; + border-radius: 6px; + margin: 0 4px; + padding: 4px 6px; + outline: none; + min-width: 80px; + width: 80px; + max-width: 100%; +} + @media (prefers-color-scheme: light) { :root { color: #213547; diff --git a/src/lib/cipher.ts b/src/lib/cipher.ts new file mode 100644 index 0000000..0219904 --- /dev/null +++ b/src/lib/cipher.ts @@ -0,0 +1,22 @@ +import { random } from "./random"; + +export function encode(word: string) { + let out = ''; + for (const letter of word) { + out += String.fromCharCode(random(32, 128)) + letter; + } + return out +} + +export function decode(ciphertext: string) { + let out = ''; + for (let i = 0; i != ciphertext.length; i++) { + if (i % 2 == 1) { + out += ciphertext[i]; + } + } + return out; +} + +globalThis.encode = encode; +globalThis.decode = decode; \ No newline at end of file diff --git a/src/targets.ts b/src/targets.ts index 2850d98..8362781 100644 --- a/src/targets.ts +++ b/src/targets.ts @@ -11,4 +11,14 @@ export function getForNWord(len: number) { return out } +export function getRandom(len: number | null = null) { + const dataset = len ? getForNWord(len) : targets; + for (const target of dataset) { + if (random(0, Math.floor(dataset.length * 0.5)) == 0) { + return target; + } + } + return dataset[0]; +} + export default targets \ No newline at end of file diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index be5db66..a3c177c 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1,3 +1,4 @@ /// /// -const TARGETS: string \ No newline at end of file +const TARGETS: string; +declare module 'qr-creator'; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 0fa9dfe..6d039ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -333,6 +333,13 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +copy-to-clipboard@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" + integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== + dependencies: + toggle-selection "^1.0.6" + css-tree@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" @@ -670,6 +677,11 @@ postcss@^8.4.27: picocolors "^1.0.0" source-map-js "^1.0.2" +qr-creator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/qr-creator/-/qr-creator-1.0.0.tgz#f350a8f0b5be02bd1fc1ef133a038a06ef8bc5ef" + integrity sha512-C0cqfbS1P5hfqN4NhsYsUXePlk9BO+a45bAQ3xLYjBL3bOIFzoVEjs79Fado9u9BPBD3buHi3+vY+C8tHh4qMQ== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -815,6 +827,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + tslib@^2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"