From 6f2584737490c8e082aa8c33be8fbafc3badd597 Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:29:16 +0900 Subject: [PATCH 1/9] =?UTF-8?q?UI:=20=EC=A0=84=EC=B2=B4=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 ++++++++- index.html | 43 +++++++++++++++++++++++------- src/main.js | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8b2833c..0d020fd 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ -# javascript-baseball-precourse \ No newline at end of file +# javascript-baseball-precourse + +## 기능 목록 +1. UI +2. feat/handleSubmit +#### submit and getValue +3. feat/setAnswer +#### set the random answer +4. feat/compAnswer +#### user가 제출한 답이 맞는지 비교한다 +5. feat/retAnswer +#### 답을 element로 return한다 \ No newline at end of file diff --git a/index.html b/index.html index b021b5c..44e22a4 100644 --- a/index.html +++ b/index.html @@ -1,12 +1,35 @@ - + - - - - - - -
- - + + + + + 숫자 야구 게임 + + + + +
+

⚾숫자 야구 게임

+

1~9까지의 수를 중복없이 3개 입력해주세요

+

올바른 예) 139

+

틀린 예) 122

+
+ + +
+

결과

+
+
+
+
+ + +
+
+
+
+ + + diff --git a/src/main.js b/src/main.js index e69de29..238ad79 100644 --- a/src/main.js +++ b/src/main.js @@ -0,0 +1,77 @@ +const inputEl = document.querySelector('input'); +let ansEl = document.querySelector('.ansEl'); + +let answer; +setAns(); + +//랜덤3개 set +//1. 랜덤돌려서 문자열 + (스트링처리) +//2. if 이미 있는 숫자면 다시 랜덤 +function setAns() { + answer = ''; + while (answer.length < 3) { + let num = Math.floor(Math.random() * 9) + 1; + if (!answer.includes(num)) { + answer += num; + } + } + console.log(answer); +} + +function onlyNumber(event) { + const key = event.key; + // 입력된 키가 숫자인지 또는 백스페이스(Backspace) 키인지 확인 + if (/\d/.test(key) || key === 'Backspace') { + return true; // 숫자거나 백스페이스면 허용 + } else { + event.preventDefault(); // 숫자가 아니면 입력 방지 + return false; + } +} + +const handleOnInput = () => { + // 중복확인 + const value = inputEl.value; + const idx = value.length - 1; + if (idx > 0 && value[idx - 1] == value[idx]) { + inputEl.value = value.slice(0, idx); + alert('중복 숫자는 허용되지 않습니다.'); + } +} + +//compare +//1. 존재하는지 확인 (ball) +//1-1. cnt++ & 위치확인 (strike) +//1-2. 존재하지 않으면 낫싱 +const compareValue = (e) => { + e.preventDefault(); + + let strikes = 0, balls = 0; + for (let i = 0; i < 3; i++) { + if (inputEl.value[i] === answer[i]) { + strikes++; + } else if (answer.includes(inputEl.value[i])) { + balls++; + } + } + + //return element + if (strikes === 3) { + ansEl.innerHTML = '정답을 맞추셨습니다!
게임을 새로 시작하시겠습니까?
'; + const resetBtn = document.createElement('button'); + resetBtn.innerText = '게임 재시작'; + resetBtn.setAttribute('onclick', 'resetValue()'); + resetBtn.classList.add('resetBtn'); + ansEl.appendChild(resetBtn); + } else if (strikes === 0 && balls === 0) { + ansEl.textContent = '낫싱'; + } else { + ansEl.textContent = `${strikes} 스트라이크, ${balls} 볼`; + } +} + +//reset +const resetValue = () => { + inputEl.value = ''; + ansEl.innerHTML = ''; +} From 2b7e99503806468fd46975a7831435c354aae9a5 Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:34:00 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EC=88=AB=EC=9E=90=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EB=B0=9B=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/HandleInput.js | 16 ++++++++++++++++ src/modules/OnlyNumber.js | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/modules/HandleInput.js create mode 100644 src/modules/OnlyNumber.js diff --git a/src/modules/HandleInput.js b/src/modules/HandleInput.js new file mode 100644 index 0000000..e0b9f68 --- /dev/null +++ b/src/modules/HandleInput.js @@ -0,0 +1,16 @@ +import { CompareValue } from "./CompareValue.js"; + +export const HandleInput = (e) => { + e.preventDefault(); + const inputEl = document.querySelector("input"); + const contents = document.getElementById("contents"); + + if (inputEl.value.length < 3) { + alert("3글자 이상 입력해주세요."); + return; + } + + contents.setAttribute("class", ""); + + CompareValue(); +}; diff --git a/src/modules/OnlyNumber.js b/src/modules/OnlyNumber.js new file mode 100644 index 0000000..3e3f263 --- /dev/null +++ b/src/modules/OnlyNumber.js @@ -0,0 +1,21 @@ +export const OnlyNumber = (event) => { + const key = event.key; + + // 입력된 키가 숫자인지, 백스페이스 또는 엔터인지 확인합니다. + if (/\d/.test(key) || key === "Backspace" || key === "Enter") { + const inputEl = document.querySelector("input"); + const value = inputEl.value; + + // 현재 입력된 값과 이전 값이 같으면 입력을 막고 경고창을 표시합니다. + if (value.length > 0 && value[value.length - 1] === key) { + event.preventDefault(); + alert("중복된 값을 입력할 수 없습니다."); + return false; + } + return true; + } else { + event.preventDefault(); + alert("숫자만 입력 가능합니다."); + return false; + } +}; From 3f71d05c5c95cbb7ba5b6fe5d761850d9ceae32e Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:35:35 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=A7=84?= =?UTF-8?q?=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/CompareValue.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/modules/CompareValue.js diff --git a/src/modules/CompareValue.js b/src/modules/CompareValue.js new file mode 100644 index 0000000..d05be9f --- /dev/null +++ b/src/modules/CompareValue.js @@ -0,0 +1,18 @@ +import { ShowResult } from "./ShowResult.js"; +import { answer } from "./SetAnswer.js"; + +export const CompareValue = () => { + const inputEl = document.querySelector("input"); + + let strikes = 0; + let balls = 0; + for (let i = 0; i < 3; i++) { + if (inputEl.value[i] === answer[i]) { + strikes++; + } else if (answer.includes(inputEl.value[i])) { + balls++; + } + } + + ShowResult(strikes, balls); +}; From 3f6bf22bae867dcb5ef8708da7327b9ac5432f94 Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:37:02 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20=EC=A0=95=EB=8B=B5=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/SetAnswer.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/modules/SetAnswer.js diff --git a/src/modules/SetAnswer.js b/src/modules/SetAnswer.js new file mode 100644 index 0000000..3c07dc1 --- /dev/null +++ b/src/modules/SetAnswer.js @@ -0,0 +1,14 @@ +let answer; + +export const SetAnswer = () => { + answer = ""; + while (answer.length < 3) { + let num = Math.floor(Math.random() * 9) + 1; + if (!answer.includes(num.toString())) { + answer += num.toString(); + } + } + console.log(answer); +}; + +export { answer }; From 0b2161adf5abd7cc654b8b70485bef6d457dfde7 Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:37:24 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/ShowResult.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/modules/ShowResult.js diff --git a/src/modules/ShowResult.js b/src/modules/ShowResult.js new file mode 100644 index 0000000..fbdffc4 --- /dev/null +++ b/src/modules/ShowResult.js @@ -0,0 +1,12 @@ +export const ShowResult = (strikes, balls) => { + const ansEl = document.getElementById("ansEl"); + + if (strikes === 3) { + ansEl.innerHTML = + "🎉정답을 맞추셨습니다!🎉
게임을 새로 시작하시겠습니까?
"; + } else if (strikes === 0 && balls === 0) { + ansEl.innerText = "낫싱"; + } else { + ansEl.innerText = `${strikes} 스트라이크, ${balls} 볼`; + } +}; From 823bff7a7d1fa172f452c4b794dd65219f391d47 Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:37:50 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20=EC=B4=88=EA=B8=B0=ED=99=94=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B2=8C=EC=9E=84=20=EC=A2=85=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/EndGame.js | 4 ++++ src/modules/ResetValues.js | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 src/modules/EndGame.js create mode 100644 src/modules/ResetValues.js diff --git a/src/modules/EndGame.js b/src/modules/EndGame.js new file mode 100644 index 0000000..3b32e26 --- /dev/null +++ b/src/modules/EndGame.js @@ -0,0 +1,4 @@ +export const EndGame = () => { + const app = document.getElementById("app"); + app.innerHTML = "

