Skip to content

[자동차 경주] 이해찬 4단계 미션 제출합니다. #61

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

Open
wants to merge 8 commits into
base: lhc0312
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
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 자동차 경주

## 1단계 - 움직이는 자동차
- [ ] 자동차는 이름을 가지고 있다.
- [x] 자동차는 움직일 수 있다.
- [X] 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다.

## 2단계 - 우승 자동차 구하기
- [X] n대의 자동차가 참여할 수 있다.
- [X] 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
- [X] 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다.
- [X] 자동차 경주 게임을 완료한 후 누가 우승했는지를 구할 수 있다. 우승자는 한 명 이상일 수 있다.

## 3단계 - 게임 실행
- [ ] 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
- [ ] 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
- [ ] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다.
- [ ] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다.
- [ ] 전진하는 조건은 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다.
- [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다.


## 바꾸자
선언할때 값을 할당 안해도 final를 넣을 수 있다..!

## 막히는 부분?
- Input시 예외처리..
InputView에서 하는가? Serive에서 하는가.
에러 핸들링은 어디서 하는가..
입력을 받자마자 바로 처리하는게 좋은 것인지, 코드상에서 에러가 나기 시작하는 지점에서 예외처리를 하는게 좋은 것인지..

- Dto를 제작해야 할까?
현재 코드에선 car.move가 public임
하지만 outView에서는 이 메소드에 접근하지 않으므로 CarList를 넘기는 것보다 RoundResultDto를 넘기는 것이 맞다 판단..

- 게임의 N번 실행은 Controller의 역할? RacingGame의 역할?
뭔가 RacingGame에서 N번 라운드를 실행해야 할 것 같다.
그러면 OutputView가 RacingGame의 라운드 결과를 출력하는 과정이 매끄럽지 않아진다.
* OutputView가 RacingGame 안에서 동작해야 함 -> contoller의 역할이 애매해진다.

- model(Domain)은 메소드를 안 가지는 것이 좋은가?
뭔가 도메인이 해야하는 일들은 서비스에서 처리하는 것이 더욱 깔끔할 것 같다..

- vaildator를 넣으면 특정 객체에 대한 탐색을 두번하게 된다 -> 비효율적인가?

- 출력되는 메세지는 어떻게 테스트하지?
애초에 테스트를 해야하나??
Empty file removed src/main/java/.gitkeep
Empty file.
11 changes: 11 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import controller.GameController;

public class Application {


public static void main(String[] args) {
final GameController gameController = new GameController();

gameController.start();
}
}
38 changes: 38 additions & 0 deletions src/main/java/Dto/GameResultDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package Dto;

import java.util.List;

public class GameResultDto {

private List<String> nameList;

public GameResultDto() {
}

public GameResultDto(Builder builder) {
this.nameList = builder.nameList;
}

public static Builder builder() {
return new Builder();
}

public static class Builder {

private List<String> nameList;

public Builder name(List<String> nameList) {
this.nameList = nameList;
return this;
}

public GameResultDto build() {
return new GameResultDto(this);
}

}

public List<String> getNameList() {
return this.nameList;
}
}
49 changes: 49 additions & 0 deletions src/main/java/Dto/RoundResultDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package Dto;

import java.util.List;

public class RoundResultDto {

private String name;
private int pos;

public RoundResultDto() {
}

public RoundResultDto(Builder builder) {
this.name = builder.name;
this.pos = builder.pos;
}

public static Builder builder() {
return new Builder();
}

public static class Builder {
private String name;
private int pos;

public Builder name(String name) {
this.name = name;
return this;
}

public Builder pos(int pos) {
this.pos = pos;
return this;
}

public RoundResultDto build() {
return new RoundResultDto(this);
}

}

public String getName() {
return this.name;
}

public int getPos() {
return this.pos;
}
}
35 changes: 35 additions & 0 deletions src/main/java/controller/GameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package controller;

import model.RacingGame;
import validator.Validator;
import view.InputView;
import view.OutputView;
import java.util.List;


public class GameController {
private final RacingGame racingGame= new RacingGame();

private final InputView inputView = new InputView();
private final OutputView outputView = new OutputView();
private final Validator validator = new Validator();

public void start() {

List<String> nameList = inputView.inputNameList();
validator.validName(nameList);

racingGame.createCarList(nameList);

int round = inputView.inputAttempt();
validator.validRound(round);

outputView.printRoundResultInfo();
for (int i=1; i<=round; i++) {
racingGame.run();
outputView.printRoundResult( racingGame.getRoundResult() );
}

outputView.printWinner( racingGame.getWinnerList() );
}
}
45 changes: 45 additions & 0 deletions src/main/java/model/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package model;

import service.NumGenerator;
import service.RandomNumGenerator;


public class Car {
private int pos=0;
private String name;
private NumGenerator numGenerator = new RandomNumGenerator();

public int getPos() {
return this.pos;
}

public void setPos(int pos) {
this.pos = pos;
}

public String getName() {
return this.name;
}

public Car (String name) {
numGenerator = new RandomNumGenerator();
this.name = name;
}

public Car (String name, NumGenerator numGenerator) {
this.numGenerator = numGenerator;
this.name = name;
}

public void move() {
int num = numGenerator.createNumber();
if (num > 9 || num < 0) {
throw new RuntimeException("생성된 숫자가 정해진 범위를 초과합니다.");
}

else if (num >= 4) {
pos += 1;
}
}

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

import Dto.GameResultDto;
import Dto.RoundResultDto;
import java.util.ArrayList;
import java.util.List;

public class RacingGame {

private int maxPos = 0;

private final List<Car> carList = new ArrayList<>();


public void createCarList(List<String> nameList) {
for (String name : nameList) {
carList.add(new Car(name));
}
}

private void getMaxPos() {
int maxPos = 0;
for (Car car : carList) {
maxPos = Math.max( maxPos, car.getPos() );
}

this.maxPos = maxPos;
}

private boolean isWinner(Car car) {
if (maxPos == car.getPos()) {
return true;
}
else {
return false;
}
}

public void run() {
for (Car car : carList) {
car.move();
}
}

public GameResultDto getWinnerList() {
List<String> winnerList = new ArrayList<>();

getMaxPos();

winnerList = carList.stream()
.filter( car -> isWinner(car) )
.map(Car::getName)
.toList();

return new GameResultDto().builder()
.name(winnerList)
.build();
}

public List<Car> getCarList() {
return carList;
}

public List<RoundResultDto> getRoundResult() {

List<RoundResultDto> roundResultDtoList = new ArrayList<>();

for(Car car : carList){
RoundResultDto roundResultDto = new RoundResultDto().builder()
.name(car.getName())
.pos(car.getPos())
.build();

roundResultDtoList.add(roundResultDto);
}

return roundResultDtoList;
}

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

public class FixedNumGenerator implements NumGenerator{

private int num;

public FixedNumGenerator (final int num) {
this.num = num;
}
@Override
public int createNumber() {
return num;
}
}
5 changes: 5 additions & 0 deletions src/main/java/service/NumGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package service;

public interface NumGenerator {
int createNumber();
}
18 changes: 18 additions & 0 deletions src/main/java/service/RandomNumGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package service;

import java.util.Random;

public class RandomNumGenerator implements NumGenerator {

private final int RAND_MAX = 10;
private final int RAND_MIN = 0;

@Override
public int createNumber() {
Random random = new Random();
return random.nextInt(0, 10);
}



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

public enum ErrorStatus {
INVAILD_ROUND_ERROR("시도할 횟수가 유효하지 않습니다."),
EMPTY_NAME_ERROR("이름에 빈값이 포함되어 있습니다."),
DUPLICATE_NAME_ERROR("중복된 이름이 존재합니다."),
NOT_FOUND_NAME_ERROR ("참가자가 존재하지 않습니다.");
private final String reason;

private ErrorStatus(String reason) {
this.reason = reason;
}

public String getReason() {
return reason;
}
}
Loading