들어가며
항해 본 과정 첫 주([chapter1]) 동안 자바스크립트 강의 5주차 분량과
주차 별 팀 과제인 '숫자야구 프로그램' 을 팀원 두 분과 함께 진행했습니다.
이번에는 만들고자 하는 프로젝트에 규칙과 기준이 잡혀 있어 이전에 진행했던 '미니 프로젝트'보단
구현하고자 하는 데에 목표가 있어 방향을 잡는 데에 덜 헤맸던 것 같습니다.
https://mimi-kkokko.notion.site/16-1-a47b70fbe8d54d5d8fafc221a53bfc7a
[항해 16기] 1주차 팀과제 - 숫자 야구 게임
📸 팀과제 실행 사진
mimi-kkokko.notion.site
https://github.com/yngjnhyk/baseball_game/tree/main
GitHub - yngjnhyk/baseball_game
Contribute to yngjnhyk/baseball_game development by creating an account on GitHub.
github.com
프로젝트 info
숫자야구 프로그램의 동작 순서는 다음과 같습니다.
- 브라우저가 렌더링되면, 컴퓨터는 정답이 될 랜덤한 숫자 3개를 뽑아 변수에 담습니다. (ex) 123, 759
- 사용자는 컴퓨터가 뽑은 숫자를 맞추기 위해 시도합니다.
- 컴퓨터는 사용자가 입력한 세자리 숫자에 대해서, 아래의 규칙대로 스트라이크(S)와 볼(B)를 알려줍니다.
- 숫자의 값과 위치가 모두 일치하면 S,
- 숫자의 값은 일치하지만 위치가 틀렸으면 B
4. 기회는 무제한이며, 몇번의 시도 후에 맞췄는지 기록됩니다. 5. 숫자 3개를 모두 맞춘 경우, 게임을 종료합니다.
1. 랜덤 숫자 3개 뽑기
랜덤 숫자 기능은 Math.floor 와 Math.random 이라는 자바스크립트 내장 객체 메서드를 활용해 0 부터 9 까지의 랜덤한 숫를 index 라는 변수로 선언하고, if 문을 통해 해당 숫자가 배열에 없는 경우, 배열에 숫자를 넣는 것으로 숫자들의 중복을 막았습니다.
let pick = [];
while (pick.length < 3) {
const index = Math.floor(Math.random() * 10);
if (!pick.includes(index)) {
pick.push(index);
}
}
const answer = pick.join("");
console.log(answer);
2, 3, 4 입력한 값에 대한 ball / strike 검사 후 렌더링
아래에 보이는 코드 중 ballStrikeCheck() 라는 함수를 통해 입력한 값에 대한 검사를 진행했는데요.
ball / strike 검사가 아닌, 팀원들과 고민해 추가로 만들어 본 입력한 값에 대한 몇 가지 검사 또한 진행되었습니다. 추가한 기능들은 아래와 같은데요.
- 세 자리 숫자 판별 기능
- 숫자 판별 기능(텍스트, 특수문자 X)
- 숫자 3개 중 중복된 숫자 판별 기능
- 앞에서 시도한 값인지 판별 기능
중요한 ball / strike 검사 기능에 대해서만 간략하게 말씀드리면, 반복문으로 정답인 3자리 숫자를 하나씩 반복하면서 indexOf 매서드를 활용해 해당 숫자가 입력한 값에 몇 번째 인덱스에 있는지 검사하고, 있다면 인덱스 값을, 없다면, -1 을 반환합니다. 이 때, 다시 한번 조건문을 활용해 인덱스 값을 얻었다면, 해당 인덱스가 지금 반복문을 돌고 있는 인덱스와 같다면, strike 에 1을 더하고, 그렇지 않다면, ball 에 1을 더합니다.
함수를 통해 검사를 마친 입력한 값에 대한 결과 strike 와 ball 을 appendChild 를 통해 실행할 때마다 결과가 아래에 쌓이게 했습니다.
// 한 자리 숫자에 대한 볼, 스트라이크 판단하기.
let attemp = 0;
const button = document.querySelector("button");
const record = document.getElementById("record");
const input = document.querySelector("input");
const tries = []; // 시도했던 값
function ballStrikeCheck() {
const value = $("#input").val(); // 유저가 입력한 값
if (value.length !== 3) {
input.classList.add("redBorder");
alert("세자리 숫자를 입력해주세요");
return;
}
if (!Number(value)) {
input.classList.add("redBorder");
alert("숫자만 입력해주세요");
return;
}
// 중복된 숫자가 있는가
if (new Set(value).size != 3) {
input.classList.add("redBorder");
alert("중복되지 않게 입력해 주세요.");
return;
}
// 이미 시도한 값은 아닌가
if (tries.includes(value)) {
input.classList.add("redBorder");
alert("이미 시도한 값입니다.");
return;
}
//input 테두리 원상복구
input.classList.remove("redBorder");
attemp++; // 시도 횟수
// 스트라이크, 볼 검사
let strike = 0;
let ball = 0;
for (let i = 0; i < answer.length; i++) {
const index = value.indexOf(answer[i]); // answer 가 345 이면, answer[0] = 3 / value.indexOf(3) / value 123.indexOf(3) => 2
if (index > -1) {
// 일치하는 숫자 발견
if (index === i) {
strike += 1;
} else {
// 숫자만 같다면
ball += 1;
}
}
}
const div = document.createElement("div");
div.textContent = `${attemp}번째 시도 : ${value} ${ball}B${strike}S`;
record.appendChild(div);
5. 숫자 3개를 모두 맞힌 경우, 게임 종료
strike 가 3개인 경우가 곧 입력한 값과 정답이 일치한 경우로, 시도한 횟수와 정답이 된 결과를 localStorage 에 저장하고, 게임 종료 메시지를 렌더링한 뒤, 결과 페이지로 이동합니다.
if (strike === 3) {
localStorage.setItem("attemp", attemp);
localStorage.setItem("result", answer);
const div = document.createElement("div");
div.textContent = `${attemp}번만에 맞히셨습니다. 게임을 종료합니다.`;
record.append(div);
setTimeout(function () {
window.location.href = "congrats.html";
}, 1000);
return;
}
이동한 페이지에서 localStorage 에 담긴 시도한 횟수와 정답 결과를 불러와 화면에 렌더링합니다.
<script>
const attemp = localStorage.getItem("attemp");
console.log(attemp);
const countSpan = document.getElementById("count");
countSpan.innerHTML = attemp;
document.getElementById("result").innerHTML =
localStorage.getItem("result");
</script>
'항해 16기 > Week I Learned' 카테고리의 다른 글
[항해 70일차] WIL_translate 를 이용한 Carousel(캐러셀) 구현 (0) | 2023.10.25 |
---|---|
[항해 63일차] WIL_React-Query 에 대해 온전한 이해 (0) | 2023.10.15 |
[항해 28일차] WIL_React 심화주차: 모달, 버튼을 포함한 웹 페이지 (0) | 2023.09.07 |
[항해 21일차] WIL_Lv.2 redux_todolist (0) | 2023.09.03 |
[항해 -1일차] WIL_1 사전 스터디(css 기초), mini 프로젝트 (0) | 2023.08.13 |