새소식

Web Programming

웹 프로그래밍 | 숫자야구 프로그램 만들기 | 자바스크립트

  • -
728x90

자바스크립트로 숫자야구 구현하기

 

과제 : 자바스크립트 함수와 조건문을 활용하여 숫자 야구 프로그램 만들기

이번에 자바스크립트 과제로 숫자야구 프로그램 과제를 받았다. 2인 1조로 페어 프로그래밍을 진행했고, 다른 팀원분은 임의로 숫자를 뽑는 로직을 작성하는 역할을 담당하셨고, 나는 함수와 프런트를 담당했다. 챗지피티 디톡스를 하고 실력을 늘리기 위해 최대한 스스로 코드를 작성해보려 하였다.

웹에 이런식으로 나와야 한다.

과제 조건

  • 컴퓨터는 0과 9 사이의 서로 다른 숫자 3개를 무작위로 뽑습니다. (ex) 123, 759
  • 사용자는 컴퓨터가 뽑은 숫자를 맞추기 위해 시도합니다.
  • 컴퓨터는 사용자가 입력한 세자리 숫자에 대해서, 아래의 규칙대로 스트라이크(S)와 볼(B)을 알려줍니다.
    • 숫자의 값과 위치가 모두 일치하면 S
    • 숫자의 값은 일치하지만 위치가 틀렸으면 B
  • 기회는 무제한이며, 몇번의 시도 후에 맞췄는지 기록됩니다.
  • 숫자 3개를 모두 맞춘 경우, 게임을 종료합니다.

 

해결방법 

1. 컴퓨터가 숫자 임의로 3개 나열하게 하기(팀원)

// 1. 랜덤 숫자 3자리 만들기
// for문으로 만들기

const numbers = [];

for(let n = 1; n < 10; n++) {
numbers.push(n);
}

const answer = [];
for(let n =0; n < 3; n++) { // 3번 반복(3자리수 만들기)
const index = Math.floor(Math.random() * numbers.length); //0~9 사이 정수
answer.push(numbers[index]);
numbers.splice(index, 1);
}
console.log(answer);

- 빈 배열 'numbers'를 생성하고 1부터 9까지의 숫자를 순차적으로 추가했다.

- answer라는 빈 배열을 만들고 3번 반복해서 숫자를 선택했다.

- Math.random() 은 0 이상 1 미만의 랜덤 숫자를 생성하므로, number.length를 곱하면 ㅇ

- 3번의 반복동안 `Math.random() * numbers.length);`  [왜냐하면 (0<x<1 * 10] 이니까

- 위 값에는 위로 부터 0에 수렴하는 값과 아래로부터 10에 수렴하는 값이 나오게 됩니다.

- 해당 값에 반올림을 해 numbers의 배열의 원소 중에 하나를 꺼내와 사용자의 입력과 비교할 배열인 answer에 넣습니다.

- numbers.splice(index, 1); 코드는 해당 인덱스의 값을 배열에서 제거해 다시 뽑히지 않도록 만듭니다. 

 

질문? 

그러면 numbers.length 가 반복문이 돌 때마다 1씩 감소하니까 점차적으로 극단값에 있는 수들이 뽑힐 확률이 줄어들듯 싶습니다. 

 

 

2. 유저의 입력값 받아와 컴퓨터의 값과 비교해 볼과 스트라이크 계산하기

//const $input = document.querySelector('#input');
//const $form = document.querySelector('#form');      

let NumberTry = 0;

      //    버튼 제출
      document
        .getElementById("submit-btn")
        .addEventListener("click", UserInput);

      function UserInput() {
        let input = document.getElementById("user-input").value;
        let ball = 0;
        let strike = 0;

        // 스트라이크와 볼 판단 로직
        for (let i = 0; i < 3; i++) {
          if (input[i] == answer[i]) {
            strike++;
          } else if (answer.includes(Number(input[i]))) {
            ball++;
          }
        }

- cont $input = document.querySelector('#input) : 쿼리 실렉터를 통해 user의 인풋값을 가지고 있어요.

- 유저의 횟수를 계산해줘야 하기 때문에 전역변수로 'NumberTry' 설정

- document.getElementByID("submit-btn").addEventListener("click",UserInput) : 버튼 클릭 이벤트를 감지해서 클릭 시에 아래 UserInput 함수를 실행합니다.

- 안에서 user-input ID 태그 안의 값을 가져오기 때문에 const $input은 필요 없을거 같아요. 
- 그리고 함수 내에 지역변수인 볼과 스트라이크를 선언해줍니다. 이 값들은 매번 함수가 돌 때마다 초기화되어야 해요. 

 

-그리고 함수 안에 반복문을 통해 스트라이크와 볼을 판단해줍니다. 

- 자바스크립트에서는 문자열은 문자의 배열로 취급될 수 있어서, 문자열에서 특정 위치의 문자에 접근하려면 배열과 마찬가지로 인덱스를 활용할 수 있습니다. 

- 그래서 사용자가 입력한 값(input)과 answer 배열의 각 원소를 첫 번째 자리부터 세 번째 자리까지 비교합니다. 맞다면 strike 카운트를 올려주고, else if 구문에서는 사용자가 입력한 값이 동일한 인덱스에는 없지만 answer의 원소 중에 하나라도 input [i] 번째 위치한 값을 가지고 있다면 볼 카운트를 늘려주는 것입니다. 

 

 

3. 결과 로그 출력하기

결과로그 부분 출력하기

 <div class="log">
        <h2>결과 로그</h2>
        <p>현재 도전 횟수 : <span id="NumberTry">0</span></p>
        <ul id="result-log"></ul>
      </div>

<script>

// 결과 로그에 출력
        const resultLog = document.getElementById("result-log");
        const resultMessage =
          strike === 3 ? `${NumberTry + 1}번만에 맞추셨습니다` : `${NumberTry + 1}번째 시도: ${input} - ${ball}B${strike}S`;
        const li = document.createElement("li");
        li.textContent = resultMessage;
        resultLog.appendChild(li);

        NumberTry++;
        document.getElementById("NumberTry").innerText = NumberTry;
      }
      
</script>

결과로그 출력 부분은 아래 순서로 진행됩니다.

도전 횟수

1. 기본적으로 현재도전 횟수가 0으로 맞춰져 있습니다.

2. 이 값은 docummet.innertext를 통해 전역변수인 NumberTry를 따라 span 태그 내의 값이 매번 바뀌게 됩니다.

 

볼 스트라이크 판별문(삼항연산자)

1. 결과 로그를 담을 ul 태그를 가져와 resultLog에 담습니다.

2. 변수 스트라이크의 값이 3인지 확인하고 맞다면, NumberTry +1 값 만에 맞췄다'를 출력합니다. 1을 더한 이유는, 해당 값은 유저가 제출 버튼을 누르기 전의 값을 가지고 있기 때문입니다. NumberTry ++ 가 삼항연산자보다 위에 있으면 1을 더하지 않아도 됩니다. 

3. 새로운 li태그를 만들어 결과 메시지에 담습니다. li.textContent를 통해 resultMessage 값을 넣습니다. 그리고 이를 appendChild를 사용해 resultlog에 추가합니다.

 

Node: appendChild() method - Web APIs | MDN

The appendChild() method of the Node interface adds a node to the end of the list of children of a specified parent node.

developer.mozilla.org

 

 

피드백

여전히 각 변수에서 왜 const와 let을 사용하는지 잘 모르겠다.  > 공부해서 공부한 링크 달도록 하자 

HTML 값을 가져오고, 이를 바꾸는 활용 방법과 그 기준을 아직도 잘 모르겠다. 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.