@hp4k1h5/terminordle
Version:
> multiplayer [wordle](https://www.powerlanguage.co.uk/wordle/) clone in your terminal
107 lines (106 loc) • 3.77 kB
JavaScript
;
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;