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
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,60 @@
# java-racingcar-precourse

---

# 기능 설계서

## Domain

1. Car
- 각 자동차에 대한 이름, 전진 횟수(점수)를 저장한다.
- 점수를 변경한다.
2. CarList
- 참여한 자동차를 List 형태로 관리한다.
- 최종 우승자를 찾는다.
3. Game
- 참여한 CarList, 게임 횟수를 관리한다.
- 진행 횟수가 남아있는지 판단한다.

## Model

1. GameService
- 게임을 진행한다.
- 진행 횟수가 남아있다면 전진하고 현재 상태 출력 신호를 보낸다.
- 랜덤값을 구해 전진할 수 있는지 판단하고 점수 변경 신호를 보낸다.
2. CarDTO
- 중간 진행 과정 출력을 위해 Car의 정보를 전달하는 객체
3. OutputPort
- GameService 진행 중에 직접 View를 호출하는 것을 방지하기 위해 데이터를 View에 전달하는 역할을 한다.
4. Validator
- 입력 받은 자동차 이름의 형식이 올바른지 판단한다.
- 입력 받은 전진 횟수의 형식이 올바른지 판단한다.

## View

1. getCarName : 자동차 이름 목록 입력 받기
2. getRoundCount : 경주 횟수 입력 받기
3. printStatusHeader : 중간 과정 머리말 출력하기(”실행 결과”)
4. printRaceStatus : 진행 과정 출력하기
5. formatOutput : 자동차의 이름과 현재 전진 횟수를 출력 형식에 맞게 변환하기
6. printFinalResult : 최종 우승자 출력하기

---

# 프로그램 흐름도

(경주 환경 설정)
1. 사용자로부터 자동차 이름 목록을 입력 받는다.
2. 입력 받은 이름 목록이 적절한 형식인지 검증한다.
3. 입력 받은 목록을 바탕으로 Car 인스턴스를 생성하고 CarList로 관리한다.
4. 사용자로부터 경주 횟수를 입력 받는다.
5. 입력 받은 경주 횟수가 적절한 형식인지 검증한다.
6. CarList와 경주 횟수를 바탕으로 Game 인스턴스를 생성한다.

(경주 진행)

7. 경주 횟수 동안 반복한다. (경주 횟수가 남아있다면)
1. 전진한다.(랜덤값 판단, 점수 변경)
2. 현재 상태를 출력한다.
8. 우승자를 찾는다.
9. 최종 결과를 출력한다.
14 changes: 14 additions & 0 deletions src/main/java/racingcar/AppConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package racingcar;

public class AppConfig {

final View view = new View();

public OutputPort outputPort(){
return new OutputPort(view);
}

public Controller controller(){
return new Controller(view, new Validator(), outputPort());
}
}
3 changes: 3 additions & 0 deletions src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
AppConfig appConfig = new AppConfig();
Controller controller = appConfig.controller();
controller.run();
}
}
24 changes: 24 additions & 0 deletions src/main/java/racingcar/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package racingcar;

public class Car {
private String name;
private int score;

public Car(String name) {
this.name = name;
score = 0;
}

public void plusScore(){
score++;
}

public CarDTO createCarDTO(){
return new CarDTO(this.name, this.score);
}

@Override
public String toString(){
return name + ":" + score;
}
}
4 changes: 4 additions & 0 deletions src/main/java/racingcar/CarDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package racingcar;

public record CarDTO(String name, int score) {
}
38 changes: 38 additions & 0 deletions src/main/java/racingcar/CarList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package racingcar;

import java.util.ArrayList;

