반복문 사용하기 - 숫자야구
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);