본문 바로가기
Study/JavaScript

JavaScript 미니 프로젝트 _ 숫자 맞추기 게임

by 나아가는 2023. 9. 11.
반응형

 

배운점

  • 상수 const 객체 선언 시 객체의 주소가 저장되기 때문에 객체 내부의 속성을 변경하는 것은 가능하다.
  • js 코드를 분리해서 DOM을 사용하려면 defer 키워드를 붙여줘야 한다.
  • <script **defer** src="game.js"></script>
  • innerHTML을 이용해 start 버튼을 생성하고 const 객체 값을 변경했더니 화면에서 적용이 안되는 문제를 발견했다.
  • 그 이유는 아래와 같다.
  • ‘innerHTML+=’ 사용 시 주의점
    1. 기존 내용 삭제
    2. 기존 내용과 새로운 내용을 합친 새로운 내용을 씀
  • 즉, innerHTML+=는 기존 코드를 덮어 씌우기 때문에 기존에 연결해 놓은 객체들이 업데이트가 안되는 문제가 발생하였던 것이다.
  • 문제해결 → button을 innerHTML 을 이용해 생성하지 않고, createElement 를 이용해 객체로 추가하였다.
  • HTML을 직접 건들이는 것과 객체로 조작하는 것의 방법차이를 깨닳았다.
  • 게임 초기화를 페이지 리로드를 통해 구현도 가능할 것 같다.

기존 코드

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8" />

    <title>Number guessing game</title>

    <style>
      html {
        font-family: sans-serif;
      }

      body {
        width: 50%;
        max-width: 800px;
        min-width: 480px;
        margin: 0 auto;
      }

      .form input[type="number"] {
        width: 200px;
      }

      .lastResult {
        color: white;
        padding: 3px;
      }
    </style>
  </head>

  <body>
    <h1>Number guessing game</h1>

    <p>
      We have selected a random number between 1 and 100. See if you can guess
      it in 10 turns or fewer. We'll tell you if your guess was too high or too
      low.
    </p>

    <div class="form">
      <form action=""></form>
      <label for="guessField">Enter a guess: </label>
      <input
        type="number"
        min="1"
        max="100"
        required
        id="guessField"
        class="guessField"
      />
      <input type="submit" value="Submit guess" class="guessSubmit" />
    </div>

    <div class="resultParas">
      <p class="guesses"></p>
      <p class="lastResult"></p>
      <p class="lowOrHi"></p>
    </div>

    <script>
      // 숫자게임
      // 숫자는 0~100 까지 랜덤숫자로 이용자가 10 턴 내에 맞춰야 한다.
      // 입력한 숫자가 맞으면 종료 알림와 재시작 버튼
      // 입력한 숫자가 틀리면 정답보다 높은지 낮은지 출력
      // 이전에 입력한 값도 함께 출력
      let answer;
      let guesses;
      let maxTurn;
      let userTurn;

      function initGame() {
        // 입력창 활성화
        document.querySelector(".guessField").disabled = false;
        document.querySelector(".guessSubmit").disabled = false;

        answer = Number.parseInt(Math.random() * 100);
        console.log(answer);

        guesses = [];
        maxTurn = 10;
        userTurn = 0;
        document.querySelector(".lastResult").innerHTML = "";
        document.querySelector(".lastResult").style.backgroundColor = "";
        document.querySelector(".lowOrHi").innerHTML = "";
        document.querySelector(".guesses").innerHTML = "";
      }

      function endGame() {
        // 입력창 비활성화
        document.querySelector(".guessField").disabled = true;
        document.querySelector(".guessSubmit").disabled = true;

        // 재시작 버튼 생성
        document.querySelector(
          ".resultParas"
        ).innerHTML += `<input type="submit" value="Start new game" class="startSubmit" />`;

        let startBtn = document.querySelector(".startSubmit");
        startBtn.onclick = function () {
          initGame();
          this.remove();
        };
      }

      initGame();
      let inputBtn = document.querySelector("input[type=submit]");

      inputBtn.onclick = function () {
        let inputTxt = document.querySelector("input[type=number]");
        let userNum = inputTxt.value;

        // 정답일 경우
        if (userNum == answer) {
          document.querySelector(".lastResult").innerHTML =
            "Congratulations! You got it right!";
          document.querySelector(".lastResult").style.backgroundColor = "green";
          document.querySelector(".lowOrHi").innerHTML = "";

          // 게임 종료
          endGame();

          // 오답일 경우
        } else {
          guesses.push(userNum);
          console.log(guesses.value);
          document.querySelector(
            ".guesses"
          ).innerHTML = `Previous guesses : ${guesses.join(", ")}`;
          document.querySelector(".lastResult").innerHTML = `Wrong!`;
          document.querySelector(".lastResult").style.backgroundColor = "red";
          if (userNum < answer) {
            document.querySelector(".lowOrHi").innerHTML =
              "Last guess was too low!";
          } else {
            document.querySelector(".lowOrHi").innerHTML =
              "Last guess was too high!";
          }
        }
        inputTxt.value = "";
        // user turn check
        userTurn++;
        if (userTurn == maxTurn) {
          document.querySelector(".lastResult").innerHTML = "!!!GAME OVER!!!";
          endGame();
        }
      };
    </script>
  </body>
