diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6f3a291 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/index.html b/index.html index feb3555..9aaa356 100644 --- a/index.html +++ b/index.html @@ -1,14 +1,61 @@ - - - - Document - - - - + + + + Document + + + - - - \ No newline at end of file + +
+

HANGMAN GAME

+
+
+

H A N G M A N

+
+
+

H A N G M A N

+
+ +
+
+ +

HANGMAN

+

VANILLA JAVASCRIPT HANGMAN GAME

+

+ Use the alphabet to guess the word, or click hint to unlock alphabets. +

+ +
+
+ +
+

+

+
+ +
+ + Your Browser does NOT support HTML5 Canvas tag +
+
+
+ + +
+
+
+
+
+

HANGMAN GAME

+
+ + + diff --git a/scripts/script.js b/scripts/script.js index e69de29..78ac0a2 100644 --- a/scripts/script.js +++ b/scripts/script.js @@ -0,0 +1,219 @@ +const buttons = document.getElementById("buttons"); +const hold = document.getElementById("hold"); +const alphabets = "abcdefghijklmnopqrstuvwxyz".split(""); +const myLive = document.getElementById("mylives"); +const playAgain = document.getElementById("reset"); +const stickman = document.getElementById("stickman"); +const context = stickman.getContext("2d"); +const hint = document.getElementById("hint"); +const remainedHint = document.getElementById("hints"); + +let lives = 10; +let gameFinished = false; +let hintsAvailable = 3; +let guess = []; + +context.strokeStyle = "#fff"; +context.lineWidth = 2; + +const draw = (fromX, fromY, toX, toY) => { + context.beginPath(); + context.moveTo(fromX, fromY); + context.lineTo(toX, toY); + context.stroke(); +}; + +const head = () => { + context.beginPath(); + context.arc(85, 40, 10, 0, Math.PI * 2, true); + context.stroke(); +}; + +const floor = () => draw(10, 150, 300, 150); +const post1 = () => draw(10, 0, 10, 150); +const post2 = () => draw(0, 0, 100, 0); +const rope = () => draw(85, 0, 85, 30); +const body = () => draw(85, 50, 85, 100); +const leftArm = () => draw(85, 65, 65, 75); +const rightArm = () => draw(85, 65, 105, 75); +const leftLeg = () => draw(85, 100, 65, 125); +const rightLeg = () => draw(85, 100, 105, 125); + +const drawing = [ + floor, + post1, + post2, + rope, + head, + body, + leftArm, + rightArm, + leftLeg, + rightLeg, +]; + +const hintsRemained = (hintsAvailable) => { + remainedHint.innerText = + hintsAvailable > 0 + ? `${hintsAvailable} hints remained` + : `No hints remaining`; +}; + +const showHint = (word) => { + if (hintsAvailable > 0 && !gameFinished) { + let hintShown = false; + + while (!hintShown) { + let randomPosition = Math.abs( + word.length - 1 - Math.floor(Math.random() * (word.length + 1)) + ); + word.forEach((letter) => { + if (letter?.hidden && letter?.value === word[randomPosition]?.value) { + letter.hidden = false; + hintShown = true; + hintsAvailable--; + hintsRemained(hintsAvailable); + const letters = document.getElementsByClassName("alphabet"); + for (let i = 0; i < letters.length; i++) { + if (letters[i].innerText.toLowerCase() === letter.value) + letters[i].setAttribute("disabled", true); + } + } + }); + } + } else { + hint.setAttribute("disabled", true); + } + + gameState(lives, word); + showLetters(word); +}; + +const gameState = (lives, word) => { + const lost = () => { + myLive.innerText = `You Lost`; + gameFinished = true; + }; + + const win = () => { + myLive.innerText = `You Win!`; + gameFinished = true; + }; + + myLive.innerText = `Your live is ${lives}`; + if (lives <= 0) lost(); + + let won = true; + + word?.forEach((letter) => { + if (letter.hidden) won = false; + }); + + if (word && won) win(); +}; + +gameState(lives); + +buttons.innerHTML = "Loading..."; + +const lettersFound = []; + +const showLetters = (word) => { + guess = word; + hold.innerHTML = ""; + + word.forEach((letter) => { + const hiddenLetter = document.createElement("span"); + hiddenLetter.classList.add("hiddenLetter"); + if (letter.hidden) { + hiddenLetter.innerText = "_"; + } else hiddenLetter.innerText = letter.value; + hold.append(hiddenLetter); + }); +}; + +const alphabetHandler = (alphabet, word, alphabetButton, randomWord) => { + if (!gameFinished) { + alphabetButton.setAttribute("disabled", true); + + word.forEach((letter) => { + if (letter.value === alphabet) letter.hidden = false; + }); + + if (!randomWord.split("").includes(alphabet)) { + lives--; + + drawing[drawing.length - 1 - lives](); + } + + gameState(lives, word); + showLetters(word); + } +}; + +const createWord = (randomWord) => { + const word = []; + + randomWord.split("").forEach((char, i) => { + word.push({ value: char, position: i, hidden: true }); + }); + + return word; +}; + +const renderAlphabets = (word, randomWord) => { + buttons.innerHTML = ""; + alphabets.forEach((char, i) => { + const alphabet = document.createElement("button"); + alphabet.innerText = char; + alphabet.setAttribute("id", `alphabet${i}`); + alphabet.classList.add("alphabet"); + + alphabet.onclick = () => alphabetHandler(char, word, alphabet, randomWord); + hint.onclick = () => showHint(word); + + buttons.append(alphabet); + }); + showLetters(word); +}; + +const reset = () => { + lives = 10; + gameState(lives); + gameFinished = false; + context.clearRect(0, 0, 400, 400); + hint.removeAttribute("disabled"); +}; + +const play = () => { + fetch("https://random-word-api.herokuapp.com/word?number=1") + .then((w) => w.json()) + .then((randomWord) => { + buttons.innerHTML = ""; + renderAlphabets(createWord(randomWord[0]), randomWord[0]); + hintsAvailable = Math.floor(randomWord[0].length / 3); + reset(); + hintsRemained(hintsAvailable); + }) + + .catch((e) => e); +}; + +play(); + +playAgain.onclick = () => play(); + +const firstPage = document.getElementById("first-container"); +const secondPage = document.getElementById("second-container"); +const startBtn = document.getElementById("start-btn"); +const hangmanLeft = document.getElementById("hangman-left"); +const hangmanRight = document.getElementById("hangman-right"); +const hangmanBottom = document.getElementById("hangman-bottom"); + +startBtn.addEventListener("click", () => { + firstPage.style.display = "none"; + secondPage.style.display = "block"; + hangmanLeft.style.display = "none"; + hangmanRight.style.display = "none"; + hangmanBottom.style.display = "none"; +}); diff --git a/styles/style.css b/styles/style.css index e69de29..ac2b024 100644 --- a/styles/style.css +++ b/styles/style.css @@ -0,0 +1,178 @@ +body { + background-color: black; + color: #fff; + font-size: 25px; + display: flex; + flex-direction: column; + justify-content: center; + text-align: center; + align-items: center; + margin: 0; +} +main { + justify-content: center; + align-items: center; + display: flex; + background-color: black; + height: 655px; + width: 100%; +} +.hangman { + margin: 0; + font-size: 30px; + color: black; + letter-spacing: 10px; + text-shadow: 1px 1px 3px black; +} +#hangman-top { + width: 100%; + background-color: red; +} +#hangman-bottom { + width: 100%; + background-color: red; +} +#hangman-left { + display: flex; + flex-direction: column; + width: 35px; + padding: 4px; + height: 100%; + position: absolute; + left: 0; + justify-content: center; + background-color: red; + text-align: center; +} +#hangman-right { + display: flex; + flex-direction: column; + width: 35px; + padding: 4px; + height: 100%; + position: absolute; + right: 0; + justify-content: center; + background-color: red; + text-align: center; +} +#first-container { + text-align: center; + letter-spacing: 4px; + text-shadow: 2px 2px 10px red; +} +#start-btn { + background-color: red; + color: #fff; + border: 2px solid #fff; + cursor: pointer; + font-size: 20px; + padding: 13px 8px; + width: 180px; + margin-top: 15px; + border-radius: 15px; + text-align: center; +} +#start-btn:hover { + background: #fff; + color: red; + border: 2px solid white; +} +#second-container { + display: none; + font-family: "Roboto Mono", monospace; +} + +.wrappper { + display: flex; + flex-direction: column; + justify-content: center; + text-align: center; + align-items: center; +} + +#main-container { + display: flex; + flex-direction: row-reverse; + justify-content: space-around; + margin: 40px; +} + +canvas { + color: #fff; + border: #fff dotted 3px; + padding: 15px; + margin-right: 250px; + width: 400px; + height: 250px; + margin-top: 18px; +} + +#hold { + font-size: 10px; +} +#buttons { + display: flex; + flex-wrap: wrap; + width: 500px; + margin-left: 250px; + text-transform: uppercase; +} +.alphabet { + background-color: black; + color: #fff; + margin: 5px; + cursor: pointer; + text-align: center; + border: 3px solid gray; + border-radius: 15px; + text-transform: uppercase; + font-size: 20px; + width: 60px; + height: 60px; + padding: 2px; + text-align: center; +} +.alphabet:hover { + cursor: pointer; + color: white; + border: 3px solid white; + background-color: #222; +} +.alphabet:disabled { + opacity: 0.5; +} +.alphabet:disabled:hover { + cursor: default; +} + +#hint, +#reset { + background-color: red; + color: #fff; + border: 1px solid #fff; + cursor: pointer; + font-size: 23px; + padding: 13px 8px; + width: 180px; + margin: 35px 15px 0px; + border-radius: 15px; + box-shadow: 2px 2px 7px white; + text-decoration: none; + text-align: center; +} + +#hint:hover, +#reset:hover { + background: #fff; + color: red; + box-shadow: none; +} + +.hiddenLetter { + font-size: 60px; +} + +.alphabet:hover { + cursor: pointer; +}