Skip to content

Commit 0ce461f

Browse files
authored
[사다리타기 - FP, OOP] 3단계 - 사다리(게임 실행) (#1441)
* feat($compile): step2 피드백 반영 step2 피드백 반영 - 매직 넘버, 매직 리터럴 상수로 분리 - Ladder -> Lines 일급 컬렉션으로 변경 - 사다리 게임 발판 전략 패턴 적용 - 출력 View StringBuilder 정적으로 선언해 재활용 하도록 구현 - 사다리 높인 경계값 테스트 및 파라미터 테스트 적용 - 플레이어명 비어있는 이름 예외 처리 * feat($compile): 사디리 포인트 이동(왼쪽, 오른쪽, 멈춤) 기능 구현. 사디리 포인트 이동(왼쪽, 오른쪽, 멈춤) 기능 구현. - 현재 포인트를 가지는 Point객체 추가 - 현재 이동 방향을 알 수 있는 Direction Enum 객체 추가. * feat($compile): 사다리 특정 위치에서 시작해서 포인트 이동하는 기능 구현. 사다리 특정 위치에서 시작해서 포인트 이동하는 기능 구현. - 현재 위치 값과 포인트를 가지는 Position 객체 추가 * feat($compile): 사다리 가로 라인 위치 이동 기능 구현. 사다리 가로 라인 위치 이동 기능 구현. - Line 객체 추가 및 move 메서드 구현 * feat($compile): 실행결과는 쉼표(,)로 구분한다 실행결과는 쉼표(,)로 구분한다 - 실행결과를 가지는 Result 객체생성 - 실행결과들을 가지는 Results 일급컬렉션 객체 생성 * feat($compile): 포인트 값으로 실행결과 찾기 포인트 값으로 실행결과 찾기 - 플레이어 이름으로 플레이어 시작 포인트 찾기 메서드 추가 - 실행결과 포인트로 실행결과 찾기 메서드 추가 * feat($compile): 사다리 실행 결과를 출력 사다리 실행 결과를 출력 - 사다리 실행 결과를 출력 - 개인별 이름을 입력하면 개인별 결과를 출력. * feat($compile): "all"을 입력하면 전체 참여자의 실행 결과를 출력. "all"을 입력하면 전체 참여자의 실행 결과를 출력. - all 입력 구분하여 결과 출력 분기 Co-authored-by: jeongjaeeom <wsKgatkfrLEFg1RIwaoehyymPa4MBMvjCGyJ8ywPGN8=>
1 parent 577ff12 commit 0ce461f

26 files changed

+623
-104
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@
22

33
## 사다리 게임 구현 기능 목록
44
* 플레이어 이름은 최대 5글자만 가능하다.
5-
* 입력된 플레이어 이름들을 ,(콤마) 구분한다.
5+
* 입력된 플레이어 이름들을 쉼표(,)로 구분한다.
66
* 사다리 가로 라인은 겹치지 않도록 한다.
77
* 사다리 높이는 1보다 작지 않도록 한다.
8+
* 사다리 포인트 이동(왼쪽, 오른쪽, 멈춤) 기능 구현.
9+
* 사다리 특정 위치에서 시작해서 포인트 이동하는 기능 구현.
10+
* 사다리 가로 라인 위치 이동 기능 구현.
11+
* 실행결과는 쉼표(,)로 구분한다.
12+
* 사다리 실행 결과를 출력.
13+
* 개인별 이름을 입력하면 개인별 결과를 출력.
14+
* "all"을 입력하면 전체 참여자의 실행 결과를 출력.
815

916
## 진행 방법
1017

@@ -15,4 +22,4 @@
1522

1623
## 온라인 코드 리뷰 과정
1724

18-
* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/nextstep-step/nextstep-docs/tree/master/codereview)
25+
* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/nextstep-step/nextstep-docs/tree/master/codereview)
Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
package nextstep.ladder;
22

3+
import java.util.List;
4+
import java.util.stream.IntStream;
35
import nextstep.ladder.domain.Height;
4-
import nextstep.ladder.domain.Ladder;
6+
import nextstep.ladder.domain.Lines;
7+
import nextstep.ladder.domain.Player;
58
import nextstep.ladder.domain.Players;
9+
import nextstep.ladder.domain.Result;
10+
import nextstep.ladder.domain.Results;
611
import nextstep.ladder.view.InputView;
712
import nextstep.ladder.view.ResultView;
813

