-
Notifications
You must be signed in to change notification settings - Fork 28
임경순_BackEnd 객체지향 2주차 #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
92c79ce
fe56b85
22a1925
ee8c6d8
6b491db
53d61e3
1ad3029
6f886e6
ae2b83b
c54b0ab
d6bab98
17cfbe9
35fe5b6
2913239
6ad7e80
c20713c
d963609
fff259c
d4a6b5a
ed4d059
df37a6d
02fa620
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # 입력 기능 | ||
| 경주할 자동차 이름 입력 받기 (쉼표 구분) | ||
| 시도할 횟수 입력 받기 | ||
| # 유효성 검사 기능 | ||
| 자동차 이름이 공백인 경우 IllegalArgumentException 발생 | ||
| 자동차 이름이 5자 초과인 경우 IllegalArgumentException 발생 | ||
| 시도 횟수가 숫자가 아닌 경우 IllegalArgumentException 발생 | ||
| 시도 횟수가 0 이하인 경우 IllegalArgumentException 발생 | ||
| # 자동차 기능 | ||
| 자동차 이름과 위치(position) 관리 | ||
| 0~9 무작위 값이 4 이상이면 전진 | ||
| # 게임 진행 기능 | ||
| 입력한 횟수만큼 라운드 반복 실행 | ||
| 매 라운드 결과 출력 (이름 + 진행 막대) | ||
| # 우승자 계산 및 출력 기능 | ||
| 최대 위치값을 가진 자동차를 우승자로 선정 | ||
| 공동 우승자 쉼표로 구분하여 출력 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| // TODO: 프로그램 구현 | ||
| RacingGame game = new RacingGame(); | ||
| game.run(); | ||
| } | ||
| } | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 코드를 커밋하실 때, 클래스 파일 마지막 줄에는 개행 한 줄 추가하는 것이 권장되고 있습니다 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package racingcar; | ||
|
|
||
| public class Car { | ||
| private final String name; | ||
| private int position; | ||
|
|
||
| public Car(String name) { | ||
| this.name = name; | ||
| this.position = 0; | ||
| } | ||
|
|
||
| public void move() { | ||
| position++; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public int getPosition() { | ||
| return position; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package racingcar; | ||
|
|
||
| import camp.nextstep.edu.missionutils.Console; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class InputHandler { | ||
|
|
||
| public List<Car> readCars() { | ||
| System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); | ||
| String input = Console.readLine(); | ||
| String[] names = input.split(",", -1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 끝에 인자로 |
||
| return parseCars(names); | ||
| } | ||
|
|
||
| private List<Car> parseCars(String[] names) { | ||
| List<Car> cars = new ArrayList<>(); | ||
| for (String name : names) { | ||
| Validator.validateCarName(name.trim()); | ||
| cars.add(new Car(name.trim())); | ||
| } | ||
| return cars; | ||
| } | ||
|
Comment on lines
+16
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| public int readAttemptCount() { | ||
| System.out.println("시도할 회수는 몇회인가요?"); | ||
| String input = Console.readLine(); | ||
| return Validator.validateAndParseAttemptCount(input); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,29 @@ | ||||||||||||||
| package racingcar; | ||||||||||||||
|
|
||||||||||||||
| import java.util.List; | ||||||||||||||
| import java.util.stream.Collectors; | ||||||||||||||
|
|
||||||||||||||
| public class OutputHandler { | ||||||||||||||
|
|
||||||||||||||
| public void printRoundResult(List<Car> cars) { | ||||||||||||||
| for (Car car : cars) { | ||||||||||||||
| System.out.println(car.getName() + " : " + buildProgressBar(car.getPosition())); | ||||||||||||||
| } | ||||||||||||||
| System.out.println(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private String buildProgressBar(int position) { | ||||||||||||||
| StringBuilder sb = new StringBuilder(); | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||
| for (int i = 0; i < position; i++) { | ||||||||||||||
| sb.append("-"); | ||||||||||||||
| } | ||||||||||||||
| return sb.toString(); | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+17
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 작성해주신 코드도 하나의 방법이지만,
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| public void printWinners(List<Car> winners) { | ||||||||||||||
| String names = winners.stream() | ||||||||||||||
| .map(Car::getName) | ||||||||||||||
| .collect(Collectors.joining(", ")); | ||||||||||||||
| System.out.println("최종 우승자 : " + names); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+23
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 스트림 활용해서 잘 해주셨네요! 좋습니다 |
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,67 @@ | ||||||||||||||||||
| package racingcar; | ||||||||||||||||||
|
|
||||||||||||||||||
| import camp.nextstep.edu.missionutils.Randoms; | ||||||||||||||||||
| import java.util.List; | ||||||||||||||||||
| import java.util.stream.Collectors; | ||||||||||||||||||
|
|
||||||||||||||||||
| public class RacingGame { | ||||||||||||||||||
|
|
||||||||||||||||||
| private static final int MOVE_THRESHOLD = 4; | ||||||||||||||||||
|
|
||||||||||||||||||
| private final InputHandler inputHandler; | ||||||||||||||||||
| private final OutputHandler outputHandler; | ||||||||||||||||||
|
|
||||||||||||||||||
| public RacingGame() { | ||||||||||||||||||
| this.inputHandler = new InputHandler(); | ||||||||||||||||||
| this.outputHandler = new OutputHandler(); | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+14
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 작성해주신 것처럼 내부에서 객체를 만들 수도 있지만,
Suggested change
나중에 Spring 프레임워크를 학습하면서 배우게 되겠지만, 이것을 |
||||||||||||||||||
|
|
||||||||||||||||||
| public void run() { | ||||||||||||||||||
| List<Car> cars = inputHandler.readCars(); | ||||||||||||||||||
| int attemptCount = inputHandler.readAttemptCount(); | ||||||||||||||||||
|
|
||||||||||||||||||
| System.out.println(); | ||||||||||||||||||
| System.out.println("실행 결과"); | ||||||||||||||||||
|
|
||||||||||||||||||
| playRounds(cars, attemptCount); | ||||||||||||||||||
|
|
||||||||||||||||||
| outputHandler.printWinners(findWinners(cars)); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void playRounds(List<Car> cars, int attemptCount) { | ||||||||||||||||||
| for (int i = 0; i < attemptCount; i++) { | ||||||||||||||||||
| playOneRound(cars); | ||||||||||||||||||
| outputHandler.printRoundResult(cars); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void playOneRound(List<Car> cars) { | ||||||||||||||||||
| for (Car car : cars) { | ||||||||||||||||||
| moveIfPossible(car); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void moveIfPossible(Car car) { | ||||||||||||||||||
| if (isMovable()) { | ||||||||||||||||||
| car.move(); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private boolean isMovable() { | ||||||||||||||||||
| return Randoms.pickNumberInRange(0, 9) >= MOVE_THRESHOLD; | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+44
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 Car 객체 내부로 옮겨도 좋을 것 같다고 생각이 드는데, 어떻게 생각하시나요?? |
||||||||||||||||||
|
|
||||||||||||||||||
| private List<Car> findWinners(List<Car> cars) { | ||||||||||||||||||
| int maxPosition = findMaxPosition(cars); | ||||||||||||||||||
| return cars.stream() | ||||||||||||||||||
| .filter(car -> car.getPosition() == maxPosition) | ||||||||||||||||||
| .collect(Collectors.toList()); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private int findMaxPosition(List<Car> cars) { | ||||||||||||||||||
| return cars.stream() | ||||||||||||||||||
| .mapToInt(Car::getPosition) | ||||||||||||||||||
| .max() | ||||||||||||||||||
| .orElse(0); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외처리 관련 부분을 별도의 클래스로 만들어서 작성해주셨네요! 좋은 설계입니다 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package racingcar; | ||
|
|
||
| public class Validator { | ||
|
|
||
| private static final int MAX_NAME_LENGTH = 5; | ||
|
|
||
| public static void validateCarName(String name) { | ||
| if (name.isBlank()) { | ||
| throw new IllegalArgumentException("자동차 이름은 공백일 수 없습니다."); | ||
| } | ||
| if (name.length() > MAX_NAME_LENGTH) { | ||
| throw new IllegalArgumentException("자동차 이름은 5자 이하만 가능합니다: " + name); | ||
| } | ||
| } | ||
|
|
||
| public static int validateAndParseAttemptCount(String input) { | ||
| try { | ||
| int count = Integer.parseInt(input.trim()); | ||
| if (count <= 0) { | ||
| throw new IllegalArgumentException("시도 횟수는 1 이상이어야 합니다."); | ||
| } | ||
| return count; | ||
| } catch (NumberFormatException e) { | ||
| throw new IllegalArgumentException("시도 횟수는 숫자여야 합니다."); | ||
| } | ||
| } | ||
|
Comment on lines
+16
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그럴 가능성은 낮겠지만, 만약에 시도 횟수에 정수가 아닌 소수가 들어가게 될 경우에는 어떻게 될까요?? |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package racingcar; | ||
|
|
||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import static org.assertj.core.api.Assertions.*; | ||
|
|
||
| class RacingGameTest { | ||
|
|
||
| @Test | ||
| @DisplayName("자동차가 이동 후 위치가 1 증가한다") | ||
| void carMoveTest() { | ||
| Car car = new Car("pobi"); | ||
| car.move(); | ||
| assertThat(car.getPosition()).isEqualTo(1); | ||
| } | ||
|
|
||
| @Test | ||
| @DisplayName("이동하지 않으면 위치는 0이다") | ||
| void carNoMoveTest() { | ||
| Car car = new Car("woni"); | ||
| assertThat(car.getPosition()).isEqualTo(0); | ||
| } | ||
|
|
||
| @Test | ||
| @DisplayName("자동차 이름이 5자를 초과하면 예외가 발생한다") | ||
| void invalidCarNameLengthTest() { | ||
| assertThatThrownBy(() -> Validator.validateCarName("toolongname")) | ||
| .isInstanceOf(IllegalArgumentException.class); | ||
| } | ||
|
|
||
| @Test | ||
| @DisplayName("자동차 이름이 공백이면 예외가 발생한다") | ||
| void blankCarNameTest() { | ||
| assertThatThrownBy(() -> Validator.validateCarName(" ")) | ||
| .isInstanceOf(IllegalArgumentException.class); | ||
| } | ||
|
|
||
| @Test | ||
| @DisplayName("시도 횟수가 숫자가 아니면 예외가 발생한다") | ||
| void invalidAttemptCountFormatTest() { | ||
| assertThatThrownBy(() -> Validator.validateAndParseAttemptCount("abc")) | ||
| .isInstanceOf(IllegalArgumentException.class); | ||
| } | ||
|
|
||
| @Test | ||
| @DisplayName("시도 횟수가 0 이하이면 예외가 발생한다") | ||
| void invalidAttemptCountRangeTest() { | ||
| assertThatThrownBy(() -> Validator.validateAndParseAttemptCount("0")) | ||
| .isInstanceOf(IllegalArgumentException.class); | ||
| } | ||
|
|
||
| @Test | ||
| @DisplayName("5자 이하의 유효한 이름은 예외가 발생하지 않는다") | ||
| void validCarNameTest() { | ||
| assertThatCode(() -> Validator.validateCarName("pobi")) | ||
| .doesNotThrowAnyException(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
마크다운 파일로 구현할 것들을 정리해주신 것 좋습니다!