wordle-shell
Version:
A Wordle for the command line
112 lines (104 loc) • 3.51 kB
text/typescript
import WordPicker from "./WordPicker";
export enum CharState {
Correct,
Misplaced,
Wrong,
Unknow
}
class Wordle {
private static words_size = 5;
private word: string;
private words: string[];
constructor(wordPicker: { getWord: () => string, getWordList: () => string[]; }) {
this.ensureWordLength(wordPicker.getWord());
this.word = wordPicker.getWord();
this.words = wordPicker.getWordList();
}
private ensureWordLength(word: string): word is string {
return word.length === Wordle.words_size;
}
public static done(states: CharState[]) {
return states.every((state) => state === CharState.Correct);
}
public static get_word_size() {
return this.words_size;
}
private checkIfMisplaced(guess: string, states: CharState[], index: number) {
if (states[index] !== CharState.Unknow) {
return false;
}
const qtd_chars_guess = guess
.slice(0, index + 1)
.split("")
.reduce<number>((sum, char) => {
return sum + (
char === guess[index]
? 1
: 0
);
}, 0);
const qtd_chars = this.word
.split("")
.reduce<number>((sum, char, internal_index) => {
return sum + (
char === guess[index] && states[internal_index] !== CharState.Correct
? 1
: 0
);
}, 0);
return qtd_chars >= qtd_chars_guess;
}
private checkAllCorrets(guess: string, states: CharState[]) {
for (let index = 0; index < Wordle.words_size; index++) {
const word_char = this.word.at(index);
const guess_char = guess.at(index) ?? "?";
if (word_char === guess_char) {
states[index] = CharState.Correct;
}
}
return states;
}
private checkAllMismatches(guess: string, states: CharState[]) {
for (let index = 0; index < Wordle.words_size; index++) {
if (this.checkIfMisplaced(guess, states, index)) {
states[index] = CharState.Misplaced;
}
}
return states;
}
private checkAllWrongs(states: CharState[]) {
for (let index = 0; index < Wordle.words_size; index++) {
if (states[index] === CharState.Unknow) {
states[index] = CharState.Wrong;
}
}
return states;
}
private createStates(): CharState[] {
let states = Array(Wordle.words_size);
for (let index = 0; index < Wordle.words_size; index++) {
states[index] = CharState.Unknow;
}
return states;
}
public checkWord(guess: string): CharState[] {
if (!this.ensureWordLength(guess)) {
throw new Error("Word is the wrong length");
}
if (!this.ensureWordPossible(guess)) {
throw new Error(`${guess} is not on the list`);
}
let states: CharState[] = this.createStates();
this.checkAllCorrets(guess, states);
this.checkAllMismatches(guess, states);
this.checkAllWrongs(states);
return states;
}
private ensureWordPossible(guess: string) {
return this.words.includes(guess);
}
public getWord() {
return this.word;
}
}
export default Wordle;