914
public class LadderGameApplication {
1015

16+
public static final String RESULT_ALL_COMMAND = "all";
17+
1118
public static void main(String[] args) {
1219
Players players = new Players(Players.create(InputView.playerNames()));
20+
Results results = new Results(Results.create(InputView.results()));
1321
Height height = new Height(InputView.ladderHeight());
14-
Ladder ladder = new Ladder(height.height(), players.count());
15-
ResultView.print(players);
16-
ResultView.print(ladder);
22+
Lines lines = Lines.of(height.height(), players.count());
23+
ResultView.print(players, lines, results);
24+
25+
String playerName = InputView.resultPlayer();
26+
if (RESULT_ALL_COMMAND.equals(playerName)) {
27+
ResultView.result(players.players(), lines, results);
28+
return;
29+
}
30+
ResultView.print(results.result(lines.move(players.point(playerName))));
1731
}
1832
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package nextstep.ladder.domain;
2+
3+
public enum Direction {
4+
LEFT, RIGHT, STOP;
5+
6+
public boolean left() {
7+
return this == LEFT;
8+
}
9+
10+
public boolean right() {
11+
return this == RIGHT;
12+
}
13+
14+
public boolean stop() {
15+
return this == STOP;
16+
}
17+
}

src/main/java/nextstep/ladder/domain/Height.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66

77
public class Height {
88

9+
public static final int MIN_HEIGHT = 1;
910
private final int height;
1011

1112
public Height(String height) {
1213
this(parseInt(height));
1314
}
1415

1516
public Height(int height) {
16-
if (height < 1) {
17+
if (height < MIN_HEIGHT) {
1718
throw new IllegalArgumentException("사다리 높이는 1보다 작을 수 없습니다.");
1819
}
1920
this.height = height;

src/main/java/nextstep/ladder/domain/Ladder.java

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/main/java/nextstep/ladder/domain/Line.java

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,61 +3,54 @@
33
import java.util.ArrayList;
44
import java.util.Collections;
55
import java.util.List;
6-
import java.util.Objects;
7-
import java.util.Random;
86

97
public class Line {
108

11-
private static final Random RANDOM = new Random();
9+
private final List<Position> positions;
1210

13-
private final List<Boolean> points;
14-
15-
public Line(int countOfPerson) {
16-
this(points(countOfPerson));
11+
public Line(List<Position> positions) {
12+
this.positions = positions;
1713
}
1814

19-
public Line(List<Boolean> points) {
20-
this.points = points;
15+
public static Line from(int numberOfPlayers, PointStrategy strategy) {
16+
List<Position> positions = new ArrayList<>();
17+
positions.add(firstPosition(strategy));
18+
for (int i = 1; i < numberOfPlayers - 1; i++) {
19+
positions.add(bodyPosition(i, positions.get(i - 1), strategy));
20+
}
21+
positions.add(lastPosition(numberOfPlayers - 1, positions.get(positions.size() - 1)));
22+
return from(positions);
2123
}
2224

23-
private static List<Boolean> points(int countOfPerson) {
24-
List<Boolean> points = new ArrayList<>();
25-
points.add(randomPoint());
26-
for (int i = 1; i < countOfPerson - 1; i++) {
27-
points.add(point(points.get(i - 1), randomPoint()));
28-
}
29-
return points;
25+
public static Line from(List<Position> points) {
26+
return new Line(points);
3027
}
3128

32-
private static Boolean point(boolean prev, boolean current) {
33-
if (prev == current) {
34-
return false;
35-
}
36-
return current;
29+
private static Position firstPosition(PointStrategy strategy) {
30+
return Position.of(0, Point.of(false, strategy.linkable()));
3731
}
3832

39-
private static Boolean randomPoint() {
40-
return RANDOM.nextBoolean();
33+
private static Position bodyPosition(int position, Position prev, PointStrategy strategy) {
34+
return Position.of(position, point(prev, strategy.linkable()));
4135
}
4236

43-
public List<Boolean> points() {
44-
return Collections.unmodifiableList(points);
37+
private static Position lastPosition(int position, Position prev) {
38+
return Position.of(position, Point.of(prev.current(), false));
4539
}
4640

47-
@Override
48-
public boolean equals(Object o) {
49-
if (this == o) {
50-
return true;
41+
private static Point point(Position prev, boolean current) {
42+
if (prev.current() == current) {
43+
return Point.of(prev.current(), false);
5144
}
52-
if (o == null || getClass() != o.getClass()) {
53-
return false;
54-
}
55-
Line line = (Line) o;
56-
return Objects.equals(points, line.points);
45+
return Point.of(prev.current(), current);
46+
}
47+
48+
public int move(int startPoint) {
49+
return positions.get(startPoint).move();
5750
}
5851

59-
@Override
60-
public int hashCode() {
61-
return Objects.hash(points);
52+
public List<Position> positions() {
53+
return Collections.unmodifiableList(positions);
6254
}
55+
6356
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package nextstep.ladder.domain;
2+
3+
import java.util.Collections;
4+
import java.util.List;
5+
import java.util.stream.Collectors;
6+
import java.util.stream.IntStream;
7+
8+
public class Lines {
9+
10+
private final List<Line> lines;
11+
12+
public Lines(List<Line> lines) {
13+
this.lines = lines;
14+
}
15+
16+
public static Lines of(int height, int numberOfPlayers) {
17+
return new Lines(IntStream.range(0, height)
18+
.mapToObj(number -> Line.from(numberOfPlayers, new RandomPointStrategy()))
19+
.collect(Collectors.toList()));
20+
}
21+
22+
public int move(int startPoint) {
23+
int result = startPoint;
24+
for (Line line : lines) {
25+
result = line.move(result);
26+
}
27+
return result;
28+
}
29+
30+
public List<Line> lines() {
31+
return Collections.unmodifiableList(lines);
32+
}
33+
}

src/main/java/nextstep/ladder/domain/Player.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,29 @@
44

55
public class Player {
66

7+
public static final int MAX_NAME_LENGTH = 5;
78
private final String name;
89

910
public Player(String name) {
10-
if (name == null || name.length() > 5) {
11+
validateEmpty(name);
12+
validateLength(name.trim());
13+
this.name = name.trim();
14+
}
15+
16+
private void validateEmpty(String name) {
17+
if (isBlank(name)) {
18+
throw new IllegalArgumentException("플레이어 이름은 비어 있을 수 없습니다.");
19+
}
20+
}
21+
22+
private void validateLength(String name) {
23+
if (name.length() > MAX_NAME_LENGTH) {
1124
throw new IllegalArgumentException("플레이어 이름은 최대 5글자만 가능합니다.");
1225
}
13-
this.name = name;
26+
}
27+
28+
private static boolean isBlank(String name) {
29+
return name == null || name.isBlank();
1430
}
1531

1632
@Override

src/main/java/nextstep/ladder/domain/Players.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package nextstep.ladder.domain;
22

33
import java.util.Arrays;
4+
import java.util.Collections;
45
import java.util.List;
56
import java.util.Objects;
67
import java.util.stream.Collectors;
78

89
public class Players {
910

1011
public static final String DELIMITER = ",";
12+
public static final String JOINING_DELIMITER = " ";
1113
private final List<Player> players;
1214

1315
public Players(List<Player> players) {
@@ -23,6 +25,13 @@ public int count() {
2325
return players.size();
2426
}
2527

28+
public int point(String playerName) {
29+
return point(new Player(playerName));
30+
}
31+
public int point(Player player) {
32+
return players.indexOf(player);
33+
}
34+
2635
private static void validateEmpty(String playerNames) {
2736
if (playerNames == null || playerNames.isBlank()) {
2837
throw new IllegalArgumentException("플레이어명은 필수입니다.");
@@ -35,6 +44,10 @@ private static List<Player> players(String playerNames) {
3544
.collect(Collectors.toList());
3645
}
3746

47+
public List<Player> players() {
48+
return Collections.unmodifiableList(players);
49+
}
50+
3851
@Override
3952
public boolean equals(Object o) {
4053
if (this == o) {
@@ -56,6 +69,6 @@ public int hashCode() {
5669
public String toString() {
5770
return players.stream()
5871
.map(String::valueOf)
59-
.collect(Collectors.joining(" "));
72+
.collect(Collectors.joining(JOINING_DELIMITER));
6073
}
6174
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package nextstep.ladder.domain;
2+
3+
public class Point {
4+
5+
private final boolean left;
6+
private final boolean current;
7+
8+
public static Point of(boolean left, boolean current) {
9+
return new Point(left, current);
10+
}
11+
12+
private Point(boolean left, boolean current) {
13+
if (left && current) {
14+
throw new IllegalArgumentException("사다리 포지션은 양쪽에 동시에 존재할 수 없습니다.");
15+
}
16+
this.left = left;
17+
this.current = current;
18+
}
19+
20+
public boolean current() {
21+
return this.current;
22+
}
23+
24+
public Direction move() {
25+
if (current) {
26+
return Direction.RIGHT;
27+
} else if (left) {
28+
return Direction.LEFT;
29+
}
30+
return Direction.STOP;
31+
}
32+
33+
@Override
34+
public String toString() {
35+
return "{" + "left:" + left + ", current:" + current + '}';
36+
}
37+
}

0 commit comments

Comments
 (0)