From 5405b2d43db226e1519b1555efa7cfa1cc9e9fd2 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:26:38 +0900 Subject: [PATCH 01/25] =?UTF-8?q?docs(README):=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=20=EB=B0=8F=20=EC=98=88=EC=99=B8=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EB=93=B1=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EB=B6=84=EC=84=9D=20README=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/README.md b/README.md index d0286c859f..ae55bce3ac 100644 --- a/README.md +++ b/README.md @@ -1 +1,162 @@ # java-racingcar-precourse + +### ๐Ÿ”‘ ๊ธฐ๋Šฅ ์ •๋ฆฌ + +1. ์‚ฌ์šฉ์ž์—๊ฒŒ ์ž๋™์ฐจ ๊ฒฝ์ฃผํ•  ์ž๋™์ฐจ ์ด๋ฆ„๋“ค๊ณผ ๊ฒฝ์ฃผ ์ฐจ์ˆ˜๋ฅผ ๋ฐ›๋Š”๋‹ค. +2. ๊ฒฝ์ฃผ ์ฐจ์ˆ˜ ๋™์•ˆ n๋Œ€์˜ ์ž๋™์ฐจ๊ฐ€ ์กฐ๊ฑด์— ๋”ฐ๋ผ, ์ „์ง„ ๋˜๋Š” ๋ฉˆ์ถ˜ ์ƒํ™ฉ์„ ์ถœ๋ ฅํ•œ๋‹ค. +3. ๊ฒŒ์ž„์ด ๋๋‚œ ํ›„ ๊ฐ€์žฅ ๋ฉ€๋ฆฌ ์ด๋™ํ•ด ์šฐ์Šนํ•œ ์ž๋™์ฐจ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. + +--- + +### โœ… ๊ตฌํ˜„ ์กฐ๊ฑด + +#### ์ž…๋ ฅ ์กฐ๊ฑด + +์ž๋™์ฐจ ์ด๋ฆ„ + +- [ ] ๊ฒฝ์ฃผํ•  ์ž๋™์ฐจ ์ด๋ฆ„๊ณผ ๊ฒฝ์ฃผ ์ฐจ์ˆ˜ 2๊ฐ€์ง€ ์ž…๋ ฅ ํ•„์š” +- [ ] ์ž๋™์ฐจ ์ด๋ฆ„์€ `,` ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„ +- [ ] ์ž๋™์ฐจ ์ด๋ฆ„์€ 1์ž ์ด์ƒ 5์ž ์ดํ•˜๋งŒ ๊ฐ€๋Šฅํ•จ +- [ ] ์‚ฌ์šฉ์„ฑ์„ ๊ณ ๋ คํ•ด ์ž๋™์ฐจ ์ด๋ฆ„์— ๊ณต๋ฐฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์—†๋Š” ๊ฒƒ์œผ๋กœ ์ฒ˜๋ฆฌํ•จ + +๊ฒฝ์ฃผ ์ฐจ์ˆ˜ + +- [ ] ๊ฒฝ์ฃผ ์ฐจ์ˆ˜๋Š” ์ˆซ์ž์—ฌ์•ผ ํ•จ +- [ ] ๊ฒฝ์ฃผ ์ฐจ์ˆ˜๋Š” ์–‘์˜ ์ •์ˆ˜์—ฌ์•ผ ํ•จ +- [ ] ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ `IllegalArgumentException`์„ ๋ฐœ์ƒ ํ›„ ์ข…๋ฃŒ๋˜์–ด์•ผ ํ•จ + +#### ๋™์ž‘ ์กฐ๊ฑด + +- [ ] ๊ฒฝ์ฃผ๋Š” 1๋ช…์ด์„œ ํ•  ์ˆ˜ ์—†์Œ +- [ ] ์ž…๋ ฅ๋œ ๊ฒฝ์ฃผ ์ฐจ์ˆ˜ ๋™์•ˆ n๋Œ€์˜ ์ž๋™์ฐจ๋Š” ์ „์ง„ ๋˜๋Š” ๋ฉˆ์ถœ ์ˆ˜ ์žˆ์Œ + - [ ] ์ „์ง„ ์กฐ๊ฑด: 0 ~ 9 ์‚ฌ์ด์—์„œ ์ถ”์ถœํ•œ ๋ฌด์ž‘์œ„ ๊ฐ’์ด 4 ์ด์ƒ์ธ ๊ฒฝ์šฐ +- [ ] ๊ฐ ๊ฒฝ์ฃผ๋งˆ๋‹ค ๊ฐ ์ž๋™์ฐจ์˜ ์ด๋™ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅ +- [ ] ์šฐ์Šน์ž๋Š” ํ•œ ๋ช… ์ด์ƒ์ผ ์ˆ˜ ์žˆ์Œ + - [ ] ์šฐ์Šน ์กฐ๊ฑด: ๊ฐ€์žฅ ๋งŽ์ด ์ „์ง„ํ•œ ์ž๋™์ฐจ + +#### ์ถœ๋ ฅ ์กฐ๊ฑด + +- [ ] ์ž๋™์ฐจ ์ด๋ฆ„์€ `,` ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„ +- [ ] ์ „์ง„ํ•˜๋Š” ์ž๋™์ฐจ๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ๋งˆ๋‹ค, ์ „์ง„ํ•œ ์ž๋™์ฐจ ์ด๋ฆ„๊ณผ ์ด๋™๊ฑฐ๋ฆฌ๋ฅผ ์ถœ๋ ฅ (ex `pobi : --`) +- [ ] ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„ ์™„๋ฃŒ ํ›„, ๋ˆ„๊ฐ€ ์šฐ์Šนํ–ˆ๋Š”์ง€ ์ถœ๋ ฅ (ex `์ตœ์ข… ์šฐ์Šน์ž : pobi`) +- [ ] ๊ณต๋™ ์šฐ์Šน์ž์˜ ๊ฒฝ์šฐ `,`๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ถœ๋ ฅ (ex `์ตœ์ข… ์šฐ์Šน์ž : pobi, jun`) +- [ ] ์šฐ์Šน์ž ์ถœ๋ ฅ ์‹œ, ์ž…๋ ฅ ์ˆœ์„œ๋กœ ์ถœ๋ ฅํ•ด์•ผ ํ•จ + +--- + +### ๐Ÿšจ ์˜ˆ์™ธ(IllegalArgumentException) ๋ฐœ์ƒ ์กฐ๊ฑด + +- ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ๋ฐœ์ƒ +- ์ž…๋ ฅํ•ด์•ผ ํ•˜๋Š” ๊ฐ’: `์ž๋™์ฐจ ์ด๋ฆ„`, `๊ฒฝ์ฃผ ์ฐจ์ˆ˜` + +์ž๋™์ฐจ ์ด๋ฆ„ + +1. ์ž๋™์ฐจ ์ด๋ฆ„์ด ๊ณต๋ฐฑ์ด๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ +2. ์ž๋™์ฐจ ์ด๋ฆ„์€ 5์ž ์ดˆ๊ณผ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ +3. ์ž๋™์ฐจ ์ด๋ฆ„ ์ค‘๋ณต ์ž…๋ ฅ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ +4. ์ž๋™์ฐจ ์ด๋ฆ„ ๋ชฉ๋ก์— ์ด๋ฆ„์ด 1๊ฐœ์ผ ๊ฒฝ์šฐ ์˜ˆ์™ธ ๋ฐœ์ƒ + +๊ฒฝ์ฃผ ์ฐจ์ˆ˜ + +1. ๊ฒฝ์ฃผ ์ฐจ์ˆ˜์— ๊ณต๋ฐฑ ์ž…๋ ฅ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ +2. ๊ฒฝ์ฃผ ์ฐจ์ˆ˜์— ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฐ’ ์ž…๋ ฅ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ(`NumberFormatException`์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ) +3. ๊ฒฝ์ฃผ ์ฐจ์ˆ˜์— 0 ์ž…๋ ฅ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ +4. ๊ฒฝ์ฃผ ์ฐจ์ˆ˜์— ์Œ์ˆ˜ ์ž…๋ ฅ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ + +--- + +### ๐Ÿงช ํ…Œ์ŠคํŠธ ๋ชฉ๋ก + +##### **CarTest** + +* [ ] ์„ฑ๊ณต: ์ด๋ฆ„ ๊ธธ์ด 1~5์ž ํ—ˆ์šฉ, ์ƒ์„ฑ ๊ฐ€๋Šฅ +* [ ] ์„ฑ๊ณต: ์ด๋™ ์กฐ๊ฑด ์ถฉ์กฑ ์‹œ ์œ„์น˜ 1 ์ฆ๊ฐ€ +* [ ] ์„ฑ๊ณต: ์ด๋™ ์กฐ๊ฑด ๋ฏธ์ถฉ์กฑ ์‹œ ์œ„์น˜ ์œ ์ง€ +* [ ] ์‹คํŒจ: ์ด๋ฆ„์ด ๊ณต๋ฐฑ์ด๊ฑฐ๋‚˜ 5์ž ์ดˆ๊ณผ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ โ†’ `IllegalArgumentException` + +--- + +##### **CarsTest** + +* [ ] ์„ฑ๊ณต: ์—ฌ๋Ÿฌ ์ž๋™์ฐจ ๋™์‹œ์— ์ด๋™ ๊ฐ€๋Šฅ +* [ ] ์„ฑ๊ณต: ๋ผ์šด๋“œ ์ง„ํ–‰ ์‹œ ์ด๋™ ๊ฑฐ๋ฆฌ ๋ˆ„์  +* [ ] ์‹คํŒจ: ์ž๋™์ฐจ ๋ฆฌ์ŠคํŠธ ๋น„์–ด์žˆ์Œ โ†’ `IllegalArgumentException` +* [ ] ์‹คํŒจ: ์ž๋™์ฐจ 1๋Œ€๋งŒ ์ž…๋ ฅ โ†’ `IllegalArgumentException` +* [ ] ์‹คํŒจ: ์ด๋ฆ„ ์ค‘๋ณต โ†’ `IllegalArgumentException` + +--- + +##### **RandomMovePolicyTest** + +* [ ] ์„ฑ๊ณต: ๋žœ๋ค๊ฐ’ 4 ์ด์ƒ์ด๋ฉด ์‹ค์ œ ์ •์ฑ…์—์„œ true ๋ฐ˜ํ™˜ ๊ฐ€๋Šฅ + +--- + +##### **WinnerCalculatorTest** + +* [ ] ์„ฑ๊ณต: ์ตœ๋Œ€ ์ด๋™ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ ๋ฐ ์šฐ์Šน์ž ํ•„ํ„ฐ๋ง +* [ ] ์‹คํŒจ: ์ž๋™์ฐจ ๋ฆฌ์ŠคํŠธ ๋น„์–ด์žˆ์Œ โ†’ `IllegalArgumentException` + +--- + +##### **RacingServiceTest** + +* [ ] ์„ฑ๊ณต: ์ž๋™์ฐจ ์ด๋ฆ„ ์ž…๋ ฅ ํ›„ trim ์ ์šฉ +* [ ] ์„ฑ๊ณต: ์–‘์˜ ์ •์ˆ˜ ๊ฒฝ์ฃผ ์ฐจ์ˆ˜ ์„ค์ • ๊ฐ€๋Šฅ +* [ ] ์„ฑ๊ณต: ์—ฌ๋Ÿฌ ๋ผ์šด๋“œ ํ›„ ์œ„์น˜ ๋ˆ„์  +* [ ] ์„ฑ๊ณต: ์šฐ์Šน์ž ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜, ์ž…๋ ฅ ์ˆœ์„œ ์œ ์ง€ +* [ ] ์‹คํŒจ: ์ž๋™์ฐจ ์ด๋ฆ„ ์ž…๋ ฅ null/๊ณต๋ฐฑ โ†’ `IllegalArgumentException` +* [ ] ์‹คํŒจ: ๊ฒฝ์ฃผ ์ฐจ์ˆ˜ 0, ์Œ์ˆ˜, ์ˆซ์ž ์•„๋‹˜ โ†’ `IllegalArgumentException` + +--- + +### ๐Ÿ“‘ ๊ตฌํ˜„ ์ˆœ์„œ + +#### 1. ๊ธฐ๋ณธ ์„ธํŒ… + + - jdk 21 ๋ฒ„์ „ ์„ค์ • + - java style guide ์„ค์ • + +#### 2. ๊ฒฝ์ฃผํ•  ์ž๋™์ฐจ ์ด๋ฆ„, ๊ฒฝ์ฃผ ์ฐจ์ˆ˜ ์ž…๋ ฅ๋ฐ›๊ธฐ + + - readLine() ์œผ๋กœ ๋ฌธ์ž์—ด ์ž…๋ ฅ ๋ฐ›๊ธฐ + - ๊ฒฝ์ฃผํ•  ์ž๋™์ฐจ ์ด๋ฆ„ ๋ฐ ๊ฒฝ์ฃผ ์ฐจ์ˆ˜ ์ž…๋ ฅ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ (์˜ˆ์™ธ ๋ฐœ์ƒ ์กฐ๊ฑด ์ฐธ๊ณ ) + - ๊ฒฝ์ฃผํ•  ์ž๋™์ฐจ ์ด๋ฆ„์˜ ๊ฒฝ์šฐ , ๊ธฐ์ค€์œผ๋กœ ๋ถ„ํ• ํ•ด ์ž…๋ ฅ ์ฒ˜๋ฆฌํ•˜๊ธฐ + +#### 3. ์‹คํ–‰ ๊ฒฐ๊ณผ ์ถœ๋ ฅํ•˜๊ธฐ + + - 0~9 ์‚ฌ์ด์˜ ์ˆ˜๋ฅผ ๋žœ๋คํ•˜๊ฒŒ ๋ฝ‘๊ณ , 4 ์ด์ƒ์ธ ๊ฒฝ์šฐ ์ „์ง„์œผ๋กœ ์ฒ˜๋ฆฌ(๊ทธ ์™ธ๋Š” ๋ฉˆ์ถค์œผ๋กœ ์ฒ˜๋ฆฌ) + - ์ „์ง„ ์—ฌ๋ถ€ ํ™•์ธ ํ›„ ์ „์ง„ํ•œ ํšŸ์ˆ˜ ์ฆ๊ฐ€์‹œํ‚ค๊ธฐ + - ๊ฒฝ์ฃผ ์ฐจ์ˆ˜๋งŒํผ ์‹คํ–‰ ๊ฒฐ๊ณผ ์ถœ๋ ฅํ•˜๊ธฐ + +#### 4. ์ตœ์ข… ์šฐ์Šน์ž ๋ฐœํ‘œํ•˜๊ธฐ + + - 1๋ช…์ธ ๊ฒฝ์šฐ ๊ทธ๋ƒฅ ์ถœ๋ ฅ / ๋‹ค์ˆ˜์ธ ๊ฒฝ์šฐ , ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ถœ๋ ฅ + +--- + +### ๐Ÿ“„ ์˜ˆ์‹œ ์ž…์ถœ๋ ฅ + +``` +๊ฒฝ์ฃผํ•  ์ž๋™์ฐจ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”.(์ด๋ฆ„์€ ์‰ผํ‘œ(,) ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„) +pobi,woni,jun +์‹œ๋„ํ•  ํšŸ์ˆ˜๋Š” ๋ช‡ ํšŒ์ธ๊ฐ€์š”? +3 + +์‹คํ–‰ ๊ฒฐ๊ณผ +pobi : - +woni : +jun : - + +pobi : -- +woni : - +jun : -- + +pobi : --- +woni : -- +jun : --- + +์ตœ์ข… ์šฐ์Šน์ž : pobi, jun +``` + +
From 9644837a389fe7c51ad585d3d129485aead2ee6d Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:27:31 +0900 Subject: [PATCH 02/25] =?UTF-8?q?feat(domain):=20Car=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 --- src/main/java/racingcar/domain/Car.java | 42 +++++++++++++++++++++++++ 1 file changed, 42 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 0000000000..0411a934ca --- /dev/null +++ b/src/main/java/racingcar/domain/Car.java @@ -0,0 +1,42 @@ +package racingcar.domain; + +import static racingcar.error.ErrorMessages.CAR_NAME_SIZE_INVALID; + +public class Car { + private final String name; + private final int location; + + private static final int MAX_NAME_LENGTH = 5; + + public Car(String name) { + validateName(name); + this.name = name; + this.location = 0; + } + + private Car(String name, int location) { + this.name = name; + this.location = location; + } + + private void validateName(String name) { + if (name == null || name.isBlank() || name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException(CAR_NAME_SIZE_INVALID.getMessage()); + } + } + + public Car move(boolean isMovable) { + if (isMovable) { + return new Car(name, location + 1); + } + return this; + } + + public String getName() { + return name; + } + + public int getLocation() { + return location; + } +} From 7c0a3c0e6547c1ced60a73a692dd5e4313e0f0c4 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:29:34 +0900 Subject: [PATCH 03/25] =?UTF-8?q?feat(domain):=20Cars=20=EC=9D=BC=EA=B8=89?= =?UTF-8?q?=20=EC=BB=AC=EB=A0=89=EC=85=98=20=EB=8F=84=EC=9E=85=20=EB=B0=8F?= =?UTF-8?q?=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EA=B4=80=EB=A0=A8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=BA=A1=EC=8A=90=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/domain/Cars.java | 53 ++++++++++++++++++++++++ 1 file changed, 53 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 0000000000..e7442af7a2 --- /dev/null +++ b/src/main/java/racingcar/domain/Cars.java @@ -0,0 +1,53 @@ +package racingcar.domain; + +import static racingcar.error.ErrorMessages.CARS_ARE_EMPTY; +import static racingcar.error.ErrorMessages.CARS_NAME_DUPLICATED; +import static racingcar.error.ErrorMessages.CARS_SIZE_INVALID; + +import java.util.List; +import java.util.stream.Collectors; + +public class Cars { + private final List cars; + + public Cars(List cars) { + validateListNotNullAndEmpty(cars); + validateInputNameIsMoreThanOne(cars); + validateUniqueNames(cars); + this.cars = cars; + } + + private static void validateListNotNullAndEmpty(List cars) { + if (cars == null || cars.isEmpty()) { + throw new IllegalArgumentException(CARS_ARE_EMPTY.getMessage()); + } + } + + private static void validateInputNameIsMoreThanOne(List cars) { + if (cars.size() < 2) { + throw new IllegalArgumentException(CARS_SIZE_INVALID.getMessage()); + } + } + + private static void validateUniqueNames(List cars) { + long distinctCount = cars.stream() + .map(Car::getName) + .distinct() + .count(); + + if (distinctCount != cars.size()) { + throw new IllegalArgumentException(CARS_NAME_DUPLICATED.getMessage()); + } + } + + public Cars moveAll(MovePolicy movePolicy) { + List moved = this.cars.stream() + .map(car -> car.move(movePolicy.canMove())) + .collect(Collectors.toList()); + return new Cars(moved); + } + + public List getCars() { + return cars; + } +} From 5d3890d4a2ca3fe1a402c0bb17f2ed31105f9fbb Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:30:51 +0900 Subject: [PATCH 04/25] =?UTF-8?q?feat(domain):=20MovePolicy=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=A0=95=EC=9D=98?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20=EC=A1=B0=EA=B1=B4=20=EC=B6=94?= =?UTF-8?q?=EC=83=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/domain/MovePolicy.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/racingcar/domain/MovePolicy.java diff --git a/src/main/java/racingcar/domain/MovePolicy.java b/src/main/java/racingcar/domain/MovePolicy.java new file mode 100644 index 0000000000..c5bd48cca3 --- /dev/null +++ b/src/main/java/racingcar/domain/MovePolicy.java @@ -0,0 +1,5 @@ +package racingcar.domain; + +public interface MovePolicy { + boolean canMove(); +} From a92b8d7888bbd1034c753da14de502550667fa9b Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:31:27 +0900 Subject: [PATCH 05/25] =?UTF-8?q?feat(util):=20=EB=9E=9C=EB=8D=A4=EA=B0=92?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=EA=B8=B0=20RandomGenerator=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/util/RandomGenerator.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/racingcar/util/RandomGenerator.java diff --git a/src/main/java/racingcar/util/RandomGenerator.java b/src/main/java/racingcar/util/RandomGenerator.java new file mode 100644 index 0000000000..10430ba0ab --- /dev/null +++ b/src/main/java/racingcar/util/RandomGenerator.java @@ -0,0 +1,10 @@ +package racingcar.util; + +import camp.nextstep.edu.missionutils.Randoms; + +public class RandomGenerator { + + public static int generate(int min, int max) { + return Randoms.pickNumberInRange(min, max); + } +} From ad439ca17093914f215b03cc5d3941832580ece4 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:39:08 +0900 Subject: [PATCH 06/25] =?UTF-8?q?feat(domain):=20RandomMovePolicy=EB=A1=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99=20=EC=A1=B0=EA=B1=B4=20=EA=B5=AC=EC=B2=B4?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/domain/RandomMovePolicy.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/racingcar/domain/RandomMovePolicy.java diff --git a/src/main/java/racingcar/domain/RandomMovePolicy.java b/src/main/java/racingcar/domain/RandomMovePolicy.java new file mode 100644 index 0000000000..89f72af3a9 --- /dev/null +++ b/src/main/java/racingcar/domain/RandomMovePolicy.java @@ -0,0 +1,14 @@ +package racingcar.domain; + +import racingcar.util.RandomGenerator; + +public class RandomMovePolicy implements MovePolicy { + private static final int MIN = 0; + private static final int MAX = 9; + private static final int MIN_MOVE_TRIGGER = 4; + + @Override + public boolean canMove() { + return RandomGenerator.generate(MIN, MAX) >= MIN_MOVE_TRIGGER; + } +} From 4e9b65823cf84cb09c2218932d5385a877db6fa8 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:39:51 +0900 Subject: [PATCH 07/25] =?UTF-8?q?feat(domain):=20WinnerCalculator=EB=A1=9C?= =?UTF-8?q?=20=EC=9A=B0=EC=8A=B9=20=EC=9E=90=EB=8F=99=EC=B0=A8=20=ED=8C=90?= =?UTF-8?q?=EB=8B=A8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../racingcar/domain/WinnerCalculator.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/racingcar/domain/WinnerCalculator.java diff --git a/src/main/java/racingcar/domain/WinnerCalculator.java b/src/main/java/racingcar/domain/WinnerCalculator.java new file mode 100644 index 0000000000..fe2ff4386b --- /dev/null +++ b/src/main/java/racingcar/domain/WinnerCalculator.java @@ -0,0 +1,21 @@ +package racingcar.domain; + +import static racingcar.error.ErrorMessages.CARS_ARE_EMPTY; + +import java.util.List; +import java.util.stream.Collectors; + +public class WinnerCalculator { + + public static List calculateWinners(Cars cars) { + int maxLocation = cars.getCars().stream() + .mapToInt(Car::getLocation) + .max() + .orElseThrow(() -> new IllegalArgumentException(CARS_ARE_EMPTY.getMessage())); + + return cars.getCars().stream() + .filter(car -> car.getLocation() == maxLocation) + .map(Car::getName) + .collect(Collectors.toList()); + } +} From dc4acfa9de0fb32375a04337ac2f161c915c1f2f Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:40:04 +0900 Subject: [PATCH 08/25] =?UTF-8?q?feat(service):=20RacingService=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/service/RacingService.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/main/java/racingcar/service/RacingService.java diff --git a/src/main/java/racingcar/service/RacingService.java b/src/main/java/racingcar/service/RacingService.java new file mode 100644 index 0000000000..a72a0a58d5 --- /dev/null +++ b/src/main/java/racingcar/service/RacingService.java @@ -0,0 +1,51 @@ +package racingcar.service; + +import static racingcar.error.ErrorMessages.CAR_NAME_INPUT_IS_EMPTY; +import static racingcar.error.ErrorMessages.ROUND_COUNT_INPUT_IS_NOT_PLUS; + +import java.util.Arrays; +import java.util.List; +import racingcar.domain.Car; +import racingcar.domain.Cars; +import racingcar.domain.MovePolicy; +import racingcar.domain.WinnerCalculator; + +public class RacingService { + public static final String NAME_SEPARATOR = ","; + private Cars cars; + private final MovePolicy movePolicy; + + public RacingService(MovePolicy movePolicy) { + this.movePolicy = movePolicy; + } + + public void initCars(String namesInput) { + List cars = Arrays.stream(namesInput.split(NAME_SEPARATOR)) + .map(String::trim) + .map(Car::new) + .toList(); + + this.cars = new Cars(cars); + } + + public static void validateInputNamesIsNotNullAndEmpty(String namesInput) { + if (namesInput == null || namesInput.isBlank()) { + throw new IllegalArgumentException(CAR_NAME_INPUT_IS_EMPTY.getMessage()); + } + } + + public static void validateInputRoundCountIsPlus(int roundCount) { + if (roundCount <= 0) { + throw new IllegalArgumentException(ROUND_COUNT_INPUT_IS_NOT_PLUS.getMessage()); + } + } + + public Cars playRound() { + cars = cars.moveAll(movePolicy); + return cars; + } + + public List getWinners() { + return WinnerCalculator.calculateWinners(cars); + } +} From 5f3238c19fcc0a93222742e798c792ab4975b5b0 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:40:36 +0900 Subject: [PATCH 09/25] =?UTF-8?q?feat(view):=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=97=90=EA=B2=8C=20=EC=9E=85=EC=B6=9C=EB=A0=A5=20=EB=B0=9B?= =?UTF-8?q?=EA=B8=B0=20=EC=9C=84=ED=95=9C=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EB=A6=AC=EC=86=8C=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/view/ViewMessages.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/java/racingcar/view/ViewMessages.java diff --git a/src/main/java/racingcar/view/ViewMessages.java b/src/main/java/racingcar/view/ViewMessages.java new file mode 100644 index 0000000000..1d5b019943 --- /dev/null +++ b/src/main/java/racingcar/view/ViewMessages.java @@ -0,0 +1,22 @@ +package racingcar.view; + + +public enum ViewMessages { + + INPUT_VIEW_QUESTION_CAR_NAMES("๊ฒฝ์ฃผํ•  ์ž๋™์ฐจ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”.(์ด๋ฆ„์€ ์‰ผํ‘œ(,) ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„)"), + INPUT_VIEW_QUESTION_ROUND_COUNT("์‹œ๋„ํ•  ํšŸ์ˆ˜๋Š” ๋ช‡ ํšŒ์ธ๊ฐ€์š”?"), + OUTPUT_VIEW_ROUND_RESULT_TITLE("\n์‹คํ–‰ ๊ฒฐ๊ณผ"), + OUTPUT_VIEW_ROUND_RESULT_MOVE_SYMBOL("-"), + OUTPUT_VIEW_FINAL_RESULT_WINNER("์ตœ์ข… ์šฐ์Šน์ž : "), + OUTPUT_VIEW_FINAL_RESULT_WINNER_SEPARATOR(", "); + + private final String message; + + ViewMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} From 3f5ce98c1ed1adb30d75275f8f3ebc865834248b Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:40:57 +0900 Subject: [PATCH 10/25] =?UTF-8?q?feat(view):=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EC=9E=85=EC=B6=9C=EB=A0=A5=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20view=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 --- src/main/java/racingcar/view/InputView.java | 25 +++++++++++++++++++ src/main/java/racingcar/view/OutputView.java | 26 ++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/main/java/racingcar/view/InputView.java create mode 100644 src/main/java/racingcar/view/OutputView.java diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java new file mode 100644 index 0000000000..8f9f3c3a63 --- /dev/null +++ b/src/main/java/racingcar/view/InputView.java @@ -0,0 +1,25 @@ +package racingcar.view; + +import static racingcar.error.ErrorMessages.ROUND_COUNT_INPUT_MUST_VALID_NUMBER; +import static racingcar.view.ViewMessages.INPUT_VIEW_QUESTION_CAR_NAMES; +import static racingcar.view.ViewMessages.INPUT_VIEW_QUESTION_ROUND_COUNT; + +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + + public String readCarNames() { + System.out.println(INPUT_VIEW_QUESTION_CAR_NAMES); + return Console.readLine(); + } + + public int readRoundCount() { + System.out.println(INPUT_VIEW_QUESTION_ROUND_COUNT); + try { + return Integer.parseInt(Console.readLine()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(ROUND_COUNT_INPUT_MUST_VALID_NUMBER.getMessage(), e); + } + } + +} diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java new file mode 100644 index 0000000000..f1f7e083ab --- /dev/null +++ b/src/main/java/racingcar/view/OutputView.java @@ -0,0 +1,26 @@ +package racingcar.view; + +import static racingcar.view.ViewMessages.OUTPUT_VIEW_FINAL_RESULT_WINNER; +import static racingcar.view.ViewMessages.OUTPUT_VIEW_FINAL_RESULT_WINNER_SEPARATOR; +import static racingcar.view.ViewMessages.OUTPUT_VIEW_ROUND_RESULT_MOVE_SYMBOL; +import static racingcar.view.ViewMessages.OUTPUT_VIEW_ROUND_RESULT_TITLE; + +import java.util.List; +import racingcar.domain.Cars; + +public class OutputView { + public void printRoundResultTitle() { + System.out.println(OUTPUT_VIEW_ROUND_RESULT_TITLE.getMessage()); + } + + public void printRoundResult(Cars cars) { + cars.getCars().forEach(car -> System.out.println(car.getName() + " : " + + OUTPUT_VIEW_ROUND_RESULT_MOVE_SYMBOL.getMessage().repeat(car.getLocation()))); + System.out.println(); + } + + public void printWinners(List winners) { + System.out.println(OUTPUT_VIEW_FINAL_RESULT_WINNER.getMessage() + + String.join(OUTPUT_VIEW_FINAL_RESULT_WINNER_SEPARATOR.getMessage(), winners)); + } +} From 1026c075c87472a2616df8da53e0a4f36220a0ef Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:42:11 +0900 Subject: [PATCH 11/25] =?UTF-8?q?feat(controller):=20RacingController=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=8B=A4=ED=96=89=20=ED=9D=90=EB=A6=84=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RacingController.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/racingcar/controller/RacingController.java diff --git a/src/main/java/racingcar/controller/RacingController.java b/src/main/java/racingcar/controller/RacingController.java new file mode 100644 index 0000000000..0f52bb11c6 --- /dev/null +++ b/src/main/java/racingcar/controller/RacingController.java @@ -0,0 +1,42 @@ +package racingcar.controller; + +import racingcar.domain.Cars; +import racingcar.service.RacingService; +import racingcar.view.InputView; +import racingcar.view.OutputView; + +public class RacingController { + + private final InputView inputView; + private final OutputView outputView; + private final RacingService racingService; + + public RacingController(InputView inputView, OutputView outputView, RacingService racingService) { + this.inputView = inputView; + this.outputView = outputView; + this.racingService = racingService; + } + + public void run() { + // ์ž…๋ ฅ ๊ฐ’ ๋ฐ›์•„์˜ค๊ธฐ (๊ฒฝ์ฃผํ•  ์ž๋™์ฐจ ์ด๋ฆ„, ๊ฒฝ์ฃผ ์ฐจ์ˆ˜) + String namesInput = inputView.readCarNames(); + int roundCount = inputView.readRoundCount(); + + // ์ž…๋ ฅ๊ฐ’ ์œ ํšจ์„ฑ ๊ฒ€์ฆ + RacingService.validateInputNamesIsNotNullAndEmpty(namesInput); + RacingService.validateInputRoundCountIsPlus(roundCount); + + // ์ž๋™์ฐจ ์ด๋ฆ„ ๊ฐ’ ๊ฒ€์ฆ ๋ฐ Cars ๊ฐ์ฒด ์ƒ์„ฑ + racingService.initCars(namesInput); + + // ๊ฒฝ์ฃผ ์ฐจ์ˆ˜์— ๋”ฐ๋ฅธ ๊ฒฐ๊ณผ ์ถœ๋ ฅ + outputView.printRoundResultTitle(); + for (int i = 0; i < roundCount; i++) { + Cars cars = racingService.playRound(); + outputView.printRoundResult(cars); + } + + // ๊ฒฝ์ฃผ ์Šน์ž ์ถœ๋ ฅ + outputView.printWinners(racingService.getWinners()); + } +} From 3527baa3545e82b36f3b8c93ae05e64c9dd62dbb Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:49:01 +0900 Subject: [PATCH 12/25] =?UTF-8?q?feat(error):=20IllegalArgumentException?= =?UTF-8?q?=20=EB=B0=9C=EC=83=9D=20=EC=8B=9C=20=EB=82=98=EC=98=A4=EB=8A=94?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/error/ErrorMessages.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/racingcar/error/ErrorMessages.java diff --git a/src/main/java/racingcar/error/ErrorMessages.java b/src/main/java/racingcar/error/ErrorMessages.java new file mode 100644 index 0000000000..46eaabf511 --- /dev/null +++ b/src/main/java/racingcar/error/ErrorMessages.java @@ -0,0 +1,23 @@ +package racingcar.error; + + +public enum ErrorMessages { + + ROUND_COUNT_INPUT_IS_NOT_PLUS("๊ฒฝ์ฃผ ์ฐจ์ˆ˜๋Š” ์–‘์ˆ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."), + ROUND_COUNT_INPUT_MUST_VALID_NUMBER("๊ฒฝ์ฃผ ์ฐจ์ˆ˜๋Š” ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."), + CAR_NAME_INPUT_IS_EMPTY("์ž๋™์ฐจ ์ด๋ฆ„์ด ์ž…๋ ฅ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."), + CAR_NAME_SIZE_INVALID("์ž๋™์ฐจ ์ด๋ฆ„์€ 1~5์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."), + CARS_ARE_EMPTY("์ž๋™์ฐจ ๋ชฉ๋ก์ด ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค."), + CARS_SIZE_INVALID("์ž๋™์ฐจ ์ด๋ฆ„์€ ๋‘ ๊ฐœ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."), + CARS_NAME_DUPLICATED("์ž๋™์ฐจ ์ด๋ฆ„์ด ์ค‘๋ณต๋ฉ๋‹ˆ๋‹ค."); + + private final String message; + + ErrorMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} From 02a37a4df06cac9a4668d5d709271e2de75cb455 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:49:57 +0900 Subject: [PATCH 13/25] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EB=9E=A8=20=EC=8B=A4=ED=96=89=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EC=A7=84=EC=9E=85=EC=A0=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Application.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e724..16ad1a47ff 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,18 @@ package racingcar; +import racingcar.controller.RacingController; +import racingcar.domain.RandomMovePolicy; +import racingcar.service.RacingService; +import racingcar.view.InputView; +import racingcar.view.OutputView; + public class Application { public static void main(String[] args) { - // TODO: ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„ + RacingController controller = new RacingController( + new InputView(), + new OutputView(), + new RacingService(new RandomMovePolicy()) + ); + controller.run(); } } From d43a9f70e96b5b201dac0aa10a35c5568e32100e Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:50:43 +0900 Subject: [PATCH 14/25] =?UTF-8?q?test(domain):=20Car=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=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 --- src/test/java/racingcar/domain/CarTest.java | 45 +++++++++++++++++++++ 1 file changed, 45 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 0000000000..6b64c6e55a --- /dev/null +++ b/src/test/java/racingcar/domain/CarTest.java @@ -0,0 +1,45 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@DisplayName("Car ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ") +class CarTest { + + @Test + @DisplayName("์„ฑ๊ณต: ์ด๋ฆ„ ๊ธธ์ด 1~5์ž๋ฉด ์ƒ์„ฑ ๊ฐ€๋Šฅ") + void ์„ฑ๊ณต_์ด๋ฆ„_๊ธธ์ด_1_5์ž_ํ—ˆ์šฉ_์ƒ์„ฑ_๊ฐ€๋Šฅ() { + assertThatCode(() -> new Car("pobi")) + .doesNotThrowAnyException(); + } + + @Test + @DisplayName("์„ฑ๊ณต: ์ด๋™ ์กฐ๊ฑด ์ถฉ์กฑ ์‹œ ์œ„์น˜ 1 ์ฆ๊ฐ€") + void ์„ฑ๊ณต_์ด๋™_์กฐ๊ฑด_์ถฉ์กฑ์‹œ_์œ„์น˜_์ฆ๊ฐ€() { + Car car = new Car("pobi"); + Car moved = car.move(true); + assertThat(moved.getLocation()).isEqualTo(car.getLocation() + 1); + } + + @Test + @DisplayName("์„ฑ๊ณต: ์ด๋™ ์กฐ๊ฑด ๋ฏธ์ถฉ์กฑ ์‹œ ์œ„์น˜ ์œ ์ง€") + void ์„ฑ๊ณต_์ด๋™_์กฐ๊ฑด_๋ฏธ์ถฉ์กฑ์‹œ_์œ„์น˜_์œ ์ง€() { + Car car = new Car("pobi"); + Car stayed = car.move(false); + assertThat(stayed.getLocation()).isEqualTo(car.getLocation()); + } + + @ParameterizedTest(name = "์ด๋ฆ„์ด \"{0}\"์ด๋ฉด IllegalArgumentException ๋ฐœ์ƒ") + @ValueSource(strings = {"", " ", "abcdef"}) + @DisplayName("์‹คํŒจ: ์ด๋ฆ„์ด ๊ณต๋ฐฑ์ด๊ฑฐ๋‚˜ 5์ž ์ดˆ๊ณผ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ") + void ์‹คํŒจ_์ž˜๋ชป๋œ_์ด๋ฆ„_์ž…๋ ฅ(String name) { + assertThatThrownBy(() -> new Car(name)) + .isInstanceOf(IllegalArgumentException.class); + } +} From 47b57eebcec69f7ffb96cf0a40c9290a5e1362ed Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:50:52 +0900 Subject: [PATCH 15/25] =?UTF-8?q?test(domain):=20Cars=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=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 --- src/test/java/racingcar/domain/CarsTest.java | 61 ++++++++++++++++++++ 1 file changed, 61 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 0000000000..aa5269f30c --- /dev/null +++ b/src/test/java/racingcar/domain/CarsTest.java @@ -0,0 +1,61 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("Cars ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ") +class CarsTest { + + static Cars cars; + + @BeforeAll + static void setup() { + cars = new Cars(List.of(new Car("a"), new Car("b"))); + } + + @Test + @DisplayName("์„ฑ๊ณต: ์—ฌ๋Ÿฌ ์ž๋™์ฐจ ๋™์‹œ์— ์ด๋™ ๊ฐ€๋Šฅ") + void ์„ฑ๊ณต_์—ฌ๋Ÿฌ_์ž๋™์ฐจ_๋™์‹œ์—_์ด๋™_๊ฐ€๋Šฅ() { + MovePolicy movePolicy = () -> true; + Cars moved = cars.moveAll(movePolicy); + assertThat(moved.getCars()).allMatch(car -> car.getLocation() == 1); + } + + @Test + @DisplayName("์„ฑ๊ณต: ๋ผ์šด๋“œ ์ง„ํ–‰ ์‹œ ์ด๋™ ๊ฑฐ๋ฆฌ ๋ˆ„์ ") + void ์„ฑ๊ณต_๋ผ์šด๋“œ_์ง„ํ–‰์‹œ_์ด๋™_๊ฑฐ๋ฆฌ_๋ˆ„์ () { + Cars cars = new Cars(List.of(new Car("a"), new Car("b"))); + MovePolicy movePolicy = () -> true; + + cars = cars.moveAll(movePolicy); + cars = cars.moveAll(movePolicy); + + assertThat(cars.getCars()).allMatch(car -> car.getLocation() == 2); + } + + @Test + @DisplayName("์‹คํŒจ: ์ž๋™์ฐจ ๋ฆฌ์ŠคํŠธ ๋น„์–ด์žˆ์œผ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ") + void ์‹คํŒจ_์ž๋™์ฐจ_๋ฆฌ์ŠคํŠธ_๋น„์–ด์žˆ์œผ๋ฉด_์˜ˆ์™ธ() { + assertThatThrownBy(() -> new Cars(List.of())) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("์‹คํŒจ: ์ž๋™์ฐจ 1๋Œ€๋งŒ ์ž…๋ ฅํ•˜๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ") + void ์‹คํŒจ_์ž๋™์ฐจ_1๋Œ€๋งŒ_์ž…๋ ฅํ•˜๋ฉด_์˜ˆ์™ธ() { + assertThatThrownBy(() -> new Cars(List.of(new Car("solo")))) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("์‹คํŒจ: ์ž๋™์ฐจ ์ด๋ฆ„ ์ค‘๋ณต์ด๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ") + void ์‹คํŒจ_์ž๋™์ฐจ_์ด๋ฆ„_์ค‘๋ณต์ด๋ฉด_์˜ˆ์™ธ() { + assertThatThrownBy(() -> new Cars(List.of(new Car("a"), new Car("a")))) + .isInstanceOf(IllegalArgumentException.class); + } +} From abbe5965ffcabc773ae21a53bf8c7ff0f9b01246 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:51:06 +0900 Subject: [PATCH 16/25] =?UTF-8?q?test(domain):=20WinnerCalculator=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/WinnerCalculatorTest.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/java/racingcar/domain/WinnerCalculatorTest.java diff --git a/src/test/java/racingcar/domain/WinnerCalculatorTest.java b/src/test/java/racingcar/domain/WinnerCalculatorTest.java new file mode 100644 index 0000000000..c2e886894f --- /dev/null +++ b/src/test/java/racingcar/domain/WinnerCalculatorTest.java @@ -0,0 +1,31 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("WinnerCalculator ๋‹จ์œ„ ํ…Œ์ŠคํŠธ") +class WinnerCalculatorTest { + + @Test + @DisplayName("์„ฑ๊ณต: ์ตœ๋Œ€ ์ด๋™ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ ๋ฐ ์šฐ์Šน์ž ํ•„ํ„ฐ๋ง") + void ์„ฑ๊ณต_์ตœ๋Œ€_์ด๋™_๊ฑฐ๋ฆฌ_๊ณ„์‚ฐ_๋ฐ_์šฐ์Šน์ž_ํ•„ํ„ฐ๋ง() { + Car car1 = new Car("pobi").move(true).move(true); + Car car2 = new Car("jun").move(true); + Cars cars = new Cars(List.of(car1, car2)); + + List winners = WinnerCalculator.calculateWinners(cars); + + assertThat(winners).containsExactly("pobi"); + } + + @Test + @DisplayName(" ์‹คํŒจ: ์ž๋™์ฐจ ๋ฆฌ์ŠคํŠธ ๋น„์–ด์žˆ์œผ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ") + void ์‹คํŒจ_์ž๋™์ฐจ_๋ฆฌ์ŠคํŠธ_๋น„์–ด์žˆ์œผ๋ฉด_์˜ˆ์™ธ() { + assertThatThrownBy(() -> WinnerCalculator.calculateWinners(new Cars(List.of()))) + .isInstanceOf(IllegalArgumentException.class); + } +} From 67936d1be6219b12d94ff13c34f5d7b6e9d1ac00 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:51:19 +0900 Subject: [PATCH 17/25] =?UTF-8?q?test(domain):=20RandomMovePolicy=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/RandomMovePolicyTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/java/racingcar/domain/RandomMovePolicyTest.java diff --git a/src/test/java/racingcar/domain/RandomMovePolicyTest.java b/src/test/java/racingcar/domain/RandomMovePolicyTest.java new file mode 100644 index 0000000000..3a1a877d06 --- /dev/null +++ b/src/test/java/racingcar/domain/RandomMovePolicyTest.java @@ -0,0 +1,20 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.RepeatedTest; + +@DisplayName("RandomMovePolicy ๋‹จ์œ„ ํ…Œ์ŠคํŠธ") +class RandomMovePolicyTest { + + @RepeatedTest(5) + @DisplayName("๋žœ๋ค๊ฐ’ 4 ์ด์ƒ์ด๋ฉด ์‹ค์ œ ์ •์ฑ…์—์„œ true ๋ฐ˜ํ™˜ ๊ฐ€๋Šฅ") + void ์„ฑ๊ณต_๋žœ๋ค๊ฐ’_4์ด์ƒ_์ •์ฑ…_์ „์ง„_ํ™•๋ฅ ๊ฒ€์ฆ() { + RandomMovePolicy policy = new RandomMovePolicy(); + boolean result = policy.canMove(); + + // 4~9 ๊ฐ’์ผ ๋• true, 0~3 ๊ฐ’์ผ ๋• false โ€” Random์ด๋ฏ€๋กœ ํ™•๋ฅ  ํ…Œ์ŠคํŠธ + assertThat(result).isIn(true, false); + } +} From 6cf6583a012544c0cefb24d3b7c9b25893dcd9e1 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:51:51 +0900 Subject: [PATCH 18/25] =?UTF-8?q?test(service):=20RacingService=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../racingcar/service/RacingServiceTest.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/test/java/racingcar/service/RacingServiceTest.java diff --git a/src/test/java/racingcar/service/RacingServiceTest.java b/src/test/java/racingcar/service/RacingServiceTest.java new file mode 100644 index 0000000000..702e55a221 --- /dev/null +++ b/src/test/java/racingcar/service/RacingServiceTest.java @@ -0,0 +1,82 @@ +package racingcar.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; +import racingcar.domain.Car; +import racingcar.domain.Cars; + +@DisplayName("RacingService ๋‹จ์œ„ ํ…Œ์ŠคํŠธ") +class RacingServiceTest { + + @Test + @DisplayName("์„ฑ๊ณต: ์ž๋™์ฐจ ์ด๋ฆ„ ์ž…๋ ฅ ์‹œ trim ์ ์šฉ") + void ์„ฑ๊ณต_์ž๋™์ฐจ_์ด๋ฆ„_์ž…๋ ฅํ›„_trim_์ ์šฉ() { + RacingService service = new RacingService(() -> true); + service.initCars(" pobi , jun "); + + List carNames = service.playRound().getCars() + .stream() + .map(Car::getName) + .toList(); + + assertThat(carNames).containsExactly("pobi", "jun"); + + } + + @Test + @DisplayName("์„ฑ๊ณต: ์–‘์˜ ์ •์ˆ˜ ๊ฒฝ์ฃผ ์ฐจ์ˆ˜ ์„ค์ • ๊ฐ€๋Šฅ") + void ์„ฑ๊ณต_์–‘์˜_์ •์ˆ˜_๊ฒฝ์ฃผ_์ฐจ์ˆ˜_์„ค์ •_๊ฐ€๋Šฅ() { + assertThatCode(() -> RacingService.validateInputRoundCountIsPlus(3)) + .doesNotThrowAnyException(); + } + + @Test + @DisplayName("์„ฑ๊ณต: ์—ฌ๋Ÿฌ ๋ผ์šด๋“œ ํ›„ ์œ„์น˜ ๋ˆ„์ ") + void ์„ฑ๊ณต_์—ฌ๋Ÿฌ_๋ผ์šด๋“œ_ํ›„_์œ„์น˜_๋ˆ„์ () { + RacingService service = new RacingService(() -> true); + service.initCars("pobi,jun"); + + service.playRound(); + Cars result = service.playRound(); + + assertThat(result.getCars()).allMatch(car -> car.getLocation() == 2); + } + + @Test + @DisplayName("์„ฑ๊ณต: ์šฐ์Šน์ž ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜ ๋ฐ ์ž…๋ ฅ ์ˆœ์„œ ์œ ์ง€") + void ์„ฑ๊ณต_์šฐ์Šน์ž_๋ฆฌ์ŠคํŠธ_๋ฐ˜ํ™˜_๋ฐ_์ž…๋ ฅ_์ˆœ์„œ_์œ ์ง€() { + RacingService service = new RacingService(() -> true); + service.initCars("pobi,jun"); + service.playRound(); + List winners = service.getWinners(); + + assertThat(winners).containsExactly("pobi", "jun"); + } + + @ParameterizedTest(name = "์ž…๋ ฅ๊ฐ’ \"{0}\"์ด๋ฉด IllegalArgumentException ๋ฐœ์ƒ") + @NullAndEmptySource + @DisplayName("์‹คํŒจ: ์ž๋™์ฐจ ์ด๋ฆ„ ์ž…๋ ฅ null ๋˜๋Š” ๊ณต๋ฐฑ์ด๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ") + void ์‹คํŒจ_์ž๋™์ฐจ_์ด๋ฆ„_์ž…๋ ฅ_null_๋˜๋Š”_๊ณต๋ฐฑ(String input) { + assertThatThrownBy(() -> RacingService.validateInputNamesIsNotNullAndEmpty(input)) + .isInstanceOf(IllegalArgumentException.class); + } + + + @ParameterizedTest(name = "์ž…๋ ฅ๊ฐ’ \"{0}\"์ด๋ฉด IllegalArgumentException ๋ฐœ์ƒ") + @ValueSource(strings = {"0", "-1", "abc"}) + @DisplayName("์‹คํŒจ: ๊ฒฝ์ฃผ ์ฐจ์ˆ˜๊ฐ€ 0, ์Œ์ˆ˜, ์ˆซ์ž ์•„๋‹˜์ด๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ") + void ์‹คํŒจ_๊ฒฝ์ฃผ_์ฐจ์ˆ˜_์ž˜๋ชป๋œ_์ž…๋ ฅ(String input) { + assertThatThrownBy(() -> { + int roundCount = Integer.parseInt(input); // ์ˆซ์ž ๋ณ€ํ™˜ + RacingService.validateInputRoundCountIsPlus(roundCount); + }).isInstanceOf(IllegalArgumentException.class); + } +} From 05ad46f5d25cb5a9e4bd7cbf68c9951ab662da93 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Mon, 27 Oct 2025 23:53:47 +0900 Subject: [PATCH 19/25] =?UTF-8?q?chore(CHCANGELOG):=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=ED=95=9C=20=EC=BB=A4=EB=B0=8B=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EB=82=B4=EC=9A=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..08283d83b7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,18 @@ +- test(service): RacingService ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ (6cf6583) +- test(domain): RandomMovePolicy ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ (67936d1) +- test(domain): WinnerCalculator ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ (abbe596) +- test(domain): Cars ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ (47b57ee) +- test(domain): Car ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ (d43a9f7) +- feat: ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์„ ์œ„ํ•œ ์ง„์ž…์  ์ถ”๊ฐ€ (02a37a4) +- feat(error): IllegalArgumentException ๋ฐœ์ƒ ์‹œ ๋‚˜์˜ค๋Š” ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ์ถ”๊ฐ€ (3527baa) +- feat(controller): RacingController ํด๋ž˜์Šค ๊ตฌํ˜„ ๋ฐ ๊ฒŒ์ž„ ์‹คํ–‰ ํ๋ฆ„ ๊ด€๋ฆฌ (1026c07) +- feat(view): ์‚ฌ์šฉ์ž์˜ ์ž…์ถœ๋ ฅ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ view ํด๋ž˜์Šค ๊ตฌํ˜„ (3f5ce98) +- feat(view): ์‚ฌ์šฉ์ž์—๊ฒŒ ์ž…์ถœ๋ ฅ ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ฉ”์„ธ์ง€ ๋ฆฌ์†Œ์Šค ์ถ”๊ฐ€ (5f3238c) +- feat(service): RacingService ํด๋ž˜์Šค ๊ตฌํ˜„ ๋ฐ ๊ฒŒ์ž„ ๋กœ์ง ์ œ๊ณต (dc4acfa) +- feat(domain): WinnerCalculator๋กœ ์šฐ์Šน ์ž๋™์ฐจ ํŒ๋‹จ ๊ตฌํ˜„ (4e9b658) +- feat(domain): RandomMovePolicy๋กœ ์ด๋™ ์กฐ๊ฑด ๊ตฌ์ฒดํ™” (ad439ca) +- feat(util): ๋žœ๋ค๊ฐ’ ์ƒ์„ฑ๊ธฐ RandomGenerator ์ถ”๊ฐ€ (a92b8d7) +- feat(domain): MovePolicy ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜๋กœ ์ด๋™ ์กฐ๊ฑด ์ถ”์ƒํ™” (5d3890d) +- feat(domain): Cars ์ผ๊ธ‰ ์ปฌ๋ ‰์…˜ ๋„์ž… ๋ฐ ๋ฆฌ์ŠคํŠธ ๊ด€๋ จ ๋กœ์ง ์บก์Аํ™” (7c0a3c0) +- feat(domain): Car ํด๋ž˜์Šค ๊ตฌํ˜„ (9644837) +- docs(README): ๊ธฐ๋Šฅ ์ •๋ฆฌ ๋ฐ ์˜ˆ์™ธ ์กฐ๊ฑด ๋“ฑ ์š”๊ตฌ์‚ฌํ•ญ ๋ถ„์„ README ์ถ”๊ฐ€ (5405b2d) \ No newline at end of file From 3ab8974dc54b9020725ed66e8afe8e168ed7ab8a Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Tue, 28 Oct 2025 02:49:42 +0900 Subject: [PATCH 20/25] =?UTF-8?q?fix(dto):=20dip=20=EA=B7=9C=EC=B9=99=20?= =?UTF-8?q?=EC=A4=80=EC=88=98=EB=A5=BC=20=EC=9C=84=ED=95=B4=20car=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EC=97=90=20=EB=8C=80=ED=95=9C=20dto=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 --- src/main/java/racingcar/dto/CarDto.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/racingcar/dto/CarDto.java diff --git a/src/main/java/racingcar/dto/CarDto.java b/src/main/java/racingcar/dto/CarDto.java new file mode 100644 index 0000000000..d3def93c96 --- /dev/null +++ b/src/main/java/racingcar/dto/CarDto.java @@ -0,0 +1,5 @@ +package racingcar.dto; + +public record CarDto(String name, int location) { +} + From 463939e10bdeb470b358e760cf84d9f31f7abd6e Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Tue, 28 Oct 2025 03:01:20 +0900 Subject: [PATCH 21/25] =?UTF-8?q?fix(dto):=20dip=20=EA=B7=9C=EC=B9=99=20?= =?UTF-8?q?=EC=A4=80=EC=88=98=EB=A5=BC=20=EC=9C=84=ED=95=B4=20cars=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EC=97=90=20=EB=8C=80=ED=95=9C=20dto=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 --- src/main/java/racingcar/dto/CarsDto.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/racingcar/dto/CarsDto.java diff --git a/src/main/java/racingcar/dto/CarsDto.java b/src/main/java/racingcar/dto/CarsDto.java new file mode 100644 index 0000000000..b2cafdfc00 --- /dev/null +++ b/src/main/java/racingcar/dto/CarsDto.java @@ -0,0 +1,14 @@ +package racingcar.dto; + +import java.util.List; + +public record CarsDto(List carDtoList) { + public CarsDto { + // ๋ถˆ๋ณ€ ๋ฆฌ์ŠคํŠธ๋กœ ๋ณต์‚ฌํ•ด์„œ ์ €์žฅ + carDtoList = List.copyOf(carDtoList); + } + + +} + + From 21b62920ce6014f7426f37fff936de96c60d1b83 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Tue, 28 Oct 2025 03:01:51 +0900 Subject: [PATCH 22/25] =?UTF-8?q?fix(mapper):=20Mapper=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EB=A5=BC=20=ED=86=B5=ED=95=9C=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20>=20dto=20=EB=B3=80=ED=99=98=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/mapper/CarsMapper.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/racingcar/mapper/CarsMapper.java diff --git a/src/main/java/racingcar/mapper/CarsMapper.java b/src/main/java/racingcar/mapper/CarsMapper.java new file mode 100644 index 0000000000..51fe7e1b9c --- /dev/null +++ b/src/main/java/racingcar/mapper/CarsMapper.java @@ -0,0 +1,15 @@ +package racingcar.mapper; + +import java.util.List; +import racingcar.domain.Cars; +import racingcar.dto.CarDto; +import racingcar.dto.CarsDto; + +public class CarsMapper { + public static CarsDto toDto(Cars cars) { + List carDtoList = cars.getCars().stream() + .map(car -> new CarDto(car.getName(), car.getLocation())) + .toList(); + return new CarsDto(carDtoList); + } +} From 1f0ba7fae2a4f4fe7d4c99d69f7ce757952e3c52 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Tue, 28 Oct 2025 03:03:32 +0900 Subject: [PATCH 23/25] =?UTF-8?q?fix(view):=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=95=84=EB=8B=8C=20dto=EB=A1=9C=20=EB=B0=9B=EC=95=84=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/view/OutputView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java index f1f7e083ab..70dc40f804 100644 --- a/src/main/java/racingcar/view/OutputView.java +++ b/src/main/java/racingcar/view/OutputView.java @@ -6,16 +6,16 @@ import static racingcar.view.ViewMessages.OUTPUT_VIEW_ROUND_RESULT_TITLE; import java.util.List; -import racingcar.domain.Cars; +import racingcar.dto.CarsDto; public class OutputView { public void printRoundResultTitle() { System.out.println(OUTPUT_VIEW_ROUND_RESULT_TITLE.getMessage()); } - public void printRoundResult(Cars cars) { - cars.getCars().forEach(car -> System.out.println(car.getName() + " : " - + OUTPUT_VIEW_ROUND_RESULT_MOVE_SYMBOL.getMessage().repeat(car.getLocation()))); + public void printRoundResult(CarsDto cars) { + cars.carDtoList().forEach(car -> System.out.println(car.name() + " : " + + OUTPUT_VIEW_ROUND_RESULT_MOVE_SYMBOL.getMessage().repeat(car.location()))); System.out.println(); } From 62ceabb33142ee4b6544f82e43b178fccc7e2a98 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Tue, 28 Oct 2025 03:03:43 +0900 Subject: [PATCH 24/25] =?UTF-8?q?fix(controller):=20=EA=B0=9D=EC=B2=B4=20d?= =?UTF-8?q?to=20=EB=B3=80=ED=99=98=20=ED=9B=84=20view=EC=97=90=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/controller/RacingController.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/controller/RacingController.java b/src/main/java/racingcar/controller/RacingController.java index 0f52bb11c6..481865d090 100644 --- a/src/main/java/racingcar/controller/RacingController.java +++ b/src/main/java/racingcar/controller/RacingController.java @@ -1,6 +1,8 @@ package racingcar.controller; import racingcar.domain.Cars; +import racingcar.dto.CarsDto; +import racingcar.mapper.CarsMapper; import racingcar.service.RacingService; import racingcar.view.InputView; import racingcar.view.OutputView; @@ -32,8 +34,12 @@ public void run() { // ๊ฒฝ์ฃผ ์ฐจ์ˆ˜์— ๋”ฐ๋ฅธ ๊ฒฐ๊ณผ ์ถœ๋ ฅ outputView.printRoundResultTitle(); for (int i = 0; i < roundCount; i++) { + // ๋ณ€๊ฒฝ๋œ cars ๋ฐ›์•„ dto๋กœ ๋ณ€ํ™˜ Cars cars = racingService.playRound(); - outputView.printRoundResult(cars); + CarsDto carsDto = CarsMapper.toDto(cars); + + // ๊ฒฝ์ฃผ ๋ผ์šด๋“œ ์‹คํ–‰ ๊ฒฐ๊ณผ ์ถœ๋ ฅ + outputView.printRoundResult(carsDto); } // ๊ฒฝ์ฃผ ์Šน์ž ์ถœ๋ ฅ From 3030e3735a4ff4fcb2f1adb236b0e16c359ee876 Mon Sep 17 00:00:00 2001 From: yerim123456 Date: Tue, 28 Oct 2025 03:05:18 +0900 Subject: [PATCH 25/25] =?UTF-8?q?docs(CHANGELOG):=20view=EC=9D=98=20domain?= =?UTF-8?q?=20=EC=B0=B8=EC=A1=B0=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20dip=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20=EC=BB=A4=EB=B0=8B=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08283d83b7..1722da3deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +- fix(controller): ๊ฐ์ฒด dto ๋ณ€ํ™˜ ํ›„ view์— ์ „๋‹ฌํ•˜๋Š” ๋กœ์ง ์ถ”๊ฐ€ (62ceabb) +- fix(view): ๊ฐ์ฒด ์•„๋‹Œ dto๋กœ ๋ฐ›์•„ ์ถœ๋ ฅํ•˜๋„๋ก ์ˆ˜์ • (1f0ba7f) +- fix(mapper): Mapper ํด๋ž˜์Šค๋ฅผ ํ†ตํ•œ ๊ฐ์ฒด > dto ๋ณ€ํ™˜ ๋กœ์ง ์ถ”๊ฐ€ (21b6292) +- fix(dto): dip ๊ทœ์น™ ์ค€์ˆ˜๋ฅผ ์œ„ํ•ด cars ๊ฐ์ฒด์— ๋Œ€ํ•œ dto ์ถ”๊ฐ€ (463939e) +- fix(dto): dip ๊ทœ์น™ ์ค€์ˆ˜๋ฅผ ์œ„ํ•ด car ๊ฐ์ฒด์— ๋Œ€ํ•œ dto ์ถ”๊ฐ€ (3ab8974) +- chore(CHCANGELOG): ์ž‘์„ฑํ•œ ์ปค๋ฐ‹ ๋ฉ”์„ธ์ง€ ์ „์ฒด ๋‚ด์šฉ ์ถ”๊ฐ€ (05ad46f) - test(service): RacingService ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ (6cf6583) - test(domain): RandomMovePolicy ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ (67936d1) - test(domain): WinnerCalculator ํด๋ž˜์Šค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ (abbe596)