돈이 만드는 세상

객체 다루기_가위바위보 게임- zerocho ES2021 강의 본문

프로그래밍/JavaScript

객체 다루기_가위바위보 게임- zerocho ES2021 강의

피델리오 2021. 11. 3. 23:30
<html>
<head>
  <meta charset="utf-8" />
  <title>가위바위보</title>
  <style>
    #computer {
      width: 142px;
      height: 200px;
    }
  </style>
</head>

<body>
<div id="computer"></div>
<div>
  <button id="scissors" class="btn">가위</button>
  <button id="rock" class="btn">바위</button>
  <button id="paper" class="btn">보</button>
</div>
<div id="score">0</div>
<script>
  const $computer = document.querySelector('#computer');
  const $score = document.querySelector('#score');
  const $rock = document.querySelector('#rock');
  const $scissors = document.querySelector('#scissors');
  const $paper = document.querySelector('#paper');
  const IMG_URL = './rsp.png';
  $computer.style.background = `url(${IMG_URL}) 0 0`; // 이미지 주소, 가로 위치, 세로 위치
  $computer.style.backgroundSize = 'auto 200px';  // 웹페이지에 뜨는 가로 너비, 세로 높이 (auto는 자동으로 이미지 크기에 맞게 하는 것)
  const rspX = {
    scissors: '0',  // 가위
    rock: '-220px', // 바위
    paper: '-440px', // 보 
  };

  let computerChoice = 'scissors';
  // setInterval은 재귀 setTimeout으로 교체 가능하다.
  const changeComputerHand = () => {
    // background랑 backgroudSize는 한 묶음이라 생각.
    if(computerChoice === 'scissors') { // 가위
      computerChoice = 'rock';
    } else if(computerChoice === 'rock') { // 바위
      computerChoice = 'paper';
    } else if(computerChoice === 'paper') {  // 보
      computerChoice = 'scissors';
    }
    $computer.style.background = `url(${IMG_URL}) ${rspX[computerChoice]} 0`;
    $computer.style.backgroundSize = 'auto 200px';
  }
  // clickButton 5번 호출, 인터벌 1번, 2번, 3번, 4번, 5번(얘만 intervalId에 저장)
  // 그 다음 버튼을 클릭하면 clearInterval하게 되면 5번만 취소
  // 1. clearInverval을 한번 더 이용하는 방법 2. removeEventListener를 사용하는 방법 3. flag를 이용하는 방법
  let intervalId = setInterval(changeComputerHand, 50);
  let clickable = true;
  let userScore = 0;
  let pcScore = 0;
  const scoreTable = {
    rock: 0,
    scissors: 1,
    paper: 2,
  };

  const clickButton = () => {
    if(clickable) {
      clearInterval(intervalId);
      clickable = false;
      // $rock.removeEventListener('click', clickButton);
      // $scissors.removeEventListener('click', clickButton);
      // $paper.removeEventListener('click', clickButton);
      const myChoice = event.target.textContent === '바위'
        ? 'rock'
        : event.target.textContent === '가위'
          ? 'scissors'
          : 'paper';
      // 점수 계산 및 화면 표시
      const myScore = scoreTable[myChoice];
      const computerScore = scoreTable[computerChoice];
      const diff = myScore - computerScore;

      let message;
      if(diff === -2 || diff === 1) {
        userScore += 1;
        message = '승리';
      } else if([-1, 2].includes(diff)) {
        pcScore += 1;
        message = '패배';
      } else {
        message = '무승부';
      }
      if(userScore == 3) {
        $score.textContent = `축하드립니다. 컴퓨터: ${pcScore} 점 대 본인: ${userScore} 점으로 먼저 승리하셨습니다.`;
      } else if(pcScore === 3) {
        $score.textContent = `아쉽게도 본인: ${userScore} 점, 컴퓨터: ${pcScore} 점으로 패배하셨습니다.`;
      } else {
        $score.textContent = `${message} 유저스코어: ${userScore} 점 컴퓨터스코어 ${pcScore} 점`;
        setTimeout(() => {
          clickable = true;
          // clearInterval(intervalId); // 해당 문제를 해결하기 위해 직전의 인터벌이 있다면 clearInterval을 통해 제거해줌. 클릭을 누르고 1초 후에 실행되는 거라 코드 중복이 아님.
          // $rock.addEventListener('click', clickButton);
          // $scissors.addEventListener('click', clickButton);
          // $paper.addEventListener('click', clickButton);
          intervalId = setInterval(changeComputerHand, 50);
        }, 1000);
      }
    }
  };
  $rock.addEventListener('click', clickButton);
  $scissors.addEventListener('click', clickButton);
  $paper.addEventListener('click', clickButton);
</script>
</body>
</html>