관리 메뉴

프로그래밍 삽질 중

Let's Get IT 자바스크립트 프로그래밍 - 숫자야구 문제점 해결 추가, 가위바위보하기 본문

카테고리 없음

Let's Get IT 자바스크립트 프로그래밍 - 숫자야구 문제점 해결 추가, 가위바위보하기

평부 2022. 7. 27. 16:05

* 출처 : https://thebook.io/080270/part02/ch07/

 

Let's Get IT 자바스크립트 프로그래밍: 7장 객체 다루기_가위바위보 게임

 

thebook.io

 

*이전 글 : https://ba-gotocode131.tistory.com/174

 

Let's Get IT 자바스크립트 프로그래밍 - 숫자야구(아웃 추가, 시도 횟수 추가)

* 출처 : https://thebook.io/080270/part02/ch05/ Let's Get IT 자바스크립트 프로그래밍: 5장 반복문 사용하기_숫자야구 게임 thebook.io * 숫자 야구 - 1~9까지 중복되지 않는 숫자 4개를 고른다 - 4개의 숫자..

ba-gotocode131.tistory.com

 

* 문제점 

- 아웃 되거나 시도 횟수를 초과할 경우 더 이상 입력해도 값이 눌러지지 않아야 함

(현재는 눌러지는 상황)

 

 

-> 결과 후 페이지 새로고침하기

 

- 홈런인 경우 -> '정답입니다' 보여준 후 3초 뒤에 페이지 새로고침

- 패배인 경우 -> 패배! 정답 보여준 후 3초 뒤에 페이지 새로고침

- 아웃 3번인 경우 -> 아웃! 정답 보여준 후  3초 뒤에 페이지 새로고침

 

결과

더보기
<!DOCTYPE html>
<html lang="en">

<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 $form = document.querySelector('#form');
        const $input = document.querySelector('#input');
        const $logs = document.querySelector('#logs');

        const numbers = []
        let out = 0;

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

        const answer = [];
        for (let n = 0; n < 4; n++) {
            const index = Math.floor(Math.random() * numbers.length);
            answer.push(numbers[index]);
            numbers.splice(index, 1);
        }
        console.log(answer.join(''));

        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; //return alert = return undefined(undefined는 if문에서 false)
        }

        $form.addEventListener('submit', (event) => {
            event.preventDefault();
            const value = $input.value; //숫자지만 문자열로 가져옴
            $input.value = '';
            const valid = checkInput(value);
            if (!valid) return; //형식이 맞지 않으면 입력 x
            if (answer.join('') === value) { //형식과 값이 맞는 경우
                $logs.textContent = '홈런입니다!';
                setTimeout(() => {
                    location.reload();
                }, 3000);
                return;
            }
            if (tries.length >= 9) {
                $logs.append(`패배! 정답은 ${answer.join('')}`);
                setTimeout(() => {
                    location.reload();
                }, 3000);
                return;
            }
            let strike = 0;
            let ball = 0;

            answer.forEach((number, aIndex) => {
                const index = value.indexOf(String(number));
                if (index > -1) {
                    if (index === aIndex) {
                        strike += 1;
                    } else {
                        ball += 1;
                    }
                }
            })
            if (strike === 0 && ball === 0) {
                out++;
                $logs.append(`${value} : ${out}아웃 | ${strike} 스트라이크 ${ball} 볼`, document.createElement('br'));
            } else {
                $logs.append(`${value} : ${strike} 스트라이크 ${ball} 볼`, document.createElement('br'));
            }
            if (out === 3) {
                $logs.append(`${out} 아웃! 정답은 ${answer.join('')}`, document.createElement('br'));
                setTimeout(() => {
                    location.reload();
                }, 3000);
            }
            tries.push(value);
        })
    </script>
</body>

</html>

 

가위바위보

- 가위, 바위, 보가 있는 사진에서 그림이 초마다 바뀌고 [가위], [바위], [보] 버튼 클릭 시 1초 멈추고 그림이 계속 돌아감

- 그림이 계속 돌아감 = 특정 주기로 어떤 작업을 계속 수행(페이지 새로고침 하지 않고 계속 쌓임)

 

* [문제점] :  버튼을 클릭하면 할수록 그림이 더 빨리 돌아감

