Readme

Clone of @maxm/staticChess but for Wordle. Every letter is a link. The game state is stored in the URL bar.

You could do silly things like playing collaborative Wordle with your friends by trading links back and forth. Or undo any mistakes by clicking the back button. I also make it easy to generate a new game from any of your current game's guesses – to send to a friend.

They key to these static games like this one and @maxm/staticChess is to figure out:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** @jsxImportSource https://esm.sh/react */
import { render } from "https://deno.land/x/resvg_wasm/mod.ts";
import { html } from "https://esm.town/v/stevekrouse/html";
import { reloadOnSaveFetchMiddleware } from "https://esm.town/v/stevekrouse/reloadOnSave";
import { renderToString } from "npm:react-dom/server";
const GREEN = "#6aaa64";
const YELLOW = "#c9b458";
const GRAY = "#787c7e";
const LIGHT_GRAY = "#d3d6da";
// TODO - more words
const wordleWords = [
"array",
"cache",
"class",
"clone",
"codec",
"debug",
"fetch",
"frame",
"gigot",
"index",
"input",
"logic",
"patch",
"query",
"proxy",
"regex",
"route",
"stack",
"token",
"tuple",
];
interface Game {
answer: string;
guesses: string[];
currentGuess: string;
}
function encodeGame(game: Game): string {
return btoa(JSON.stringify(game));
}
function decodeGame(encoded: string): Game {
return JSON.parse(atob(encoded));
}
function nextStateEncoded(url, game: Game, action: string): string | undefined {
const next = nextState(game, action);
return next ? `https://${url}/${encodeGame(next)}` : undefined;
}
function nextState(game: Game, action: string): Game | undefined {
// TODO - check if action is valid and return null if not, ie no link
const { answer, guesses, currentGuess } = game;
if (guesses.some((guess) => [...guess].some((x, i) => x === action && !answer.includes(action)))) {
return null;
}
if (answer === guesses.at(-1)) return null;
if (action === "Enter" && currentGuess.length !== 5) return null;
if (action === "Enter") {
return {
...game,
guesses: [...game.guesses, currentGuess],
currentGuess: "",
};
}
if (action === "Delete") {
return {
...game,
currentGuess: currentGuess.slice(0, -1),
};
}
if (currentGuess.length === 5) return null;
return {
...game,
currentGuess: currentGuess + action,
};
}
function rightPad(str: string, length: number): string {
return str + " ".repeat(length - str.length);
}
function letterColor({ answer, guesses }: Game, letter: string): string {
if (guesses.some((guess) => [...guess].some((x, i) => x === letter && answer[i] === letter))) {
return GREEN;
}
if (
guesses.some((guess) => [...guess].some((x, i) => x === letter && answer[i] !== letter && answer.includes(letter)))
) {
return YELLOW;
}
if (guesses.some((guess) => [...guess].some((x, i) => x === letter && !answer.includes(letter)))) {
return GRAY;
}
return LIGHT_GRAY;
}
async function handler(req: Request): Promise<Response> {
const url = new URL(req.url);
if (url.pathname === "/") {
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
v130 was merged from the PR "og:image generated!" by stevekrouse
stevekrouse-staticwordle.web.val.run
v130
May 18, 2024