Skip to content
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

[강원대 BE_최준형] 미션 제출합니다. #143

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
# java-racingcar-precourse
# java-racingcar-precourse

## 구현 기능 목록

### 자동차의 이름 입력

* 이름은 쉼표로 구분하고, 5자 이하만 입력이 가능합니다.

* 잘못된 입력 시 `IllegalArgumentException`이 발생하고 다시 입력을 받습니다.

### 이동 횟수 입력

* 사용자는 몇 번 이동할 것인지 횟수를 입력 합니다.

* 마찬가지로 잘못된 입력 시 `IllegalArgumentException`이 발생하고 다시 입력을 받습니다.

### 난수 생성

* 0부터 9까지의 무작위 수를 생성합니다.

### 자동차 앞으로 전진

* 생성된 난수가 4 이상일 시 한 칸 전진합니다.

* 전진이 끝나면 진행 결과를 출력합니다.
* 이 과정은 사용자로부터 입력 받은 이동 횟수만큼 반복됩니다.

### 완주 및 우승자 판단

* 가장 많이 전진한 자동차가 우승자로 선정됩니다.

* 최종 우승자를 출력합니다.
10 changes: 10 additions & 0 deletions src/main/java/RacingCarApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import controller.RacingCarController;

public class RacingCarApplication {

public static void main(String[] args) {
RacingCarController controller = new RacingCarController();
controller.startGame();
}

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

import java.util.List;
import model.Car;
import model.RacingCarGame;
import view.InputView;
import view.OutputView;

public class RacingCarController {

private final InputView inputView = new InputView();
private final OutputView outputView = new OutputView();

public void startGame() {
String[] carNames = inputView.inputCarNames();
int movementCount = inputView.inputMovementCount();

RacingCarGame game = new RacingCarGame(carNames);

outputView.printResultMessage();
for (int i = 0; i < movementCount; i++) {
outputView.printProgress(game.playOneRound());
}

List<String> winnerCarNames = game.judgeWinners().stream()
.map(Car::getCarName)
.toList();
outputView.printWinners(winnerCarNames);
}

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

public class Car {

private final String carName;
private int position = 0;

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

public void move(int randomNumber) {
if (randomNumber >= 4) {
position += 1;
}
}

public String getCarName() {
return carName;
}

public int getPosition() {
return position;
}

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

import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import util.RandomNumberGenerator;

public class RacingCarGame {

private final List<Car> cars = new ArrayList<>();

private final RandomNumberGenerator generator = new RandomNumberGenerator();;

public RacingCarGame(String[] carNames) {
for (String carName : carNames) {
cars.add(new Car(carName));
}
}

public List<Car> playOneRound() {
for (Car car : cars) {
car.move(generator.generateRandomNumber());
}

return cars;
}

public List<Car> judgeWinners() {
int winnerPosition = cars.stream()
.mapToInt(Car::getPosition)
.max()
.orElseThrow(NoSuchElementException::new);

return cars.stream()
.filter(car -> car.getPosition() == winnerPosition)
.toList();
}

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

import java.util.Random;

public class RandomNumberGenerator {

private final Random random = new Random();

public int generateRandomNumber() {
return random.nextInt(10);
}

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

import java.util.Scanner;

public class InputView {

private final Scanner scanner = new Scanner(System.in);

public String[] inputCarNames() {
String[] carNames = null;
boolean isValid = false;

while(!isValid) {
System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)");
carNames = scanner.nextLine().split(",");

isValid = isValidCarNames(carNames);
}

return carNames;
}

public int inputMovementCount() {
System.out.println("시도할 횟수는 몇회인가요?");

return scanner.nextInt();
}

private boolean isValidCarNames(String[] carNames) {
for (String carName : carNames) {
if(!isValidCarName(carName)) {
return false;
}
}
return true;
}

private boolean isValidCarName(String carName) {
try {
if (carName.length() > 5) {
throw new IllegalArgumentException("[ERROR] 자동차 이름은 5자 이하만 입력이 가능합니다.");
}
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());

return false;
}
return true;
}

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

import java.util.List;
import model.Car;

public class OutputView {

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

public void printProgress(List<Car> cars) {
for (Car car : cars) {
System.out.println(car.getCarName() + " : " + "-".repeat(car.getPosition()));
}
System.out.println();
}

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

}
36 changes: 36 additions & 0 deletions src/test/java/model/CarTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package model;

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

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

class CarTest {

@DisplayName("자동차를 앞으로 한 칸 전진시킨다.")
@Test
void move() throws Exception {
//given
Car car = new Car("kia");

//when
car.move(7);

//then
assertThat(car.getPosition()).isEqualTo(1);
}

@DisplayName("자동차를 앞으로 한 칸 전진 시키는데, 주어진 난수가 4 미만이면 전진하지 않는다.")
@Test
void moveWithRandomNumberLessThanFour() throws Exception {
//given
Car car = new Car("kia");

//when
car.move(3);

//then
assertThat(car.getPosition()).isEqualTo(0);
}

}
25 changes: 25 additions & 0 deletions src/test/java/model/RacingCarGameTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package model;

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

import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class RacingCarGameTest {

@DisplayName("우승자를 판단하고, 우승자 목록을 반환한다.")
@Test
void judgeWinners() throws Exception {
//given
String[] carNames = {"kia", "good", "test", "hyu"};
RacingCarGame racingCarGame = new RacingCarGame(carNames);

//when
List<Car> winners = racingCarGame.judgeWinners();

//then -> 전진 없이 모두가 같은 위치이므로 모두가 우승자
assertThat(winners.size()).isEqualTo(carNames.length);
}

}
23 changes: 23 additions & 0 deletions src/test/java/util/RandomNumberGeneratorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package util;

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

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

class RandomNumberGeneratorTest {

@DisplayName("0부터 9까지 무작위 수를 생성한다.")
@Test
void generateRandomNumber() throws Exception {
//given
RandomNumberGenerator generator = new RandomNumberGenerator();

//when
int randomNumber = generator.generateRandomNumber();

//then
assertThat(randomNumber).isBetween(0, 9);
}

}