돈이 만드는 세상

숫자야구 코드 및 설명 - zerocho ES2021 강의 본문

프로그래밍/JavaScript

숫자야구 코드 및 설명 - zerocho ES2021 강의

피델리오 2021. 11. 2. 15:39

```
1. 정답이 될 숫자 4개를 입력한다.
2. 숫자 4개를 입력한다. 중복되지 않게 입력해야한다.
2-1. 중복을 검사한다.
- 숫자를 처리할 방법은 숫자 자체를 입력을 따로 받아 4개의 변수로써 처리해 검사하는 방법을 이용하면 쉽게 풀 수 있을 것 같다.
- 반복문을 통해, 입력 받은 변수들과 정답과의 변수들과 비교해 2-1, 2-2과정을 거친다.
3-1. '자리'와 '숫자'가 모두 맞다면 Strike를 '+'해준다.
3-2. '숫자'만 맞다면, Ball을 '+' 해준다.
4. Strike와 Ball의 개수를 출력한다.
4-1. 만약 4S일 경우, 게임을 종료한다.
4-2. 아닐 경우, 2번으로 돌아간다.
```
내가 강의를 듣기 전에 숫자야구라는 게임의 구조를 생각해 만들어본 순서도이다.

숫자야구에서 중요한 것은 숫자 4개를 랜덤으로 뽑는 것인데, 랜덤하게 뽑기 위해서 `Math.random()`을 이용할 것이다. `Math`는 수학 관련한 메서드들을 담아둔 객체이다.
- Math.floor 내림
- Math.ceil 올림
- Math.round 반올림

`form 태그`의 특성은 `event.target[]`을 통해 배열 처럼 접근이 가능하다는 것이다. 예를 들어, 아래 코드에서는 `event.target[0]`은 `input`을 나타내고 `event.target[1]`은 `button`을 가리킨다.

`.join()`을 통해 배열을 분리할 수 있다. `('')` 빈 문자열을 넣게 되면, 예를 들어 3,1,4,6이 아닌 3146을 뽑을 수 있다.

`.append()`는 말그대로 추가를 하는 것이다. 한번에 `,`를 통해 여러 개를 추가 할 수 있다. `appendChild()`를 개선한 것이 `append()`이므로 실제로는 `append`를 사용한다. 이것을 사용하지 않고 `appendChild(document.createTextNode())`와 `document.createElement()`을 통해 구현가능하다.

<html>
    <head>
    </head>
    <body>
        <div>
            <form id="form">
                <input type="text" id="input">
                <button id="check">확인</button>
            </form>
        </div>
        <div id="logs"></div>
        <script>
            const $input = document.querySelector('#input');
            const $form = document.querySelector('#form');
            const $logs = document.querySelector('#logs');
            let out = 0;

            const numbers = [];
            for(let i = 0; i < 9; i += 1) {
                numbers.push(i + 1);
            }
            const answer = [];
            for(let i = 0; i < 4; i += 1) {
                const index = Math.floor(Math.random() * (numbers.length - i));    // 0~8을 입력받고 입력 받고 반복을 할 때마다 범위를 크기를 최댓값의 범위를 1 줄인다.
                answer.push(numbers[index]);    // 해당 인덱스가 있다면 answer에 push한다.
                numbers.splice(index, 1);   // 한번 나왔으므로 numbers에서 지워버린다. 그러면 그 뒤에 숫자들은 자동적으로 앞으로 땡겨진다.
            }
            console.log(answer);

            const tries = [];
            function checkInput(input) {
                if(input.length !== 4) {
                    return alert('4자리 숫자를 입력해주세요.');
                }
                if(new Set(input).size !== 4) {
                    return alert('중복되지 않게 입력해주세요.');
                }
                if(tries.includes(input)) {
                    return alert('이미 시도한 값입니다.');
                }
                return true;
            }
            
            function defeated() {
                const message = document.createTextNode(`패배! 정답은 ${answer.join('')}`);
                $logs.appendChild(message);
            }

            $form.addEventListener('submit', (event) => {
                event.preventDefault(); // 기본 동작 막기. -> 여기서는 새로고침을 막음. 대표적인 친구들이 form tag와 a tag.
                const value = $input.value; // event.target[0].value로 접근 가능.
                $input.value = '';
                if(checkInput(value)) {
                    // 입력값 문제 없음
                    if(answer.join('') === value) {
                        $logs.textContent = '홈런!!';
                        return;
                    }
                    if(tries.length >= 9) {
                        defeated();
                        return;
                    }
                } else {
                    // 에러
                    return;
                }

                let strike = 0;
                let ball = 0;
                for(let i = 0; i < answer.length; i += 1) {
                    const index = value.indexOf(answer[i]);
                    if(index > -1) {
                        if(i === index) {
                            strike += 1;
                        } else {
                            ball += 1;
                        }
                    }
                }
                if(ball === 0 && strike == 0) {
                    out++;
                    $logs.append(`현재 아웃 개수 ${out}`, document.createElement('br'));
                } else {
                    $logs.append(`${value}: ${strike}스트라이크 ${ball}볼 ${out}아웃`, document.createElement('br'));
                }
                if(out === 3) {
                    defeated();
                    return;
                }
                //$logs.appendChild(document.createTextNode(`${value}`));
                //$logs.appendChild(document.createElement('br'));
                tries.push(value);
            });
        </script>
    </body>
</html>