From 854ff0e292d26b399f16394675cee2639e2aeba4 Mon Sep 17 00:00:00 2001
From: dkile
Date: Thu, 9 Nov 2023 15:41:48 +0900
Subject: [PATCH 1/8] =?UTF-8?q?Feat:=20=EB=9E=9C=EB=8D=A4=20=EC=88=AB?=
=?UTF-8?q?=EC=9E=90=20=EC=83=9D=EC=84=B1=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/index.js | 40 +++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/src/index.js b/src/index.js
index 1553d753..fce3013d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,13 +1,27 @@
-export default function BaseballGame() {
- this.play = function (computerInputNumbers, userInputNumbers) {
- return "결과 값 String";
- };
-}
-
-// export default class BaseballGame {
-// play(computerInputNumbers, userInputNumbers) {
-// return "결과 값 String";
-// }
-// }
-
-new BaseballGame();
+import BaseballGame from "./BaseballGame.js";
+
+const concatPrimitiveIterToStr = (iter) =>
+ Array.from(iter).reduce((prev, cur) => prev + cur, "");
+
+const generateRandomInt = (length = 1) => {
+ const min = 10 ** (length - 1);
+ const max = 10 ** length;
+
+ return Math.floor(Math.random() * (max - min)) + min;
+};
+
+const generateFixedSizeSet = (size = 1, generateValue) => {
+ const set = new Set();
+ while (set.size < size) {
+ const value = generateValue();
+ set.add(value);
+ }
+ return set;
+};
+
+const generateRandomIntArr = (length) =>
+ Array.from(generateFixedSizeSet(length, generateRandomInt));
+
+const computerInputNumbers = Number(
+ concatPrimitiveIterToStr(generateRandomIntArr(3))
+);
From b0b7cc30e453ebdd4ae507c1e7f6d309b319f07d Mon Sep 17 00:00:00 2001
From: dkile
Date: Fri, 10 Nov 2023 15:09:22 +0900
Subject: [PATCH 2/8] =?UTF-8?q?Feat:=20UI=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?=
=?UTF-8?q?=EB=8F=99=EC=9E=91=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/index.js | 72 ++++++++++++++++++++++++++++++++++++++--------------
src/utils.js | 25 ++++++++++++++++++
2 files changed, 78 insertions(+), 19 deletions(-)
create mode 100644 src/utils.js
diff --git a/src/index.js b/src/index.js
index fce3013d..69baba76 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,27 +1,61 @@
-import BaseballGame from "./BaseballGame.js";
+import BaseballGame from "/src/BaseballGame.js";
+import {
+ convertDigitArrayToInt,
+ generateNonDuplicateRandomIntArray,
+} from "/src/utils.js";
-const concatPrimitiveIterToStr = (iter) =>
- Array.from(iter).reduce((prev, cur) => prev + cur, "");
+const generateComputerInputNumbers = () =>
+ convertDigitArrayToInt(generateNonDuplicateRandomIntArray(3, 1));
-const generateRandomInt = (length = 1) => {
- const min = 10 ** (length - 1);
- const max = 10 ** length;
+const userInputEl = document.querySelector("#user-input");
+const submitBtnEl = document.querySelector("#submit");
+const resultEl = document.querySelector("#result");
- return Math.floor(Math.random() * (max - min)) + min;
+const baseballGame = new BaseballGame();
+let computerInputNumbers = generateComputerInputNumbers();
+
+const handleRestart = (e) => {
+ userInputEl.disabled = false;
+ userInputEl.value = null;
+ userInputEl.focus();
+ resultEl.innerHTML = "";
+ computerInputNumbers = generateComputerInputNumbers();
};
-const generateFixedSizeSet = (size = 1, generateValue) => {
- const set = new Set();
- while (set.size < size) {
- const value = generateValue();
- set.add(value);
+const handleSubmit = (e) => {
+ const userInputNumbers = Number(userInputEl?.value);
+ const result = baseballGame.play(computerInputNumbers, userInputNumbers);
+
+ if (!result) {
+ alert("유효하지 않은 입력입니다.");
+ userInputEl.focus();
+ return;
}
- return set;
-};
+ if (result === "정답을 맞추셨습니다!") {
+ userInputEl.disabled = true;
+
+ const strongEl = document.createElement("strong");
+ strongEl.textContent = result;
+ resultEl.textContent = "";
+ resultEl.appendChild(strongEl);
+
+ const restartMention = document.createElement("span");
+ restartMention.textContent = "게임을 새로 시작하시겠습니까?";
+
+ const restartButtonEl = document.createElement("button");
+ restartButtonEl.textContent = "게임 재시작";
+ restartButtonEl.addEventListener("click", handleRestart);
-const generateRandomIntArr = (length) =>
- Array.from(generateFixedSizeSet(length, generateRandomInt));
+ const restartWrapper = document.createElement("div");
+ restartWrapper.appendChild(restartMention);
+ restartWrapper.appendChild(restartButtonEl);
+
+ resultEl.appendChild(restartWrapper);
+
+ return;
+ }
+
+ resultEl.textContent = result;
+};
-const computerInputNumbers = Number(
- concatPrimitiveIterToStr(generateRandomIntArr(3))
-);
+submitBtnEl.addEventListener("click", handleSubmit);
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 00000000..2072a047
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,25 @@
+export const convertDigitArrayToInt = (digitArr) => parseInt(digitArr.join(""));
+
+export const generateRandomInt = (length = 1) => {
+ const min = 10 ** (length - 1);
+ const max = 10 ** length;
+
+ return Math.floor(Math.random() * (max - min)) + min;
+};
+
+export const generateFixedSizeSet = (size = 1, generateValue) => {
+ const set = new Set();
+ while (set.size < size) {
+ const value = generateValue();
+ set.add(value);
+ }
+ return set;
+};
+
+export const generateNonDuplicateRandomIntArray = (
+ arraylength,
+ digitCount = 1
+) =>
+ Array.from(
+ generateFixedSizeSet(arraylength, () => generateRandomInt(digitCount))
+ );
From 4279b4ea4c15049894b3cd40dd55d55ee2b0a986 Mon Sep 17 00:00:00 2001
From: dkile
Date: Fri, 10 Nov 2023 15:09:42 +0900
Subject: [PATCH 3/8] =?UTF-8?q?Feat:=20=EC=88=AB=EC=9E=90=20=EC=95=BC?=
=?UTF-8?q?=EA=B5=AC=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/BaseballGame.js | 71 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 src/BaseballGame.js
diff --git a/src/BaseballGame.js b/src/BaseballGame.js
new file mode 100644
index 00000000..7c4512e7
--- /dev/null
+++ b/src/BaseballGame.js
@@ -0,0 +1,71 @@
+// Controller
+export default class BaseballGame {
+ #DIGIT_LENGTH = 3;
+ play(computerInputNumbers, userInputNumbers) {
+ const isValidInput =
+ this.#validateInputNumbers(computerInputNumbers) &&
+ this.#validateInputNumbers(userInputNumbers);
+ if (!isValidInput) return "";
+ const judgement = this.#judge(computerInputNumbers, userInputNumbers);
+ const result = this.#formatResult(judgement);
+
+ return result;
+ }
+
+ // TODO: 널 오브젝트 패턴?? Judgeable을 validate하는 서비스로 추출
+ #validateInputNumbers(inputNumbers) {
+ const inputStr = String(inputNumbers);
+ if (!this.#validateCorrectLength(inputStr)) return false;
+ if (!this.#validateAllDigit(inputStr)) return false;
+ if (!this.#validateDuplication(inputStr)) return false;
+
+ return true;
+ }
+
+ #validateCorrectLength(input) {
+ return input.length === this.#DIGIT_LENGTH;
+ }
+
+ #validateAllDigit(input) {
+ return /^\d+$/.test(input);
+ }
+
+ #validateDuplication(input) {
+ return new Set(input).size === inputStr.length;
+ }
+
+ // TODO: Judgeable 객체를 두 개를 비즈니스 로직에 따라 처리하는 Referee 서비스로 추출
+ #judge(computerInputDigits, userInputDigits) {
+ const set = new Set();
+ let strike = 0;
+ let ball = 0;
+ const computerInputDigits = Array.from(
+ String(computerInputNumbers),
+ Number
+ );
+ const userInputDigits = Array.from(String(userInputNumbers), Number);
+
+ for (let i = 0; i < computerInputDigits.length; i++) {
+ if (computerInputDigits[i] === userInputDigits[i]) {
+ strike += 1;
+ continue;
+ }
+ set.add(computerInputDigits[i]);
+ }
+
+ for (const userInputDigit of userInputDigits) {
+ if (set.has(userInputDigit)) ball += 1;
+ }
+
+ return { strike, ball };
+ }
+
+ // TODO: VO 객체(Judge) 내의 로직으로 분리
+ #formatResult({ strike, ball }) {
+ if (strike === 0 && ball === 0) return "낫싱";
+ if (strike === this.#DIGIT_LENGTH) return "정답을 맞추셨습니다!";
+ if (strike === 0) return `${ball}볼`;
+ if (ball === 0) return `${strike}스트라이크`;
+ return `${ball}볼 ${strike}스트라이크`;
+ }
+}
From e2699debf46c4de41028cbabe377b62a7869dee9 Mon Sep 17 00:00:00 2001
From: dkile
Date: Sat, 11 Nov 2023 17:19:49 +0900
Subject: [PATCH 4/8] =?UTF-8?q?Refactor:=20form=20=EC=9A=94=EC=86=8C=20?=
=?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
index.html | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/index.html b/index.html
index 041e0300..09b05d51 100644
--- a/index.html
+++ b/index.html
@@ -13,8 +13,10 @@ ⚾ 숫자 야구 게임
올바른 예) 139
틀린 예) 122
-
-
+
📄 결과
From 97cd89bf9fb30a323f32cb21d421975cdbb31247 Mon Sep 17 00:00:00 2001
From: dkile
Date: Sat, 11 Nov 2023 17:21:47 +0900
Subject: [PATCH 5/8] =?UTF-8?q?Refactor:=20generateNonDuplicateRandomIntAr?=
=?UTF-8?q?ray=20=ED=95=A8=EC=88=98=20=EC=9D=B8=EC=9E=90=20=EA=B0=9D?=
=?UTF-8?q?=EC=B2=B4=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/index.js | 7 ++++++-
src/utils.js | 6 +++---
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/index.js b/src/index.js
index 69baba76..f2949e7c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,7 +5,12 @@ import {
} from "/src/utils.js";
const generateComputerInputNumbers = () =>
- convertDigitArrayToInt(generateNonDuplicateRandomIntArray(3, 1));
+ convertDigitArrayToInt(
+ generateNonDuplicateRandomIntArray({
+ arraylength: 3,
+ digitCount: 1,
+ })
+ );
const userInputEl = document.querySelector("#user-input");
const submitBtnEl = document.querySelector("#submit");
diff --git a/src/utils.js b/src/utils.js
index 2072a047..398f2f69 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -16,10 +16,10 @@ export const generateFixedSizeSet = (size = 1, generateValue) => {
return set;
};
-export const generateNonDuplicateRandomIntArray = (
+export const generateNonDuplicateRandomIntArray = ({
arraylength,
- digitCount = 1
-) =>
+ digitCount = 1,
+}) =>
Array.from(
generateFixedSizeSet(arraylength, () => generateRandomInt(digitCount))
);
From d7b75c595018b8ddc6c125ab907445209fffef00 Mon Sep 17 00:00:00 2001
From: dkile
Date: Sat, 11 Nov 2023 17:23:22 +0900
Subject: [PATCH 6/8] =?UTF-8?q?Refactor:=20generateFixedSizeSet=20?=
=?UTF-8?q?=ED=95=A8=EC=88=98=20size=20=EC=9D=B8=EC=9E=90=20option?=
=?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/utils.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/utils.js b/src/utils.js
index 398f2f69..24140575 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -7,7 +7,7 @@ export const generateRandomInt = (length = 1) => {
return Math.floor(Math.random() * (max - min)) + min;
};
-export const generateFixedSizeSet = (size = 1, generateValue) => {
+export const generateFixedSizeSet = (generateValue, { size = 1 }) => {
const set = new Set();
while (set.size < size) {
const value = generateValue();
@@ -21,5 +21,7 @@ export const generateNonDuplicateRandomIntArray = ({
digitCount = 1,
}) =>
Array.from(
- generateFixedSizeSet(arraylength, () => generateRandomInt(digitCount))
+ generateFixedSizeSet(() => generateRandomInt(digitCount), {
+ size: arraylength,
+ })
);
From 24aec7e2ce1f5d98df1de404b83b3969fa8c7467 Mon Sep 17 00:00:00 2001
From: dkile
Date: Sat, 11 Nov 2023 17:24:21 +0900
Subject: [PATCH 7/8] =?UTF-8?q?Refactor:=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?=
=?UTF-8?q?=ED=95=B8=EB=93=A4=EB=9F=AC=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?=
=?UTF-8?q?=EC=B6=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/index.js | 50 ++++++++++++++++++++++++++++++--------------------
1 file changed, 30 insertions(+), 20 deletions(-)
diff --git a/src/index.js b/src/index.js
index f2949e7c..a546b0f0 100644
--- a/src/index.js
+++ b/src/index.js
@@ -19,11 +19,39 @@ const resultEl = document.querySelector("#result");
const baseballGame = new BaseballGame();
let computerInputNumbers = generateComputerInputNumbers();
-const handleRestart = (e) => {
+const resetUserInput = () => {
userInputEl.disabled = false;
userInputEl.value = null;
userInputEl.focus();
+};
+
+const resetResultEl = () => {
resultEl.innerHTML = "";
+};
+
+const showWinningResult = () => {
+ const strongEl = document.createElement("strong");
+ strongEl.textContent = result;
+ resultEl.textContent = "";
+ resultEl.appendChild(strongEl);
+
+ const restartMention = document.createElement("span");
+ restartMention.textContent = "게임을 새로 시작하시겠습니까?";
+
+ const restartButtonEl = document.createElement("button");
+ restartButtonEl.textContent = "게임 재시작";
+ restartButtonEl.addEventListener("click", handleRestart);
+
+ const restartWrapper = document.createElement("div");
+ restartWrapper.appendChild(restartMention);
+ restartWrapper.appendChild(restartButtonEl);
+
+ resultEl.appendChild(restartWrapper);
+};
+
+const handleRestart = (e) => {
+ resetUserInput();
+ resetResultEl();
computerInputNumbers = generateComputerInputNumbers();
};
@@ -38,25 +66,7 @@ const handleSubmit = (e) => {
}
if (result === "정답을 맞추셨습니다!") {
userInputEl.disabled = true;
-
- const strongEl = document.createElement("strong");
- strongEl.textContent = result;
- resultEl.textContent = "";
- resultEl.appendChild(strongEl);
-
- const restartMention = document.createElement("span");
- restartMention.textContent = "게임을 새로 시작하시겠습니까?";
-
- const restartButtonEl = document.createElement("button");
- restartButtonEl.textContent = "게임 재시작";
- restartButtonEl.addEventListener("click", handleRestart);
-
- const restartWrapper = document.createElement("div");
- restartWrapper.appendChild(restartMention);
- restartWrapper.appendChild(restartButtonEl);
-
- resultEl.appendChild(restartWrapper);
-
+ showWinningResult();
return;
}
From 0a9cbda2927a597563f1fb76def7f9bd68f3f48e Mon Sep 17 00:00:00 2001
From: dkile
Date: Sat, 11 Nov 2023 17:53:57 +0900
Subject: [PATCH 8/8] =?UTF-8?q?Fix:=20judge=20=ED=95=A8=EC=88=98=20?=
=?UTF-8?q?=EC=9E=98=20=EB=AA=BB=20=ED=91=9C=EA=B8=B0=EB=90=9C=20=EC=9D=B8?=
=?UTF-8?q?=EC=9E=90=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/BaseballGame.js | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/BaseballGame.js b/src/BaseballGame.js
index 7c4512e7..6e386b1c 100644
--- a/src/BaseballGame.js
+++ b/src/BaseballGame.js
@@ -1,11 +1,18 @@
// Controller
export default class BaseballGame {
#DIGIT_LENGTH = 3;
+ #referee;
+
+ constructor(referee) {
+ this.#referee = referee;
+ }
+
play(computerInputNumbers, userInputNumbers) {
const isValidInput =
this.#validateInputNumbers(computerInputNumbers) &&
this.#validateInputNumbers(userInputNumbers);
if (!isValidInput) return "";
+
const judgement = this.#judge(computerInputNumbers, userInputNumbers);
const result = this.#formatResult(judgement);
@@ -35,7 +42,7 @@ export default class BaseballGame {
}
// TODO: Judgeable 객체를 두 개를 비즈니스 로직에 따라 처리하는 Referee 서비스로 추출
- #judge(computerInputDigits, userInputDigits) {
+ #judge(computerInputNumbers, userInputNumbers) {
const set = new Set();
let strike = 0;
let ball = 0;