From 8653fc2287013c66e7bb05981aafe1833f20f68d Mon Sep 17 00:00:00 2001 From: "victor.shin" Date: Mon, 5 May 2025 01:36:30 +0900 Subject: [PATCH 1/3] =?UTF-8?q?refactor:PR=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/view/ResultView.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/nextstep/ladder/view/ResultView.java b/src/main/java/nextstep/ladder/view/ResultView.java index c6c86c9f61..572d84c775 100644 --- a/src/main/java/nextstep/ladder/view/ResultView.java +++ b/src/main/java/nextstep/ladder/view/ResultView.java @@ -25,6 +25,10 @@ public static void ladderResult(Names names, Ladder ladder, Rewards rewards) { for(Reward reward: rewards.values()) { System.out.printf("%-5s ", reward.toString()); } + + for(Reward reward: rewards.values()) { + System.out.printf("%-5s ", reward.toString()); + } } public static String viewLine(Line line) { From 61e23dd44d3fda475f65db75b69a2e2c671fafe0 Mon Sep 17 00:00:00 2001 From: "victor.shin" Date: Mon, 5 May 2025 01:36:30 +0900 Subject: [PATCH 2/3] =?UTF-8?q?refactor:PR=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/view/ResultView.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/nextstep/ladder/view/ResultView.java b/src/main/java/nextstep/ladder/view/ResultView.java index 572d84c775..b6297bdb9c 100644 --- a/src/main/java/nextstep/ladder/view/ResultView.java +++ b/src/main/java/nextstep/ladder/view/ResultView.java @@ -29,6 +29,10 @@ public static void ladderResult(Names names, Ladder ladder, Rewards rewards) { for(Reward reward: rewards.values()) { System.out.printf("%-5s ", reward.toString()); } + + for(Reward reward: rewards.values()) { + System.out.printf("%-5s ", reward.toString()); + } } public static String viewLine(Line line) { From e02c9bef4662c85942a286baf189ed4e6c742a0f Mon Sep 17 00:00:00 2001 From: "victor.shin" Date: Thu, 15 May 2025 21:55:11 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactoring:step4=20=EC=82=AC=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC(=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81)=20PR=EB=B0=98?= =?UTF-8?q?=EC=98=81-05/15?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++ .../ladder2/domain/ladder/Direction.java | 14 +++- .../ladder2/domain/ladder/Ladder.java | 41 +++-------- .../ladder2/domain/ladder/Position.java | 68 +++++++++++++++++++ .../ladder2/domain/result/MatchingResult.java | 11 +-- .../nextstep/ladder2/ladder/LadderTest.java | 17 +++-- .../nextstep/ladder2/ladder/PositionTest.java | 60 ++++++++++++++++ .../ladder2/result/MatchingResultTest.java | 4 +- 8 files changed, 172 insertions(+), 47 deletions(-) create mode 100644 src/main/java/nextstep/ladder2/domain/ladder/Position.java create mode 100644 src/test/java/nextstep/ladder2/ladder/PositionTest.java diff --git a/README.md b/README.md index df82c6af05..e779476ea6 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ ## 4단계 - 사다리(리팩터링) +- [x] PR 반영 + - [x] position 객체화 + - [x] direction enum refactoring with 'move value' + - [x] PR 반영 - [x] 리뷰 코멘트의 가이드 코멘트 및 코드를 참고하여 반영해보자. - 가이드 코드: https://github.com/next-step/java-ladder/pull/2421#discussion_r2074396800 diff --git a/src/main/java/nextstep/ladder2/domain/ladder/Direction.java b/src/main/java/nextstep/ladder2/domain/ladder/Direction.java index c639256a5b..c1da6a7e47 100644 --- a/src/main/java/nextstep/ladder2/domain/ladder/Direction.java +++ b/src/main/java/nextstep/ladder2/domain/ladder/Direction.java @@ -1,5 +1,17 @@ package nextstep.ladder2.domain.ladder; public enum Direction { - LEFT, RIGHT, PASS; + LEFT (-1), + RIGHT (+1), + PASS (0); + + private final int value; + + Direction(int value) { + this.value = value; + } + + public int getValue() { + return value; + } } diff --git a/src/main/java/nextstep/ladder2/domain/ladder/Ladder.java b/src/main/java/nextstep/ladder2/domain/ladder/Ladder.java index 752732eba1..d825844f6e 100644 --- a/src/main/java/nextstep/ladder2/domain/ladder/Ladder.java +++ b/src/main/java/nextstep/ladder2/domain/ladder/Ladder.java @@ -29,44 +29,19 @@ public int height() { public List lines() { return List.copyOf(lines); } - - public int resultOf(int position) { - validatePosition(position); - + + public Position resultOf(Position position) { for (Line line : lines) { - position = moveWithDirection(position, line); - } - - return position; - } - - private int moveWithDirection(int position, Line line) { - if (position < 0 || position >= line.size()) { - return position; - } - - Direction direction = line.move(position); - - if (direction == Direction.LEFT) { - return position - 1; + position.moveBy(line.move(position.value())); } - - if (direction == Direction.RIGHT) { - return position + 1; - } - + return position; } - - private void validatePosition(int position) { - if (position < 0 || position >= peopleCount) { - throw new IllegalArgumentException("유효하지 않은 위치입니다: " + position); - } - } - + public MatchingResult play() { - List playerRewardList = IntStream.range(0, peopleCount) - .mapToObj(this::resultOf) + List positions = Position.range(0, peopleCount, peopleCount); + List playerRewardList = positions.stream() + .map(this::resultOf) .collect(Collectors.toList()); return new MatchingResult(playerRewardList); } diff --git a/src/main/java/nextstep/ladder2/domain/ladder/Position.java b/src/main/java/nextstep/ladder2/domain/ladder/Position.java new file mode 100644 index 0000000000..a99bf170e0 --- /dev/null +++ b/src/main/java/nextstep/ladder2/domain/ladder/Position.java @@ -0,0 +1,68 @@ +package nextstep.ladder2.domain.ladder; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class Position { + + private int value; + private final int max; + + private Position(int value, int max) { + if (value < 0 || value >= max) { + throw new IllegalArgumentException("유효하지 않은 위치입니다: v=" + value + ", max=" + max); + } + + this.value = value; + this.max = max; + } + + public static Position of(int value, int max) { + return new Position(value, max); + } + + public static List listOf(int max, int... values) { + return Arrays.stream(values) + .mapToObj(value -> new Position(value, max)) + .collect(Collectors.toList()); + } + + public static List range(int start, int end, int max) { + return IntStream.range(start, end) + .mapToObj(value -> new Position(value, max)) + .collect(Collectors.toList()); + } + + public void moveBy(Direction direction) { + int target = value + direction.getValue(); + validatePosition(target); + + value = target; + } + + private void validatePosition(int value) { + if (value < 0 || value >= max) { + throw new IllegalArgumentException("유효하지 않은 위치입니다: v=" + value + ", max=" + max); + } + } + + public int value() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Position position = (Position) o; + return value == position.value && max == position.max; + } + + @Override + public int hashCode() { + return Objects.hash(value, max); + } +} diff --git a/src/main/java/nextstep/ladder2/domain/result/MatchingResult.java b/src/main/java/nextstep/ladder2/domain/result/MatchingResult.java index c1f2e72c8d..4891f6e629 100644 --- a/src/main/java/nextstep/ladder2/domain/result/MatchingResult.java +++ b/src/main/java/nextstep/ladder2/domain/result/MatchingResult.java @@ -1,5 +1,6 @@ package nextstep.ladder2.domain.result; +import nextstep.ladder2.domain.ladder.Position; import nextstep.ladder2.domain.player.Players; import nextstep.ladder2.domain.reward.Reward; import nextstep.ladder2.domain.reward.Rewards; @@ -9,22 +10,22 @@ public class MatchingResult { - private List playerRewardList; + private List playerRewardList; - public MatchingResult(List playerRewardList) { + public MatchingResult(List playerRewardList) { this.playerRewardList = playerRewardList; } public LadderResult map(Players players, Rewards rewards) { List rewardList = new ArrayList<>(); - for (Integer idx: playerRewardList) { - rewardList.add(rewards.get(idx)); + for (Position position: playerRewardList) { + rewardList.add(rewards.get(position.value())); } return new LadderResult(players, rewardList); } - public List playerRewardList() { + public List playerRewardList() { return playerRewardList; } } diff --git a/src/test/java/nextstep/ladder2/ladder/LadderTest.java b/src/test/java/nextstep/ladder2/ladder/LadderTest.java index a12258f674..da5c5c6ff9 100644 --- a/src/test/java/nextstep/ladder2/ladder/LadderTest.java +++ b/src/test/java/nextstep/ladder2/ladder/LadderTest.java @@ -2,6 +2,7 @@ import nextstep.ladder2.domain.ladder.Ladder; import nextstep.ladder2.domain.ladder.Line; +import nextstep.ladder2.domain.ladder.Position; import nextstep.ladder2.domain.result.MatchingResult; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -10,6 +11,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -49,8 +52,8 @@ public class LadderTest { Ladder ladder = new Ladder(peopleCount, 10); for (int i = 0; i < peopleCount; i++) { - int result = ladder.resultOf(i); - assertThat(result).isBetween(0, peopleCount - 1); + Position result = ladder.resultOf(Position.of(i, 4)); + assertThat(result.value()).isBetween(0, peopleCount - 1); } } @@ -58,8 +61,8 @@ public class LadderTest { void 유효하지_않은_위치로_결과를_요청하면_예외가_발생한다() { Ladder ladder = new Ladder(3, 5); - assertThatIllegalArgumentException().isThrownBy(() -> ladder.resultOf(-1)); - assertThatIllegalArgumentException().isThrownBy(() -> ladder.resultOf(3)); + assertThatIllegalArgumentException().isThrownBy(() -> ladder.resultOf(Position.of(-1, 3))); + assertThatIllegalArgumentException().isThrownBy(() -> ladder.resultOf(Position.of(3, 3))); } @ParameterizedTest @@ -78,9 +81,9 @@ public class LadderTest { MatchingResult result = ladder.play(); - List playerRewardIndexList = result.playerRewardList(); - Set actual = new HashSet<>(playerRewardIndexList); - Set expected = new HashSet<>(List.of(0, 1, 2, 3, 4)); + List playerRewardIndexList = result.playerRewardList(); + Set actual = new HashSet<>(playerRewardIndexList); + Set expected = new HashSet<>(Position.range(0, 5, peopleCount)); assertThat(actual).isEqualTo(expected); } diff --git a/src/test/java/nextstep/ladder2/ladder/PositionTest.java b/src/test/java/nextstep/ladder2/ladder/PositionTest.java new file mode 100644 index 0000000000..1fa679f076 --- /dev/null +++ b/src/test/java/nextstep/ladder2/ladder/PositionTest.java @@ -0,0 +1,60 @@ +package nextstep.ladder2.ladder; + +import nextstep.ladder2.domain.ladder.Direction; +import nextstep.ladder2.domain.ladder.Position; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class PositionTest { + @ParameterizedTest + @ValueSource(ints={-1, -2}) + public void 포지션값은_0보다같거나커야한다(int value) { + assertThatThrownBy(() -> { + Position.of(value, 5); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + public void 포지션값은_최대값보다_작아야한다() { + assertThatThrownBy(() -> { + Position.of(5, 5); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + public void 왼쪽으로이동하면_위치값이_1작아진다() { + Position position = Position.of(3, 5); + + position.moveBy(Direction.LEFT); + + assertThat(position.value()).isEqualTo(2); + } + + @Test + public void 오른쪽으로이동하면_위치값이_1커진다() { + Position position = Position.of(3, 5); + + position.moveBy(Direction.RIGHT); + + assertThat(position.value()).isEqualTo(4); + } + + @Test + public void 범위를_벗어나는_이동은_예외가_발생한다() { + Position position = Position.of(0, 5); + + assertThatThrownBy(() -> { + position.moveBy(Direction.LEFT); + }).isInstanceOf(IllegalArgumentException.class); + + Position position2 = Position.of(4, 5); + + assertThatThrownBy(() -> { + position2.moveBy(Direction.RIGHT); + }).isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/nextstep/ladder2/result/MatchingResultTest.java b/src/test/java/nextstep/ladder2/result/MatchingResultTest.java index 99db188bd8..580e0696ef 100644 --- a/src/test/java/nextstep/ladder2/result/MatchingResultTest.java +++ b/src/test/java/nextstep/ladder2/result/MatchingResultTest.java @@ -1,5 +1,6 @@ package nextstep.ladder2.result; +import nextstep.ladder2.domain.ladder.Position; import nextstep.ladder2.domain.player.Players; import nextstep.ladder2.domain.result.LadderResult; import nextstep.ladder2.domain.result.MatchingResult; @@ -18,7 +19,8 @@ public class MatchingResultTest { void 플레이어와_보상을_매핑할수있다() { Players players = new Players("철수", "영희", "민수"); Rewards rewards = new Rewards("꽝", "당첨", "행운"); - List indexList = List.of(1, 2, 0); + int rewardsCount = 3; + List indexList = Position.listOf(rewardsCount, 1, 2, 0); MatchingResult matchingResult = new MatchingResult(indexList); LadderResult ladderResult = matchingResult.map(players, rewards);