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

[경북대 BE_김영인] 미션 제출합니다. #145

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2dc7c58
docs(README.md) : 기능 요구사항 분석 및 기능 목록 정리
Youngini Jun 9, 2024
4815840
feat(RacingCar.java) : 경주용 자동차 domain 작성
Youngini Jun 9, 2024
00c4eae
feat(RacingCarName.java) : 경주용 자동차 이름 길이 제한
Youngini Jun 9, 2024
d637374
feat(RacingCarName.java) : 경주용 자동차 이름 길이 제한
Youngini Jun 9, 2024
29a6a03
feat(RacingCars.java) : 경주용 자동차 중복 이름 사용 금지
Youngini Jun 9, 2024
ab9a3f8
feat(RacingCars.java) : 경주용 자동차 2개 이상 생성을 위한 예외 생성
Youngini Jun 9, 2024
107bc0a
feat(SplitingCarName.java) : 경주용 자동차들의 이름을 분리하기 위한 method
Youngini Jun 9, 2024
08a8ee8
feat(InputView.java) : 경주용 자동차들의 이름 입력받기 위한 view 구현
Youngini Jun 9, 2024
6c6c83f
feat(OutputView.java) : 경주용 자동차들의 이름 입력을 위한 안내사항 출력 view 작성
Youngini Jun 9, 2024
626f088
feat(MovingNum.java) : 경주용 자동차들의 이동 횟수를 위한 domain 작성
Youngini Jun 9, 2024
c185d3e
feat(RandomGenerator.java) : 0 ~ 9 사이의 난수 생성 util 구현
Youngini Jun 9, 2024
874b8e3
feat(Distance.java) : racingCar의 위치를 바꾸기 위한 record class 구현
Youngini Jun 9, 2024
3c543dd
feat(RacingCar.java) : racingCar의 위치 나타내기 위한 distance 변수 추가
Youngini Jun 9, 2024
42a1ae6
feat(RacingCar.java) : racingCar의 전진조건 추가
Youngini Jun 9, 2024
4a4c86d
feat(OutputView.java) : racingCar의 이동 횟수입력을 위한 출력 뷰 구현
Youngini Jun 9, 2024
892fd38
refactor (RacingCar.java) : racingCar getter method들 변수 수정
Youngini Jun 9, 2024
a86a83f
refactor (RacingCars.java) : racingCars 이름 getter method 변수 수정
Youngini Jun 9, 2024
12a35a2
feat (InputView.java) : 시도 횟수 입력 뷰 구현 완료
Youngini Jun 9, 2024
d077030
feat (OutputView.java) : 실행결과 출력뷰 구현
Youngini Jun 9, 2024
bf31d21
feat (OutputView.java) : racing game controller 구현
Youngini Jun 9, 2024
81eee2a
feat (Application.java) : 프로그램 실행의 시작점 구현
Youngini Jun 9, 2024
0fb1fc2
feat (Application.java) : racing game 시작 구현
Youngini Jun 9, 2024
ff75dda
feat (CreatingCar.java) : racing game을 위한 racing car 생성 util
Youngini Jun 9, 2024
0b0ad51
feat (RacingCameController.java) : racing game을 위한 racing car 생성을 위한 …
Youngini Jun 9, 2024
141b696
refactor (RacingCameController.java) : 생성자 단수형 -> 복수형으로 수정
Youngini Jun 9, 2024
1066930
feat (RacingCameController.java) : 게임 시작 시, 몇 번 이동할 지 선택하는 method 구현
Youngini Jun 9, 2024
933ab08
feat (RacingCars.java) : racing Car 객체 불러오는 method 구현
Youngini Jun 9, 2024
0359881
feat (Output.java) : 각 라운드 별, 자동차들의 이름, 전진한 거리를 출력하기 위한 view 구현
Youngini Jun 9, 2024
e7051b1
feat (RacingCars.java) : racing car 이동을 위한 method 구현
Youngini Jun 9, 2024
f54e8f4
feat (RacingGameController.java) : racing car 이동한 거리를 출력하는 View 연결
Youngini Jun 9, 2024
afbcb07
feat (RacingCar.java) : racing car 객체에서 거리 비교가 가능하도록 구현
Youngini Jun 9, 2024
368508a
feat (RacingCar.java) : racing car들 중 , 동일한 거리를 이동한 차 확인하는 메소드 구현
Youngini Jun 9, 2024
2d56843
feat (RacingCars.java) : 우승한 racing car(s)을 찾는 메소드 구현
Youngini Jun 9, 2024
99ce937
feat (OutputView.java) : 우승한 racing car(s)을 출력하는 view 구현
Youngini Jun 9, 2024
95f956e
feat (RacingCarNameTest.java) : racing Car naem List의 각 값이 1이상 5이하의 길…
Youngini Jun 10, 2024
5c22bd2
feat (RacingCarTest.java) : racing car들 끼리 중복된 이름 사용이 불가능한 것을 테스트 하는 기능
Youngini Jun 10, 2024
09b5a70
feat (RacingCarTest.java) : racing game을 하기 위해서는 racing car 적어도 2대 필요
Youngini Jun 10, 2024
2a1714b
feat (SplitingCarNameTest.java) : racingCar name들을 쉼표 기준으로 잘 구분하는 지 확…
Youngini Jun 10, 2024
b2be156
feat (TrialNumTest.java) : 사용자가 입력하는 이동 횟수가 숫자인지 아닌지 오류 검증하는 test 작성 완료
Youngini Jun 10, 2024
536ffca
feat (DistanceTest.java) : 자동차가 전진했다는 가정 하에 위치 변경을 test 한다.
Youngini Jun 10, 2024
6471c06
feat (RacingCarTest.java) : 랜덤값이 4미만이면 정지, 4이상이면 1 이동하는게 맞는지 확인하는 test
Youngini Jun 10, 2024
8b89d45
feat (RacingCarTest.java) : 같은 위치의 자동차가 있는 경우 출력이 잘 되는 지 확인하는 test
Youngini Jun 10, 2024
a2272b1
feat (RacingCarTest.java) : 각 자동차들의 위치 비교하는 test
Youngini Jun 10, 2024
801b9e5
feat (RacingCarTest.java) : 우승자 확인 test code 작성 완료
Youngini Jun 10, 2024
8c3c168
refactor (RacingCarName.java) : 예외 처리 오류 수정 (오류 오투 수정)
Youngini Jun 10, 2024
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
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
# java-racingcar-precourse
# java-racingcar-precourse

