-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[자동차 경주] 이해승 미션 제출합니다. #1467
base: main
Are you sure you want to change the base?
[자동차 경주] 이해승 미션 제출합니다. #1467
Changes from all commits
f5131a9
a6d725e
86566df
d637765
81fcc92
7dca641
3660d70
5a848b3
81e3d45
fd304a9
f02f625
b1f389a
65c5cc3
fef4a61
d71c6f6
c6d0396
b854187
8c90330
4af7d71
bf28d9e
c31b90f
0d54bb9
4ebbf7d
8c56fec
6eba633
51337b1
2cbaa6f
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 |
---|---|---|
@@ -1 +1,39 @@ | ||
# java-racingcar-precourse | ||
|
||
# 기능 목록 | ||
|
||
- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. | ||
- 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. | ||
- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. | ||
- 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. | ||
- 전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다. | ||
- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. | ||
- 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. | ||
- 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`을 발생시킨 후 애플리케이션은 종료되어야 한다. | ||
|
||
# 구현할 기능 | ||
|
||
## 자동차 | ||
|
||
- [x] 주어진 횟수 동안 자동차의 전진/정지 기능 | ||
- [x] 자동차에 이름 부여 기능 | ||
- [x] 0에서 9까지의 무작위 값 구하기 및 4 이상인 경우 전진 | ||
- [x] 예외 처리 | ||
- [x] 이름 없는 경우 | ||
- [x] 자동차 이름이 5글자를 초과한 경우 | ||
|
||
## 입력 | ||
|
||
- [x] 쉼표(,)를 기준으로 구분된 5자 이하의 자동차 이름 입력 | ||
- [x] 이동 횟수 입력 | ||
- [x] 잘못된 값을 입력한 경우 예외 처리 | ||
- [x] 같은 이름의 자동차가 들어오는 경우 | ||
- [x] 자동차 이름이 5글자를 초과한 경우 | ||
- [x] 이름이 없는 경우 → 오류 출력 | ||
- [x] 시도하는 횟수 입력이 올바르지 않은 경우 | ||
|
||
## 출력 | ||
|
||
- [x] 자동차 출력 (이름과 전진한 정도) | ||
- [x] 우승자 출력 | ||
- [x] 여러명인 경우 쉼표(,)로 구분하여 출력 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,46 @@ | ||
package racingcar; | ||
|
||
import camp.nextstep.edu.missionutils.Console; | ||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
public class Application { | ||
public static void main(String[] args) { | ||
// TODO: 프로그램 구현 | ||
System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); | ||
String carNameStrings = Console.readLine(); | ||
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. View에서 Output과 Input으로도 나누어 볼 수 있겠네요! |
||
|
||
// view 생성 | ||
Output view = new Output(); | ||
|
||
// model 생성 | ||
List<Car> cars = new ArrayList<>(); | ||
Set<String> carNamesSet = new HashSet<>(); | ||
for (String carName : carNameStrings.split(",", -1)) { | ||
if (carNamesSet.contains(carName)) { | ||
throw new IllegalArgumentException(); | ||
} | ||
cars.add(new Car(carName)); | ||
carNamesSet.add(carName); | ||
} | ||
|
||
// controller 생성 | ||
RacingCarController controller = new RacingCarController(view, cars); | ||
|
||
System.out.println("시도할 횟수는 몇 회인가요?"); | ||
String playTimeString = Console.readLine(); | ||
|
||
int playTime = -1; | ||
try { | ||
playTime = Integer.parseInt(playTimeString); | ||
} catch (Exception e) { | ||
throw new IllegalArgumentException(); | ||
} | ||
if (playTime < 0) { | ||
throw new IllegalArgumentException(); | ||
} | ||
|
||
controller.play(playTime); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,43 @@ | ||||||||||||||||||||||||||||||
package racingcar; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
import camp.nextstep.edu.missionutils.Randoms; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
public class Car { | ||||||||||||||||||||||||||||||
private Integer location; | ||||||||||||||||||||||||||||||
private String name; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
public Car(String name) { | ||||||||||||||||||||||||||||||
location = 0; | ||||||||||||||||||||||||||||||
name = name.trim(); | ||||||||||||||||||||||||||||||
if (name.isEmpty() || name.length() > 5) { | ||||||||||||||||||||||||||||||
throw new IllegalArgumentException(); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
this.name = name; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
Comment on lines
+9
to
+16
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 Car() { | ||||||||||||||||||||||||||||||
location = 0; | ||||||||||||||||||||||||||||||
throw new IllegalArgumentException(); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
private void move() { | ||||||||||||||||||||||||||||||
location++; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
public void randomMove() { | ||||||||||||||||||||||||||||||
int randomValue = Randoms.pickNumberInRange(0,9); | ||||||||||||||||||||||||||||||
if (randomValue >= 4) { | ||||||||||||||||||||||||||||||
this.move(); | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
// 정지 | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
public Integer getLocation() { | ||||||||||||||||||||||||||||||
return location; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
public String getName() { | ||||||||||||||||||||||||||||||
return name; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} |
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. Output에 대한 분리는 잘하신 것 같습니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package racingcar; | ||
|
||
import java.util.List; | ||
|
||
public class Output { | ||
private static final String ONE_STEP = "-"; | ||
|
||
public void printResultString() { | ||
System.out.println("실행 결과"); | ||
} | ||
|
||
public void printCars(List<Car> cars) { | ||
for (Car car : cars) { | ||
System.out.print(car.getName()); | ||
System.out.print(" : "); | ||
System.out.println(ONE_STEP.repeat(car.getLocation())); | ||
} | ||
System.out.println(); | ||
} | ||
|
||
public void printWinners(List<String> winners) { | ||
System.out.print("최종 우승자 : "); | ||
for (String winner : winners) { | ||
System.out.print(winner); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,43 @@ | ||||||||||||||||||
package racingcar; | ||||||||||||||||||
|
||||||||||||||||||
import java.util.ArrayList; | ||||||||||||||||||
import java.util.List; | ||||||||||||||||||
|
||||||||||||||||||
public class RacingCarController { | ||||||||||||||||||
|
||||||||||||||||||
private Output output; | ||||||||||||||||||
private List<Car> cars; | ||||||||||||||||||
|
||||||||||||||||||
public RacingCarController(Output output, List<Car> cars) { | ||||||||||||||||||
this.output = output; | ||||||||||||||||||
this.cars = cars; | ||||||||||||||||||
} | ||||||||||||||||||
Comment on lines
+11
to
+14
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 play(int time) { | ||||||||||||||||||
output.printResultString(); | ||||||||||||||||||
for (int i = 0; i < time; i++) { | ||||||||||||||||||
for (Car car : cars) { | ||||||||||||||||||
car.randomMove(); | ||||||||||||||||||
} | ||||||||||||||||||
output.printCars(cars); | ||||||||||||||||||
} | ||||||||||||||||||
List<String> winners = findWinner(); | ||||||||||||||||||
output.printWinners(winners); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
public List<String> findWinner() { | ||||||||||||||||||
List<String> winners = new ArrayList<>(); | ||||||||||||||||||
int maxLocation = 0; | ||||||||||||||||||
|
||||||||||||||||||
for (Car car : cars) { | ||||||||||||||||||
if (maxLocation < car.getLocation()) { | ||||||||||||||||||
winners.clear(); | ||||||||||||||||||
winners.add(car.getName()); | ||||||||||||||||||
} else if (maxLocation == car.getLocation()) { | ||||||||||||||||||
winners.add(car.getName()); | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
return winners; | ||||||||||||||||||
} | ||||||||||||||||||
Comment on lines
+16
to
+42
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. 해당 부분(비지니스 로직)은 model 쪽에서 관리할 수 있게 하는게 좋을 것 같아요. |
||||||||||||||||||
} |
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,54 @@ | ||
package racingcar; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable; | ||
import org.junit.jupiter.api.Test; | ||
|
||
public class CarTest { | ||
|
||
@Test | ||
void createCarWithName() { | ||
// 자동차는 초기 위치가 0 | ||
Car car = new Car("car1"); | ||
assertEquals(car.getLocation(), 0); | ||
assertEquals(car.getName(), "car1"); | ||
} | ||
|
||
@Test | ||
void createCarWithWrongName() { | ||
// 자동차의 이름은 5자 이하 | ||
assertThatExceptionOfType(IllegalArgumentException.class) | ||
.isThrownBy(() -> new Car("haeseung")); | ||
} | ||
|
||
@Test | ||
void createCarWithoutName() { | ||
// 자동차 이름이 없는 경우 오류 출력 | ||
// 없는 경우 | ||
assertThatExceptionOfType(IllegalArgumentException.class) | ||
.isThrownBy(() -> new Car()); | ||
// 공백 | ||
assertThatExceptionOfType(IllegalArgumentException.class) | ||
.isThrownBy(() -> new Car("")); | ||
// 스페이스바 | ||
assertThatExceptionOfType(IllegalArgumentException.class) | ||
.isThrownBy(() -> new Car(" ")); | ||
// 탭 | ||
assertThatExceptionOfType(IllegalArgumentException.class) | ||
.isThrownBy(() -> new Car(" ")); | ||
} | ||
|
||
@Test | ||
void randomMoveCar() { | ||
// 자동차 확률적으로 전진/정지 | ||
Car car = new Car("car1"); | ||
int preLocation = car.getLocation(); | ||
car.randomMove(); | ||
int curLocation = car.getLocation(); | ||
assertThat(curLocation).isBetween(preLocation, curLocation); | ||
} | ||
|
||
} |
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.
Application과 Controller의 역할이 중복되는 것 같은데 통합된다면 좋을 것 같습니다!