ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript] 자바스크립트로 숫자 야구 게임 만들기
    Javascript 2023. 5. 15. 22:35
    반응형

    5-1. 숫자야구 순서도 그리기

    간단한 순서도

    1. 시작

    2. 숫자 4개를 뽑는다.


    1. 사용자에게 숫자를 4개 입력 받는다

    2. 입력 받는 숫자가 조건에 맞는지 검사한다.

    3. 2번이 true이면 홈런인가 검사한다.

    4. 3번이 flase이면 10번 시도했는지 검사한다.

    5. 4번이 flase이면 몇 스트라이크, 몇 볼인지 표시하고 시도 횟수를 1 늘린다.

     

    5-2. 랜덤 사용하기(Math.random)

    무작위로 숫자 뽑기

    Math.random 과정

    Math.random() 0<= x < 1 ex) 0.9555, 0.03487 ...
    Math.random() * 9 0<= x < 9 ex) 0.3341,6.656 ...
    Math.random() * 9 + 1  1<= x < 10 ex) 1.4714, 9.6451 ...
    Math.floor(Math.random() * 9 + 1 ) x = { 1,2,3,4,5,6,7,8,9 } ex) 2,5,6,9 ...

    Math.floor는 내림 기능이다.

     

    5-3. 무작위로 숫자 네 개 뽑기

    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <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");
    
            // 랜덤 숫자 뽑기
            const numbers = []; // [1, 2, 3, 4, 5, 6, 7, 8, 9]
            for (let n = 0; n < 9; n+=1) {
                numbers.push(n + 1);
            } 
            
            const answer = [];
            for (let n = 0; n < 4; n++) { // 네 번 반복
                const index = Math.floor(Math.random() * (numbers.length - n)); // 0 ~ 9까지 정수
                answer.push(numbers[index]); // 뽑은 숫자를 answer 리스트에 push
                numbers.splice(index, 1); // 뽑은 수 지우기
            }
            console.log(answer);
        </script>
    </body>
    </html>
    Tip
    프로그램 에러 검증 : list의 끝 값(가장 처음, 가장 마지막 인덱스 값)을 예시를 삼아서 시뮬레이션 해보기

    5-4. 입력값 검증하기

    form

     // $form 함수
            $form.addEventListener('submit',(event) => {
                // 기본 동작(화면 새로고침) 막기
                event.preventDefault();
            })

    event.target[0] : 입력창 -> 입력창 내부 값(value) 가져 올 때, 사용할 수 있다.

    event.target[1] : 확인버튼

    입력값 검증 함수와 사용

    const tries = [];
            // 입력값 검증하는 함수
            function checkInput(input) {
                if(input.length !== 4) { // 4자리 숫자 검사
                    return alert('4자리 숫자를 입력해주세요!');
                }
                if(new Set(input).size !== 4) { // 중복된 숫자 존재 여부 검사
                    return alert('중복되지 않게 입력해 주세요!');
                }
                if(tries.includes(input)) { // 이미 시도한 값이진 검증
                    return alert('이미 시도한 값입니다.');
                }
                return true;
            }
            
            $form.addEventListener('submit', (event) => {
                // 기본 동작(화면 새로고침) 막기
                event.preventDefault();
                const value = $input.value; // const value = event.target[0].value
                $input.value = ''; // 다음 값을 입력하기 전에 입력창 비움
                if(checkInput(value)) {
                    //입력값 문제 없음
                    tries.push(value);
                } else { 
                    // 에러 있음
                }
            });

     

    5-5. 홈런인지 검사해서 표시하기

    $form.addEventListener('submit', (event) => {
                // 기본 동작(화면 새로고침) 막기
                event.preventDefault();
                const value = $input.value; // const value = event.target[0].value
                $input.value = ''; // 다음 값을 입력하기 전에 입력창 비움
               //
                if (checkInput(value)) {
                    // 에러 존재
                    return;
                }
                //입력값 문제 없음
                // 홈런 했는지 여부 확인
                if (answer.join('') === value) { // join 메소드로 배열을 문자열로 만든다. [3, 1, 4, 6] -> '3,1,4,6' 
                    $logs.textContent = '홈런!'; // textContent는 문자열삽입
                    return;
                }
                // 10번 시도한 것
                if (tries.length >= 9) {
                    const message = document.createTextNode(`패배! 정답은 ${answer.join('')}`); // `` 안에 있는 텍스트 노드를 생성한다. 그리고 길이서 변수로 그냥 담은 것임
                    $logs.appendChild(message); // appendChild로 Node객체만을 받을 수 있다. 단, 한가지 만 가능하다.
                    return;
                }
                // 몇스트라이크 몇 볼인지 검사
                tries.push(value); // 시도한 값을 저장
            });

    join, split

    if (answer.join("") === value) {
      $logs.textContent = "홈런!";
      return;
    }

    ex) 리스트 a = [1,2,3,4,6]

    join

    a.join()

    출력 : '1,2,3,4,6'

    a.join("")

    출력 : '12346'

    split

    '12346'.split()

    출력 : ['12346']

    '12346'.split()

    출력 : ['1','2','3','4','6']

     

     $logs.textContent, $logs.innerHTML

    $logs.textContent

    홈런 text에 다른 텍스트를 추가하기 위해서

    $logs.textContent = $logs.textContent + " 홈런"

    textContent는 모든 글자를 모두 text로 인식해서, html 코드를 인식하지 못한다.

    $logs.innerHTML

    $logs.innerHTML = $logs.textContent + "<br/>홈런";

    innerHTML을 사용하면 문자열 중간의 html 태그를 인식하여 글자를 추가해준다.

     

    message, append

    if (tries.length >= 9) {
      const message = document.createTextNode(
         `패배! 정답은 ${answer.join("")}`
        );
       $logs.appendChild(message);
       return;
    }

    message

    const message = document.createTextNode()

    Tip
    줄바꿈 하고 싶은 경우 createElement('br')를 통해 br태그를 생성할 수 있다. 

    $logs.append(document.createElement('br'));

     

     

    append

    $logs에 message를 추가한다.

     

    5-6. 몇 볼 몇 스트라이크인지 계산하기

    <script>
     // 몇스트라이크 몇 볼인지 검사
                let strike = 0;
                let ball = 0;
                // 예시) answer: 3416, value: 1234 // 3볼임
                // 같은 자리에 숫자도 같으면 스트라이크
                // 다른 자리에 숫자가 같으면 볼
                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>

    최종 코드

    <!DOCTYPE html>
    <html lang="ko">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <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");
    
            // 랜덤 숫자 뽑기
            const numbers = []; // [1, 2, 3, 4, 5, 6, 7, 8, 9]
            for (let n = 0; n < 9; n += 1) {
                numbers.push(n + 1);
            }
    
            // 결과 배열 뽑기
            const answer = [];
            for (let n = 0; n < 4; n++) { // 네 번 반복
                const index = Math.floor(Math.random() * (numbers.length - n)); // 0 ~ 9까지 정수
                answer.push(numbers[index]); // 뽑은 숫자를 answer 리스트에 push
                numbers.splice(index, 1); // 뽑은 수 지우기
            }
            // console.log(answer);
    
            const tries = [];
            // 입력값 검증하는 함수
            function checkInput(input) {
                // 4자리 숫자인지 검사
                if (input.length !== 4) { 
                    return alert('4자리 숫자를 입력해주세요!');
                }
                // 중복된 숫자 존재 여부 검사
                if (new Set(input).size !== 4) { 
                    return alert('중복되지 않게 입력해 주세요!');
                }
                // 이미 시도한 값이진 검증
                if (tries.includes(input)) { 
                    return alert('이미 시도한 값입니다.');
                }
                return true;
            }
    
            $form.addEventListener('submit', (event) => {
                // 기본 동작(화면 새로고침) 막기
                event.preventDefault();
                const value = $input.value; // const value = event.target[0].value
                $input.value = ''; // 다음 값을 입력하기 전에 입력창 비움
               //
                if (checkInput(value)) {
                    // 에러 존재
                    return;
                }
                //입력값 문제 없음
                // 홈런 했는지 여부 확인
                if (answer.join('') === value) { // join 메소드로 배열을 문자열로 만든다. [3, 1, 4, 6] -> '3,1,4,6' 
                    $logs.textContent = '홈런!'; // textContent는 문자열삽입
                    return;
                }
                // 10번 시도한 것
                if (tries.length >= 9) {
                    const message = document.createTextNode(`패배! 정답은 ${answer.join('')}`); // `` 안에 있는 텍스트 노드를 생성한다. 그리고 길이서 변수로 그냥 담은 것임
                    $logs.appendChild(message); // appendChild로 Node객체만을 받을 수 있다. 단, 한가지 만 가능하다.
                    return;
                }
                // 몇스트라이크 몇 볼인지 검사
                let strike = 0;
                let ball = 0;
                // 예시) answer: 3416, value: 1234 // 3볼임
                // 같은 자리에 숫자도 같으면 스트라이크
                // 다른 자리에 숫자가 같으면 볼
                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>

     

    출처:  https://tinyurl.com/bdd5cxu4

     

    ES2021 자바스크립트 강좌

     

    www.youtube.com

     

    반응형

    댓글

Designed by Tistory.