## 기능 요구 사항
초간단 자동차 경주 게임을 구현한다.

- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
- 각 자동차에 이름을 부여할 수 있다.
- 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다.
- 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다.
- 전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다.
- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다.
- 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다.
- 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`을 발생시킨 후 애플리케이션은 종료되어야 한다.

## 자동차 경주 기능 목록
- [ ] 게임을 시작하면, 경주할 자동차를 생성할 수 있어야 한다.
- [ ] 자동차는 쉼표(,)를 기준으로 구분하여 생성된다.
- [ ] 자동차 이름은 5자 이하만 가능하다.
- [ ] 자동차 이름은 중복으로 사용될 수 없다.
- [ ] 자동차경주를 하기위해서는, 자동차는 최소 2대 이상 생성해야한다.


- [ ] 사용자는 몇 번의 이동을 할 것인지 입력할 수 있다.
- [ ] 이동할 횟수는 0이상의 '자연수'이어야 한다.


- [ ] 자동차는 전진 또는 멈출 수 있다.
- [ ] 0에서 9사이에서 무작위한 값이 4이상인 경우 전진한다.
- [ ] 0에서 9사이의 무작위한 값이 3이하인 경우 멈춘다.


- [ ] 자동차 경주를 확인할 수 있다.
- [ ] 경주하는 자동차 이름을 확인할 수 있다.
- [ ] 라운드마다 자동차가 전진했다면 `-`로 이동 거리를 출력한다.


- [ ] 자동차 경주 게임의 우승자를 확인할 수 있다.
- [ ] 단독 우승자의 경우 우승한 자동차를 출력한다.
- [ ] 공동 우승자의 경우 우승한 자동차 이름을 `, `로 구분지어서 출력한다.
9 changes: 9 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import controller.RacingGameController;

public class Application {
public static void main(String[] args) {
RacingGameController racingGameController = new RacingGameController();
racingGameController.startGame();
}
}

43 changes: 43 additions & 0 deletions src/main/java/controller/RacingGameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package controller;

import domain.RacingCars;
import domain.TrialNum;
import util.CreatingCar;
import util.RandomGeneratingMove;
import view.InputView;
import view.OutputView;

public class RacingGameController {
private InputView inputView = new InputView();
private OutputView outputView = new OutputView();
private final RandomGeneratingMove randomGeneratingMove = new RandomGeneratingMove();
public void startGame(){
RacingCars racingCars = createRacingCars();
TrialNum trialNum = getTryCount();

racing(racingCars, trialNum);
}

private RacingCars createRacingCars(){
outputView.printRequestCarNames();
String[] carNames = inputView.inputCarNames();
return CreatingCar.createCars(carNames);
}

private TrialNum getTryCount(){
outputView.printRequestTryCount();
String inputTryCount = inputView.inputTryCount();
return new TrialNum(inputTryCount);
}

private void racing(RacingCars cars, TrialNum trialNum) {
outputView.printExecutionResult();

for (int i = 0; i < trialNum.getTrialNum(); i++) {
cars.moveAll(randomGeneratingMove);
outputView.printRoundByExecutionResults(cars);
}
outputView.printRacingCarWinnerResult(cars);
}

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

public record Distance(int location) {
private static final int MOVE_VALUE = 1;

public Distance increase(){
return new Distance(location + MOVE_VALUE);
}
}
36 changes: 36 additions & 0 deletions src/main/java/domain/RacingCar.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package domain;

public class RacingCar implements Comparable<RacingCar> {
private static final int MOVE_CONDITION = 4;

private RacingCarName racingCarName;
private Distance distance;

public RacingCar(final String name, final int distance) {
this.racingCarName = new RacingCarName(name);
this.distance = new Distance(distance);
}

public void move(final int num){
if(num >= MOVE_CONDITION){
this.distance = distance.increase();
}
}

public String getRacingCarName() {
return racingCarName.carName();
}

public Integer getDistance() {
return distance.location();
}

public boolean isSameDistance(RacingCar competeCar) {
return this.distance.location() == competeCar.distance.location();
}

@Override
public int compareTo(RacingCar competeCar) {
return this.distance.location() - competeCar.distance.location();
}
}
15 changes: 15 additions & 0 deletions src/main/java/domain/RacingCarName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package domain;

public record RacingCarName(String carName){
private static final int CAR_NAME_LENGTH_MAX = 5;

public RacingCarName {
isCarNameLengthValidate(carName);
}

private void isCarNameLengthValidate(final String carName){
if (carName.isEmpty() || carName.length() > CAR_NAME_LENGTH_MAX){
throw new IllegalArgumentException("자동차이름은 1자리이상 5자 이하만 가능합니다.");
}
}
}
66 changes: 66 additions & 0 deletions src/main/java/domain/RacingCars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package domain;

import util.RandomGeneratingMove;

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

public class RacingCars {
private static final int MINIMUM_CAR_COUNT = 2;
private final List<RacingCar> cars;

public RacingCars(List<RacingCar> cars) {
isDifferentCarName(cars);
minimumNumofCars(cars.size());
this.cars = cars;
}

public void moveAll(final RandomGeneratingMove randomGeneratingMove) {
for (final RacingCar car : cars) {
int engine = randomGeneratingMove.generateRandomInt();
car.move(engine);
}
}

private void isDifferentCarName(List<RacingCar> cars) {
List<String> carName = cars.stream()
.map(idx -> idx.getRacingCarName())
.collect(Collectors.toList());

HashSet<String> carNameDuplicateSet = new HashSet<>(carName);

if (carNameDuplicateSet.size() != carName.size()) {
throw new IllegalArgumentException("자동차 이름을 중복으로 사용할 수 없습니다.");
}
}

private void minimumNumofCars(int size) {
if (size < MINIMUM_CAR_COUNT) {
throw new IllegalArgumentException("자동차 경주를 위해서는 최소 2대 이상의 자동차를 만들어야 합니다.");
}
}

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

public List<String> findWinners(){
RacingCar maxDistanceCar = findMaxDistanceCar();
List<String> winnerCarNameList = findSameDistanceList(maxDistanceCar);
return winnerCarNameList;
}

private RacingCar findMaxDistanceCar() {
return cars.stream()
.max(RacingCar::compareTo)
.orElseThrow(() -> new IllegalArgumentException("차량 리스트가 비었습니다."));
}

private List<String> findSameDistanceList(RacingCar maxDistanceCar) {
return cars.stream()
.filter(maxDistanceCar::isSameDistance)
.map(RacingCar::getRacingCarName)
.collect(Collectors.toList());
}
}
25 changes: 25 additions & 0 deletions src/main/java/domain/TrialNum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package domain;

public class TrialNum {

private final int trialNum;

public TrialNum(final String trialNum) {
isNaturalNumberValidate(trialNum);
this.trialNum = convertStringToInt(trialNum);
}

private void isNaturalNumberValidate(String trialNum) {
if (!trialNum.matches("^[1-9]\\d*$")){
throw new IllegalArgumentException("이동할 횟수는 자연수여야 한다.");
}
}

private int convertStringToInt(String input) {
return Integer.parseInt(input);
}

public int getTrialNum() {
return trialNum;
}
}
26 changes: 26 additions & 0 deletions src/main/java/util/CreatingCar.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package util;

import domain.RacingCar;
import domain.RacingCars;
import java.util.stream.Collectors;
import java.util.Arrays;
import java.util.List;

public class CreatingCar {
private static final int START_LOCATION = 0;

public static RacingCars createCars(final String[] carNames) {
List<RacingCar> cars = makeCars(carNames);
return new RacingCars(cars);
}

private static List<RacingCar> makeCars(final String[] carNames) {
return Arrays.stream(carNames)
.map(CreatingCar::makeCar)
.collect(Collectors.toList());
}

private static RacingCar makeCar(final String carName) {
return new RacingCar(carName, START_LOCATION);
}
}
20 changes: 20 additions & 0 deletions src/main/java/util/RandomGeneratingMove.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package util;

import java.util.Random;

public class RandomGeneratingMove implements RandomGenerator {

private static final int MIN_RANDOM_NUMBER = 0;
private static final int MAX_RANDOM_NUMBER = 9;
private Random random;

public RandomGeneratingMove() {
this.random = new Random();
}

@Override
public int generateRandomInt() {
return random.nextInt((MAX_RANDOM_NUMBER - MIN_RANDOM_NUMBER + 1)) + MIN_RANDOM_NUMBER;
}
}

5 changes: 5 additions & 0 deletions src/main/java/util/RandomGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package util;

public interface RandomGenerator {
int generateRandomInt();
}
9 changes: 9 additions & 0 deletions src/main/java/util/SplitingCarName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package util;

public class SplitingCarName {
private static final String STRING_SPLITTER = ",";

public static String[] splitCarName(String carNames) {
return carNames.split(STRING_SPLITTER);
}
}
22 changes: 22 additions & 0 deletions src/main/java/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package view;

import util.SplitingCarName;

import java.util.Scanner;

public class InputView {
private Scanner scanner;

public InputView() {
this.scanner = new Scanner(System.in);
}

public String[] inputCarNames(){
String carNames = scanner.nextLine();
return SplitingCarName.splitCarName(carNames);
}

public String inputTryCount(){
return scanner.nextLine();
}
}
Loading