Skip to content

Commit ceeb1cf

Browse files
authored
고생하셨습니다.
🎉 PR 머지 완료! 🎉
1 parent 021c504 commit ceeb1cf

38 files changed

+740
-284
lines changed

README.md

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,53 @@
99

1010
## 요구사항
1111

12-
- 사다리의 높이와 넓이를 입력받아 생성한다.
13-
- 넓이와 높이는 2 이상 24 이하 여야한다.
14-
- 사다리의 시작 지점과 도착 지점을 출력한다.
12+
- 참여할 사람 이름 (쉼표 기준)
13+
- 이름은 최대 5자까지 가능하다.
14+
- 실행 결과 ex) 꽝, 5000, 꽝, 3000
15+
- 최대 사다리 높이
16+
- 높이는 2 이상 24 이하 여야한다.
17+
- 결과를 볼 사람의 이름
18+
- 참여할 사람을 입력할 시 결과만 출력
19+
```text
20+
결과를 보고 싶은 사람은?
21+
neo
22+
23+
실행 결과
24+
25+
```
26+
- `all`을 입력할 시 전체 출력 후 종료
27+
```text
28+
결과를 보고 싶은 사람은?
29+
all
30+
31+
실행 결과
32+
neo : 꽝
33+
brown : 3000
34+
brie : 꽝
35+
tommy : 5000
36+
```
1537
1638
## 구현 기능
1739
40+
### 플레이어(들)
41+
42+
- 플레이어 이름 목록을 관리한다.
43+
- 각 플레이어는 고유한 이름을 가진다.
44+
- 이름 길이 제약 및 중복 방지를 검증한다.
45+
- 사다리 결과 조회 시 이름으로 식별된다.
46+
47+
### 실행 결과(들)
48+
49+
- 실행 결과 값을 리스트로 관리한다.
50+
- 플레이어 수와 결과 수가 일치하는지 검증한다.
51+
- 결과는 순서가 보장되며, 인덱스를 기준으로 조회된다.
52+
53+
### 사다리 결과 보드
54+
55+
- 사다리 구조와 실행 결과, 플레이어를 매핑하여 결과 보드를 생성한다.
56+
- 플레이어 이름 → 결과값 을 빠르게 조회할 수 있도록 캐싱한다.
57+
- 전체 결과 또는 특정 플레이어 결과를 제공한다.
58+
1859
### 사다리
1960
2061
- 여러 개의 라인을 가지며 전체 사다리 구조를 나타낸다.
@@ -44,23 +85,44 @@
4485
## 출력 예시
4586
4687
```text
47-
사다리의 넓이는 몇 인가요?
48-
5
88+
참여할 플레이어의 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)
89+
neo,brown,brie,tommy
4990
50-
사다리의 높이는 몇 인가요?
91+
실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)
92+
꽝,5000,꽝,3000
93+
94+
사다리의 최대 높이는 몇 인가요?
5195
5
5296
53-
실행결과
97+
사다리 결과
98+
99+
neo brown brie tommy
100+
|-----| | |
101+
|-----| |-----|
102+
| | |-----|
103+
| |-----| |
104+
|-----| | |
105+
꽝 5000 꽝 3000
106+
107+
결과를 보고 싶은 사람은?
108+
neo
109+
110+
실행 결과
111+
5000
112+
113+
결과를 보고 싶은 사람은?
114+
brie
115+
116+
실행 결과
117+
118+
119+
결과를 보고 싶은 사람은?
120+
all
54121
55-
|-----| |-----| |
56-
| | | |-----|
57-
|-----| | | |
58-
| |-----| |-----|
59-
|-----| |-----| |
122+
실행 결과
123+
neo : 5000
124+
brown : 꽝
125+
brie : 꽝
126+
tommy : 3000
60127
61-
0 -> 1
62-
1 -> 3
63-
2 -> 2
64-
3 -> 0
65-
4 -> 4
66128
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package constants;
2+
3+
public final class ReservedWord {
4+
5+
public static final String FINISH_KEYWORD = "all";
6+
7+
private ReservedWord() {
8+
}
9+
}
Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package controller;
22

3-
import domain.Height;
4-
import domain.Width;
5-
import domain.dto.RequestLadder;
3+
import static constants.ReservedWord.FINISH_KEYWORD;
4+
5+
import domain.dto.RequestLadderGame;
66
import domain.dto.ResponseLadder;
7-
import domain.dto.ResponseLadderResult;
7+
import domain.ladder.Height;
88
import domain.ladder.Ladder;
99
import domain.ladder.LadderFactory;
10+
import domain.ladder.result.LadderResultBoard;
11+
import domain.player.Players;
12+
import domain.runningResult.Results;
13+
import java.util.function.Function;
14+
import java.util.function.Supplier;
1015
import strategy.LineGenerator;
1116
import strategy.PointGenerator;
1217
import strategy.RandomLineGenerator;
@@ -16,36 +21,72 @@
1621

1722
public class LadderController {
1823

24+
private static final String NOT_FOUND_PLAYER_RETRY_MESSAGE = "존재하지 않는 플레이어입니다. 다시 입력해주세요.";
25+
1926
public void play() {
20-
RequestLadder requestLadder = inputLadderSettings();
21-
Width width = requestLadder.toWidth();
22-
Height height = requestLadder.toHeight();
27+
RequestLadderGame request = inputLadderSettings();
28+
Players players = request.toPlayers();
29+
Height height = request.toHeight();
30+
Results results = request.toResults(players.size());
2331

24-
LineGenerator lineGenerator = createLineGenerator();
25-
LadderFactory factory = new LadderFactory();
26-
Ladder ladder = factory.draw(width, height, lineGenerator);
32+
Ladder ladder = drawLadder(players, height);
33+
LadderResultBoard resultBoard = LadderResultBoard.of(players, ladder, results);
2734

28-
drawLadder(ladder, width);
35+
showGameScreen(players, ladder, results);
36+
showPlayerResult(resultBoard);
2937
}
3038

31-
private RequestLadder inputLadderSettings() {
32-
String width = InputView.inputLadderWidth();
39+
private RequestLadderGame inputLadderSettings() {
40+
String names = InputView.inputPlayerNames();
41+
String results = InputView.inputRunningResult();
3342
String height = InputView.inputLadderHeight();
34-
return new RequestLadder(width, height);
43+
return new RequestLadderGame(names, results, height);
44+
}
45+
46+
private Ladder drawLadder(final Players players, final Height height) {
47+
LineGenerator generator = createLineGenerator();
48+
LadderFactory factory = new LadderFactory();
49+
return factory.draw(players, height, generator);
3550
}
3651

3752
private LineGenerator createLineGenerator() {
3853
PointGenerator pointGenerator = new RandomPointGenerator();
3954
return new RandomLineGenerator(pointGenerator);
4055
}
4156

42-
private void drawLadder(final Ladder ladder, final Width width) {
57+
private void showGameScreen(final Players players, final Ladder ladder, final Results results) {
4358
OutputView.printLadderResultTitle();
59+
OutputView.printPlayerNames(players);
60+
OutputView.drawLadder(ResponseLadder.from(ladder));
61+
OutputView.printResults(results);
62+
}
63+
64+
private void showPlayerResult(final LadderResultBoard board) {
65+
repeatUntilDone(
66+
InputView::inputTargetPlayerName,
67+
name -> {
68+
if (name.equals(FINISH_KEYWORD)) {
69+
OutputView.printAllLadderResult(board);
70+
return true;
71+
}
4472

45-
ResponseLadder responseLadder = ResponseLadder.from(ladder);
46-
OutputView.drawLadder(responseLadder);
73+
if (board.findResultOf(name).isEmpty()) {
74+
System.out.println();
75+
System.out.println(NOT_FOUND_PLAYER_RETRY_MESSAGE);
76+
return false;
77+
}
78+
79+
OutputView.printSingleLadderResult(board, name);
80+
return false;
81+
}
82+
);
83+
}
4784

48-
ResponseLadderResult responseResult = ResponseLadderResult.of(ladder, width);
49-
OutputView.printLadderResult(responseResult);
85+
private void repeatUntilDone(final Supplier<String> inputSupplier, final Function<String, Boolean> handler) {
86+
boolean done = false;
87+
while (!done) {
88+
String input = inputSupplier.get();
89+
done = handler.apply(input);
90+
}
5091
}
5192
}

src/main/java/domain/Width.java

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

src/main/java/domain/dto/RequestLadder.java

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package domain.dto;
2+
3+
import domain.ladder.Height;
4+
import domain.player.Players;
5+
import domain.runningResult.Results;
6+
import java.util.List;
7+
import java.util.stream.Stream;
8+
9+
public record RequestLadderGame(
10+
String playerNames,
11+
String runningResults,
12+
String height
13+
) {
14+
15+
private static final String INPUT_DELIMITER = ",";
16+
17+
public RequestLadderGame {
18+
validateEmptyPlayerNames(playerNames);
19+
validateEmptyResults(runningResults);
20+
validateEmptyHeight(height);
21+
}
22+
23+
private static void validatePlayerCountEqualsResultsCount(final int playerCount, final List<String> results) {
24+
if (playerCount != results.size()) {
25+
throw new IllegalArgumentException("실행 결과 수는 플레이어 수와 동일해야 합니다.");
26+
}
27+
}
28+
29+
private void validateEmptyPlayerNames(final String playerNames) {
30+
if (playerNames == null || playerNames.isBlank()) {
31+
throw new IllegalArgumentException("플레이어들의 이름은 공백이 아니어야 합니다.");
32+
}
33+
}
34+
35+
private void validateEmptyResults(final String results) {
36+
if (results == null || results.isBlank()) {
37+
throw new IllegalArgumentException("실행 결과는 공백이 아니어야 합니다.");
38+
}
39+
}
40+
41+
private void validateEmptyHeight(final String height) {
42+
if (height == null || height.isBlank()) {
43+
throw new IllegalArgumentException("사다리의 높이는 공백이 아니어야 합니다.");
44+
}
45+
}
46+
47+
public Players toPlayers() {
48+
List<String> names = Stream.of(playerNames.split(INPUT_DELIMITER))
49+
.map(String::strip)
50+
.toList();
51+
return Players.from(names);
52+
}
53+
54+
public Height toHeight() {
55+
try {
56+
return new Height(Integer.parseInt(height.strip()));
57+
} catch (NumberFormatException e) {
58+
throw new IllegalArgumentException("사다리의 높이는 숫자여야 합니다.");
59+
}
60+
}
61+
62+
public Results toResults(final int playerCount) {
63+
List<String> results = Stream.of(runningResults.split(INPUT_DELIMITER))
64+
.map(String::strip)
65+
.toList();
66+
67+
validatePlayerCountEqualsResultsCount(playerCount, results);
68+
return Results.from(results);
69+
}
70+
}

src/main/java/domain/dto/ResponseLadderResult.java

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

0 commit comments

Comments
 (0)