Created
January 8, 2022 00:09
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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