자바스크립트 과제로 많이 하는 숫자야구 진행해봤다.
html, css 는 코드가 너무 길어서 일단 생략하기루~~
코드를 작성하고 하나하나 뜯다보니 주석이 굉장히 많은데
깃허브에 올릴땐 주석을 삭제하고 올릴것~~!
[ 숫자야구 순서도 ]
1. 무작위의 숫자 4개를 랜덤으로 선정한다. (numbers)
2. 참여자는 숫자 4개를 랜덤으로 입력한다. (answer)
3. 입력받은 숫자가 오류가 없는지 검증한다.
- 4개의 숫자가 맞는지? (길이 4)
- 중복된 숫자가 없는지? (1233불가능)
- 이미 시도한 값은 아닌지? (1234 입력 후 재 입력 불가능)
4. 선정된 4개의 값과 입력된 4개의 값이 맞으면 " 홈런 "
5. 10회 이상 입력시 실패 메세지와 함께 답 공개
=> 여기까지 구현완료
6. 4개의 값 중 몇개가 맞았는지 힌트 제공 ( 1 볼, 1 스트라이크 )
=> 6번은 내일 구현 예정
====> 2차 구현 목표
7. 다시하기 누르면 초기화
8. 홈런 popup 으로 띄워보기..?
[ 숫자야구 규칙 ]
정답 예시 : 1234
참여자 예시 : 1356
1. 참여자는 중복되지않은 네개의 숫자를 콤마 없이 입력한다.
2. 자릿수와 값이 같을 경우 스트라이크
3. 자릿수는 다르지만 값이 있을경우 볼
ex) 1234 -> 1356 : 1스트라이크 (숫자,자리 1), 1볼 (숫자 3)
4. 네자리 모두 틀리면 아웃
ex) 1234 -> 5678 일때, 0스트라이크 0볼이 아닌 아웃
5. 쓰리아웃되면 패배
6. 10회 이상 시도하면 패배
7. 자릿수와 숫자 모두 같을 경우 홈런
[ 예시 ]
- 콘솔에 찍힌 랜덤한 4개의 숫자값 ( 1452 )
- 스트라이크, 볼 예시 (1스트라이크, 1볼)
자릿수와 값이 같을 경우 스트라이크, 자릿수는 다르지만 값이 있을경우 볼
- 아웃 예시
원아웃, 투아웃 표시, 쓰리아웃시에는 패배
- 홈런
[ JS ]
const $input = document.querySelector("#input");
const $form = document.querySelector("#form");
const $numResult = document.querySelector("#numResult");
const numbers = []; // 숫자를 담을 배열 생성
for (let n = 0; n < 9; n += 1) {
// 보통 0부터 시작이기때문에 n+1;
numbers.push(n + 1); //배열에 push 로 넣어줌
}
const answer = []; //뽑을 숫자 담을 배열 생성
// 네 번 반복
for (let n = 0; n < 4; n += 1) {
const index = Math.floor(Math.random() * (numbers.length - n)); //0~8까지
answer.push(numbers[index]);
numbers.splice(index, 1); //numbers에서 splice 로 지워줌
// index => 랜덤 뽑기로 나온 숫자, 1 => 배열에서 하나 지움
// -> 이값은 answer에 들어간다.
// 뽑다보면 numbers에서 숫자가 뽑혀나오기때문에 undefined가 나올수도 있음.
// Math.floor(Math.random() * 9) -> 변경 Math.floor(Math.random() * (9 - n))
// -> 반복문이 줄때마다 9에서 n을 하나씩 빼주면 undefined가 나오지 않음..
// -> 9 - n 을 수시로 바꿔줄 수 없으니 length를 이용하자 (numbers.length - n)
}
console.log(answer);
const tries = [];
// 검사하는 코드
// 순서 (2) 밑에 tries 배열에 input submit된 값을 여기서 검증
function checkInput(input) {
// 길이는 4가 아닌가?
if (input.length !== 4) {
// 4가 아니라면 alert
return alert("숫자 4개를 입력해주세요.");
}
// 중복된 숫자가 있는가?
if (new Set(input).size !== 4) {
// 중복되었다면 alert
return alert("중복된 숫자입니다. 다시 입력하세요.");
}
// 이미 시도한 값인가?
if (tries.includes(input)) {
// inclues -> 배열에 tries 값이 들어있는가?
//이미 시도되었다면 alert
return alert("이미 시도한 값입니다. ");
}
return true;
//if문 다 돌고 true 면 맞는 값 반환
}
//out 변수
let out = 0;
// form 저장
// 순서 (1)
$form.addEventListener("submit", (e) => {
//event e 매개변수로 사용
// 기본동작 막기
e.preventDefault();
const value = $input.value; // 사용자가 입력한 숫자를 변수(value)에 저장한 다음에
$input.value = ""; // 글자를 지워준다.
if (!checkInput(value)) {
return;
}
// checkInput (검사) 함수에서 value를 보내줌
// 입력값에 문제가 없음
if (answer.join("") === value) {
// join("") -> 배열의 원소를 ""를 제거하고, 문자열로 합치기 / [3,1,4,6] ->3146
$numResult.textContent = "홈런~! 정답입니다!!";
return;
}
if (tries.length >= 9) {
// 10번이상 시도했을때도 못맞추면
const msg = document.createTextNode(`패배! 정답은 ${answer.join("")}`);
$numResult.appendChild(msg);
return;
}
// 몇 스트라이크 몇 볼인지 검사
// answer: 3146, value(사용자입력): 1234
let strike = 0; // 변수 만들어서 count
let ball = 0;
// value에 answer i 값이 있나 확인 (3 있음)
for (let i = 0; i < answer.length; i++) {
const index = value.indexOf(answer[i]);
// 3의 index는 (012->2임)
if (index > -1) {
// 해당값을 찾지 못하면 index는 -1이 됨, 찾으면 0 이상이 나옴
//일치하는 숫자 확인
if (index === i) {
//숫자와 자릿수 모두 같음
strike += 1;
} else {
//숫자만 같음
ball += 1;
}
}
}
if (strike === 0 && ball === 0) {
out++;
$numResult.append(`${value} : 아웃`, document.createElement("br"));
} else {
$numResult.append(
`${value}: ${strike} 스트라이크, ${ball} 볼`,
document.createElement("br")
);
}
if (out === 1) {
$numResult.append(`원 아웃~!`, document.createElement("br"));
}
if (out === 2) {
$numResult.append(`투 아웃~!`, document.createElement("br"));
}
if (out === 3) {
const msg = document.createTextNode(
`쓰리아웃으로 패배입니다! 정답은 ${answer.join("")}`
);
$numResult.appendChild(msg);
}
return;
tries.push(value);
console.log("submit", e);
});
'공부 > javascript' 카테고리의 다른 글
2022.06.17 - weatherAPI 사용해보기 (0) | 2022.06.17 |
---|---|
2022.06.16 - (6/17완성) 노마드코더 크롬 앱 만들기 정리 (0) | 2022.06.16 |
2022.06.07 - javascript 호이스팅 / var, let 의 차이 (0) | 2022.06.07 |
2022.06.05 - (+ 수정완료 ) javascript 계산기 만들기 (0) | 2022.06.05 |
2022.05.27(금) - javascript Scope, hoisting (0) | 2022.05.27 |