import { Controller } from "https://unpkg.com/@hotwired/stimulus@v3.2.2/dist/stimulus.js" import { GUESS_RESULT, MARKERS, GameController } from "../models/gamecontroller.js"; import { WordSource } from "../models/words.js"; export default class extends Controller { static targets = ["row", "playfield", "topMessage", "nextPuzzleButtons"]; static outlets = ["overlay"]; async connect() { this._wordSource = new WordSource(); this._gameController = new GameController(this._wordSource); await this._gameController.start(); this._buildPlayfield(); } tappedKey(key) { console.log(`Key ${key} was tapped via outliet`); this._addLetter(key); } _addLetter(letter) { if (this._activeRowIndex < 0) { return; } else if (this._activeLetter >= this._gameController.wordLength()) { return; } let rowElem = this.rowTargets[this._activeRowIndex]; let colElem = rowElem.querySelectorAll("span")[this._activeLetter]; colElem.innerText = letter.toUpperCase(); this._activeLetter += 1; } enterGuess() { if (this._activeLetter >= this._gameController.wordLength()) { let rowElem = this.rowTargets[this._activeRowIndex]; this._verifyGuess(rowElem); } } loadDef(ev) { ev.preventDefault() let word = this._gameController.currentWord(); window.open(`https://www.ecosia.org/search?q=define+${word}`, "_blank"); } tappedBackspace() { if (this._activeLetter == 0) { return; } this._activeLetter -= 1; let rowElem = this.rowTargets[this._activeRowIndex]; let colElem = rowElem.querySelectorAll("span")[this._activeLetter]; colElem.innerText = ""; } _verifyGuess(rowElem) { let guessedWord = Array.from(rowElem.querySelectorAll("span")).map((x) => x.innerText).join(""); console.log("The guessed word is: " + guessedWord); let results = this._gameController.checkGuess(guessedWord); switch (results.guessResult) { case GUESS_RESULT.FOUL: this.overlayOutlet.showMessage("Not a valid word"); rowElem.replaceWith(this._buildPlayfieldRow(this._gameController.wordLength())); this._activeLetter = 0; window.dispatchEvent(new CustomEvent("guessResults", { detail: results })); break; case GUESS_RESULT.MISS: this._colorizeRow(rowElem, results); this._activeRowIndex += 1; if (this._activeRowIndex >= this._gameController.guesses()) { this.topMessageTarget.innerText = this._gameController.currentWord().toUpperCase(); this.nextPuzzleButtonsTarget.classList.remove("hide"); } else { this._activeLetter = 0; } break; case GUESS_RESULT.WIN: this._colorizeRow(rowElem, results); this.topMessageTarget.innerText = "Hooray! You did it."; this.nextPuzzleButtonsTarget.classList.remove("hide"); break; } } async loadNextPuzzle(ev) { ev.preventDefault(); if (await this._gameController.nextWord()) { this._buildPlayfield(); } else { this.overlayOutlet.showMessage("No more words available."); } } _buildPlayfield() { let rows = this._gameController.guesses(); let wordLength = this._gameController.wordLength(); this._activeRowIndex = 0; this._activeLetter = 0; let newRows = []; for (let r = 0; r < rows; r++) { newRows.push(this._buildPlayfieldRow(wordLength)); } this.playfieldTarget.replaceChildren.apply(this.playfieldTarget, newRows); this.topMessageTarget.innerHTML = " " this.nextPuzzleButtonsTarget.classList.add("hide"); window.dispatchEvent(new CustomEvent("resetKeyColors")); } _buildPlayfieldRow(wordLength) { let divElem = document.createElement("div"); divElem.classList.add("row"); divElem.setAttribute("data-playfield-target", "row"); for (let c = 0; c < wordLength; c++) { let letterSpan = document.createElement("span"); divElem.appendChild(letterSpan); } return divElem; } _colorizeRow(row, results) { let markers = results.markers; for (let i = 0; i < this._gameController.wordLength(); i++) { switch (markers[i]) { case MARKERS.RIGHT_POS: row.children[i].classList.add("right-pos"); break; case MARKERS.RIGHT_CHAR: row.children[i].classList.add("right-char"); break; case MARKERS.MISS: row.children[i].classList.add("miss"); break; } } window.dispatchEvent(new CustomEvent("guessResults", { detail: results })); } }