-> 1초 뒤 멈춤(clearInterval이나 clearTimeout 이용(setTime은 인수로 넣은 함수가 실행되기 전에 celarTimeout 호출할 것)

(출처 : https://thebook.io/080270/part02/ch07/04/

-> 왜 이런 현상 발생? : 버튼 클릭 시 각각의 setTimeout 타이머가 실행됨, 버튼을 누른 횟수만큼 setTimeout 타이머 실행

-> 각각 1초 뒤에 setInterval 수행 -> 그림이 돌아가는 속도가 점점 빨라짐

-> 해결책 : 함수가 아무 일도 하지 않게 함(clickable = false)

 

        let clickable = true;

        const clickButton = () => {
            if (clickable) {
                clearInterval(intervalId);
                clickable = false;
                // 점수 계산 및 화면 표시
                setTimeout(() => {
                    clickable = true;
                    intervalId = setInterval(changeComputerHand, 50);
                }, 1000);
            }
        };
        $rock.addEventListener('click', clickButton);
        $scissors.addEventListener('click', clickButton);
        $paper.addEventListener('click', clickButton);

 

*  ||로 사용된 코드는 includes로 변경 가능

(참고 : https://leffept.tistory.com/363)

 

[Javascript]if, else 문 최소화하기

Javascript를 이용하여 개발을 하다보면 if, else문이 많아짐에 따라 가독성을 상당히 해치는 코드를 종종 볼 수 있습니다. 특히나 프론트 UI에서 조건에 따라 렌더링 및 데이터를 보여주는 로직이 존

leffept.tistory.com

//bad 
function topgun1(member) {
	if(member === 'maverick' || member === 'rooster' .... ... ...) 
    {
    	console.log('탑건 1편 등장인물');
    }
}

//better
function topgun1(member) {
    const memberList = ['maverick', 'goose', 'iceman', 'slider'];
	if(memberList.includes(member) {
    	console.log('탑건 1편 등장인물);
     }
}

 

* 가위바위보 결과

더보기
<!DOCTYPE html>
<html lang="en">

<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>
<style>
    #computer {
        width: 142px;
        height: 200px;
    }
</style>

<body>
    <div id="computer"></div>
    <div>
        <button id="scissors" class="btn">가위</button>
        <button id="rock" class="btn">바위</button>
        <button id="paper" class="btn">보</button>
    </div>
    <div id="score">0</div>
    <script>
        const $computer = document.querySelector('#computer');
        const $score = document.querySelector("#score");
        const $scissors = document.querySelector("#scissors");
        const $rock = document.querySelector("#rock");
        const $paper = document.querySelector("#paper");
        const IMG_URL = './rsp.png';
        $computer.style.background = `url(${IMG_URL}) 0 0`;
        $computer.style.backgroundSize = `auto 200px`;
        let clickable = true;
        let count = 0;
        let myTotal = 0;
        let comTotal = 0;

        // 0 : 가위 -220px : 바위 -440px : 보
        const rspX = {
            scissors: '0',
            rock: '-220px',
            paper: '-440px'
        }

        const scoreTable = {
            rock: 0,
            scissors: 1,
            paper: -1
        }


        //가위 -> 보
        let computerChoice = 'scissors';
        const changeComputerHand = () => {
            if (computerChoice === 'rock') {
                computerChoice = 'scissors'
            } else if (computerChoice === 'scissors') {
                computerChoice = 'paper';
            } else if (computerChoice === 'paper') {
                computerChoice = 'rock';
            }
            $computer.style.background = `url(${IMG_URL}) ${rspX[computerChoice]} 0`;
            $computer.style.backgroundSize = `auto 200px`;
        }

        let intervalId = setInterval(changeComputerHand, 50);

        const clickButton = () => {
            if (clickable) {
                clearInterval(intervalId);
                clickable = false;
                const myChoice = event.target.textContent === '바위'
                    ? 'rock'
                    : event.target.textContent === '가위'
                        ? 'scissors'
                        : 'paper';

                const myScore = scoreTable[myChoice];
                const computerScore = scoreTable[computerChoice];
                const diff = myScore - computerScore;
                let message;
                if ([2, -1].includes(diff)) {
                    // console.log('나의 승리!');
                    // score += 1;
                    myTotal += 1;
                    count += 1;
                    message = '나의 승리';
                } else if ([-2, 1].includes(diff)) {
                    // console.log('컴퓨터의 승리!')
                    comTotal += 1;
                    count += 1;
                    message = '컴퓨터의 승리!';
                } else {
                    console.log('무승부!');
                    count += 1;
                    message = '무승부';
                }


                if (myTotal === 3) {
                    $score.textContent = `${message} 나의 승리! 총 ${myTotal}점`;
                } else if (comTotal === 3) {
                    $score.textContent = `${message} 컴퓨터의 승리! 총 ${comTotal}점`;
                } else {
                    $score.textContent = `${message} ${myTotal} vs ${comTotal}`;
                    // 점수 계산 및 화면 표시
                    setTimeout(() => {
                        clickable = true;
                        intervalId = setInterval(changeComputerHand, 50);
                    }, 1000);
                }

            }
        };
        $rock.addEventListener('click', clickButton);
        $scissors.addEventListener('click', clickButton);
        $paper.addEventListener('click', clickButton);
    </script>
</body>

</html>