게임이 종료되었습니다.

"; +}; diff --git a/src/modules/ResetValues.js b/src/modules/ResetValues.js new file mode 100644 index 0000000..d011a63 --- /dev/null +++ b/src/modules/ResetValues.js @@ -0,0 +1,8 @@ +export const ResetValues = () => { + const inputEl = document.querySelector("input"); + const ansEl = document.getElementById("ansEl"); + inputEl.value = ""; + ansEl.innerText = ""; + + location.reload(); +}; From 444edf8bb66bc37ab4957474f9f6107562914f45 Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:38:10 +0900 Subject: [PATCH 7/9] feat: main.js --- src/main.js | 85 +++++++---------------------------------------------- 1 file changed, 11 insertions(+), 74 deletions(-) diff --git a/src/main.js b/src/main.js index 238ad79..718e8b3 100644 --- a/src/main.js +++ b/src/main.js @@ -1,77 +1,14 @@ -const inputEl = document.querySelector('input'); -let ansEl = document.querySelector('.ansEl'); +import { HandleInput } from "./modules/HandleInput.js"; +import { SetAnswer } from "./modules/SetAnswer.js"; +import { OnlyNumber } from "./modules/OnlyNumber.js"; +import { ResetValues } from "./modules/ResetValues.js"; +import { EndGame } from "./modules/EndGame.js"; -let answer; -setAns(); +SetAnswer(); -//랜덤3개 set -//1. 랜덤돌려서 문자열 + (스트링처리) -//2. if 이미 있는 숫자면 다시 랜덤 -function setAns() { - answer = ''; - while (answer.length < 3) { - let num = Math.floor(Math.random() * 9) + 1; - if (!answer.includes(num)) { - answer += num; - } - } - console.log(answer); -} +document.querySelector("form").addEventListener("submit", HandleInput); +document.querySelector("input").addEventListener("keydown", OnlyNumber); -function onlyNumber(event) { - const key = event.key; - // 입력된 키가 숫자인지 또는 백스페이스(Backspace) 키인지 확인 - if (/\d/.test(key) || key === 'Backspace') { - return true; // 숫자거나 백스페이스면 허용 - } else { - event.preventDefault(); // 숫자가 아니면 입력 방지 - return false; - } -} - -const handleOnInput = () => { - // 중복확인 - const value = inputEl.value; - const idx = value.length - 1; - if (idx > 0 && value[idx - 1] == value[idx]) { - inputEl.value = value.slice(0, idx); - alert('중복 숫자는 허용되지 않습니다.'); - } -} - -//compare -//1. 존재하는지 확인 (ball) -//1-1. cnt++ & 위치확인 (strike) -//1-2. 존재하지 않으면 낫싱 -const compareValue = (e) => { - e.preventDefault(); - - let strikes = 0, balls = 0; - for (let i = 0; i < 3; i++) { - if (inputEl.value[i] === answer[i]) { - strikes++; - } else if (answer.includes(inputEl.value[i])) { - balls++; - } - } - - //return element - if (strikes === 3) { - ansEl.innerHTML = '정답을 맞추셨습니다!
게임을 새로 시작하시겠습니까?
'; - const resetBtn = document.createElement('button'); - resetBtn.innerText = '게임 재시작'; - resetBtn.setAttribute('onclick', 'resetValue()'); - resetBtn.classList.add('resetBtn'); - ansEl.appendChild(resetBtn); - } else if (strikes === 0 && balls === 0) { - ansEl.textContent = '낫싱'; - } else { - ansEl.textContent = `${strikes} 스트라이크, ${balls} 볼`; - } -} - -//reset -const resetValue = () => { - inputEl.value = ''; - ansEl.innerHTML = ''; -} +// 추가된 버튼의 이벤트 리스너를 할당합니다. +document.getElementById("resetBtn").addEventListener("click", ResetValues); +document.getElementById("endGameBtn").addEventListener("click", EndGame); From 400d8f5a9bc58b3a488ff7c6df604f6b32e32109 Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:38:41 +0900 Subject: [PATCH 8/9] =?UTF-8?q?style:=20=EC=8A=A4=ED=83=80=EC=9D=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .prettierrc | 4 ++++ src/style/style.css | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 .prettierrc create mode 100644 src/style/style.css diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..9fc789d --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": false, + "tabWidth": 4 +} diff --git a/src/style/style.css b/src/style/style.css new file mode 100644 index 0000000..b81fc8e --- /dev/null +++ b/src/style/style.css @@ -0,0 +1,27 @@ +.displayNone { + display: none; +} + +#result__section { + width: 350px; + height: 200px; + border-radius: 10px; + background-color: beige; + + position: relative; +} + +#ansEl { + width: 100%; + text-align: center; + position: absolute; + top: 48%; + left: 50%; + transform: translate(-50%, -50%); +} + +.btn-wrap{ + position: absolute; + bottom: 15px; + right: 15px; +} From 48dfbee20f8784f3b1185586d916b3a08042ece7 Mon Sep 17 00:00:00 2001 From: soyeeee2 Date: Fri, 10 May 2024 02:39:13 +0900 Subject: [PATCH 9/9] =?UTF-8?q?README=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 64 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0d020fd..18b213f 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,52 @@ -# javascript-baseball-precourse - -## 기능 목록 -1. UI -2. feat/handleSubmit -#### submit and getValue -3. feat/setAnswer -#### set the random answer -4. feat/compAnswer -#### user가 제출한 답이 맞는지 비교한다 -5. feat/retAnswer -#### 답을 element로 return한다 \ No newline at end of file +# 숫자 야구 게임 + +## UI +1. **템플릿 구현**: 화면 디자인 및 템플릿을 구현합니다. +2. **처음 게임 시작 시 '결과' 부분 숨기기**: 게임이 시작될 때 '결과' 부분을 숨겨 사용자의 눈을 덜 끌어냅니다. + +## 야구게임 결과 +게임 진행 중에 발생하는 다양한 결과에 대한 설명입니다. + +### 1. 정답인 경우 +- 정답 문구 출력 +- 게임 재시작 문구 출력 +- 게임 재시작 버튼 생성 + +### 2. 오답인 경우 +- N스트라이크 N볼 형식으로 게임 진행 상황 출력 + +### 3. 잘못된 값 입력 시 +- `alert()`로 에러 메시지 출력 + +### 예외 케이스 종류 +1. 문자열 입력 +2. 특수문자 입력 +3. 소수 입력 +4. 중복된 숫자 입력 +5. 3개 이상 또는 이하의 숫자 입력 + +## 기능 구현 + +### 정답 세팅 (SetAnswer) +1. 랜덤 함수로 정답을 생성합니다. + +### 숫자 입력 받기 (HandleInput, OnlyNumber) +1. input 창에 숫자 입력을 받습니다. +2. 확인 버튼 클릭 시, 입력된 숫자를 전달 받습니다. +3. 예외 케이스에 해당하는 입력을 받았을 경우 에러 메시지를 출력합니다. + +### 게임 진행 (CompareValue) +1. 입력된 수와 컴퓨터의 수를 비교합니다. + - 같은 수, 같은 자리 = 스트라이크 + - 같은 수, 다른 자리 = 볼 + - 모두 다른 수 = 낫싱 + + +### 출력 (ShowResult) +1. displayNone으로 숨겨뒀던 결과 content를 보이게 합니다. +2. 비교한 결과를 사용자에게 보여줍니다. + +### 리셋 (ResetValues, EndGame) +1. 게임 재시작 버튼을 눌렀을 시, location.reload()로 초기화합니다. +2. 게임 종료 버튼을 눌렀을 시, 화면을 초기화하고 게임을 종료합니다. +