diff --git a/index.html b/index.html new file mode 100644 index 0000000..7904aa4 --- /dev/null +++ b/index.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + TD - Hangman Game + + + +
+

The Hangman Game

+
+
+
+
+ +
+
+
+ + + + + + \ No newline at end of file diff --git a/keyboard.js b/keyboard.js new file mode 100644 index 0000000..db74faa --- /dev/null +++ b/keyboard.js @@ -0,0 +1,132 @@ +const keyBoardButtons = [ + { + letter: "A", + id: 1, + disabled: false, + }, + { + letter: "B", + id: 2, + disabled: false, + }, + { + letter: "C", + id: 3, + disabled: false, + }, + { + letter: "D", + id: 4, + disabled: false, + }, + { + letter: "E", + id: 5, + disabled: false, + }, + { + letter: "F", + id: 6, + disabled: false, + }, + { + letter: "G", + id: 7, + disabled: false, + }, + { + letter: "H", + id: 8, + disabled: false, + }, + { + letter: "I", + id: 9, + disabled: false, + }, + { + letter: "J", + id: 10, + disabled: false, + }, + { + letter: "K", + id: 11, + disabled: false, + }, + { + letter: "L", + id: 12, + disabled: false, + }, + { + letter: "M", + id: 13, + disabled: false, + }, + { + letter: "N", + id: 14, + disabled: false, + }, + { + letter: "O", + id: 15, + disabled: false, + }, + { + letter: "P", + id: 16, + disabled: false, + }, + { + letter: "Q", + id: 17, + disabled: false, + }, + { + letter: "R", + id: 18, + disabled: false, + }, + { + letter: "S", + id: 19, + disabled: false, + }, + { + letter: "T", + id: 20, + disabled: false, + }, + { + letter: "U", + id: 21, + disabled: false, + }, + { + letter: "V", + id: 22, + disabled: false, + }, + { + letter: "W", + id: 23, + disabled: false, + }, + { + letter: "X", + id: 24, + disabled: false, + }, + { + letter: "Y", + id: 25, + disabled: false, + }, + { + letter: "Z", + id: 26, + disabled: false, + }, +]; diff --git a/solution.js b/solution.js new file mode 100644 index 0000000..6db1173 --- /dev/null +++ b/solution.js @@ -0,0 +1,194 @@ +//tastiera a video realizzata sul layout +//per le parole da indovinare proviamo ad usare una api swapi +//quando ho finito la partita avro un button che resetta + +const keyBoardSection = document.getElementById("keyboard"); +const hangWordContainer = document.querySelector(".hang-word"); +const hangBoard = document.querySelector("#hang-board"); +const paragraphsLowDash = document.querySelectorAll("p"); + +/** + * It creates a button for each letter in the keyBoard array, and then calls the keyPressed function. + * @param keyBoard - an array of objects that contain the letter and the status of the letter. + */ +async function createKeyBoard(keyBoard) { + const secretWords = await getSecretWords(); + keyBoard.forEach((key) => { + const newButton = document.createElement("button"); + newButton.classList.add("btn"); + const buttonLetter = document.createTextNode(key.letter); + newButton.appendChild(buttonLetter); + keyBoardSection.appendChild(newButton); + }); + + keyPressed(secretWords); +} + +/** + * The function takes a random word from the array and checks if the letter pressed is in the word. If + * it is, it will reveal the letter in the word. If it's not, it will add 1 to the attempts. If the + * attempts reach 3, the game is over. + * @param randomSecretWord - the word that the user has to guess + */ +function keyPressed(randomSecretWord) { + const buttons = document.querySelectorAll(".btn"); + let letterPressed = ""; + const lettersGuessed = []; + const maxAttempts = 3; + let attempts = 0; + document.addEventListener("keyup", (event) => { + const keyPressed = String.fromCharCode(event.keyCode); + const isGuessed = checkIfGuessed(randomSecretWord, keyPressed); + if (isGuessed) { + paragraphsLowDash.forEach((paragraph, i) => { + if ( + keyPressed === randomSecretWord[i] && + paragraph.innerHTML !== keyPressed + ) { + paragraph.innerHTML = randomSecretWord[i]; + lettersGuessed.push(paragraph.innerHTML); + if (lettersGuessed.length === randomSecretWord.length) { + showAlert("won"); + } + } + }); + } else { + attempts = attempts + 1; + if (attempts === maxAttempts) { + showAlert("lost"); + } + } + }); + buttons.forEach((button) => { + button.addEventListener("click", () => { + button.classList.add("clicked-btn"); + button.attributes.disabled = true; + /* It's a variable that is being used to store the letter that the user pressed. */ + letterPressed = button.textContent; + + const isGuessed = checkIfGuessed(randomSecretWord, letterPressed); + if (isGuessed) { + const paragraphsLowDash = document.querySelectorAll("p"); + paragraphsLowDash.forEach((paragraph, i) => { + if ( + /* It's checking if the letter pressed is in the secret word and if it's not already + displayed. */ + letterPressed === randomSecretWord[i] && + paragraph.innerHTML !== letterPressed + ) { + paragraph.innerHTML = randomSecretWord[i]; + lettersGuessed.push(paragraph.innerHTML); + if (lettersGuessed.length === randomSecretWord.length) { + showAlert("won"); + } + } + }); + } else { + attempts = attempts + 1; + if (attempts === maxAttempts) { + showAlert("lost"); + } + } + }); + }); + return letterPressed; +} + +/** + * It fetches the data from the API, then maps over the results and pushes the planet names to an + * array, then returns a randomly chosen word from that array. + * @returns a promise. + */ +async function getSecretWords() { + const secretWords = []; + await fetch("https://swapi.dev/api/planets") + .then((response) => response.json()) + .then((data) => { + data.results.map((planet) => { + secretWords.push(planet.name.toUpperCase()); + }); + }); + console.log("secret words array: ", secretWords); + const randomSecretWord = await randomlyChosenWord(secretWords); + return randomSecretWord; +} + +/** + * It takes an array of words, chooses one at random, and then returns that word. + * @param secrets - an array of words + * @returns The word that is being returned is the word that is being randomly chosen from the array of + * words. + */ +async function randomlyChosenWord(secrets) { + const randomNumberIndex = Math.floor(Math.random() * secrets.length); + console.log("random secret word: ", secrets[randomNumberIndex]); + + createHangBoard(secrets[randomNumberIndex]); + return await secrets[randomNumberIndex]; +} + +/** + * It takes a random word from the array, splits it into letters, and then creates a paragraph element + * for each letter and appends it to the hangWordContainer div. + * @param randomSecretWord - "apple" + */ +function createHangBoard(randomSecretWord) { + const splittedWord = randomSecretWord.split(""); + splittedWord.forEach((letter) => { + const newVoidLowDash = document.createElement("p"); + newVoidLowDash.classList.add("low-dash"); + const pLowDash = document.createTextNode("_"); + newVoidLowDash.appendChild(pLowDash); + hangWordContainer.appendChild(newVoidLowDash); + }); +} + +/** + * If the secret word includes the letter pressed, return true, otherwise return false. + * @param secretWord - the word that the user is trying to guess + * @param letterPressed - the letter that the user pressed + * @returns a boolean value. + */ +function checkIfGuessed(secretWord, letterPressed) { + if (secretWord.includes(letterPressed)) { + return true; + } else { + return false; + } +} + +/** + * Reset the game by removing the hangboard, getting new secret words, and creating a new keyboard. + */ +const reset = function resetProgram() { + hangBoard.innerHTML = ""; + hangBoard.appendChild(hangWordContainer); + hangBoard.removeChild(hangWordContainer); + hangWordContainer.innerHTML = ""; + hangBoard.appendChild(hangWordContainer); + keyBoardSection.innerHTML = ""; + + createKeyBoard(keyBoardButtons); +}; + +/** + * The showAlert function takes a message as an argument and displays it in a div with a button that + * resets the game. + * @param message - the message to display in the alert + */ +function showAlert(message) { + const alertMessage = ` +
+
+ You ${message}, +
+
+ `; + + hangBoard.innerHTML = hangBoard.innerHTML + alertMessage; + + const resetBtn = document.getElementById("reset-btn"); + resetBtn.addEventListener("click", reset); +} + +createKeyBoard(keyBoardButtons); diff --git a/style.css b/style.css new file mode 100644 index 0000000..c7649fb --- /dev/null +++ b/style.css @@ -0,0 +1,113 @@ +* { + box-sizing: border-box; + padding: 0; + margin: 0; + font-family: "Roboto", sans-serif; + background-color: rgb(30 41 139); +} + +main { + display: flex; + flex-direction: column; + align-items: center; +} + +header { + display: flex; + justify-content: center; + align-items: center; + padding: 0.5rem 0; + border-bottom: 1px solid rgb(54 63 151); +} + +.title { + color: white; + font-size: 22px; + font-weight: 500; +} + +#keyboard { + width: 48vw; +} + +.btn { + height: 3em; + width: 3em; + color: rgba(0, 0, 0, 0.7); + background-color: rgba(9, 165, 154, 0.8); + box-shadow: 0px 10px 13px -7px #000000, 5px 5px 15px 5px rgba(0, 0, 0, 0); + border-radius: 0.4em; + line-height: 3em; + letter-spacing: 1px; + margin: 0.1em; + transition: transform 0.3s; + text-align: center; + font-size: 1em; + font-weight: 600; + cursor: pointer; +} + +.btn:hover { + transform: translateY(-0.2rem); +} + +.clicked-btn { + background-color: tomato; + cursor: not-allowed; +} + +#hang-board { + padding: 4rem 2rem; +} + +.hang-word { + display: flex; + justify-content: space-around; + width: 11rem; +} + +.low-dash { + color: white; + font-size: 22px; + font-weight: 600; +} + +.game-alert { + background-color: rgba(9, 165, 154, 0.4); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; +} + +.game-alert-message { + font-size: 40px; + font-weight: 600; + padding: 20px; + background-color: var(--accent-color); + display: flex; + justify-content: center; + align-items: center; +} + +#reset-btn { + border-radius: 8px; + border: none; + color: whitesmoke; + letter-spacing: 1px; + padding: 1rem 2rem; + margin-left: 0.6rem; + font-size: 20px; + font-weight: 600; + cursor: pointer; + transition: transform 0.3s; + box-shadow: 2px 11px 17px 5px rgba(0, 0, 0, 0.48); +} + +#reset-btn:hover { + transform: translateY(-0.2rem); +}