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
Binary file removed .gradle/7.5.1/checksums/checksums.lock
Binary file not shown.
Binary file removed .gradle/7.5.1/checksums/md5-checksums.bin
Binary file not shown.
Binary file removed .gradle/7.5.1/checksums/sha1-checksums.bin
Binary file not shown.
Binary file not shown.
Empty file.
Binary file removed .gradle/7.5.1/executionHistory/executionHistory.bin
Binary file not shown.
Binary file removed .gradle/7.5.1/executionHistory/executionHistory.lock
Binary file not shown.
Binary file removed .gradle/7.5.1/fileChanges/last-build.bin
Binary file not shown.
Binary file removed .gradle/7.5.1/fileHashes/fileHashes.bin
Binary file not shown.
Binary file removed .gradle/7.5.1/fileHashes/fileHashes.lock
Binary file not shown.
Empty file removed .gradle/7.5.1/gc.properties
Empty file.
Binary file removed .gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary file not shown.
2 changes: 0 additions & 2 deletions .gradle/buildOutputCleanup/cache.properties

This file was deleted.

Binary file removed .gradle/buildOutputCleanup/outputFiles.bin
Binary file not shown.
Binary file removed .gradle/file-system.probe
Binary file not shown.
Empty file removed .gradle/vcs-1/gc.properties
Empty file.
5 changes: 2 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ repositories {

dependencies {
implementation 'org.projectlombok:lombok:1.18.22'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.4.2'
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
}

Expand Down
Binary file removed out/production/classes/Application.class
Binary file not shown.
41 changes: 28 additions & 13 deletions src/main/java/controller/RacingGameController.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
package controller;

import exception.InvalidTryCountException;
import model.Cars;
import model.RacingCars;
import properties.ErrorMessage;
import service.Movable;
import service.RandomMoveConstraintsStrategy;
import view.RacingGameView;

public class RacingGameController {

private Cars cars;
private RacingCars racingCars;
private int tryCount;
private Movable moveStrategy;

public void start() {
init();
readyForRace();
race();
result();
printWinners();
}

private void readyForRace() {
initMoveStrategy();
askCarNames();
askTryCount();
}

private void init() {
private void initMoveStrategy() {
this.moveStrategy = new RandomMoveConstraintsStrategy();
}

private void askCarNames() {
RacingGameView.askCarNames();
initCars(RacingGameView.getConsoleInput());
initRacingCars(RacingGameView.getConsoleInput());
}

private void askTryCount() {
RacingGameView.askTryCount();
initTryCount(RacingGameView.getConsoleInput());
}

private void initCars(final String carNames) {
cars = new Cars(carNames);
private void initRacingCars(final String carNames) {
this.racingCars = new RacingCars(carNames);
}

private void initTryCount(final String tryCount) {
Expand All @@ -46,13 +61,13 @@ private int parsedTryCount(String tryCount) {
private void race() {
int playCount = 0;
while (playCount != tryCount) {
cars.move();
cars.moveResult();
racingCars.move(moveStrategy);
racingCars.moveResult();
playCount++;
}
}

private void result() {
cars.pickWinners();
private void printWinners() {
racingCars.printWinners();
}
}
7 changes: 7 additions & 0 deletions src/main/java/exception/InvalidPositionException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package exception;

public class InvalidPositionException extends RacingGameException {
public InvalidPositionException(String message) {
super(message);
}
}
17 changes: 9 additions & 8 deletions src/main/java/model/Car.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package model;

import service.Movable;
import view.RacingGameView;

public class Car {

private final CarName name;
private final Position position;
private Position position;

public Car(String name) {
this(name, 0);
Expand All @@ -16,26 +17,26 @@ public Car(String name, int position) {
this.position = new Position(position);
}

public void move() {
if (!position.canMove())
public void move(Movable moveStrategy) {
if (!moveStrategy.canMove())
return;

position.increasePosition();
this.position = this.position.increasePosition();
}

public void printCurrPosition() {
RacingGameView.printText(
name.getName() + " : " + position.indicateCharacterByPosition()
name.getName() + " : " + position.getPosition()
);
}

public int getCurrentPosition() {
return position.getPosition();
return position.getPosition().length();
}

public String getNameIfWin(int winnerPosition) {
if (position.getPosition() == winnerPosition)
return name.getName() + ", ";
if (position.getPosition().length() == winnerPosition)
return name.getName();

return "";
}
Expand Down
28 changes: 21 additions & 7 deletions src/main/java/model/Cars.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@

import exception.InvalidCarNameException;
import properties.ErrorMessage;
import service.Movable;
import view.RacingGameView;

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

public class Cars {
private final List<Car> cars;

private static final String CAR_NAME_DELIMITER = ",";

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

public Cars(String carNames) {
this.cars = makeCars(carNames);
}
Expand All @@ -22,8 +29,8 @@ public List<Car> makeCars(String carNames) {
return parsedCarNames(carNames).stream().map(Car::new).toList();
}

public void move() {
cars.forEach(Car::move);
public void move(Movable moveStrategy) {
cars.forEach(car -> car.move(moveStrategy));
}

public void moveResult() {
Expand All @@ -32,12 +39,19 @@ public void moveResult() {
RacingGameView.printLine();
}

public void pickWinners() {
int winnerPosition = cars.stream().mapToInt(Car::getCurrentPosition).max().getAsInt();
public int getWinnerPosition() {
return cars.stream().mapToInt(Car::getCurrentPosition).max().getAsInt();
}

public List<String> findWinnerNamesByPosition(int winnerPosition) {
StringBuilder result = new StringBuilder();
cars.forEach(car -> result.append(car.getNameIfWin(winnerPosition)));
String winners = result.substring(0, result.length() - 2);
RacingGameView.printText(winners + "가 최종 우승했습니다.");
cars.forEach(car ->
result.append(car.getNameIfWin(winnerPosition)).append(",")
);

return Stream.of(result.toString().split(","))
.filter(winner -> !winner.isBlank())
.collect(Collectors.toList());
}

private void validNames(String carNames) {
Expand Down
41 changes: 26 additions & 15 deletions src/main/java/model/Position.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
package model;

public class Position {
import exception.InvalidPositionException;
import properties.ErrorMessage;

import java.util.Objects;

private int position;
public class Position {

private static final int MOVE_CONDITION = 4;
private final int position;

private static final String DISPLAY_CHARACTER = "-";

public Position(int position) {
this.position = position;
public Position() {
this(0);
}

public int getPosition() {
return position;
public Position(int position) {
if (position < 0)
throw new InvalidPositionException(ErrorMessage.Position.NOT_POSITIVE_NUMBER);

this.position = position;
}

public void increasePosition() {
position++;
public Position increasePosition() {
return new Position(position + 1);
}

public boolean canMove() {
return createRandomNumber() >= MOVE_CONDITION;
public String getPosition() {
return DISPLAY_CHARACTER.repeat(Math.max(0, position));
}

public int createRandomNumber() {
return (int) (Math.random() * 10);
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Position position1 = (Position) o;
return position == position1.position;
}

public String indicateCharacterByPosition() {
return DISPLAY_CHARACTER.repeat(Math.max(0, position));
@Override
public int hashCode() {
return Objects.hash(position);
}
}
34 changes: 34 additions & 0 deletions src/main/java/model/RacingCars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package model;

import org.apache.commons.lang3.StringUtils;
import service.Movable;
import view.RacingGameView;

import java.util.List;

public class RacingCars {

private final Cars cars;

public RacingCars(String carNames) {
this.cars = new Cars(carNames);
}

public void move(Movable moveStrategy) {
cars.move(moveStrategy);
}

public void moveResult() {
cars.moveResult();
}

public void printWinners() {
RacingGameView.printText(findWinnerNames() + "가 최종 우승했습니다.");
}

private String findWinnerNames() {
List<String> winners = cars.findWinnerNamesByPosition(cars.getWinnerPosition());
return StringUtils.join(winners, ", ");
}

}
4 changes: 4 additions & 0 deletions src/main/java/properties/ErrorMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ public static class CarName {
public static class TryCount {
public static final String NOT_POSITIVE_NUMBER = "[ERROR] 시도 횟수 입력값은 1 이상의 정수여야만 합니다.";
}

public static class Position {
public static final String NOT_POSITIVE_NUMBER = "[ERROR] 위치 값은 음수일 수 없습니다.";
}
}
6 changes: 6 additions & 0 deletions src/main/java/service/Movable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package service;

@FunctionalInterface
public interface Movable {
boolean canMove();
}
11 changes: 11 additions & 0 deletions src/main/java/service/RandomMoveConstraintsStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package service;

public class RandomMoveConstraintsStrategy implements Movable {

private static final int CONSTRAINTS = 4;

@Override
public boolean canMove() {
return (int) (Math.random() * 10) >= CONSTRAINTS;
}
}
21 changes: 21 additions & 0 deletions src/test/java/model/CarNameTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package model;

import exception.InvalidCarNameException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import properties.ErrorMessage;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class CarNameTest {

@ParameterizedTest
@ValueSource(strings = {"123456"})
@DisplayName("잘못된 자동차 이름 에러 테스트")
void test(String parameter) {
InvalidCarNameException invalidCarNameException = assertThrows(InvalidCarNameException.class, () -> new CarName(parameter));
assertEquals(ErrorMessage.CarName.NOT_EXCEED_CAR_NAME_LENGTH, invalidCarNameException.getMessage());
}
}
27 changes: 27 additions & 0 deletions src/test/java/model/CarTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package model;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class CarTest {

@Test
@DisplayName("move전략의 움직임 여부가 true면 위치값이 1 증가한다.")
void test() {
Car car = new Car("seung");
car.move(() -> true);

assertEquals(1, car.getCurrentPosition());
}

@Test
@DisplayName("move전략의 움직임 여부가 false면 움직이지 않는다.")
void test2() {
Car car = new Car("seung");
car.move(() -> false);

assertEquals(0, car.getCurrentPosition());
}
}
Loading