Skip to content
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,20 @@ git checkout main // 기본 브랜치가 main인 경우
git checkout -b 브랜치이름
ex) git checkout -b apply-feedback
```

4. 기능 요구 사항
```jsx
- 3 대의 자동차의 이름을 입력받는다.(5자를 초과할 수 없다)
- 경주 레이스의 횟수를 입력받는다.
- 자동차마다 0에서 9 사이 랜덤 숫자를 저장할 변수를 갖는다.

(경주 시작)
- 매 횟수마다 자동차의 random 값이 갱신
- 4이상일 경우 전진

(경주 종료)
- 마지막에 가장 많이 전진한 자동차가 우승했음을 알려준다.
- 우승자는 한명 이상일 수 있다.


```
54 changes: 54 additions & 0 deletions src/main/java/StringAddCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class StringAddCalculator {
public static int splitAndSum(String s) {
String[] tokens = new String[0];
if(isNull(s)) return 0;

Matcher m = Pattern.compile("//(.)\n(.*)").matcher(s);
// 지정된 구분자가 있을 경우
if(m.find()) {
String customDelimiter = m.group(1);
tokens= m.group(2).split(customDelimiter);
}

// 구분자가 , 또는 : 일 경우
if(!m.find() && s.contains(",") || s.contains(":")) {
tokens = s.split(",|:");
}

// 숫자만 들어올 경우
if(tokens.length == 0){
return Integer.parseInt(s);
}

List<String> numList = arrayToList(tokens);
if(containsNegative(numList)) throw new RuntimeException();

return sum(numList);
}
public static List<String> arrayToList(String[] tokens) {
return Arrays.stream(tokens).sorted().collect(Collectors.toList());
}
public static int sum(List<String> numList) {
return numList.stream()
.mapToInt(Integer::parseInt).sum();
}
public static boolean isNull(String text) {
return (text == null) || (text.isEmpty());
}
// 메인 메소드
public static boolean containsNegative(List<String> list) {
return list.stream().mapToInt(Integer::parseInt).anyMatch(StringAddCalculator::isNegative);
}

// 음수인지 판별하는 메소드
private static boolean isNegative(int number) {
return number < 0;
}

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

import java.util.Random;

public class Car {
private final String name;
private final int randomNum;
private int raceScore;

public Car(String name) {
this.name = name;
this.randomNum = makeRandomNum();
this.raceScore = 0;
}

public static String[] splitCarNames(String str) {
return str.split(",");
}
public int makeRandomNum() {
Random random = new Random();
return random.nextInt(9)+1; // 1~9
}
public void addScore(int randomNum, int raceScore) {
if(randomNum >= 4) raceScore++;
this.raceScore = raceScore;
}
public int getRandomNum() {
return this.randomNum;
}
public int getRaceScore() {
return this.raceScore;
}
public String getName() {
return name;
}

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

import java.util.Scanner;

import static car_racing.Car.splitCarNames;

public class CarRacing {
public void racing() {
Scanner sc = new Scanner(System.in);
System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).");
String carNames = sc.nextLine();
Cars cars = new Cars(splitCarNames(carNames));


System.out.println("시도할 회수는 몇회인가요?");
int racingNum = sc.nextInt();

System.out.println("실행결과");
PrintResult print = null;
while (racingNum > 0) {
print = cars.printCurrent(cars.play());
racingNum--;
}

if(print != null) print.finalResult(cars.findHighestScore());

}
public CarRacing() {
racing();
}

public static void main(String[] args){
new CarRacing();
}
}
51 changes: 51 additions & 0 deletions src/main/java/car_racing/Cars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package car_racing;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.OptionalInt;
import java.util.stream.Collectors;

public class Cars {
private final List<Car> cars;

public Cars(String[] carsName) {
this.cars = getCars(carsName);
}

private List<Car> getCars(String[] carsName) {
List<Car> cars = new ArrayList<>();
for (int i = 0; i < 3; i++) {
cars.add(new Car(carsName[i]));
}
return cars;
}
public List<Car> play() {
for (Car c:
cars) {
c.addScore(c.makeRandomNum(), c.getRaceScore());
}
return cars;
}
// 매 회차마다 문자열 출력
public PrintResult printCurrent(List<Car> cars) {
PrintResult result = new PrintResult(cars);
for (Car c: cars) {
result.writeCurrentResult(c);
}System.out.println();
return result;
}
// 최대값 찾기
public List<Car> findHighestScore() {
OptionalInt maxScore = cars.stream()
.mapToInt(Car::getRaceScore)
.max();

return maxScore.isPresent() ?
cars.stream()
.filter(car -> car.getRaceScore() == maxScore.getAsInt())
.collect(Collectors.toList())
: Collections.emptyList(); // 최대값이 없으면 빈 리스트 반환
}

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

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

public class PrintResult {

private final List<Car> result;
public PrintResult(List<Car> result) {
this.result = result;
}
public void writeCurrentResult(Car car){
StringBuilder sb = new StringBuilder();
sb.append(car.getName()).append(" : ");
for (int i = 0; i < car.getRaceScore(); i++) {
sb.append("-");
}
System.out.println(sb);
}

public void finalResult(List<Car> result) {
if (result.isEmpty()) {
return;
}
String resultString = getResultString(result);
System.out.println(resultString + "가 최종 우승했습니다.");
}

private String getResultString(List<Car> result) {
StringBuilder sb = new StringBuilder();

for (Car car : result) {
sb.append(car.getName()).append(", ");
}

// 마지막 ", " 제거
int length = sb.length();
if (length > 0) sb.delete(length - 2, length);

return sb.toString();
}

}
45 changes: 45 additions & 0 deletions src/test/java/StringAddCalculatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import org.junit.jupiter.api.Test;

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

public class StringAddCalculatorTest {
@Test
public void splitAndSum_null_또는_빈문자() {
int result = StringAddCalculator.splitAndSum(null);
assertThat(result).isEqualTo(0);

result = StringAddCalculator.splitAndSum("");
assertThat(result).isEqualTo(0);
}

@Test
public void splitAndSum_숫자하나() throws Exception {
int result = StringAddCalculator.splitAndSum("1");
assertThat(result).isEqualTo(1);
}

@Test
public void splitAndSum_쉼표구분자() throws Exception {
int result = StringAddCalculator.splitAndSum("1,2");
assertThat(result).isEqualTo(3);
}

@Test
public void splitAndSum_쉼표_또는_콜론_구분자() throws Exception {
int result = StringAddCalculator.splitAndSum("1,2:3");
assertThat(result).isEqualTo(6);
}

@Test
public void splitAndSum_custom_구분자() throws Exception {
int result = StringAddCalculator.splitAndSum("//;\n1;2;3");
assertThat(result).isEqualTo(6);
}

@Test
public void splitAndSum_negative() throws Exception {
assertThatThrownBy(() -> StringAddCalculator.splitAndSum("-1,2,3"))
.isInstanceOf(RuntimeException.class);
}
}
32 changes: 32 additions & 0 deletions src/test/java/car_racing/CarTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package car_racing;

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

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

class CarTest {
Car car1, car2;
@BeforeEach
void setUp() {
car1 = new Car("pobi");
car2 = new Car("crong");
}
@Test
@DisplayName("자동차마다 갖게될 랜덤숫자 생성")
void car_randomNum() {
assertThat(car1.getRandomNum()).isNotZero();
assertThat(car2.getRandomNum()).isNotZero();
}
@Test
@DisplayName("자동차의 랜덤숫자가 4 이상일 때 점수에 축적")
void car_addScore() {
car1.addScore(2, 0);
car2.addScore(4,2);
assertThat(car1.getRaceScore()).isEqualTo(0);
assertThat(car2.getRaceScore()).isEqualTo(3);
}


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

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

import java.util.List;

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

class CarsTest {
Car car1, car2, car3;
@BeforeEach
void setup(){
car1 = new Car("pobi");
car2 = new Car("crong");
car3 = new Car("honux");
}

@Test
@DisplayName("3번를 진행할 때 가질 수 있는 max값은 회차 수와 같다")
void car_racing() {
String[] names = {"pobi", "crong", "honux"};
Cars cars = new Cars(names);
for (int i = 1; i <= 3; i++) {
List<Car> carResult = cars.play(); // 1~3회 진행
assertThat(carResult.get(0).getRaceScore()).isLessThanOrEqualTo(i); // i이하
assertThat(carResult.get(1).getRaceScore()).isLessThanOrEqualTo(i); // i이하
assertThat(carResult.get(2).getRaceScore()).isLessThanOrEqualTo(i); // i이하
}

}

@Test
@DisplayName(("종료 후 가장 높은 raceScore 을 보유한 List<Car> 출력 - 무조건 1개 이상"))
void find_highestScore() {
String[] names = {"pobi", "crong", "honux"};
Cars cars = new Cars(names);
for (int i = 1; i <= 3; i++) {
cars.play(); // 3회 진행
}
assertThat(cars.findHighestScore()).isNotNull();
}

}