Skip to content

4단계 - 사다리(리팩터링) PR 반영 05/15 #2423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: victor-shin
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/nextstep/ladder/view/ResultView.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ 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());
}

for(Reward reward: rewards.values()) {
System.out.printf("%-5s ", reward.toString());
}
}

public static String viewLine(Line line) {
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/nextstep/ladder2/domain/ladder/Direction.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
41 changes: 8 additions & 33 deletions src/main/java/nextstep/ladder2/domain/ladder/Ladder.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,44 +29,19 @@ public int height() {
public List<Line> 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<Integer> playerRewardList = IntStream.range(0, peopleCount)
.mapToObj(this::resultOf)
List<Position> positions = Position.range(0, peopleCount, peopleCount);
List<Position> playerRewardList = positions.stream()
.map(this::resultOf)
.collect(Collectors.toList());
return new MatchingResult(playerRewardList);
}
Expand Down
68 changes: 68 additions & 0 deletions src/main/java/nextstep/ladder2/domain/ladder/Position.java
Original file line number Diff line number Diff line change
@@ -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<Position> listOf(int max, int... values) {
return Arrays.stream(values)
.mapToObj(value -> new Position(value, max))
.collect(Collectors.toList());
}

public static List<Position> 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);
}
}
11 changes: 6 additions & 5 deletions src/main/java/nextstep/ladder2/domain/result/MatchingResult.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -9,22 +10,22 @@

public class MatchingResult {

private List<Integer> playerRewardList;
private List<Position> playerRewardList;

public MatchingResult(List<Integer> playerRewardList) {
public MatchingResult(List<Position> playerRewardList) {
this.playerRewardList = playerRewardList;
}

public LadderResult map(Players players, Rewards rewards) {
List<Reward> 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<Integer> playerRewardList() {
public List<Position> playerRewardList() {
return playerRewardList;
}
}
17 changes: 10 additions & 7 deletions src/test/java/nextstep/ladder2/ladder/LadderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -49,17 +52,17 @@ 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);
}
}

@Test
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
Expand All @@ -78,9 +81,9 @@ public class LadderTest {

MatchingResult result = ladder.play();

List<Integer> playerRewardIndexList = result.playerRewardList();
Set<Integer> actual = new HashSet<>(playerRewardIndexList);
Set<Integer> expected = new HashSet<>(List.of(0, 1, 2, 3, 4));
List<Position> playerRewardIndexList = result.playerRewardList();
Set<Position> actual = new HashSet<>(playerRewardIndexList);
Set<Position> expected = new HashSet<>(Position.range(0, 5, peopleCount));

assertThat(actual).isEqualTo(expected);
}
Expand Down
60 changes: 60 additions & 0 deletions src/test/java/nextstep/ladder2/ladder/PositionTest.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -18,7 +19,8 @@ public class MatchingResultTest {
void 플레이어와_보상을_매핑할수있다() {
Players players = new Players("철수", "영희", "민수");
Rewards rewards = new Rewards("꽝", "당첨", "행운");
List<Integer> indexList = List.of(1, 2, 0);
int rewardsCount = 3;
List<Position> indexList = Position.listOf(rewardsCount, 1, 2, 0);

MatchingResult matchingResult = new MatchingResult(indexList);
LadderResult ladderResult = matchingResult.map(players, rewards);
Expand Down