public class CarList {
private ArrayList<Car> carArrayList;
private int carNumber;

public CarList(String[] carList) {
carArrayList = new ArrayList<>();
for (String string : carList) {
carArrayList.add(new Car(string));
}
carNumber = carList.length;
}

public int getCarNumber(){
return carNumber;
}

public void moveForward(int currentCarIndex) {
carArrayList.get(currentCarIndex).plusScore();
}

public ArrayList<CarDTO> printCurrentStatus(){
ArrayList<CarDTO> carListDTO = new ArrayList<>();
for (Car car : carArrayList) {
carListDTO.add(car.createCarDTO());
}
return carListDTO;
}

@Override
public String toString(){
return carArrayList.toString();
}

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

import java.util.ArrayList;

public class Controller {
View view;
Validator validator;
OutputPort outputPort;

public Controller(View view, Validator validator, OutputPort outputPort) {
this.view = view;
this.validator = validator;
this.outputPort = outputPort;
}

public void run(){
String[] carNameList = validator.validateCarName(view.getCarName());
CarList carList = new CarList(carNameList);
int roundCount = validator.validateRoundCount(view.getRoundCount());
Game game = new Game(carList, roundCount);
GameService gameService = new GameService(game, outputPort);
view.printStatusHeader();
gameService.runGame();
ArrayList<CarDTO> carDTOS = carList.printCurrentStatus();
view.printFinalResult(gameService.findWinnerList(carDTOS));
}
}
66 changes: 66 additions & 0 deletions src/main/java/racingcar/Game.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package racingcar;

import java.util.ArrayList;

public class Game {
private CarList carList;
private int roundCount;
private int currentRound;

public Game(CarList carList, int roundCount) {
this.carList = carList;
this.roundCount = roundCount;
currentRound = 0;
}

public boolean checkRemainRound(){
currentRound++;
if (currentRound > roundCount) {
return false;
}
return true;
}

public boolean hasNextCar(int currentCarIndex){
if(currentCarIndex<carList.getCarNumber()){
return true;
}
return false;
}

public void moveForward(int currentCarIndex){
carList.moveForward(currentCarIndex);
}

public ArrayList<CarDTO> printCurrentStatus(){
return carList.printCurrentStatus();
}

public ArrayList<String> findWinner(ArrayList<CarDTO> carDTOS){
int maxScore = findMaxScore(carDTOS);
ArrayList<String> winnerNameList = new ArrayList<>();
for (CarDTO car : carDTOS) {
addWinnerName(car,maxScore,winnerNameList);
}
return winnerNameList;
}

public int findMaxScore(ArrayList<CarDTO> carDTOS){
int maxScore = 0;
for (CarDTO car : carDTOS) {
maxScore = Math.max(maxScore, car.score());
}
return maxScore;
}

public void addWinnerName(CarDTO car, int maxScore, ArrayList<String> winnerNameList) {
if (car.score() == maxScore) {
winnerNameList.add(car.name());
}
}

@Override
public String toString(){
return carList.toString() + "," + roundCount + "," + currentRound;
}
}
44 changes: 44 additions & 0 deletions src/main/java/racingcar/GameService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package racingcar;

import java.util.ArrayList;

import static camp.nextstep.edu.missionutils.Randoms.pickNumberInRange;

public class GameService {
Game game;
OutputPort outputPort;

public GameService(Game game,OutputPort outputPort) {
this.game = game;
this.outputPort = outputPort;
}

public void runGame(){
while(game.checkRemainRound()){
proceedRound(true);
outputPort.printRaceStatus(game.printCurrentStatus());
}
}

public void proceedRound(boolean movingResult){
int currentCarIndex = 0;
while(game.hasNextCar(currentCarIndex)){
movingResult = decideMoving();
if (!movingResult) return;
game.moveForward(currentCarIndex++);
}
}

public ArrayList<String> findWinnerList(ArrayList<CarDTO> carDTOS){
return game.findWinner(carDTOS);
}

public boolean decideMoving(){
int result = pickNumberInRange(0,9);
if (result >= 4) {
return true;
}
return false;
}

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

import java.util.ArrayList;

public class OutputPort {
View view;

public OutputPort(View view) {
this.view = view;
}

public void printRaceStatus(ArrayList<CarDTO> carListDTO){
view.printRaceStatus(carListDTO);
}
}
33 changes: 33 additions & 0 deletions src/main/java/racingcar/Validator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package racingcar;

public class Validator {
public String[] validateCarName(String userInput) {
try{
String[] nameList = userInput.split(",");
if(!checkNameLength(nameList)){
throw new IllegalArgumentException();
}
return nameList;
}catch(Exception e) {
throw new IllegalArgumentException();
}
}

public boolean checkNameLength(String[] nameList) {
for (String name : nameList) {
if(name.length()>5) return false;
if(name.isEmpty()) return false;
}
return true;
}

public int validateRoundCount(String userInput) {
try {
int roundCount = Integer.parseInt(userInput);
if(roundCount<0) throw new IllegalArgumentException();
return roundCount;
} catch (Exception e) {
throw new IllegalArgumentException();
}
}
}
45 changes: 45 additions & 0 deletions src/main/java/racingcar/View.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package racingcar;

import java.util.ArrayList;

import static camp.nextstep.edu.missionutils.Console.readLine;

public class View {
public String getCarName(){
System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)");
return readLine();
}

public String getRoundCount() {
System.out.println("시도할 횟수는 몇 회인가요?");
return readLine();
}

public void printStatusHeader(){
System.out.println("\n실행 결과");
}

public void printRaceStatus(ArrayList<CarDTO> carListDTO){
for (CarDTO carDTO : carListDTO) {
System.out.print(formatOutput(carDTO));
}
System.out.print("\n");
}

public String formatOutput(CarDTO carDTO) {
StringBuilder sb = new StringBuilder();
sb.append(carDTO.name()).append(" : ");
for (int i = 0; i < carDTO.score(); i++) {
sb.append("-");
}
sb.append("\n");
return String.valueOf(sb);
}


public void printFinalResult(ArrayList<String> winnerNameList) {
String result = "최종 우승자 : "+String.join(", ",winnerNameList);
System.out.println(result);

}
}
Loading