export const GUESS_RESULT = { MISS: 'm', WIN: 'w', FOUL: 'f' }; export const MARKERS = { MISS: 'm', RIGHT_POS: 'g', RIGHT_CHAR: 'y' }; export class GameController { constructor(wordSource) { this._wordSource = wordSource; } async start() { this._currentWord = await this._wordSource.getCurrentWord(); this._guesses = 5; console.log("The current word: " + this._currentWord); } wordLength() { this._checkHasStarted(); return this._currentWord.length; } guesses() { this._checkHasStarted(); return this._guesses; } currentWord() { this._checkHasStarted(); return this._currentWord; } async nextWord() { this._currentWord = await this._wordSource.getCurrentWord(); this._guesses = 5; return true; } checkGuess(guess) { this._checkHasStarted(); guess = guess.toLowerCase(); if (guess.length != this._currentWord.length) { throw Error(`Expected length to be ${this._currentWord.length} but was ${guess.length}`); } // Check correct placements let guessResult; let markers = new Array(guess.length); let misses = {}; let hits = {}; if (!this._wordSource.isWord(guess)) { return { guessResult: GUESS_RESULT.FOUL, }; } for (let i = 0; i < guess.length; i++) { if (guess[i] == this._currentWord[i]) { markers[i] = MARKERS.RIGHT_POS; hits[guess[i]] = MARKERS.RIGHT_POS; } else { if (this._currentWord[i] in misses) { misses[this._currentWord[i]] += 1; } else { misses[this._currentWord[i]] = 1; } } } // Check words that are wrong placement but are in the word // Distribute based on the words position for (let i = 0; i < guess.length; i++) { if (markers[i]) { continue; } if (misses[guess[i]] && misses[guess[i]] > 0) { misses[guess[i]] -= 1; markers[i] = MARKERS.RIGHT_CHAR; if (!hits[guess[i]]) { hits[guess[i]] = MARKERS.RIGHT_CHAR; } } else { if (!hits[guess[i]]) { hits[guess[i]] = MARKERS.MISS; } markers[i] = MARKERS.MISS; } } let isRight = markers.filter((x) => x == MARKERS.RIGHT_POS).length == this._currentWord.length; if (isRight) { guessResult = GUESS_RESULT.WIN; } else { guessResult = GUESS_RESULT.MISS; } return { guessResult: guessResult, hits: hits, markers: markers }; } _checkHasStarted() { if (!this._currentWord) { throw new Error("call start() first"); } } }