FRONT/JAVASCRIPT

[JS] 바닐라 자바스크립트로 행맨 게임 만들기

연듀 2021. 7. 25. 16:17

 

행맨 게임 with vanilla javascript

 

 

 

실행 화면

 

플레이 화면

 

결과 화면

 

 

 

 

 

 


 

 

기능

 

 

  • 랜덤으로 선택된 단어의 길이에 따라 빈칸 생성
  • 누른 알파벳 키보드는 색상이 바뀌고, 한번 더 클릭할시 팝업창이 뜨고 목숨에 영향을 받지 않음
  • 누른 알파벳이 맞을 경우 => 빈칸이 알파벳으로 바뀜
  • 누른 알파벳이 틀릴 경우 => 행맨 그림 선이 생기고 목숨 하나 감소
  • 결과에 따라 결과창 띄우기

 

 

 


코드

 

const alphabet = [..
];
const words = [..
];

const buttons = document.querySelector(".keyboardBtn");

const chosenWord = words[Math.floor(Math.random() * words.length)]; // 랜덤으로 선택된 단어

const word = document.querySelector(".wordBox");
const wrongLetters = document.querySelector(".wrongLetters");
const winResult = document.querySelector(".result-box-win");
const loseResult = document.querySelector(".result-box-lose");
const hangman = document.querySelectorAll(".hangman");
const alert = document.querySelector(".alert");

let guessArr = [];
let wrongLettersArr = [];
let count = 0;
let checkArr = [];
let clickLettersArr = [];

function showAlphabet(guessArr) {
  word.innerHTML = "";
  const ul = document.createElement("ul");
  for (let i = 0; i < guessArr.length; i++) {
    ul.id = "wordUl";
    const li = document.createElement("li");
    li.id = "guessBar";

    li.innerHTML = `${guessArr[i].innerHTML}`;

    word.appendChild(ul);
    ul.appendChild(li);
  }
}

function playAgain() {
  const playAgainBtn = document.querySelector(".playAgainBtn");
  playAgainBtn.addEventListener("click", () => {
    window.location.reload();
  });
}
function showAlert() {
  alert.classList.add("show-alert");
  //setTimeout : 일정 시간후 함수 한번 실행
  setTimeout(() => {
    alert.classList.remove("show-alert");
  }, 2500);
}

function checkWord() {
  const guessLetter = this.innerHTML; // this는 <li id="letter">e</li> 즉 클릭 addEventListenr가 발생한 li
  this.setAttribute("class", "active");
  // this.onclick = null;

  if (clickLettersArr.includes(guessLetter)) {
    // 이미 누른 값의 배열에 포함된다면 팝업 경고창
    console.log("alert!!");
    showAlert();
  }
  //이미 누른 값이 아닐 경우에만 push
  else {
    clickLettersArr.push(guessLetter);

    if (!chosenWord.includes(guessLetter)) {
      // 짐작한 알파벳이 틀렸다면 count를 올려준다.
      if (!wrongLettersArr.includes(guessLetter)) {
        wrongLettersArr.push(guessLetter);
        wrongLetters.innerHTML = `<i class="fas fa-ban"></i> ${wrongLettersArr} `;
      }

      count++;

      if (count === 10) {
        gameOver();
      }
    }
  }

  // 맞은 알파벳을 보여주고 모두 맞았을시 이긴 결과창 띄움
  for (let i = 0; i < chosenWord.length; i++) {
    if (chosenWord[i] == guessLetter) {
      guessArr[i].innerHTML = guessLetter;

      showAlphabet(guessArr);
      checkArr.push(guessLetter);

      if (checkArr.length == chosenWord.length) {
        winResult.classList.remove("hide");
        playAgain();
      }
    }
    //console.log(guessArr[i]);
  }
  // 틀릴경우 행맨 그림 그리기
  hangman.forEach((part, index) => {
    const wrongNums = wrongLettersArr.length;

    console.log(wrongNums, index);

    if (wrongNums > index) {
      part.style.display = "block";
    } else {
      part.style.display = "none";
    }
  });
  
}

function gameOver() {
  loseResult.classList.remove("hide");
  loseResult.innerHTML = `
  <span>YOU LOSE!</span>
  <span>정답 : ${chosenWord}</span>
  <button class="playAgainBtn">다시 시작</button>`;

  playAgain();
}

function setting() {
  // 빈칸 세팅하기
  const ul = document.createElement("ul");
  for (let i = 0; i < chosenWord.length; i++) {
    ul.id = "wordUl";
    const li = document.createElement("li");
    li.id = "guessBar";
    li.innerHTML = `_`;

    word.appendChild(ul);
    ul.appendChild(li);
    guessArr.push(li);
  }

  // 키보드 버튼 만들고 누른 값이 맞는지 체크하는 함수 실행
  const letters = document.createElement("ul");

  for (let i = 0; i < alphabet.length; i++) {
    letters.id = "letters";
    const li = document.createElement("li");
    li.id = "letter";
    li.innerHTML = alphabet[i];

    li.addEventListener("click", checkWord);

    letters.appendChild(li);
    buttons.appendChild(letters);
  }
}

setting();

 

 

 

 


 

svg를 사용해서 브라우저에 그림을 그려보는 법을 배울 수 있었다.

클릭한 알파벳 배열, 틀린 알파벳 배열 등 케이스별로 배열을 나눠서 꼼꼼히 검사를 해야하고 그만큼 코드도 정확히 작성해야 한다. includes와 같은 내장 함수가 얼마나 유용한지 새삼 느꼈고 함수들에 대해 공부를 더하고 익숙해져야겠다는 생각이 듬.