Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
# java-racingcar-precourse
# 자동차 경주 게임

## 기능 요구 사항
- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
- 각 자동차에 이름을 부여할 수 있다.
- 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다.
- 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다.
- 전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다.
- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다.
- 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다.
- 사용자가 잘못된 값을 입력할 경우 를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.
- Exception이 아닌 IllegalArgumentException , IllegalStateException 등과 같은 명확한 유형을 처리한다.

## 구현 기능
### Model
* Car
* 이름 및 위치 정보 보유
* 자동차 전진
* Race
* 차량 정보 보유
* 경주 진행

### View
* Input
* 자동차 이름 입력 및 검증
* 시도 회수 입력 및 검증
* Output
* 경주 결과 출력
* 우승자 출력

### Controller
* Controller
* Car 생성
* 경주 정보 설정
* 게임 시작
9 changes: 9 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import controller.Controller;

public class Application {
private static final Controller controller = new Controller();

public static void main(String[] args) {
controller.play();
}
}
34 changes: 34 additions & 0 deletions src/main/java/controller/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package controller;

import java.util.ArrayList;
import java.util.List;
import model.Car;
import model.Race;
import view.Input;
import view.Output;

public class Controller {
private List<Car> createCars() {
while (true) {
try {
String[] names = Input.getCarName();
List<Car> cars = new ArrayList<>();
for (String carName : names) {
cars.add(new Car(carName));
}
return cars;
} catch (IllegalArgumentException e){
System.out.println("[ERROR] " + e.getMessage());
}
}
}

public void play() {
List<Car> cars = createCars();
int round = Input.getRound();
Race race = new Race(cars, round);

race.start();
Output.printWinner(race.getWinner());
}
}
29 changes: 29 additions & 0 deletions src/main/java/model/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package model;

public class Car {
final private String name;
private int pos;

public Car(String name) {
if (5 < name.length()) {
throw new IllegalArgumentException("차의 이름은 5글자 이하여야 합니다");
}
this.name = name;
this.pos = 0;
}

public String getName() {
return name;
}

public int getPos() {
return pos;
}

public void move() {
int randomNumber = (int)(Math.random() * 10);
if (4 <= randomNumber) {
pos++;
}
}
}
38 changes: 38 additions & 0 deletions src/main/java/model/Race.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package model;

import java.util.List;
import java.util.ArrayList;
import view.Output;

public class Race {
private final List<Car> cars;
private final int move;

public Race(List<Car> cars, int move) {
this.cars = cars;
this.move = move;
}

public void start(){
for(int i = 0; i < move; i++) {
for (Car car : cars) {
car.move();
}
Output.printResult(cars);
}
}

public List<String> getWinner() {
int max = 0;
for (Car car : cars) {
max = Math.max(max, car.getPos());
}
List<String> winners = new ArrayList<>();
for (Car car : cars) {
if (car.getPos() == max) {
winners.add(car.getName());
}
}
return winners;
}
}
27 changes: 27 additions & 0 deletions src/main/java/view/Input.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package view;

import java.util.Scanner;

public class Input {
private static final Scanner sc = new Scanner(System.in);

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

public static int getRound() {
while (true) {
try {
System.out.println("시도할 회수는 몇회인가요?");
int round = Integer.parseInt(sc.nextLine());
if (round <= 0) {
throw new IllegalArgumentException("시도 회수는 양의 정수여야 합니다");
}
return round;
} catch (IllegalArgumentException e) {
System.out.println("[ERROR] " + e.getMessage());
}
}
}
}
17 changes: 17 additions & 0 deletions src/main/java/view/Output.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package view;

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

public class Output {
public static void printResult(List<Car> cars) {
for (Car car : cars) {
System.out.println(car.getName() + " : " + "-".repeat(car.getPos()));
}
System.out.println();
}

public static void printWinner(List<String> winner) {
System.out.println("최종 우승자 : " + String.join(",", winner));
}
}
24 changes: 24 additions & 0 deletions src/test/java/CarTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

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

public class CarTest {
@Test
@DisplayName("차량 이름 검증 테스트")
void carNameLengthTest() {
assertThatThrownBy(() -> new Car("testLongName")).isInstanceOf(IllegalArgumentException.class);
}

@Test
@DisplayName("Car.move() 반복 후 이동 여부 테스트")
void carMoveTest(){
Car car = new Car("car1");
for (int i = 0; i < 1000; i++){
car.move();
}
assertThat(car.getPos()).isNotZero();
}
}
22 changes: 22 additions & 0 deletions src/test/java/RaceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import static org.assertj.core.api.Assertions.assertThat;

import java.util.ArrayList;
import model.Car;
import model.Race;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class RaceTest {
@Test
@DisplayName("레이스 우승자 결과 테스트")
void raceWinnerTest() {
ArrayList<Car> cars = new ArrayList<Car>() {{
add(new Car("car1"));
add(new Car("car2"));
}};
Race race = new Race(cars, 10);
race.start();

assertThat(race.getWinner().size()).isNotZero();
}
}