Small Grey Outline Pointer [레츠기릿] 숫자야구 게임 만들기 (반복문 사용하기)
본문 바로가기
Dev./JavaScript

[레츠기릿] 숫자야구 게임 만들기 (반복문 사용하기)

by sso. 2023. 5. 14.

숫자야구 룰 

https://thebook.io/080270/0265/

 

Let's Get IT 자바스크립트 프로그래밍: 5장 반복문 사용하기_숫자야구 게임

더북(TheBook): (주)도서출판 길벗에서 제공하는 IT 도서 열람 서비스입니다.

thebook.io

 

 

 

 


무작위 숫자를 뽑는 과정

Math.random()을 사용하여 랜덤으로 4개의 숫자를 추출한다

 

 Math.floor 내림

 Math.ceil 올림

 Math.round 반올림

Math.random()		// 0<= x < 1
Math.random() * 9	// 0<= x < 9
Math.random() * 9 + 1 // 1<= x <10

Math.random() 를 출력하면 0 이상 1미만의 숫자가 나온다

 

 

1~9까지의 자연수만 원한다면 

1 <= Math.random() * 9 + 1 < 10

Math.floor(Math.random() * 9 + 1)

이렇게 표현할 수 있다

그 후 floor를 사용하여 소수점 아래는 다 버려준다(정수로 만들기) 

 

하지만 Math.random()은 진짜 무작위가 아니라는 점

암호화적으로 완전한 무작위가 아니다. 따라서 보안과 관련된 작업을 할 때는 위험하다

이를 위한 window.crypto.getRandowValues() 함수가 따로 존재한다

 

 


배열을 사용할지, 객체를 사용할 지 어떻게 판단하는가?

 

배열 : 단순히 값들만 모아놓을 거라면 배열을 사용

객체 : 각각의 값에 속성이름을 붙여 값들을 구분하고 싶다면 객체리터럴 사용

 

 

const numbers = [];
for(let n=0; n<9; n+=1){
    numbers.push(n+1);
}

const answer = [];
for(let n =0; n<=3; n+=1) { //네번 반복
    //numbers.length : 숫자를 뽑고 난 후에 numbers의 길이는 하나씩 줄어들기 때문에 그만큼만 곱해줘야 한다
    const index = Math.floor(Math.random()*(numbers.length)); // numbers길이에 따라
    answer.push(numbers[index]);
    numbers.splice(index, 1);
}
console.log(answer);

undefined가 섞여나오는 것을 방지하기 위해 

Math.floor(Math.random()*9) 가 아니라
Math.floor(Math.random()*(numbers.length)) 로 수정 해줌

 

 

 


 

 

 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;

}

 

 

new Set 중복을 허용하지 않는 특수한 배열

Set 객체는 중복되지 않는 유일한 값들의 집합. 배열의 중복을 제거한다

length가 아닌 size를 사용한다

 

 

인풋값 검사 함수를 리턴 받아 if의 조건문으로 넣어준다

//인풋값 검사 함수 실행
if(checkInput(value)){
    //입력값 문제 없음
}else{
    //입력값 문제 있음
}

 

 

if의 중첩을 없애는 작업을 해준다

 

$form.addEventListener('submit', ()=>{
    event.preventDefault(); //기본 동작 막기
    const value = $input.value;
    $input.value = ''; //입력값 비워주기
    const valid = checkInput(value);

    //입력값 문제 있음
    if(!valid) return;

    //입력값 문제 없음
    if(answer.join('') === value){
        $logs.textContent = '홈런!';
        return;
    }
    if(tries.length >= 9){
        const message = document.createTextNode(`패배! 정답은 ${answer.join('')}`);
        $logs.appendChild(message);
        return;
    }
});

 

 

 

 

Array.join()

배열의 모든 요소를 연결해 하나의 문자열로 만든다

arr.join([구분자])

const arr = ['사과', '바나나', '딸기'];

console.log(arr.join());
// 사과,바나나,딸기

console.log(arr.join(''));
// 사과바나나딸기

console.log(arr.join(':'));
// 사과:바나나:딸기

'3146'.split() //["3146"]
'3146'.split('') // ["3", "1", "4", "6"]
'3146'.split('1') // ["3", "46"] 1을 기준으로 나뉘게 된다

 

 


