Javascript & Node.js

반복문 사용하기 - 숫자야구

지문어 2025. 1. 19. 15:00

0. 화면 만들기

<html>
<head>
    <meta charset="utf-8">
    <title>숫자야구</title>
</head>
<body>
    <form id="form">
        <input type="text" id="input">
        <button>확인</button>
    </form>
    <div id="logs"></div>
    <script>
        const $input = document.querySelector('#input');
        const $form = document.querySelector('#form');
        const $logs = document.querySelector('#logs');
    </script>
</body>
</html>

 


1. 숫자 4개 무작위로 뽑기

- 무작위 숫자를 중복되지 않게 뽑으려면: 배열 or 객체 사용

- 배열: 단순한 값의 나열일 때 사용 / 객체: 값에 이름이 붙을 때 사용

(숫자야구의 경우에는 단순한 숫자의 나열이므로 배열 사용)

 

1-1. numbers라는 빈 배열 만들고 그 안에 1부터 9까지의 숫자 넣기

-> 언젠가 긴 배열을 만들 걸 대비해서 '반복문'으로 배열을 생성하는 연습

※ 반복문에서 조건식에 반복 범위를 작성하는 방법(4)

  • 0부터 9미만으로 적기
  • 0부터 8이하로 적기
  • 1부터 10미만으로 적기
  • 1부터 9이하로 적기
const numbers = [];
        for (let n = 1; n <= 9; n += 1) {
            numbers.push(n);
        } #numbers 배열에 1부터 9까지의 숫자 담기

 

1-2. numbers 배열에 1~9까지의 숫자를 넣었고, 이제 그 중에서 무작위로 4개 뽑기

 const answer = [];
        for (let n = 0; n <= 3; n += 1) { #4번 반복(정답인 숫자 4개 뽑기)
            const index = Math.floor(Math.random() * 9); #0~8 정수 뽑기(인덱스에 해당)
            answer.push(numbers[index]); #해당 인덱스에 담긴 숫자를 가져와 answer 배열에 추가(push)
            numbers.splice(index, 1); #뽑은 숫자를 numbers 배열에서 제거(splice), 중복 방지
        }
 
 console.log(answer);

※ Math.random() 

: 자바스크립트에서 난수를 생성하는 함수, 0 이상 1 미만(0 ≤ x < 1) 사이의 난수를 생성

Math.random() * 9: Math.random()으로 생성된 난수에 9를 곱함 -> 0 이상 9 미만(0 ≤ x < 9)의 값이 생성

 

※ Math.floor()

정수인 난수를 생성하려면? Math.random() 함수와 Math.floor() 함수를 함께 사용

Math.floor() 함수는 소수점을 버리고 가장 가까운 정수로 내림

(자바스크립트 - 반올림(round), 올림(ceil), 내림(floor) -> 소수점, 음수,자리수 지정)

 

참고

https://hianna.tistory.com/454

 

[Javascript] 난수 생성하기 (랜덤 숫자, Random Number)

Javascript로 난수를 생성하는 방법을 소개합니다. Math.random() 범위를 지정한 난수 생성하기 0~9 0~10 0~99 0~100 1~10 2~5 난수 생성 함수 만들기 (범위 지정) min

hianna.tistory.com

 

1-3. 코드 오류 수정(4개를 뽑았을 때 undefined가 나오는 경우)

- numbers 배열은 splice 메서드를 호출할 때마다 크기가 줄어듦
- Math.floor(Math.random() * 9)은 항상 0에서 8 사이의 숫자를 생성하지만, 배열 크기가 줄어들면 인덱스가 유효하지 않을 수 있다!

for (let n = 0; n <= 3; n += 1) { 
            const index = Math.floor(Math.random() * numbers.length); #수정
            answer.push(numbers[index]); 
            numbers.splice(index, 1); 
        }

 

-> 9라는 고정된 숫자를 곱하는 대신, numbers 배열의 길이에 맞춰 곱하는 숫자가 줄어들도록 수정

 


2. 입력값 검사하기 (입력값이 형식에 맞는지)

const tries = []; #입력한 값을 담을 배열 생성('1234'처럼 하나의 문자열로)
        function checkInput(input) {} #입력한 값을 검사할 checkInput() 함수 만들기
        $form.addEventListener('submit', (event) => { # #form 태그에 submit 이벤트 달기
            event.preventDefault(); # #form 태그의 기본적인 동작 취소하기
            const value = $input.value; #입력한 값을 $input.value로 가져와서 value 변수에 저장
            $input.value = ''; #입력한 값은 문자열로 들어옴
            const valid = checkInput(value); #checkInput() 함수를 호출 -> 입력한 값 검사, 결과 반환
        });

 

- checkInput() 함수의 내부 작성

: 입력한 값이 4글자인지 / 중복되는 숫자가 있는지 / 이미 시도한 값인지

if (input.length != 4) { #길이가 4인지
                return alert('4자리 숫자를 입력하세요.');
            }
            if (new Set(input).size !== 4) { #중복된 숫자가 있는지
                return alert('중복된 숫자를 입력했습니다.');
            }
            if (tries.includes(input)) { #이미 시도한 값인지
                return alert('이미 시도한 값입니다.');
            }
            return true;

 

 


3. 입력값과 정답 비교하기

3-1. 홈런 여부와 시도 횟수 검사하기

 

- 홈런인지, 시도 횟수가 10번을 넘겼는지 검사하기

if (!valid) #입력값 검사를 통과했는지 확인
                return;
            if (answer.join('') === value) { #answer배열의 값 -> 문자열로 만들기(join() 메서드)
                $logs.textContent = '홈런!';
                return;
            }
            if (tries.length >= 9) {
                const message = document.createTextNode(`패배! 정답은 ${answer.join('')}`);
                $logs.appendChild(message);
            }
            #몇 스트라이크 몇 볼인지 검사

 

3-2. 몇 스트라이크 몇 볼인지 표시하기

let strike = 0; #스트라이크 수
            let ball = 0; //볼 수
            for (let i = 0; i < answe.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);