UNPKG

@hp4k1h5/terminordle

Version:

> multiplayer [wordle](https://www.powerlanguage.co.uk/wordle/) clone in your terminal

107 lines (106 loc) 3.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isCorrect = exports.updateAlphabet = exports.evaluateGuess = exports.validateResponse = exports.wordToRow = void 0; //@ts-strict const structs_1 = require("./lib/structs"); const util_1 = require("./util"); function wordToRow(word) { return word.split('').map(letter => ({ letter, visibility: structs_1.Visibility.hidden, })); } exports.wordToRow = wordToRow; function validateResponse(response) { if (!response.content || typeof response.content !== 'string') { throw 'bad guess'; } else if (/[^a-z]/i.test(response.content)) { throw 'only a-zA-Z'; } else if (response.content.length !== 5) { throw '5 letters only'; } else if (!util_1.words[response.content.toLocaleLowerCase()]) { throw 'not in wordlist'; } } exports.validateResponse = validateResponse; // update guess and alphabet Rows in place // each guess is a new object // alphabet (letters) is a global function evaluateGuess(guess, answer) { // update guess Row status guess.forEach((option, i) => { const oL = option.letter.toLocaleLowerCase(); const aL = answer[i].letter.toLocaleLowerCase(); if (oL === aL) { option.visibility = structs_1.Visibility.revealed; } else if (letterExists(guess, i, answer)) { option.visibility = structs_1.Visibility.exists; } else { option.visibility = structs_1.Visibility.guessed; } // update alphabet Row status if (util_1.letters[oL] !== structs_1.Visibility.revealed) util_1.letters[oL] = option.visibility; }); } exports.evaluateGuess = evaluateGuess; // update alphabet when the evaluated guess comes from server function updateAlphabet(guess) { guess.forEach((option) => { const oL = option.letter.toLocaleLowerCase(); if (util_1.letters[oL] !== structs_1.Visibility.revealed) { util_1.letters[oL] = option.visibility; } }); } exports.updateAlphabet = updateAlphabet; // determine whether to mark a letter exists (yellow) // i.e. whether the letter // - exists somewhere in the answer // - does not exist in that postion // - is not already accounted for by previous guess instances of the letter function letterExists(guess, i, answer) { const option = guess[i]; if (!answer.find(l => l.letter === option.letter)) { return false; } // get intersection of letter instances in guess and answer function sameLetterIndices(row) { return row.slice().reduce((a, v, j) => { if (v.letter === option.letter) { a.push(j); } return a; }, []); } const sameAnswerLetterIndices = sameLetterIndices(answer); const sameGuessLetterIndices = sameLetterIndices(guess); const intersection = sameAnswerLetterIndices.filter(i => !sameGuessLetterIndices.includes(i)); // get difference between needed instances of the letter and provided // instances sameGuessLetterIndices.forEach(i => { if (guess[i].visibility === structs_1.Visibility.exists) { intersection.shift(); } }); // there are unaccounted for instances if (intersection.length) { return true; } // this are too many instances return false; } // this does not check against the answer because in a client-server model the // client never receives the answer, only the evaluated guess function isCorrect(guess) { if (guess.some(letter => letter.visibility !== structs_1.Visibility.revealed)) { return false; } return true; } exports.isCorrect = isCorrect;