나는 일단 숫자야구가 뭔지 몰라서 룰을 좀 배워왔다.
일단 4자리수의 랜덤한 숫자를 만들어 제공하면 그 숫자를 맞추는 게임인데, 만약에 3456이라는 숫자가 있는데 사용자가 3546이런식으로 적었다면 순서와 숫자가 모두 맞으면 : 스트라이크 / 자리는 틀렸지만 숫자가 포함 : 볼
➡️ 2스트라이크 2볼인셈이다 🧢 이 힌트를 조합해서 숫자를 맞추는 게임❗
이제 좀 내가 구현 할 내용을 토대로 구체적으로 적어보았다.
const $userInput = document.querySelector("#userInput");
const $submitBtn = document.querySelector("#submitBtn");
const $resetBtn = document.querySelector("#resetBtn");
const $prevNum = document.querySelector("#prevNum");
const $result = document.querySelector("#result");
const $attempts = document.querySelector("#attempts");
let secretNum = [];
let attemptsLeft = 10;
// 정답 생성 (중복 없는 4자리 숫자)
function makeRandomNum() {
secretNum = [];
while (secretNum.length < 4) {
const rand = Math.floor(Math.random() * 10);
if (!secretNum.includes(rand)) {
secretNum.push(rand);
}
}
}
makeRandomNum();
console.log(secretNum); // 테스트용 정답 출력
💡
우선 필요한 변수들을 전부 선언해주고,
정답으로 들어갈 secretNum
을 빈 배열로 선언해주었다.
그리고 while
문을 사용해서 길이를 0 1 2 3 (4자리) 돌게끔!
Math.floor(Math.random()*10)
을 통해서 0~9자리 수를 만들어주었다
(이건 정말 색깔 플립퍼 만들때 정말 많이해서 쉬웠다.)
정답 숫자에 랜덤으로 만든 숫자가 포함되어있지 않으면 랜덤숫자를 push
(중복 숫자 없는 네자리 숫자를 만들기 위해서!)
function calculateResult(input) {
let strike = 0;
let ball = 0;
const inputArr = input.split("").map(Number);
inputArr.forEach((num, index) => {
if (num === secretNum[index]) {
strike++;
} else if (secretNum.includes(num)) {
ball++;
}
});
return { strike, ball };
}
💡
사실 이 부분 구현이 순서도를 그릴때 가장 어렵지 않을까? 했는데 쉽다!
split
을 통해서 ''단위로 잘라주고,map
을 통해서 숫자 배열로 만들어주었다.forEach
를 통해서 숫자와 인덱스를 매개 변수로 받고,function submitInput() {
if (attemptsLeft <= 0) {
$result.textContent = "기회를 모두 사용하셨습니다. 게임이 종료됩니다.";
return;
}
const userInput = $userInput.value;
if (userInput.length !== 4 || isNaN(userInput)) {
$result.textContent = "숫자 4자리를 입력해주세요 😢";
return;
}
const { strike, ball } = calculateResult(userInput);
attemptsLeft--;
$attempts.textContent = `남은 기회 : ${attemptsLeft}`;
if (strike === 4) {
$result.textContent = "정답을 맞추셨습니다. 축하드립니다 🥳";
$submitBtn.style.display = "none";
$resetBtn.style.display = "inline-block";
$userInput.disabled = true;
} else if (attemptsLeft > 0) {
$prevNum.innerHTML += `<p>${userInput} - Strike: ${strike}, Ball: ${ball}</p>`;
$result.textContent = "아쉽지만 다시 시도해보세요!";
} else {
$result.textContent = `기회를 모두 사용했습니다. 정답은 ${secretNum.join("")}였습니다. 😢`;
$submitBtn.style.display = "none";
$resetBtn.style.display = "inline-block";
$userInput.disabled = true;
}
$userInput.value = ""; // 입력 필드 초기화
}
// 이벤트 리스너
$submitBtn.addEventListener("click", submitInput);
$userInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
submitInput();
}
});
// 초기 기회 표시
$attempts.textContent = `남은 기회 : ${attemptsLeft}`;
💡
이 부분은 어제 딥 다이브 DOM을 공부해서 그런지 어렵지 않았다.
attemptsLeft--;
, 남은 횟수 알림function resetGame() {
attemptsLeft = 10;
makeRandomNum();
$userInput.value = "";
$prevNum.innerHTML = "";
$result.textContent = "";
$attempts.textContent = `남은 기회 : ${attemptsLeft}`;
$submitBtn.style.display = "inline-block";
$resetBtn.style.display = "none";
$userInput.disabled = false;
console.log(secretNum); // 테스트용 정답 출력
}
$resetBtn.addEventListener("click", resetGame);
💡
모든 부분을 다 초기화 시켜준다고 생각하면 된다.
그걸 새게임 버튼에 적용 시켜주면 끝
완성본