Skip to content

Commit

Permalink
3단계 - 자동차 경주(우승자) (#320)
Browse files Browse the repository at this point in the history
* implement calculator

* implement calculator

* feat(calc): add 기능 추가

* feat(calc): 뺄셈 기능 추가

* feat(calc): 곱하기 기능 추가

* feat(calc): 나누기 기능 추가

* feat(calc): 사칙 연산을 모두 포함하는 계산 기능 추가

* feat(calc): 입력 값이 null 이거나 빈 공백일 경우 예외처리

* 사칙연산 기호가 아닌 경우 예외처리

* fix(calc): 피드백 개선

* implement calculator

* Revert "implement calculator"

This reverts commit c017e34.

* docs(readme): add README.md file.

* feat(race): 자동차 수와 이동 횟수 입력 기능 추가

* feat(race): 사용자에게 입력 받는 기능 추가

* feat(race): 랜덤 값에 따라 전진와 정지 결정 로직 추가

* refactor(race): 이동 로직 변경

* reactor(race): 중복되는 print 관련 코드 수정

* refactor(race): 객체 분리되도록 개선

* docs(readme): Step3 요구사항 추가

* feat(cars): 자동차가 이름을 가질 수 있는 기능 추가

* refactor(strategy): 줄일 수 있는 로직 개선

* feat(printer): 승자 출력 기능 추가

* tset(cars): RacingGame 생성자 인자 변경에 따른 테스트코드 수정

* feat(winner-maker): 승자 선정 기능과 테스트 추가
  • Loading branch information
minseok-kr authored and YoungJae Kim committed Jun 18, 2019
1 parent efe7dcd commit f5b31aa
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 35 deletions.
14 changes: 12 additions & 2 deletions src/main/java/racing/Car.java
Expand Up @@ -3,9 +3,11 @@
import racing.strategy.DrivingStrategy;

public class Car {
public int position;
private String name;
private int position;

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

Expand All @@ -27,5 +29,13 @@ public String getMovesRoad() {

return builder.toString();
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}
}

20 changes: 19 additions & 1 deletion src/main/java/racing/Printer.java
Expand Up @@ -3,20 +3,38 @@
import java.util.List;

public class Printer {
static public final String DEL_WINNER_CARS = ", ";

static public void printStartRacing() {
print("\n실행 결과");
}

static public void printResult(List<Car> cars) {
for (Car car : cars) {
print(car.getMovesRoad());
print(car.getName() + " : " + car.getMovesRoad());
}

print("");
}

static public void printEndGame(List<Car> winners) {
String winner = getWinnersString(winners);

print(winner + "가 최종 우승했습니다.");
}

private static void print(String message) {
System.out.println(message);
}

private static String getWinnersString(List<Car> winners) {
StringBuilder builder = new StringBuilder();

for (Car car : winners) {
builder.append(car.getName()).append(DEL_WINNER_CARS);
}

int length = builder.length() - DEL_WINNER_CARS.length();
return builder.substring(0, length).toString();
}
}
31 changes: 26 additions & 5 deletions src/main/java/racing/Prompter.java
@@ -1,16 +1,37 @@
package racing;

import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Prompter {
static public int getPrompt(String message) {
static public int getIntPrompt(String message) {
System.out.println(message);

return getInput();
return getIntInput();
}

static private int getInput() {
Scanner scanner = new Scanner(System.in);
return scanner.nextInt();
static public List<String> getStringsPrompt(String message) {
System.out.println(message);

String[] carNames = split(getStringInput());

return Arrays.asList(carNames);
}

static private int getIntInput() {
return getScanner().nextInt();
}

static private String getStringInput() {
return getScanner().nextLine();
}

static private Scanner getScanner() {
return new Scanner(System.in);
}

static private String[] split(String names) {
return names.split(",");
}
}
21 changes: 16 additions & 5 deletions src/main/java/racing/README.md
@@ -1,12 +1,23 @@
## 자동차 경주

* 기능
* 사용자로부터 자동차의 수와 이동 횟수를 입력받는다.
* 입력받은 값에 따라 전진 혹은 정지한다.
* 자동차의 상태를 출력한다.
* 기능
* step2
+ 사용자로부터 자동차의 수와 이동 횟수를 입력받는다.
+ 입력받은 값에 따라 전진 혹은 정지한다.
+ 자동차의 상태를 출력한다.
* step3
- 전진하는 자동차를 출력할때 자동차의 이름을 같이 출력한다.
+ 각 자동차에 이름을 부여할 수 있다.
+ 전진하는 자동차를 출력할때 자동차의 이름을 같이 출력한다.
+ 게임이 완료되면 누가 우승했는지 알려준다. (우승자는 한명 이상이다)

* 요구사항
* 프로그래밍
* 모든 로직에 단위 테스트를 구현한다.
* 자바 코드 컨벤션을 지킨다.
* else 에약어 사용하지않는다.
* else 예약어 사용하지않는다.
* indent depth를 2를 넘지 않도록 구현한다.
* 함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.
* 모든 로직에 단위 테스트를 구현한다. (핵심로직을 구현하는 코드와 UI를 담당하는 로직을 구분한다.)
14 changes: 8 additions & 6 deletions src/main/java/racing/RacingGame.java
Expand Up @@ -7,8 +7,8 @@ public class RacingGame {
private List<Car> cars;
private int moves;

public RacingGame(int numOfCars, int numOfMoves) {
setCars(numOfCars);
public RacingGame(List<String> carNames, int numOfMoves) {
setCars(carNames);
setMoves(numOfMoves);
}

Expand All @@ -18,6 +18,8 @@ public void startRacing() {
for (int i = 0; i < this.moves; i++) {
move();
}

Printer.printEndGame(new WinnerMaker(cars).getWinners());
}

private void move() {
Expand All @@ -28,11 +30,11 @@ private void move() {
Printer.printResult(cars);
}

private void setCars(int numOfCars) {
cars = new ArrayList<>(numOfCars);
private void setCars(List<String> carNames) {
cars = new ArrayList<>(carNames.size());

for (int i = 0; i < numOfCars; i++) {
cars.add(new Car());
for (String carName : carNames) {
cars.add(new Car(carName));
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/racing/RacingGameRunner.java
Expand Up @@ -4,8 +4,8 @@ public class RacingGameRunner {

public static void main(String[] args) {
RacingGame game = new RacingGame(
Prompter.getPrompt("자동차 대수는 몇 대 인가요?"),
Prompter.getPrompt("시도할 회수는 몇 회 인가요?")
Prompter.getStringsPrompt("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."),
Prompter.getIntPrompt("시도할 회수는 몇 회 인가요?")
);
game.startRacing();
}
Expand Down
43 changes: 43 additions & 0 deletions src/main/java/racing/WinnerMaker.java
@@ -0,0 +1,43 @@
package racing;

import java.util.List;
import java.util.stream.Collectors;

public class WinnerMaker {
private List<Car> cars;

public WinnerMaker(List<Car> cars) {
this.cars = cars;
}

public List<Car> getWinners() {
int max = getWinnerRecord(cars);

return findWinners(max, cars);
}

private int getWinnerRecord(List<Car> cars) {
int max = Integer.MIN_VALUE;

for (Car car : cars) {
int position = car.getPosition();
if (isBigger(position, max)) {
max = position;
}
}

return max;
}

private List<Car> findWinners(int max, List<Car> cars) { ;
List<Car> winners = cars.stream()
.filter(car -> car.getPosition() == max)
.collect(Collectors.toList());

return winners;
}

private boolean isBigger(int original, int target) {
return original > target;
}
}
6 changes: 1 addition & 5 deletions src/main/java/racing/strategy/DrivingRandomStrategy.java
Expand Up @@ -15,11 +15,7 @@ public DrivingRandomStrategy() {
@Override
public boolean isMovable() {
int rand = getNumber();
if (rand >= MIN_MOVABLE_NUMBER) {
return true;
}

return false;
return rand >= MIN_MOVABLE_NUMBER;
}

private int getNumber() {
Expand Down
27 changes: 18 additions & 9 deletions src/test/java/racing/RacingTest.java
Expand Up @@ -2,29 +2,33 @@

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import racing.strategy.DrivingMoveStrategy;
import racing.strategy.DrivingStopStrategy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;

public class RacingTest {
private int INPUT_CARS_COUNT = 1;
private int INPUT_MOVES_COUNT = 1;
private int INPUT_MOVES_COUNT = 1;
private List<String> INPUT_CARS_NAMES = Arrays.asList("car1", "car2");
private String INPUT_CAR_NAME = "car";

private RacingGame mGame;
private Car mCar;

@BeforeEach
void setUp() {
mGame = new RacingGame(INPUT_CARS_COUNT, INPUT_MOVES_COUNT);
mCar = new Car();
mGame = new RacingGame(INPUT_CARS_NAMES, INPUT_MOVES_COUNT);
mCar = new Car(INPUT_CAR_NAME);
}

@Test
void input_generate_cars() {
assertThat(mGame.getNumOfCars()).isEqualTo(INPUT_CARS_COUNT);
assertThat(mGame.getNumOfCars()).isEqualTo(INPUT_CARS_NAMES.size());
}

@Test
Expand All @@ -36,14 +40,14 @@ void input_move_times() {
void go() {
mCar.goOrNot(new DrivingMoveStrategy());

assertThat(mCar.position).isEqualTo(1);
assertThat(mCar.getPosition()).isEqualTo(1);
}

@Test
void stop() {
mCar.goOrNot(new DrivingStopStrategy());

assertThat(mCar.position).isEqualTo(0);
assertThat(mCar.getPosition()).isEqualTo(0);
}

@Test
Expand All @@ -52,4 +56,9 @@ void print_position() {

assertThat(mCar.getMovesRoad()).isEqualTo("-");
}

@Test
void name() {
assertThat(mCar.getName()).isEqualTo(INPUT_CAR_NAME);
}
}
42 changes: 42 additions & 0 deletions src/test/java/racing/WinnerTest.java
@@ -0,0 +1,42 @@
package racing;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class WinnerTest {

private String INPUT_CAR_NAME = "car";
private String INPUT_CAR_NAME_COMPARED = "car_compared";

private WinnerMaker winnerMaker;
private Car mCar;
private Car mCompared;
private List<Car> cars;

@BeforeEach
void setUp() {
mCar = new Car(INPUT_CAR_NAME);
mCompared = new Car(INPUT_CAR_NAME_COMPARED);

cars = Arrays.asList(mCompared, mCar);

winnerMaker = new WinnerMaker(cars);
}

@Test
void winner() {
mCompared.go();

assertThat(new WinnerMaker(cars).getWinners()).containsExactly(mCompared);
}

@Test
void winners_두명이상() {
assertThat(new WinnerMaker(cars).getWinners()).contains(mCar, mCompared);
}
}

0 comments on commit f5b31aa

Please sign in to comment.