<h1>Hangman</h1>
<p>Find the hidden word - Enter a letter</p>

<div class="box">
  <svg width="200" height="250">
    <!--rod-->
    <line x1="60" y1="20" x2="140" y2="20" />
    <line x1="140" y1="20" x2="140" y2="50" />
    <line x1="60" y1="20" x2="60" y2="230" />

    <!--head-->
    <circle cx="140" cy="70" r="20" class="part" />
    <!--body-->
    <line x1="140" y1="90" x2="140" y2="150" class="part" />
    <!--arms-->
    <line x1="140" y1="120" x2="120" y2="100" class="part" />
    <line x1="140" y1="120" x2="160" y2="100" class="part" />
    <!--legs-->
    <line x1="140" y1="150" x2="120" y2="180" class="part" />
    <line x1="140" y1="150" x2="160" y2="180" class="part" />
  </svg>

  <div class="wrong-letters"></div>
  <div class="word"></div>
</div>

<div class="popup">
  <p class="message"></p>
  <p class="reveal-word"></p>
  <button>Play Again</button>
</div>

<div class="notification">
  <p>You have already entered this letter</p>
</div>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: radial-gradient(circle, skyblue, steelblue);
  font-family: helvetica;
  color: #ddd;
  overflow: hidden;
}

h1 {
  margin: 20px 0 0;
}

.box {
  margin: auto;
  padding: 20px 30px;
  position: relative;
  width: 450px;
  height: 350px;
}

svg {
  fill: transparent;
  stroke: #222;
  stroke-width: 4px;
  stroke-linecap: round;
}

.part {
  display: none;
}

.wrong-letters {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  align-items: flex-end;
}

.wrong-letters span {
  margin: 0 3px;
  font-size: 24px;
}

.word {
  display: flex;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
}

.letter {
  margin: 0 3px;
  width: 20px;
  height: 50px;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  font-size: 30px;
  border-bottom: 3px solid forestgreen;
}

.popup {
  padding: 20px;
  background: rgba(0, 0, 0, 0.3);
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  border-radius: 5px;
  box-shadow: 0 15px 10px 3px rgba(0, 0, 0, 0.1);
  font-size: 24px;
  text-align: center;
}

.popup button {
  padding: 12px 20px;
  margin-top: 20px;
  background: #ddd;
  color: #222;
  border: none;
  outline: none;
  font-size: 16px;
  cursor: pointer;
}

.popup button:active {
  transform: scale(0.98);
}

.notification {
  padding: 15px 20px;
  position: absolute;
  bottom: -50px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px 10px 0 0;
  transition: transform 0.3s ease-in-out;
}

.notification.show {
  transform: translateY(-50px);
}
const word = document.querySelector(".word");
const wrongLettersBox = document.querySelector(".wrong-letters");
const playButton = document.querySelector("button");
const popup = document.querySelector(".popup");
const notification = document.querySelector(".notification");
const message = document.querySelector(".message");
const revealWord = document.querySelector(".reveal-word");

const parts = document.querySelectorAll(".part");

const words = ["application", "programming", "interface", "wizard"];

let selectedWord = words[Math.floor(Math.random() * words.length)];

let playable = true;

const correctLetters = [];
const wrongLetters = [];

function displayWord() {
  word.innerHTML = `
        ${selectedWord
          .split("")
          .map(
            (letter) => `
                    <span class="letter">
                        ${correctLetters.includes(letter) ? letter : ""}
                    </span>
                `
          )
          .join("")}`;
  const innerWord = word.textContent.replace(/[ \n]/g, "");

  if (innerWord === selectedWord) {
    message.textContent = "You won!";
    revealWord.textContent = "";
    popup.style.display = "flex";

    playable = false;
  }
}

function updateWrongLettersBox() {
  wrongLettersBox.innerHTML = `
        ${wrongLetters.map((letter) => `<span>${letter}</span>`)}
    `;

  parts.forEach((part, index) => {
    const errors = wrongLetters.length;

    index < errors
      ? (part.style.display = "block")
      : (part.style.display = "none");
  });

  if (wrongLetters.length === parts.length) {
    message.textContent = "You lost!";
    revealWord.textContent = `Right word: ${selectedWord}`;
    popup.style.display = "flex";

    playable = false;
  }
}

function showNotification() {
  notification.classList.add("show");

  const timer = setTimeout(() => {
    notification.classList.remove("show");
    clearTimeout(timer);
  }, 2000);
}

document.addEventListener("keydown", (e) => {
  if (playable) {
    if (e.keyCode >= 65 && e.keyCode <= 90) {
      const letter = e.key.toLowerCase();

      if (selectedWord.includes(letter)) {
        if (!correctLetters.includes(letter)) {
          correctLetters.push(letter);

          displayWord();
        } else {
          showNotification();
        }
      } else {
        if (!wrongLetters.includes(letter)) {
          wrongLetters.push(letter);

          updateWrongLettersBox();
        } else {
          showNotification();
        }
      }
    }
  }
});

playButton.addEventListener("click", () => {
  playable = true;

  correctLetters.length = 0;
  wrongLetters.length = 0;

  selectedWord = words[Math.floor(Math.random() * words.length)];

  displayWord();

  updateWrongLettersBox();

  popup.style.display = "none";
});

displayWord();
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.