Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
Binary file added .DS_Store
Binary file not shown.
33 changes: 33 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 미션 - 자동차 경주

### car (input 조건)
- 입력받을 때 이름이 5글자 이하 or 예외처리
- ','를 기준으로 이름을 입력받음.
- 사용자는 몇 번 시도할지 횟수를 입력받음.

### play
- 0 ~ 9 사이의 랜덤 숫자
- 4 이상일 때는 전진, 아니면 멈춤

### outputview
- 우승자는 한명 이상일 수 있다.
- 우승자는 여러 명일 경우 쉼표로 구분
- 주사위 돌아갈 때마다 [car 이름: 이동 상태 출력]
- 예외처리 illegalArgumentException / 프로그램 종료

### testcode 작성하기
- JUnit 5와 AssertJ를 이용하여 본인이 정리한 기능 목록이 정상 동작함을 테스트 코드로 확인한다.
테스트 도구 사용법이 익숙하지 않다면 test/java/study를 참고하여 학습한 후 테스트를 구현한다.
작성한 테스트 코드의 Coverage가 도메인(모델) 패키지 90%, 코드 전체 60% 이상인지 확인한다.

### 코드 컨벤션(요구사항)
- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
- 3항 연산자를 쓰지 않는다.
- 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
- else 예약어를 쓰지 않는다.
- if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.
else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다.
함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.
함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다.
Binary file added src/.DS_Store
Binary file not shown.
Binary file added src/main/.DS_Store
Binary file not shown.
Binary file added src/main/java/.DS_Store
Binary file not shown.
5 changes: 5 additions & 0 deletions src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package racingcar;

import racingcar.controller.GameController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
GameController gameController = new GameController();
gameController.gameStart();
}
}

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

import racingcar.domain.Cars;
import racingcar.validate.CarNameValidate;
import racingcar.view.InputView;
import racingcar.view.OutputView;

import java.util.List;

public class GameController {

private final Cars cars = new Cars();

public void gameStart() {
String[] carNames = InputView.inputCarName();
CarNameValidate.validateCarName(carNames);
cars.inputCarName(carNames);
int repeat = InputView.showMoveCount();
Racing(repeat);
OutputView.printWinnerCars(findWinners());
}

public void Racing(int repeat) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

변수명 첫글자가 대문자인데 큰 이유가 없다면 소문자(카멜 케이스)로 통일하는게 좋을 것 같아요.

OutputView.outputMessage();
for (int round = 0; round < repeat; round++) {
cars.carForward();
OutputView.showCar(cars);
}
}

public List<String> findWinners() {
return cars.findWinners();
}
}
31 changes: 31 additions & 0 deletions src/main/java/racingcar/domain/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package racingcar.domain;

import camp.nextstep.edu.missionutils.Console;

import java.awt.*;
Copy link
Collaborator

Choose a reason for hiding this comment

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

GUI 라이브러리를 사용하지 않는 것 같은데 불러온 이유가 따로 있을까요?

Copy link
Author

Choose a reason for hiding this comment

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

음.. 뭔가 했다가 지우지 못했던거 같습니다

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Car {

private String name;
private int position = 0;

public Car(String name) {
this.name = name;
}

public void moveForward() {
position++;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}
}
54 changes: 54 additions & 0 deletions src/main/java/racingcar/domain/Cars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package racingcar.domain;

import camp.nextstep.edu.missionutils.Randoms;

import java.util.*;

public class Cars {

private List<Car> cars;
private static final int FORWARD_NUM = 4;
private static final int MINIMUM_POSITION = 0;

public Cars() {
this.cars = new ArrayList<>();
}

public void inputCarName(String[] carNames) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 메서드를 생성자로 변경해도 괜찮을 것 같아요. 그러면 inputCarName 메서드를 호출할 필요가 없겠죠?

for (String carName : carNames) {
cars.add(new Car(carName));
}
}

public List<Car> getCars() {
return cars;
}

public void carForward() {
for (Car car : cars) {
if (createRandomNum() >= FORWARD_NUM) {
car.moveForward();
}
}
}

public int createRandomNum() {
return Randoms.pickNumberInRange(0, 9);
}

public List<String> findWinners() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Car 클래스를 반환하는 것이아니라 이름을 반환하는 것이니 좀 더 명확한 의미를 가지도록 메서드 명을 변경해보세요!

int maxPosition = MINIMUM_POSITION;
for (Car car : cars) {
if (car.getPosition() > maxPosition) {
maxPosition = car.getPosition();
}
}
List<String> winners = new ArrayList<>();
for (Car car : cars) {
if (car.getPosition() == maxPosition) {
winners.add(car.getName());
}
}
return winners;
}
}
16 changes: 16 additions & 0 deletions src/main/java/racingcar/validate/CarNameValidate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package racingcar.validate;

