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

πŸš€ 4단계 - μžλ™μ°¨ κ²½μ£Ό(우승자) - μ½”λ“œλ¦¬λ·°λ₯Ό λ°”νƒ•μœΌλ‘œ μˆ˜μ • #5807

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
bb020a6
Step1 (#5615)
yunji1201 Sep 26, 2024
cdfb759
2단계 - λ¬Έμžμ—΄ λ§μ…ˆ 계산기 (#5715)
yunji1201 Oct 2, 2024
e06edf2
3단계 - μžλ™μ°¨ κ²½μ£Ό (#5736)
yunji1201 Oct 5, 2024
3945b00
refactor : μ½”λ“œλ¦¬λ·°λ₯Ό λ°”νƒ•μœΌλ‘œ λ¦¬νŒ©ν† λ§ μž‘μ—…
yunji1201 Oct 7, 2024
0dc8a6b
refactor : 도메인(Racing)이 view(ResultView)에 μ˜μ‘΄ν•˜μ§€ μ•Šλ„λ‘ ꡬ쑰 λ³€κ²½
yunji1201 Oct 7, 2024
d80b43b
docs : 4단계 κΈ°λŠ₯ μš”κ΅¬μ‚¬ν•­ 정리
yunji1201 Oct 9, 2024
ea596ee
test : μžλ™μ°¨ 이름이 5κΈ€μž 이상인 경우 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•˜λŠ”μ§€ ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈ
yunji1201 Oct 9, 2024
29fff60
feat : μ‚¬μš©μžκ°€ μžλ™μ°¨μ˜ 이름을 μž…λ ₯ ν•  수 μžˆμ–΄μ•Ό 함
yunji1201 Oct 9, 2024
badbbec
feat : μ „μ§„ν•˜λŠ” μžλ™μ°¨λ₯Ό 좜λ ₯ν•  λ•Œ 이름을 같이 좜λ ₯
yunji1201 Oct 9, 2024
d986739
test : κ°€μž₯ λ§Žμ€ 거리λ₯Ό κ°„ μžλ™μ°¨λ₯Ό 우승자둜 λ°˜ν™˜ν•˜λŠ”μ§€ ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈ 진행
yunji1201 Oct 9, 2024
0e5005e
feat : λ ˆμ΄μ‹± μ™„λ£Œ ν›„ 우승자λ₯Ό 좜λ ₯ν•˜λŠ” κΈ°λŠ₯ μΆ”κ°€
yunji1201 Oct 9, 2024
13a7434
test : Racing ν΄λž˜μŠ€μ— λŒ€ν•œ ν…ŒμŠ€νŠΈ μΆ”κ°€
yunji1201 Oct 9, 2024
f181330
refactor : 각 도메인에 맞게 ν…ŒμŠ€νŠΈ 뢄리
yunji1201 Oct 9, 2024
68499a7
refactor : μ½”λ“œλ¦¬λ·° 받은걸 λ°”νƒ•μœΌλ‘œ λ¦¬νŒ©ν† λ§ 진행
yunji1201 Oct 9, 2024
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
28 changes: 28 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
### TODO

1. [x] κ΅¬ν˜„ν•  κΈ°λŠ₯ λͺ©λ‘μ„ 정리해 μΆ”κ°€
2. [x] μžλ™μž 수, 이동 수 μž…λ ₯ ν•  수 μžˆμ–΄μ•Ό 함
3. [x] μ „μ§„ν•˜λŠ” 쑰건은 0μ—μ„œ 9 μ‚¬μ΄μ—μ„œ random 값을 κ΅¬ν•œ ν›„ random 값이 4이상일 경우
4. [x] λͺ¨λ“  μžλ™μ°¨κ°€ 이동을 μ™„λ£Œν•˜λ©΄ μ’…λ£Œ
5. [x] μžλ™μ°¨μ˜ μƒνƒœλ₯Ό 화면에 좜λ ₯
6. [x] 각 μžλ™μ°¨μ— 이름 μž…λ ₯ κ°€λŠ₯
7. [x] μžλ™μ°¨ 이름은 5κΈ€μžλ₯Ό μ΄ˆκ³Όν•  수 μ—†μŒ
9. [x] μžλ™μ°¨ 이름은 μ‰Όν‘œ(,)λ₯Ό κΈ°μ€€μœΌλ‘œ ꡬ뢄
8. [x] μ „μ§„ν•˜λŠ” μžλ™μ°¨λ₯Ό 좜λ ₯ν•  λ•Œ 이름 같이 좜λ ₯
10. [x] μžλ™μ°¨ κ²½μ£Ό κ²Œμž„μ„ μ™„λ£Œν•œ ν›„ λˆ„κ°€ μš°μŠΉν–ˆλŠ”μ§€λ₯Ό μ•Œλ €μ€Œ. μš°μŠΉμžλŠ” ν•œλͺ… 이상도 κ°€λŠ₯.

- 값을 μž…λ ₯ λ°›λŠ” APIλŠ” Scannerλ₯Ό 이용
- 랜덀 값은 μžλ°” java.util.Random 클래슀의 nextInt(10) λ©”μ†Œλ“œλ₯Ό ν™œμš©
- else μ˜ˆμ•½μ–΄λ₯Ό 쓰지 μ•ŠλŠ”λ‹€
- κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κΈ° 전에 README.md νŒŒμΌμ— κ΅¬ν˜„ν•  κΈ°λŠ₯ λͺ©λ‘μ„ 정리해 μΆ”κ°€
- git의 commit λ‹¨μœ„λŠ” μ•ž λ‹¨κ³„μ—μ„œ README.md νŒŒμΌμ— μ •λ¦¬ν•œ κΈ°λŠ₯ λͺ©λ‘ λ‹¨μœ„λ‘œ μΆ”κ°€

### AngularJS Commit Message Conventions

* feat (feature)
* fix (bug fix)
* docs (documentation)
* style (formatting, missing semi colons, …)
* refactor
* test (when adding missing tests)
* chore (maintain)
64 changes: 64 additions & 0 deletions src/main/java/calculator/StringAddCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package calculator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringAddCalculator {

public static final String DEFAULT_DELIMITER = ",|:";
public static final String CUSTOM_DELIMITER = "//(.)\n(.*)";
public static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile(CUSTOM_DELIMITER);

public static int calculateSum(String text) {
if (isBlank(text)) {
return 0;
}
return sumValues(toInts(splitValues(text)));
}

private static String[] splitValues(String text) {
Matcher matcher = CUSTOM_DELIMITER_PATTERN.matcher(text);
if (matcher.find()) {
String customDelimiter = matcher.group(1);
return matcher.group(2).split(customDelimiter);
}
return text.split(DEFAULT_DELIMITER);
}

private static boolean isBlank(String text) {
return text == null || text.isBlank();
}

private static int[] toInts(String[] values) {
int[] numbers = new int[values.length];

for (int i = 0; i < values.length; i++) {
validateNumber(values[i]);
numbers[i] = Integer.parseInt(values[i]);
}
return numbers;
}

private static void validateNumber(String value) {
int number = parseNumber(value);
if (number < 0) {
throw new IllegalArgumentException("μŒμˆ˜λŠ” κ³„μ‚°λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.");
}
}

private static int parseNumber(String value) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("숫자 μ΄μ™Έμ˜ 값이 μž…λ ₯λ˜μ—ˆμŠ΅λ‹ˆλ‹€.");
}
}

private static int sumValues(int[] values) {
int result = 0;
for (int value : values) {
result += value;
}
return result;
}
}
45 changes: 45 additions & 0 deletions src/main/java/racingcar/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package racingcar;

public class Car {

private static final int MOVE_CONDITION = 4;
private static final int MAX_NAME_LENGTH = 5;

private final String name;
private int currentPosition;

public Car(final String name) {
this(name, 0);
}

public Car(String name, int position) {
validationCarName(name);
this.name = name.trim();
this.currentPosition = position;
}

private void validationCarName(String name) {
if (name == null || name.trim().isBlank()) {
throw new IllegalArgumentException("μžλ™μ°¨ 이름은 값이 μ‘΄μž¬ν•΄μ•Ό ν•©λ‹ˆλ‹€.");
}
if (name.trim().length() >= MAX_NAME_LENGTH) {
throw new IllegalArgumentException("μžλ™μ°¨ 이름은 5 미만의 κΈ€μžμ—¬μ•Ό ν•©λ‹ˆλ‹€.");
}
}

public int move(int randomNumber) {
if (randomNumber >= MOVE_CONDITION) {
currentPosition++;
}
return currentPosition;
}

public int getCurrentPosition() {
return currentPosition;
}

public String getName() {
return name;
}

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

import java.util.Scanner;

public class InputView {

private static final Scanner SCANNER = new Scanner(System.in);

private InputView() {

}

public static String[] getCarNames() {
System.out.println("κ²½μ£Όν•  μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”. (이름은 μ‰Όν‘œ(,)λ₯Ό κΈ°μ€€μœΌλ‘œ ꡬ뢄");
return SCANNER.nextLine().split(",");
}

public static int getRoundNumber() {
System.out.println("μ‹œλ„ ν•  νšŸμˆ˜λŠ” λͺ‡ 번 μΈκ°€μš”?");
return SCANNER.nextInt();
}
}
28 changes: 28 additions & 0 deletions src/main/java/racingcar/Racing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package racingcar;

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

public class Racing {

private static final Random RANDOM = new Random();

private final List<Car> cars;

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

public List<RacingResult> play() {
List<RacingResult> racingResults = new ArrayList();

for (Car car : cars) {
car.move(RANDOM.nextInt(10));
RacingResult racingResult = new RacingResult(car.getName(), car.getCurrentPosition());
racingResults.add(racingResult);
}
return racingResults;
}

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

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

public class RacingCarMain {

public static void main(String[] args) {
String[] names = InputView.getCarNames();
int roundNum = InputView.getRoundNumber();

List<Car> cars = new ArrayList<>();
for (int i = 0; i < names.length; i++) {
cars.add(new Car(names[i]));
}

Racing racing = new Racing(cars);

for (int i = 0; i < roundNum; i++) {
ResultView.roundStart(i + 1);
List<RacingResult> carPositions = racing.play();
ResultView.drawCarPositions(carPositions);
}
List<Car> winners = Winners.findWinners(cars);
ResultView.printWinners(winners);
}

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

public class RacingResult {

private final String name;
private final int position;

public RacingResult(String name, int position) {
this.name = name;
this.position = position;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}
}
39 changes: 39 additions & 0 deletions src/main/java/racingcar/ResultView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package racingcar;

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

public class ResultView {

private static final String LINE = "-".repeat(5);

private ResultView() {

}

public static void roundStart(int roundNumber) {
System.out.println(LINE + roundNumber + " λΌμš΄λ“œ μ‹œμž‘!" + LINE);
}

public static void drawCarPositions(List<RacingResult> results) {
for (RacingResult result : results) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder
.append(result.getName())
.append(" : ")
.append("-".repeat(result.getPosition()));
System.out.println(stringBuilder.toString());
}
}

public static void printWinners(List<Car> winners) {
String winnersName = winners.stream().map(Car::getName)
.collect(Collectors.joining(","));

StringBuilder stringBuilder = new StringBuilder();
stringBuilder
.append(winnersName)
.append("이(κ°€) μ΅œμ’… 우승 ν–ˆμŠ΅λ‹ˆλ‹€.");
System.out.println(stringBuilder.toString());
}
}
32 changes: 32 additions & 0 deletions src/main/java/racingcar/Winners.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package racingcar;

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

public class Winners {
public static List<Car> findWinners(List<Car> cars) {
return findWinners(cars, getMaxPosition(cars));
}

private static List<Car> findWinners(List<Car> cars, int maxPosition) {
List<Car> winners = new ArrayList<>();
for (Car car : cars) {
addIfMaxPosition(maxPosition, car, winners);
}
return winners;
}

private static void addIfMaxPosition(int maxPosition, Car car, List<Car> winners) {
if (maxPosition == car.getCurrentPosition()) {
winners.add(car);
}
}

private static int getMaxPosition(List<Car> cars) {
int maxPosition = 0;
for (Car car : cars) {
maxPosition = Math.max(car.getCurrentPosition(), maxPosition);
}
return maxPosition;
}
}
64 changes: 64 additions & 0 deletions src/test/java/calculator/StringAddCalculatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package calculator;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.NullAndEmptySource;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class StringAddCalculatorTest {

@Test
@DisplayName("숫자 ν•˜λ‚˜λ₯Ό λ¬Έμžμ—΄λ‘œ μž…λ ₯ν•  μ‹œ ν•΄λ‹Ή 숫자λ₯Ό λ°˜ν™˜ν•˜λŠ”μ§€ 확인")
void oneStringNumTest() {
int result = StringAddCalculator.calculateSum("1");
assertThat(result).isEqualTo(1);
}

@Test
@DisplayName("콀마λ₯Ό κ΅¬λΆ„μžλ‘œ λ‚˜λ‰˜μ–΄ 각 숫자의 합을 λ°˜ν™˜ν•˜λŠ”μ§€ 확인")
void sumWithCommaDelimiter() {
int result = StringAddCalculator.calculateSum("1,2");
assertThat(result).isEqualTo(3);
}

@Test
@DisplayName("μ½œλ‘ μ„ κ΅¬λΆ„μžλ‘œ λ‚˜λ‰˜μ–΄ 각 숫자의 합을 λ°˜ν™˜ν•˜λŠ”μ§€ 확인")
void sumWithColonDelimiter() {
int result = StringAddCalculator.calculateSum("1:2");
assertThat(result).isEqualTo(3);
}

@ParameterizedTest
@DisplayName("빈 λ¬Έμžμ—΄ λ˜λŠ” null 값을 μž…λ ₯ν•  경우 0을 λ°˜ν™˜ν•˜λŠ”μ§€ 확인")
@NullAndEmptySource
void returnZeroForEmpty(String input) {
int result = StringAddCalculator.calculateSum(input);
assertThat(result).isEqualTo(0);
}

@Test
@DisplayName("//”와 β€œ\\n” 문자 사이에 μ»€μŠ€ν…€ κ΅¬λΆ„μž μ§€μ •ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλŠ”μ§€ 확인")
void sumWithCustomDelimiter() {
int result = StringAddCalculator.calculateSum("//;\n1;2;3");
assertThat(result).isEqualTo(6);
}

@Test
@DisplayName("음수λ₯Ό 전달할 경우 RuntimeException μ˜ˆμ™Έ throwν•˜λŠ”μ§€ 확인")
void returnErrorForNegativeNum() {
assertThatThrownBy(() -> {
StringAddCalculator.calculateSum("-3");
}).isInstanceOf(IllegalArgumentException.class);
}

@Test
@DisplayName("숫자 μ΄μ™Έμ˜ 값을 전달할 경우 RuntimeException μ˜ˆμ™Έ throwν•˜λŠ”μ§€ 확인")
void returnErrorForInvalidText() {
assertThatThrownBy(() -> {
StringAddCalculator.calculateSum("&");
}).isInstanceOf(IllegalArgumentException.class);
}
}
Loading