diff --git a/build.gradle b/build.gradle index 3697236..797a137 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ version '1.0-SNAPSHOT' repositories { mavenCentral() + maven { url 'https://jitpack.io' } } dependencies { @@ -13,6 +14,8 @@ dependencies { testImplementation platform('org.assertj:assertj-bom:3.25.1') testImplementation('org.junit.jupiter:junit-jupiter') testImplementation('org.assertj:assertj-core') + + implementation 'com.github.kokodak:mission-utils:1.0.0' } java { diff --git a/src/main/java/RacingMain.java b/src/main/java/RacingMain.java deleted file mode 100644 index 4394287..0000000 --- a/src/main/java/RacingMain.java +++ /dev/null @@ -1,7 +0,0 @@ -public class RacingMain { - - public static void main(String[] args) { - // TODO: MVC 패턴을 기반으로 자동차 경주 미션 구현해보기 - System.out.println("Hello, World!"); - } -} diff --git a/src/main/java/controller/RacingMain.java b/src/main/java/controller/RacingMain.java new file mode 100644 index 0000000..0ef03bc --- /dev/null +++ b/src/main/java/controller/RacingMain.java @@ -0,0 +1,18 @@ +package controller; + +import view.InputView; +import view.ResultView; +import domain.RacingGame; + +public class RacingMain { + public static void main(final String... args) { + final var carNames = InputView.getCarNames(); + final var tryCount = InputView.getTryCount(); + + final var racingGame = new RacingGame(carNames, tryCount); + System.out.print("\n실행 결과"); + racingGame.race(); + + ResultView.printWinners(racingGame.getWinners()); + } +} diff --git a/src/main/java/domain/RacingGame.java b/src/main/java/domain/RacingGame.java new file mode 100644 index 0000000..6b79931 --- /dev/null +++ b/src/main/java/domain/RacingGame.java @@ -0,0 +1,67 @@ +package domain; + + +import org.kokodak.Randoms; +import view.ExceptionMessage; +import view.ResultView; + +import java.util.*; + +public class RacingGame { + private final int tryCount; + List carList; + public Map moveCnt; + + public RacingGame(List carNames, int tryCount) { + this.carList = carNames; + this.tryCount = tryCount; + } + + public void race() { + moveCnt = setMoveCnt(carList); + for (int i = 0; i < tryCount; i++) { + System.out.println(); + setRandomMove(); + ResultView.printCarMove(moveCnt); + } + + } + + private Map setMoveCnt(List carList) { + Map moveCnt = new HashMap<>(); + for (String s : carList) { + moveCnt.put(s, 0); + } + return moveCnt; + } + + private void setRandomMove() { + for (int i = 0; i < carList.size(); i++) { + int move = Randoms.pickNumberInRange(0, 9); + canMove(move, i); + } + } + + private void canMove(int move, int i) { + if (move >= 4) { + moveCnt.put(carList.get(i), moveCnt.get(carList.get(i)) + 1); + } + } + + public List getWinners() { + System.out.println(); + for (String s : moveCnt.keySet()) { + String bars = "-".repeat(moveCnt.get(s)); + System.out.println(s + " : " + bars); + } + return findWinners(moveCnt); + } + + private List findWinners(Map moveCnt) { + int max = Collections.max(moveCnt.values()); + return moveCnt.entrySet().stream() + .filter(m -> m.getValue() == max) + .map(Map.Entry::getKey) + .toList(); + } +} diff --git a/src/main/java/view/ExceptionMessage.java b/src/main/java/view/ExceptionMessage.java new file mode 100644 index 0000000..45602a5 --- /dev/null +++ b/src/main/java/view/ExceptionMessage.java @@ -0,0 +1,20 @@ +package view; + +public class ExceptionMessage { + + // 1. 자동차 이름 5자 이상 + public static void isInvalidNameLength() { + System.out.println("[ERROR] 자동차의 이름은 1자 이상 5자 이하여야 한다."); + } + + // 2. 시도 횟수 음수 혹은 0 + public static void isInvalidTryCount() { + System.out.println("[ERROR] 시도 횟수는 양수여야 한다."); + } + + // 3. 자동차 이름 중복 확인 + public static void isDuplicateCarName() { + System.out.println("[ERROR] 자동차 이름은 중복되지 않아야 한다."); + } + +} diff --git a/src/main/java/view/InputValidate.java b/src/main/java/view/InputValidate.java new file mode 100644 index 0000000..bfc187d --- /dev/null +++ b/src/main/java/view/InputValidate.java @@ -0,0 +1,30 @@ +package view; + +import java.util.HashSet; +import java.util.List; + +public class InputValidate { + + + public static void isValidCarName(List carList) { + for (String s : carList) { + isValidCarNameLength(s); + } + } + + public static void isValidCarNameLength(String carName) { + if (carName.length() < 1 || carName.length() > 5) { + ExceptionMessage.isInvalidNameLength(); + throw new IllegalArgumentException(); + } + } + + public static void isDuplicateCarName(List carList) { + HashSet names = new HashSet<>(carList); + System.out.println(); + if (names.size() != carList.size()) { + ExceptionMessage.isDuplicateCarName(); + throw new IllegalArgumentException(); + } + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000..5c4708d --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,69 @@ +package view; + +import org.kokodak.Console; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import static view.InputValidate.isDuplicateCarName; +import static view.InputValidate.isValidCarName; + +public class InputView { + + public static List getCarNames() { + System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."); + return splitCarNames(Console.readLine()); + } + + public static List splitCarNames(String carNames) { + List list; + list = Arrays.stream(carNames.split(",")) + .map(String::trim) + .toList(); + isValidCarName(list); + isDuplicateCarName(list); + return list; + } +// +// private static void isValidCarName(List carList) { +// for (String s : carList) { +// isValidCarNameLength(s); +// } +// } +// +// private static void isValidCarNameLength(String carName) { +// if (carName.length() < 1 || carName.length() > 5) { +// ExceptionMessage.isInvalidNameLength(); +// throw new IllegalArgumentException(); +// } +// } +// +// private static void isDuplicateCarName(List carList) { +// HashSet names = new HashSet<>(carList); +// System.out.println("set size = " + names.size()); +// System.out.println("list size = " + carList.size()); +// System.out.println(); +// if (names.size() != carList.size()) { +// ExceptionMessage.isDuplicateCarName(); +// throw new IllegalArgumentException(); +// } +// } + + + public static int getTryCount() { + System.out.println("시도할 회수는 몇회인가요?"); + String str = Console.readLine(); + int tryCount = Integer.parseInt(str); + isValidTryCount(tryCount); + return tryCount; + } + + private static void isValidTryCount(int tryCount) { + if (tryCount < 1) { + ExceptionMessage.isInvalidTryCount(); + throw new IllegalArgumentException(); + } + } + +} diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java new file mode 100644 index 0000000..1ddd71d --- /dev/null +++ b/src/main/java/view/ResultView.java @@ -0,0 +1,21 @@ +package view; + +import java.util.List; +import java.util.Map; + +public class ResultView { + + public static void printCarMove(Map moveCnt) { + for (String s : moveCnt.keySet()) { + String bars = "-".repeat(moveCnt.get(s)); + System.out.println(s + " : " + bars); + } + } + public static void printWinners(List winners) { + System.out.println(); + for (int i = 0; i < winners.size() - 1; i++) { + System.out.print(winners.get(i) + ", "); + } + System.out.println(winners.get(winners.size() - 1) + "가 최종 우승했습니다."); + } +} diff --git a/src/test/java/domain/RacingGameTest.java b/src/test/java/domain/RacingGameTest.java new file mode 100644 index 0000000..8aa0540 --- /dev/null +++ b/src/test/java/domain/RacingGameTest.java @@ -0,0 +1,9 @@ +package domain; + +import static org.junit.jupiter.api.Assertions.*; + +class RacingGameTest { + + + +} \ No newline at end of file