자바스크립트 이용하여 요소 추가하기

 

createElement()

createTextNode()

appendChild()

 

.createElement('h1') // <h1></h1>

createTextNode('text') //text라는 문자열 생성

appendChild() // 선택한 요소 안에 자식 요소를 추가한다

 

 

 


 

 

몇 볼 몇 스트라이크인지 계산하기

 

 

 

 

append() : 텍스트와 태그를 동시에 여러개 추가 가능 return값 반환X

appendChild() : 하나의 텍스트나 하나의 태그만 추가 가능

두 메서드 모두 부모에 자식노드를 추가하는 메서드

 

//몇 스트라이크 , 몇 볼인지 체크 
let strike = 0;
let ball = 0;
for(let i =0; i<answer.length; i++){
    const index = value.indexOf(answer[i]); //indexOf : 특정문자의 위치 찾기
    if(index > -1){ //일치하는 숫자 발견
        if(index === i){ //자릿수도 일치 
            strike += 1;
        }else{//숫자만 같음
            ball += 1; 
        }
    }
}
$logs.append(`${value} : ${strike} 스트라이크 ${ball}볼`, document.createElement('br'));
tries.push(value); //값을 기록하면서 몇번 시도했는지 체크

 

 

indexOf 와 includes

 

indexOf / includes는 배열이나 문자열에 원하는 값이 들어있는지 찾는 메서드

indexOf : 원하는 값이 들어있다면 해당 인덱스를 알려주고, 아니라면 -1 반환

includes : true / false로 반환

 

'2345'.indexOf(3) === 1;
'2345'.indexOf(6) === -1;
['2', '3', '4', '5'].indexOf('5') === 3;
['2', '3', '4', '5'].indexOf(5) === -1; // 요소의 자료형까지 같아야 함
'2345'.includes(3) === true;
['2', '3', '4', '5'].includes(5) === false;

 

 

 

forEach와 map

for문을 forEach로 바꿔보기

//몇 스트라이크 , 몇 볼인지 체크 
let strike = 0;
let ball = 0;
// 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; 
//         }
//     }
// }
answer.forEach((number, aIndex)=>{
    const index = value.indexOf(String(number));
    if(index > -1){
        if(index === aIndex){
            strike += 1;
        }else{
            ball += 1;
        }
    }
});

 

answer 배열에 있는 요소를 forEach로 순회한다

forEach는 인수로 함수를 받고, 배열 요소 하나하나에 인수로 받은 함수를 각각 적용한다

이때 요소 순서대로 함수를 적용, 반복문처럼 돌게 된다

 

 

 

 


const numbers = [];
for (let n = 1; n <= 9; n += 1) {
  numbers.push(n);
}

//for문 바꿔보기
const numbers = Array(9).fill().map((v, i) => i + 1);

Array(9) : 길이가 9인 배열을 만든다

fill() : 배열 요소를 채워넣는다 지금은 () 비어있어서 undefined로 채워짐

map() : 요소들을 일대일로 짝지어서 다른 값으로 변환하는 메서드 (리턴값에 따라 새로운 요소를 반환 함)

단, 기존 배열의 값이 바뀌는 것이 아니라 새로운 배열을 만든다

 

배열의 메서드

const array = [1, 3, 5, 7];
const newArray = array.map((number, index) => {
  console.log(number, index);
  return number + 1;
});
console.log(array); // [1, 3, 5, 7]
console.log(newArray); // [2, 4, 6, 8]

 

 

1분 퀴즈

forEach를 for문으로 바꿔보기

//forEach문
const array = [1, 3, 5, 7]; 
array.forEach((number, index) => { 
  console.log(number, index); 
});

 

//for문
const array = [1,3,5,7];
for(let i=0; i<array.length; i++){
    console.log(array[i],i);
}

 

 


 

out 추가하기

 

 if (strike === 0 && ball === 0) {
    out++;
    $logs.append(`${value}:아웃`, document.createElement(‘br’));
  } else {
    $logs.append(`${value}:${strike} 스트라이크 ${ball} 볼`, document.createElement(‘br’));
  }
  if (out === 3) {
    const message = document.createTextNode(`패배! 정답은 ${answer.join(‘’)}`);
    $logs.appendChild(message);
    return;
  }
  tries.push(value);
728x90

댓글