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
24 changes: 24 additions & 0 deletions README-HS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 프로그래밍 요구사항
1. depth 2까지 가능
2. else, switch, 3항 연산자 사용 불가
3. 함수 또는 메소드는 한 가지 일만 하도록 구현
4. 모든 기능 단위 테스트 존재 필수 (System.out, System.in 로직 제외)
5. 모든 원시 값과 문자열 포장
6. 일급 컬렉션 사용

---

# 구현 기능
1. 게임 설명 출력
2. 자동차 이름 입력
1. 이름이 5자 미만인지 검증
2. 자동차 이름이 쉼표로 구분되어 있는지 검증
3. 시도 횟수 질문 출력
4. 시도 횟수 입력
1. 숫자 입력 했는지 검증
5. 게임 시작 (시도 횟수 만큼 반복)
1. random 값 생성 (0부터 9사이)
2. random 값이 4 이상일 경우 전진
3. 실행 결과 출력
5. 게임 결과, 최종 우승자 출력

2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
17 changes: 17 additions & 0 deletions src/main/java/RacingCarApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import racingcar.RacingCarGame;
import racingcar.model.RacingCars;
import racingcar.scanner.RacingCarScanner;

public class RacingCarApplication {
public static void main(String[] args) {
RacingCarScanner scanner = new RacingCarScanner();

RacingCars cars = new RacingCars(scanner.inputCarNames());

RacingCarGame game = new RacingCarGame(cars);
game.play(scanner.inputRepeat());
game.winner();


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

import racingcar.model.RacingCar;
import racingcar.model.RacingCars;
import racingcar.view.ResultView;

import java.util.Random;

public class RacingCarGame {
private static final int FORWARD_STANDARD = 4;
private static final int MAX_NUM = 9;

private final RacingCars cars;
private final Random random = new Random();

public RacingCarGame(RacingCars cars) {
this.cars = cars;
}

public void play(int repeatNum) {
for(int i=0; i<repeatNum; i++){
playRound();
}
}

public void playRound(){
for (RacingCar car : cars.getCars()) {
race(car, random.nextInt(MAX_NUM) + 1);
ResultView.displayRacingCar(car);
}
ResultView.printNewLine();
}


public void race(RacingCar car, int randomNum){
if (randomNum >= FORWARD_STANDARD){
car.forward();
}
}

public void winner() {
ResultView.displayRacingCars(cars);
ResultView.printWinner(cars.getWinnerName());
}
}

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

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

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

public void forward() {
location++;
}

public String getName(){
return name;
}

public int getLocation() {
return location;
}

public String formatRacingCar() {
return name + " : " + "-".repeat(location);
}
}
38 changes: 38 additions & 0 deletions src/main/java/racingcar/model/RacingCars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package racingcar.model;

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

public class RacingCars {
private List<RacingCar> cars;

public RacingCars(String[] carNames){
cars = new ArrayList<>();

for (String carName : carNames) {
RacingCar car = new RacingCar(carName);
cars.add(car);
}
}

public List<RacingCar> getCars() {
return cars;
}

public String getWinnerName() {
int winnerLocation = cars.stream()
.mapToInt(RacingCar::getLocation)
.max()
.orElse(0);


return cars.stream()
.filter(car -> car.getLocation() == winnerLocation)
.map(RacingCar::getName)
.collect(Collectors.joining(", "));
}



}
56 changes: 56 additions & 0 deletions src/main/java/racingcar/scanner/RacingCarScanner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package racingcar.scanner;

import racingcar.validation.InputValidator;
import racingcar.view.ErrorView;
import racingcar.view.InputView;

import java.util.Scanner;

public class RacingCarScanner {
private final Scanner scanner;
private final InputValidator validator;

public RacingCarScanner(){
this.scanner = new Scanner(System.in);
this.validator = new InputValidator();
}

public String[] inputCarNames(){
while (true) {
InputView.inputCarName();
String input = scanner.nextLine();

if (validator.isEmptyInput(input)) {
continue;
}

String[] inputArr = splitComma(input);
if (validator.isValidCarName(inputArr)){
return inputArr;
}

ErrorView.invalidInputCarName();
}
}


public int inputRepeat() {
while(true){
InputView.inputRepeatNum();
String repeatString = scanner.nextLine();

if (validator.isEmptyInput(repeatString)){
continue;
}

if (validator.isNumberInput(repeatString)){
return Integer.parseInt(repeatString);
}
}
}


public String[] splitComma(String input) {
return input.replaceAll(" ", "").split(",");
}
}
39 changes: 39 additions & 0 deletions src/main/java/racingcar/validation/InputValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package racingcar.validation;

import racingcar.view.ErrorView;

import java.util.Arrays;

public class InputValidator {
public static final int LIMIT_NAME_LENGTH = 5;

public boolean isValidCarName(String[] inputArr) {
return !isEmptyArray(inputArr) && Arrays.stream(inputArr).allMatch(this::isLessThanFiveCharacters);
}

public boolean isEmptyArray(String[] inputArr) {
return inputArr.length == 0;
}

public boolean isLessThanFiveCharacters(String input){
return input.length() < LIMIT_NAME_LENGTH;
}

public boolean isEmptyInput(String input) {
if (input.isEmpty()){
ErrorView.invalidInputEmpty();
return true;
}
return false;
}


public boolean isNumberInput(String input) {
if (!input.matches("\\d+")) {
ErrorView.invalidInputRepeat();
return false;
}

return true;
}
}
19 changes: 19 additions & 0 deletions src/main/java/racingcar/view/ErrorView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package racingcar.view;

public class ErrorView {
public static final String INVALID_INPUT_CAR_NAME_MESSAGE = "이름은 5자 이하로 입력 가능합니다. 다시 입력해주세요.";
public static final String INVALID_INPUT_EMPTY_MESSAGE = "공백은 입력할 수 없습니다. 다시 입력해주세요.";
public static final String INVALID_INPUT_REPEAT_MESSAGE = "시도 횟수는 숫자만 입력 가능합니다.";

public static void invalidInputCarName(){
System.out.println(INVALID_INPUT_CAR_NAME_MESSAGE);
}

public static void invalidInputEmpty(){
System.out.println(INVALID_INPUT_EMPTY_MESSAGE);
}

public static void invalidInputRepeat(){
System.out.println(INVALID_INPUT_REPEAT_MESSAGE);
}
}
14 changes: 14 additions & 0 deletions src/main/java/racingcar/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package racingcar.view;

public class InputView {
public static final String INPUT_CAR_NAME_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).";
public static final String INPUT_REPEAT_NUM_MESSAGE = "시도할 회수는 몇회인가요?";

public static void inputCarName() {
System.out.println(INPUT_CAR_NAME_MESSAGE);
}

public static void inputRepeatNum() {
System.out.println(INPUT_REPEAT_NUM_MESSAGE);
}
}
25 changes: 25 additions & 0 deletions src/main/java/racingcar/view/ResultView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package racingcar.view;