</html>

 

 

개선 코드

  • 객체 상수 const 저장
  • 재시작시 div p 돌면서 textContent 초기화
  • 다음 턴 때 입력창 활성화하여 시각적으로 다음 값을 입력해야 한다는 느낌을 줄 수 있음
  • guessField.focus();
  • 텍스트 변경시 innerHTML → textContext 사용
// 숫자게임
// 숫자는 0~100 까지 랜덤숫자로 이용자가 10 턴 내에 맞춰야 한다.
// 입력한 숫자가 맞으면 종료 알림와 재시작 버튼
// 입력한 숫자가 틀리면 정답보다 높은지 낮은지 출력
// 이전에 입력한 값도 함께 출력

// 재시작 버튼 생성
let input = document.createElement("input");
input.className = "startSubmit";
input.value = "Start new game";
input.type = "submit";
input.hidden = true;
document.querySelector(".resultParas").append(input);

const startBtn = document.querySelector(".startSubmit");
startBtn.onclick = function () {
  this.setAttribute("hidden", true);
  initGame();
};

const guesses = document.querySelector(".guesses");
const lastResult = document.querySelector(".lastResult");
const lowOrHi = document.querySelector(".lowOrHi");
const guessesSubmit = document.querySelector(".guessSubmit");
const guessField = document.querySelector(".guessField");

let randomNum;
let guessCount;
let resetButton;

function initGame() {
  // 입력창 활성화
  guessField.disabled = false;
  guessesSubmit.disabled = false;

  // 출력값 초기화
  const resetParas = document.querySelectorAll(".resultParas p");
  for (const resetPara of resetParas) {
    resetPara.textContent = "";
  }
  lastResult.style.backgroundColor = "white";

  // 게임 세팅
  randomNum = Math.floor(Math.random() * 100) + 1;
  guessCount = 1;
  console.log(randomNum);
}

function endGame() {
  // 입력창 비활성화
  guessField.disabled = true;
  guessesSubmit.disabled = true;

  // 재시작 버튼 생성
  startBtn.hidden = false;
}

function checkGuess() {
  let userNum = Number(guessField.value);

  // 이전 입력값 출력
  if (guessCount === 1) {
    guesses.textContent = "Previous guesses : ";
  }
  guesses.textContent += userNum + " ";

  // 정답일 경우
  if (userNum === randomNum) {
    lastResult.textContent = "Congratulations! You got it right!";
    lastResult.style.backgroundColor = "green";
    lowOrHi.textContent = "";

    // 게임 종료
    endGame();

    // 턴 초과일 경우
  } else if (guessCount === 10) {
    lastResult.textContent = "!!!GAME OVER!!!";
    endGame();

    // 오답일 경우
  } else {
    lastResult.textContent = `Wrong!`;
    lastResult.style.backgroundColor = "red";

    // 입력값이 작을 경우
    if (userNum < randomNum) {
      lowOrHi.textContent = "Last guess was too low!";

      // 입력값이 클 경우
    } else {
      lowOrHi.textContent = "Last guess was too high!";
    }
  }

  guessCount++;
  // 입력창 초기화, 커서 활성화
  guessField.value = "";
  guessField.focus();
}

initGame();
guessesSubmit.onclick = checkGuess;

 

참고 자료

https://developer.mozilla.org/ko/docs/Learn/JavaScript/First_steps/A_first_splash

 

JavaScript에 발 담그기 - Web 개발 학습하기 | MDN

JavaScript에 관한 약간의 이론과, JavaScript가 할 수 있는 일을 알아봤으니 이제 간단한 JavaScript 프로그램을 만들어보면서 개발 과정이 어떤 느낌인지 알아보겠습니다. "숫자 알아맞히기" 게임을 차

developer.mozilla.org

 

반응형

'Study > JavaScript' 카테고리의 다른 글

JavaScript 미니 프로젝트 Todo List  (0) 2023.09.12
DOM 노드와 주요 프로퍼티  (0) 2023.08.30
문서 객체 모델 DOM  (0) 2023.08.29
자바 스크립트 기본  (0) 2023.08.28