Skip to content

Instantly share code, notes, and snippets.

@amster
Created January 8, 2022 00:09
Show Gist options
  • Save amster/f3a029941d6a67ce6e1f601deaa25a24 to your computer and use it in GitHub Desktop.
Save amster/f3a029941d6a67ce6e1f601deaa25a24 to your computer and use it in GitHub Desktop.
Given a Wordle answer and your guesses, it will format an emoji grid and English alt text.
// Wordle Emoji Formatter
//
// Given the correct word and your guesses, generates an emoji representation and ALT text.
let PUZZLE_NUMBER: number = 202;
let WORD: string = 'slump';
let GUESSES: string[] = ['clear', 'hoist', 'dumpy', 'slump'];
// ---
let _CARDINAL: string[] = ['-', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth'];
let _MAX_GUESSES: number = 6;
let _NEWLINE: string = "\n";
let _RESULT_EMOJI: {[key: string]: string} = {
'correct': '🟩',
'in_word': '🟨',
'miss': '⬜️'
};
interface KeyValue {
[key: string]: boolean
}
interface LetterTuple {
guessLetter: string;
answerLetter?: string;
isGuessLetterInWord: boolean;
isGuessLetterCorrect: boolean;
}
function checkForCorrectWord(resultMap: LetterTuple[][]): boolean {
let hasCorrectWord: boolean = false;
resultMap.forEach( wordTuple => {
if (checkTupleIsAllCorrect(wordTuple)) {
hasCorrectWord = true;
}
});
return hasCorrectWord;
}
function checkTupleIsAllCorrect(wordTuple: LetterTuple[]): boolean {
let allCorrect: boolean = true;
wordTuple.forEach( letterTuple => {
if (!letterTuple.isGuessLetterCorrect) {
allCorrect = false;
}
});
return allCorrect;
}
function flat(a: any): any[] {
if (!Array.isArray(a)) { return [a]; }
return a.reduce( (acc: any[], curr: any) => {
if (!Array.isArray(curr)) {
acc.push(curr);
return acc;
}
return acc.concat( flat(curr) );
}, [] );
}
function generateAltText(resultMap: LetterTuple[][]): string {
let isCorrectWordInResult: boolean = checkForCorrectWord(resultMap);
let numberGuessesDescription = generateNumberGuessesDescription();
if (!isCorrectWordInResult) {
return `Wordle grid with no correct guess after ${numberGuessesDescription}.`;
}
return `Wordle guessed correct in ${numberGuessesDescription}: ${resultMap.map((wordTuple, idx) => generateAltTextForWordTuple(wordTuple, idx)).join(', ')}.`;
}
function generateAltTextForWordTuple(wordTuple: LetterTuple[], index: number): string {
let guessDescription: string;
if (checkTupleIsAllCorrect(wordTuple)) {
guessDescription = 'is correct'
} else {
let numberInWord: number = 0;
let numberCorrect: number = 0;
wordTuple.forEach(letterTuple => {
if (letterTuple.isGuessLetterCorrect) {
numberCorrect++;
} else if (letterTuple.isGuessLetterInWord) {
numberInWord++;
}
});
if (numberInWord > 0) {
if (numberCorrect > 0) {
guessDescription = `${numberCorrect} correct ${numberInWord} in wrong place`;
} else {
guessDescription = `${numberInWord} in wrong place`;
}
} else {
if (numberCorrect > 0) {
guessDescription = `${numberCorrect} correct`;
} else {
guessDescription = `no letters match`;
}
}
}
return `${_CARDINAL[index + 1]} guess ${guessDescription}`;
}
function generateHeader(): string {
let numberGuesses: number = GUESSES.length;
return `Wordle ${PUZZLE_NUMBER} ${numberGuesses}/${_MAX_GUESSES}`;
}
function generateNumberGuessesDescription(): string {
let numberGuesses: number = GUESSES.length;
return numberGuesses == 1
? '1 guess'
: `${numberGuesses} guesses`;
}
function generateResultGrid(resultMap: LetterTuple[][]): string {
return resultMap.map(guessTupleSet => {
return guessTupleSet.map(letterTuple => mapGuess(letterTuple)).join('')
}).join(_NEWLINE);
}
function generateResultMap(comparisonMap: KeyValue): LetterTuple[][] {
return GUESSES.map(guess => getLetterTuples(guess, WORD, comparisonMap))
}
function getCharactersFromString(s: string): string[] {
let acc: string[] = [];
for (let i: number = 0; i<s.length; i++) {
acc.push(s.charAt(i).toUpperCase());
}
return acc;
}
function getComparisonMap(word: string) {
let map: KeyValue = {};
getCharactersFromString(word).forEach(
character => map[character] = true
);
return map;
}
function getLetterTuples(guessWord: string, answerWord: string, comparisonMap: KeyValue): LetterTuple[] {
let letterTuples: LetterTuple[] = [];
getCharactersFromString(guessWord).forEach(char => {
letterTuples.push({
guessLetter:char,
isGuessLetterInWord: comparisonMap[char] !== undefined,
isGuessLetterCorrect: false
});
})
getCharactersFromString(answerWord).forEach((char, idx) => {
if (idx >= letterTuples.length) { return; }
letterTuples[idx].answerLetter = char;
if (letterTuples[idx].guessLetter === char) {
letterTuples[idx].isGuessLetterCorrect = true;
}
})
return letterTuples;
}
function go() {
let comparisonMap: KeyValue = getComparisonMap(WORD);
let resultMap: LetterTuple[][] = generateResultMap(comparisonMap);
let results: any[] = [
generateHeader(),
generateResultGrid(resultMap),
'',
generateAltText(resultMap)
];
console.log(flat(results).join(_NEWLINE));
}
function mapGuess(letterTuple: LetterTuple): string {
if (letterTuple.isGuessLetterCorrect) { return _RESULT_EMOJI['correct']; }
if (letterTuple.isGuessLetterInWord) { return _RESULT_EMOJI['in_word']; }
return _RESULT_EMOJI['miss'];
}
// ---
go();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment