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

[자동차 경주] 김진호 미션 제출합니다. #1457

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,23 @@
# java-racingcar-precourse

## 구현할 기능 목록

1. RacingManager라는 클래스를 만들어 구체적인 함수들 포함.
1. RacingManager의 생성자에서 자동차 이름들과 횟수 입력받기
2. 자동차이름 ‘,’기준으로 나눠 자동차이름, 전진한 횟수(position)를 멤버 변수로 가진 Car클래스의 객체 리스트에 저장
3. 객체 리스트를 하나씩 확인하며 랜덤숫자가 4이상이면 전진한 횟수를 +1시킨다.
4. 한번의 횟수(스텝)마다 전진한 횟수대로 ‘-’를 생성하여 출력
5. 입력한 횟수가 끝나면 전진한 횟수를 비교해 우승자 출력
2. 예외처리 해주기
1. `자동차이름입력값_빈값일때_예외_테스트`
2. `반복횟수_빈값일때_예외_테스트`
3. `반복횟수_0일때_예외_테스트`
4. `반복횟수_음수일때_예외_테스트`
5. `유효하지않은_구분자_예외_테스트` : ‘,’이외의 구분자가 입력으로 들어왔을 때
6. `자동차이름에_숫자_포함돼있을시_예외_테스트`
7. `자동차이름에_다른구분자_포함돼있을시_예외_테스트`
8. `구분자가_맨앞에있을때_예외_테스트`
9. `구분자가_겹쳐있을때_예외_테스트`
10. `구분자가_맨뒤에있을때_예외_테스트`
3. 예외처리 테스트
4. 우승자 여러명일 때 테스트
10 changes: 10 additions & 0 deletions src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
package racingcar;

import camp.nextstep.edu.missionutils.Console;
import camp.nextstep.edu.missionutils.Randoms;

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

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

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

public Car (String name, int position){
this.name = name;
this.POSITION = position;
}

public void moveForword(){
this.POSITION += 1;
}

public String getName() {
return name;
}

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

public class ExceptionManager {

private String input = "";
private String[] inputCars;
private int NUMBER;

ExceptionManager(String input, String[] inputCars, int NUMBER){
this.input = input;
this.inputCars = inputCars;
this.NUMBER = NUMBER;
}

// 빈값 확인
private void checkInputCarsIsNull(){
if(input.equals("")){
throw new IllegalArgumentException("입력된 값이 없습니다.");
}
}

// NUMBER 0또는 음수인지 확인
private void checkWrongInputNumber(){
if(NUMBER <= 0){
throw new IllegalArgumentException("양수를 입력해야합니다.");
}
}

private void checkWrongWord(){
// 다른 구분자나 숫자가 포함되어 있는지 확인하기
if(!input.matches("^[a-zA-Z,]*$")) {
throw new IllegalArgumentException("문자와 구분자','외에 다른문자가 포함되어 있습니다.");
}
}

private void checkWrongDelimiter(){
// input의 delimiter 위치 확인(','가 맨앞에 오거나 겹치는 경우)
for(String inputCar : inputCars) {
if(inputCar.isEmpty()){
throw new IllegalArgumentException("구분자가 겹쳐있거나 문자열 맨앞에 위치해 있습니다.");
}
}
// input의 delimiter 위치 확인(','가 맨앞 맨뒤에 있는 경우)
if(input.charAt(input.length() - 1) == ','){
throw new IllegalArgumentException("구분자가 문자열 맨뒤에 위치해 있습니다.");
}
}

private void checkWrongLength(){
// input의 차 이름이 5글자 이하인지 확인
for(String inputCar : inputCars) {
checkNumOfCarName(inputCar);
}
}

private void checkNumOfCarName(String inputCar) {
int MAX_NUM_OF_CAR_NAME = 5;
if(inputCar.length() > MAX_NUM_OF_CAR_NAME){
throw new IllegalArgumentException("자동차 이름이 5글자 이하여야합니다.");
}
}

public void checkException(){
checkInputCarsIsNull();
checkWrongInputNumber();
checkWrongWord();
checkWrongDelimiter();
checkWrongLength();
}
}
110 changes: 110 additions & 0 deletions src/main/java/racingcar/RacingManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package racingcar;

