Gather input about an in-progress Wordle game and present a live-updating list of valid candidates.
This example isn't too useful as a form, but shows the power of programmability in this context. With a relatively modest line count, the code is only focused on the core solving loop, pretty much the way you'd write it if you were building a command-line solver: download a word list, and filter it down incrementally based on user input until a single word remains.
Formulate wraps an interactive web UI over this core loop, and gives you undo for free.
let alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
let getDescription = (words) => {
if (words.length > 5) {
return `${words.slice(0, 5).join(", ")}, and ${words.length - 5} more`;
} else {
return words.join(", ");
}
};
export default async function () {
let url = "https://prod.static.formulate.dev/gallery/wordle.txt";
let response = await form.fetch(url);
let words = response.text.split("\n");
await form.statement("Hello, welcome to the Wordle solver!", {
description: `
- Enter a starting word on [the Wordle website](https://www.nytimes.com/games/wordle), and then hit Next.
- **Candidates**: ${getDescription(words)}
`,
});
while (true) {
let { value: type } = await form.multi(
"Do you want to tell me about a green, yellow, or gray letter?",
["Green", "Yellow", "Gray"],
{ single: true }
);
let { value: letter } = await form.multi("Ok, and what letter?", alphabet, {
hideNumbers: true,
single: true,
});
letter = letter.toLowerCase();
if (type === "Green") {
let { value: position } = await form.multi(
"Great, and what position?",
[1, 2, 3, 4, 5],
{ hideNumbers: true, single: true }
);
words = words.filter((word) => word[position - 1] === letter);
}
if (type === "Yellow") {
let { value: position } = await form.multi(
"Great, and what position?",
[1, 2, 3, 4, 5],
{ hideNumbers: true, single: true }
);
words = words.filter(
(word) => word[position - 1] !== letter && word.includes(letter)
);
}
if (type === "Gray") {
words = words.filter((word) => !word.includes(letter));
}
await form.statement("Ok, I think I've got that!", {
description: `**Candidates remaining**: ${getDescription(words)}`,
});
if (words.length === 1) {
break;
}
}
}