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

[자동차 경주] 최승훈 미션 제출합니다. #60

Open
wants to merge 16 commits into
base: sseung3424
Choose a base branch
from
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
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# 자동차 경주 게임

## 기능 요구사항
sseung3424 marked this conversation as resolved.
Show resolved Hide resolved
- [x] 자동차는 이름을 가지고 있다.
- [x] 자동차는 움직일 수 있다.
- [x] 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다.
- [x] n대의 자동차가 참여할 수 있다.
- [x] 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
- [x] 자동차 경주 게임을 완료한 후 누가 우승했는지를 구할 수 있다. 우승자는 한 명 이상일 수 있다.

## 새로운 프로그래밍 요구사항
- [x] 자동차가 움직이는 기능이 의도대로 동작하는지 테스트한다.
- [x] 우승자를 구하는 기능이 의도대로 동작하는지 테스트한다.

## 자바 코드 컨벤션(Java Style Guide)
- [x] indent(인덴트, 들여쓰기) depth를 2를 넘지 않도록 구현한다. 1까지만 허용한다.
- 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
- 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
- [x] 3항 연산자를 쓰지 않는다.
- [x] else 예약어를 쓰지 않는다.
- [x] else 예약어를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다.
- 힌트: if문에서 값을 반환하는 방식으로 구현하면 else 예약어를 사용하지 않아도 된다.
- [x] 함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.
- [x] 함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다.

## 기능 요구사항
- [x] 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
- [x] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다.
- [x] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다.

- 실행 결과

위 요구사항에 따라 3대의 자동차가 5번 움직였을 경우 프로그램을 실행한 결과는 다음과 같다.
경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).
neo,brie,brown
시도할 회수는 몇회인가요?
5

실행 결과
neo : -
brie : -
brown : -

neo : --
brie : -
brown : --

neo : ---
brie : --
brown : ---

neo : ----
brie : ---
brown : ----

neo : -----
brie : ----
brown : -----

neo : -----
brie : ----
brown : -----

neo, brown가 최종 우승했습니다.

- [x] 메인 메서드를 추가하여 실행 가능한 애플리케이션으로 만든다.
15 changes: 15 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import view.InputView;
import view.ResultView;
import domain.CarRace;

public class Application {
public static void main(String[] args) {
final var carNames = InputView.getCarNames();
final var tryCount = InputView.getTryCount();

final var racingGame = new CarRace(tryCount, carNames);
racingGame.runRace();

ResultView.printWinners(racingGame.getWinners());
}
}
69 changes: 69 additions & 0 deletions src/main/java/domain/CarRace.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package domain;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class CarRace {
private final int rounds;
private final List<RacingCar> cars = new ArrayList<>();
private final List<String> coWinners = new ArrayList<>();

public CarRace(final int rounds, String carNames) {
this.rounds = rounds;
Arrays.stream(carNames.split(","))
.map(RacingCar::new)
.forEach(cars::add);
}

public int getDistance(int index) {
return cars.get(index).getDistance();
}

public List<String> getWinnersName() {
return updateAllWinners(findWinningDistance());
}

public List<String> getWinners() {
return coWinners;
}

public void carMove(int number) {
for(RacingCar car : cars)
car.move(number);
}

public void runRace() {
System.out.println("실행 결과");
for (int i = 0; i < rounds; i++) {
moveAllCars();
}
int winningDistance = findWinningDistance();
updateAllWinners(winningDistance);
}

private void moveAllCars() {
Random random = new Random();
for(RacingCar car : cars) {
int randNum = random.nextInt(1, 11);
car.move(randNum);
System.out.println(car.getName() + " : " + "-".repeat(car.getDistance()));
}
System.out.println(" ");
}

private int findWinningDistance() {
return cars.stream()
.mapToInt(RacingCar::getDistance)
.max()
.orElse(0);
}

private List<String> updateAllWinners(int winningDistance) {
cars.stream()
.filter(c -> c.getDistance() == winningDistance)
.forEach(c -> coWinners.add(c.getName()));
return coWinners;
}
}
24 changes: 24 additions & 0 deletions src/main/java/domain/RacingCar.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package domain;

public class RacingCar {
private final String name;
private int distance;

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

public String getName() {
return name;
}

public int getDistance() {
return distance;
}

public void move(int randNum) {
if(randNum >= 4)
distance += 1;
}
}
27 changes: 27 additions & 0 deletions src/main/java/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package view;

import domain.CarRace;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class InputView {
static Scanner scanner = new Scanner(System.in);

public static String getCarNames() {
System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분): ");
String carNames = scanner.nextLine();
while (Arrays.stream(carNames.split(","))
.anyMatch(s -> s.length() >= 6))
{
System.out.println("이름은 5자 이하만 가능합니다.");
carNames = scanner.nextLine();
}
return carNames;
}

public static int getTryCount() {
System.out.println("시도할 회수는 몇회인가요?");
return scanner.nextInt();
}
}
11 changes: 11 additions & 0 deletions src/main/java/view/ResultView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package view;

import java.util.List;

public class ResultView {
public static void printWinners(List<String> winners) {
String result = String.join(", ", winners);
System.out.println(result + "가 최종 우승했습니다.");
}

}
52 changes: 52 additions & 0 deletions src/test/java/CarRaceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import static org.assertj.core.api.Assertions.assertThat;

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

public class CarRaceTest {

final String carNames = "neo,brie,brown";

@Test
@DisplayName("자동차_경주_우승자_찾기")
public void 자동차_경주_우승자_찾기() {
final int roundNum = 10;
final CarRace carRace = new CarRace(roundNum, carNames);
carRace.runRace();

String expected = carRace.getWinnersName().toString();
String actual = carRace.getWinners().toString();

assertThat(actual)
.isEqualTo(expected);
}

@Test
@DisplayName("숫자_4이상일_때_자동차_경주_테스트")
public void 숫자_4이상일_때_자동차_경주_테스트() {
final int roundNum = 1;
final CarRace carRace = new CarRace(roundNum, carNames);
carRace.carMove(4);

int expected = 1;
int actual = carRace.getDistance(2);

assertThat(actual)
.isEqualTo(expected);
}

@Test
@DisplayName("숫자_3이하일_때_자동차_경주_테스트")
public void 숫자_3이하일_때_자동차_경주_테스트() {
final int roundNum = 1;
final CarRace carRace = new CarRace(roundNum, carNames);
carRace.carMove(3);

int expected = 0;
int actual = carRace.getDistance(2);

assertThat(actual)
.isEqualTo(expected);
}
}