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

[혁] 레이싱 게임 #18

Open
wants to merge 19 commits into
base: master
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
6 changes: 6 additions & 0 deletions .idea/encodings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions .idea/racing-game.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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

import racing.domain.CarFactory;
import racing.domain.CarMover;
import racing.domain.RacingCars;
import racing.domain.RacingField;
import racing.view.InputHelper;
import racing.view.OutputView;

import java.util.List;

public class RacingGameApplication {
public static void main(String[] args) {
OutputView outputView = new OutputView();
InputHelper inputHelper = new InputHelper(outputView);

List<String> carNames = inputHelper.getCarNames();
int totalGameTurns = inputHelper.getTotalGameTurns();

RacingCars racingCars = CarFactory.createRacingCars(carNames, new CarMover());
RacingField racingField = new RacingField(totalGameTurns, racingCars);

outputView.printRacingResult(racingField.race());
}
}
49 changes: 49 additions & 0 deletions src/main/java/racing/domain/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package racing.domain;

import java.util.Objects;

public class Car {
private int drivenDistance = 0;
private Mover mover;
private String name;

public Car(String name, Mover mover) {
verifyName(name);
this.name = name;
this.mover = mover;
}

public void move() {
if (mover.canMove()) {
drivenDistance++;
}
}

public int getDrivenDistance() {
return drivenDistance;
}

public String getName() {
return name;
}

private void verifyName(String name) {
if (name.isEmpty()) {
throw new IllegalArgumentException("자동차의 이름은 공백일 수 없음.");
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return drivenDistance == car.drivenDistance &&
Objects.equals(mover, car.mover);
}

@Override
public int hashCode() {
return Objects.hash(drivenDistance, mover);
}
}
16 changes: 16 additions & 0 deletions src/main/java/racing/domain/CarFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package racing.domain;

import java.util.ArrayList;
import java.util.List;

public class CarFactory {

public static RacingCars createRacingCars(List<String> carNames, Mover mover) {
List<Car> cars = new ArrayList<>();
for (String carName : carNames) {
Car car = new Car(carName, mover);
cars.add(car);
}
return new RacingCars(cars);
}
}
17 changes: 17 additions & 0 deletions src/main/java/racing/domain/CarMover.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package racing.domain;

import java.util.Random;

public class CarMover implements Mover {
private static final int RANDOM_ADJUSTER = 10;
private static final int FORWARD_CONDITION = 4;

private Random random = new Random();

@Override
public boolean canMove() {
int randomNum = random.nextInt(RANDOM_ADJUSTER);
return FORWARD_CONDITION <= randomNum;
}

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

public interface Mover {

boolean canMove();

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

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

public class RacingCars {
private List<Car> cars;

public RacingCars(List<Car> cars) {
verifyCarsNotEmpty(cars);
this.cars = cars;
}

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

public List<Integer> getDistances() {
return cars.stream()
.map(Car::getDrivenDistance)
.collect(Collectors.toList());
}

public List<String> getCarNames() {
return cars.stream()
.map(Car::getName)
.collect(Collectors.toList());
}

private void verifyCarsNotEmpty(List<Car> cars) {
if (cars.isEmpty()) {
throw new IllegalArgumentException("RacingCars는 항상 Car가 1개 이상이어야 합니다.");
}
}

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

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

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

public class RacingField {
private final int totalTurns;
private final RacingCars racingCars;

public RacingField(int totalTurns, RacingCars racingCars) {
this.totalTurns = totalTurns;
this.racingCars = racingCars;
}

public RacingResult race() {
List<RacingTurn> racingTurns = new ArrayList<>();
for (int turn = 0; turn < totalTurns; turn++) {
racingCars.move();
RacingTurn racingTurn = new RacingTurn(racingCars.getDistances());
racingTurns.add(racingTurn);
}
return new RacingResult(new RacingTurns(racingTurns), racingCars.getCarNames());
}
}
57 changes: 57 additions & 0 deletions src/main/java/racing/domain/RacingResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package racing.domain;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class RacingResult {
private List<String> carNames;
private List<String> winners;
private RacingTurns racingTurns;

public RacingResult(RacingTurns racingTurns, List<String> carNames) {
this.racingTurns = racingTurns;
this.carNames = carNames;
this.winners = findWinners();
}

public List<String> getCarNames() {
return new ArrayList<>(carNames);
}

public List<String> getWinners() {
return new ArrayList<>(winners);
}

public RacingTurns getRacingTurns() {
return racingTurns;
}

private List<String> findWinners() {
int maxDistance = racingTurns.getMaxDistance();
List<Integer> lastTurnCarDistances = racingTurns.getLastTurnCarDistances();
return IntStream.range(0, carNames.size())
.boxed()
.filter(i -> lastTurnCarDistances.get(i) == maxDistance)
.map(i -> carNames.get(i))
.collect(Collectors.toList());
Comment on lines +34 to +40
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Winner는 distance와 name으로 결정되는데 그 상태들이 서로 따로 행동하고 있어
나느 응집도가 떨어지는것으로 보이는데 이 상태값들을 하나로 관리할 수 있는 방향으로 리팩토링을 다시 해보면 좋을 것 같아
그렇게 되면 여러 책임이 다른 객체에게 위임될 수 있을것 같아

}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RacingResult that = (RacingResult) o;
return Objects.equals(carNames, that.carNames) &&
Objects.equals(winners, that.winners) &&
Objects.equals(racingTurns, that.racingTurns);
}

@Override
public int hashCode() {
return Objects.hash(carNames, winners, racingTurns);
}
}
30 changes: 30 additions & 0 deletions src/main/java/racing/domain/RacingTurn.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package racing.domain;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class RacingTurn {
private final List<Integer> carDistances;

public RacingTurn(List<Integer> carDistances) {
this.carDistances = carDistances;
}

public List<Integer> getCarDistances() {
return new ArrayList<>(carDistances);
}

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

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

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

public class RacingTurns {

private List<RacingTurn> racingTurns;

public RacingTurns(List<RacingTurn> racingTurns) {
verifyRacingTurnsNotEmpty(racingTurns);
this.racingTurns = racingTurns;
}

public List<RacingTurn> get() {
return new ArrayList<>(racingTurns);
}

public int getMaxDistance() {
return getLastTurn()
.getCarDistances()
.stream()
.max(Comparator.naturalOrder())
.orElseThrow(IllegalStateException::new);
}

public List<Integer> getLastTurnCarDistances() {
return getLastTurn().getCarDistances();
}

private RacingTurn getLastTurn() {
int lastTurnIndex = racingTurns.size() - 1;
return racingTurns.get(lastTurnIndex);
}

private void verifyRacingTurnsNotEmpty(List<RacingTurn> racingTurns) {
if (racingTurns.isEmpty()) {
throw new IllegalStateException("RacingTurn의 개수는 0개일 수 없음.");
}
}

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

@Override
public int hashCode() {
return Objects.hash(racingTurns);
}
}
Empty file.
25 changes: 25 additions & 0 deletions src/main/java/racing/view/InputHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package racing.view;

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

public class InputHelper {
private Scanner scanner;
private OutputView outputView;

public InputHelper(OutputView outputView) {
this.outputView = outputView;
this.scanner = new Scanner(System.in);
}

public int getTotalGameTurns() {
outputView.printInputGameTurnsNotice();
return scanner.nextInt();
}

public List<String> getCarNames() {
outputView.printInputCarNamesNotice();
return Arrays.asList(scanner.nextLine().split(","));
}
}
Loading