export const GUESS_RESULT = { MISS: 'm', WIN: 'w', FOUL: 'f' }; export const MARKERS = { MISS: 'm', RIGHT_POS: 'g', RIGHT_CHAR: 'y' }; class ProgressionState { getProgression() { let prog = localStorage.getItem('progression'); if (prog) { return JSON.parse(prog); } prog = {wordLength: 4, wordIndex: {"4": 0, "5": 0, "6": 0}}; localStorage.setItem('progression', JSON.stringify(prog)); return prog; } saveProgression(prog) { localStorage.setItem('progression', JSON.stringify(prog)); } } export class GameController { constructor(wordSource) { this._wordSource = wordSource; this._progressionState = new ProgressionState(); } async start() { let prog = this._progressionState.getProgression(); this._currentWord = await this._wordSource.getCurrentWord(prog); this._guesses = Math.max(this._currentWord.length, 5) + 1; 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() { // Increment the progress let prog = this._progressionState.getProgression(); prog.wordIndex[prog.wordLength + ""] += 1; prog.wordLength = (((Math.random() * 23) | 0) / 10 | 0) + 4; this._progressionState.saveProgression(prog); this._currentWord = await this._wordSource.getCurrentWord(prog); this._guesses = Math.max(this._currentWord.length, 5) + 1; 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._currentWord.length <= 5) { 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"); } } }