import camp.nextstep.edu.missionutils.Console;
import camp.nextstep.edu.missionutils.Randoms;

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

public class RacingManager {

private String input = "";
private int NUMBER;
private String[] inputCars;
private ExceptionManager exceptionManager;
private List<Car> carList = new ArrayList<>();
private int MAX_POSITION;
private List<String> names = new ArrayList<>();


RacingManager(){
System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)");
this.input = Console.readLine(); // 사용자 입력을 받는 메소드
System.out.println("시도할 횟수는 몇 회인가요?");
try {
this.NUMBER = Integer.parseInt(Console.readLine());
} catch (NumberFormatException e){
throw new IllegalArgumentException("숫자를 입력하지 않았습니다.");
}
splitInputCars();
exceptionManager = new ExceptionManager(input, inputCars, NUMBER);
}

private void splitInputCars() {
this.inputCars = input.split(",");
}

private void createCar() {
for(int i = 0; i < inputCars.length; i++){
Car car = new Car(inputCars[i], 0);
carList.add(car);
}
}

private void startRacing() {
System.out.println();
System.out.println("실행 결과");
while(NUMBER > 0){
startMove(carList);
System.out.println();
NUMBER -= 1;
}
}

private void startMove(List<Car> carList) {
int RANDOM_NUM;
for(int i = 0; i < carList.size(); i++) {
String position = "";
Car car = carList.get(i);
checkMove(car);
printPosition(car, position);
}
}

private void checkMove(Car car) {
int RANDOM_NUM = Randoms.pickNumberInRange(0, 9);
int MOVE_FORWARD_NUM = 4;
if(RANDOM_NUM >= MOVE_FORWARD_NUM) {
car.moveForword();
}
}

private void printPosition(Car car, String position) {
for(int j = 0; j < car.getPosition(); j++) {
position += '-';
}
System.out.println(car.getName() + " : " + position);
}

public void getMaxPosition() {
MAX_POSITION = carList.stream()
.max(Comparator.comparingInt(Car::getPosition))
.map(Car::getPosition)
.orElse(-1);
}

public void getMaxPostionCars() {
// 최대 position을 가진 모든 객체의 name을 리스트로 추출
names = carList.stream()
.filter(o -> o.getPosition() == MAX_POSITION)
.map(Car::getName)
.collect(Collectors.toList());
}

public void printMaxPositionCars() {
String result = names.stream()
.collect(Collectors.joining(", "));
System.out.println("최종 우승자 : " + result);
}

public void runRacing() {
exceptionManager.checkException();
createCar();
startRacing();
getMaxPosition();
getMaxPostionCars();
printMaxPositionCars();
}
}
90 changes: 90 additions & 0 deletions src/test/java/racingcar/ApplicationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ class ApplicationTest extends NsTest {
);
}

@Test
void 우승자_여러명일때_기능_테스트() {
assertSimpleTest(
() -> {
run("pobi,woni", "1");
assertThat(output()).contains("pobi : -", "woni : -", "최종 우승자 : pobi, woni");
}
);
}

@Test
void 예외_테스트() {
assertSimpleTest(() ->
Expand All @@ -31,6 +41,86 @@ class ApplicationTest extends NsTest {
);
}

@Test
void 자동차이름입력값_빈값일때_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("", "1"))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 반복횟수_빈값일때_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("pobi,java", null))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 반복횟수_0일때_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("pobi,java", "0"))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 반복횟수_음수일때_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("pobi,java", "-1"))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 유효하지않은_구분자_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("pobi@java", "1"))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 자동차이름에_숫자_포함돼있을시_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("pobi,java2", "1"))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 자동차이름에_다른구분자_포함돼있을시_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("pobi:java", "1"))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 구분자가_맨앞에있을때_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException(",pobi,java", "1"))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 구분자가_겹쳐있을때_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("pobi,,java", "1"))
.isInstanceOf(IllegalArgumentException.class)
);
}

@Test
void 구분자가_맨뒤에있을때_예외_테스트() {
assertSimpleTest(() ->
assertThatThrownBy(() -> runException("pobi,java,", "1"))
.isInstanceOf(IllegalArgumentException.class)
);
}

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