From cb4f68c394b8315ab9c4fb8919c5d83869c77fb5 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 16:16:53 +0900 Subject: [PATCH 01/76] =?UTF-8?q?=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 81 --------------- src/main/java/Main.java | 99 ------------------- src/main/java/domain/BridgeGenerator.java | 7 -- .../java/domain/BridgeRandomGenerator.java | 37 ------- src/main/java/domain/ExceptionType.java | 30 ------ src/main/java/domain/Height.java | 23 ----- src/main/java/domain/Ladder.java | 31 ------ src/main/java/domain/LadderGame.java | 55 ----------- src/main/java/domain/LadderGameException.java | 8 -- src/main/java/domain/LadderGameOperator.java | 7 -- src/main/java/domain/Name.java | 32 ------ src/main/java/domain/Names.java | 39 -------- src/main/java/domain/Position.java | 88 ----------------- src/main/java/domain/Result.java | 4 - src/main/java/domain/Results.java | 24 ----- src/main/java/domain/Row.java | 29 ------ src/main/java/domain/Width.java | 23 ----- src/main/java/view/ClimbResultPrinter.java | 17 ---- src/main/java/view/InputView.java | 16 --- .../view/LadderGameOperatorInputView.java | 22 ----- src/main/java/view/LadderPrinter.java | 12 --- src/main/java/view/NameInputView.java | 69 ------------- src/main/java/view/NamePrinter.java | 13 --- src/main/java/view/NamesPrinter.java | 12 --- src/main/java/view/OutputView.java | 7 -- src/main/java/view/ResultInputView.java | 51 ---------- src/main/java/view/RowPrinter.java | 19 ---- src/test/java/domain/HeightTest.java | 18 ---- .../java/domain/LadderGameOperatorTest.java | 19 ---- src/test/java/domain/LadderGameTest.java | 73 -------------- src/test/java/domain/LadderTest.java | 46 --------- src/test/java/domain/NamesTest.java | 16 --- src/test/java/domain/PositionTest.java | 49 --------- src/test/java/domain/RowTest.java | 16 --- src/test/java/domain/WidthTest.java | 18 ---- .../java/view/ClimbResultPrinterTest.java | 18 ---- .../view/LadderGameOperatorInputViewTest.java | 33 ------- src/test/java/view/LadderPrinterTest.java | 29 ------ src/test/java/view/NameInputViewTest.java | 56 ----------- src/test/java/view/NamesPrinterTest.java | 17 ---- src/test/java/view/ResultInputViewTest.java | 68 ------------- 41 files changed, 1331 deletions(-) delete mode 100644 src/main/java/Main.java delete mode 100644 src/main/java/domain/BridgeGenerator.java delete mode 100644 src/main/java/domain/BridgeRandomGenerator.java delete mode 100644 src/main/java/domain/ExceptionType.java delete mode 100644 src/main/java/domain/Height.java delete mode 100644 src/main/java/domain/Ladder.java delete mode 100644 src/main/java/domain/LadderGame.java delete mode 100644 src/main/java/domain/LadderGameException.java delete mode 100644 src/main/java/domain/LadderGameOperator.java delete mode 100644 src/main/java/domain/Name.java delete mode 100644 src/main/java/domain/Names.java delete mode 100644 src/main/java/domain/Position.java delete mode 100644 src/main/java/domain/Result.java delete mode 100644 src/main/java/domain/Results.java delete mode 100644 src/main/java/domain/Row.java delete mode 100644 src/main/java/domain/Width.java delete mode 100644 src/main/java/view/ClimbResultPrinter.java delete mode 100644 src/main/java/view/InputView.java delete mode 100644 src/main/java/view/LadderGameOperatorInputView.java delete mode 100644 src/main/java/view/LadderPrinter.java delete mode 100644 src/main/java/view/NameInputView.java delete mode 100644 src/main/java/view/NamePrinter.java delete mode 100644 src/main/java/view/NamesPrinter.java delete mode 100644 src/main/java/view/OutputView.java delete mode 100644 src/main/java/view/ResultInputView.java delete mode 100644 src/main/java/view/RowPrinter.java delete mode 100644 src/test/java/domain/HeightTest.java delete mode 100644 src/test/java/domain/LadderGameOperatorTest.java delete mode 100644 src/test/java/domain/LadderGameTest.java delete mode 100644 src/test/java/domain/LadderTest.java delete mode 100644 src/test/java/domain/NamesTest.java delete mode 100644 src/test/java/domain/PositionTest.java delete mode 100644 src/test/java/domain/RowTest.java delete mode 100644 src/test/java/domain/WidthTest.java delete mode 100644 src/test/java/view/ClimbResultPrinterTest.java delete mode 100644 src/test/java/view/LadderGameOperatorInputViewTest.java delete mode 100644 src/test/java/view/LadderPrinterTest.java delete mode 100644 src/test/java/view/NameInputViewTest.java delete mode 100644 src/test/java/view/NamesPrinterTest.java delete mode 100644 src/test/java/view/ResultInputViewTest.java diff --git a/README.md b/README.md index d045937e4b..7c0ab84281 100644 --- a/README.md +++ b/README.md @@ -5,84 +5,3 @@ ## 우아한테크코스 코드리뷰 - [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) - -## 기능 요구사항 해석 - -1. 사다리 게임에 참여하는 사람에 이름을 최대5글자까지 부여할 수 있다. 사다리를 출력할 때 사람 이름도 같이 출력한다. - - 사람의 이름은 중복이 되어선 안된다. - - 이름은 최소 1글자 최대 5글자 까지 부여되어야 한다. - - 알파뱃 대 소문자로 이루어 진다. - - 사람 이름은 "all"일 수 없다. - -2. 사람 이름은 쉼표(,)를 기준으로 구분한다. - - 쉼표로 시작하거나 쉼표로 끝내면 예외 발생 - - 쉼표로 나뉘는데, 알파벳 대소문자가 아닌 경우 예외 발생 - - 사람은 최대 10명까지 받을 수 있다. - -3. 사다리 높이를 입력할 수 있다. - - 사다리 높이는 5 이상 10 이하의 정수로 입력해야 한다. - - 사다리의 폭은 사람들의 수이다. - -4. 실행 결과를 입력할 수 있다. 실행 결과란, 사다리 게임에서 사다리 아래의 항목을 말한다. - - 실행 결과는 쉼표(,)를 기준으로 구분한다. - - 각 실행 결과는 최소 1글자 최대 5글자 까지 부여되어야 한다. - - 각 실행 결과는 공백 문자만으로 이루어질 수 없다. - -5. 사람 이름을 5자 기준으로 출력하기 때문에 사다리 폭도 넓어져야 한다. - - 사다리의 가로(`-`)는 `최대 이름 길이`로 고정한다. - - 사람의 이름은 사다리의 세로(`|`) 에 맞춰 정렬한다. - - 사람의 이름이 `최대 이름 길이`보다 작을경우 다음과 같은 규칙으로 공백을 추가한다. - - ``` - `a` -> ` a ` - `aa` -> ` aa ` - `aaa` -> ` aaa ` - `aaaa` -> `aaaa ` - `aaaaa` -> `aaaaa` - ``` - -6. 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다. - - |-----|-----| 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다. -7. 사용자 입력 중 예외가 발생할 경우, 예외 발생 원인을 출력한 뒤, 처음부터 다시 입력받는다. -8. 사다리 게임 실행 결과를 알 수 있다. - - all 을 입력한 경우 전체 결과를 알 수 있다. - - 앞서 입력한 사람 이름 중 하나를 입력하면 그 사람의 결과를 알 수 있다. - - 잘못된 입력을 할 경우, 예외 메세지를 출력한 뒤 결과를 보고 싶은 사람 이름부터 다시 입력받는다. - -## 기능 목록 - -- [x] 사람 이름 입력 기능 - - [x] 사람 이름 길이 검증 기능 - - [x] 사람 이름 문자 검증 가능 -- [x] 사람 생성 기능 - - [x] 사람 이름 중복 검증 기능 - - [x] ","로 구분된 사람 이름 입력 기능 - - [x] 사람 이름 개수 검증 기능 -- [x] 사다리 높이 입력 기능 - - [x] 사다리 높이 검증 기능 -- [x] 사다리 생성 기능 - - [x] 사다리 높이 지정 기능 - - [x] 사다리 전체 폭 지정 기능 - - [x] 세로 라인 생성 기능 - - [x] 가로 라인 생성 기능 -- [x] 사람 이름, 사다리 출력 기능 - - [x] 사람 이름 출력 기능 - - [x] 사다리 출력 기능 -- [x] 입력 예외 처리 기능 -- [x] 실행 결과 입력 기능 -- [x] 실행 결과 판독 기능 -- [x] 실행 결과를 보고 싶은 이름 입력 기능 -- [x] 실행 결과 출력 기능 - -## 1단계 피드백 반영 사항 - -- [x] Pattern 객체 재사용하도록 수정 -- [x] 도메인 로직에서 UI 로직 분리 - - [x] ~ String 클래스 이름 변경 - - [x] ~ String 클래스 view 패키지로 이동 - - [x] 이름 관련 정책 구현 위치 view로 이동 - -## 2단계 피드백 반영 사항 - -- [x] 모호한 변수 및 메서드 명 변경 -- [x] 적절하지 않은 예외 사용 코드 삭제 diff --git a/src/main/java/Main.java b/src/main/java/Main.java deleted file mode 100644 index 24af80ad45..0000000000 --- a/src/main/java/Main.java +++ /dev/null @@ -1,99 +0,0 @@ -import domain.LadderGame; -import java.util.List; -import java.util.function.Supplier; -import view.ClimbResultPrinter; -import view.InputView; -import view.LadderGameOperatorInputView; -import view.LadderPrinter; -import view.NameInputView; -import view.NamesPrinter; -import view.OutputView; -import view.ResultInputView; - -public class Main { - public static void main(String[] args) { - LadderGame ladderGame = generateLadderGame(); - - printName(ladderGame); - printLadder(ladderGame); - printResults(ladderGame); - - List rawNames = ladderGame.getRawNames(); - printClimbResult(ladderGame, rawNames); - } - - private static LadderGame generateLadderGame() { - return RetryHelper.retry(() -> { - OutputView.print("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); - List names = NameInputView.getNames(InputView::getInput); - OutputView.print("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); - List rawResults = ResultInputView.getResults(InputView::getInput, names.size()); - OutputView.print("최대 사다리 높이는 몇 개인가요?"); - int ladderHeight = Integer.parseInt(InputView.getInput()); - return new LadderGame(names, ladderHeight, rawResults); - }); - } - - private static void printName(LadderGame ladderGame) { - OutputView.print(NamesPrinter.from(ladderGame.getRawNames())); - } - - private static void printLadder(LadderGame ladderGame) { - OutputView.print(LadderPrinter.from(ladderGame.getRawLadder())); - } - - private static void printResults(LadderGame ladderGame) { - OutputView.print(NamesPrinter.from(ladderGame.getRawResults())); - } - - private static void printClimbResult(LadderGame ladderGame, List rawNames) { - String gameOperator = getGameOperator(ladderGame); - - gameOperator = printClimbResultsUntilOperatorIsAll(ladderGame, gameOperator); - - List climbResults = ClimbResultPrinter.of(rawNames, ladderGame.getClimbResults(gameOperator)); - climbResults.forEach(OutputView::print); - } - - private static String getGameOperator(LadderGame ladderGame) { - OutputView.print("결과를 보고 싶은 사람은?"); - String gameOperator = RetryHelper.retry( - () -> LadderGameOperatorInputView.getOperator(InputView::getInput, ladderGame.getRawNames()) - ); - OutputView.print("실행 결과"); - return gameOperator; - } - - private static String printClimbResultsUntilOperatorIsAll(LadderGame ladderGame, String gameOperator) { - while (!gameOperator.equals("all")) { - List climbResults = ClimbResultPrinter.of( - List.of(gameOperator), - ladderGame.getClimbResults(gameOperator) - ); - climbResults.forEach(OutputView::print); - - gameOperator = getGameOperator(ladderGame); - } - return gameOperator; - } - - static final class RetryHelper { - - public static E retry(Supplier supplier) { - E result = null; - while (result == null) { - result = useSupplier(supplier); - } - return result; - } - - private static E useSupplier(Supplier supplier) { - try { - return supplier.get(); - } catch (Exception e) { - System.out.println(e.getMessage()); - return null; - } - } - } -} diff --git a/src/main/java/domain/BridgeGenerator.java b/src/main/java/domain/BridgeGenerator.java deleted file mode 100644 index 3ae2e55d04..0000000000 --- a/src/main/java/domain/BridgeGenerator.java +++ /dev/null @@ -1,7 +0,0 @@ -package domain; - -import java.util.List; - -interface BridgeGenerator { - List generate(int width); -} diff --git a/src/main/java/domain/BridgeRandomGenerator.java b/src/main/java/domain/BridgeRandomGenerator.java deleted file mode 100644 index 0779a6ba73..0000000000 --- a/src/main/java/domain/BridgeRandomGenerator.java +++ /dev/null @@ -1,37 +0,0 @@ -package domain; - -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -class BridgeRandomGenerator implements BridgeGenerator { - public List generate(int width) { - Random random = new Random(); - List rawBridges = generateBridges(width, random); - fixInvalidBridges(width, rawBridges); - return rawBridges; - } - - private List generateBridges(int width, Random random) { - return IntStream.range(0, width) - .mapToObj(value -> random.nextBoolean()) - .collect(Collectors.toList()); - } - - private void fixInvalidBridges(int width, List rawBridges) { - for (int index = 1; index < width; index++) { - fixIfNeed(rawBridges, index); - } - } - - private void fixIfNeed(List rawBridges, int index) { - if (isBridgeInARow(rawBridges, index)) { - rawBridges.set(index, false); - } - } - - private boolean isBridgeInARow(List rawBridges, int index) { - return rawBridges.get(index) && rawBridges.get(index - 1); - } -} diff --git a/src/main/java/domain/ExceptionType.java b/src/main/java/domain/ExceptionType.java deleted file mode 100644 index 4b54288a0b..0000000000 --- a/src/main/java/domain/ExceptionType.java +++ /dev/null @@ -1,30 +0,0 @@ -package domain; - -public enum ExceptionType { - HEIGHT_RANGE("높이는 5이상 10 이하여야 합니다."), - WIDTH_RANGE("폭은 2이상 10 이하여야 합니다."), - NAME_CHARACTER("이름은 알파벳 대소문자로만 이루어져있어야 합니다."), - NAME_BLACK_LIST("사용할 수 없는 이름입니다."), - NAME_LENGTH_RANGE("이름의 길이는 1자 이상 5자 이하여야 합니다."), - NAMES_COUNT("사람은 최대 10명까지 받을 수 있습니다."), - NAMES_DUPLICATE("이름은 중복될 수 없습니다."), - NAMES_SEPARATOR("구분자가 맨 앞이나 맨 뒤에 있으면 안됩니다."), - ROW_COUNT("가로 라인 개수는 1이상 9 이하여야 합니다."), - ROW_NEAR("연속해서 가로 라인이 등장할 수 없습니다."), - RESULTS_COUNT_RANGE("실행 결과는 최대 10개까지 받을 수 있습니다."), - RESULT_COUNT("실행 결과의 개수와 이름의 개수가 다릅니다."), - RESULTS_SEPARATOR("구분자가 맨 앞이나 맨 뒤에 있으면 안됩니다."), - RESULT_LENGTH("실행 결과의 길이는 1자 이상 5자 이하여야 합니다."), - NAME_NOT_FOUND("없는 이름입니다."), - POSITION_OVERFLOW("위치는 0 이상 이름 개수 미만이어야 합니다."); - - private final String message; - - ExceptionType(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } -} diff --git a/src/main/java/domain/Height.java b/src/main/java/domain/Height.java deleted file mode 100644 index aa1555802f..0000000000 --- a/src/main/java/domain/Height.java +++ /dev/null @@ -1,23 +0,0 @@ -package domain; - -class Height { - static final int MIN = 5; - static final int MAX = 10; - - private final int length; - - Height(int length) { - validate(length); - this.length = length; - } - - private void validate(int length) { - if (length < MIN || length > MAX) { - throw new LadderGameException(ExceptionType.HEIGHT_RANGE); - } - } - - int getLength() { - return length; - } -} diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java deleted file mode 100644 index 0ab787028f..0000000000 --- a/src/main/java/domain/Ladder.java +++ /dev/null @@ -1,31 +0,0 @@ -package domain; - -import java.util.List; -import java.util.stream.IntStream; - -class Ladder { - private final List rows; - - Ladder(int rawHeight, int rawWidth, BridgeGenerator bridgeGenerator) { - Height height = new Height(rawHeight); - Width width = new Width(rawWidth); - rows = IntStream.range(0, height.getLength()) - .mapToObj(value -> bridgeGenerator.generate(width.getLength() - 1)) - .map(Row::new) - .toList(); - } - - List> getRawLadder() { - return rows.stream() - .map(Row::getBridges) - .toList(); - } - - Position climb(Position startPosition) { - Position endPosition = startPosition; - for (Row row : rows) { - endPosition = row.move(endPosition); - } - return endPosition; - } -} diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java deleted file mode 100644 index 910bbb48b6..0000000000 --- a/src/main/java/domain/LadderGame.java +++ /dev/null @@ -1,55 +0,0 @@ -package domain; - -import java.util.List; - -public class LadderGame { - private final Ladder ladder; - private final Names names; - private final Results results; - - public LadderGame(List userNames, int ladderHeight, List rawResults) { - names = new Names(userNames); - int nameCount = names.getNameCount(); - ladder = new Ladder(ladderHeight, nameCount, new BridgeRandomGenerator()); - this.results = new Results(rawResults); - } - - LadderGame(List userNames, int ladderHeight, List rawResults, BridgeGenerator bridgeGenerator) { - names = new Names(userNames); - int nameCount = names.getNameCount(); - ladder = new Ladder(ladderHeight, nameCount, bridgeGenerator); - this.results = new Results(rawResults); - } - - public List getRawNames() { - return names.getRawNames(); - } - - public List> getRawLadder() { - return ladder.getRawLadder(); - } - - public List getRawResults() { - return results.getRawResults(); - } - - public List getClimbResults(String rawOperator) { - LadderGameOperator operator = new LadderGameOperator(rawOperator); - if (operator.isAll()) { - return climbAll(); - } - return List.of(climb(rawOperator)); - } - - private List climbAll() { - return names.getRawNames().stream() - .map(this::climb) - .toList(); - } - - private String climb(String rawName) { - Position startPosition = names.position(rawName); - Position endPosition = ladder.climb(startPosition); - return results.getRawResult(endPosition.getRawPosition()); - } -} diff --git a/src/main/java/domain/LadderGameException.java b/src/main/java/domain/LadderGameException.java deleted file mode 100644 index e1ba3ce68b..0000000000 --- a/src/main/java/domain/LadderGameException.java +++ /dev/null @@ -1,8 +0,0 @@ -package domain; - -public class LadderGameException extends RuntimeException { - - public LadderGameException(ExceptionType exceptionType) { - super(exceptionType.getMessage()); - } -} diff --git a/src/main/java/domain/LadderGameOperator.java b/src/main/java/domain/LadderGameOperator.java deleted file mode 100644 index 6a45e8cbc2..0000000000 --- a/src/main/java/domain/LadderGameOperator.java +++ /dev/null @@ -1,7 +0,0 @@ -package domain; - -record LadderGameOperator(String rawOperator) { - boolean isAll() { - return rawOperator.equals("all"); - } -} diff --git a/src/main/java/domain/Name.java b/src/main/java/domain/Name.java deleted file mode 100644 index 183d034886..0000000000 --- a/src/main/java/domain/Name.java +++ /dev/null @@ -1,32 +0,0 @@ -package domain; - -import java.util.Objects; - -public class Name { - private final String name; - - Name(String name) { - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Name other = (Name) o; - return Objects.equals(name, other.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - - String getName() { - return name; - } -} diff --git a/src/main/java/domain/Names.java b/src/main/java/domain/Names.java deleted file mode 100644 index 3b7c62d99a..0000000000 --- a/src/main/java/domain/Names.java +++ /dev/null @@ -1,39 +0,0 @@ -package domain; - -import java.util.List; - -public class Names { - private final List names; - - Names(List names) { - validateDuplicateName(names); - this.names = names.stream().map(Name::new).toList(); - } - - private void validateDuplicateName(List splitNames) { - long distinctCount = splitNames.stream().distinct().count(); - if (distinctCount != splitNames.size()) { - throw new LadderGameException(ExceptionType.NAMES_DUPLICATE); - } - } - - List getRawNames() { - return names.stream() - .map(Name::getName) - .toList(); - } - - Position position(String rawName) { - Name needToFind = new Name(rawName); - try { - int rawPosition = names.indexOf(needToFind); - return Position.getCachedPosition(rawPosition, names.size() - 1); - } catch (NullPointerException e) { - throw new LadderGameException(ExceptionType.NAME_NOT_FOUND); - } - } - - int getNameCount() { - return names.size(); - } -} diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java deleted file mode 100644 index ba3b71ab67..0000000000 --- a/src/main/java/domain/Position.java +++ /dev/null @@ -1,88 +0,0 @@ -package domain; - -import static domain.ExceptionType.POSITION_OVERFLOW; - -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; - -class Position { - - private static final Map> cache = new ConcurrentHashMap<>(); - - static Position getCachedPosition(int rawPosition, int maxPosition) { - if (cache.containsKey(maxPosition)) { - Map cacheThatSameMaxPosition = cache.get(maxPosition); - return cacheThatSameMaxPosition.computeIfAbsent(rawPosition, key -> new Position(key, maxPosition)); - } - cache.computeIfAbsent(maxPosition, key -> new ConcurrentHashMap<>()) - .put(rawPosition, new Position(rawPosition, maxPosition)); - return getCachedPosition(rawPosition, maxPosition); - } - - private final int rawPosition; - private final int maxPosition; - - - private Position(int rawPosition, int maxPosition) { - validateRange(rawPosition, maxPosition); - this.rawPosition = rawPosition; - this.maxPosition = maxPosition; - } - - private void validateRange(int rawPosition, int maxPosition) { - if (rawPosition < 0 || rawPosition > maxPosition) { - throw new LadderGameException(POSITION_OVERFLOW); - } - } - - Position move(List bridges) { - Boolean canGoRight = getCanGo(bridges, rawPosition); - Boolean canGoLeft = getCanGo(bridges, rawPosition - 1); - if (canGoRight) { - return moveRight(); - } - if (canGoLeft) { - return moveLeft(); - } - return this; - } - - private Boolean getCanGo(List bridges, int nextRawPosition) { - if (nextRawPosition < 0 || nextRawPosition >= maxPosition) { - return false; - } - return bridges.get(nextRawPosition); - } - - private Position moveRight() { - return Position.getCachedPosition(rawPosition + 1, maxPosition); - } - - private Position moveLeft() { - return Position.getCachedPosition(rawPosition - 1, maxPosition); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || obj.getClass() != this.getClass()) { - return false; - } - var that = (Position) obj; - return this.rawPosition == that.rawPosition && - this.maxPosition == that.maxPosition; - } - - @Override - public int hashCode() { - return Objects.hash(rawPosition, maxPosition); - } - - int getRawPosition() { - return rawPosition; - } -} diff --git a/src/main/java/domain/Result.java b/src/main/java/domain/Result.java deleted file mode 100644 index b1652e31d1..0000000000 --- a/src/main/java/domain/Result.java +++ /dev/null @@ -1,4 +0,0 @@ -package domain; - -record Result(String rawResult) { -} diff --git a/src/main/java/domain/Results.java b/src/main/java/domain/Results.java deleted file mode 100644 index c80ce6763a..0000000000 --- a/src/main/java/domain/Results.java +++ /dev/null @@ -1,24 +0,0 @@ -package domain; - -import java.util.List; - -public class Results { - private final List results; - - public Results(List results) { - this.results = results.stream() - .map(Result::new) - .toList(); - } - - public List getRawResults() { - return results.stream() - .map(Result::rawResult) - .toList(); - } - - public String getRawResult(int position) { - List rawResults = getRawResults(); - return rawResults.get(position); - } -} diff --git a/src/main/java/domain/Row.java b/src/main/java/domain/Row.java deleted file mode 100644 index 9149e21a3d..0000000000 --- a/src/main/java/domain/Row.java +++ /dev/null @@ -1,29 +0,0 @@ -package domain; - -import java.util.Collections; -import java.util.List; -import java.util.stream.IntStream; - -class Row { - private final List bridges; - - Row(List bridges) { - IntStream.range(1, bridges.size()) - .forEach(index -> validateNearInfo(bridges, index)); - this.bridges = Collections.unmodifiableList(bridges); - } - - private void validateNearInfo(List rowInfos, int index) { - if (rowInfos.get(index) && rowInfos.get(index - 1)) { - throw new LadderGameException(ExceptionType.ROW_NEAR); - } - } - - List getBridges() { - return bridges; - } - - Position move(Position startPosition) { - return startPosition.move(bridges); - } -} diff --git a/src/main/java/domain/Width.java b/src/main/java/domain/Width.java deleted file mode 100644 index 8cadbef622..0000000000 --- a/src/main/java/domain/Width.java +++ /dev/null @@ -1,23 +0,0 @@ -package domain; - -class Width { - static final int MIN = 2; - static final int MAX = 10; - - private final int length; - - Width(int length) { - validate(length); - this.length = length; - } - - private void validate(int width) { - if (width < MIN || width > MAX) { - throw new LadderGameException(ExceptionType.WIDTH_RANGE); - } - } - - int getLength() { - return length; - } -} diff --git a/src/main/java/view/ClimbResultPrinter.java b/src/main/java/view/ClimbResultPrinter.java deleted file mode 100644 index b5714fe504..0000000000 --- a/src/main/java/view/ClimbResultPrinter.java +++ /dev/null @@ -1,17 +0,0 @@ -package view; - -import java.util.ArrayList; -import java.util.List; - -public class ClimbResultPrinter { - public static List of(List rawNames, List rawResults) { - List climbResults = new ArrayList<>(); - for (int index = 0; index < rawNames.size(); index++) { - String rawName = rawNames.get(index); - String rawResult = rawResults.get(index); - String result = "%s : %s".formatted(rawName, rawResult); - climbResults.add(result); - } - return climbResults; - } -} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java deleted file mode 100644 index 022d8ad5aa..0000000000 --- a/src/main/java/view/InputView.java +++ /dev/null @@ -1,16 +0,0 @@ -package view; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -public class InputView { - public static String getInput() { - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); - try { - return bufferedReader.readLine(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/view/LadderGameOperatorInputView.java b/src/main/java/view/LadderGameOperatorInputView.java deleted file mode 100644 index 1a0875c0f4..0000000000 --- a/src/main/java/view/LadderGameOperatorInputView.java +++ /dev/null @@ -1,22 +0,0 @@ -package view; - -import domain.ExceptionType; -import domain.LadderGameException; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Supplier; - -public class LadderGameOperatorInputView { - public static String getOperator(Supplier supplier, List names) { - String operator = supplier.get(); - validateOperator(new HashSet<>(names), operator); - return operator; - } - - private static void validateOperator(Set names, String operator) { - if (!names.contains(operator) && !operator.equals("all")) { - throw new LadderGameException(ExceptionType.NAME_NOT_FOUND); - } - } -} diff --git a/src/main/java/view/LadderPrinter.java b/src/main/java/view/LadderPrinter.java deleted file mode 100644 index d697192a3f..0000000000 --- a/src/main/java/view/LadderPrinter.java +++ /dev/null @@ -1,12 +0,0 @@ -package view; - -import java.util.List; -import java.util.stream.Collectors; - -public class LadderPrinter { - public static String from(List> rawLadder) { - return rawLadder.stream() - .map(RowPrinter::from) - .collect(Collectors.joining("\n")); - } -} diff --git a/src/main/java/view/NameInputView.java b/src/main/java/view/NameInputView.java deleted file mode 100644 index 422799722f..0000000000 --- a/src/main/java/view/NameInputView.java +++ /dev/null @@ -1,69 +0,0 @@ -package view; - -import domain.ExceptionType; -import domain.LadderGameException; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.function.Supplier; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class NameInputView { - static final int MAX_NAMES_COUNT = 10; - static final int MAX_NAME_LENGTH = 5; - - private static final String SEPARATOR = ","; - - private static final Pattern NAME_CHARACTER_REGEX = Pattern.compile("^[^a-zA-Z]+$"); - - - public static List getNames(Supplier supplier) { - String names = supplier.get(); - validateSeparator(names); - List splitNames = splitName(names); - validateNameCount(splitNames); - splitNames.forEach(NameInputView::validateNameCharacters); - splitNames.forEach(NameInputView::validateNameBlackList); - splitNames.forEach(NameInputView::validateNameLength); - return splitNames; - } - - private static void validateSeparator(String names) { - boolean startsWith = names.startsWith(SEPARATOR); - boolean endsWith = names.endsWith(SEPARATOR); - if (startsWith || endsWith) { - throw new LadderGameException(ExceptionType.NAMES_SEPARATOR); - } - } - - private static List splitName(String names) { - return Arrays.stream(names.split(SEPARATOR)).toList(); - } - - private static void validateNameCount(List splitNames) { - if (splitNames.size() > MAX_NAMES_COUNT) { - throw new LadderGameException(ExceptionType.NAMES_COUNT); - } - } - - private static void validateNameCharacters(String name) { - Matcher matcher = NAME_CHARACTER_REGEX.matcher(name); - if (matcher.matches()) { - throw new LadderGameException(ExceptionType.NAME_CHARACTER); - } - } - - private static void validateNameLength(String name) { - if (name.isEmpty() || name.length() > MAX_NAME_LENGTH) { - throw new LadderGameException(ExceptionType.NAME_LENGTH_RANGE); - } - } - - private static void validateNameBlackList(String name) { - Set blackList = Set.of("all"); - if (blackList.contains(name)) { - throw new LadderGameException(ExceptionType.NAME_BLACK_LIST); - } - } -} diff --git a/src/main/java/view/NamePrinter.java b/src/main/java/view/NamePrinter.java deleted file mode 100644 index 4f39c20a5b..0000000000 --- a/src/main/java/view/NamePrinter.java +++ /dev/null @@ -1,13 +0,0 @@ -package view; - -class NamePrinter { - static final int MAX_NAME_LENGTH = 5; - - static String from(String name) { - if (name.length() < MAX_NAME_LENGTH) { - name = name + " "; - } - int nameStringLength = name.length(); - return " ".repeat(MAX_NAME_LENGTH - nameStringLength) + name; - } -} diff --git a/src/main/java/view/NamesPrinter.java b/src/main/java/view/NamesPrinter.java deleted file mode 100644 index f06e6fdbab..0000000000 --- a/src/main/java/view/NamesPrinter.java +++ /dev/null @@ -1,12 +0,0 @@ -package view; - -import java.util.List; -import java.util.stream.Collectors; - -public class NamesPrinter { - public static String from(List names) { - return names.stream() - .map(NamePrinter::from) - .collect(Collectors.joining(" ")); - } -} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java deleted file mode 100644 index a4fe96b263..0000000000 --- a/src/main/java/view/OutputView.java +++ /dev/null @@ -1,7 +0,0 @@ -package view; - -public class OutputView { - public static void print(String needToPrint) { - System.out.println(needToPrint); - } -} diff --git a/src/main/java/view/ResultInputView.java b/src/main/java/view/ResultInputView.java deleted file mode 100644 index d403a16939..0000000000 --- a/src/main/java/view/ResultInputView.java +++ /dev/null @@ -1,51 +0,0 @@ -package view; - -import domain.ExceptionType; -import domain.LadderGameException; -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; - -public class ResultInputView { - static final int MAX_RESULTS_COUNT = 10; - static final int MAX_RESULT_LENGTH = 5; - private static final String SEPARATOR = ","; - - public static List getResults(Supplier supplier, int resultCount) { - String results = supplier.get(); - validateSeparator(results); - List splitResults = splitResult(results); - splitResults.forEach(ResultInputView::validateResultLength); - validateResultsCount(splitResults, resultCount); - return splitResults; - } - - private static List splitResult(String results) { - return Arrays.stream(results.split(SEPARATOR)).toList(); - } - - - private static void validateSeparator(String results) { - boolean startsWith = results.startsWith(SEPARATOR); - boolean endsWith = results.endsWith(SEPARATOR); - if (startsWith || endsWith) { - throw new LadderGameException(ExceptionType.RESULTS_SEPARATOR); - } - } - - private static void validateResultsCount(List splitNames, int expectedResultCount) { - if (splitNames.size() > MAX_RESULTS_COUNT) { - throw new LadderGameException(ExceptionType.RESULTS_COUNT_RANGE); - } - if (splitNames.size() != expectedResultCount) { - throw new LadderGameException(ExceptionType.RESULT_COUNT); - } - } - - private static void validateResultLength(String name) { - if (name.isEmpty() || name.length() > MAX_RESULT_LENGTH) { - throw new LadderGameException(ExceptionType.RESULT_LENGTH); - } - - } -} diff --git a/src/main/java/view/RowPrinter.java b/src/main/java/view/RowPrinter.java deleted file mode 100644 index 42317093f1..0000000000 --- a/src/main/java/view/RowPrinter.java +++ /dev/null @@ -1,19 +0,0 @@ -package view; - -import java.util.List; -import java.util.stream.Collectors; - -class RowPrinter { - static String from(List bridges) { - String rawRowString = bridges.stream().map(RowPrinter::makeBridge) - .collect(Collectors.joining("|")); - return " |%s|".formatted(rawRowString); - } - - private static String makeBridge(Boolean aBoolean) { - if (aBoolean) { - return "-----"; - } - return " "; - } -} diff --git a/src/test/java/domain/HeightTest.java b/src/test/java/domain/HeightTest.java deleted file mode 100644 index 05b0905f0e..0000000000 --- a/src/test/java/domain/HeightTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package domain; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class HeightTest { - @ParameterizedTest - @ValueSource(ints = {Height.MIN - 1, Height.MAX + 1}) - @DisplayName("높이 검증") - void validateHeight(int length) { - assertThatThrownBy(() -> new Height(length)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.HEIGHT_RANGE.getMessage()); - } -} diff --git a/src/test/java/domain/LadderGameOperatorTest.java b/src/test/java/domain/LadderGameOperatorTest.java deleted file mode 100644 index f528191746..0000000000 --- a/src/test/java/domain/LadderGameOperatorTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package domain; - - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; - -class LadderGameOperatorTest { - - @ParameterizedTest - @CsvSource(value = {"'a',false", "'all',true"}) - @DisplayName("isAll 메서드 검증") - void isAll(String rawOperator, boolean expected) { - LadderGameOperator all = new LadderGameOperator(rawOperator); - Assertions.assertThat(all.isAll()) - .isEqualTo(expected); - } -} diff --git a/src/test/java/domain/LadderGameTest.java b/src/test/java/domain/LadderGameTest.java deleted file mode 100644 index 2fc9a1ea5a..0000000000 --- a/src/test/java/domain/LadderGameTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package domain; - -import java.util.List; -import java.util.stream.Stream; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class LadderGameTest { - - static Stream climbParameter() { - return Stream.of( - Arguments.of("a", List.of("2")), - Arguments.of("b", List.of("1")), - Arguments.of("c", List.of("3")), - Arguments.of("all", List.of("2", "1", "3")) - ); - } - - @Test - @DisplayName("사다리 타기 게임의 이름이 제대로 저장되는지 검증") - void getRawNames() { - List expectedRawNames = List.of("a", "b"); - List rawResults = List.of("1,2"); - LadderGame ladderGame = new LadderGame(expectedRawNames, 5, rawResults); - List actualRawNames = ladderGame.getRawNames(); - Assertions.assertThat(actualRawNames) - .containsExactlyElementsOf(expectedRawNames); - } - - @Test - @DisplayName("사다리 타기 게임의 사다리가 제대로 생성되는지 검증") - void getRawLadder() { - List expectedRawNames = List.of("a", "b"); - List rawResults = List.of("1,2"); - int ladderHeight = 5; - LadderGame ladderGame = new LadderGame(expectedRawNames, ladderHeight, rawResults); - List> actualRawLadder = ladderGame.getRawLadder(); - Assertions.assertThat(actualRawLadder.size()) - .isEqualTo(ladderHeight); - Assertions.assertThat(actualRawLadder.get(0).size()) - .isEqualTo(expectedRawNames.size() - 1); - } - - @Test - @DisplayName("사다리 타기 게임의 실행 결과가 제대로 저장되는지 검증") - void getRawResults() { - List rawNames = List.of("a", "b"); - List expectedRawResults = List.of("1,2"); - int ladderHeight = 5; - LadderGame ladderGame = new LadderGame(rawNames, ladderHeight, expectedRawResults); - List actualRawResults = ladderGame.getRawResults(); - Assertions.assertThat(actualRawResults) - .containsExactlyElementsOf(expectedRawResults); - } - - @ParameterizedTest - @MethodSource("climbParameter") - @DisplayName("사다리 타기 게임을 실행했을 때, 제대로 사다리가 타지는지 검증") - void climb(String nameThatWantToShoResult, List expectedResult) { - List expectedRawNames = List.of("a", "b", "c"); - List rawResults = List.of("1", "2", "3"); - int ladderHeight = 5; - LadderGame ladderGame = new LadderGame(expectedRawNames, ladderHeight, rawResults, - width -> List.of(true, false)); - List climbResults = ladderGame.getClimbResults(nameThatWantToShoResult); - Assertions.assertThat(climbResults) - .isEqualTo(expectedResult); - } -} diff --git a/src/test/java/domain/LadderTest.java b/src/test/java/domain/LadderTest.java deleted file mode 100644 index baec9b3bd5..0000000000 --- a/src/test/java/domain/LadderTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package domain; - -import java.util.List; -import java.util.stream.Stream; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class LadderTest { - - static Stream climbParameters() { - return Stream.of( - Arguments.of(0, 1), - Arguments.of(1, 0), - Arguments.of(2, 2) - ); - } - - @Test - @DisplayName("사다리 전체 폭 검증") - void validateRowCount() { - Ladder ladder = new Ladder(5, 5, new BridgeRandomGenerator()); - Assertions.assertThat(ladder.getRawLadder().size()) - .isEqualTo(5); - } - - @ParameterizedTest - @MethodSource("climbParameters") - @DisplayName("사다리 타기") - void climb(int startPosition, int endPosition) { - int rawWidth = 3; - Ladder ladder = new Ladder(5, rawWidth, width -> List.of(true, false)); - /* - * |-----| | - * |-----| | - * |-----| | - * |-----| | - * |-----| | */ - Position actual = ladder.climb(Position.getCachedPosition(startPosition, rawWidth - 1)); - Assertions.assertThat(actual) - .isEqualTo(Position.getCachedPosition(endPosition, rawWidth - 1)); - } -} diff --git a/src/test/java/domain/NamesTest.java b/src/test/java/domain/NamesTest.java deleted file mode 100644 index 55acb0cf4c..0000000000 --- a/src/test/java/domain/NamesTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package domain; - -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class NamesTest { - @Test - @DisplayName("사람 이름 중복 검사") - void validateDuplicateName() { - Assertions.assertThatThrownBy(() -> new Names(List.of("abcde", "abcde", "abc"))) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.NAMES_DUPLICATE.getMessage()); - } -} diff --git a/src/test/java/domain/PositionTest.java b/src/test/java/domain/PositionTest.java deleted file mode 100644 index f8c5cc33f1..0000000000 --- a/src/test/java/domain/PositionTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package domain; - -import static domain.ExceptionType.POSITION_OVERFLOW; - -import java.util.List; -import java.util.stream.Stream; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class PositionTest { - - static Stream nextParameter() { - return Stream.of( - Arguments.of(0, 1), - Arguments.of(1, 0) - ); - } - - @Test - @DisplayName("최대 위치 값 이하만 생성되는지 검증") - void validateMax() { - Assertions.assertThatThrownBy(() -> Position.getCachedPosition(3, 2)) - .isInstanceOf(LadderGameException.class) - .hasMessage(POSITION_OVERFLOW.getMessage()); - } - - @Test - @DisplayName("최소 위치 값 이상만 생성되는지 검증") - void validateMin() { - Assertions.assertThatThrownBy(() -> Position.getCachedPosition(-1, 2)) - .isInstanceOf(LadderGameException.class) - .hasMessage(POSITION_OVERFLOW.getMessage()); - } - - @ParameterizedTest - @MethodSource("nextParameter") - @DisplayName("다음 위치 검증") - void next(int rawPosition, int rawExpectedNextPosition) { - Position position = Position.getCachedPosition(rawPosition, 1); - Position actual = position.move(List.of(true)); - Position expected = Position.getCachedPosition(rawExpectedNextPosition, 1); - Assertions.assertThat(actual) - .isEqualTo(expected); - } -} diff --git a/src/test/java/domain/RowTest.java b/src/test/java/domain/RowTest.java deleted file mode 100644 index b521987499..0000000000 --- a/src/test/java/domain/RowTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package domain; - -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class RowTest { - @Test - @DisplayName("연속해서 가로 라인이 등장하는지 확인") - void validateNearInfo() { - Assertions.assertThatThrownBy(() -> new Row(List.of(true, true))) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.ROW_NEAR.getMessage()); - } -} diff --git a/src/test/java/domain/WidthTest.java b/src/test/java/domain/WidthTest.java deleted file mode 100644 index eb7a1957bd..0000000000 --- a/src/test/java/domain/WidthTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package domain; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class WidthTest { - @ParameterizedTest - @ValueSource(ints = {Width.MIN - 1, Width.MAX + 1}) - @DisplayName("폭 검증") - void validateWidth(int length) { - assertThatThrownBy(() -> new Width(length)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.WIDTH_RANGE.getMessage()); - } -} diff --git a/src/test/java/view/ClimbResultPrinterTest.java b/src/test/java/view/ClimbResultPrinterTest.java deleted file mode 100644 index 261db20e70..0000000000 --- a/src/test/java/view/ClimbResultPrinterTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package view; - -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class ClimbResultPrinterTest { - - @Test - @DisplayName("사다리 타기 출력 문자열 생성") - void of() { - List actualResults = ClimbResultPrinter.of(List.of("nameA", "nameB"), List.of("A", "B")); - List expectedResults = List.of("nameA : A", "nameB : B"); - Assertions.assertThat(actualResults) - .containsExactlyElementsOf(expectedResults); - } -} diff --git a/src/test/java/view/LadderGameOperatorInputViewTest.java b/src/test/java/view/LadderGameOperatorInputViewTest.java deleted file mode 100644 index 8476af150e..0000000000 --- a/src/test/java/view/LadderGameOperatorInputViewTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package view; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import domain.ExceptionType; -import domain.LadderGameException; -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class LadderGameOperatorInputViewTest { - @Test - @DisplayName("결과를 확인하고 싶은 이름이 입력되지 않은 이름인 경우 검증") - void validateNameNotFound() { - assertThatThrownBy( - () -> LadderGameOperatorInputView.getOperator(() -> "abc", List.of("abcd,ab"))) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.NAME_NOT_FOUND.getMessage()); - } - - @ParameterizedTest - @ValueSource(strings = {"a", "b", "c", "all"}) - @DisplayName("결과를 확인하고 싶은 이름이 입력되지 않은 이름인 경우 검증") - void getNameThatNeedToShowResult(String name) { - String nameThatNeedToShowResult = LadderGameOperatorInputView.getOperator(() -> name, - List.of("a", "b", "c")); - Assertions.assertThat(nameThatNeedToShowResult) - .isEqualTo(name); - } -} diff --git a/src/test/java/view/LadderPrinterTest.java b/src/test/java/view/LadderPrinterTest.java deleted file mode 100644 index e0e0f1edd0..0000000000 --- a/src/test/java/view/LadderPrinterTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package view; - -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class LadderPrinterTest { - @Test - @DisplayName("사다리 문자열 생성") - void ladderToString() { - List> rawLadder = makeRawLadder(); - String actual = LadderPrinter.from(rawLadder); - String expected = " | |-----|\n".repeat(5); - expected = expected.substring(0, expected.length() - 1); - Assertions.assertThat(actual) - .isEqualTo(expected); - } - - private static List> makeRawLadder() { - return List.of( - List.of(false, true), - List.of(false, true), - List.of(false, true), - List.of(false, true), - List.of(false, true) - ); - } -} diff --git a/src/test/java/view/NameInputViewTest.java b/src/test/java/view/NameInputViewTest.java deleted file mode 100644 index a12e07ca8b..0000000000 --- a/src/test/java/view/NameInputViewTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package view; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import domain.ExceptionType; -import domain.LadderGameException; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class NameInputViewTest { - @ParameterizedTest - @ValueSource(strings = {",abc,ab", "abc,ab,", ",abc,ab,"}) - @DisplayName("구분자가 맨 앞이나 맨 뒤에 있는지 확인") - void validateSeparator(String names) { - Assertions.assertThatThrownBy(() -> NameInputView.getNames(() -> names)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.NAMES_SEPARATOR.getMessage()); - } - - @Test - @DisplayName("사람이름 개수 검사") - void validateNameCount() { - Assertions.assertThatThrownBy(() -> NameInputView.getNames(() -> "a,b,c,d,e,f,g,h,i,j,k")) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.NAMES_COUNT.getMessage()); - } - - @ParameterizedTest - @ValueSource(strings = {"", "abcdef,a"}) - @DisplayName("사람 이름 길이 검증") - void validateNameLength(String name) { - assertThatThrownBy(() -> NameInputView.getNames(() -> name)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.NAME_LENGTH_RANGE.getMessage()); - } - - @ParameterizedTest - @ValueSource(strings = {"12345,a", "!@#$%,a", "가나다라마,a"}) - @DisplayName("사람 이름 구성 문자 검증") - void validateNameCharacters(String name) { - assertThatThrownBy(() -> NameInputView.getNames(() -> name)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.NAME_CHARACTER.getMessage()); - } - - @Test - @DisplayName("사람 이름 구성 문자 검증") - void validateBlackList() { - assertThatThrownBy(() -> NameInputView.getNames(() -> "all,abc")) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.NAME_BLACK_LIST.getMessage()); - } -} diff --git a/src/test/java/view/NamesPrinterTest.java b/src/test/java/view/NamesPrinterTest.java deleted file mode 100644 index 94b9173240..0000000000 --- a/src/test/java/view/NamesPrinterTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package view; - -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class NamesPrinterTest { - @Test - @DisplayName("이름 문자열 생성") - void namesToString() { - List rawNames = List.of("a", "aa", "aaa", "aaaa", "aaaaa"); - String actual = NamesPrinter.from(rawNames); - String expected = " a aa aaa aaaa aaaaa"; - Assertions.assertThat(actual).isEqualTo(expected); - } -} diff --git a/src/test/java/view/ResultInputViewTest.java b/src/test/java/view/ResultInputViewTest.java deleted file mode 100644 index 97df8e675f..0000000000 --- a/src/test/java/view/ResultInputViewTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package view; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import domain.ExceptionType; -import domain.LadderGameException; -import java.util.List; -import java.util.stream.Stream; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; - -class ResultInputViewTest { - - static Stream validateResultLengthParameter() { - return Stream.of( - Arguments.of("", 0), - Arguments.of("abcdef,a", 2) - ); - } - - @ParameterizedTest - @ValueSource(strings = {",abc,ab", "abc,ab,", ",abc,ab,"}) - @DisplayName("구분자가 맨 앞이나 맨 뒤에 있는지 확인") - void validateSeparator(String results) { - Assertions.assertThatThrownBy(() -> ResultInputView.getResults(() -> results, 3)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.RESULTS_SEPARATOR.getMessage()); - } - - @Test - @DisplayName("실행 결과 최대 개수 검사") - void validateResultsCount() { - Assertions.assertThatThrownBy(() -> ResultInputView.getResults(() -> "a,b,c,d,e,f,g,h,i,j,k", 11)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.RESULTS_COUNT_RANGE.getMessage()); - } - - @Test - @DisplayName("실행 결과 개수가 이름의 개수와 같은지 검사") - void validateResultsCountSameAsNamesCount() { - Assertions.assertThatThrownBy(() -> ResultInputView.getResults(() -> "a,b,c", 4)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.RESULT_COUNT.getMessage()); - } - - @ParameterizedTest - @MethodSource("validateResultLengthParameter") - @DisplayName("실행 결과 길이 검증") - void validateResultLength(String result, int resultCount) { - assertThatThrownBy(() -> ResultInputView.getResults(() -> result, 2)) - .isInstanceOf(LadderGameException.class) - .hasMessage(ExceptionType.RESULT_LENGTH.getMessage()); - } - - @Test - @DisplayName("정상 동작 테스트") - void getResults() { - List results = ResultInputView.getResults(() -> "당첨,꽝,꽝", 3); - List expected = List.of("당첨", "꽝", "꽝"); - Assertions.assertThat(results) - .containsExactlyElementsOf(expected); - } -} From 88a9e5cf06308decdd36fe3447a1104943b11575 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 14:39:23 +0900 Subject: [PATCH 02/76] =?UTF-8?q?docs:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=ED=95=B4=EC=84=9D=20=EB=B0=8F=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EB=AA=A9=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7c0ab84281..9af72b4265 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,46 @@ -# java-ladder +# 요구사항 해석 -사다리 타기 미션 저장소 +> 다시 구현하는 것인 만큼, 조금 난이도를 높이기 위해 생성되는 사다리에 제약 사항을 추가했습니다. -## 우아한테크코스 코드리뷰 +- 참가자 관련 요구 사항 + 1. 참가자는 최대 10명까지 입력 가능하다 + 2. 참가자 이름의 구분은 ","를 기준으로 수행된다. +- 참가자 이름 관련 요구 사항 + 1. 참가자 이름은 최소 한글자 최대 5글자까지 부여할 수 있다. + 2. 참가자 이름은 중복될 수 없다. + 3. 참가자 이름에는 알파벳 대소문자, 숫자 만 입력할 수 있다. + 4. 참가자 이름은 all이 될 수 없다. +- 사다리 관련 요구 사항 + 1. 어느 한 위치에서 왼쪽과 오른쪽에 동시에 발판이 있을 수 없다. + - 즉, 다음과 같은 사다리는 생성되면 안된다. + ``` + |-----| | + |-----|-----| + ``` + 2. 사다리의 높이는 최소 2, 최대 20이다. + 3. 두 참여자 사이에는 최소한 한개 이상의 발판이 있어야 한다. + - 즉, 다음과 같은 사다리는 생성되면 안된다. + ``` + |-----| | + |-----| | + |-----| | + ``` +- 안정적인 프로그램 실행을 위한 요구사항 + 1. 잘못된 입력이 발생한 경우, 적절한 에러 메세지를 출력한 뒤 해당 위치부터 다시 입력을 수행한다. + 2. 재입력은 무한히 시도될 수 있어야 한다. +- 출력 요구 사항 + 1. 사다리의 가로(-)는 최대 이름 길이로 고정한다. + 2. 사람의 이름은 사다리의 세로(|) 에 맞춰 정렬한다. + 3. 사람의 이름이 최대 이름 길이보다 작을경우 다음과 같은 규칙으로 공백을 추가한다. + 1. 이름 맨 뒤에 공백 문자를 추가한다. + 2. 앞에서 추가된 공백 문자를 포함한 이름의 길이가 최대 이름 길이 보다 작을 경우, 공백을 포함한 이름의 길이가 최대 이름 길이가 되도록 공백 문자를 이름 앞에 추가한다. -- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) +# 기능 목록 + +- [ ] 참가자 이름 입력 기능 +- [ ] 참가자 생성 기능 +- [ ] 사다리 높이 입력 기능 +- [ ] 사다리 생성 기능 +- [ ] 사다리 출력 기능 +- [ ] 사다리 타기 실행 기능 +- [ ] 사다리 타기 결과 출력 기능 From 032a69fa83c9466913dc8254f50dd1610b21b63f Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 15:10:17 +0900 Subject: [PATCH 03/76] =?UTF-8?q?test:=20=EA=B0=81=20=EC=A7=80=EC=A0=90?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20=EC=A0=81?= =?UTF-8?q?=EC=A0=88=ED=95=9C=20=EC=A7=80=EC=A0=90=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=95=98=EB=8A=94=EC=A7=80=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Direction.java | 5 +++++ src/main/java/domain/Point.java | 13 +++++++++++++ src/test/java/domain/PointTest.java | 26 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 src/main/java/domain/Direction.java create mode 100644 src/main/java/domain/Point.java create mode 100644 src/test/java/domain/PointTest.java diff --git a/src/main/java/domain/Direction.java b/src/main/java/domain/Direction.java new file mode 100644 index 0000000000..3f1583434e --- /dev/null +++ b/src/main/java/domain/Direction.java @@ -0,0 +1,5 @@ +package domain; + +public enum Direction { + RIGHT, LEFT, STRAIGHT +} diff --git a/src/main/java/domain/Point.java b/src/main/java/domain/Point.java new file mode 100644 index 0000000000..977d447a4b --- /dev/null +++ b/src/main/java/domain/Point.java @@ -0,0 +1,13 @@ +package domain; + +public class Point { + private final Direction direction; + + public Point(Direction direction) { + this.direction = direction; + } + + public Point next() { + return null; + } +} diff --git a/src/test/java/domain/PointTest.java b/src/test/java/domain/PointTest.java new file mode 100644 index 0000000000..87f5ec7017 --- /dev/null +++ b/src/test/java/domain/PointTest.java @@ -0,0 +1,26 @@ +package domain; + +import static domain.Direction.LEFT; +import static domain.Direction.RIGHT; +import static domain.Direction.STRAIGHT; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PointTest { + @Test + @DisplayName("각 지점에서 이동 시 적절한 지점으로 이동하는지 확인") + void next() { + // |-----| |-----| | + //Todo 생성시에 올바를 Point 들인지 확인할 수 있어야 함 + List points = List.of(new Point(RIGHT), new Point(LEFT), new Point(RIGHT), new Point(LEFT), + new Point(STRAIGHT)); + Assertions.assertThat(points.get(0).next()).isEqualTo(points.get(1)); + Assertions.assertThat(points.get(1).next()).isEqualTo(points.get(0)); + Assertions.assertThat(points.get(2).next()).isEqualTo(points.get(3)); + Assertions.assertThat(points.get(3).next()).isEqualTo(points.get(2)); + Assertions.assertThat(points.get(4).next()).isEqualTo(points.get(4)); + } +} From 3dadff9e87eba09ac83af874e8049628aec85236 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 15:16:57 +0900 Subject: [PATCH 04/76] =?UTF-8?q?feat:=20=EA=B0=81=20=EC=A7=80=EC=A0=90?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20=EC=A0=81?= =?UTF-8?q?=EC=A0=88=ED=95=9C=20=EC=A7=80=EC=A0=90=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Point.java | 46 ++++++++++++++++++++++++++++- src/test/java/domain/PointTest.java | 4 +-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/Point.java b/src/main/java/domain/Point.java index 977d447a4b..640fb31d24 100644 --- a/src/main/java/domain/Point.java +++ b/src/main/java/domain/Point.java @@ -2,12 +2,56 @@ public class Point { private final Direction direction; + private final int index; public Point(Direction direction) { + this(direction, 0); + } + + public Point(Direction direction, int index) { this.direction = direction; + this.index = index; } public Point next() { - return null; + if (direction == Direction.LEFT) { + return new Point(Direction.RIGHT, index - 1); + } + if (direction == Direction.RIGHT) { + return new Point(Direction.LEFT, index + 1); + } + return new Point(Direction.STRAIGHT, index); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Point point = (Point) o; + + if (index != point.index) { + return false; + } + return direction == point.direction; + } + + @Override + public int hashCode() { + int result = direction != null ? direction.hashCode() : 0; + result = 31 * result + index; + return result; + } + + @Override + public String toString() { + return "Point{" + + "direction=" + direction + + ", index=" + index + + '}'; } } diff --git a/src/test/java/domain/PointTest.java b/src/test/java/domain/PointTest.java index 87f5ec7017..853cbd6f5e 100644 --- a/src/test/java/domain/PointTest.java +++ b/src/test/java/domain/PointTest.java @@ -15,8 +15,8 @@ class PointTest { void next() { // |-----| |-----| | //Todo 생성시에 올바를 Point 들인지 확인할 수 있어야 함 - List points = List.of(new Point(RIGHT), new Point(LEFT), new Point(RIGHT), new Point(LEFT), - new Point(STRAIGHT)); + List points = List.of(new Point(RIGHT), new Point(LEFT, 1), new Point(RIGHT, 2), new Point(LEFT, 3), + new Point(STRAIGHT, 4)); Assertions.assertThat(points.get(0).next()).isEqualTo(points.get(1)); Assertions.assertThat(points.get(1).next()).isEqualTo(points.get(0)); Assertions.assertThat(points.get(2).next()).isEqualTo(points.get(3)); From 8b8e086e9701ba4f9b2ec23218db5770257a4f9f Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 15:45:47 +0900 Subject: [PATCH 05/76] =?UTF-8?q?test:=20=EC=97=B0=EC=86=8D=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9C=ED=8C=90=EC=9D=B4=20=EB=82=98=ED=83=80?= =?UTF-8?q?=EB=82=98=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Line.java | 12 ++++++++++++ src/test/java/domain/LineTest.java | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/main/java/domain/Line.java create mode 100644 src/test/java/domain/LineTest.java diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java new file mode 100644 index 0000000000..5a1f239840 --- /dev/null +++ b/src/main/java/domain/Line.java @@ -0,0 +1,12 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Line { + private final List points; + + public Line(Boolean... canGoRights) { + this.points = new ArrayList<>(); + } +} diff --git a/src/test/java/domain/LineTest.java b/src/test/java/domain/LineTest.java new file mode 100644 index 0000000000..556ee9d7cd --- /dev/null +++ b/src/test/java/domain/LineTest.java @@ -0,0 +1,25 @@ +package domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class LineTest { + @Test + @DisplayName("올바른 Point로 Line이 잘 생성되는지 확인") + void normal() { + Assertions.assertThatNoException() + .isThrownBy( + () -> new Line(true, false, false, true, false)); + } + + @Test + @DisplayName("|-----|-----| 인 Point로 Line이 생성되지 않는지 확인") + void leftContinueOrRightContinue() { + Assertions.assertThatThrownBy( + () -> new Line(true, true, false)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("|-----|-----| 연결 감지!"); + } + +} From 79544fab7d0086326820b0a162d0dcadd736da1c Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 15:46:17 +0900 Subject: [PATCH 06/76] =?UTF-8?q?feat:=20=EC=97=B0=EC=86=8D=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9C=ED=8C=90=EC=9D=B4=20=EB=82=98=ED=83=80?= =?UTF-8?q?=EB=82=98=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Line.java | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 5a1f239840..89f108b470 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -1,12 +1,34 @@ package domain; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Line { private final List points; public Line(Boolean... canGoRights) { - this.points = new ArrayList<>(); + List points = new ArrayList<>(); + if (canGoRights.length == 0) { + throw new IllegalArgumentException(); + } + if (canGoRights[0]) { + points.add(new Point(Direction.RIGHT, 0)); + } + for (int index = 1; index < canGoRights.length; index++) { + if (canGoRights[index]) { + points.add(new Point(Direction.RIGHT, index)); + } + if (canGoRights[index - 1] && canGoRights[index]) { + throw new IllegalArgumentException("|-----|-----| 연결 감지!"); + } + if (canGoRights[index - 1] && !canGoRights[index]) { + points.add(new Point(Direction.LEFT, index)); + } + if (!canGoRights[index - 1] && !canGoRights[index]) { + points.add(new Point(Direction.STRAIGHT, index)); + } + } + this.points = Collections.unmodifiableList(points); } } From a772d45af5dad3cf2d05bd67b8b290c865e59a2d Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 15:48:58 +0900 Subject: [PATCH 07/76] =?UTF-8?q?test:=20=EC=98=A4=EB=A5=B8=EC=AA=BD=20?= =?UTF-8?q?=EB=81=9D=EC=97=90=EC=84=9C=20=EC=98=A4=EB=A5=B8=EC=AA=BD?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B0=80=EB=8A=94=20=EB=B0=9C=ED=8C=90?= =?UTF-8?q?=EC=9D=B4=20=EB=82=98=ED=83=80=EB=82=98=EB=8A=94=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/LineTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/domain/LineTest.java b/src/test/java/domain/LineTest.java index 556ee9d7cd..99426bbeed 100644 --- a/src/test/java/domain/LineTest.java +++ b/src/test/java/domain/LineTest.java @@ -22,4 +22,12 @@ void leftContinueOrRightContinue() { .hasMessage("|-----|-----| 연결 감지!"); } + @Test + @DisplayName("|-----|----- 인 Point로 Line이 생성되지 않는지 확인") + void rightAfterEnd() { + Assertions.assertThatThrownBy( + () -> new Line(true, false, true)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("오른쪽 끝에선 오른쪽으로 갈 수 없습니다."); + } } From 28c661268eb6f1f899d33e8b53babf319753289c Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 15:50:35 +0900 Subject: [PATCH 08/76] =?UTF-8?q?feat:=20=EC=98=A4=EB=A5=B8=EC=AA=BD=20?= =?UTF-8?q?=EB=81=9D=EC=97=90=EC=84=9C=20=EC=98=A4=EB=A5=B8=EC=AA=BD?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B0=80=EB=8A=94=20=EB=B0=9C=ED=8C=90?= =?UTF-8?q?=EC=9D=B4=20=EB=82=98=ED=83=80=EB=82=98=EB=8A=94=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Line.java | 3 +++ src/test/java/domain/PointTest.java | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 89f108b470..3a10682876 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -15,6 +15,9 @@ public Line(Boolean... canGoRights) { if (canGoRights[0]) { points.add(new Point(Direction.RIGHT, 0)); } + if (canGoRights[canGoRights.length - 1]) { + throw new IllegalArgumentException("오른쪽 끝에선 오른쪽으로 갈 수 없습니다."); + } for (int index = 1; index < canGoRights.length; index++) { if (canGoRights[index]) { points.add(new Point(Direction.RIGHT, index)); diff --git a/src/test/java/domain/PointTest.java b/src/test/java/domain/PointTest.java index 853cbd6f5e..93f83fdc5f 100644 --- a/src/test/java/domain/PointTest.java +++ b/src/test/java/domain/PointTest.java @@ -14,7 +14,6 @@ class PointTest { @DisplayName("각 지점에서 이동 시 적절한 지점으로 이동하는지 확인") void next() { // |-----| |-----| | - //Todo 생성시에 올바를 Point 들인지 확인할 수 있어야 함 List points = List.of(new Point(RIGHT), new Point(LEFT, 1), new Point(RIGHT, 2), new Point(LEFT, 3), new Point(STRAIGHT, 4)); Assertions.assertThat(points.get(0).next()).isEqualTo(points.get(1)); From 9ddefcacc131289273f0faf59e0fa2a62d0de7a5 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 15:57:53 +0900 Subject: [PATCH 09/76] =?UTF-8?q?refactor:=20Line=20=EB=82=B4=EB=B6=80=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Line.java | 56 ++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 3a10682876..ce9b7a2737 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -8,30 +8,54 @@ public class Line { private final List points; public Line(Boolean... canGoRights) { + validateLineSize(canGoRights); + validateRightAfterEnd(canGoRights); List points = new ArrayList<>(); + addFirstPoint(points, canGoRights); + addRemainPoints(points, canGoRights); + this.points = Collections.unmodifiableList(points); + } + + private void validateLineSize(Boolean[] canGoRights) { if (canGoRights.length == 0) { throw new IllegalArgumentException(); } - if (canGoRights[0]) { - points.add(new Point(Direction.RIGHT, 0)); - } + } + + private void validateRightAfterEnd(Boolean[] canGoRights) { if (canGoRights[canGoRights.length - 1]) { throw new IllegalArgumentException("오른쪽 끝에선 오른쪽으로 갈 수 없습니다."); } + } + + private void addFirstPoint(List points, Boolean[] canGoRights) { + if (canGoRights[0]) { + points.add(new Point(Direction.RIGHT, 0)); + } + } + + private void addRemainPoints(List points, Boolean[] canGoRights) { for (int index = 1; index < canGoRights.length; index++) { - if (canGoRights[index]) { - points.add(new Point(Direction.RIGHT, index)); - } - if (canGoRights[index - 1] && canGoRights[index]) { - throw new IllegalArgumentException("|-----|-----| 연결 감지!"); - } - if (canGoRights[index - 1] && !canGoRights[index]) { - points.add(new Point(Direction.LEFT, index)); - } - if (!canGoRights[index - 1] && !canGoRights[index]) { - points.add(new Point(Direction.STRAIGHT, index)); - } + validateContinuousRight(index, canGoRights); + addPoint(points, index, canGoRights); + } + } + + private void validateContinuousRight(int index, Boolean[] canGoRights) { + if (canGoRights[index - 1] && canGoRights[index]) { + throw new IllegalArgumentException("|-----|-----| 연결 감지!"); + } + } + + private void addPoint(List points, int index, Boolean[] canGoRights) { + if (canGoRights[index]) { + points.add(new Point(Direction.RIGHT, index)); + } + if (canGoRights[index - 1] && !canGoRights[index]) { + points.add(new Point(Direction.LEFT, index)); + } + if (!canGoRights[index - 1] && !canGoRights[index]) { + points.add(new Point(Direction.STRAIGHT, index)); } - this.points = Collections.unmodifiableList(points); } } From 5b6ab9e9e217210571efd504943b47f8d246a6dd Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 16:00:06 +0900 Subject: [PATCH 10/76] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=93=A4=EC=9D=98=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=20=EC=A7=80=EC=A0=95=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Direction.java | 2 +- src/main/java/domain/Line.java | 4 ++-- src/main/java/domain/Point.java | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/domain/Direction.java b/src/main/java/domain/Direction.java index 3f1583434e..30469a8e56 100644 --- a/src/main/java/domain/Direction.java +++ b/src/main/java/domain/Direction.java @@ -1,5 +1,5 @@ package domain; -public enum Direction { +enum Direction { RIGHT, LEFT, STRAIGHT } diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index ce9b7a2737..7acdc9f29e 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -4,10 +4,10 @@ import java.util.Collections; import java.util.List; -public class Line { +class Line { private final List points; - public Line(Boolean... canGoRights) { + Line(Boolean... canGoRights) { validateLineSize(canGoRights); validateRightAfterEnd(canGoRights); List points = new ArrayList<>(); diff --git a/src/main/java/domain/Point.java b/src/main/java/domain/Point.java index 640fb31d24..7433ab91f4 100644 --- a/src/main/java/domain/Point.java +++ b/src/main/java/domain/Point.java @@ -1,19 +1,19 @@ package domain; -public class Point { +class Point { private final Direction direction; private final int index; - public Point(Direction direction) { + Point(Direction direction) { this(direction, 0); } - public Point(Direction direction, int index) { + Point(Direction direction, int index) { this.direction = direction; this.index = index; } - public Point next() { + Point next() { if (direction == Direction.LEFT) { return new Point(Direction.RIGHT, index - 1); } From b848e074d11bcf4ff63367e2f241d0bbfcfccc9f Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 16:40:26 +0900 Subject: [PATCH 11/76] =?UTF-8?q?test:=20=EB=91=90=20=EC=A7=80=EC=A0=90=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=97=90=20=EC=97=B0=EA=B2=B0=EC=9D=B4=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EC=82=AC=EB=8B=A4=EB=A6=AC=EA=B0=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/LadderTest.java | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/java/domain/LadderTest.java diff --git a/src/test/java/domain/LadderTest.java b/src/test/java/domain/LadderTest.java new file mode 100644 index 0000000000..6e88310fbd --- /dev/null +++ b/src/test/java/domain/LadderTest.java @@ -0,0 +1,29 @@ +package domain; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class LadderTest { + + @Test + @DisplayName("두 지점 사이에 연결이 없는 사다리가 생성되지 않는지 검증") + void validLadder() { + Assertions.assertThatNoException() + .isThrownBy(() -> new Ladder( + List.of(new Line(false, true, false), new Line(true, false, false), + new Line(false, true, false), new Line(false, true, false), + new Line(false, true, false), new Line(false, true, false)))); + } + + @Test + @DisplayName("두 지점 사이에 연결이 없는 사다리가 생성되지 않는지 검증") + void noConnectedLadder() { + Assertions.assertThatThrownBy(() -> new Ladder( + List.of(new Line(false, true, false), new Line(false, true, false), new Line(false, true, false), + new Line(false, true, false), new Line(false, true, false), new Line(false, true, false)))) + .isInstanceOf(IllegalStateException.class) + .hasMessage("두 지점 사이에는 반드시 한개 이상의 발판이 있어야 합니다."); + } +} From 199ea26e9c1911483a65259cf8ffe979be0358dd Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 16:56:08 +0900 Subject: [PATCH 12/76] =?UTF-8?q?fix:=20=EC=9D=BC=EB=B6=80=20=EC=83=81?= =?UTF-8?q?=ED=99=A9=EC=97=90=EC=84=9C=20Line=EC=9D=84=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8A=94=200=EB=B2=88=EC=A7=B8=20Point=20?= =?UTF-8?q?=EB=88=84=EB=9D=BD=EB=90=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Line.java | 7 +++++++ src/test/java/domain/LineTest.java | 13 ++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 7acdc9f29e..1576b64a84 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -32,6 +32,9 @@ private void addFirstPoint(List points, Boolean[] canGoRights) { if (canGoRights[0]) { points.add(new Point(Direction.RIGHT, 0)); } + if (!canGoRights[0]) { + points.add(new Point(Direction.STRAIGHT, 0)); + } } private void addRemainPoints(List points, Boolean[] canGoRights) { @@ -58,4 +61,8 @@ private void addPoint(List points, int index, Boolean[] canGoRights) { points.add(new Point(Direction.STRAIGHT, index)); } } + + int length() { + return points.size(); + } } diff --git a/src/test/java/domain/LineTest.java b/src/test/java/domain/LineTest.java index 99426bbeed..4bc6ecf864 100644 --- a/src/test/java/domain/LineTest.java +++ b/src/test/java/domain/LineTest.java @@ -8,9 +8,16 @@ class LineTest { @Test @DisplayName("올바른 Point로 Line이 잘 생성되는지 확인") void normal() { - Assertions.assertThatNoException() - .isThrownBy( - () -> new Line(true, false, false, true, false)); + // |-----| | |-----| + Line line = new Line(true, false, false, true, false); + int length = line.length(); + Assertions.assertThat(length) + .isEqualTo(5); + // | | | |-----| + Line line2 = new Line(false, false, false, true, false); + int length2 = line.length(); + Assertions.assertThat(length2) + .isEqualTo(5); } @Test From a9e0ee787b4ec0101bd3ccf7e333798c97c4b12e Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 16:59:10 +0900 Subject: [PATCH 13/76] =?UTF-8?q?chore:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20Di?= =?UTF-8?q?splayName=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/LadderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/domain/LadderTest.java b/src/test/java/domain/LadderTest.java index 6e88310fbd..030fd45080 100644 --- a/src/test/java/domain/LadderTest.java +++ b/src/test/java/domain/LadderTest.java @@ -8,7 +8,7 @@ public class LadderTest { @Test - @DisplayName("두 지점 사이에 연결이 없는 사다리가 생성되지 않는지 검증") + @DisplayName("정상적인 사다리가 생성되는지 검증") void validLadder() { Assertions.assertThatNoException() .isThrownBy(() -> new Ladder( From 4906acca2578b3d60b2834282b6aecf03883afd8 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 17:03:27 +0900 Subject: [PATCH 14/76] =?UTF-8?q?fix:=20=EB=91=90=20=EC=A7=80=EC=A0=90=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=97=90=20=EC=97=B0=EA=B2=B0=EC=9D=B4=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EC=82=AC=EB=8B=A4=EB=A6=AC=EA=B0=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Ladder.java | 26 ++++++++++++++++++++++++++ src/main/java/domain/Line.java | 9 +++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/main/java/domain/Ladder.java diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java new file mode 100644 index 0000000000..81cfed96b8 --- /dev/null +++ b/src/main/java/domain/Ladder.java @@ -0,0 +1,26 @@ +package domain; + +import java.util.List; + +public class Ladder { + private final List lines; + + public Ladder(List lines) { + int ladderWeight = lines.get(0).length(); + boolean[] isConnectedWithNext = new boolean[ladderWeight - 1]; + for (int index = 0; index < ladderWeight - 1; index++) { + for (Line line : lines) { + isConnectedWithNext[index] = line.isConnectWithNextPoint(index); + if (isConnectedWithNext[index]) { + break; + } + } + } + for (int index = 0; index < ladderWeight - 1; index++) { + if (!isConnectedWithNext[index]) { + throw new IllegalStateException("두 지점 사이에는 반드시 한개 이상의 발판이 있어야 합니다."); + } + } + this.lines = lines; + } +} diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 1576b64a84..2ba42cbafb 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -65,4 +65,13 @@ private void addPoint(List points, int index, Boolean[] canGoRights) { int length() { return points.size(); } + + boolean isConnectWithNextPoint(int index) { + if (index == points.size() - 1) { + return false; + } + Point point = points.get(index); + Point nextPoint = points.get(index + 1); + return point.next().equals(nextPoint); + } } From cbc96d5827f3a6a63be591f646f05b4524bf8dd3 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 17:21:39 +0900 Subject: [PATCH 15/76] =?UTF-8?q?refactor:=20Ladder=20=EB=82=B4=EB=B6=80?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EC=BD=94=EB=93=9C=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Ladder.java | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index 81cfed96b8..ccda5f2c3c 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -1,26 +1,27 @@ package domain; import java.util.List; +import java.util.stream.IntStream; public class Ladder { private final List lines; public Ladder(List lines) { - int ladderWeight = lines.get(0).length(); - boolean[] isConnectedWithNext = new boolean[ladderWeight - 1]; - for (int index = 0; index < ladderWeight - 1; index++) { - for (Line line : lines) { - isConnectedWithNext[index] = line.isConnectWithNextPoint(index); - if (isConnectedWithNext[index]) { - break; - } - } - } - for (int index = 0; index < ladderWeight - 1; index++) { - if (!isConnectedWithNext[index]) { - throw new IllegalStateException("두 지점 사이에는 반드시 한개 이상의 발판이 있어야 합니다."); - } - } + validateConnectedLadder(lines); this.lines = lines; } + + private void validateConnectedLadder(List lines) { + int lastIndex = lines.get(0).length() - 1; + boolean isConnectedLadder = IntStream.range(0, lastIndex) + .allMatch(index -> isConnectedAtIndex(lines, index)); + if (!isConnectedLadder) { + throw new IllegalStateException("두 지점 사이에는 반드시 한개 이상의 발판이 있어야 합니다."); + } + } + + private boolean isConnectedAtIndex(List lines, int index) { + return lines.stream() + .anyMatch(line -> line.isConnectWithNextPoint(index)); + } } From 145402470b5d10f53fb8a8fe3b2eb8a3ef1a0d64 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 17:46:23 +0900 Subject: [PATCH 16/76] =?UTF-8?q?chore:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/LineTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/domain/LineTest.java b/src/test/java/domain/LineTest.java index 4bc6ecf864..de971fe2a8 100644 --- a/src/test/java/domain/LineTest.java +++ b/src/test/java/domain/LineTest.java @@ -15,7 +15,7 @@ void normal() { .isEqualTo(5); // | | | |-----| Line line2 = new Line(false, false, false, true, false); - int length2 = line.length(); + int length2 = line2.length(); Assertions.assertThat(length2) .isEqualTo(5); } From 9eb6999c2080816930342b72ca6a223e7341fccb Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 17:46:50 +0900 Subject: [PATCH 17/76] =?UTF-8?q?test:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=83=80=EA=B8=B0=20=EA=B2=B0=EA=B3=BC=EA=B0=80=20=EC=9E=98=20?= =?UTF-8?q?=EB=82=98=EC=98=A4=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Ladder.java | 4 ++++ src/test/java/domain/LadderTest.java | 31 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index ccda5f2c3c..85fc3166b0 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -24,4 +24,8 @@ private boolean isConnectedAtIndex(List lines, int index) { return lines.stream() .anyMatch(line -> line.isConnectWithNextPoint(index)); } + + public int climb(int startIndex) { + return 1; + } } diff --git a/src/test/java/domain/LadderTest.java b/src/test/java/domain/LadderTest.java index 030fd45080..3eec117ff7 100644 --- a/src/test/java/domain/LadderTest.java +++ b/src/test/java/domain/LadderTest.java @@ -1,9 +1,13 @@ package domain; import java.util.List; +import java.util.stream.Stream; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public class LadderTest { @@ -26,4 +30,31 @@ void noConnectedLadder() { .isInstanceOf(IllegalStateException.class) .hasMessage("두 지점 사이에는 반드시 한개 이상의 발판이 있어야 합니다."); } + + @ParameterizedTest + @MethodSource("climbParameter") + @DisplayName("사다리 타기 결과가 잘 나오는지 검증") + void climb(int startIndex, int endIndex) { + /* + * | |-----| + * |-----| | + * | |-----| + * | |-----| + * | |-----| + * | |-----| + * */ + Ladder ladder = new Ladder( + List.of(new Line(false, true, false), new Line(true, false, false), + new Line(false, true, false), new Line(false, true, false), + new Line(false, true, false), new Line(false, true, false))); + int actual = ladder.climb(startIndex); + Assertions.assertThat(actual) + .isEqualTo(endIndex); + } + + static Stream climbParameter() { + return Stream.of(Arguments.of(0, 1), + Arguments.of(1, 2), + Arguments.of(2, 0)); + } } From 1e4734e23a628676ca762887805470b5baf76ebd Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 17:48:02 +0900 Subject: [PATCH 18/76] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=83=80=EA=B8=B0=20=EA=B2=B0=EA=B3=BC=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/domain/Ladder.java | 6 +++++- src/main/java/domain/Line.java | 6 ++++++ src/main/java/domain/Point.java | 4 ++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9af72b4265..c76df98ecf 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ - [ ] 참가자 이름 입력 기능 - [ ] 참가자 생성 기능 - [ ] 사다리 높이 입력 기능 -- [ ] 사다리 생성 기능 +- [x] 사다리 생성 기능 - [ ] 사다리 출력 기능 - [ ] 사다리 타기 실행 기능 - [ ] 사다리 타기 결과 출력 기능 diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index 85fc3166b0..8028fb1474 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -26,6 +26,10 @@ private boolean isConnectedAtIndex(List lines, int index) { } public int climb(int startIndex) { - return 1; + int endIndex = startIndex; + for (Line line : lines) { + endIndex = line.move(endIndex); + } + return endIndex; } } diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 2ba42cbafb..0758ed88c7 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -74,4 +74,10 @@ boolean isConnectWithNextPoint(int index) { Point nextPoint = points.get(index + 1); return point.next().equals(nextPoint); } + + int move(int startIndex) { + Point start = points.get(startIndex); + Point next = start.next(); + return next.getIndex(); + } } diff --git a/src/main/java/domain/Point.java b/src/main/java/domain/Point.java index 7433ab91f4..69e2bf18ff 100644 --- a/src/main/java/domain/Point.java +++ b/src/main/java/domain/Point.java @@ -54,4 +54,8 @@ public String toString() { ", index=" + index + '}'; } + + int getIndex() { + return index; + } } From 10830e5c34235f58588be7c828c02aa62ed4b30d Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 17:58:05 +0900 Subject: [PATCH 19/76] =?UTF-8?q?refactor:=20Point=20=EC=99=80=20Direction?= =?UTF-8?q?=20=EC=82=AC=EC=9D=B4=20=EC=97=AD=ED=95=A0=20=EC=9E=AC=EB=B6=84?= =?UTF-8?q?=EB=B0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Direction.java | 21 ++++++++++++++++++++- src/main/java/domain/Point.java | 8 +------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/java/domain/Direction.java b/src/main/java/domain/Direction.java index 30469a8e56..5b7e5a9166 100644 --- a/src/main/java/domain/Direction.java +++ b/src/main/java/domain/Direction.java @@ -1,5 +1,24 @@ package domain; +import java.util.function.Function; + enum Direction { - RIGHT, LEFT, STRAIGHT + + RIGHT(index -> index + 1), LEFT(index -> index - 1), STRAIGHT(index -> index); + private final Function nextIndexFunction; + + Direction(Function nextIndexFunction) { + this.nextIndexFunction = nextIndexFunction; + } + + Point nextPoint(int nowIndex) { + Integer nextIndex = nextIndexFunction.apply(nowIndex); + if (this == LEFT) { + return new Point(RIGHT, nextIndex); + } + if (this == RIGHT) { + return new Point(LEFT, nextIndex); + } + return new Point(STRAIGHT, nextIndex); + } } diff --git a/src/main/java/domain/Point.java b/src/main/java/domain/Point.java index 69e2bf18ff..f7cea3dc0e 100644 --- a/src/main/java/domain/Point.java +++ b/src/main/java/domain/Point.java @@ -14,13 +14,7 @@ class Point { } Point next() { - if (direction == Direction.LEFT) { - return new Point(Direction.RIGHT, index - 1); - } - if (direction == Direction.RIGHT) { - return new Point(Direction.LEFT, index + 1); - } - return new Point(Direction.STRAIGHT, index); + return direction.nextPoint(index); } @Override From 08cce9c0a0e5a6ac22ec3b5ed6cb0676ad1d25a8 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 18:10:36 +0900 Subject: [PATCH 20/76] =?UTF-8?q?refactor:=20Point=20Record=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Line.java | 2 +- src/main/java/domain/Point.java | 46 +-------------------------------- 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 0758ed88c7..3a1d1f42ee 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -78,6 +78,6 @@ boolean isConnectWithNextPoint(int index) { int move(int startIndex) { Point start = points.get(startIndex); Point next = start.next(); - return next.getIndex(); + return next.index(); } } diff --git a/src/main/java/domain/Point.java b/src/main/java/domain/Point.java index f7cea3dc0e..e1f24f37b8 100644 --- a/src/main/java/domain/Point.java +++ b/src/main/java/domain/Point.java @@ -1,55 +1,11 @@ package domain; -class Point { - private final Direction direction; - private final int index; - +record Point(Direction direction, int index) { Point(Direction direction) { this(direction, 0); } - Point(Direction direction, int index) { - this.direction = direction; - this.index = index; - } - Point next() { return direction.nextPoint(index); } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Point point = (Point) o; - - if (index != point.index) { - return false; - } - return direction == point.direction; - } - - @Override - public int hashCode() { - int result = direction != null ? direction.hashCode() : 0; - result = 31 * result + index; - return result; - } - - @Override - public String toString() { - return "Point{" + - "direction=" + direction + - ", index=" + index + - '}'; - } - - int getIndex() { - return index; - } } From d040005734cc8bdd4b8a866e1462e68ab79e93e1 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 21:26:54 +0900 Subject: [PATCH 21/76] =?UTF-8?q?test:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EA=B8=B8=EC=9D=B4=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Player.java | 7 +++++++ src/test/java/domain/PlayerTest.java | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/main/java/domain/Player.java create mode 100644 src/test/java/domain/PlayerTest.java diff --git a/src/main/java/domain/Player.java b/src/main/java/domain/Player.java new file mode 100644 index 0000000000..15549b7838 --- /dev/null +++ b/src/main/java/domain/Player.java @@ -0,0 +1,7 @@ +package domain; + +record Player(String name) { + Player { + + } +} diff --git a/src/test/java/domain/PlayerTest.java b/src/test/java/domain/PlayerTest.java new file mode 100644 index 0000000000..eec906875e --- /dev/null +++ b/src/test/java/domain/PlayerTest.java @@ -0,0 +1,18 @@ +package domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class PlayerTest { + @ParameterizedTest + @ValueSource(strings = {"123456", ""}) + @DisplayName("참가자 이름 길이 검증") + void validatePlayerNameLength(String name) { + Assertions.assertThatThrownBy(() -> new Player(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("참가자 이름은 1글자 이상 5글자 이하여야 합니다."); + } + +} From bb4f3db03e49c05d29d4997046d3666fe38c9edd Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 21:27:13 +0900 Subject: [PATCH 22/76] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EA=B8=B8=EC=9D=B4=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Player.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/Player.java b/src/main/java/domain/Player.java index 15549b7838..a2e1927d33 100644 --- a/src/main/java/domain/Player.java +++ b/src/main/java/domain/Player.java @@ -2,6 +2,8 @@ record Player(String name) { Player { - + if (name == null || name.isEmpty() || name.length() > 5) { + throw new IllegalArgumentException("참가자 이름은 1글자 이상 5글자 이하여야 합니다."); + } } } From b7da5b01e8b1c408e333795e79954eded85ca919 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 21:35:45 +0900 Subject: [PATCH 23/76] =?UTF-8?q?test:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EA=B5=AC=EC=84=B1=20=EB=AC=B8=EC=9E=90=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/PlayerTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/domain/PlayerTest.java b/src/test/java/domain/PlayerTest.java index eec906875e..9be7376512 100644 --- a/src/test/java/domain/PlayerTest.java +++ b/src/test/java/domain/PlayerTest.java @@ -15,4 +15,21 @@ void validatePlayerNameLength(String name) { .hasMessage("참가자 이름은 1글자 이상 5글자 이하여야 합니다."); } + @ParameterizedTest + @ValueSource(strings = {"!", " ", "가나다", "abc "}) + @DisplayName("참가자 이름 구성 문자 검증") + void validatePlayerNameCharacter(String name) { + Assertions.assertThatThrownBy(() -> new Player(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("참가자 이름은 알파벳 대소문자와 숫자만으로 이루어져야 합니다."); + } + + @ParameterizedTest + @ValueSource(strings = {"robin", "12345", "abc12", "12Abc"}) + @DisplayName("참가자 이름 구성 문자 검증") + void normalName(String name) { + Assertions.assertThatNoException() + .isThrownBy(() -> new Player(name)); + } + } From 256705d356f83f2bfdd5b9dada6bdd74cd5fc329 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 21:36:05 +0900 Subject: [PATCH 24/76] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EA=B5=AC=EC=84=B1=20=EB=AC=B8=EC=9E=90=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Player.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/domain/Player.java b/src/main/java/domain/Player.java index a2e1927d33..0ee63b147b 100644 --- a/src/main/java/domain/Player.java +++ b/src/main/java/domain/Player.java @@ -1,9 +1,18 @@ package domain; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + record Player(String name) { + private static final Pattern pattern = Pattern.compile(".*[^a-zA-Z0-9].*"); + Player { if (name == null || name.isEmpty() || name.length() > 5) { throw new IllegalArgumentException("참가자 이름은 1글자 이상 5글자 이하여야 합니다."); } + Matcher matcher = pattern.matcher(name); + if (matcher.matches()) { + throw new IllegalArgumentException("참가자 이름은 알파벳 대소문자와 숫자만으로 이루어져야 합니다."); + } } } From f8b5079adc137e04892830c9a1bc7415a7b7501d Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 21:41:47 +0900 Subject: [PATCH 25/76] =?UTF-8?q?refactor:=20Player=20=EB=82=B4=EB=B6=80?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Player.java | 16 ++++++++++++++++ src/test/java/domain/PlayerTest.java | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/src/main/java/domain/Player.java b/src/main/java/domain/Player.java index 0ee63b147b..33e391f805 100644 --- a/src/main/java/domain/Player.java +++ b/src/main/java/domain/Player.java @@ -7,12 +7,28 @@ record Player(String name) { private static final Pattern pattern = Pattern.compile(".*[^a-zA-Z0-9].*"); Player { + validateNameLength(name); + validateNameCharacter(name); + validateNameBlackList(name); + } + + private void validateNameLength(String name) { if (name == null || name.isEmpty() || name.length() > 5) { throw new IllegalArgumentException("참가자 이름은 1글자 이상 5글자 이하여야 합니다."); } + } + + private void validateNameCharacter(String name) { Matcher matcher = pattern.matcher(name); if (matcher.matches()) { throw new IllegalArgumentException("참가자 이름은 알파벳 대소문자와 숫자만으로 이루어져야 합니다."); } } + + private void validateNameBlackList(String name) { + if (name.equals("all")) { + throw new IllegalArgumentException("참가자 이름은 all이 될 수 없습니다."); + } + } + } diff --git a/src/test/java/domain/PlayerTest.java b/src/test/java/domain/PlayerTest.java index 9be7376512..90932365e0 100644 --- a/src/test/java/domain/PlayerTest.java +++ b/src/test/java/domain/PlayerTest.java @@ -24,6 +24,15 @@ void validatePlayerNameCharacter(String name) { .hasMessage("참가자 이름은 알파벳 대소문자와 숫자만으로 이루어져야 합니다."); } + @ParameterizedTest + @ValueSource(strings = {"all"}) + @DisplayName("참가자 이름 구성 문자 검증") + void validateNameBlackList(String name) { + Assertions.assertThatThrownBy(() -> new Player(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("참가자 이름은 all이 될 수 없습니다."); + } + @ParameterizedTest @ValueSource(strings = {"robin", "12345", "abc12", "12Abc"}) @DisplayName("참가자 이름 구성 문자 검증") From 9003f6af19d1967254bc90b48554325208ec754d Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 21:49:59 +0900 Subject: [PATCH 26/76] =?UTF-8?q?test:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=B4=20=EC=A4=91=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Players.java | 16 ++++++++++++++++ src/test/java/domain/PlayersTest.java | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/main/java/domain/Players.java create mode 100644 src/test/java/domain/PlayersTest.java diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java new file mode 100644 index 0000000000..a0020fe87c --- /dev/null +++ b/src/main/java/domain/Players.java @@ -0,0 +1,16 @@ +package domain; + +import java.util.Collections; +import java.util.List; + +class Players { + private final List players; + + Players(List players) { + this.players = Collections.unmodifiableList(players); + } + + static Players of(String... playerNames) { + return new Players(null); + } +} diff --git a/src/test/java/domain/PlayersTest.java b/src/test/java/domain/PlayersTest.java new file mode 100644 index 0000000000..e768b14a83 --- /dev/null +++ b/src/test/java/domain/PlayersTest.java @@ -0,0 +1,17 @@ +package domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PlayersTest { + + @Test + @DisplayName("중복된 이름의 참가자가 생성되지 않는지 확인") + void validateDuplicateName() { + Assertions.assertThatThrownBy(() -> Players.of("robin", "robin")) + .isInstanceOf(IllegalStateException.class) + .hasMessage("이름이 같은 참가자는 있을 수 없습니다."); + } + +} From 8c44c732d7d80caebf1928c46de40a3a6d73bc87 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 21:52:57 +0900 Subject: [PATCH 27/76] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=B4=20=EC=A4=91=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Players.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index a0020fe87c..9e1dd89ac6 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -1,16 +1,28 @@ package domain; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; class Players { private final List players; Players(List players) { + validateDuplicateName(players); this.players = Collections.unmodifiableList(players); } + private void validateDuplicateName(List players) { + Set distinctPlayers = new HashSet<>(players); + if (distinctPlayers.size() != players.size()) { + throw new IllegalStateException("이름이 같은 참가자는 있을 수 없습니다."); + } + } + static Players of(String... playerNames) { - return new Players(null); + List players = Arrays.stream(playerNames).map(Player::new).toList(); + return new Players(players); } } From 8b60a91dd9d37350068aa1709a9c2c84a8760387 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 22:03:40 +0900 Subject: [PATCH 28/76] =?UTF-8?q?test:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B8=EC=9B=90=EC=88=98=20=EA=B2=80=EC=A6=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/PlayersTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/domain/PlayersTest.java b/src/test/java/domain/PlayersTest.java index e768b14a83..cfca350a01 100644 --- a/src/test/java/domain/PlayersTest.java +++ b/src/test/java/domain/PlayersTest.java @@ -1,8 +1,11 @@ package domain; +import java.util.stream.IntStream; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; class PlayersTest { @@ -14,4 +17,18 @@ void validateDuplicateName() { .hasMessage("이름이 같은 참가자는 있을 수 없습니다."); } + @ParameterizedTest + @ValueSource(ints = {1, 11}) + @DisplayName("참가자 인원 수가 너무 적거나 너무 많은지 확인") + void validatePlayersCount(int playersCount) { + String[] playerNames = IntStream.rangeClosed(1, playersCount) + .mapToObj("a%d"::formatted) + .toList() + .toArray(new String[playersCount]); + + Assertions.assertThatThrownBy(() -> Players.of(playerNames)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("참가자는 2명 이상 10명 이하여야 합니다."); + } + } From b0424e0e8c793cabf9dfcd1b0c26d048d1c4a50b Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 22:04:57 +0900 Subject: [PATCH 29/76] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B8=EC=9B=90=EC=88=98=20=EA=B2=80=EC=A6=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/domain/Players.java | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c76df98ecf..682d31f4f4 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ # 기능 목록 - [ ] 참가자 이름 입력 기능 -- [ ] 참가자 생성 기능 +- [x] 참가자 생성 기능 - [ ] 사다리 높이 입력 기능 - [x] 사다리 생성 기능 - [ ] 사다리 출력 기능 diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index 9e1dd89ac6..a2196c9b55 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -11,6 +11,7 @@ class Players { Players(List players) { validateDuplicateName(players); + validatePlayersCount(players); this.players = Collections.unmodifiableList(players); } @@ -21,6 +22,12 @@ private void validateDuplicateName(List players) { } } + private void validatePlayersCount(List players) { + if (players == null || players.size() < 2 || players.size() > 10) { + throw new IllegalStateException("참가자는 2명 이상 10명 이하여야 합니다."); + } + } + static Players of(String... playerNames) { List players = Arrays.stream(playerNames).map(Player::new).toList(); return new Players(players); From a0c4c77c0ee938ee3a112f30f05912d348450cde Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 22:18:03 +0900 Subject: [PATCH 30/76] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=EC=97=90=20=EC=83=81=ED=92=88=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 682d31f4f4..d17c75cf9d 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,9 @@ |-----| | |-----| | ``` +- 상품 관련 요구 사항 + 1. 상품은 사다리 타기의 결과로 참여자와 1대 1 매칭 될 어떤 것을 말한다. + 2. 상품은 최소 한글자 최대 5글자까지 부여할 수 있다. - 안정적인 프로그램 실행을 위한 요구사항 1. 잘못된 입력이 발생한 경우, 적절한 에러 메세지를 출력한 뒤 해당 위치부터 다시 입력을 수행한다. 2. 재입력은 무한히 시도될 수 있어야 한다. @@ -40,6 +43,8 @@ - [ ] 참가자 이름 입력 기능 - [x] 참가자 생성 기능 - [ ] 사다리 높이 입력 기능 +- [ ] 상품 이름 입력 기능 +- [ ] 상품 생성 기능 - [x] 사다리 생성 기능 - [ ] 사다리 출력 기능 - [ ] 사다리 타기 실행 기능 From 2e2934b83b22278a36be0a394633fae841a01353 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 22:21:09 +0900 Subject: [PATCH 31/76] =?UTF-8?q?test:=20=EC=83=81=ED=92=88=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EA=B8=B8=EC=9D=B4=20=EA=B2=80=EC=A6=9D=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/GiftTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/java/domain/GiftTest.java diff --git a/src/test/java/domain/GiftTest.java b/src/test/java/domain/GiftTest.java new file mode 100644 index 0000000000..caa99822a8 --- /dev/null +++ b/src/test/java/domain/GiftTest.java @@ -0,0 +1,17 @@ +package domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class GiftTest { + @ParameterizedTest + @ValueSource(strings = {"123456", ""}) + @DisplayName("상품 이름 길이 검증") + void validateGiftNameLength(String name) { + Assertions.assertThatThrownBy(() -> new Gift(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("상품 이름은 1글자 이상 5글자 이하여야 합니다."); + } +} From 54b99be628450230758afe3a59f352e228626abb Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 22:21:27 +0900 Subject: [PATCH 32/76] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EA=B8=B8=EC=9D=B4=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Gift.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/domain/Gift.java diff --git a/src/main/java/domain/Gift.java b/src/main/java/domain/Gift.java new file mode 100644 index 0000000000..1539e08013 --- /dev/null +++ b/src/main/java/domain/Gift.java @@ -0,0 +1,14 @@ +package domain; + +record Gift(String name) { + + Gift { + validateNameLength(name); + } + + private void validateNameLength(String name) { + if (name == null || name.isEmpty() || name.length() > 5) { + throw new IllegalArgumentException("상품 이름은 1글자 이상 5글자 이하여야 합니다."); + } + } +} From 48a090fe986c6ccf3538c31226938a71094567e4 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 22:22:41 +0900 Subject: [PATCH 33/76] =?UTF-8?q?chore:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9D=B4=EB=A6=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/PlayerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/domain/PlayerTest.java b/src/test/java/domain/PlayerTest.java index 90932365e0..905f39ff1f 100644 --- a/src/test/java/domain/PlayerTest.java +++ b/src/test/java/domain/PlayerTest.java @@ -35,7 +35,7 @@ void validateNameBlackList(String name) { @ParameterizedTest @ValueSource(strings = {"robin", "12345", "abc12", "12Abc"}) - @DisplayName("참가자 이름 구성 문자 검증") + @DisplayName("정상적인 이름의 참여자 생성") void normalName(String name) { Assertions.assertThatNoException() .isThrownBy(() -> new Player(name)); From 4f90e64594c184e42cfbb3894dfb620c3c0eeb65 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 22:42:25 +0900 Subject: [PATCH 34/76] =?UTF-8?q?test:=20=EC=83=81=ED=92=88=EC=88=98=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Gifts.java | 17 +++++++++++++++++ src/test/java/domain/GiftsTest.java | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/main/java/domain/Gifts.java create mode 100644 src/test/java/domain/GiftsTest.java diff --git a/src/main/java/domain/Gifts.java b/src/main/java/domain/Gifts.java new file mode 100644 index 0000000000..c3d8e9289f --- /dev/null +++ b/src/main/java/domain/Gifts.java @@ -0,0 +1,17 @@ +package domain; + +import java.util.Arrays; +import java.util.List; + +class Gifts { + private final List gifts; + + private Gifts(List gifts) { + this.gifts = gifts; + } + + static Gifts of(String... giftsName) { + List gifts = Arrays.stream(giftsName).map(Gift::new).toList(); + return new Gifts(gifts); + } +} diff --git a/src/test/java/domain/GiftsTest.java b/src/test/java/domain/GiftsTest.java new file mode 100644 index 0000000000..3786886185 --- /dev/null +++ b/src/test/java/domain/GiftsTest.java @@ -0,0 +1,24 @@ +package domain; + +import java.util.stream.IntStream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class GiftsTest { + @ParameterizedTest + @ValueSource(ints = {1, 11}) + @DisplayName("상품 수가 너무 적거나 너무 많은지 확인") + void validateGiftsCount(int giftsCount) { + String[] giftNames = IntStream.rangeClosed(1, giftsCount) + .mapToObj("a%d"::formatted) + .toList() + .toArray(new String[giftsCount]); + + Assertions.assertThatThrownBy(() -> Gifts.of(giftNames)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("상품은 2개 이상 10개 이하여야 합니다."); + } + +} From b1ec852d44be2ce525ebeaf8ad7c16352ed3d664 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 22:44:34 +0900 Subject: [PATCH 35/76] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=EC=88=98=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/domain/Gifts.java | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d17c75cf9d..3764850975 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ - [x] 참가자 생성 기능 - [ ] 사다리 높이 입력 기능 - [ ] 상품 이름 입력 기능 -- [ ] 상품 생성 기능 +- [x] 상품 생성 기능 - [x] 사다리 생성 기능 - [ ] 사다리 출력 기능 - [ ] 사다리 타기 실행 기능 diff --git a/src/main/java/domain/Gifts.java b/src/main/java/domain/Gifts.java index c3d8e9289f..903e9a266a 100644 --- a/src/main/java/domain/Gifts.java +++ b/src/main/java/domain/Gifts.java @@ -7,9 +7,16 @@ class Gifts { private final List gifts; private Gifts(List gifts) { + validateGiftsCount(gifts); this.gifts = gifts; } + private void validateGiftsCount(List players) { + if (players == null || players.size() < 2 || players.size() > 10) { + throw new IllegalStateException("상품은 2개 이상 10개 이하여야 합니다."); + } + } + static Gifts of(String... giftsName) { List gifts = Arrays.stream(giftsName).map(Gift::new).toList(); return new Gifts(gifts); From fc96389f1a39ff623f989a93aea0f420ec5b308a Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 23:16:50 +0900 Subject: [PATCH 36/76] =?UTF-8?q?test:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=83=80=EA=B8=B0=20=EA=B2=B0=EA=B3=BC=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/LadderGame.java | 68 +++++++++++++++++++++ src/main/java/domain/LadderGameResult.java | 4 ++ src/main/java/domain/LadderGameResults.java | 11 ++++ src/test/java/domain/LadderGameTest.java | 26 ++++++++ 4 files changed, 109 insertions(+) create mode 100644 src/main/java/domain/LadderGame.java create mode 100644 src/main/java/domain/LadderGameResult.java create mode 100644 src/main/java/domain/LadderGameResults.java create mode 100644 src/test/java/domain/LadderGameTest.java diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java new file mode 100644 index 0000000000..460f595c1d --- /dev/null +++ b/src/main/java/domain/LadderGame.java @@ -0,0 +1,68 @@ +package domain; + +import java.util.List; +import java.util.function.Supplier; + +public class LadderGame { + private final Players players; + private final Gifts gifts; + private final Supplier ladderMakeStrategy; + private final int ladderHeight; + + //Todo: 매개 변수 너무 많음 + private LadderGame(Players players, Gifts gifts, Supplier ladderMakeStrategy, int ladderHeight) { + validateRequiredValues(players, gifts, ladderMakeStrategy); + this.players = players; + this.gifts = gifts; + this.ladderMakeStrategy = ladderMakeStrategy; + this.ladderHeight = ladderHeight; + } + + private void validateRequiredValues(Players players, Gifts gifts, Supplier ladderMakeStrategy) { + if (players == null || gifts == null || ladderMakeStrategy == null) { + throw new IllegalStateException("필수 값이 설정되지 않았습니다."); + } + } + + public LadderGameResults start(String operator) { + return new LadderGameResults(List.of(new LadderGameResult("a", "b"))); + } + + public static final class LadderGameBuilder { + private Players players; + private Gifts gifts; + private Supplier ladderMakeStrategy; + private int ladderHeight; + + private LadderGameBuilder() { + } + + public static LadderGameBuilder builder() { + return new LadderGameBuilder(); + } + + public LadderGameBuilder players(String... playerNames) { + this.players = Players.of(playerNames); + return this; + } + + public LadderGameBuilder gifts(String... giftNames) { + this.gifts = Gifts.of(giftNames); + return this; + } + + public LadderGameBuilder ladderMakeStrategy(Supplier ladderMakeStrategy) { + this.ladderMakeStrategy = ladderMakeStrategy; + return this; + } + + public LadderGameBuilder ladderHeight(int ladderHeight) { + this.ladderHeight = ladderHeight; + return this; + } + + public LadderGame build() { + return new LadderGame(players, gifts, ladderMakeStrategy, ladderHeight); + } + } +} diff --git a/src/main/java/domain/LadderGameResult.java b/src/main/java/domain/LadderGameResult.java new file mode 100644 index 0000000000..eaabb9b182 --- /dev/null +++ b/src/main/java/domain/LadderGameResult.java @@ -0,0 +1,4 @@ +package domain; + +public record LadderGameResult(String playerName, String giftName) { +} diff --git a/src/main/java/domain/LadderGameResults.java b/src/main/java/domain/LadderGameResults.java new file mode 100644 index 0000000000..4a82b2e3ac --- /dev/null +++ b/src/main/java/domain/LadderGameResults.java @@ -0,0 +1,11 @@ +package domain; + +import java.util.List; + +public class LadderGameResults { + private final List ladderGameResults; + + public LadderGameResults(List ladderGameResults) { + this.ladderGameResults = ladderGameResults; + } +} diff --git a/src/test/java/domain/LadderGameTest.java b/src/test/java/domain/LadderGameTest.java new file mode 100644 index 0000000000..c3e1eacdc5 --- /dev/null +++ b/src/test/java/domain/LadderGameTest.java @@ -0,0 +1,26 @@ +package domain; + +import domain.LadderGame.LadderGameBuilder; +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class LadderGameTest { + + @ParameterizedTest + @CsvSource(value = {"robin,2등", "phobi,1등"}) + @DisplayName("게임 실행 결과 검증") + void start(String playerName, String giftName) { + LadderGame ladderGame = LadderGameBuilder.builder() + .players("robin", "phobi") + .gifts("1등", "2등") + .ladderMakeStrategy(() -> new Boolean[]{true, false}) + .ladderHeight(5) + .build(); + LadderGameResults actualGameResults = ladderGame.start(playerName); + Assertions.assertThat(actualGameResults) + .isEqualTo(new LadderGameResults(List.of(new LadderGameResult(playerName, giftName)))); + } +} From cbda7c3c91abd9f4b2cbf7f85e4e91af52764894 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 23:41:18 +0900 Subject: [PATCH 37/76] =?UTF-8?q?test:=20=EA=B2=8C=EC=9E=84=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=EC=8B=9C=20=EC=97=86=EB=8A=94=20=EC=B0=B8=EC=97=AC?= =?UTF-8?q?=EC=9E=90=20=EA=B2=B0=EA=B3=BC=20=EC=A1=B0=ED=9A=8C=20=EC=95=88?= =?UTF-8?q?=EB=90=98=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/LadderGameTest.java | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/test/java/domain/LadderGameTest.java b/src/test/java/domain/LadderGameTest.java index c3e1eacdc5..957a63c36d 100644 --- a/src/test/java/domain/LadderGameTest.java +++ b/src/test/java/domain/LadderGameTest.java @@ -4,6 +4,7 @@ import java.util.List; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -13,14 +14,27 @@ class LadderGameTest { @CsvSource(value = {"robin,2등", "phobi,1등"}) @DisplayName("게임 실행 결과 검증") void start(String playerName, String giftName) { - LadderGame ladderGame = LadderGameBuilder.builder() + LadderGame ladderGame = makeTestLadderGame(); + LadderGameResults actualGameResults = ladderGame.start(playerName); + Assertions.assertThat(actualGameResults) + .isEqualTo(new LadderGameResults(List.of(new LadderGameResult(playerName, giftName)))); + } + + private LadderGame makeTestLadderGame() { + return LadderGameBuilder.builder() .players("robin", "phobi") .gifts("1등", "2등") .ladderMakeStrategy(() -> new Boolean[]{true, false}) .ladderHeight(5) .build(); - LadderGameResults actualGameResults = ladderGame.start(playerName); - Assertions.assertThat(actualGameResults) - .isEqualTo(new LadderGameResults(List.of(new LadderGameResult(playerName, giftName)))); + } + + @Test + @DisplayName("게임 실행 시 없는 참여자 결과 조회 안되는지 검증") + void validateOperator() { + LadderGame ladderGame = makeTestLadderGame(); + Assertions.assertThatThrownBy(() -> ladderGame.start("none")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("없는 참가자 입니다."); } } From 81f9ddb992f754fd6978330f25e01a73ff2c9b09 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 23:43:36 +0900 Subject: [PATCH 38/76] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=83=80=EA=B8=B0=20=EC=8B=A4=ED=96=89=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/domain/Gifts.java | 5 ++++ src/main/java/domain/LadderGame.java | 33 +++++++++++++++++---- src/main/java/domain/LadderGameResults.java | 25 ++++++++++++++++ src/main/java/domain/Players.java | 10 +++++++ 5 files changed, 69 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3764850975..9bfd2ab813 100644 --- a/README.md +++ b/README.md @@ -47,5 +47,5 @@ - [x] 상품 생성 기능 - [x] 사다리 생성 기능 - [ ] 사다리 출력 기능 -- [ ] 사다리 타기 실행 기능 +- [x] 사다리 타기 실행 기능 - [ ] 사다리 타기 결과 출력 기능 diff --git a/src/main/java/domain/Gifts.java b/src/main/java/domain/Gifts.java index 903e9a266a..cfed8345c7 100644 --- a/src/main/java/domain/Gifts.java +++ b/src/main/java/domain/Gifts.java @@ -17,6 +17,11 @@ private void validateGiftsCount(List players) { } } + String getGiftName(int index) { + Gift gift = gifts.get(index); + return gift.name(); + } + static Gifts of(String... giftsName) { List gifts = Arrays.stream(giftsName).map(Gift::new).toList(); return new Gifts(gifts); diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index 460f595c1d..59c13629af 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -2,30 +2,53 @@ import java.util.List; import java.util.function.Supplier; +import java.util.stream.IntStream; public class LadderGame { private final Players players; private final Gifts gifts; private final Supplier ladderMakeStrategy; - private final int ladderHeight; + private final Integer ladderHeight; + + private final Ladder ladder; //Todo: 매개 변수 너무 많음 private LadderGame(Players players, Gifts gifts, Supplier ladderMakeStrategy, int ladderHeight) { - validateRequiredValues(players, gifts, ladderMakeStrategy); + validateRequiredValues(players, gifts, ladderMakeStrategy, ladderHeight); this.players = players; this.gifts = gifts; this.ladderMakeStrategy = ladderMakeStrategy; this.ladderHeight = ladderHeight; + List lines = IntStream.range(0, ladderHeight) + .mapToObj(value -> new Line(ladderMakeStrategy.get())) + .toList(); + this.ladder = new Ladder(lines); } - private void validateRequiredValues(Players players, Gifts gifts, Supplier ladderMakeStrategy) { - if (players == null || gifts == null || ladderMakeStrategy == null) { + private void validateRequiredValues(Players players, Gifts gifts, Supplier ladderMakeStrategy, + Integer ladderHeight) { + if (players == null || gifts == null || ladderMakeStrategy == null || ladderHeight == null) { throw new IllegalStateException("필수 값이 설정되지 않았습니다."); } } public LadderGameResults start(String operator) { - return new LadderGameResults(List.of(new LadderGameResult("a", "b"))); + validateOperator(operator); + LadderGameResult ladderGameResult = generateLadderGameResult(operator); + return LadderGameResults.of(ladderGameResult); + } + + private void validateOperator(String operator) { + if (players.notContains(operator)) { + throw new IllegalArgumentException("없는 참가자 입니다."); + } + } + + private LadderGameResult generateLadderGameResult(String operator) { + int startIndex = players.indexOf(operator); + int endIndex = ladder.climb(startIndex); + String giftName = gifts.getGiftName(endIndex); + return new LadderGameResult(operator, giftName); } public static final class LadderGameBuilder { diff --git a/src/main/java/domain/LadderGameResults.java b/src/main/java/domain/LadderGameResults.java index 4a82b2e3ac..bdabeb8017 100644 --- a/src/main/java/domain/LadderGameResults.java +++ b/src/main/java/domain/LadderGameResults.java @@ -1,5 +1,6 @@ package domain; +import java.util.HashSet; import java.util.List; public class LadderGameResults { @@ -8,4 +9,28 @@ public class LadderGameResults { public LadderGameResults(List ladderGameResults) { this.ladderGameResults = ladderGameResults; } + + public static LadderGameResults of(LadderGameResult... ladderGameResults) { + return new LadderGameResults(List.of(ladderGameResults)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + LadderGameResults that = (LadderGameResults) o; + boolean thatContainsThis = new HashSet<>(that.ladderGameResults).containsAll(ladderGameResults); + boolean thisContainsThat = new HashSet<>(ladderGameResults).containsAll(that.ladderGameResults); + return thatContainsThis && thisContainsThat; + } + + @Override + public int hashCode() { + return ladderGameResults != null ? ladderGameResults.hashCode() : 0; + } } diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index a2196c9b55..ec14ea17dc 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -27,6 +27,16 @@ private void validatePlayersCount(List players) { throw new IllegalStateException("참가자는 2명 이상 10명 이하여야 합니다."); } } + + boolean notContains(String playerName) { + return players.stream() + .noneMatch(player -> player.name().equals(playerName)); + } + + int indexOf(String playerName) { + List playerNames = players.stream().map(Player::name).toList(); + return playerNames.indexOf(playerName); + } static Players of(String... playerNames) { List players = Arrays.stream(playerNames).map(Player::new).toList(); From d39e18926bd0fe472e98a86c4f2a17cdd3aa248e Mon Sep 17 00:00:00 2001 From: robinjoon Date: Fri, 1 Mar 2024 23:58:45 +0900 Subject: [PATCH 39/76] =?UTF-8?q?test:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=EC=8B=9C=20=EA=B5=AC?= =?UTF-8?q?=EB=B6=84=EC=9E=90=EB=A1=9C=20=EC=9E=98=20=EC=9E=90=EB=A5=B4?= =?UTF-8?q?=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/PlayersInputView.java | 10 ++++++ src/test/java/view/PlayersInputViewTest.java | 36 ++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/view/PlayersInputView.java create mode 100644 src/test/java/view/PlayersInputViewTest.java diff --git a/src/main/java/view/PlayersInputView.java b/src/main/java/view/PlayersInputView.java new file mode 100644 index 0000000000..597d3ef255 --- /dev/null +++ b/src/main/java/view/PlayersInputView.java @@ -0,0 +1,10 @@ +package view; + +import java.util.Collections; +import java.util.List; + +public class PlayersInputView { + public static List getPlayerNames(String rawString) { + return Collections.emptyList(); + } +} diff --git a/src/test/java/view/PlayersInputViewTest.java b/src/test/java/view/PlayersInputViewTest.java new file mode 100644 index 0000000000..c3eb927557 --- /dev/null +++ b/src/test/java/view/PlayersInputViewTest.java @@ -0,0 +1,36 @@ +package view; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class PlayersInputViewTest { + + @Test + @DisplayName("참여자 이름을 구분자로 잘 자르는지 검증") + void getPlayerNames() { + List playerNames = PlayersInputView.getPlayerNames("robin,phobi,12345,test1"); + Assertions.assertThat(playerNames) + .containsExactlyElementsOf(List.of("robin", "phobi", "12345", "test1")); + } + + @Test + @DisplayName("연속된 구분자가 입력된 경우 실행 안되는지 검증") + void validateDuplicateSeparator() { + Assertions.assertThatThrownBy(() -> PlayersInputView.getPlayerNames("robin,,a")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("입력에 구분자가 연속으로 등장하면 안됩니다."); + } + + @ParameterizedTest + @ValueSource(strings = {",robin,phobi", "robin,phobi,"}) + @DisplayName("구분자로 시작하거나 끝나도록 입력된 경우 실행 안되는지 검증") + void validateStartOrEndWithSeparator(String input) { + Assertions.assertThatThrownBy(() -> PlayersInputView.getPlayerNames(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("입력이 구분자로 시작하거나 끝나면 안됩니다."); + } +} From 7a94a68a4fbad60e92b79726dfc1ead68eddd4b5 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:04:02 +0900 Subject: [PATCH 40/76] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/view/PlayersInputView.java | 30 ++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9bfd2ab813..12bfc897a5 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ # 기능 목록 -- [ ] 참가자 이름 입력 기능 +- [x] 참가자 이름 입력 기능 - [x] 참가자 생성 기능 - [ ] 사다리 높이 입력 기능 - [ ] 상품 이름 입력 기능 diff --git a/src/main/java/view/PlayersInputView.java b/src/main/java/view/PlayersInputView.java index 597d3ef255..7211f8af9a 100644 --- a/src/main/java/view/PlayersInputView.java +++ b/src/main/java/view/PlayersInputView.java @@ -1,10 +1,36 @@ package view; -import java.util.Collections; +import java.util.Arrays; import java.util.List; public class PlayersInputView { + private static final String SEPARATOR = ","; + public static List getPlayerNames(String rawString) { - return Collections.emptyList(); + validateSeparator(rawString); + return splitName(rawString); + } + + private static void validateSeparator(String playerNames) { + validateStarOrEndWithSeparator(playerNames); + validateDuplicateSeparator(playerNames); + } + + private static void validateStarOrEndWithSeparator(String playerNames) { + boolean startsWith = playerNames.startsWith(SEPARATOR); + boolean endsWith = playerNames.endsWith(SEPARATOR); + if (startsWith || endsWith) { + throw new IllegalArgumentException("입력이 구분자로 시작하거나 끝나면 안됩니다."); + } + } + + private static void validateDuplicateSeparator(String names) { + if (names.contains(SEPARATOR + SEPARATOR)) { + throw new IllegalArgumentException("입력에 구분자가 연속으로 등장하면 안됩니다."); + } + } + + private static List splitName(String playerNames) { + return Arrays.stream(playerNames.split(SEPARATOR)).toList(); } } From f1e0c5d733fd90d2a1e68ff489f500b0ea4598e1 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:09:02 +0900 Subject: [PATCH 41/76] =?UTF-8?q?test:=20=EC=83=81=ED=92=88=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=9E=85=EB=A0=A5=EC=8B=9C=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=EC=9E=90=EB=A1=9C=20=EC=9E=98=20=EC=9E=90=EB=A5=B4=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/GiftsInputView.java | 10 ++++++ src/test/java/view/GiftsInputViewTest.java | 36 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/view/GiftsInputView.java create mode 100644 src/test/java/view/GiftsInputViewTest.java diff --git a/src/main/java/view/GiftsInputView.java b/src/main/java/view/GiftsInputView.java new file mode 100644 index 0000000000..b2a01481f0 --- /dev/null +++ b/src/main/java/view/GiftsInputView.java @@ -0,0 +1,10 @@ +package view; + +import java.util.Collections; +import java.util.List; + +public class GiftsInputView { + public static List getGiftNames(String rawString) { + return Collections.emptyList(); + } +} diff --git a/src/test/java/view/GiftsInputViewTest.java b/src/test/java/view/GiftsInputViewTest.java new file mode 100644 index 0000000000..34b262260c --- /dev/null +++ b/src/test/java/view/GiftsInputViewTest.java @@ -0,0 +1,36 @@ +package view; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class GiftsInputViewTest { + + @Test + @DisplayName("상품 이름을 구분자로 잘 자르는지 검증") + void getGiftNames() { + List giftNames = GiftsInputView.getGiftNames("robin,phobi,12345,test1"); + Assertions.assertThat(giftNames) + .containsExactlyElementsOf(List.of("robin", "phobi", "12345", "test1")); + } + + @Test + @DisplayName("연속된 구분자가 입력된 경우 실행 안되는지 검증") + void validateDuplicateSeparator() { + Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("robin,,a")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("입력에 구분자가 연속으로 등장하면 안됩니다."); + } + + @ParameterizedTest + @ValueSource(strings = {",robin,phobi", "robin,phobi,"}) + @DisplayName("구분자로 시작하거나 끝나도록 입력된 경우 실행 안되는지 검증") + void validateStartOrEndWithSeparator(String input) { + Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("입력이 구분자로 시작하거나 끝나면 안됩니다."); + } +} From 2de28816427aff375397c3ab968e22f037ea550c Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:10:47 +0900 Subject: [PATCH 42/76] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=9E=85=EB=A0=A5=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/view/GiftsInputView.java | 30 ++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 12bfc897a5..b3cfebca82 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ - [x] 참가자 이름 입력 기능 - [x] 참가자 생성 기능 - [ ] 사다리 높이 입력 기능 -- [ ] 상품 이름 입력 기능 +- [x] 상품 이름 입력 기능 - [x] 상품 생성 기능 - [x] 사다리 생성 기능 - [ ] 사다리 출력 기능 diff --git a/src/main/java/view/GiftsInputView.java b/src/main/java/view/GiftsInputView.java index b2a01481f0..9bc44292d8 100644 --- a/src/main/java/view/GiftsInputView.java +++ b/src/main/java/view/GiftsInputView.java @@ -1,10 +1,36 @@ package view; -import java.util.Collections; +import java.util.Arrays; import java.util.List; public class GiftsInputView { + private static final String SEPARATOR = ","; + public static List getGiftNames(String rawString) { - return Collections.emptyList(); + validateSeparator(rawString); + return splitName(rawString); + } + + private static void validateSeparator(String giftNames) { + validateStarOrEndWithSeparator(giftNames); + validateDuplicateSeparator(giftNames); + } + + private static void validateStarOrEndWithSeparator(String giftNames) { + boolean startsWith = giftNames.startsWith(SEPARATOR); + boolean endsWith = giftNames.endsWith(SEPARATOR); + if (startsWith || endsWith) { + throw new IllegalArgumentException("입력이 구분자로 시작하거나 끝나면 안됩니다."); + } + } + + private static void validateDuplicateSeparator(String names) { + if (names.contains(SEPARATOR + SEPARATOR)) { + throw new IllegalArgumentException("입력에 구분자가 연속으로 등장하면 안됩니다."); + } + } + + private static List splitName(String giftNames) { + return Arrays.stream(giftNames.split(SEPARATOR)).toList(); } } From a63c4802bc878497f33a3cb7e3ccf3fa7b74536c Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:15:17 +0900 Subject: [PATCH 43/76] =?UTF-8?q?refactor:=20=EB=AC=B8=EC=9E=90=EC=97=B4?= =?UTF-8?q?=20=EC=9E=90=EB=A5=B4=EB=8A=94=20=EC=97=AD=ED=95=A0=20=EB=B3=84?= =?UTF-8?q?=EB=8F=84=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/GiftsInputView.java | 28 ++---------------- src/main/java/view/PlayersInputView.java | 28 ++---------------- src/main/java/view/StringSeparator.java | 36 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 52 deletions(-) create mode 100644 src/main/java/view/StringSeparator.java diff --git a/src/main/java/view/GiftsInputView.java b/src/main/java/view/GiftsInputView.java index 9bc44292d8..ab2816973e 100644 --- a/src/main/java/view/GiftsInputView.java +++ b/src/main/java/view/GiftsInputView.java @@ -1,36 +1,12 @@ package view; -import java.util.Arrays; import java.util.List; public class GiftsInputView { private static final String SEPARATOR = ","; public static List getGiftNames(String rawString) { - validateSeparator(rawString); - return splitName(rawString); - } - - private static void validateSeparator(String giftNames) { - validateStarOrEndWithSeparator(giftNames); - validateDuplicateSeparator(giftNames); - } - - private static void validateStarOrEndWithSeparator(String giftNames) { - boolean startsWith = giftNames.startsWith(SEPARATOR); - boolean endsWith = giftNames.endsWith(SEPARATOR); - if (startsWith || endsWith) { - throw new IllegalArgumentException("입력이 구분자로 시작하거나 끝나면 안됩니다."); - } - } - - private static void validateDuplicateSeparator(String names) { - if (names.contains(SEPARATOR + SEPARATOR)) { - throw new IllegalArgumentException("입력에 구분자가 연속으로 등장하면 안됩니다."); - } - } - - private static List splitName(String giftNames) { - return Arrays.stream(giftNames.split(SEPARATOR)).toList(); + StringSeparator separator = new StringSeparator(SEPARATOR); + return separator.splitName(rawString); } } diff --git a/src/main/java/view/PlayersInputView.java b/src/main/java/view/PlayersInputView.java index 7211f8af9a..dbd6a5ac8e 100644 --- a/src/main/java/view/PlayersInputView.java +++ b/src/main/java/view/PlayersInputView.java @@ -1,36 +1,12 @@ package view; -import java.util.Arrays; import java.util.List; public class PlayersInputView { private static final String SEPARATOR = ","; public static List getPlayerNames(String rawString) { - validateSeparator(rawString); - return splitName(rawString); - } - - private static void validateSeparator(String playerNames) { - validateStarOrEndWithSeparator(playerNames); - validateDuplicateSeparator(playerNames); - } - - private static void validateStarOrEndWithSeparator(String playerNames) { - boolean startsWith = playerNames.startsWith(SEPARATOR); - boolean endsWith = playerNames.endsWith(SEPARATOR); - if (startsWith || endsWith) { - throw new IllegalArgumentException("입력이 구분자로 시작하거나 끝나면 안됩니다."); - } - } - - private static void validateDuplicateSeparator(String names) { - if (names.contains(SEPARATOR + SEPARATOR)) { - throw new IllegalArgumentException("입력에 구분자가 연속으로 등장하면 안됩니다."); - } - } - - private static List splitName(String playerNames) { - return Arrays.stream(playerNames.split(SEPARATOR)).toList(); + StringSeparator separator = new StringSeparator(SEPARATOR); + return separator.splitName(rawString); } } diff --git a/src/main/java/view/StringSeparator.java b/src/main/java/view/StringSeparator.java new file mode 100644 index 0000000000..57c3c292c9 --- /dev/null +++ b/src/main/java/view/StringSeparator.java @@ -0,0 +1,36 @@ +package view; + +import java.util.Arrays; +import java.util.List; + +class StringSeparator { + private final String separator; + + StringSeparator(String separator) { + this.separator = separator; + } + + List splitName(String separatedString) { + validateSeparator(separatedString); + return Arrays.stream(separatedString.split(separator)).toList(); + } + + private void validateSeparator(String separatedString) { + validateStarOrEndWithSeparator(separatedString); + validateDuplicateSeparator(separatedString); + } + + private void validateStarOrEndWithSeparator(String separatedString) { + boolean startsWith = separatedString.startsWith(separator); + boolean endsWith = separatedString.endsWith(separator); + if (startsWith || endsWith) { + throw new IllegalArgumentException("입력이 구분자로 시작하거나 끝나면 안됩니다."); + } + } + + private void validateDuplicateSeparator(String separatedString) { + if (separatedString.contains(separator + separator)) { + throw new IllegalArgumentException("입력에 구분자가 연속으로 등장하면 안됩니다."); + } + } +} From 451ada113619e80ee73695512628ccd59d1fd297 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:22:08 +0900 Subject: [PATCH 44/76] =?UTF-8?q?test:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=20=EC=9E=85=EB=A0=A5=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/LadderHeightInputView.java | 7 +++++ .../java/view/LadderHeightInputViewTest.java | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/main/java/view/LadderHeightInputView.java create mode 100644 src/test/java/view/LadderHeightInputViewTest.java diff --git a/src/main/java/view/LadderHeightInputView.java b/src/main/java/view/LadderHeightInputView.java new file mode 100644 index 0000000000..e9e89e99c1 --- /dev/null +++ b/src/main/java/view/LadderHeightInputView.java @@ -0,0 +1,7 @@ +package view; + +public class LadderHeightInputView { + public static int getLadderHeight(String rawString) { + return 0; + } +} diff --git a/src/test/java/view/LadderHeightInputViewTest.java b/src/test/java/view/LadderHeightInputViewTest.java new file mode 100644 index 0000000000..53cb6b6963 --- /dev/null +++ b/src/test/java/view/LadderHeightInputViewTest.java @@ -0,0 +1,27 @@ +package view; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class LadderHeightInputViewTest { + + @ParameterizedTest + @ValueSource(strings = {"2", "20"}) + @DisplayName("정상적인 사다리 높이가 입력된 경우") + void getLadderHeight(String input) { + int ladderHeight = LadderHeightInputView.getLadderHeight(input); + Assertions.assertThat(ladderHeight) + .isEqualTo(Integer.valueOf(input)); + } + + @ParameterizedTest + @ValueSource(strings = {"ㅁ2", "a", " 2", "2 ", "a", "A"}) + @DisplayName("숫자가 아닌게 입력된 경우") + void validateLadderHeight(String input) { + Assertions.assertThatThrownBy(() -> LadderHeightInputView.getLadderHeight(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("숫자가 아닙니다."); + } +} From 25e65b44f7012f4714b950cd47a9af2bc605b455 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:23:39 +0900 Subject: [PATCH 45/76] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/view/LadderHeightInputView.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b3cfebca82..42bd5965ac 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ - [x] 참가자 이름 입력 기능 - [x] 참가자 생성 기능 -- [ ] 사다리 높이 입력 기능 +- [x] 사다리 높이 입력 기능 - [x] 상품 이름 입력 기능 - [x] 상품 생성 기능 - [x] 사다리 생성 기능 diff --git a/src/main/java/view/LadderHeightInputView.java b/src/main/java/view/LadderHeightInputView.java index e9e89e99c1..f2826eacfc 100644 --- a/src/main/java/view/LadderHeightInputView.java +++ b/src/main/java/view/LadderHeightInputView.java @@ -2,6 +2,10 @@ public class LadderHeightInputView { public static int getLadderHeight(String rawString) { - return 0; + try { + return Integer.parseInt(rawString); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자가 아닙니다."); + } } } From 12f263b228936d75fcce2812ecfdb4768ab114c9 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:29:15 +0900 Subject: [PATCH 46/76] =?UTF-8?q?test:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=20=EC=83=9D=EC=84=B1=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/LadderPrinter.java | 9 +++++++ src/test/java/view/LadderPrinterTest.java | 29 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/main/java/view/LadderPrinter.java create mode 100644 src/test/java/view/LadderPrinterTest.java diff --git a/src/main/java/view/LadderPrinter.java b/src/main/java/view/LadderPrinter.java new file mode 100644 index 0000000000..625cdcf562 --- /dev/null +++ b/src/main/java/view/LadderPrinter.java @@ -0,0 +1,9 @@ +package view; + +import java.util.List; + +public class LadderPrinter { + public static String from(List> rawLadder) { + return null; + } +} diff --git a/src/test/java/view/LadderPrinterTest.java b/src/test/java/view/LadderPrinterTest.java new file mode 100644 index 0000000000..e0e0f1edd0 --- /dev/null +++ b/src/test/java/view/LadderPrinterTest.java @@ -0,0 +1,29 @@ +package view; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class LadderPrinterTest { + @Test + @DisplayName("사다리 문자열 생성") + void ladderToString() { + List> rawLadder = makeRawLadder(); + String actual = LadderPrinter.from(rawLadder); + String expected = " | |-----|\n".repeat(5); + expected = expected.substring(0, expected.length() - 1); + Assertions.assertThat(actual) + .isEqualTo(expected); + } + + private static List> makeRawLadder() { + return List.of( + List.of(false, true), + List.of(false, true), + List.of(false, true), + List.of(false, true), + List.of(false, true) + ); + } +} From bbe2d23e4eb9b19f6d65c6e83194169c52de68af Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:31:22 +0900 Subject: [PATCH 47/76] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/LadderPrinter.java | 5 ++++- src/main/java/view/LinePrinter.java | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/main/java/view/LinePrinter.java diff --git a/src/main/java/view/LadderPrinter.java b/src/main/java/view/LadderPrinter.java index 625cdcf562..6e9b4a1373 100644 --- a/src/main/java/view/LadderPrinter.java +++ b/src/main/java/view/LadderPrinter.java @@ -1,9 +1,12 @@ package view; import java.util.List; +import java.util.stream.Collectors; public class LadderPrinter { public static String from(List> rawLadder) { - return null; + return rawLadder.stream() + .map(LinePrinter::from) + .collect(Collectors.joining("\n")); } } diff --git a/src/main/java/view/LinePrinter.java b/src/main/java/view/LinePrinter.java new file mode 100644 index 0000000000..4474de2674 --- /dev/null +++ b/src/main/java/view/LinePrinter.java @@ -0,0 +1,19 @@ +package view; + +import java.util.List; +import java.util.stream.Collectors; + +public class LinePrinter { + static String from(List canGoRights) { + String rawRowString = canGoRights.stream().map(LinePrinter::makeBridge) + .collect(Collectors.joining("|")); + return " |%s|".formatted(rawRowString); + } + + private static String makeBridge(Boolean aBoolean) { + if (aBoolean) { + return "-----"; + } + return " "; + } +} From 577bff0911c94c921133c98905fb8ed7a25f4f8e Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:34:40 +0900 Subject: [PATCH 48/76] =?UTF-8?q?test:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=20=EC=83=9D=EC=84=B1=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/PlayersPrinter.java | 9 +++++++++ src/test/java/view/PlayersPrinterTest.java | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/main/java/view/PlayersPrinter.java create mode 100644 src/test/java/view/PlayersPrinterTest.java diff --git a/src/main/java/view/PlayersPrinter.java b/src/main/java/view/PlayersPrinter.java new file mode 100644 index 0000000000..3d021c742a --- /dev/null +++ b/src/main/java/view/PlayersPrinter.java @@ -0,0 +1,9 @@ +package view; + +import java.util.List; + +public class PlayersPrinter { + public static String from(List rawPlayerNames) { + return null; + } +} diff --git a/src/test/java/view/PlayersPrinterTest.java b/src/test/java/view/PlayersPrinterTest.java new file mode 100644 index 0000000000..aecbfab954 --- /dev/null +++ b/src/test/java/view/PlayersPrinterTest.java @@ -0,0 +1,18 @@ +package view; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PlayersPrinterTest { + @Test + @DisplayName("이름 문자열 생성") + void namesToString() { + List rawNames = List.of("a", "aa", "aaa", "aaaa", "aaaaa"); + String actual = PlayersPrinter.from(rawNames); + String expected = " a aa aaa aaaa aaaaa"; + Assertions.assertThat(actual).isEqualTo(expected); + } + +} From 87f62171b1eb21f9f101aca8ed35bd34aaee21e3 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:36:18 +0900 Subject: [PATCH 49/76] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/PlayerPrinter.java | 13 +++++++++++++ src/main/java/view/PlayersPrinter.java | 5 ++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/main/java/view/PlayerPrinter.java diff --git a/src/main/java/view/PlayerPrinter.java b/src/main/java/view/PlayerPrinter.java new file mode 100644 index 0000000000..a6799d1d55 --- /dev/null +++ b/src/main/java/view/PlayerPrinter.java @@ -0,0 +1,13 @@ +package view; + +public class PlayerPrinter { + static final int MAX_NAME_LENGTH = 5; + + static String from(String name) { + if (name.length() < MAX_NAME_LENGTH) { + name = name + " "; + } + int nameStringLength = name.length(); + return " ".repeat(MAX_NAME_LENGTH - nameStringLength) + name; + } +} diff --git a/src/main/java/view/PlayersPrinter.java b/src/main/java/view/PlayersPrinter.java index 3d021c742a..0821c0818a 100644 --- a/src/main/java/view/PlayersPrinter.java +++ b/src/main/java/view/PlayersPrinter.java @@ -1,9 +1,12 @@ package view; import java.util.List; +import java.util.stream.Collectors; public class PlayersPrinter { public static String from(List rawPlayerNames) { - return null; + return rawPlayerNames.stream() + .map(PlayerPrinter::from) + .collect(Collectors.joining(" ")); } } From 0cdcd7009da5795a5549a145736ef17b6989ecb6 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:37:53 +0900 Subject: [PATCH 50/76] =?UTF-8?q?test:=20=EC=83=81=ED=92=88=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=20=EC=83=9D=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/GiftsPrinter.java | 9 +++++++++ src/test/java/view/GiftsPrinterTest.java | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/main/java/view/GiftsPrinter.java create mode 100644 src/test/java/view/GiftsPrinterTest.java diff --git a/src/main/java/view/GiftsPrinter.java b/src/main/java/view/GiftsPrinter.java new file mode 100644 index 0000000000..a602391c2b --- /dev/null +++ b/src/main/java/view/GiftsPrinter.java @@ -0,0 +1,9 @@ +package view; + +import java.util.List; + +public class GiftsPrinter { + public static String from(List rawNames) { + return null; + } +} diff --git a/src/test/java/view/GiftsPrinterTest.java b/src/test/java/view/GiftsPrinterTest.java new file mode 100644 index 0000000000..34a56c9c95 --- /dev/null +++ b/src/test/java/view/GiftsPrinterTest.java @@ -0,0 +1,18 @@ +package view; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class GiftsPrinterTest { + @Test + @DisplayName("상품 문자열 생성") + void namesToString() { + List rawNames = List.of("a", "aa", "aaa", "aaaa", "aaaaa"); + String actual = GiftsPrinter.from(rawNames); + String expected = " a aa aaa aaaa aaaaa"; + Assertions.assertThat(actual).isEqualTo(expected); + } + +} From ff6d8659284cc9dc679daab95ef70148a58f08da Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 00:39:43 +0900 Subject: [PATCH 51/76] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/GiftPrinter.java | 13 +++++++++++++ src/main/java/view/GiftsPrinter.java | 7 +++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 src/main/java/view/GiftPrinter.java diff --git a/src/main/java/view/GiftPrinter.java b/src/main/java/view/GiftPrinter.java new file mode 100644 index 0000000000..04d0e4a7d3 --- /dev/null +++ b/src/main/java/view/GiftPrinter.java @@ -0,0 +1,13 @@ +package view; + +public class GiftPrinter { + static final int MAX_NAME_LENGTH = 5; + + static String from(String name) { + if (name.length() < MAX_NAME_LENGTH) { + name = name + " "; + } + int nameStringLength = name.length(); + return " ".repeat(MAX_NAME_LENGTH - nameStringLength) + name; + } +} diff --git a/src/main/java/view/GiftsPrinter.java b/src/main/java/view/GiftsPrinter.java index a602391c2b..5853c522bd 100644 --- a/src/main/java/view/GiftsPrinter.java +++ b/src/main/java/view/GiftsPrinter.java @@ -1,9 +1,12 @@ package view; import java.util.List; +import java.util.stream.Collectors; public class GiftsPrinter { - public static String from(List rawNames) { - return null; + public static String from(List rawGiftNames) { + return rawGiftNames.stream() + .map(GiftPrinter::from) + .collect(Collectors.joining(" ")); } } From fe2d5e7e2f3543db7811710ce6fd7c9023e169b6 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 01:04:01 +0900 Subject: [PATCH 52/76] =?UTF-8?q?refactor:=20LadderGameResults=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20Record=20?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/LadderGame.java | 2 ++ src/main/java/{domain => dto}/LadderGameResult.java | 2 +- .../java/{domain => dto}/LadderGameResults.java | 13 ++----------- src/test/java/domain/LadderGameTest.java | 2 ++ 4 files changed, 7 insertions(+), 12 deletions(-) rename src/main/java/{domain => dto}/LadderGameResult.java (81%) rename src/main/java/{domain => dto}/LadderGameResults.java (66%) diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index 59c13629af..d85538a77d 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -1,5 +1,7 @@ package domain; +import dto.LadderGameResult; +import dto.LadderGameResults; import java.util.List; import java.util.function.Supplier; import java.util.stream.IntStream; diff --git a/src/main/java/domain/LadderGameResult.java b/src/main/java/dto/LadderGameResult.java similarity index 81% rename from src/main/java/domain/LadderGameResult.java rename to src/main/java/dto/LadderGameResult.java index eaabb9b182..653ea9922a 100644 --- a/src/main/java/domain/LadderGameResult.java +++ b/src/main/java/dto/LadderGameResult.java @@ -1,4 +1,4 @@ -package domain; +package dto; public record LadderGameResult(String playerName, String giftName) { } diff --git a/src/main/java/domain/LadderGameResults.java b/src/main/java/dto/LadderGameResults.java similarity index 66% rename from src/main/java/domain/LadderGameResults.java rename to src/main/java/dto/LadderGameResults.java index bdabeb8017..71429aad49 100644 --- a/src/main/java/domain/LadderGameResults.java +++ b/src/main/java/dto/LadderGameResults.java @@ -1,14 +1,9 @@ -package domain; +package dto; import java.util.HashSet; import java.util.List; -public class LadderGameResults { - private final List ladderGameResults; - - public LadderGameResults(List ladderGameResults) { - this.ladderGameResults = ladderGameResults; - } +public record LadderGameResults(List ladderGameResults) { public static LadderGameResults of(LadderGameResult... ladderGameResults) { return new LadderGameResults(List.of(ladderGameResults)); @@ -29,8 +24,4 @@ public boolean equals(Object o) { return thatContainsThis && thisContainsThat; } - @Override - public int hashCode() { - return ladderGameResults != null ? ladderGameResults.hashCode() : 0; - } } diff --git a/src/test/java/domain/LadderGameTest.java b/src/test/java/domain/LadderGameTest.java index 957a63c36d..62a3a9338d 100644 --- a/src/test/java/domain/LadderGameTest.java +++ b/src/test/java/domain/LadderGameTest.java @@ -1,6 +1,8 @@ package domain; import domain.LadderGame.LadderGameBuilder; +import dto.LadderGameResult; +import dto.LadderGameResults; import java.util.List; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; From 2fc4743bc01a7e3a0a4f2cfc643c147d4b11c0a8 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 01:06:08 +0900 Subject: [PATCH 53/76] =?UTF-8?q?refactor:=20LadderGame=EC=9D=98=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/LadderGame.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index d85538a77d..f6426b08b5 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -9,18 +9,12 @@ public class LadderGame { private final Players players; private final Gifts gifts; - private final Supplier ladderMakeStrategy; - private final Integer ladderHeight; - private final Ladder ladder; - //Todo: 매개 변수 너무 많음 private LadderGame(Players players, Gifts gifts, Supplier ladderMakeStrategy, int ladderHeight) { validateRequiredValues(players, gifts, ladderMakeStrategy, ladderHeight); this.players = players; this.gifts = gifts; - this.ladderMakeStrategy = ladderMakeStrategy; - this.ladderHeight = ladderHeight; List lines = IntStream.range(0, ladderHeight) .mapToObj(value -> new Line(ladderMakeStrategy.get())) .toList(); From edcbc69836a7798ceb20e0c61fb91a8b41775f29 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 01:34:29 +0900 Subject: [PATCH 54/76] =?UTF-8?q?test:=20=EB=9E=9C=EB=8D=A4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=83=9D=EC=84=B1=EB=90=9C=20Line=EC=9D=B4=20?= =?UTF-8?q?=EC=9C=A0=ED=9A=A8=ED=95=9C=EC=A7=80=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/RandomLadderMakeStrategy.java | 11 +++++++++++ .../domain/RandomLadderMakeStrategyTest.java | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/main/java/domain/RandomLadderMakeStrategy.java create mode 100644 src/test/java/domain/RandomLadderMakeStrategyTest.java diff --git a/src/main/java/domain/RandomLadderMakeStrategy.java b/src/main/java/domain/RandomLadderMakeStrategy.java new file mode 100644 index 0000000000..fd558ed537 --- /dev/null +++ b/src/main/java/domain/RandomLadderMakeStrategy.java @@ -0,0 +1,11 @@ +package domain; + +public class RandomLadderMakeStrategy { + public RandomLadderMakeStrategy(int lineSize) { + + } + + public Boolean[] makeLine() { + return new Boolean[]{}; + } +} diff --git a/src/test/java/domain/RandomLadderMakeStrategyTest.java b/src/test/java/domain/RandomLadderMakeStrategyTest.java new file mode 100644 index 0000000000..2942a9ef12 --- /dev/null +++ b/src/test/java/domain/RandomLadderMakeStrategyTest.java @@ -0,0 +1,19 @@ +package domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class RandomLadderMakeStrategyTest { + + @Test + @DisplayName("|-----|----- 인 Point로 Line이 생성되지 않는지 확인") + void makeLine() { + RandomLadderMakeStrategy randomLadderMakeStrategy = new RandomLadderMakeStrategy(5); + Boolean[] booleans = randomLadderMakeStrategy.makeLine(); + Assertions.assertThat(booleans.length) + .isEqualTo(5); + Assertions.assertThat(booleans[booleans.length - 1]) + .isFalse(); + } +} From bed688b436b4e9372cf91cb903055b0d108523e6 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 01:38:34 +0900 Subject: [PATCH 55/76] =?UTF-8?q?feat:=20=EB=9E=9C=EB=8D=A4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20Line=20=EC=9D=84=20=EC=83=9D=EC=84=B1=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=A0=84=EB=9E=B5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/RandomLadderMakeStrategy.java | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/RandomLadderMakeStrategy.java b/src/main/java/domain/RandomLadderMakeStrategy.java index fd558ed537..791a24b0c2 100644 --- a/src/main/java/domain/RandomLadderMakeStrategy.java +++ b/src/main/java/domain/RandomLadderMakeStrategy.java @@ -1,11 +1,43 @@ package domain; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + public class RandomLadderMakeStrategy { - public RandomLadderMakeStrategy(int lineSize) { + private final int lineSize; + public RandomLadderMakeStrategy(int lineSize) { + this.lineSize = lineSize; } public Boolean[] makeLine() { - return new Boolean[]{}; + return generateBridges(new Random()); + } + + private Boolean[] generateBridges(Random random) { + List randomBooleans = IntStream.range(0, lineSize - 1) + .mapToObj(value -> random.nextBoolean()) + .collect(Collectors.toList()); + fixInvalidBridges(randomBooleans); + randomBooleans.add(false); + return randomBooleans.toArray(Boolean[]::new); + } + + private void fixInvalidBridges(List rawBridges) { + for (int index = 1; index < lineSize - 1; index++) { + fixIfNeed(rawBridges, index); + } + } + + private void fixIfNeed(List rawBridges, int index) { + if (isBridgeInARow(rawBridges, index)) { + rawBridges.set(index, false); + } + } + + private boolean isBridgeInARow(List rawBridges, int index) { + return rawBridges.get(index) && rawBridges.get(index - 1); } } From e819163b8c013c8ce7340b61f7e991c0a0334080 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 01:44:13 +0900 Subject: [PATCH 56/76] =?UTF-8?q?refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EC=A0=81=EC=A0=88=ED=95=98=EA=B2=8C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/LadderGame.java | 6 +++--- ...mLadderMakeStrategy.java => RandomLineMakeStrategy.java} | 4 ++-- ...akeStrategyTest.java => RandomLineMakeStrategyTest.java} | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) rename src/main/java/domain/{RandomLadderMakeStrategy.java => RandomLineMakeStrategy.java} (92%) rename src/test/java/domain/{RandomLadderMakeStrategyTest.java => RandomLineMakeStrategyTest.java} (68%) diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index f6426b08b5..c9541fb3ec 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -11,12 +11,12 @@ public class LadderGame { private final Gifts gifts; private final Ladder ladder; - private LadderGame(Players players, Gifts gifts, Supplier ladderMakeStrategy, int ladderHeight) { - validateRequiredValues(players, gifts, ladderMakeStrategy, ladderHeight); + private LadderGame(Players players, Gifts gifts, Supplier lineMakeStrategy, int ladderHeight) { + validateRequiredValues(players, gifts, lineMakeStrategy, ladderHeight); this.players = players; this.gifts = gifts; List lines = IntStream.range(0, ladderHeight) - .mapToObj(value -> new Line(ladderMakeStrategy.get())) + .mapToObj(value -> new Line(lineMakeStrategy.get())) .toList(); this.ladder = new Ladder(lines); } diff --git a/src/main/java/domain/RandomLadderMakeStrategy.java b/src/main/java/domain/RandomLineMakeStrategy.java similarity index 92% rename from src/main/java/domain/RandomLadderMakeStrategy.java rename to src/main/java/domain/RandomLineMakeStrategy.java index 791a24b0c2..934f28cce7 100644 --- a/src/main/java/domain/RandomLadderMakeStrategy.java +++ b/src/main/java/domain/RandomLineMakeStrategy.java @@ -5,10 +5,10 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -public class RandomLadderMakeStrategy { +public class RandomLineMakeStrategy { private final int lineSize; - public RandomLadderMakeStrategy(int lineSize) { + public RandomLineMakeStrategy(int lineSize) { this.lineSize = lineSize; } diff --git a/src/test/java/domain/RandomLadderMakeStrategyTest.java b/src/test/java/domain/RandomLineMakeStrategyTest.java similarity index 68% rename from src/test/java/domain/RandomLadderMakeStrategyTest.java rename to src/test/java/domain/RandomLineMakeStrategyTest.java index 2942a9ef12..be93b3854b 100644 --- a/src/test/java/domain/RandomLadderMakeStrategyTest.java +++ b/src/test/java/domain/RandomLineMakeStrategyTest.java @@ -4,13 +4,13 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -class RandomLadderMakeStrategyTest { +class RandomLineMakeStrategyTest { @Test @DisplayName("|-----|----- 인 Point로 Line이 생성되지 않는지 확인") void makeLine() { - RandomLadderMakeStrategy randomLadderMakeStrategy = new RandomLadderMakeStrategy(5); - Boolean[] booleans = randomLadderMakeStrategy.makeLine(); + RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(5); + Boolean[] booleans = randomLineMakeStrategy.makeLine(); Assertions.assertThat(booleans.length) .isEqualTo(5); Assertions.assertThat(booleans[booleans.length - 1]) From 01a40dffd2fdfb9eb3002c9c38205f0297f56108 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 02:00:18 +0900 Subject: [PATCH 57/76] =?UTF-8?q?test:=20=EC=9D=BC=EC=A0=95=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=EA=B9=8C=EC=A7=80=EB=A7=8C=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EC=9D=B4=20=EC=9E=AC=EC=8B=9C=EB=8F=84=20=EB=90=98=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/util/RetryHelper.java | 12 ++++++++++ src/test/java/util/RetryHelperTest.java | 30 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/util/RetryHelper.java create mode 100644 src/test/java/util/RetryHelperTest.java diff --git a/src/main/java/util/RetryHelper.java b/src/main/java/util/RetryHelper.java new file mode 100644 index 0000000000..eabc6efa1a --- /dev/null +++ b/src/main/java/util/RetryHelper.java @@ -0,0 +1,12 @@ +package util; + +import java.util.function.Supplier; + +class RetryHelper { + public RetryHelper(int maxRetryCount) { + } + + public E retry(Supplier supplier) { + return null; + } +} diff --git a/src/test/java/util/RetryHelperTest.java b/src/test/java/util/RetryHelperTest.java new file mode 100644 index 0000000000..393f09872b --- /dev/null +++ b/src/test/java/util/RetryHelperTest.java @@ -0,0 +1,30 @@ +package util; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class RetryHelperTest { + + @Test + @DisplayName("최대 재시도 횟수까지만 재시도 하는지 검증") + void retry() { + int maxRetryCount = 10; + int retryCount = retrySomeLogic(maxRetryCount); + Assertions.assertThat(retryCount) + .isEqualTo(maxRetryCount); + } + + private static int retrySomeLogic(int maxRetryCount) { + RetryHelper retryHelper = new RetryHelper(maxRetryCount); + int[] count = new int[]{-1}; + retryHelper.retry(() -> { + if (count[0] <= maxRetryCount * 2) { + count[0]++; + throw new RuntimeException(); + } + return 1; + }); + return count[0]; + } +} From 8e843cf59351354ff5299faa255ef879b5903845 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 02:01:00 +0900 Subject: [PATCH 58/76] =?UTF-8?q?feat:=20=EC=9D=BC=EC=A0=95=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=EA=B9=8C=EC=A7=80=EB=A7=8C=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EC=9D=B4=20=EC=9E=AC=EC=8B=9C=EB=8F=84=20=EB=90=98=EA=B2=8C=20?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/util/RetryHelper.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/util/RetryHelper.java b/src/main/java/util/RetryHelper.java index eabc6efa1a..ebde3901c2 100644 --- a/src/main/java/util/RetryHelper.java +++ b/src/main/java/util/RetryHelper.java @@ -3,10 +3,29 @@ import java.util.function.Supplier; class RetryHelper { + + private final int maxRetryCount; + private int retryCount = -1; + public RetryHelper(int maxRetryCount) { + this.maxRetryCount = maxRetryCount; } public E retry(Supplier supplier) { - return null; + E result = null; + while (result == null && retryCount < maxRetryCount) { + result = useSupplier(supplier); + } + return result; + } + + private E useSupplier(Supplier supplier) { + retryCount++; + try { + return supplier.get(); + } catch (Exception e) { + System.out.println(e.getMessage()); + return null; + } } } From 060ad0c6e1384ca23419e2692c1a86623deeb9fb Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 02:30:26 +0900 Subject: [PATCH 59/76] =?UTF-8?q?fix:=20LadderPrinter=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/LinePrinter.java | 2 +- src/test/java/view/LadderPrinterTest.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/view/LinePrinter.java b/src/main/java/view/LinePrinter.java index 4474de2674..4878a1a736 100644 --- a/src/main/java/view/LinePrinter.java +++ b/src/main/java/view/LinePrinter.java @@ -5,7 +5,7 @@ public class LinePrinter { static String from(List canGoRights) { - String rawRowString = canGoRights.stream().map(LinePrinter::makeBridge) + String rawRowString = canGoRights.stream().limit(canGoRights.size() - 1).map(LinePrinter::makeBridge) .collect(Collectors.joining("|")); return " |%s|".formatted(rawRowString); } diff --git a/src/test/java/view/LadderPrinterTest.java b/src/test/java/view/LadderPrinterTest.java index e0e0f1edd0..44c8fb8b4f 100644 --- a/src/test/java/view/LadderPrinterTest.java +++ b/src/test/java/view/LadderPrinterTest.java @@ -19,11 +19,11 @@ void ladderToString() { private static List> makeRawLadder() { return List.of( - List.of(false, true), - List.of(false, true), - List.of(false, true), - List.of(false, true), - List.of(false, true) + List.of(false, true, false), + List.of(false, true, false), + List.of(false, true, false), + List.of(false, true, false), + List.of(false, true, false) ); } } From fc41f53e0391499d0f24873d92a950511b65666f Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 02:32:12 +0900 Subject: [PATCH 60/76] =?UTF-8?q?feat:=20Main=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- src/main/java/Main.java | 38 +++++++++++++++++++ src/main/java/domain/Ladder.java | 6 +++ src/main/java/domain/LadderGame.java | 4 ++ src/main/java/domain/Line.java | 6 +++ src/main/java/util/RetryHelper.java | 3 +- src/main/java/view/InputView.java | 16 ++++++++ .../java/view/LadderGameResultPrinter.java | 9 +++++ .../java/view/LadderGameResultsPrinter.java | 12 ++++++ src/main/java/view/OutputView.java | 26 +++++++++++++ 10 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 src/main/java/Main.java create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/LadderGameResultPrinter.java create mode 100644 src/main/java/view/LadderGameResultsPrinter.java create mode 100644 src/main/java/view/OutputView.java diff --git a/README.md b/README.md index 42bd5965ac..dfb16d4087 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,6 @@ - [x] 상품 이름 입력 기능 - [x] 상품 생성 기능 - [x] 사다리 생성 기능 -- [ ] 사다리 출력 기능 +- [x] 사다리 출력 기능 - [x] 사다리 타기 실행 기능 -- [ ] 사다리 타기 결과 출력 기능 +- [x] 사다리 타기 결과 출력 기능 diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000000..fec3ba4697 --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,38 @@ +import domain.LadderGame; +import domain.LadderGame.LadderGameBuilder; +import domain.RandomLineMakeStrategy; +import dto.LadderGameResults; +import java.util.List; +import util.RetryHelper; +import view.GiftsInputView; +import view.InputView; +import view.LadderHeightInputView; +import view.OutputView; +import view.PlayersInputView; + +public class Main { + public static void main(String[] args) { + RetryHelper retryHelper = new RetryHelper(10); + OutputView.print("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + List playerNames = retryHelper.retry(() -> PlayersInputView.getPlayerNames(InputView.getInput())); + OutputView.print("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); + List giftNames = retryHelper.retry(() -> GiftsInputView.getGiftNames(InputView.getInput())); + OutputView.print("최대 사다리 높이는 몇 개인가요?"); + Integer ladderHeight = retryHelper.retry(() -> LadderHeightInputView.getLadderHeight(InputView.getInput())); + RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(playerNames.size()); + LadderGame ladderGame = LadderGameBuilder.builder() + .players(playerNames.toArray(String[]::new)) + .gifts(giftNames.toArray(String[]::new)) + .ladderHeight(ladderHeight) + .ladderMakeStrategy(randomLineMakeStrategy::makeLine) + .build(); + OutputView.printPlayers(playerNames); + OutputView.printLadder(ladderGame.rawLadder()); + OutputView.printGifts(giftNames); + LadderGameResults ladderGameResults = retryHelper.retry(() -> { + String operator = InputView.getInput(); + return ladderGame.start(operator); + }); + OutputView.printLadderGameResults(ladderGameResults); + } +} diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index 8028fb1474..4f5bbeeea1 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -32,4 +32,10 @@ public int climb(int startIndex) { } return endIndex; } + + List> getRawLadder() { + return lines.stream() + .map(Line::getRawLine) + .toList(); + } } diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index c9541fb3ec..cb7180d3c2 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -84,4 +84,8 @@ public LadderGame build() { return new LadderGame(players, gifts, ladderMakeStrategy, ladderHeight); } } + + public List> rawLadder() { + return ladder.getRawLadder(); + } } diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 3a1d1f42ee..3061332861 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -6,6 +6,7 @@ class Line { private final List points; + private final Boolean[] canGoRights; Line(Boolean... canGoRights) { validateLineSize(canGoRights); @@ -14,6 +15,7 @@ class Line { addFirstPoint(points, canGoRights); addRemainPoints(points, canGoRights); this.points = Collections.unmodifiableList(points); + this.canGoRights = canGoRights; } private void validateLineSize(Boolean[] canGoRights) { @@ -80,4 +82,8 @@ int move(int startIndex) { Point next = start.next(); return next.index(); } + + List getRawLine() { + return List.of(canGoRights); + } } diff --git a/src/main/java/util/RetryHelper.java b/src/main/java/util/RetryHelper.java index ebde3901c2..7ea1c36219 100644 --- a/src/main/java/util/RetryHelper.java +++ b/src/main/java/util/RetryHelper.java @@ -2,7 +2,7 @@ import java.util.function.Supplier; -class RetryHelper { +public class RetryHelper { private final int maxRetryCount; private int retryCount = -1; @@ -16,6 +16,7 @@ public E retry(Supplier supplier) { while (result == null && retryCount < maxRetryCount) { result = useSupplier(supplier); } + retryCount = -1; return result; } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000000..022d8ad5aa --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,16 @@ +package view; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class InputView { + public static String getInput() { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); + try { + return bufferedReader.readLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/view/LadderGameResultPrinter.java b/src/main/java/view/LadderGameResultPrinter.java new file mode 100644 index 0000000000..e57ac1f70a --- /dev/null +++ b/src/main/java/view/LadderGameResultPrinter.java @@ -0,0 +1,9 @@ +package view; + +import dto.LadderGameResult; + +public class LadderGameResultPrinter { + static String from(LadderGameResult ladderGameResult) { + return "%s : %s".formatted(ladderGameResult.playerName(), ladderGameResult.giftName()); + } +} diff --git a/src/main/java/view/LadderGameResultsPrinter.java b/src/main/java/view/LadderGameResultsPrinter.java new file mode 100644 index 0000000000..0d554763f3 --- /dev/null +++ b/src/main/java/view/LadderGameResultsPrinter.java @@ -0,0 +1,12 @@ +package view; + +import dto.LadderGameResults; +import java.util.stream.Collectors; + +public class LadderGameResultsPrinter { + static String from(LadderGameResults ladderGameResults) { + return ladderGameResults.ladderGameResults().stream() + .map(LadderGameResultPrinter::from) + .collect(Collectors.joining("\n")); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000000..f752b5790a --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,26 @@ +package view; + +import dto.LadderGameResults; +import java.util.List; + +public class OutputView { + public static void print(String string) { + System.out.println(string); + } + + public static void printPlayers(List playerNames) { + print(PlayersPrinter.from(playerNames)); + } + + public static void printLadder(List> rawLadder) { + print(LadderPrinter.from(rawLadder)); + } + + public static void printGifts(List giftNames) { + print(GiftsPrinter.from(giftNames)); + } + + public static void printLadderGameResults(LadderGameResults ladderGameResults) { + print(LadderGameResultsPrinter.from(ladderGameResults)); + } +} From 9c1ae9516f8268c2b77e46078211630bb573d8c2 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 14:15:12 +0900 Subject: [PATCH 61/76] =?UTF-8?q?test:=20=EC=B0=B8=EC=97=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=EC=97=90=20=EB=A7=9E=EB=8A=94=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=A7=8C=20=EC=9E=85=EB=A0=A5=EB=90=98=EB=8A=94=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/view/PlayersInputViewTest.java | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/test/java/view/PlayersInputViewTest.java b/src/test/java/view/PlayersInputViewTest.java index c3eb927557..8dbae6d067 100644 --- a/src/test/java/view/PlayersInputViewTest.java +++ b/src/test/java/view/PlayersInputViewTest.java @@ -33,4 +33,30 @@ void validateStartOrEndWithSeparator(String input) { .isInstanceOf(IllegalArgumentException.class) .hasMessage("입력이 구분자로 시작하거나 끝나면 안됩니다."); } + + @Test + @DisplayName("참가자 이름 길이 검증") + void validatePlayerNameLength() { + Assertions.assertThatThrownBy(() -> PlayersInputView.getPlayerNames("123456,aa")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("참가자 이름은 1글자 이상 5글자 이하여야 합니다."); + } + + @ParameterizedTest + @ValueSource(strings = {"!,zbc", "zbc, ", "zvb,가나다", "zbv,abc "}) + @DisplayName("참가자 이름 구성 문자 검증") + void validatePlayerNameCharacter(String input) { + Assertions.assertThatThrownBy(() -> PlayersInputView.getPlayerNames(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("참가자 이름은 알파벳 대소문자와 숫자만으로 이루어져야 합니다."); + } + + @ParameterizedTest + @ValueSource(strings = {"all,aa"}) + @DisplayName("참가자 이름 블랙리스트 검증") + void validateNameBlackList(String input) { + Assertions.assertThatThrownBy(() -> PlayersInputView.getPlayerNames(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("참가자 이름은 all이 될 수 없습니다."); + } } From 021dbb8733da374663ecedd4b40002598558a8da Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 14:15:32 +0900 Subject: [PATCH 62/76] =?UTF-8?q?feat:=20=EC=B0=B8=EC=97=AC=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=EC=97=90=20=EB=A7=9E=EB=8A=94=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=A7=8C=20=EC=9E=85=EB=A0=A5=EB=90=98=EB=8A=94=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/PlayersInputView.java | 31 +++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/view/PlayersInputView.java b/src/main/java/view/PlayersInputView.java index dbd6a5ac8e..446d430017 100644 --- a/src/main/java/view/PlayersInputView.java +++ b/src/main/java/view/PlayersInputView.java @@ -1,12 +1,41 @@ package view; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class PlayersInputView { private static final String SEPARATOR = ","; + private static final Pattern pattern = Pattern.compile(".*[^a-zA-Z0-9].*"); + public static List getPlayerNames(String rawString) { StringSeparator separator = new StringSeparator(SEPARATOR); - return separator.splitName(rawString); + List splitName = separator.splitName(rawString); + for (String name : splitName) { + validateNameLength(name); + validateNameCharacter(name); + validateNameBlackList(name); + } + return splitName; + } + + private static void validateNameLength(String name) { + if (name == null || name.isEmpty() || name.length() > 5) { + throw new IllegalArgumentException("참가자 이름은 1글자 이상 5글자 이하여야 합니다."); + } + } + + private static void validateNameCharacter(String name) { + Matcher matcher = pattern.matcher(name); + if (matcher.matches()) { + throw new IllegalArgumentException("참가자 이름은 알파벳 대소문자와 숫자만으로 이루어져야 합니다."); + } + } + + private static void validateNameBlackList(String name) { + if (name.equals("all")) { + throw new IllegalArgumentException("참가자 이름은 all이 될 수 없습니다."); + } } } From ffed2ffd2e199245ffcccacac57aaab031ba6c8d Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 14:26:01 +0900 Subject: [PATCH 63/76] =?UTF-8?q?test:=20=EC=83=81=ED=92=88=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=8B=9C=20=EC=83=81=ED=92=88=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=EC=9D=B4=20=EC=A1=B0=EA=B1=B4=EC=97=90=20=EB=A7=9E=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/GiftsInputView.java | 5 +++++ src/test/java/view/GiftsInputViewTest.java | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/view/GiftsInputView.java b/src/main/java/view/GiftsInputView.java index ab2816973e..304252f0b2 100644 --- a/src/main/java/view/GiftsInputView.java +++ b/src/main/java/view/GiftsInputView.java @@ -9,4 +9,9 @@ public static List getGiftNames(String rawString) { StringSeparator separator = new StringSeparator(SEPARATOR); return separator.splitName(rawString); } + + public static List getGiftNames(String rawString, int count) { + StringSeparator separator = new StringSeparator(SEPARATOR); + return separator.splitName(rawString); + } } diff --git a/src/test/java/view/GiftsInputViewTest.java b/src/test/java/view/GiftsInputViewTest.java index 34b262260c..0748e6b759 100644 --- a/src/test/java/view/GiftsInputViewTest.java +++ b/src/test/java/view/GiftsInputViewTest.java @@ -33,4 +33,21 @@ void validateStartOrEndWithSeparator(String input) { .isInstanceOf(IllegalArgumentException.class) .hasMessage("입력이 구분자로 시작하거나 끝나면 안됩니다."); } + + @Test + @DisplayName("상품 이름 길이 검증") + void validateGiftNameLength() { + Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("123456,abc")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("상품 이름은 1글자 이상 5글자 이하여야 합니다."); + } + + @ParameterizedTest + @ValueSource(ints = {2, 10}) + @DisplayName("상품 이름 개수 검증") + void validateGiftNameLength(int count) { + Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("123456,abc,10", count)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("상품 이름이 너무 많거나 너무 적습니다."); + } } From b2cb299cc648d7cfd38cbdb27fbdb630b2b68822 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 14:31:59 +0900 Subject: [PATCH 64/76] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=8B=9C=20=EC=83=81=ED=92=88=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=EC=9D=B4=20=EC=A1=B0=EA=B1=B4=EC=97=90=20=EB=A7=9E=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Main.java | 3 ++- src/main/java/view/GiftsInputView.java | 22 +++++++++++++++++----- src/test/java/view/GiftsInputViewTest.java | 10 +++++----- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index fec3ba4697..79ea9b678c 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -16,7 +16,8 @@ public static void main(String[] args) { OutputView.print("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); List playerNames = retryHelper.retry(() -> PlayersInputView.getPlayerNames(InputView.getInput())); OutputView.print("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); - List giftNames = retryHelper.retry(() -> GiftsInputView.getGiftNames(InputView.getInput())); + List giftNames = retryHelper.retry(() -> GiftsInputView.getGiftNames(InputView.getInput(), + playerNames.size())); OutputView.print("최대 사다리 높이는 몇 개인가요?"); Integer ladderHeight = retryHelper.retry(() -> LadderHeightInputView.getLadderHeight(InputView.getInput())); RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(playerNames.size()); diff --git a/src/main/java/view/GiftsInputView.java b/src/main/java/view/GiftsInputView.java index 304252f0b2..dcab54a4d1 100644 --- a/src/main/java/view/GiftsInputView.java +++ b/src/main/java/view/GiftsInputView.java @@ -5,13 +5,25 @@ public class GiftsInputView { private static final String SEPARATOR = ","; - public static List getGiftNames(String rawString) { + public static List getGiftNames(String rawString, int count) { StringSeparator separator = new StringSeparator(SEPARATOR); - return separator.splitName(rawString); + List splitNames = separator.splitName(rawString); + validateSplitNamesCount(count, splitNames); + for (String splitName : splitNames) { + validateNameLength(splitName); + } + return splitNames; } - public static List getGiftNames(String rawString, int count) { - StringSeparator separator = new StringSeparator(SEPARATOR); - return separator.splitName(rawString); + private static void validateSplitNamesCount(int count, List splitNames) { + if (splitNames.size() != count) { + throw new IllegalArgumentException("상품 이름이 너무 많거나 너무 적습니다."); + } + } + + private static void validateNameLength(String name) { + if (name == null || name.isEmpty() || name.length() > 5) { + throw new IllegalArgumentException("상품 이름은 1글자 이상 5글자 이하여야 합니다."); + } } } diff --git a/src/test/java/view/GiftsInputViewTest.java b/src/test/java/view/GiftsInputViewTest.java index 0748e6b759..4e56b24c24 100644 --- a/src/test/java/view/GiftsInputViewTest.java +++ b/src/test/java/view/GiftsInputViewTest.java @@ -12,7 +12,7 @@ class GiftsInputViewTest { @Test @DisplayName("상품 이름을 구분자로 잘 자르는지 검증") void getGiftNames() { - List giftNames = GiftsInputView.getGiftNames("robin,phobi,12345,test1"); + List giftNames = GiftsInputView.getGiftNames("robin,phobi,12345,test1", 4); Assertions.assertThat(giftNames) .containsExactlyElementsOf(List.of("robin", "phobi", "12345", "test1")); } @@ -20,7 +20,7 @@ void getGiftNames() { @Test @DisplayName("연속된 구분자가 입력된 경우 실행 안되는지 검증") void validateDuplicateSeparator() { - Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("robin,,a")) + Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("robin,,a", 3)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("입력에 구분자가 연속으로 등장하면 안됩니다."); } @@ -29,7 +29,7 @@ void validateDuplicateSeparator() { @ValueSource(strings = {",robin,phobi", "robin,phobi,"}) @DisplayName("구분자로 시작하거나 끝나도록 입력된 경우 실행 안되는지 검증") void validateStartOrEndWithSeparator(String input) { - Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames(input)) + Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames(input, 3)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("입력이 구분자로 시작하거나 끝나면 안됩니다."); } @@ -37,7 +37,7 @@ void validateStartOrEndWithSeparator(String input) { @Test @DisplayName("상품 이름 길이 검증") void validateGiftNameLength() { - Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("123456,abc")) + Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("123456,abc", 2)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("상품 이름은 1글자 이상 5글자 이하여야 합니다."); } @@ -46,7 +46,7 @@ void validateGiftNameLength() { @ValueSource(ints = {2, 10}) @DisplayName("상품 이름 개수 검증") void validateGiftNameLength(int count) { - Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("123456,abc,10", count)) + Assertions.assertThatThrownBy(() -> GiftsInputView.getGiftNames("12345,abc,10", count)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("상품 이름이 너무 많거나 너무 적습니다."); } From 6f0e811e762857f0c80240ee79865f6b60234156 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 14:34:57 +0900 Subject: [PATCH 65/76] =?UTF-8?q?test:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EB=84=88?= =?UTF-8?q?=EB=AC=B4=20=EA=B8=B8=EA=B1=B0=EB=82=98=20=EC=A7=A7=EC=9D=80=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=EA=B0=80=20=EC=9E=85=EB=A0=A5=EB=90=98?= =?UTF-8?q?=EC=97=88=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/view/LadderHeightInputViewTest.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/test/java/view/LadderHeightInputViewTest.java b/src/test/java/view/LadderHeightInputViewTest.java index 53cb6b6963..00757525ec 100644 --- a/src/test/java/view/LadderHeightInputViewTest.java +++ b/src/test/java/view/LadderHeightInputViewTest.java @@ -19,9 +19,18 @@ void getLadderHeight(String input) { @ParameterizedTest @ValueSource(strings = {"ㅁ2", "a", " 2", "2 ", "a", "A"}) @DisplayName("숫자가 아닌게 입력된 경우") - void validateLadderHeight(String input) { + void validateLadderHeightIsNotNumber(String input) { Assertions.assertThatThrownBy(() -> LadderHeightInputView.getLadderHeight(input)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("숫자가 아닙니다."); } + + @ParameterizedTest + @ValueSource(strings = {"1", "21"}) + @DisplayName("너무 길거나 짧은 사다리 높이가 입력된 경우") + void validateLadderHeight(String input) { + Assertions.assertThatThrownBy(() -> LadderHeightInputView.getLadderHeight(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("사다리 높이는 2 이상 20 이하여야 합니다."); + } } From 4423b705a4730e5c8f4982141234dad7680d1b89 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 14:50:55 +0900 Subject: [PATCH 66/76] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EB=84=88?= =?UTF-8?q?=EB=AC=B4=20=EA=B8=B8=EA=B1=B0=EB=82=98=20=EC=A7=A7=EC=9D=80=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=EA=B0=80=20=EC=9E=85=EB=A0=A5=EB=90=98?= =?UTF-8?q?=EC=97=88=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/LadderHeightInputView.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/view/LadderHeightInputView.java b/src/main/java/view/LadderHeightInputView.java index f2826eacfc..10a884f492 100644 --- a/src/main/java/view/LadderHeightInputView.java +++ b/src/main/java/view/LadderHeightInputView.java @@ -2,6 +2,14 @@ public class LadderHeightInputView { public static int getLadderHeight(String rawString) { + int ladderHeight = parseInteger(rawString); + if (ladderHeight < 2 || ladderHeight > 20) { + throw new IllegalArgumentException("사다리 높이는 2 이상 20 이하여야 합니다."); + } + return ladderHeight; + } + + private static int parseInteger(String rawString) { try { return Integer.parseInt(rawString); } catch (NumberFormatException e) { From 1710098495edb7d9efcb4c10f338292956abb872 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 14:53:48 +0900 Subject: [PATCH 67/76] =?UTF-8?q?test:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=EB=90=9C=20=EC=9D=B4=EB=A6=84=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8,=20=EC=B0=B8?= =?UTF-8?q?=EA=B0=80=EC=9E=90=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EA=B0=80=20?= =?UTF-8?q?=EB=84=88=EB=AC=B4=20=EB=A7=8E=EA=B1=B0=EB=82=98=20=EC=A0=81?= =?UTF-8?q?=EC=9D=80=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/view/PlayersInputViewTest.java | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/test/java/view/PlayersInputViewTest.java b/src/test/java/view/PlayersInputViewTest.java index 8dbae6d067..9334581e50 100644 --- a/src/test/java/view/PlayersInputViewTest.java +++ b/src/test/java/view/PlayersInputViewTest.java @@ -1,6 +1,8 @@ package view; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -59,4 +61,24 @@ void validateNameBlackList(String input) { .isInstanceOf(IllegalArgumentException.class) .hasMessage("참가자 이름은 all이 될 수 없습니다."); } + + @Test + @DisplayName("중복된 이름의 참가자가 생성되지 않는지 확인") + void validateDuplicateName() { + Assertions.assertThatThrownBy(() -> PlayersInputView.getPlayerNames("aa,aa")) + .isInstanceOf(IllegalStateException.class) + .hasMessage("이름이 같은 참가자는 있을 수 없습니다."); + } + + @ParameterizedTest + @ValueSource(ints = {1, 11}) + @DisplayName("참가자 인원 수가 너무 적거나 너무 많은지 확인") + void validatePlayersCount(int playersCount) { + String input = IntStream.rangeClosed(1, playersCount) + .mapToObj("a%d"::formatted) + .collect(Collectors.joining(",")); + Assertions.assertThatThrownBy(() -> PlayersInputView.getPlayerNames(input)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("참가자는 2명 이상 10명 이하여야 합니다."); + } } From 2e2989ca370ea6790d724dd51e5a3e343ade0ff7 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 14:56:28 +0900 Subject: [PATCH 68/76] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=EB=90=9C=20=EC=9D=B4=EB=A6=84=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5,=20=EC=B0=B8=EA=B0=80?= =?UTF-8?q?=EC=9E=90=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EA=B0=80=20=EB=84=88?= =?UTF-8?q?=EB=AC=B4=20=EB=A7=8E=EA=B1=B0=EB=82=98=20=EC=A0=81=EC=9D=80?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/PlayersInputView.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/view/PlayersInputView.java b/src/main/java/view/PlayersInputView.java index 446d430017..52089304e1 100644 --- a/src/main/java/view/PlayersInputView.java +++ b/src/main/java/view/PlayersInputView.java @@ -1,6 +1,8 @@ package view; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -12,6 +14,8 @@ public class PlayersInputView { public static List getPlayerNames(String rawString) { StringSeparator separator = new StringSeparator(SEPARATOR); List splitName = separator.splitName(rawString); + validateDuplicateName(splitName); + validatePlayersCount(splitName); for (String name : splitName) { validateNameLength(name); validateNameCharacter(name); @@ -20,6 +24,19 @@ public static List getPlayerNames(String rawString) { return splitName; } + private static void validateDuplicateName(List playersNames) { + Set distinctPlayersNames = new HashSet<>(playersNames); + if (distinctPlayersNames.size() != playersNames.size()) { + throw new IllegalStateException("이름이 같은 참가자는 있을 수 없습니다."); + } + } + + private static void validatePlayersCount(List playersNames) { + if (playersNames == null || playersNames.size() < 2 || playersNames.size() > 10) { + throw new IllegalStateException("참가자는 2명 이상 10명 이하여야 합니다."); + } + } + private static void validateNameLength(String name) { if (name == null || name.isEmpty() || name.length() > 5) { throw new IllegalArgumentException("참가자 이름은 1글자 이상 5글자 이하여야 합니다."); From ad9233da64330d3a0036ec9d68c872910ab9d8dc Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 15:05:40 +0900 Subject: [PATCH 69/76] =?UTF-8?q?refactor:=20main=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Main.java | 52 ++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 79ea9b678c..5372e48b06 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -13,27 +13,53 @@ public class Main { public static void main(String[] args) { RetryHelper retryHelper = new RetryHelper(10); - OutputView.print("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); - List playerNames = retryHelper.retry(() -> PlayersInputView.getPlayerNames(InputView.getInput())); - OutputView.print("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); - List giftNames = retryHelper.retry(() -> GiftsInputView.getGiftNames(InputView.getInput(), - playerNames.size())); - OutputView.print("최대 사다리 높이는 몇 개인가요?"); - Integer ladderHeight = retryHelper.retry(() -> LadderHeightInputView.getLadderHeight(InputView.getInput())); + List playerNames = getPlayerNames(retryHelper); + List giftNames = getGiftNames(retryHelper, playerNames); + Integer ladderHeight = getLadderHeight(retryHelper); RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(playerNames.size()); - LadderGame ladderGame = LadderGameBuilder.builder() + LadderGame ladderGame = makeLadderGame(playerNames, giftNames, ladderHeight, randomLineMakeStrategy); + printLadderGame(playerNames, giftNames, ladderGame); + LadderGameResults ladderGameResults = retryHelper.retry(() -> { + String operator = InputView.getInput(); + return ladderGame.start(operator); + }); + OutputView.printLadderGameResults(ladderGameResults); + } + + private static List getPlayerNames(RetryHelper retryHelper) { + return retryHelper.retry(() -> { + OutputView.print("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + return PlayersInputView.getPlayerNames(InputView.getInput()); + }); + } + + private static List getGiftNames(RetryHelper retryHelper, List playerNames) { + return retryHelper.retry(() -> { + OutputView.print("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); + return GiftsInputView.getGiftNames(InputView.getInput(), playerNames.size()); + }); + } + + private static Integer getLadderHeight(RetryHelper retryHelper) { + return retryHelper.retry(() -> { + OutputView.print("최대 사다리 높이는 몇 개인가요?"); + return LadderHeightInputView.getLadderHeight(InputView.getInput()); + }); + } + + private static LadderGame makeLadderGame(List playerNames, List giftNames, Integer ladderHeight, + RandomLineMakeStrategy randomLineMakeStrategy) { + return LadderGameBuilder.builder() .players(playerNames.toArray(String[]::new)) .gifts(giftNames.toArray(String[]::new)) .ladderHeight(ladderHeight) .ladderMakeStrategy(randomLineMakeStrategy::makeLine) .build(); + } + + private static void printLadderGame(List playerNames, List giftNames, LadderGame ladderGame) { OutputView.printPlayers(playerNames); OutputView.printLadder(ladderGame.rawLadder()); OutputView.printGifts(giftNames); - LadderGameResults ladderGameResults = retryHelper.retry(() -> { - String operator = InputView.getInput(); - return ladderGame.start(operator); - }); - OutputView.printLadderGameResults(ladderGameResults); } } From de3a4e2d84a72f52d45d07b470759b6c3e59133c Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 15:14:09 +0900 Subject: [PATCH 70/76] =?UTF-8?q?test:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=83=80=EA=B8=B0=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EB=B3=B4?= =?UTF-8?q?=EA=B3=A0=20=EC=8B=B6=EC=9D=80=20=EC=B0=B8=EA=B0=80=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=EC=9E=85=EB=A0=A5=ED=95=A0=20=EB=95=8C=20=EC=98=AC?= =?UTF-8?q?=EB=B0=94=EB=A5=B8=20=EC=9E=85=EB=A0=A5=EC=9D=B8=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/LadderGameOperatorInputView.java | 9 ++++++ .../view/LadderGameOperatorInputViewTest.java | 28 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/main/java/view/LadderGameOperatorInputView.java create mode 100644 src/test/java/view/LadderGameOperatorInputViewTest.java diff --git a/src/main/java/view/LadderGameOperatorInputView.java b/src/main/java/view/LadderGameOperatorInputView.java new file mode 100644 index 0000000000..77357111b6 --- /dev/null +++ b/src/main/java/view/LadderGameOperatorInputView.java @@ -0,0 +1,9 @@ +package view; + +import java.util.List; + +public class LadderGameOperatorInputView { + public static String getOperator(String rawString, List playerNames) { + return rawString; + } +} diff --git a/src/test/java/view/LadderGameOperatorInputViewTest.java b/src/test/java/view/LadderGameOperatorInputViewTest.java new file mode 100644 index 0000000000..b31bdf4659 --- /dev/null +++ b/src/test/java/view/LadderGameOperatorInputViewTest.java @@ -0,0 +1,28 @@ +package view; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class LadderGameOperatorInputViewTest { + + @ParameterizedTest + @ValueSource(strings = {"robin", "phobi", "all"}) + @DisplayName("참가자 이름이거나 all 이 입력된 경우만 제대로 처리되는지 검증") + void getOperator(String input) { + String operator = LadderGameOperatorInputView.getOperator(input, List.of("robin", "phobi")); + Assertions.assertThat(operator) + .isEqualTo(input); + } + + @Test + @DisplayName("잘못된 명령어인지 검증") + void invalidOperator() { + Assertions.assertThatThrownBy(() -> LadderGameOperatorInputView.getOperator("aa", List.of("robin", "phobi"))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("없는 참가자 입니다."); + } +} From 9ad6d124b0da8d82ffd79511d9acdefd6acb61f9 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 15:16:25 +0900 Subject: [PATCH 71/76] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=83=80=EA=B8=B0=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EB=B3=B4?= =?UTF-8?q?=EA=B3=A0=20=EC=8B=B6=EC=9D=80=20=EC=B0=B8=EA=B0=80=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=EC=9E=85=EB=A0=A5=ED=95=A0=20=EB=95=8C=20=EC=98=AC?= =?UTF-8?q?=EB=B0=94=EB=A5=B8=20=EC=9E=85=EB=A0=A5=EC=9D=B8=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/LadderGameOperatorInputView.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/view/LadderGameOperatorInputView.java b/src/main/java/view/LadderGameOperatorInputView.java index 77357111b6..80a9fd0f49 100644 --- a/src/main/java/view/LadderGameOperatorInputView.java +++ b/src/main/java/view/LadderGameOperatorInputView.java @@ -4,6 +4,13 @@ public class LadderGameOperatorInputView { public static String getOperator(String rawString, List playerNames) { + validateOperator(rawString, playerNames); return rawString; } + + private static void validateOperator(String rawString, List playerNames) { + if (!playerNames.contains(rawString) && !rawString.equals("all")) { + throw new IllegalArgumentException("없는 참가자 입니다."); + } + } } From 8adb21c6b5daf99698eed79882ca3ed20d574995 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 15:39:53 +0900 Subject: [PATCH 72/76] =?UTF-8?q?fix:=20=EA=B0=84=ED=98=B9=20=EC=82=AC?= =?UTF-8?q?=EB=8B=A4=EB=A6=AC=20=EC=83=9D=EC=84=B1=EC=9D=B4=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=ED=95=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=A0=84=EC=B2=B4=20=EC=B0=B8=EA=B0=80?= =?UTF-8?q?=EC=9E=90=20=EC=8B=A4=ED=96=89=20=EA=B2=B0=EA=B3=BC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Main.java | 20 +++++++++++---- src/main/java/domain/LadderGame.java | 38 ++++++++++++++++++++++------ src/main/java/domain/Players.java | 6 ++++- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 5372e48b06..952ae89612 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -6,6 +6,7 @@ import util.RetryHelper; import view.GiftsInputView; import view.InputView; +import view.LadderGameOperatorInputView; import view.LadderHeightInputView; import view.OutputView; import view.PlayersInputView; @@ -19,11 +20,10 @@ public static void main(String[] args) { RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(playerNames.size()); LadderGame ladderGame = makeLadderGame(playerNames, giftNames, ladderHeight, randomLineMakeStrategy); printLadderGame(playerNames, giftNames, ladderGame); - LadderGameResults ladderGameResults = retryHelper.retry(() -> { - String operator = InputView.getInput(); - return ladderGame.start(operator); - }); - OutputView.printLadderGameResults(ladderGameResults); + String ladderGameResultOwner = showLadderGameResult(playerNames, ladderGame); + while (!ladderGameResultOwner.equals("all")) { + ladderGameResultOwner = showLadderGameResult(playerNames, ladderGame); + } } private static List getPlayerNames(RetryHelper retryHelper) { @@ -62,4 +62,14 @@ private static void printLadderGame(List playerNames, List giftN OutputView.printLadder(ladderGame.rawLadder()); OutputView.printGifts(giftNames); } + + private static String showLadderGameResult(List playerNames, LadderGame ladderGame) { + RetryHelper retryHelper = new RetryHelper(10); + return retryHelper.retry(() -> { + String operator = LadderGameOperatorInputView.getOperator(InputView.getInput(), playerNames); + LadderGameResults ladderGameResults = ladderGame.start(operator); + OutputView.printLadderGameResults(ladderGameResults); + return operator; + }); + } } diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index cb7180d3c2..4ccb30f490 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.function.Supplier; import java.util.stream.IntStream; +import util.RetryHelper; public class LadderGame { private final Players players; @@ -15,10 +16,7 @@ private LadderGame(Players players, Gifts gifts, Supplier lineMakeStr validateRequiredValues(players, gifts, lineMakeStrategy, ladderHeight); this.players = players; this.gifts = gifts; - List lines = IntStream.range(0, ladderHeight) - .mapToObj(value -> new Line(lineMakeStrategy.get())) - .toList(); - this.ladder = new Ladder(lines); + this.ladder = makeLadder(lineMakeStrategy, ladderHeight); } private void validateRequiredValues(Players players, Gifts gifts, Supplier ladderMakeStrategy, @@ -28,7 +26,24 @@ private void validateRequiredValues(Players players, Gifts gifts, Supplier lineMakeStrategy, int ladderHeight) { + RetryHelper retryHelper = new RetryHelper(Integer.MAX_VALUE); + return retryHelper.retry(() -> { + List lines = IntStream.range(0, ladderHeight) + .mapToObj(value -> new Line(lineMakeStrategy.get())) + .toList(); + return new Ladder(lines); + }); + } + public LadderGameResults start(String operator) { + if (operator.equals("all")) { + return startAllPlayer(); + } + return startSinglePlayer(operator); + } + + private LadderGameResults startSinglePlayer(String operator) { validateOperator(operator); LadderGameResult ladderGameResult = generateLadderGameResult(operator); return LadderGameResults.of(ladderGameResult); @@ -47,6 +62,17 @@ private LadderGameResult generateLadderGameResult(String operator) { return new LadderGameResult(operator, giftName); } + private LadderGameResults startAllPlayer() { + List ladderGameResults = players.getPlayerNames().stream() + .map(this::generateLadderGameResult) + .toList(); + return new LadderGameResults(ladderGameResults); + } + + public List> rawLadder() { + return ladder.getRawLadder(); + } + public static final class LadderGameBuilder { private Players players; private Gifts gifts; @@ -84,8 +110,4 @@ public LadderGame build() { return new LadderGame(players, gifts, ladderMakeStrategy, ladderHeight); } } - - public List> rawLadder() { - return ladder.getRawLadder(); - } } diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index ec14ea17dc..d5edd1a83c 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -27,7 +27,7 @@ private void validatePlayersCount(List players) { throw new IllegalStateException("참가자는 2명 이상 10명 이하여야 합니다."); } } - + boolean notContains(String playerName) { return players.stream() .noneMatch(player -> player.name().equals(playerName)); @@ -38,6 +38,10 @@ int indexOf(String playerName) { return playerNames.indexOf(playerName); } + List getPlayerNames() { + return players.stream().map(Player::name).toList(); + } + static Players of(String... playerNames) { List players = Arrays.stream(playerNames).map(Player::new).toList(); return new Players(players); From f183b9cda4382c984a5eef3a4a0cf65f04189775 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sat, 2 Mar 2024 15:43:32 +0900 Subject: [PATCH 73/76] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Main.java | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 952ae89612..b1d953f183 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -17,13 +17,11 @@ public static void main(String[] args) { List playerNames = getPlayerNames(retryHelper); List giftNames = getGiftNames(retryHelper, playerNames); Integer ladderHeight = getLadderHeight(retryHelper); - RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(playerNames.size()); - LadderGame ladderGame = makeLadderGame(playerNames, giftNames, ladderHeight, randomLineMakeStrategy); + + LadderGame ladderGame = makeLadderGame(playerNames, giftNames, ladderHeight); printLadderGame(playerNames, giftNames, ladderGame); - String ladderGameResultOwner = showLadderGameResult(playerNames, ladderGame); - while (!ladderGameResultOwner.equals("all")) { - ladderGameResultOwner = showLadderGameResult(playerNames, ladderGame); - } + + printLadderGameResults(playerNames, ladderGame); } private static List getPlayerNames(RetryHelper retryHelper) { @@ -47,6 +45,11 @@ private static Integer getLadderHeight(RetryHelper retryHelper) { }); } + private static LadderGame makeLadderGame(List playerNames, List giftNames, Integer ladderHeight) { + RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(playerNames.size()); + return makeLadderGame(playerNames, giftNames, ladderHeight, randomLineMakeStrategy); + } + private static LadderGame makeLadderGame(List playerNames, List giftNames, Integer ladderHeight, RandomLineMakeStrategy randomLineMakeStrategy) { return LadderGameBuilder.builder() @@ -63,6 +66,13 @@ private static void printLadderGame(List playerNames, List giftN OutputView.printGifts(giftNames); } + private static void printLadderGameResults(List playerNames, LadderGame ladderGame) { + String ladderGameResultOwner = showLadderGameResult(playerNames, ladderGame); + while (!ladderGameResultOwner.equals("all")) { + ladderGameResultOwner = showLadderGameResult(playerNames, ladderGame); + } + } + private static String showLadderGameResult(List playerNames, LadderGame ladderGame) { RetryHelper retryHelper = new RetryHelper(10); return retryHelper.retry(() -> { From 5898e161b566056812ac4af6e7ae48bbe75863ce Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sun, 3 Mar 2024 11:58:03 +0900 Subject: [PATCH 74/76] =?UTF-8?q?docs:=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=20=EC=98=88=EC=A0=95=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index dfb16d4087..7bfdf26243 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,11 @@ - [x] 사다리 출력 기능 - [x] 사다리 타기 실행 기능 - [x] 사다리 타기 결과 출력 기능 + +# 피드백 반영 예정 목록 + +- [ ] List와 가변 배열 사이의 불필요한 변환 작업 삭제 +- [ ] Ladder 의 정적 팩토리 메서드 추가 +- [ ] 표준 함수형 인터페이스 대신 적절한 커스텀 인터페이스 정의 +- [ ] 불필요한 매개변수 삭제 +- [ ] 생성자와 정적 팩토리 메서드에 매개변수 차이 부여 From a2d278561109d6df0b2f90504fa055b25ec98e82 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Sun, 3 Mar 2024 23:34:48 +0900 Subject: [PATCH 75/76] =?UTF-8?q?refactor:=20LineGenerateStrategy=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20Ladder=20=EC=97=90=20=EC=A0=95?= =?UTF-8?q?=EC=A0=81=20=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +-- src/main/java/Main.java | 11 ++++--- .../domain/AbstractLineGenerateStrategy.java | 33 +++++++++++++++++++ src/main/java/domain/Ladder.java | 11 +++++++ src/main/java/domain/LadderGame.java | 29 +++++----------- src/main/java/domain/Line.java | 5 +++ .../java/domain/LineGenerateStrategy.java | 7 ++++ .../domain/RandomLineGenerateStrategy.java | 15 +++++++++ src/test/java/domain/LadderGameTest.java | 2 +- .../RandomLineGenerateStrategyTest.java | 20 +++++++++++ .../domain/RandomLineMakeStrategyTest.java | 19 ----------- .../java/domain/TestLineGenerateStrategy.java | 13 ++++++++ 12 files changed, 121 insertions(+), 48 deletions(-) create mode 100644 src/main/java/domain/AbstractLineGenerateStrategy.java create mode 100644 src/main/java/domain/LineGenerateStrategy.java create mode 100644 src/main/java/domain/RandomLineGenerateStrategy.java create mode 100644 src/test/java/domain/RandomLineGenerateStrategyTest.java delete mode 100644 src/test/java/domain/RandomLineMakeStrategyTest.java create mode 100644 src/test/java/domain/TestLineGenerateStrategy.java diff --git a/README.md b/README.md index 7bfdf26243..bc1def9a62 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ # 피드백 반영 예정 목록 - [ ] List와 가변 배열 사이의 불필요한 변환 작업 삭제 -- [ ] Ladder 의 정적 팩토리 메서드 추가 -- [ ] 표준 함수형 인터페이스 대신 적절한 커스텀 인터페이스 정의 +- [x] Ladder 의 정적 팩토리 메서드 추가 +- [x] 표준 함수형 인터페이스 대신 적절한 커스텀 인터페이스 정의 - [ ] 불필요한 매개변수 삭제 - [ ] 생성자와 정적 팩토리 메서드에 매개변수 차이 부여 diff --git a/src/main/java/Main.java b/src/main/java/Main.java index b1d953f183..9a57c3748d 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,6 +1,7 @@ import domain.LadderGame; import domain.LadderGame.LadderGameBuilder; -import domain.RandomLineMakeStrategy; +import domain.LineGenerateStrategy; +import domain.RandomLineGenerateStrategy; import dto.LadderGameResults; import java.util.List; import util.RetryHelper; @@ -46,17 +47,17 @@ private static Integer getLadderHeight(RetryHelper retryHelper) { } private static LadderGame makeLadderGame(List playerNames, List giftNames, Integer ladderHeight) { - RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(playerNames.size()); - return makeLadderGame(playerNames, giftNames, ladderHeight, randomLineMakeStrategy); + LineGenerateStrategy lineGenerateStrategy = new RandomLineGenerateStrategy(); + return makeLadderGame(playerNames, giftNames, ladderHeight, lineGenerateStrategy); } private static LadderGame makeLadderGame(List playerNames, List giftNames, Integer ladderHeight, - RandomLineMakeStrategy randomLineMakeStrategy) { + LineGenerateStrategy randomLineMakeStrategy) { return LadderGameBuilder.builder() .players(playerNames.toArray(String[]::new)) .gifts(giftNames.toArray(String[]::new)) .ladderHeight(ladderHeight) - .ladderMakeStrategy(randomLineMakeStrategy::makeLine) + .lineGenerateStrategy(randomLineMakeStrategy) .build(); } diff --git a/src/main/java/domain/AbstractLineGenerateStrategy.java b/src/main/java/domain/AbstractLineGenerateStrategy.java new file mode 100644 index 0000000000..4ef0b49bfc --- /dev/null +++ b/src/main/java/domain/AbstractLineGenerateStrategy.java @@ -0,0 +1,33 @@ +package domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +abstract non-sealed class AbstractLineGenerateStrategy implements LineGenerateStrategy { + @Override + public final List generate(int lineSize) { + List generate = new ArrayList<>(generateStrategy(lineSize)); + fixInvalidBridges(generate); + return Collections.unmodifiableList(generate); + } + + public abstract List generateStrategy(int lineSize); + + private void fixInvalidBridges(List rawBridges) { + rawBridges.set(rawBridges.size() - 1, false); + for (int index = 1; index < rawBridges.size() - 1; index++) { + fixIfNeed(rawBridges, index); + } + } + + private void fixIfNeed(List rawBridges, int index) { + if (isBridgeInARow(rawBridges, index)) { + rawBridges.set(index, false); + } + } + + private boolean isBridgeInARow(List rawBridges, int index) { + return rawBridges.get(index) && rawBridges.get(index - 1); + } +} diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index 4f5bbeeea1..1fa5207638 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.stream.IntStream; +import util.RetryHelper; public class Ladder { private final List lines; @@ -38,4 +39,14 @@ List> getRawLadder() { .map(Line::getRawLine) .toList(); } + + public static Ladder of(LineGenerateStrategy lineGenerateStrategy, int ladderHeight, int lineSize) { + RetryHelper retryHelper = new RetryHelper(Integer.MAX_VALUE); + return retryHelper.retry(() -> { + List lines = IntStream.range(0, ladderHeight) + .mapToObj(value -> Line.of(lineGenerateStrategy, lineSize)) + .toList(); + return new Ladder(lines); + }); + } } diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index 4ccb30f490..8aa6c8b529 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -3,39 +3,26 @@ import dto.LadderGameResult; import dto.LadderGameResults; import java.util.List; -import java.util.function.Supplier; -import java.util.stream.IntStream; -import util.RetryHelper; public class LadderGame { private final Players players; private final Gifts gifts; private final Ladder ladder; - private LadderGame(Players players, Gifts gifts, Supplier lineMakeStrategy, int ladderHeight) { + private LadderGame(Players players, Gifts gifts, LineGenerateStrategy lineMakeStrategy, int ladderHeight) { validateRequiredValues(players, gifts, lineMakeStrategy, ladderHeight); this.players = players; this.gifts = gifts; - this.ladder = makeLadder(lineMakeStrategy, ladderHeight); + this.ladder = Ladder.of(lineMakeStrategy, ladderHeight, players.getPlayerNames().size()); } - private void validateRequiredValues(Players players, Gifts gifts, Supplier ladderMakeStrategy, + private void validateRequiredValues(Players players, Gifts gifts, LineGenerateStrategy lineGenerateStrategy, Integer ladderHeight) { - if (players == null || gifts == null || ladderMakeStrategy == null || ladderHeight == null) { + if (players == null || gifts == null || lineGenerateStrategy == null || ladderHeight == null) { throw new IllegalStateException("필수 값이 설정되지 않았습니다."); } } - private static Ladder makeLadder(Supplier lineMakeStrategy, int ladderHeight) { - RetryHelper retryHelper = new RetryHelper(Integer.MAX_VALUE); - return retryHelper.retry(() -> { - List lines = IntStream.range(0, ladderHeight) - .mapToObj(value -> new Line(lineMakeStrategy.get())) - .toList(); - return new Ladder(lines); - }); - } - public LadderGameResults start(String operator) { if (operator.equals("all")) { return startAllPlayer(); @@ -76,7 +63,7 @@ public List> rawLadder() { public static final class LadderGameBuilder { private Players players; private Gifts gifts; - private Supplier ladderMakeStrategy; + private LineGenerateStrategy lineGenerateStrategy; private int ladderHeight; private LadderGameBuilder() { @@ -96,8 +83,8 @@ public LadderGameBuilder gifts(String... giftNames) { return this; } - public LadderGameBuilder ladderMakeStrategy(Supplier ladderMakeStrategy) { - this.ladderMakeStrategy = ladderMakeStrategy; + public LadderGameBuilder lineGenerateStrategy(LineGenerateStrategy lineGenerateStrategy) { + this.lineGenerateStrategy = lineGenerateStrategy; return this; } @@ -107,7 +94,7 @@ public LadderGameBuilder ladderHeight(int ladderHeight) { } public LadderGame build() { - return new LadderGame(players, gifts, ladderMakeStrategy, ladderHeight); + return new LadderGame(players, gifts, lineGenerateStrategy, ladderHeight); } } } diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 3061332861..0eb8aa24ce 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -18,6 +18,11 @@ class Line { this.canGoRights = canGoRights; } + public static Line of(LineGenerateStrategy lineGenerateStrategy, int lineSize) { + List generate = lineGenerateStrategy.generate(lineSize); + return new Line(generate.toArray(Boolean[]::new)); + } + private void validateLineSize(Boolean[] canGoRights) { if (canGoRights.length == 0) { throw new IllegalArgumentException(); diff --git a/src/main/java/domain/LineGenerateStrategy.java b/src/main/java/domain/LineGenerateStrategy.java new file mode 100644 index 0000000000..e55978af60 --- /dev/null +++ b/src/main/java/domain/LineGenerateStrategy.java @@ -0,0 +1,7 @@ +package domain; + +import java.util.List; + +public sealed interface LineGenerateStrategy permits AbstractLineGenerateStrategy { + List generate(int lineSize); +} diff --git a/src/main/java/domain/RandomLineGenerateStrategy.java b/src/main/java/domain/RandomLineGenerateStrategy.java new file mode 100644 index 0000000000..2573ba453e --- /dev/null +++ b/src/main/java/domain/RandomLineGenerateStrategy.java @@ -0,0 +1,15 @@ +package domain; + +import java.util.List; +import java.util.Random; +import java.util.stream.IntStream; + +public final class RandomLineGenerateStrategy extends AbstractLineGenerateStrategy { + @Override + public List generateStrategy(int lineSize) { + Random random = new Random(); + return IntStream.range(0, lineSize) + .mapToObj(value -> random.nextBoolean()) + .toList(); + } +} diff --git a/src/test/java/domain/LadderGameTest.java b/src/test/java/domain/LadderGameTest.java index 62a3a9338d..b874b76314 100644 --- a/src/test/java/domain/LadderGameTest.java +++ b/src/test/java/domain/LadderGameTest.java @@ -26,7 +26,7 @@ private LadderGame makeTestLadderGame() { return LadderGameBuilder.builder() .players("robin", "phobi") .gifts("1등", "2등") - .ladderMakeStrategy(() -> new Boolean[]{true, false}) + .lineGenerateStrategy(new TestLineGenerateStrategy()) .ladderHeight(5) .build(); } diff --git a/src/test/java/domain/RandomLineGenerateStrategyTest.java b/src/test/java/domain/RandomLineGenerateStrategyTest.java new file mode 100644 index 0000000000..42370db37f --- /dev/null +++ b/src/test/java/domain/RandomLineGenerateStrategyTest.java @@ -0,0 +1,20 @@ +package domain; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class RandomLineGenerateStrategyTest { + + @Test + @DisplayName("|-----|----- 인 Point로 Line이 생성되지 않는지 확인") + void makeLine() { + LineGenerateStrategy randomLineMakeStrategy = new RandomLineGenerateStrategy(); + List generate = randomLineMakeStrategy.generate(5); + Assertions.assertThat(generate.size()) + .isEqualTo(5); + Assertions.assertThat(generate.get(generate.size() - 1)) + .isFalse(); + } +} diff --git a/src/test/java/domain/RandomLineMakeStrategyTest.java b/src/test/java/domain/RandomLineMakeStrategyTest.java deleted file mode 100644 index be93b3854b..0000000000 --- a/src/test/java/domain/RandomLineMakeStrategyTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package domain; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class RandomLineMakeStrategyTest { - - @Test - @DisplayName("|-----|----- 인 Point로 Line이 생성되지 않는지 확인") - void makeLine() { - RandomLineMakeStrategy randomLineMakeStrategy = new RandomLineMakeStrategy(5); - Boolean[] booleans = randomLineMakeStrategy.makeLine(); - Assertions.assertThat(booleans.length) - .isEqualTo(5); - Assertions.assertThat(booleans[booleans.length - 1]) - .isFalse(); - } -} diff --git a/src/test/java/domain/TestLineGenerateStrategy.java b/src/test/java/domain/TestLineGenerateStrategy.java new file mode 100644 index 0000000000..4ca8f92a70 --- /dev/null +++ b/src/test/java/domain/TestLineGenerateStrategy.java @@ -0,0 +1,13 @@ +package domain; + +import java.util.List; +import java.util.stream.IntStream; + +public class TestLineGenerateStrategy extends AbstractLineGenerateStrategy { + @Override + public List generateStrategy(int lineSize) { + return IntStream.range(0, lineSize) + .mapToObj(value -> value % 2 == 0) + .toList(); + } +} From 1e165624d36a900bd737c946f2074da5cd451493 Mon Sep 17 00:00:00 2001 From: robinjoon Date: Mon, 4 Mar 2024 00:03:24 +0900 Subject: [PATCH 76/76] =?UTF-8?q?refactor:=20=EA=B0=80=EB=B3=80=20?= =?UTF-8?q?=EB=B0=B0=EC=97=B4=20=EC=82=AC=EC=9A=A9=ED=95=9C=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20List=20=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +-- src/main/java/Main.java | 4 +- src/main/java/domain/Gifts.java | 5 +-- src/main/java/domain/Ladder.java | 2 +- src/main/java/domain/LadderGame.java | 4 +- src/main/java/domain/Line.java | 52 +++++++++++++----------- src/main/java/domain/Players.java | 5 +-- src/test/java/domain/GiftsTest.java | 6 +-- src/test/java/domain/LadderGameTest.java | 4 +- src/test/java/domain/LadderTest.java | 16 ++++---- src/test/java/domain/LineTest.java | 8 ++-- src/test/java/domain/PlayersTest.java | 8 ++-- 12 files changed, 61 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index bc1def9a62..299e3f602c 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,8 @@ # 피드백 반영 예정 목록 -- [ ] List와 가변 배열 사이의 불필요한 변환 작업 삭제 +- [x] List와 가변 배열 사이의 불필요한 변환 작업 삭제 - [x] Ladder 의 정적 팩토리 메서드 추가 - [x] 표준 함수형 인터페이스 대신 적절한 커스텀 인터페이스 정의 -- [ ] 불필요한 매개변수 삭제 -- [ ] 생성자와 정적 팩토리 메서드에 매개변수 차이 부여 +- [x] 불필요한 매개변수 삭제 +- [x] 생성자와 정적 팩토리 메서드에 매개변수 차이 부여 diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 9a57c3748d..ef419ed81f 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -54,8 +54,8 @@ private static LadderGame makeLadderGame(List playerNames, List private static LadderGame makeLadderGame(List playerNames, List giftNames, Integer ladderHeight, LineGenerateStrategy randomLineMakeStrategy) { return LadderGameBuilder.builder() - .players(playerNames.toArray(String[]::new)) - .gifts(giftNames.toArray(String[]::new)) + .players(playerNames) + .gifts(giftNames) .ladderHeight(ladderHeight) .lineGenerateStrategy(randomLineMakeStrategy) .build(); diff --git a/src/main/java/domain/Gifts.java b/src/main/java/domain/Gifts.java index cfed8345c7..6762376c42 100644 --- a/src/main/java/domain/Gifts.java +++ b/src/main/java/domain/Gifts.java @@ -1,6 +1,5 @@ package domain; -import java.util.Arrays; import java.util.List; class Gifts { @@ -22,8 +21,8 @@ String getGiftName(int index) { return gift.name(); } - static Gifts of(String... giftsName) { - List gifts = Arrays.stream(giftsName).map(Gift::new).toList(); + static Gifts of(List giftsName) { + List gifts = giftsName.stream().map(Gift::new).toList(); return new Gifts(gifts); } } diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index 1fa5207638..f0a2dbc7b3 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -7,7 +7,7 @@ public class Ladder { private final List lines; - public Ladder(List lines) { + Ladder(List lines) { validateConnectedLadder(lines); this.lines = lines; } diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index 8aa6c8b529..b887e7313e 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -73,12 +73,12 @@ public static LadderGameBuilder builder() { return new LadderGameBuilder(); } - public LadderGameBuilder players(String... playerNames) { + public LadderGameBuilder players(List playerNames) { this.players = Players.of(playerNames); return this; } - public LadderGameBuilder gifts(String... giftNames) { + public LadderGameBuilder gifts(List giftNames) { this.gifts = Gifts.of(giftNames); return this; } diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 0eb8aa24ce..4dcc2bed61 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -6,65 +6,60 @@ class Line { private final List points; - private final Boolean[] canGoRights; + private final List canGoRights; - Line(Boolean... canGoRights) { + private Line(List canGoRights) { validateLineSize(canGoRights); validateRightAfterEnd(canGoRights); List points = new ArrayList<>(); addFirstPoint(points, canGoRights); addRemainPoints(points, canGoRights); this.points = Collections.unmodifiableList(points); - this.canGoRights = canGoRights; + this.canGoRights = Collections.unmodifiableList(canGoRights); } - public static Line of(LineGenerateStrategy lineGenerateStrategy, int lineSize) { - List generate = lineGenerateStrategy.generate(lineSize); - return new Line(generate.toArray(Boolean[]::new)); - } - - private void validateLineSize(Boolean[] canGoRights) { - if (canGoRights.length == 0) { + private void validateLineSize(List canGoRights2) { + if (canGoRights2.size() == 0) { throw new IllegalArgumentException(); } } - private void validateRightAfterEnd(Boolean[] canGoRights) { - if (canGoRights[canGoRights.length - 1]) { + private void validateRightAfterEnd(List canGoRights2) { + if (canGoRights2.get(canGoRights2.size() - 1)) { throw new IllegalArgumentException("오른쪽 끝에선 오른쪽으로 갈 수 없습니다."); } } - private void addFirstPoint(List points, Boolean[] canGoRights) { - if (canGoRights[0]) { + private void addFirstPoint(List points, List canGoRights) { + if (canGoRights.get(0)) { points.add(new Point(Direction.RIGHT, 0)); } - if (!canGoRights[0]) { + if (!canGoRights.get(0)) { points.add(new Point(Direction.STRAIGHT, 0)); } } - private void addRemainPoints(List points, Boolean[] canGoRights) { - for (int index = 1; index < canGoRights.length; index++) { + private void addRemainPoints(List points, List canGoRights) { + for (int index = 1; index < canGoRights.size(); index++) { validateContinuousRight(index, canGoRights); addPoint(points, index, canGoRights); } } - private void validateContinuousRight(int index, Boolean[] canGoRights) { - if (canGoRights[index - 1] && canGoRights[index]) { + private void validateContinuousRight(int index, List canGoRights) { + if (canGoRights.get(index - 1) && canGoRights.get(index)) { throw new IllegalArgumentException("|-----|-----| 연결 감지!"); } } - private void addPoint(List points, int index, Boolean[] canGoRights) { - if (canGoRights[index]) { + private void addPoint(List points, int index, List canGoRights) { + if (canGoRights.get(index)) { points.add(new Point(Direction.RIGHT, index)); } - if (canGoRights[index - 1] && !canGoRights[index]) { + if (canGoRights.get(index - 1) && !canGoRights.get(index)) { points.add(new Point(Direction.LEFT, index)); } - if (!canGoRights[index - 1] && !canGoRights[index]) { + if (!canGoRights.get(index - 1) && !canGoRights.get(index)) { points.add(new Point(Direction.STRAIGHT, index)); } } @@ -89,6 +84,15 @@ int move(int startIndex) { } List getRawLine() { - return List.of(canGoRights); + return canGoRights; + } + + public static Line of(LineGenerateStrategy lineGenerateStrategy, int lineSize) { + List generate = lineGenerateStrategy.generate(lineSize); + return Line.from(generate.toArray(Boolean[]::new)); + } + + static Line from(Boolean... canGoRights) { + return new Line(List.of(canGoRights)); } } diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index d5edd1a83c..1ea44774be 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -1,6 +1,5 @@ package domain; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -42,8 +41,8 @@ List getPlayerNames() { return players.stream().map(Player::name).toList(); } - static Players of(String... playerNames) { - List players = Arrays.stream(playerNames).map(Player::new).toList(); + static Players of(List playerNames) { + List players = playerNames.stream().map(Player::new).toList(); return new Players(players); } } diff --git a/src/test/java/domain/GiftsTest.java b/src/test/java/domain/GiftsTest.java index 3786886185..d37cb25e8a 100644 --- a/src/test/java/domain/GiftsTest.java +++ b/src/test/java/domain/GiftsTest.java @@ -1,5 +1,6 @@ package domain; +import java.util.List; import java.util.stream.IntStream; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -11,10 +12,9 @@ class GiftsTest { @ValueSource(ints = {1, 11}) @DisplayName("상품 수가 너무 적거나 너무 많은지 확인") void validateGiftsCount(int giftsCount) { - String[] giftNames = IntStream.rangeClosed(1, giftsCount) + List giftNames = IntStream.rangeClosed(1, giftsCount) .mapToObj("a%d"::formatted) - .toList() - .toArray(new String[giftsCount]); + .toList(); Assertions.assertThatThrownBy(() -> Gifts.of(giftNames)) .isInstanceOf(IllegalStateException.class) diff --git a/src/test/java/domain/LadderGameTest.java b/src/test/java/domain/LadderGameTest.java index b874b76314..b65a1670b9 100644 --- a/src/test/java/domain/LadderGameTest.java +++ b/src/test/java/domain/LadderGameTest.java @@ -24,8 +24,8 @@ void start(String playerName, String giftName) { private LadderGame makeTestLadderGame() { return LadderGameBuilder.builder() - .players("robin", "phobi") - .gifts("1등", "2등") + .players(List.of("robin", "phobi")) + .gifts(List.of("1등", "2등")) .lineGenerateStrategy(new TestLineGenerateStrategy()) .ladderHeight(5) .build(); diff --git a/src/test/java/domain/LadderTest.java b/src/test/java/domain/LadderTest.java index 3eec117ff7..9c58a292ff 100644 --- a/src/test/java/domain/LadderTest.java +++ b/src/test/java/domain/LadderTest.java @@ -16,17 +16,17 @@ public class LadderTest { void validLadder() { Assertions.assertThatNoException() .isThrownBy(() -> new Ladder( - List.of(new Line(false, true, false), new Line(true, false, false), - new Line(false, true, false), new Line(false, true, false), - new Line(false, true, false), new Line(false, true, false)))); + List.of(Line.from(false, true, false), Line.from(true, false, false), + Line.from(false, true, false), Line.from(false, true, false), + Line.from(false, true, false), Line.from(false, true, false)))); } @Test @DisplayName("두 지점 사이에 연결이 없는 사다리가 생성되지 않는지 검증") void noConnectedLadder() { Assertions.assertThatThrownBy(() -> new Ladder( - List.of(new Line(false, true, false), new Line(false, true, false), new Line(false, true, false), - new Line(false, true, false), new Line(false, true, false), new Line(false, true, false)))) + List.of(Line.from(false, true, false), Line.from(false, true, false), Line.from(false, true, false), + Line.from(false, true, false), Line.from(false, true, false), Line.from(false, true, false)))) .isInstanceOf(IllegalStateException.class) .hasMessage("두 지점 사이에는 반드시 한개 이상의 발판이 있어야 합니다."); } @@ -44,9 +44,9 @@ void climb(int startIndex, int endIndex) { * | |-----| * */ Ladder ladder = new Ladder( - List.of(new Line(false, true, false), new Line(true, false, false), - new Line(false, true, false), new Line(false, true, false), - new Line(false, true, false), new Line(false, true, false))); + List.of(Line.from(false, true, false), Line.from(true, false, false), + Line.from(false, true, false), Line.from(false, true, false), + Line.from(false, true, false), Line.from(false, true, false))); int actual = ladder.climb(startIndex); Assertions.assertThat(actual) .isEqualTo(endIndex); diff --git a/src/test/java/domain/LineTest.java b/src/test/java/domain/LineTest.java index de971fe2a8..58e228fcdd 100644 --- a/src/test/java/domain/LineTest.java +++ b/src/test/java/domain/LineTest.java @@ -9,12 +9,12 @@ class LineTest { @DisplayName("올바른 Point로 Line이 잘 생성되는지 확인") void normal() { // |-----| | |-----| - Line line = new Line(true, false, false, true, false); + Line line = Line.from(true, false, false, true, false); int length = line.length(); Assertions.assertThat(length) .isEqualTo(5); // | | | |-----| - Line line2 = new Line(false, false, false, true, false); + Line line2 = Line.from(false, false, false, true, false); int length2 = line2.length(); Assertions.assertThat(length2) .isEqualTo(5); @@ -24,7 +24,7 @@ void normal() { @DisplayName("|-----|-----| 인 Point로 Line이 생성되지 않는지 확인") void leftContinueOrRightContinue() { Assertions.assertThatThrownBy( - () -> new Line(true, true, false)) + () -> Line.from(true, true, false)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("|-----|-----| 연결 감지!"); } @@ -33,7 +33,7 @@ void leftContinueOrRightContinue() { @DisplayName("|-----|----- 인 Point로 Line이 생성되지 않는지 확인") void rightAfterEnd() { Assertions.assertThatThrownBy( - () -> new Line(true, false, true)) + () -> Line.from(true, false, true)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("오른쪽 끝에선 오른쪽으로 갈 수 없습니다."); } diff --git a/src/test/java/domain/PlayersTest.java b/src/test/java/domain/PlayersTest.java index cfca350a01..0b4429eb81 100644 --- a/src/test/java/domain/PlayersTest.java +++ b/src/test/java/domain/PlayersTest.java @@ -1,5 +1,6 @@ package domain; +import java.util.List; import java.util.stream.IntStream; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -12,7 +13,7 @@ class PlayersTest { @Test @DisplayName("중복된 이름의 참가자가 생성되지 않는지 확인") void validateDuplicateName() { - Assertions.assertThatThrownBy(() -> Players.of("robin", "robin")) + Assertions.assertThatThrownBy(() -> Players.of(List.of("robin", "robin"))) .isInstanceOf(IllegalStateException.class) .hasMessage("이름이 같은 참가자는 있을 수 없습니다."); } @@ -21,10 +22,9 @@ void validateDuplicateName() { @ValueSource(ints = {1, 11}) @DisplayName("참가자 인원 수가 너무 적거나 너무 많은지 확인") void validatePlayersCount(int playersCount) { - String[] playerNames = IntStream.rangeClosed(1, playersCount) + List playerNames = IntStream.rangeClosed(1, playersCount) .mapToObj("a%d"::formatted) - .toList() - .toArray(new String[playersCount]); + .toList(); Assertions.assertThatThrownBy(() -> Players.of(playerNames)) .isInstanceOf(IllegalStateException.class)