public class CarNameValidate {

public static void validateCarName(String[] carNames){
Copy link
Collaborator

Choose a reason for hiding this comment

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

메서드 명만 보면 차 이름 하나로 Validation하는 메서드인줄 알았는데 이름 여러개를 검증하다보니 헷갈리는 것 같아요. 한개의 매개변수에 대해서만 검증하는 로직으로 변경하거나 메서드 명을 변경하시면 좋을 것 같아요.


for (String carName : carNames) {
if(carName.length() > 5){
throw new IllegalArgumentException("자동차 이름은 5글자 이하로 만들어 주세요.");
}
if(carName.length() < 1){
throw new IllegalArgumentException("자동차 이름은 1글자 이상으로 만들어 주세요.");
}
}
}
}
16 changes: 16 additions & 0 deletions src/main/java/racingcar/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package racingcar.view;

import camp.nextstep.edu.missionutils.Console;

public class InputView {
Copy link
Collaborator

Choose a reason for hiding this comment

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

View에 해당하는 클래스 메서드들을 static으로 한 이유가 궁금해요. non-static으로 하고 객체를 생성해서 사용하는게 좀더 좋지 않을까요?

Copy link
Author

Choose a reason for hiding this comment

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

확장성을 고려하지 못한거 같았습니다. static메서드를 사용하지 않고 객체를 만들어서 메서드를 사용하는게 더 좋을거 같네요! 길어지는게 싫어서 썼던거 같습니다.


public static String[] inputCarName() {
System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)");
return Console.readLine().split(",");
}

public static int showMoveCount() {
System.out.println("시도할 회수는 몇 회인가요?");
return Integer.parseInt(Console.readLine());
}
}
35 changes: 35 additions & 0 deletions src/main/java/racingcar/view/OutputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

package racingcar.view;

import racingcar.domain.Car;
import racingcar.domain.Cars;

import java.util.List;

public class OutputView {
Copy link
Collaborator

Choose a reason for hiding this comment

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

showCar, showCarPosition에서 문자열 조합 관련 로직이 보이는데 출력 메서드(ex - println)는 많은 자원을 소모해요

그래서 문자열을 조합한다음에 마지막에 한번에 출력하도록 리팩토링 해봐요


public static void outputMessage() {
System.out.println("실행 결과");
}

public static void showCar(Cars cars) {
List<Car> participants = cars.getCars();
for (Car car : participants) {
System.out.print(car.getName() + " : ");
showCarPosition(car);
}
System.out.println();
}

public static void showCarPosition(Car car) {
for (int i = 0; i < car.getPosition(); i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

좀 더 리팩토링 할 수 있을 것 같아요 String 관련 메서드를 찾아보세요

System.out.print("-");
}
System.out.println();
}

public static void printWinnerCars(List<String> winners) {
System.out.print("최종 우승자 : " + String.join(", ", winners));

}
}
29 changes: 24 additions & 5 deletions src/test/java/racingcar/ApplicationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Copy link
Collaborator

Choose a reason for hiding this comment

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

단위 테스트도 한번 해보세요!!

import camp.nextstep.edu.missionutils.test.NsTest;
import org.junit.jupiter.api.Test;
import racingcar.domain.Cars;

import java.util.List;

import static camp.nextstep.edu.missionutils.test.Assertions.assertRandomNumberInRangeTest;
import static camp.nextstep.edu.missionutils.test.Assertions.assertSimpleTest;
Expand All @@ -15,11 +18,11 @@ class ApplicationTest extends NsTest {
@Test
void 전진_정지() {
assertRandomNumberInRangeTest(
() -> {
run("pobi,woni", "1");
assertThat(output()).contains("pobi : -", "woni : ", "최종 우승자 : pobi");
},
MOVING_FORWARD, STOP
() -> {
run("pobi,woni", "1");
assertThat(output()).contains("pobi : -", "woni : ", "최종 우승자 : pobi");
},
MOVING_FORWARD, STOP
);
}

Expand All @@ -31,6 +34,22 @@ class ApplicationTest extends NsTest {
);
}

@Test
void 우승자_리스트() {

// given
Cars cars = new Cars();
cars.inputCarName(new String[]{"babo","baba","bobo"});

// when
cars.getCars().get(0).moveForward();
cars.getCars().get(2).moveForward();
List<String> winners = cars.findWinners();

// then
assertThat(winners).containsExactly("babo","bobo");
}

@Override
public void runMain() {
Application.main(new String[]{});
Expand Down