From 2e4912078cc9072fdc87b5b5c57922a226ad64f4 Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Tue, 24 Oct 2023 15:03:58 +0900 Subject: [PATCH 01/11] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EB=A6=AC=EB=93=9C=EB=AF=B8=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..e69de29bb From d5b891060b31116fb77a8973b19a49ee31127c5f Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 17:56:35 +0900 Subject: [PATCH 02/11] =?UTF-8?q?Feat:=20=ED=95=A8=EC=88=98=EB=93=A4?= =?UTF-8?q?=EC=9D=B4=20=EB=8F=99=EC=9E=91=ED=95=A0=20app.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index c38b30d5b..f75c732ce 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,39 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; +import { MESSAGE } from "./Constant/Constant.js"; +import Computer from "./Computer/Computer.js"; +import NumCompare from "./Computer/NumCompare.js"; +import User from "./User/User.js"; + class App { - async play() {} + constructor() { + this.user = new User(); + this.numCompare = new NumCompare(); + this.isRunning = true; + } + + async play() { + while (this.isRunning) { + const computer = new Computer(); + const START = computer.makeAnswer(); + + MissionUtils.Console.print(MESSAGE.START); + + let result; + while (result !== "3스트라이크") { + const userInput = await this.user.getInput(); + result = this.numCompare.checkAnswer(userInput, START); + MissionUtils.Console.print(result); + } + + MissionUtils.Console.print(MESSAGE.END); + + const replayInput = await this.user.getReplay(); + + if (replayInput === "2") { + this.isRunning = false; + } + } + } } export default App; From bbd1763af3eefad235ad1b96ff9af51c254e8b6a Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 17:56:52 +0900 Subject: [PATCH 03/11] =?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=ED=95=A8=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Computer/Computer.js | 14 ++++++++++++++ src/Computer/NumCompare.js | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/Computer/Computer.js create mode 100644 src/Computer/NumCompare.js diff --git a/src/Computer/Computer.js b/src/Computer/Computer.js new file mode 100644 index 000000000..d7542d423 --- /dev/null +++ b/src/Computer/Computer.js @@ -0,0 +1,14 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; + +export default class Computer { + makeAnswer() { + const answer = []; + while (answer.length < 3) { + const randomNum = MissionUtils.Random.pickNumberInRange(1, 9); + if (!answer.includes(randomNum)) { + answer.push(randomNum); + } + } + return answer; + } +} diff --git a/src/Computer/NumCompare.js b/src/Computer/NumCompare.js new file mode 100644 index 000000000..a4a9a779d --- /dev/null +++ b/src/Computer/NumCompare.js @@ -0,0 +1,22 @@ +export default class NumCompare { + checkAnswer(userInput, computerAnswer) { + let ball = 0; + let strike = 0; + + for (let i = 0; i < 3; i++) { + if (userInput[i] === computerAnswer[i]) { + strike++; + } else if (computerAnswer.includes(Number(userInput[i]))) { + ball++; + } + } + + if (strike === 0 && ball === 0) { + return "낫싱"; + } + + const answer = `${ball ? ball + "볼" : ""} ${strike ? strike + "스트라이크" : ""}`.trim(); + return answer; + } + } + \ No newline at end of file From 51cdecb3e51329d744af60b1f54e5ba0146e9d7c Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 17:57:31 +0900 Subject: [PATCH 04/11] =?UTF-8?q?Chore:=20=EC=83=81=EC=88=98=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Constant/Constant.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/Constant/Constant.js diff --git a/src/Constant/Constant.js b/src/Constant/Constant.js new file mode 100644 index 000000000..81bdc9698 --- /dev/null +++ b/src/Constant/Constant.js @@ -0,0 +1,12 @@ +export const MESSAGE = { + START: "숫자 야구 게임을 시작합니다.", + INPUT: "숫자를 입력해주세요 : ", + END: "3스트라이크!\n3개의 숫자를 모두 맞히셨습니다! 게임 종료", + RESET: "게임을 다시 시작하려면 1, 게임을 종료하려면 2를 입력하세요.", + }; + + export const ERROR = { + INVALID_INPUT: "[ERROR] 제시된 조건을 확인해주세요 (1~9까지의 서로 다른 3자리의 수)", + INVALID_REPLAY: "[ERROR] 1 또는 2를 입력해주세요.", + }; + \ No newline at end of file From 8f497f76fd24ca43d4242e07b56629d37c7d46ad Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 17:57:48 +0900 Subject: [PATCH 05/11] =?UTF-8?q?Feat:=20=EC=97=90=EB=9F=AC=20=ED=95=A8?= =?UTF-8?q?=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Error/Error.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/Error/Error.js diff --git a/src/Error/Error.js b/src/Error/Error.js new file mode 100644 index 000000000..d3c0f9abe --- /dev/null +++ b/src/Error/Error.js @@ -0,0 +1,19 @@ +import { ERROR } from "../Constant/Constant"; + +export default class ErrorHandler { + checkInput(userInput) { + if ( + userInput.length !== 3 || + new Set(userInput).size !== 3 || + [...userInput].some((item) => Number(item) < 1 || Number(item) > 9) + ) { + throw new Error(ERROR.INVALID_INPUT); + } + } + + checkReplay(replayInput) { + if (replayInput !== "1" && replayInput !== "2") { + throw new Error(ERROR.INVALID_REPLAY); + } + } +} From 4cc4fb473e87975b1f3348986a6213d94a048fb9 Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 17:58:00 +0900 Subject: [PATCH 06/11] =?UTF-8?q?Feat:=20=EC=9C=A0=EC=A0=80=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=ED=95=A8=EC=88=98=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/User/User.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/User/User.js diff --git a/src/User/User.js b/src/User/User.js new file mode 100644 index 000000000..a59d657f2 --- /dev/null +++ b/src/User/User.js @@ -0,0 +1,21 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; +import { MESSAGE } from "../Constant/Constant.js"; +import ErrorHandler from "../Error/Error.js"; + +export default class User { + constructor() { + this.errorHandler = new ErrorHandler(); + } + + async getInput() { + const userInput = await MissionUtils.Console.readLineAsync(MESSAGE.INPUT); + this.errorHandler.checkInput(userInput); + return userInput; + } + + async getReplay() { + const replayInput = await MissionUtils.Console.readLineAsync(MESSAGE.RESET); + this.errorHandler.checkReplay(replayInput); + return replayInput; + } +} From 1bdc6e70e993a09c4ea3985fe59b47ea8c3da92c Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 22:15:27 +0900 Subject: [PATCH 07/11] =?UTF-8?q?Rename:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=AF=B8=ED=86=B5=EA=B3=BC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Computer/NumCompare.js | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/Computer/NumCompare.js diff --git a/src/Computer/NumCompare.js b/src/Computer/NumCompare.js deleted file mode 100644 index a4a9a779d..000000000 --- a/src/Computer/NumCompare.js +++ /dev/null @@ -1,22 +0,0 @@ -export default class NumCompare { - checkAnswer(userInput, computerAnswer) { - let ball = 0; - let strike = 0; - - for (let i = 0; i < 3; i++) { - if (userInput[i] === computerAnswer[i]) { - strike++; - } else if (computerAnswer.includes(Number(userInput[i]))) { - ball++; - } - } - - if (strike === 0 && ball === 0) { - return "낫싱"; - } - - const answer = `${ball ? ball + "볼" : ""} ${strike ? strike + "스트라이크" : ""}`.trim(); - return answer; - } - } - \ No newline at end of file From 98518afceae4b6a4c4dd744c0ec55b0a30563c68 Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 22:17:21 +0900 Subject: [PATCH 08/11] =?UTF-8?q?Refactor:=20=EB=9E=9C=EB=8D=A4=EA=B0=92?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=ED=95=A8=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Computer/Computer.js | 20 +++++++++++++------- src/Error/Error.js | 19 ------------------- src/User/User.js | 21 --------------------- 3 files changed, 13 insertions(+), 47 deletions(-) delete mode 100644 src/Error/Error.js delete mode 100644 src/User/User.js diff --git a/src/Computer/Computer.js b/src/Computer/Computer.js index d7542d423..f38136642 100644 --- a/src/Computer/Computer.js +++ b/src/Computer/Computer.js @@ -1,14 +1,20 @@ import { MissionUtils } from "@woowacourse/mission-utils"; -export default class Computer { - makeAnswer() { - const answer = []; - while (answer.length < 3) { +class Computer { + constructor() { + this.number = this.getRandomNum(); + } + + getRandomNum() { + const number = []; + while (number.length < 3) { const randomNum = MissionUtils.Random.pickNumberInRange(1, 9); - if (!answer.includes(randomNum)) { - answer.push(randomNum); + if (!number.includes(randomNum)) { + number.push(randomNum); } } - return answer; + return number; } } + +export default Computer; diff --git a/src/Error/Error.js b/src/Error/Error.js deleted file mode 100644 index d3c0f9abe..000000000 --- a/src/Error/Error.js +++ /dev/null @@ -1,19 +0,0 @@ -import { ERROR } from "../Constant/Constant"; - -export default class ErrorHandler { - checkInput(userInput) { - if ( - userInput.length !== 3 || - new Set(userInput).size !== 3 || - [...userInput].some((item) => Number(item) < 1 || Number(item) > 9) - ) { - throw new Error(ERROR.INVALID_INPUT); - } - } - - checkReplay(replayInput) { - if (replayInput !== "1" && replayInput !== "2") { - throw new Error(ERROR.INVALID_REPLAY); - } - } -} diff --git a/src/User/User.js b/src/User/User.js deleted file mode 100644 index a59d657f2..000000000 --- a/src/User/User.js +++ /dev/null @@ -1,21 +0,0 @@ -import { MissionUtils } from "@woowacourse/mission-utils"; -import { MESSAGE } from "../Constant/Constant.js"; -import ErrorHandler from "../Error/Error.js"; - -export default class User { - constructor() { - this.errorHandler = new ErrorHandler(); - } - - async getInput() { - const userInput = await MissionUtils.Console.readLineAsync(MESSAGE.INPUT); - this.errorHandler.checkInput(userInput); - return userInput; - } - - async getReplay() { - const replayInput = await MissionUtils.Console.readLineAsync(MESSAGE.RESET); - this.errorHandler.checkReplay(replayInput); - return replayInput; - } -} From 6ae1e9c97591d5ebf281a6143af76a88e5e91e51 Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 22:18:16 +0900 Subject: [PATCH 09/11] =?UTF-8?q?Refactor:=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EA=B0=84=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Constant/Constant.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Constant/Constant.js b/src/Constant/Constant.js index 81bdc9698..72fb76e7c 100644 --- a/src/Constant/Constant.js +++ b/src/Constant/Constant.js @@ -1,12 +1,8 @@ export const MESSAGE = { START: "숫자 야구 게임을 시작합니다.", INPUT: "숫자를 입력해주세요 : ", - END: "3스트라이크!\n3개의 숫자를 모두 맞히셨습니다! 게임 종료", - RESET: "게임을 다시 시작하려면 1, 게임을 종료하려면 2를 입력하세요.", - }; - - export const ERROR = { - INVALID_INPUT: "[ERROR] 제시된 조건을 확인해주세요 (1~9까지의 서로 다른 3자리의 수)", - INVALID_REPLAY: "[ERROR] 1 또는 2를 입력해주세요.", + END: "3개의 숫자를 모두 맞히셨습니다! 게임 종료", + REPLAY: "게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.", + ERROR: "[ERROR] 잘못된 입력입니다." }; \ No newline at end of file From a68804c91f0e5e820aeb8f2bcc46f467084bd881 Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 22:19:26 +0900 Subject: [PATCH 10/11] =?UTF-8?q?Feat:=20=EA=B0=92=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=ED=95=A8=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/UserInput/UserInput.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/UserInput/UserInput.js diff --git a/src/UserInput/UserInput.js b/src/UserInput/UserInput.js new file mode 100644 index 000000000..9e1eccc75 --- /dev/null +++ b/src/UserInput/UserInput.js @@ -0,0 +1,29 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; +import { MESSAGE } from "../Constant/Constant"; + +class UserInput { + async inputUser() { + const userInput = await MissionUtils.Console.readLineAsync(MESSAGE.INPUT); + if (!this.isValidInput(userInput)) { + throw new Error(MESSAGE.ERROR); + } + return userInput.split('').map(Number); + } + + isValidInput(userInput) { + return new Set(userInput).size === 3 && /^[1-9]{3}$/.test(userInput); + } + + async restartOption() { + const option = await MissionUtils.Console.readLineAsync(MESSAGE.REPLAY); + if (option === '1') { + return true; + } else if (option === '2') { + return false; + } else { + throw new Error(MESSAGE.ERROR); + } + } +} + +export default UserInput; From a79a3db7b8355d8b7f94b74b040effac4d209b13 Mon Sep 17 00:00:00 2001 From: OhHyukJun Date: Wed, 25 Oct 2023 22:19:44 +0900 Subject: [PATCH 11/11] =?UTF-8?q?Refactor:=20=EB=A9=94=EC=9D=B8=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 55 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/src/App.js b/src/App.js index f75c732ce..810d6308f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,38 +1,53 @@ import { MissionUtils } from "@woowacourse/mission-utils"; -import { MESSAGE } from "./Constant/Constant.js"; import Computer from "./Computer/Computer.js"; -import NumCompare from "./Computer/NumCompare.js"; -import User from "./User/User.js"; +import UserInput from "./UserInput/UserInput.js"; class App { constructor() { - this.user = new User(); - this.numCompare = new NumCompare(); - this.isRunning = true; + this.computer = new Computer(); + this.userInput = new UserInput(); } async play() { - while (this.isRunning) { - const computer = new Computer(); - const START = computer.makeAnswer(); + MissionUtils.Console.print("숫자 야구 게임을 시작합니다."); - MissionUtils.Console.print(MESSAGE.START); + while (true) { + const userInput = await this.userInput.inputUser(); + const result = this.compareNum(userInput); - let result; - while (result !== "3스트라이크") { - const userInput = await this.user.getInput(); - result = this.numCompare.checkAnswer(userInput, START); - MissionUtils.Console.print(result); - } + MissionUtils.Console.print(result); - MissionUtils.Console.print(MESSAGE.END); + if (result === '3스트라이크') { + MissionUtils.Console.print("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); + if (!(await this.userInput.restartOption())) { + break; + } + this.computer = new Computer(); + } + } + } - const replayInput = await this.user.getReplay(); + compareNum(userInput) { + let strike = 0; + let ball = 0; - if (replayInput === "2") { - this.isRunning = false; + for (let i = 0; i < 3; i++) { + if (userInput[i] === this.computer.number[i]) { + strike++; + } else if (this.computer.number.includes(userInput[i])) { + ball++; } } + + if (strike > 0 && ball > 0) { + return `${ball}볼 ${strike}스트라이크`; + } else if (strike > 0) { + return `${strike}스트라이크`; + } else if (ball > 0) { + return `${ball}볼`; + } else { + return "낫싱"; + } } }