WEB/JavaScript

[제로초JS] chap5. 숫자야구게임

Harimad 2022. 1. 11. 17:59

  • 챕터목표 : 숫자 야구 게임을 할 수 있는 작은 프로그램 만들기
  • 게임규칙:
    • 숫자 1~9 중에 4개를 무작위로 뽑아서 정답으로 설정하고, 사용자가 중복되지 않는 4자리 숫자를 입력한다. 
    • 정답과 사용자의 입력값을 비교할때, 같은 자리의 값이 일치하면 strike를 1증가 시킨다. 다른 자리의 값이 일치하면 ball을 1증가 시킨다.
    • 10번 시도해서 숫자를 맞추지 못하면 패배한다. 

야구게임 순서도

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>숫자야구게임</title>
</head>
<body>
  <form id="form">
    <!-- HTML5 검증 기능 활용 -->
    <input type="text" id="input" required minlength="4" maxlength="4" pattern="^(?!.*(.).*\1)\d{4}$">
    <button>확인</button>
  </form>
  <div id="logs"></div>

  <script>
    const $input = document.querySelector('#input');
    const $form = document.querySelector('#form');
    const $logs = document.querySelector('#logs');

    const numbers = [];
    for (let n = 1; n <= 9; n++) {
      numbers.push(n); //const numbers = Array(9).fill().map((v, i) => i + 1); 
    }

    //answer값 설정
    const answer = [];
    for (let n = 0; n <= 3; n++) { //네 번 반복
      const index = Math.floor(Math.random() * numbers.length); //numbers길이에따라 숫자 랜덤 뽑기
      answer.push(numbers[index]);
      numbers.splice(index, 1);
    }
    console.log(answer);

    //내 답 예측하기
    const tries = [];

    function checkInput(input) {
      if (input.length !== 4) {
        return alert('4자리 숫자 입력하세요!'); //alert는 undefined 반환
      } 
      if (new Set(input).size !== 4) { //Set은 중복을 허락X는 특수배열, length대신 size 씀
        return alert('중복되지 않게 입력하세요!');
      }
      if (tries.includes(input)) { 
        return alert('이미 시도한 값임!')
      }
      return true;
    }

    $form.addEventListener('submit', (event) => {
      event.preventDefault(); //폼 태그 기본동작 취소코드, submit발생때 새로고침 방지
      const value = $input.value;
      $input.value = '';
      const valid = checkInput(value);
      //시도 횟수 10회 넘겼는지 검사
      if (!valid) return;
      if (answer.join('') === value) {
        $logs.textContent = '홈런';
        return;
      }
      if (tries.length >= 9) {
        const message = document.createTextNode(`패배! 정답은 ${answer.join('')}`);
        $logs.appendChild(message);
        return;
      }
      //몇 스트라이크 몇 볼인지 검사
      let strike = 0;
      let ball = 0;
      for (let i = 0; i < answer.length; i++) {
        const index = value.indexOf(answer[i])
        if (index > -1) { //일치하는 숫자 발견
          if (index === i) { //자릿수도 같을때
            strike += 1;
          } else { //숫자만 같을때
            ball += 1;
          }
        }
      }
      $logs.append(`${value}: ${strike} 스트라이크 ${ball} 볼`, document.createElement('br'));
      tries.push(value);
    })
  </script>
</body>
</html>
숫자야구게임

아웃 추가한 순서도

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>숫자야구게임</title>
</head>
<body>
  <form id="form">
    <!-- HTML5 검증 기능 활용 -->
    <input type="text" id="input" required minlength="4" maxlength="4" pattern="^(?!.*(.).*\1)\d{4}$">
    <button>확인</button>
  </form>
  <div id="logs"></div>

  <script>
    const $input = document.querySelector('#input');
    const $form = document.querySelector('#form');
    const $logs = document.querySelector('#logs');

    const numbers = [];
    for (let n = 1; n <= 9; n++) {
      numbers.push(n); //const numbers = Array(9).fill().map((v, i) => i + 1); 
    }

    //answer값 설정
    const answer = [];
    for (let n = 0; n <= 3; n++) { //네 번 반복
      const index = Math.floor(Math.random() * numbers.length); //numbers길이에따라 숫자 랜덤 뽑기
      answer.push(numbers[index]);
      numbers.splice(index, 1);
    }
    console.log(answer);

    //내 답 예측하기
    const tries = [];

    //입력값 확인 함수
    function checkInput(input) {
      if (input.length !== 4) {
        return alert('4자리 숫자 입력하세요!'); //alert는 undefined 반환
      } 
      if (new Set(input).size !== 4) { //Set은 중복을 허락X는 특수배열, length대신 size 씀
        return alert('중복되지 않게 입력하세요!');
      }
      if (tries.includes(input)) { 
        return alert('이미 시도한 값임!')
      }
      return true;
    }
    //패배 출력 함수
    function defeated() {
      const message = document.createTextNode(`패배! 정답은 ${answer.join('')}`);
      $logs.appendChild(message);
    }

    let out = 0;
    $form.addEventListener('submit', (event) => {
      event.preventDefault(); //폼 태그 기본동작 취소코드, submit발생때 새로고침 방지
      const value = $input.value;
      $input.value = '';
      const valid = checkInput(value);
      //시도 횟수 10회 넘겼는지 검사
      if (!valid) return;
      if (answer.join('') === value) {
        $logs.textContent = '홈런';
        return;
      }

      if (tries.length >= 9) {
        defeated();
        return;
      }
      //몇 스트라이크 몇 볼인지 검사
      let strike = 0;
      let ball = 0;
      for (let i = 0; i < answer.length; i++) {
        const index = value.indexOf(answer[i])
        if (index > -1) { //일치하는 숫자 발견
          if (index === i) { //자릿수도 같을때
            strike += 1;
          } else { //숫자만 같을때
            ball += 1;
          }
        }
      }
      if (strike === 0 && ball === 0) {
        out++;
        $logs.append(`${value}: 아웃`, document.createElement('br'));
      } else {
        $logs.append(`${value}: ${strike} 스트라이크 ${ball} 볼`, document.createElement('br'));
      }
      if (out === 3) {
        defeated();
        return;
      }
      tries.push(value);
    })
  </script>
</body>
</html>
숫자야구게임

 

 

 

 

정규표현식 참고: https://github.com/ziishaned/learn-regex/blob/master/translations/README-ko.md

 

GitHub - ziishaned/learn-regex: Learn regex the easy way

Learn regex the easy way. Contribute to ziishaned/learn-regex development by creating an account on GitHub.

github.com

출처: https://www.zerocho.com/book/2

 

ZeroCho Blog

ZeroCho의 Javascript와 Node.js 그리고 Web 이야기

www.zerocho.com