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

[자동차 경주] 박상욱 미션 제출합니다. #1480

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

---

## 요구사항 분석
* 입력 처리 클래스 구현
* 쉼표를 기준으로 경주할 자동자 이름을 분리하여 입력
* 시도할 횟수 입력
* Car(자동차) 클래스 구현
* 이름
* 현재 위치
* Race(경주) 클래스 구현
* 게임 진행 메소드
* 출력(Race 클래스에서 구현)
* 차수별 실행 결과
* 단독 우승자 안내 문구
* 공동 우승자 안내 문구
* 잘못된 입력 처리
* 입력 클래스에서 입력값을 확인한 후 예외 발생
* 각 항목별 테스트 코드 작성

### 출력예시:
```
경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)
pobi,woni,jun
시도할 횟수는 몇 회인가요?
5

실행 결과
pobi : -
woni :
jun : -

pobi : --
woni : -
jun : --

pobi : ---
woni : --
jun : ---

pobi : ----
woni : ---
jun : ----

pobi : -----
woni : ----
jun : -----

최종 우승자 : pobi, jun
```
23 changes: 22 additions & 1 deletion src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
package racingcar;

import java.util.ArrayList;
import java.util.List;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
InputHandler inputHandler = new InputHandler();

// 입력 받기
inputHandler.inputNames();
inputHandler.inputCount();

// 입력을 기반으로 Car 인스턴스 생성
List<Car> cars = new ArrayList<>();
for(String name : inputHandler.getNames()){
Car car = new Car(name);
cars.add(car);
}

// Race 인스턴스 생성
Race race = new Race(cars, inputHandler.getRunCount());

// 경주 진행
race.runRace();
race.showWinners();
}
}
37 changes: 37 additions & 0 deletions src/main/java/racingcar/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package racingcar;

import camp.nextstep.edu.missionutils.Randoms;

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

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

public void moveOnceRandom() {
int num = Randoms.pickNumberInRange(0, 9);

if (num >= 4) {
location++;
}
}

public int getLocation() {
return location;
}

public String getName() {
return name;
}

public String getNameAndLocation() {
String returnStr = name + " : ";
for (int i = 0; i < location; i++) {
returnStr += "-";
}
return returnStr;
}
}
43 changes: 43 additions & 0 deletions src/main/java/racingcar/InputHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package racingcar;

import camp.nextstep.edu.missionutils.Console;

import java.util.List;

public class InputHandler {
private String input;
private List<String> names;
private int runCount;

public void inputNames(){
System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)");
this.input = Console.readLine();
this.names = InputHandler.commaSeparator(input);
}

public void inputCount(){
System.out.println("시도할 횟수는 몇 회인가요?");
this.runCount = Integer.parseInt(Console.readLine());
}

public static List<String> commaSeparator(String input){
List<String> names = List.of(input.split(","));
for(String name : names){
if(name.trim().isEmpty()){
throw new IllegalArgumentException("이름이 비었습니다.");
}
if(name.length() > 5){
throw new IllegalArgumentException("이름은 5자 이하만 가능합니다.");
}
}
return names;
}

public Integer getRunCount() {
return runCount;
}

public List<String> getNames() {
return names;
}
}
51 changes: 51 additions & 0 deletions src/main/java/racingcar/Race.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package racingcar;

import org.junit.platform.commons.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

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

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

public void runOneRound(){
for(Car car : cars){
car.moveOnceRandom();
}
}

public void printLocations(){
for(Car car : cars){
System.out.println(car.getNameAndLocation());
}
}

public void runRace(){
System.out.println("실행 결과");
for(int i = 0; i < count; i++){
runOneRound();
printLocations();
System.out.println();
}
}

public void showWinners(){
int max = cars.stream().map(Car::getLocation).max(Integer::compareTo).orElse(Integer.MIN_VALUE);

List<String> winners = new ArrayList<>();
for(Car car : cars){
if(car.getLocation() == max){
winners.add(car.getName());
}
}

String winnersOutput = String.join(", ", winners);
System.out.println("최종 우승자 : " + winnersOutput);
}
}
42 changes: 42 additions & 0 deletions src/test/java/racingcar/CarTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package racingcar;

import camp.nextstep.edu.missionutils.Randoms;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static camp.nextstep.edu.missionutils.test.Assertions.assertRandomNumberInRangeTest;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.*;

class CarTest {
private Car car;

@BeforeEach
void setUp() {
car = new Car("pobi");
}

@Test
void 자동차의_이름을_반환한다() {
assertThat(car.getName()).isEqualTo("pobi");
}

@Test
void 자동차의_초기_위치는_0이다() {
assertThat(car.getLocation()).isEqualTo(0);
}

@Test
void 자동차는_랜덤숫자가_4이상일_경우_이동한다() {
assertRandomNumberInRangeTest(
() -> {
car.moveOnceRandom();
assertThat(car.getLocation()).isEqualTo(1);

car.moveOnceRandom();
assertThat(car.getLocation()).isEqualTo(1);
},
4, 3
);
}
}
46 changes: 46 additions & 0 deletions src/test/java/racingcar/InputHandlerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package racingcar;

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

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.*;

class InputHandlerTest {

private InputHandler inputHandler;

@BeforeEach
void setUp() {
inputHandler = new InputHandler();
}

@Test
void 자동차_이름을_쉼표로_구분하여_입력할_수_있다() {
String input = "pobi,woni";
List<String> expectedNames = List.of("pobi", "woni");

List<String> names = InputHandler.commaSeparator(input);

assertThat(names).isEqualTo(expectedNames);
}

@Test
void 자동차_이름은_빈_문자열일_수_없다() {
String input = "pobi,,woni";

assertThatThrownBy(() -> InputHandler.commaSeparator(input))
.isInstanceOf(IllegalArgumentException.class);
}

@Test
void 자동차_이름은_5자_이하만_허용된다() {
String input = "pobi,woni,longname";

assertThatThrownBy(() -> InputHandler.commaSeparator(input))
.isInstanceOf(IllegalArgumentException.class);
}
}
38 changes: 38 additions & 0 deletions src/test/java/racingcar/RaceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package racingcar;

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

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Arrays;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.*;

class RaceTest {
private Race race;
private ByteArrayOutputStream outputStream;

@BeforeEach
void setUp() {
Car car1 = new Car("pobi");
Car car2 = new Car("woni");
race = new Race(Arrays.asList(car1, car2), 5);

outputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputStream));
}

@Test
void 경주가_정상적으로_진행되는지_테스트() {
race.runRace();
race.showWinners();

String output = outputStream.toString();
assertThat(output).contains("실행 결과"); // 경주 시작 메시지 확인
assertThat(output).contains("pobi : ", "woni : "); // 자동차의 위치 정보가 출력되었는지 확인

assertThat(output).contains("최종 우승자 : "); // 최종 우승자 메시지 확인
}
}