import racingcar.model.RacingCar;
import racingcar.model.RacingCars;

public class ResultView {
public static void displayRacingCars(RacingCars cars){
for (RacingCar car : cars.getCars()){
displayRacingCar(car);
}
printNewLine();
}

public static void displayRacingCar(RacingCar car){
System.out.println(car.formatRacingCar());
}

public static void printWinner(String winnerName){
System.out.println(winnerName + "가 최종 우승했습니다.");
}

public static void printNewLine(){
System.out.println();
}
}
49 changes: 49 additions & 0 deletions src/test/java/racingcar/RacingCarGameTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package racingcar;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import racingcar.model.RacingCar;
import racingcar.model.RacingCars;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class RacingCarGameTest {

private RacingCars cars;

@BeforeEach
void setUp(){
cars = new RacingCars(new String[]{"red", "blue"});
}


@Test
@DisplayName("랜덤 값이 4 이상이여서 전진")
void raceMore4(){
// given
RacingCarGame game = new RacingCarGame(cars);
RacingCar car1 = cars.getCars().get(0);

// when
game.race(car1, 4);

// then
assertEquals(car1.getLocation(), 1);
}

@Test
@DisplayName("랜덤 값이 4 이하여서 전진 안함")
void raceLessThan4(){
// given, when
RacingCarGame game = new RacingCarGame(cars);
RacingCar car1 = cars.getCars().get(0);

// when
game.race(car1, 3);

// then
assertEquals(car1.getLocation(), 0);
}

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

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

import static org.junit.jupiter.api.Assertions.*;

public class RacingCarTest {

@Test
@DisplayName("자동차 이름과 위치 문자열로 반환")
void formatRacingCar(){
// given
RacingCar car = new RacingCar("red");
car.forward();

// when
String response = car.formatRacingCar();

// then
assertEquals(response, "red : -");
}

}
Loading