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
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,52 @@

자동차 경주 미션 저장소

## 도메인 다이어그램

```mermaid
graph TD
RacingCarController --> InputView
RacingCarController --> OutputView
RacingCarController --> RacingGame

RacingGame --> Players
RacingGame --> TryCount

Players --> Player

Player --> Name
Player --> Distance

Distance --> Random

```

## 기능 구현 목록

### RacingGame

- [x] Players와 Trycount 관리한다.

### Players

- [x] 여러 명일 수 있다.

### Player

- [x] 이름을 가진다.
- [x] 최소 1자, 최대 5자까지 가능하다.
- [x] 중간 공백은 허용하고 쉼표로 구분한다.
- [x] 거리를 가진다.

### 입력

- [x] 플레이어의 이름을 입력한다.
- [x] 앞, 뒤 공백은 제거한다.
- [x] 이동 횟수를 입력한다.

### 출력

- [x] 최종 결과를 출력한다.
- [x] 최종 우승자를 출력한다.
- [x] 여러명일 수 있다.

13 changes: 9 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ version '1.0-SNAPSHOT'

repositories {
mavenCentral()
maven { url 'https://jitpack.io' }

}

dependencies {
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation platform('org.assertj:assertj-bom:3.25.1')
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation('org.assertj:assertj-core')
implementation 'com.github.kokodak:mission-utils:1.0.0'

implementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
implementation 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
implementation 'org.mockito:mockito-inline:3.12.4'
implementation 'org.assertj:assertj-core:3.21.0'
implementation 'org.junit.jupiter:junit-jupiter:5.8.1'
}

java {
Expand Down
7 changes: 0 additions & 7 deletions src/main/java/RacingMain.java

This file was deleted.

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

import racingcar.controller.RacingCarController;
import racingcar.view.InputView;
import racingcar.view.OutputView;

public class RacingMain {
public static void main(String[] args) {
final InputView inputView = new InputView();
final OutputView outputView = new OutputView();

final RacingCarController racingCarController = new RacingCarController(inputView, outputView);
racingCarController.run();
}
}
94 changes: 94 additions & 0 deletions src/main/java/racingcar/controller/RacingCarController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package racingcar.controller;

import racingcar.domain.RacingGame;
import racingcar.domain.players.Player;
import racingcar.domain.players.Players;
import racingcar.domain.trycount.TryCount;
import racingcar.view.InputView;
import racingcar.view.OutputView;
import racingcar.view.dto.PlayerResponse;

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

public class RacingCarController {
private final InputView inputView;
private final OutputView outputView;

public RacingCarController(final InputView inputView, final OutputView outputView) {
this.inputView = inputView;
this.outputView = outputView;
}
public void run() {
final Players players = getPlayers();
final TryCount tryCount = getTryCount();
final RacingGame racingGame = initRacingGame(players, tryCount);

PlayGame(racingGame);

printResult(racingGame);
}

private void PlayGame(final RacingGame racingGame) {
printResultMessage();
final int tryCount = racingGame.getTryCount();
for(int i=0; i<tryCount; i++){
race(racingGame);
printPlayersData(racingGame);
}
}

private void printResultMessage() {
outputView.printResultMessage();
}

private void printPlayersData(final RacingGame racingGame) {
for(Player p :racingGame.getPlayers()){
printPlayerData(p);
}
outputView.println();
}

private void printPlayerData(final Player player) {
outputView.printPlayerData(PlayerResponse.from(player));
}

private void race(final RacingGame racingGame) {
racingGame.startRace();
}

private void printResult(RacingGame racingGame) {
final List<PlayerResponse> playerResponses = getPlayerResponses(racingGame.findWinners());

outputView.printResult(playerResponses);
}

private List<PlayerResponse> getPlayerResponses(final List<Player> players) {
return players.stream()
.map(PlayerResponse::from)
.collect(Collectors.toList());
}

private RacingGame initRacingGame(Players players, TryCount tryCount) {
return new RacingGame(players, tryCount);
}

private TryCount getTryCount() {
return new TryCount(inputView.readTryCount());
}

private Players getPlayers() {
final List<Player> players = new ArrayList<>();
players.addAll(createPlayers());

return new Players(players);
}
private List<Player> createPlayers() {
final List<String> playerNames = inputView.readNames();

return playerNames.stream()
.map(Player::new)
.collect(Collectors.toList());
}
}
44 changes: 44 additions & 0 deletions src/main/java/racingcar/domain/RacingGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package racingcar.domain;

import racingcar.domain.players.Player;
import racingcar.domain.players.Players;
import racingcar.domain.trycount.TryCount;

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

public class RacingGame {
private final Players players;
private final TryCount tryCount;

public RacingGame(Players players, TryCount tryCount) {
this.players = players;
this.tryCount = tryCount;
}

public void startRace() {
players.race();
}

public int getTryCount() {
return tryCount.getTryCount();
}

public List<Player> getPlayers() {
return players.getPlayers();
}

public List<Player> findWinners() {
int maxDistance = getMaxDistance();
return players.getPlayers().stream()
.filter(p -> p.getDistance() == maxDistance)
.collect(Collectors.toList());
}
private int getMaxDistance() {
return players.getPlayers().stream()
.mapToInt(Player::getDistance)
.max()
.orElse(0);
}
}

26 changes: 26 additions & 0 deletions src/main/java/racingcar/domain/players/Movement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package racingcar.domain.players;

import racingcar.domain.random.Random;

public class Movement {
private String movement ="";

public void move(){
final Random random = new Random();
if(random.getRandom()>=4)
moveForward();
}

private void moveForward(){
this.movement +="-";
}

public String getMovement() {
return movement;
}

public int getDistance() {
return movement.length();
}

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

import java.util.Objects;

public class Name {

private static final int UPPER_BOUND = 5;
private final String name;

public Name(final String input) {
validate(input);
this.name = input;
}

private void validate(final String input) {
validateNullAndBlank(input);
validateLength(input);
}

private void validateNullAndBlank(final String input) {
if (input == null || input.isBlank()) {
throw new IllegalArgumentException("[ERROR] 이름이 존재하지 않습니다.");
}
}

private void validateLength(final String input) {
if (input.length() > UPPER_BOUND) {
throw new IllegalArgumentException("[ERROR] 이름은 " + UPPER_BOUND + "글자 이하여야 합니다. 현재 이름: " + input);
}
}

public String getName() {
return name;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Name n = (Name) o;
return Objects.equals(name, n.name);
}

@Override
public int hashCode() {
return Objects.hash(name);
}

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

import java.util.Objects;

public class Player {
private final Name name;
private final Movement movement;

public Player(String name) {
this.name = new Name(name);
this.movement = new Movement();
}

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

public String getMovement() {
return movement.getMovement();
}

public int getDistance() {
return movement.getDistance();
}

public void race() {
movement.move();
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Player player = (Player) o;
return Objects.equals(name, player.name);
}

@Override
public int hashCode() {
return Objects.hash(name);
}
}
29 changes: 29 additions & 0 deletions src/main/java/racingcar/domain/players/Players.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package racingcar.domain.players;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Players {
private final List<Player> players;

public Players(final List<Player> players) {
validateDuplicate(players);
this.players = List.copyOf(players);
}
private void validateDuplicate(final List<Player> players) {
final Set<Player> uniquePlayers = new HashSet<>(players);

if (uniquePlayers.size() != players.size()) {
throw new IllegalArgumentException("[ERROR] 참가자 이름은 중복될 수 없습니다.");
}
}
public void race() {
players.forEach(Player::race);
}

public List<Player> getPlayers() {
return players;
}

}
Loading