From e1cb1e5b49b4d9fbd5a093d2cc56653fb563ed33 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:03:42 +0900 Subject: [PATCH 01/16] =?UTF-8?q?docs:readme=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/README.md b/docs/README.md index e69de29bb2d..4690b145a3c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,39 @@ +# πŸ’ͺ ν”„λ‘œμ νŠΈ κ°œμš” + +μžλ™μ°¨ κ²½μ£Ό κ²Œμž„μ„ κ΅¬ν˜„ν•œλ‹€. +μžλ™μ°¨μ˜ 이름과 전진을 μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯λ°›κ³ , μžλ™μ°¨λ₯Ό μ „μ§„μ‹œν‚¨ ν›„ 우승자λ₯Ό μ„ μ •ν•œλ‹€. + +# πŸ“ κ΅¬ν˜„ κΈ°λŠ₯ λͺ©λ‘ + +### μžλ™μ°¨ 이름을 μž…λ ₯ν•˜λŠ” κΈ°λŠ₯ + +- [ ] `κ²½μ£Όν•  μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”.(이름은 μ‰Όν‘œ(,) κΈ°μ€€μœΌλ‘œ ꡬ뢄)`λ₯Ό 좜λ ₯ν•œλ‹€. +- [ ] μžλ™μ°¨μ˜ 이름을 μž…λ ₯λ°›λŠ”λ‹€. + - [ ] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. + - [ ] μ˜¬λ°”λ₯Έ κ΅¬λΆ„μžλ‘œ κ΅¬λΆ„λ˜μ—ˆμŒμ„ κ²€μ¦ν•œλ‹€. + - [ ] μ€‘λ³΅λ˜λŠ” 이름이 μ—†μŒμ„ κ²€μ¦ν•œλ‹€. + - [ ] 5자 μ΄ν•˜μ˜ 이름인지 κ²€μ¦ν•œλ‹€. + +### μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•˜λŠ” κΈ°λŠ₯ + +- [ ] `μ‹œλ„ν•  νšŒμˆ˜λŠ” λͺ‡νšŒμΈκ°€μš”?`λ₯Ό 좜λ ₯ν•œλ‹€. +- [ ] μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•œλ‹€. + - [ ] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. + - [ ] 1 μ΄μƒμ˜ 숫자둜 이루어져 μžˆμŒμ„ κ²€μ¦ν•œλ‹€. + +### μžλ™μ°¨λ₯Ό μ „μ§„ν•˜λŠ” κΈ°λŠ₯ + +- [ ] μž…λ ₯ν•œ 횟수만큼 μžλ™μ°¨ 전진을 μ‹œλ„ν•œλ‹€. +- [ ] λ¬΄μž‘μœ„ 값을 μƒμ„±ν•˜κ³  μ „μ§„ν•˜λŠ” 쑰건을 κ²€μ‚¬ν•œλ‹€. +- [ ] 쑰건에 λΆ€ν•©ν•œλ‹€λ©΄ μžλ™μ°¨λ₯Ό μ „μ§„μ‹œν‚¨λ‹€. + +### μžλ™μ°¨μ˜ μƒνƒœλ₯Ό 좜λ ₯ν•˜λŠ” κΈ°λŠ₯ + +- [ ] λͺ¨λ“  μžλ™μ°¨μ˜ 이름과 μ΄λ™ν•œ 갯수λ₯Ό 뷰에 μ „λ‹¬ν•œλ‹€. +- [ ] λ·°μ—μ„œ μžλ™μ°¨ 이름을 좜λ ₯ν•˜κ³  μ΄λ™ν•œ 갯수λ₯Ό `-`둜 좜λ ₯ν•œλ‹€. + +### 우승자λ₯Ό 좜λ ₯ν•˜λŠ” κΈ°λŠ₯ + +- [ ] κ°€μž₯ 많이 μ΄λ™ν•œ μžλ™μ°¨λ₯Ό μ„ μ •ν•œλ‹€. +- [ ] `μ΅œμ’… 우승자 : pobi`와 같이 우승자λ₯Ό 좜λ ₯ν•œλ‹€. + From c9f117cc63c31f7fd96777263fc09977cb30e0b5 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:26:18 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=EA=B2=BD=EC=A3=BC=ED=95=A0=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=B0=A8=EC=9D=98=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=EC=9D=84=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EA=B3=A0=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=EC=9D=84=20=EC=A0=9C=EA=B1=B0=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 10 ++--- src/main/java/racingcar/view/InputView.java | 49 +++++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 src/main/java/racingcar/view/InputView.java diff --git a/docs/README.md b/docs/README.md index 4690b145a3c..c847f70abd7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,11 +7,11 @@ ### μžλ™μ°¨ 이름을 μž…λ ₯ν•˜λŠ” κΈ°λŠ₯ -- [ ] `κ²½μ£Όν•  μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”.(이름은 μ‰Όν‘œ(,) κΈ°μ€€μœΌλ‘œ ꡬ뢄)`λ₯Ό 좜λ ₯ν•œλ‹€. -- [ ] μžλ™μ°¨μ˜ 이름을 μž…λ ₯λ°›λŠ”λ‹€. - - [ ] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. - - [ ] μ˜¬λ°”λ₯Έ κ΅¬λΆ„μžλ‘œ κ΅¬λΆ„λ˜μ—ˆμŒμ„ κ²€μ¦ν•œλ‹€. - - [ ] μ€‘λ³΅λ˜λŠ” 이름이 μ—†μŒμ„ κ²€μ¦ν•œλ‹€. +- [x] `κ²½μ£Όν•  μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”.(이름은 μ‰Όν‘œ(,) κΈ°μ€€μœΌλ‘œ ꡬ뢄)`λ₯Ό 좜λ ₯ν•œλ‹€. +- [x] μžλ™μ°¨μ˜ 이름을 μž…λ ₯λ°›λŠ”λ‹€. + - [x] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. + - [x] μ˜¬λ°”λ₯Έ κ΅¬λΆ„μžλ‘œ κ΅¬λΆ„λ˜μ—ˆμŒμ„ κ²€μ¦ν•œλ‹€. + - [x] μ€‘λ³΅λ˜λŠ” 이름이 μ—†μŒμ„ κ²€μ¦ν•œλ‹€. - [ ] 5자 μ΄ν•˜μ˜ 이름인지 κ²€μ¦ν•œλ‹€. ### μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•˜λŠ” κΈ°λŠ₯ diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java new file mode 100644 index 00000000000..28c094734de --- /dev/null +++ b/src/main/java/racingcar/view/InputView.java @@ -0,0 +1,49 @@ +package racingcar.view; + +import java.util.Arrays; +import java.util.List; +import racingcar.global.exception.CustomException; +import racingcar.global.exception.ErrorMessage; +import racingcar.view.console.ConsoleReader; +import racingcar.view.console.ConsoleWriter; + +public class InputView { + private static final String CAR_NAMES_NOTICE = "κ²½μ£Όν•  μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”.(이름은 μ‰Όν‘œ(,) κΈ°μ€€μœΌλ‘œ ꡬ뢄)`λ₯Ό 좜λ ₯ν•œλ‹€."; + public static final String CAR_NAMES_SEPARATOR = ","; + + public List readCarNames() { + ConsoleWriter.printlnMessage(CAR_NAMES_NOTICE); + return Validator.validateCarNames(ConsoleReader.enterMessage()); + } + + private static class Validator { + private static List validateCarNames(String message) { + List cars = parseStringToList(message, CAR_NAMES_SEPARATOR); + validateDuplicated(cars); + } + + private static void validateDuplicated(List items) { + if (hasDuplicated(items)) { + throw CustomException.from(ErrorMessage.DUPLICATED_CAR_ERROR); + } + } + + private static boolean hasDuplicated(List items) { + return items.size() != calculateUniqueCount(items); + } + + private static int calculateUniqueCount(List items) { + return (int) items.stream() + .distinct() + .count(); + } + + private static List parseStringToList(String message, String separator) { + return Arrays.stream(split(message, separator)).toList(); + } + + private static String[] split(String message, String separator) { + return message.split(separator, -1); + } + } +} From 0fa3d7709fcbe6914814bfdca4948867e3c85335 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:26:49 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A6=84=EC=9D=B4=201?= =?UTF-8?q?=EC=9E=90=20=EC=9D=B4=EC=83=81,=205=EC=9E=90=20=EC=9D=B4?= =?UTF-8?q?=ED=95=98=EC=9E=84=EC=9D=84=20=EA=B2=80=EC=A6=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/domain/Name.java | 27 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/domain/Name.java diff --git a/docs/README.md b/docs/README.md index c847f70abd7..3cbd1c88ca2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,7 +12,7 @@ - [x] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. - [x] μ˜¬λ°”λ₯Έ κ΅¬λΆ„μžλ‘œ κ΅¬λΆ„λ˜μ—ˆμŒμ„ κ²€μ¦ν•œλ‹€. - [x] μ€‘λ³΅λ˜λŠ” 이름이 μ—†μŒμ„ κ²€μ¦ν•œλ‹€. - - [ ] 5자 μ΄ν•˜μ˜ 이름인지 κ²€μ¦ν•œλ‹€. + - [x] 5자 μ΄ν•˜μ˜ 이름인지 κ²€μ¦ν•œλ‹€. ### μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•˜λŠ” κΈ°λŠ₯ diff --git a/src/main/java/racingcar/domain/Name.java b/src/main/java/racingcar/domain/Name.java new file mode 100644 index 00000000000..e7fb4601aa9 --- /dev/null +++ b/src/main/java/racingcar/domain/Name.java @@ -0,0 +1,27 @@ +package racingcar.domain; + +import racingcar.global.exception.CustomException; +import racingcar.global.exception.ErrorMessage; + +public class Name { + public static final int MIN = 1; + public static final int MAX = 5; + private final String name; + + public Name(String name) { + Validator.validateRange(name.length(), MIN, MAX); + this.name = name; + } + + public static class Validator { + private static void validateRange(int length, int start, int end) { + if (isInvalidRange(length, start, end)) { + throw CustomException.from(ErrorMessage.INVALID_LENGTH_ERROR); + } + } + + private static boolean isInvalidRange(int number, int start, int end) { + return number < start || number > end; + } + } +} From 6062b34d00ac1f3110119cef91353bee11ed1033 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:27:09 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=A6=84=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=EC=9E=90=EB=8F=99=EC=B0=A8=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/domain/Cars.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/racingcar/domain/Cars.java diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java new file mode 100644 index 00000000000..d006626f2e4 --- /dev/null +++ b/src/main/java/racingcar/domain/Cars.java @@ -0,0 +1,17 @@ +package racingcar.domain; + +import java.util.List; + +public class Cars { + private final List cars; + + public Cars(List cars) { + this.cars = generateToCars(cars); + } + + private List generateToCars(List cars) { + return cars.stream() + .map(name -> new Car(new Name(name))) + .toList(); + } +} From f561bc765db7608a158208c7dc093c4312250e45 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:27:22 +0900 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/exception/CustomException.java | 13 +++++++++++++ .../global/exception/ErrorMessage.java | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/main/java/racingcar/global/exception/CustomException.java create mode 100644 src/main/java/racingcar/global/exception/ErrorMessage.java diff --git a/src/main/java/racingcar/global/exception/CustomException.java b/src/main/java/racingcar/global/exception/CustomException.java new file mode 100644 index 00000000000..1c423097d63 --- /dev/null +++ b/src/main/java/racingcar/global/exception/CustomException.java @@ -0,0 +1,13 @@ +package racingcar.global.exception; + +public class CustomException extends IllegalArgumentException { + private static final String PREFIX = "[ERROR] "; + + private CustomException(ErrorMessage errorMessage) { + super(PREFIX + errorMessage.getMessage()); + } + + public static CustomException from(ErrorMessage errorMessage) { + return new CustomException(errorMessage); + } +} diff --git a/src/main/java/racingcar/global/exception/ErrorMessage.java b/src/main/java/racingcar/global/exception/ErrorMessage.java new file mode 100644 index 00000000000..749039cce6c --- /dev/null +++ b/src/main/java/racingcar/global/exception/ErrorMessage.java @@ -0,0 +1,17 @@ +package racingcar.global.exception; + +public enum ErrorMessage { + BLANK_INPUT_ERROR("빈 λ¬Έμžμ—΄μ΄ μž…λ ₯λ˜μ—ˆμŠ΅λ‹ˆλ‹€."), + INVALID_LENGTH_ERROR("잘λͺ»λœ 길이의 λ¬Έμžμ—΄μ„ μž…λ ₯ν•˜μ˜€μŠ΅λ‹ˆλ‹€. "), + DUPLICATED_CAR_ERROR("μžλ™μ°¨μ˜ 이름이 μ€‘λ³΅λ˜μ—ˆμŠ΅λ‹ˆλ‹€."); + + private final String message; + + ErrorMessage(String message) { + this.message = message; + } + + public String getMessage() { + return this.message; + } +} From 9b63408f330179b4a8af43c0c3fa3db5d89aa888 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:27:33 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat:=20=EC=BD=98=EC=86=94=20=EC=9E=85?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EB=8B=B4=EB=8B=B9=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../racingcar/view/console/ConsoleReader.java | 24 +++++++++++++++++++ .../racingcar/view/console/ConsoleWriter.java | 11 +++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/main/java/racingcar/view/console/ConsoleReader.java create mode 100644 src/main/java/racingcar/view/console/ConsoleWriter.java diff --git a/src/main/java/racingcar/view/console/ConsoleReader.java b/src/main/java/racingcar/view/console/ConsoleReader.java new file mode 100644 index 00000000000..70e24343e10 --- /dev/null +++ b/src/main/java/racingcar/view/console/ConsoleReader.java @@ -0,0 +1,24 @@ +package racingcar.view.console; + +import camp.nextstep.edu.missionutils.Console; +import racingcar.global.exception.CustomException; +import racingcar.global.exception.ErrorMessage; + +public final class ConsoleReader { + public static String enterMessage() { + return Validator.validate(Console.readLine()); + } + + private static class Validator { + public static String validate(String message) { + validateBlankInput(message); + return message; + } + + private static void validateBlankInput(String message) { + if (message.isBlank()) { + throw CustomException.from(ErrorMessage.BLANK_INPUT_ERROR); + } + } + } +} diff --git a/src/main/java/racingcar/view/console/ConsoleWriter.java b/src/main/java/racingcar/view/console/ConsoleWriter.java new file mode 100644 index 00000000000..38b391e2631 --- /dev/null +++ b/src/main/java/racingcar/view/console/ConsoleWriter.java @@ -0,0 +1,11 @@ +package racingcar.view.console; + +public final class ConsoleWriter { + public static void printlnMessage(String message) { + System.out.println(message); + } + + public static void printlnFormat(String message, Object... args) { + printlnMessage(String.format(message, args)); + } +} From bf40421e1210d9e75adaba9c82e7dccc0a373bfa Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:27:46 +0900 Subject: [PATCH 07/16] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=EC=9D=98=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/domain/Car.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/racingcar/domain/Car.java diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java new file mode 100644 index 00000000000..c4e6b18363c --- /dev/null +++ b/src/main/java/racingcar/domain/Car.java @@ -0,0 +1,11 @@ +package racingcar.domain; + +public class Car { + private Name name; + private int moved; + + public Car(Name name) { + this.name = name; + this.moved = 0; + } +} From 77be8c9293853644bc69664d9cc32663bfd008fb Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:32:19 +0900 Subject: [PATCH 08/16] =?UTF-8?q?feat:=20=EC=8B=9C=EB=8F=84=ED=95=A0=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98=EB=A5=BC=20=EC=9E=85=EB=A0=A5=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 8 ++++---- .../global/exception/ErrorMessage.java | 3 ++- src/main/java/racingcar/view/InputView.java | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 3cbd1c88ca2..c4b7923e4f9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,10 +16,10 @@ ### μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•˜λŠ” κΈ°λŠ₯ -- [ ] `μ‹œλ„ν•  νšŒμˆ˜λŠ” λͺ‡νšŒμΈκ°€μš”?`λ₯Ό 좜λ ₯ν•œλ‹€. -- [ ] μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•œλ‹€. - - [ ] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. - - [ ] 1 μ΄μƒμ˜ 숫자둜 이루어져 μžˆμŒμ„ κ²€μ¦ν•œλ‹€. +- [x] `μ‹œλ„ν•  νšŒμˆ˜λŠ” λͺ‡νšŒμΈκ°€μš”?`λ₯Ό 좜λ ₯ν•œλ‹€. +- [x] μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•œλ‹€. + - [x] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. + - [x] 1 μ΄μƒμ˜ 숫자둜 이루어져 μžˆμŒμ„ κ²€μ¦ν•œλ‹€. ### μžλ™μ°¨λ₯Ό μ „μ§„ν•˜λŠ” κΈ°λŠ₯ diff --git a/src/main/java/racingcar/global/exception/ErrorMessage.java b/src/main/java/racingcar/global/exception/ErrorMessage.java index 749039cce6c..a1e998169f8 100644 --- a/src/main/java/racingcar/global/exception/ErrorMessage.java +++ b/src/main/java/racingcar/global/exception/ErrorMessage.java @@ -3,7 +3,8 @@ public enum ErrorMessage { BLANK_INPUT_ERROR("빈 λ¬Έμžμ—΄μ΄ μž…λ ₯λ˜μ—ˆμŠ΅λ‹ˆλ‹€."), INVALID_LENGTH_ERROR("잘λͺ»λœ 길이의 λ¬Έμžμ—΄μ„ μž…λ ₯ν•˜μ˜€μŠ΅λ‹ˆλ‹€. "), - DUPLICATED_CAR_ERROR("μžλ™μ°¨μ˜ 이름이 μ€‘λ³΅λ˜μ—ˆμŠ΅λ‹ˆλ‹€."); + DUPLICATED_CAR_ERROR("μžλ™μ°¨μ˜ 이름이 μ€‘λ³΅λ˜μ—ˆμŠ΅λ‹ˆλ‹€."), + INVALID_TRY_COUNT_ERROR("잘λͺ»λœ μ‹œλ„ 횟수의 μž…λ ₯μž…λ‹ˆλ‹€."); private final String message; diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java index 28c094734de..44a9cee6336 100644 --- a/src/main/java/racingcar/view/InputView.java +++ b/src/main/java/racingcar/view/InputView.java @@ -10,16 +10,23 @@ public class InputView { private static final String CAR_NAMES_NOTICE = "κ²½μ£Όν•  μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”.(이름은 μ‰Όν‘œ(,) κΈ°μ€€μœΌλ‘œ ꡬ뢄)`λ₯Ό 좜λ ₯ν•œλ‹€."; public static final String CAR_NAMES_SEPARATOR = ","; + public static final String TRY_COUNT_NOTICE = "μ‹œλ„ν•  νšŒμˆ˜λŠ” λͺ‡νšŒμΈκ°€μš”?"; public List readCarNames() { ConsoleWriter.printlnMessage(CAR_NAMES_NOTICE); return Validator.validateCarNames(ConsoleReader.enterMessage()); } + public int readTryCount() { + ConsoleWriter.printlnMessage(TRY_COUNT_NOTICE); + return Validator.validateNumber(ConsoleReader.enterMessage()); + } + private static class Validator { private static List validateCarNames(String message) { List cars = parseStringToList(message, CAR_NAMES_SEPARATOR); validateDuplicated(cars); + return cars; } private static void validateDuplicated(List items) { @@ -45,5 +52,16 @@ private static List parseStringToList(String message, String separator) private static String[] split(String message, String separator) { return message.split(separator, -1); } + + private static int validateNumber(String message) { + if (isNotNumber(message)) { + throw CustomException.from(ErrorMessage.INVALID_TRY_COUNT_ERROR); + } + return Integer.parseInt(message); + } + + private static boolean isNotNumber(String str) { + return !str.matches("^[1-9]+$"); + } } } From ba7ea294ea0448b1a753967af4ea9ab9758269e2 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:36:42 +0900 Subject: [PATCH 09/16] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=ED=95=9C=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98=EB=A7=8C=ED=81=BC=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=EB=A5=BC=20=EC=A0=84=EC=A7=84=EC=8B=9C=ED=82=A4?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../racingcar/controller/GameManager.java | 41 +++++++++++++++++++ src/main/java/racingcar/domain/Cars.java | 4 ++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/controller/GameManager.java diff --git a/docs/README.md b/docs/README.md index c4b7923e4f9..2250c1f7d8b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,7 +23,7 @@ ### μžλ™μ°¨λ₯Ό μ „μ§„ν•˜λŠ” κΈ°λŠ₯ -- [ ] μž…λ ₯ν•œ 횟수만큼 μžλ™μ°¨ 전진을 μ‹œλ„ν•œλ‹€. +- [x] μž…λ ₯ν•œ 횟수만큼 μžλ™μ°¨ 전진을 μ‹œλ„ν•œλ‹€. - [ ] λ¬΄μž‘μœ„ 값을 μƒμ„±ν•˜κ³  μ „μ§„ν•˜λŠ” 쑰건을 κ²€μ‚¬ν•œλ‹€. - [ ] 쑰건에 λΆ€ν•©ν•œλ‹€λ©΄ μžλ™μ°¨λ₯Ό μ „μ§„μ‹œν‚¨λ‹€. diff --git a/src/main/java/racingcar/controller/GameManager.java b/src/main/java/racingcar/controller/GameManager.java new file mode 100644 index 00000000000..520cc772c49 --- /dev/null +++ b/src/main/java/racingcar/controller/GameManager.java @@ -0,0 +1,41 @@ +package racingcar.controller; + +import java.util.function.Supplier; +import racingcar.domain.Cars; +import racingcar.view.InputView; +import racingcar.view.console.ConsoleWriter; + +public class GameManager { + private final InputView inputView; + + public GameManager(InputView inputView) { + this.inputView = inputView; + } + + public void run() { + Cars cars = retry(() -> { + return new Cars(inputView.readCarNames()); + }); + int count = retry(() -> { + return inputView.readTryCount(); + }); + + for (int i = 0; i < count; i++) { + play(cars); + } + } + + private void play(Cars cars) { + cars.moveCars(); + } + + private static T retry(Supplier supplier) { + while (true) { + try { + return supplier.get(); + } catch (IllegalArgumentException e) { + ConsoleWriter.printlnMessage(e.getMessage()); + } + } + } +} diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index d006626f2e4..72b8a0e33da 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -14,4 +14,8 @@ private List generateToCars(List cars) { .map(name -> new Car(new Name(name))) .toList(); } + + public void moveCars() { + + } } From d6244518f814c47cf89fe3473f463f91b75a6e51 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:41:24 +0900 Subject: [PATCH 10/16] =?UTF-8?q?feat:=20=EB=AC=B4=EC=9E=91=EC=9C=84=20?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20=ED=86=B5=ED=95=B4=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=EB=A5=BC=20=EC=A0=84=EC=A7=84=EC=8B=9C=ED=82=A4?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++-- src/main/java/racingcar/domain/Car.java | 20 +++++++++++++++++++ src/main/java/racingcar/domain/Cars.java | 4 +++- .../global/util/RandomNumberGenerator.java | 10 ++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/main/java/racingcar/global/util/RandomNumberGenerator.java diff --git a/docs/README.md b/docs/README.md index 2250c1f7d8b..75edc956d4d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,8 +24,8 @@ ### μžλ™μ°¨λ₯Ό μ „μ§„ν•˜λŠ” κΈ°λŠ₯ - [x] μž…λ ₯ν•œ 횟수만큼 μžλ™μ°¨ 전진을 μ‹œλ„ν•œλ‹€. -- [ ] λ¬΄μž‘μœ„ 값을 μƒμ„±ν•˜κ³  μ „μ§„ν•˜λŠ” 쑰건을 κ²€μ‚¬ν•œλ‹€. -- [ ] 쑰건에 λΆ€ν•©ν•œλ‹€λ©΄ μžλ™μ°¨λ₯Ό μ „μ§„μ‹œν‚¨λ‹€. +- [x] λ¬΄μž‘μœ„ 값을 μƒμ„±ν•˜κ³  μ „μ§„ν•˜λŠ” 쑰건을 κ²€μ‚¬ν•œλ‹€. +- [x] 쑰건에 λΆ€ν•©ν•œλ‹€λ©΄ μžλ™μ°¨λ₯Ό μ „μ§„μ‹œν‚¨λ‹€. ### μžλ™μ°¨μ˜ μƒνƒœλ₯Ό 좜λ ₯ν•˜λŠ” κΈ°λŠ₯ diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java index c4e6b18363c..c10923b2bc2 100644 --- a/src/main/java/racingcar/domain/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -1,6 +1,12 @@ package racingcar.domain; +import racingcar.global.util.RandomNumberGenerator; + public class Car { + private static final int THRESHOLD = 4; + private static final int START = 0; + private static final int END = 9; + public static final int INTERVAL = 1; private Name name; private int moved; @@ -8,4 +14,18 @@ public Car(Name name) { this.name = name; this.moved = 0; } + + public void move() { + if (canMove()) { + moved += INTERVAL; + } + } + + private boolean canMove() { + int number = RandomNumberGenerator.generate(START, END); + if (number >= THRESHOLD) { + return true; + } + return false; + } } diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index 72b8a0e33da..ef8e8e5c204 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -16,6 +16,8 @@ private List generateToCars(List cars) { } public void moveCars() { - + for (Car car : cars) { + car.move(); + } } } diff --git a/src/main/java/racingcar/global/util/RandomNumberGenerator.java b/src/main/java/racingcar/global/util/RandomNumberGenerator.java new file mode 100644 index 00000000000..e2c4f8fbbfe --- /dev/null +++ b/src/main/java/racingcar/global/util/RandomNumberGenerator.java @@ -0,0 +1,10 @@ +package racingcar.global.util; + +import camp.nextstep.edu.missionutils.Randoms; + +public class RandomNumberGenerator { + + public static int generate(int start, int end) { + return Randoms.pickNumberInRange(start, end); + } +} From 5b539da0eece881971b89281ad4cbd8707b72966 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 16:48:36 +0900 Subject: [PATCH 11/16] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=EC=9D=98=20=EC=83=81=ED=83=9C=EB=A5=BC=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 +-- .../racingcar/controller/GameManager.java | 6 +++- src/main/java/racingcar/domain/Car.java | 8 ++++++ src/main/java/racingcar/domain/Cars.java | 8 ++++++ src/main/java/racingcar/domain/Name.java | 4 +++ .../global/util/RandomNumberGenerator.java | 1 - src/main/java/racingcar/view/OutputView.java | 28 +++++++++++++++++++ .../racingcar/view/console/ConsoleWriter.java | 4 +++ 8 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/main/java/racingcar/view/OutputView.java diff --git a/docs/README.md b/docs/README.md index 75edc956d4d..316652553cb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -29,8 +29,8 @@ ### μžλ™μ°¨μ˜ μƒνƒœλ₯Ό 좜λ ₯ν•˜λŠ” κΈ°λŠ₯ -- [ ] λͺ¨λ“  μžλ™μ°¨μ˜ 이름과 μ΄λ™ν•œ 갯수λ₯Ό 뷰에 μ „λ‹¬ν•œλ‹€. -- [ ] λ·°μ—μ„œ μžλ™μ°¨ 이름을 좜λ ₯ν•˜κ³  μ΄λ™ν•œ 갯수λ₯Ό `-`둜 좜λ ₯ν•œλ‹€. +- [x] λͺ¨λ“  μžλ™μ°¨μ˜ 이름과 μ΄λ™ν•œ 갯수λ₯Ό 뷰에 μ „λ‹¬ν•œλ‹€. +- [x] λ·°μ—μ„œ μžλ™μ°¨ 이름을 좜λ ₯ν•˜κ³  μ΄λ™ν•œ 갯수λ₯Ό `-`둜 좜λ ₯ν•œλ‹€. ### 우승자λ₯Ό 좜λ ₯ν•˜λŠ” κΈ°λŠ₯ diff --git a/src/main/java/racingcar/controller/GameManager.java b/src/main/java/racingcar/controller/GameManager.java index 520cc772c49..5ff43d72e62 100644 --- a/src/main/java/racingcar/controller/GameManager.java +++ b/src/main/java/racingcar/controller/GameManager.java @@ -3,13 +3,16 @@ import java.util.function.Supplier; import racingcar.domain.Cars; import racingcar.view.InputView; +import racingcar.view.OutputView; import racingcar.view.console.ConsoleWriter; public class GameManager { private final InputView inputView; + private final OutputView outputView; - public GameManager(InputView inputView) { + public GameManager(InputView inputView, OutputView outputView) { this.inputView = inputView; + this.outputView = outputView; } public void run() { @@ -27,6 +30,7 @@ public void run() { private void play(Cars cars) { cars.moveCars(); + outputView.printResult(cars); } private static T retry(Supplier supplier) { diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java index c10923b2bc2..a05007d24a6 100644 --- a/src/main/java/racingcar/domain/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -28,4 +28,12 @@ private boolean canMove() { } return false; } + + public int getMoved() { + return moved; + } + + public String getName() { + return name.getValue(); + } } diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index ef8e8e5c204..d5e4065746e 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -20,4 +20,12 @@ public void moveCars() { car.move(); } } + + public int size() { + return cars.size(); + } + + public Car get(int i) { + return cars.get(i); + } } diff --git a/src/main/java/racingcar/domain/Name.java b/src/main/java/racingcar/domain/Name.java index e7fb4601aa9..0a8fe83adf2 100644 --- a/src/main/java/racingcar/domain/Name.java +++ b/src/main/java/racingcar/domain/Name.java @@ -13,6 +13,10 @@ public Name(String name) { this.name = name; } + public String getValue() { + return name; + } + public static class Validator { private static void validateRange(int length, int start, int end) { if (isInvalidRange(length, start, end)) { diff --git a/src/main/java/racingcar/global/util/RandomNumberGenerator.java b/src/main/java/racingcar/global/util/RandomNumberGenerator.java index e2c4f8fbbfe..9f27d67da44 100644 --- a/src/main/java/racingcar/global/util/RandomNumberGenerator.java +++ b/src/main/java/racingcar/global/util/RandomNumberGenerator.java @@ -3,7 +3,6 @@ import camp.nextstep.edu.missionutils.Randoms; public class RandomNumberGenerator { - public static int generate(int start, int end) { return Randoms.pickNumberInRange(start, end); } diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java new file mode 100644 index 00000000000..7d761203c5d --- /dev/null +++ b/src/main/java/racingcar/view/OutputView.java @@ -0,0 +1,28 @@ +package racingcar.view; + +import racingcar.domain.Car; +import racingcar.domain.Cars; +import racingcar.view.console.ConsoleWriter; + +public class OutputView { + public static final String RESULT_NOTICE = "μ‹€ν–‰ κ²°κ³Ό"; + + public void printResult(Cars cars) { + ConsoleWriter.printlnMessage(RESULT_NOTICE); + printCarsStatus(cars); + ConsoleWriter.println(); + } + + private void printCarsStatus(Cars cars) { + for (int i = 0; i < cars.size(); i++) { + Car car = cars.get(i); + printCarStatus(car, i); + } + } + + private void printCarStatus(Car car, int i) { + String name = car.getName(); + int moved = car.getMoved(); + ConsoleWriter.printlnMessage(name + " : " + "_".repeat(moved)); + } +} diff --git a/src/main/java/racingcar/view/console/ConsoleWriter.java b/src/main/java/racingcar/view/console/ConsoleWriter.java index 38b391e2631..06636a36d92 100644 --- a/src/main/java/racingcar/view/console/ConsoleWriter.java +++ b/src/main/java/racingcar/view/console/ConsoleWriter.java @@ -8,4 +8,8 @@ public static void printlnMessage(String message) { public static void printlnFormat(String message, Object... args) { printlnMessage(String.format(message, args)); } + + public static void println() { + System.out.println(); + } } From f049fbd216cbb40eda3060c6fe8f5177d5518494 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 17:00:56 +0900 Subject: [PATCH 12/16] =?UTF-8?q?feat:=20=EC=9A=B0=EC=8A=B9=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=EA=B0=80=EB=A0=A4=EB=82=B4=EA=B3=A0=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++-- .../racingcar/controller/GameManager.java | 7 +++++++ src/main/java/racingcar/domain/Car.java | 4 ++-- src/main/java/racingcar/domain/Cars.java | 16 +++++++++++++++ src/main/java/racingcar/view/OutputView.java | 20 ++++++++++++++++--- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/docs/README.md b/docs/README.md index 316652553cb..439263e1c0b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -34,6 +34,6 @@ ### 우승자λ₯Ό 좜λ ₯ν•˜λŠ” κΈ°λŠ₯ -- [ ] κ°€μž₯ 많이 μ΄λ™ν•œ μžλ™μ°¨λ₯Ό μ„ μ •ν•œλ‹€. -- [ ] `μ΅œμ’… 우승자 : pobi`와 같이 우승자λ₯Ό 좜λ ₯ν•œλ‹€. +- [x] κ°€μž₯ 많이 μ΄λ™ν•œ μžλ™μ°¨λ₯Ό μ„ μ •ν•œλ‹€. +- [x] `μ΅œμ’… 우승자 : pobi`와 같이 우승자λ₯Ό 좜λ ₯ν•œλ‹€. diff --git a/src/main/java/racingcar/controller/GameManager.java b/src/main/java/racingcar/controller/GameManager.java index 5ff43d72e62..823081adcf3 100644 --- a/src/main/java/racingcar/controller/GameManager.java +++ b/src/main/java/racingcar/controller/GameManager.java @@ -1,5 +1,6 @@ package racingcar.controller; +import java.util.List; import java.util.function.Supplier; import racingcar.domain.Cars; import racingcar.view.InputView; @@ -26,6 +27,7 @@ public void run() { for (int i = 0; i < count; i++) { play(cars); } + complete(); } private void play(Cars cars) { @@ -33,6 +35,11 @@ private void play(Cars cars) { outputView.printResult(cars); } + private void complete(Cars cars) { + List winners = cars.selectWinners(); + outputView.printWinners(winners); + } + private static T retry(Supplier supplier) { while (true) { try { diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java index a05007d24a6..8ab801f4ce0 100644 --- a/src/main/java/racingcar/domain/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -29,11 +29,11 @@ private boolean canMove() { return false; } - public int getMoved() { + public int moved() { return moved; } - public String getName() { + public String name() { return name.getValue(); } } diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index d5e4065746e..cc59b39c03e 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -21,6 +21,22 @@ public void moveCars() { } } + public List selectWinners() { + int maxMoved = getMaxMoved(); + + return cars.stream() + .filter(car -> car.moved() == maxMoved) + .map(Car::name) + .toList(); + } + + private int getMaxMoved() { + return cars.stream() + .mapToInt(car -> car.moved()) + .max() + .orElseThrow(IllegalStateException::new); + } + public int size() { return cars.size(); } diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java index 7d761203c5d..3486c9c77bd 100644 --- a/src/main/java/racingcar/view/OutputView.java +++ b/src/main/java/racingcar/view/OutputView.java @@ -1,11 +1,14 @@ package racingcar.view; +import java.util.List; import racingcar.domain.Car; import racingcar.domain.Cars; import racingcar.view.console.ConsoleWriter; public class OutputView { - public static final String RESULT_NOTICE = "μ‹€ν–‰ κ²°κ³Ό"; + private static final String RESULT_NOTICE = "μ‹€ν–‰ κ²°κ³Ό"; + private static final String WINNER_NOTICE = "μ΅œμ’… 우승자 : %s"; + private static final String WINNER_SEPARATOR = ", "; public void printResult(Cars cars) { ConsoleWriter.printlnMessage(RESULT_NOTICE); @@ -21,8 +24,19 @@ private void printCarsStatus(Cars cars) { } private void printCarStatus(Car car, int i) { - String name = car.getName(); - int moved = car.getMoved(); + String name = car.name(); + int moved = car.moved(); ConsoleWriter.printlnMessage(name + " : " + "_".repeat(moved)); } + + public void printWinners(List winners) { + ConsoleWriter.printlnFormat( + WINNER_NOTICE, + generateWinnerResult(winners) + ); + } + + private String generateWinnerResult(List winners) { + return String.join(WINNER_SEPARATOR, winners); + } } From 9cbca0040a03439e2628911d2bb99d95b3e43ef1 Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 17:29:30 +0900 Subject: [PATCH 13/16] =?UTF-8?q?feat:=20=EC=96=B4=ED=94=8C=EB=A6=AC?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EC=85=98=20=EC=8B=A4=ED=96=89=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Application.java | 12 +++++++++- .../racingcar/controller/GameManager.java | 22 +++---------------- src/main/java/racingcar/view/OutputView.java | 2 +- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e7242..50cb6d90e69 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,17 @@ package racingcar; +import camp.nextstep.edu.missionutils.Console; +import racingcar.controller.GameManager; +import racingcar.view.InputView; +import racingcar.view.OutputView; + public class Application { public static void main(String[] args) { - // TODO: ν”„λ‘œκ·Έλž¨ κ΅¬ν˜„ + GameManager gameManager = new GameManager( + new InputView(), + new OutputView() + ); + gameManager.run(); + Console.close(); } } diff --git a/src/main/java/racingcar/controller/GameManager.java b/src/main/java/racingcar/controller/GameManager.java index 823081adcf3..be948fc271d 100644 --- a/src/main/java/racingcar/controller/GameManager.java +++ b/src/main/java/racingcar/controller/GameManager.java @@ -1,11 +1,9 @@ package racingcar.controller; import java.util.List; -import java.util.function.Supplier; import racingcar.domain.Cars; import racingcar.view.InputView; import racingcar.view.OutputView; -import racingcar.view.console.ConsoleWriter; public class GameManager { private final InputView inputView; @@ -17,17 +15,13 @@ public GameManager(InputView inputView, OutputView outputView) { } public void run() { - Cars cars = retry(() -> { - return new Cars(inputView.readCarNames()); - }); - int count = retry(() -> { - return inputView.readTryCount(); - }); + Cars cars = new Cars(inputView.readCarNames()); + int count = inputView.readTryCount(); for (int i = 0; i < count; i++) { play(cars); } - complete(); + complete(cars); } private void play(Cars cars) { @@ -39,14 +33,4 @@ private void complete(Cars cars) { List winners = cars.selectWinners(); outputView.printWinners(winners); } - - private static T retry(Supplier supplier) { - while (true) { - try { - return supplier.get(); - } catch (IllegalArgumentException e) { - ConsoleWriter.printlnMessage(e.getMessage()); - } - } - } } diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java index 3486c9c77bd..4c89bda6e3a 100644 --- a/src/main/java/racingcar/view/OutputView.java +++ b/src/main/java/racingcar/view/OutputView.java @@ -26,7 +26,7 @@ private void printCarsStatus(Cars cars) { private void printCarStatus(Car car, int i) { String name = car.name(); int moved = car.moved(); - ConsoleWriter.printlnMessage(name + " : " + "_".repeat(moved)); + ConsoleWriter.printlnMessage(name + " : " + "-".repeat(moved)); } public void printWinners(List winners) { From a1c63e10f8f855573cb34d6f8286d1fcf47b284b Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 17:29:56 +0900 Subject: [PATCH 14/16] =?UTF-8?q?test:=20Car=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=EC=9D=98=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=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 --- src/test/java/racingcar/domain/CarTest.java | 55 +++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/test/java/racingcar/domain/CarTest.java diff --git a/src/test/java/racingcar/domain/CarTest.java b/src/test/java/racingcar/domain/CarTest.java new file mode 100644 index 00000000000..8542b551770 --- /dev/null +++ b/src/test/java/racingcar/domain/CarTest.java @@ -0,0 +1,55 @@ +package racingcar.domain; + +import static org.mockito.Mockito.mockStatic; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import org.mockito.MockedStatic; +import racingcar.global.util.RandomNumberGenerator; + +class CarTest { + + private static MockedStatic generator; + + @BeforeAll + public static void beforeALl() { + generator = mockStatic(RandomNumberGenerator.class); + } + + @AfterAll + public static void afterAll() { + generator.close(); + } + + @Test + @DisplayName("이동 쑰건을 λ§Œμ‘±ν•˜μ—¬ μžλ™μ°¨κ°€ μ΄λ™ν•œλ‹€.") + void moveSuccessTest() { + // given + Car car = new Car(new Name("μžλ™μ°¨")); + BDDMockito.given(RandomNumberGenerator.generate(0, 9)).willReturn(5); + + // when + car.move(); + + // then + Assertions.assertThat(car.moved()).isEqualTo(1); + } + + @Test + @DisplayName("이동 쑰건을 λ§Œμ‘±ν•˜μ§€ λͺ»ν•˜μ—¬ μžλ™μ°¨κ°€ μ΄λ™ν•˜μ§€ μ•ŠλŠ”λ‹€.") + void moveFailTest() { + // given + Car car = new Car(new Name("μžλ™μ°¨")); + BDDMockito.given(RandomNumberGenerator.generate(0, 9)).willReturn(1); + + // when + car.move(); + + // then + Assertions.assertThat(car.moved()).isEqualTo(0); + } +} From 8bfb10462bd1399e235e5062b18dc775e190fd4f Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 17:41:50 +0900 Subject: [PATCH 15/16] =?UTF-8?q?test:=20Cars=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/racingcar/domain/CarsTest.java | 90 ++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/test/java/racingcar/domain/CarsTest.java diff --git a/src/test/java/racingcar/domain/CarsTest.java b/src/test/java/racingcar/domain/CarsTest.java new file mode 100644 index 00000000000..7ccc08ab5b4 --- /dev/null +++ b/src/test/java/racingcar/domain/CarsTest.java @@ -0,0 +1,90 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mockStatic; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import org.mockito.MockedStatic; +import racingcar.global.exception.ErrorMessage; +import racingcar.global.util.RandomNumberGenerator; + +class CarsTest { + private static MockedStatic generator; + + @BeforeAll + public static void beforeALl() { + generator = mockStatic(RandomNumberGenerator.class); + } + + @AfterAll + public static void afterAll() { + generator.close(); + } + + @Test + @DisplayName("μžλ™μ°¨ μ΄λ¦„μ˜ μž…λ ₯으둜 Cars 객체λ₯Ό μƒμ„±ν•œλ‹€.") + void generateToCarsTest() { + // given + List names = Arrays.asList("car1", "car2", "car3"); + Cars cars = new Cars(names); + + // when & then + assertThat(cars.size()).isEqualTo(3); + } + + @Test + @DisplayName("5자 초과의 이름 μž…λ ₯으둜 μ˜ˆμ™Έκ°€ λ°œμƒν•œλ‹€.") + void TooLongCarNameError() { + // given + List names = Arrays.asList("carrrrrr", "car"); + + assertThatThrownBy(() -> new Cars(names)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ErrorMessage.INVALID_LENGTH_ERROR.getMessage()); + } + + @Test + @DisplayName("단일 우승자λ₯Ό μ„±κ³΅μ μœΌλ‘œ κ°€λ €λ‚Έλ‹€.") + void selectSingleWinnersTest() { + // given + List names = Arrays.asList("car1", "car2", "car3"); + BDDMockito.given(RandomNumberGenerator.generate(anyInt(), anyInt())) + .willReturn(3, 6, 1); + Cars cars = new Cars(names); + + // when + cars.moveCars(); + List winners = cars.selectWinners(); + + // then + assertThat(winners.size()).isEqualTo(1); + assertThat(winners.get(0)).isEqualTo("car2"); + } + + @Test + @DisplayName("볡수의 우승자λ₯Ό μ„±κ³΅μ μœΌλ‘œ κ°€λ €λ‚Έλ‹€.") + void selectCoupleWinnersTest() { + // given + List names = Arrays.asList("car1", "car2", "car3"); + BDDMockito.given(RandomNumberGenerator.generate(anyInt(), anyInt())) + .willReturn(4, 6, 1); + Cars cars = new Cars(names); + + // when + cars.moveCars(); + List winners = cars.selectWinners(); + + // then + assertThat(winners.size()).isEqualTo(2); + assertThat(winners.get(0)).isEqualTo("car1"); + assertThat(winners.get(1)).isEqualTo("car2"); + } +} From 311f70a7e9ce081613e8882c2a507cfcc9e92abe Mon Sep 17 00:00:00 2001 From: MingyeomKim Date: Thu, 14 Dec 2023 17:48:03 +0900 Subject: [PATCH 16/16] =?UTF-8?q?docs:=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20?= =?UTF-8?q?=ED=9D=90=EB=A6=84=EB=8F=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 17 ++++++++++------- .../\355\235\220\353\246\204\353\217\204.png" | Bin 0 -> 56665 bytes 2 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 "docs/\355\235\220\353\246\204\353\217\204.png" diff --git a/docs/README.md b/docs/README.md index 439263e1c0b..26cba572bb3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,17 +9,17 @@ - [x] `κ²½μ£Όν•  μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”.(이름은 μ‰Όν‘œ(,) κΈ°μ€€μœΌλ‘œ ꡬ뢄)`λ₯Ό 좜λ ₯ν•œλ‹€. - [x] μžλ™μ°¨μ˜ 이름을 μž…λ ₯λ°›λŠ”λ‹€. - - [x] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. - - [x] μ˜¬λ°”λ₯Έ κ΅¬λΆ„μžλ‘œ κ΅¬λΆ„λ˜μ—ˆμŒμ„ κ²€μ¦ν•œλ‹€. - - [x] μ€‘λ³΅λ˜λŠ” 이름이 μ—†μŒμ„ κ²€μ¦ν•œλ‹€. - - [x] 5자 μ΄ν•˜μ˜ 이름인지 κ²€μ¦ν•œλ‹€. + - [x] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. + - [x] μ˜¬λ°”λ₯Έ κ΅¬λΆ„μžλ‘œ κ΅¬λΆ„λ˜μ—ˆμŒμ„ κ²€μ¦ν•œλ‹€. + - [x] μ€‘λ³΅λ˜λŠ” 이름이 μ—†μŒμ„ κ²€μ¦ν•œλ‹€. + - [x] 5자 μ΄ν•˜μ˜ 이름인지 κ²€μ¦ν•œλ‹€. ### μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•˜λŠ” κΈ°λŠ₯ - [x] `μ‹œλ„ν•  νšŒμˆ˜λŠ” λͺ‡νšŒμΈκ°€μš”?`λ₯Ό 좜λ ₯ν•œλ‹€. - [x] μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•œλ‹€. - - [x] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. - - [x] 1 μ΄μƒμ˜ 숫자둜 이루어져 μžˆμŒμ„ κ²€μ¦ν•œλ‹€. + - [x] 빈 λ¬Έμžμ—΄μ΄ μ•„λ‹˜μ„ κ²€μ¦ν•œλ‹€. + - [x] 1 μ΄μƒμ˜ 숫자둜 이루어져 μžˆμŒμ„ κ²€μ¦ν•œλ‹€. ### μžλ™μ°¨λ₯Ό μ „μ§„ν•˜λŠ” κΈ°λŠ₯ @@ -35,5 +35,8 @@ ### 우승자λ₯Ό 좜λ ₯ν•˜λŠ” κΈ°λŠ₯ - [x] κ°€μž₯ 많이 μ΄λ™ν•œ μžλ™μ°¨λ₯Ό μ„ μ •ν•œλ‹€. -- [x] `μ΅œμ’… 우승자 : pobi`와 같이 우승자λ₯Ό 좜λ ₯ν•œλ‹€. +- [x] `μ΅œμ’… 우승자 : pobi`와 같이 우승자λ₯Ό 좜λ ₯ν•œλ‹€. +# πŸ›  μ‹œμŠ€ν…œ 흐름도 + +![img.png](흐름도.png) diff --git "a/docs/\355\235\220\353\246\204\353\217\204.png" "b/docs/\355\235\220\353\246\204\353\217\204.png" new file mode 100644 index 0000000000000000000000000000000000000000..23fea6a34e7958ffefed8531394de9a062c1bdc5 GIT binary patch literal 56665 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 Z_Ophi#D1d&5JwdXB`$M>?~i~UCm60>V< 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

nqLr4>KT6364z+L&5AYa4U@;! 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 literal 0 HcmV?d00001