Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# 입력

### 자동차
- 숫자 n개의 자동차의 이름을 입력받는다.
- 자동차의 이름은 영어이며 5자 이하이다.
- 자동차의 이름은 쉼표로 구별한다.
### 이동 횟수
- 숫자 m의 자동차 이동 횟수를 입력받는다.
- 매 시도마다 0에서 9사이의 무작위 값을 구하고, 만약 4 이상의 값이라면 전진한다.
- 모든 경주가 끝이나면 우승자를 출력한다.
- 우승자는 한 명 이상일 수 있다. 만약 우승자가 여러명인 경우 쉼표로 구분한다.
### 예외처리
- 사용자가 잘못된 값을 입력하면 `IllegalArgumentException`을 발생시킨 후 애플리케이션은 종료된다.
7 changes: 5 additions & 2 deletions src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package racingcar;

import java.io.IOException;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
public static void main(String[] args) throws IOException {
Controller controller = new Controller();
controller.startGame();
}
}
19 changes: 19 additions & 0 deletions src/main/java/racingcar/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package racingcar;

import java.io.IOException;

public class Controller {
Model model = new Model();
View view = new View();

public void startGame() throws IOException {
model.carNames = view.inputCarNames();
model.initCarProgress(model.carNames.size());
model.frequency = view.inputFrequency();
for (int i = 0; i < model.frequency; i++) {
model.gameProgress(model.carNames, model.carProgress);
view.printCarProgress(model.carNames, model.carProgress);
}
view.printResult(model.carNames, model.carProgress);
}
}
34 changes: 34 additions & 0 deletions src/main/java/racingcar/Model.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package racingcar;

import camp.nextstep.edu.missionutils.Randoms;

import java.util.ArrayList;
import java.util.List;

public class Model {
List<String> carNames = new ArrayList<>();
List<String> carProgress = new ArrayList<>();
int frequency = 0;

public List<String> initCarProgress(int length) {
for (int i = 0; i < length; i++) {
carProgress.add("");
}
return carProgress;
}

public boolean move() {
int random = Randoms.pickNumberInRange(0, 9);
return random >= 4;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 메서드는 움직이는 메서드라기보단 "움직일 수 있는지?" 여부에 대한 기능을 담고 있기 때문에

메서드명을 isMovable()로 바꾸거나, random >= 4일 때 실제로 carProgress에 "-"이 더 추가되도록 하면 좋을 것 같습니다.

근데 사실 문자열은 연산 자체가 복잡한 감이 있어서 그냥 변수를 int 타입으로 하고, 자동차의 이동거리를 화면에 출력할 때만 "-" 으로 변환해서 출력하는 게 제일 좋을 것 같긴 합니다!

Copy link
Member Author

@boroboro01 boroboro01 Sep 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문자열을 사용하면 로직에서 길이를 정수형으로 받아오는 과정이 추가되는데, 확실히 정수형을 사용하면 훨씬 간단해지는군요! 올바른 타입을 결정하는 것도 중요하다는 것을 알게되었습니다


public void gameProgress(List<String> carNames, List<String> carProgress) {
for (int i = 0; i < carNames.size(); i++) {
String progress = carProgress.get(i);
if (move()) {
progress += '-';
carProgress.set(i, progress);
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위에서 언급한 것처럼 이 부분이 좀 어색한 것 같습니다.

if (move()) {
  // 자동차가 움직이는 로직
}

직독하면 "만약 움직인다면 -> 움직인다"인데 "만약 움직일 수 있다면 -> 움직인다" 가 훨씬 자연스러운 것 같습니다!

}
60 changes: 60 additions & 0 deletions src/main/java/racingcar/View.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package racingcar;

import camp.nextstep.edu.missionutils.Console;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class View {
public List<String> inputCarNames() throws IOException {
System.out.println("자동차의 이름들을 입력하세요");
String carNames = Console.readLine();
List<String> cars = new ArrayList<>();
StringTokenizer st = new StringTokenizer(carNames, ",");
while (st.hasMoreTokens()) {
String str = st.nextToken();
cars.add(str);
if (str.length() > 5) {
throw new IllegalArgumentException();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 new IllegalArgumentException() 안에 에러 메시지까지 넣어주면 좋을 것 같습니다!

"자동차의 이름은 5글자 이내여야 합니다." <- 이런 식으로용

}
}
return cars;
}

public int inputFrequency() throws IOException {
System.out.println("총 시도할 횟수를 입력하세요");
return Integer.parseInt(Console.readLine());
}

public void printCarProgress(List<String> carNames, List<String> carProgress) {
for (int i = 0; i < carNames.size(); i++) {
System.out.println(carNames.get(i) + " : " + carProgress.get(i));
}
System.out.println();
}

public void printResult(List<String> carNames, List<String> carProgress) {
List<String> winner = new ArrayList<>();
int max = 0;
for (int i = 0; i < carProgress.size(); i++) { // 최댓값 찾기
if (carProgress.get(i).length() >= max) {
max = carProgress.get(i).length();
}
}
for (int i = 0; i < carProgress.size(); i++) { // 우승자 찾기
if (carProgress.get(i).length() >= max) {
winner.add(carNames.get(i));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최댓값을 찾고 이를 이용해 우승자를 찾는 부분은 Model의 책임인 것 같아서,
이 메서드의 파라미터를 받을 때 애초에 Model에서 우승자 목록을 넘겨주고 printResult에서는 출력만 하는 게 올바른 구조인 것 같습니다!


System.out.print("최종 우승자 : ");
for (int i = 0; i < winner.size(); i++) {
System.out.print(winner.get(i));
if (i + 1 < winner.size()) {
System.out.print(",");
}
}
}
}
8 changes: 7 additions & 1 deletion src/test/java/racingcar/ApplicationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import camp.nextstep.edu.missionutils.test.NsTest;
import org.junit.jupiter.api.Test;

import java.io.IOException;

import static camp.nextstep.edu.missionutils.test.Assertions.assertRandomNumberInRangeTest;
import static camp.nextstep.edu.missionutils.test.Assertions.assertSimpleTest;
import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -33,6 +35,10 @@ class ApplicationTest extends NsTest {

@Override
public void runMain() {
Application.main(new String[]{});
try {
Application.main(new String[]{});
} catch (IOException e) {
throw new RuntimeException(e);
}
Comment on lines +38 to +42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

만약 위에서 new IllegalArgumentException()을 던질 때 에러 메시지를 추가한다면,
여기서 에러를 캐치할 때 콘솔창에 에러 메시지를 print문을 통해 출력하면 좋을 것 같습니다!

Comment on lines +38 to +42

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트코드 대응 굿

}
}