Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
cb4f68c
초기화
robinjoon Mar 2, 2024
88a9e5c
docs: 요구사항 해석 및 기능 목록 작성
robinjoon Mar 1, 2024
032a69f
test: 각 지점에서 이동 시 적절한 지점으로 이동하는지 확인하는 테스트 추가
robinjoon Mar 1, 2024
3dadff9
feat: 각 지점에서 이동 시 적절한 지점으로 이동하는 기능 구현
robinjoon Mar 1, 2024
8b8e086
test: 연속으로 발판이 나타나는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
79544fa
feat: 연속으로 발판이 나타나는지 검증 기능 구현
robinjoon Mar 1, 2024
a772d45
test: 오른쪽 끝에서 오른쪽으로 가는 발판이 나타나는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
28c6612
feat: 오른쪽 끝에서 오른쪽으로 가는 발판이 나타나는지 검증하는 기능 구현
robinjoon Mar 1, 2024
9ddefca
refactor: Line 내부 메서드 분리
robinjoon Mar 1, 2024
5b6ab9e
refactor: 도메인 클래스들의 접근 지정자 변경
robinjoon Mar 1, 2024
b848e07
test: 두 지점 사이에 연결이 없는 사다리가 생성되지 않는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
199ea26
fix: 일부 상황에서 Line을 구성하는 0번째 Point 누락되는 오류 수정
robinjoon Mar 1, 2024
a9e0ee7
chore: 테스트 DisplayName 수정
robinjoon Mar 1, 2024
4906acc
fix: 두 지점 사이에 연결이 없는 사다리가 생성되지 않도록 검증하는 기능 구현
robinjoon Mar 1, 2024
cbc96d5
refactor: Ladder 내부 검증 코드 최적화
robinjoon Mar 1, 2024
1454024
chore: 테스트 코드 오타 수정
robinjoon Mar 1, 2024
9eb6999
test: 사다리 타기 결과가 잘 나오는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
1e4734e
feat: 사다리 타기 결과 생성 기능 구현
robinjoon Mar 1, 2024
10830e5
refactor: Point 와 Direction 사이 역할 재분배
robinjoon Mar 1, 2024
08cce9c
refactor: Point Record화
robinjoon Mar 1, 2024
d040005
test: 참가자 이름 길이 검증하는 테스트 추가
robinjoon Mar 1, 2024
bb4f3db
feat: 참가자 이름 길이 검증하는 기능 추가
robinjoon Mar 1, 2024
b7da5b0
test: 참가자 이름 구성 문자 검증 테스트 추가
robinjoon Mar 1, 2024
256705d
feat: 참가자 이름 구성 문자 검증 기능 구현
robinjoon Mar 1, 2024
f8b5079
refactor: Player 내부 메서드 분리
robinjoon Mar 1, 2024
9003f6a
test: 참가자 이름이 중복되는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
8c44c73
feat: 참가자 이름이 중복되는지 검증하는 기능 구현
robinjoon Mar 1, 2024
8b60a91
test: 참가자 인원수 검증하는 테스트 추가
robinjoon Mar 1, 2024
b0424e0
feat: 참가자 인원수 검증하는 기능 구현
robinjoon Mar 1, 2024
a0c4c77
docs: 기능문서에 상품 생성 기능 추가
robinjoon Mar 1, 2024
2e2934b
test: 상품 이름 길이 검증 테스트 추가
robinjoon Mar 1, 2024
54b99be
feat: 상품 이름 길이 검증 기능 구현
robinjoon Mar 1, 2024
48a090f
chore: 잘못된 테스트 이름 수정
robinjoon Mar 1, 2024
4f90e64
test: 상품수 검증하는 테스트 추가
robinjoon Mar 1, 2024
b1ec852
feat: 상품수 검증하는 기능 구현
robinjoon Mar 1, 2024
fc96389
test: 사다리 타기 결과 검증 테스트 추가
robinjoon Mar 1, 2024
cbda7c3
test: 게임 실행 시 없는 참여자 결과 조회 안되는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
81f9ddb
feat: 사다리 타기 실행 기능 구현
robinjoon Mar 1, 2024
d39e189
test: 참가자 이름 입력시 구분자로 잘 자르는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
7a94a68
feat: 참가자 이름 입력기능 구현
robinjoon Mar 1, 2024
f1e0c5d
test: 상품 이름 입력시 구분자로 잘 자르는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
2de2881
feat: 상품 이름 입력기능 구현
robinjoon Mar 1, 2024
a63c480
refactor: 문자열 자르는 역할 별도 클래스로 분리
robinjoon Mar 1, 2024
451ada1
test: 사다리 높이 입력 검증 테스트 추가
robinjoon Mar 1, 2024
25e65b4
feat: 사다리 높이 입력 기능 구현
robinjoon Mar 1, 2024
12f263b
test: 사다리 출력을 위한 문자열 생성 테스트 추가
robinjoon Mar 1, 2024
bbe2d23
feat: 사다리 출력을 위한 문자열 생성 기능 구현
robinjoon Mar 1, 2024
577bff0
test: 참가자 출력을 위한 문자열 생성 테스트 추가
robinjoon Mar 1, 2024
87f6217
feat: 참가자 출력을 위한 문자열 생성 기능 구현
robinjoon Mar 1, 2024
0cdcd70
test: 상품 출력을 위한 문자열 생성 테스트 추가
robinjoon Mar 1, 2024
ff6d865
feat: 상품 출력을 위한 문자열 생성 기능 구현
robinjoon Mar 1, 2024
fe2d5e7
refactor: LadderGameResults 패키지 이동 및 Record 로 변환
robinjoon Mar 1, 2024
2fc4743
refactor: LadderGame의 필요없는 필드 제거
robinjoon Mar 1, 2024
edcbc69
test: 랜덤으로 생성된 Line이 유효한지 검증하는 테스트 추가
robinjoon Mar 1, 2024
bed688b
feat: 랜덤으로 Line 을 생성하는 전략 구현
robinjoon Mar 1, 2024
e819163
refactor: 클래스 이름 적절하게 변경
robinjoon Mar 1, 2024
01a40df
test: 일정 횟수까지만 로직이 재시도 되는지 검증하는 테스트 추가
robinjoon Mar 1, 2024
8e843cf
feat: 일정 횟수까지만 로직이 재시도 되게 하는 기능 구현
robinjoon Mar 1, 2024
060ad0c
fix: LadderPrinter 오류 수정
robinjoon Mar 1, 2024
fc41f53
feat: Main 메서드 구현
robinjoon Mar 1, 2024
9c1ae95
test: 참여자 이름 입력 시 조건에 맞는 입력만 입력되는지 검증하는 테스트 추가
robinjoon Mar 2, 2024
021dbb8
feat: 참여자 이름 입력 시 조건에 맞는 입력만 입력되는지 검증하는 기능 구현
robinjoon Mar 2, 2024
ffed2ff
test: 상품 입력 시 상품 이름이 조건에 맞는지 검증하는 테스트 추가
robinjoon Mar 2, 2024
b2cb299
feat: 상품 입력 시 상품 이름이 조건에 맞는지 검증하는 기능 구현
robinjoon Mar 2, 2024
6f0e811
test: 사다리 높이 입력 시 너무 길거나 짧은 높이가 입력되었는지 검증하는 테스트 추가
robinjoon Mar 2, 2024
4423b70
feat: 사다리 높이 입력 시 너무 길거나 짧은 높이가 입력되었는지 검증하는 기능 구현
robinjoon Mar 2, 2024
1710098
test: 참가자 이름 입력 시 중복된 이름 검증하는 테스트, 참가자 이름 수가 너무 많거나 적은지 검증하는 테스트 추가
robinjoon Mar 2, 2024
2e2989c
feat: 참가자 이름 입력 시 중복된 이름 검증하는 기능, 참가자 이름 수가 너무 많거나 적은지 검증하는 기능 구현
robinjoon Mar 2, 2024
ad9233d
refactor: main 메서드 분리
robinjoon Mar 2, 2024
de3a4e2
test: 사다리 타기 결과를 보고 싶은 참가자를 입력할 때 올바른 입력인지 검증하는 테스트 추가
robinjoon Mar 2, 2024
9ad6d12
feat: 사다리 타기 결과를 보고 싶은 참가자를 입력할 때 올바른 입력인지 검증하는 기능 구현
robinjoon Mar 2, 2024
8adb21c
fix: 간혹 사다리 생성이 실패하는 오류 수정 및 전체 참가자 실행 결과 조회 기능 구현
robinjoon Mar 2, 2024
f183b9c
refactor: 메서드 분리
robinjoon Mar 2, 2024
5898e16
docs: 피드백 반영 예정 목록 추가
robinjoon Mar 3, 2024
a2d2785
refactor: LineGenerateStrategy 추가 및 Ladder 에 정적 팩토리 메서드 추가
robinjoon Mar 3, 2024
1e16562
refactor: 가변 배열 사용한 부분 List 로 수정
robinjoon Mar 3, 2024
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
139 changes: 55 additions & 84 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,59 @@
# java-ladder

사다리 타기 미션 저장소

## 우아한테크코스 코드리뷰

- [온라인 코드 리뷰 과정](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] 사람 이름 개수 검증 기능
# 요구사항 해석

> 다시 구현하는 것인 만큼, 조금 난이도를 높이기 위해 생성되는 사다리에 제약 사항을 추가했습니다.

- 참가자 관련 요구 사항
1. 참가자는 최대 10명까지 입력 가능하다
2. 참가자 이름의 구분은 ","를 기준으로 수행된다.
- 참가자 이름 관련 요구 사항
1. 참가자 이름은 최소 한글자 최대 5글자까지 부여할 수 있다.
2. 참가자 이름은 중복될 수 없다.
3. 참가자 이름에는 알파벳 대소문자, 숫자 만 입력할 수 있다.
4. 참가자 이름은 all이 될 수 없다.
- 사다리 관련 요구 사항
1. 어느 한 위치에서 왼쪽과 오른쪽에 동시에 발판이 있을 수 없다.
- 즉, 다음과 같은 사다리는 생성되면 안된다.
```
|-----| |
|-----|-----|
```
2. 사다리의 높이는 최소 2, 최대 20이다.
3. 두 참여자 사이에는 최소한 한개 이상의 발판이 있어야 한다.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이번에 추가하신 요구사항 맞을까요? 😃
도전하는것 너무 좋네요 💯

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이번에 추가하신 요구사항 맞을까요? 😃 도전하는것 너무 좋네요 💯

넵 뭔가 그대로 하는 것 보단, 뭐라도 좀 어렵게 해보는게 좋을 것 같아서 추가해봤습니다!

- 즉, 다음과 같은 사다리는 생성되면 안된다.
```
|-----| |
|-----| |
|-----| |
```
- 상품 관련 요구 사항
1. 상품은 사다리 타기의 결과로 참여자와 1대 1 매칭 될 어떤 것을 말한다.
2. 상품은 최소 한글자 최대 5글자까지 부여할 수 있다.
- 안정적인 프로그램 실행을 위한 요구사항
1. 잘못된 입력이 발생한 경우, 적절한 에러 메세지를 출력한 뒤 해당 위치부터 다시 입력을 수행한다.
2. 재입력은 무한히 시도될 수 있어야 한다.
- 출력 요구 사항
1. 사다리의 가로(-)는 최대 이름 길이로 고정한다.
2. 사람의 이름은 사다리의 세로(|) 에 맞춰 정렬한다.
3. 사람의 이름이 최대 이름 길이보다 작을경우 다음과 같은 규칙으로 공백을 추가한다.
1. 이름 맨 뒤에 공백 문자를 추가한다.
2. 앞에서 추가된 공백 문자를 포함한 이름의 길이가 최대 이름 길이 보다 작을 경우, 공백을 포함한 이름의 길이가 최대 이름 길이가 되도록 공백 문자를 이름 앞에 추가한다.

# 기능 목록

- [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로 이동
- [x] 사다리 출력 기능
- [x] 사다리 타기 실행 기능
- [x] 사다리 타기 결과 출력 기능

## 2단계 피드백 반영 사항
# 피드백 반영 예정 목록

- [x] 모호한 변수 및 메서드 명 변경
- [x] 적절하지 않은 예외 사용 코드 삭제
- [x] List와 가변 배열 사이의 불필요한 변환 작업 삭제
- [x] Ladder 의 정적 팩토리 메서드 추가
- [x] 표준 함수형 인터페이스 대신 적절한 커스텀 인터페이스 정의
- [x] 불필요한 매개변수 삭제
- [x] 생성자와 정적 팩토리 메서드에 매개변수 차이 부여
123 changes: 55 additions & 68 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -1,99 +1,86 @@
import domain.LadderGame;
import domain.LadderGame.LadderGameBuilder;
import domain.LineGenerateStrategy;
import domain.RandomLineGenerateStrategy;
import dto.LadderGameResults;
import java.util.List;
import java.util.function.Supplier;
import view.ClimbResultPrinter;
import util.RetryHelper;
import view.GiftsInputView;
import view.InputView;
import view.LadderGameOperatorInputView;
import view.LadderPrinter;
import view.NameInputView;
import view.NamesPrinter;
import view.LadderHeightInputView;
import view.OutputView;
import view.ResultInputView;
import view.PlayersInputView;

public class Main {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View에서 검증한 것을 도메인에서 또 검증해야 하는가? 검증해야 한다면, 검증 코드를 재사용 해야 하는가?

View에서 검증한 것을 도메인에서 또 검증해야 하는가?

  1. 귀찮게 굳이?
  2. View 는 프론트엔드를 대신하는 것이기 때문에 View에서도 검증을 해야 하고, 도메인은 백엔드기 때문에 별개다. 따라서 둘 다 해야 한다.

view(프론트엔드) 에서는 보통 값의 타입이나 형태(정규식) 정도를 검증해줄 텐데요

저는 프론트와 약속하기 나름이라고 생각해요
프론트에서 반드시 검증해서 넘겨주겠다 하고 신뢰할 수 있다면 믿고 쓸 수 있는것이구요
프론트를 100% 신뢰할 수 없다. 중요한 기능이므로 검증되지 않은 값을 완벽하게 차단해야한다. 라면 둘 다 구현할 것같아요 ㅎㅎ

검증해야 한다면, 검증 코드를 재사용 해야 하는가? 에 대해선 다음과 같은 생각을 할 수 있을 것 같습니다.

  1. 중복은 제거해야지!
  2. View와 도메인이 같은 것을 의존하는 것이 좋은건가?
    이번에는 저번 구현에서와는 다른 것을 경험해 보고 싶어서 중복해서 검증하고, 각 영역에서의 검증 코드를 따로 작성했습니다.

재사용한다면 domain, view 어느 방향으로든 의존이 생길텐데 저는 지양하고 싶군요!
어느쪽이든 domain 이 view의 변화에 영향을 받을 수 있으니까요!~
그래서 각각 검증코드를 사용할 것 같아요

현재는 간단한 Console Application 이고
로빈이 view 와 domain 을 모두 구현하고 있어서 이런 고민이 발생할 수 있다고 생각해요~!

public static void main(String[] args) {
LadderGame ladderGame = generateLadderGame();
RetryHelper retryHelper = new RetryHelper(10);
List<String> playerNames = getPlayerNames(retryHelper);
List<String> giftNames = getGiftNames(retryHelper, playerNames);
Integer ladderHeight = getLadderHeight(retryHelper);

printName(ladderGame);
printLadder(ladderGame);
printResults(ladderGame);
LadderGame ladderGame = makeLadderGame(playerNames, giftNames, ladderHeight);
printLadderGame(playerNames, giftNames, ladderGame);

List<String> rawNames = ladderGame.getRawNames();
printClimbResult(ladderGame, rawNames);
printLadderGameResults(playerNames, ladderGame);
}

private static LadderGame generateLadderGame() {
return RetryHelper.retry(() -> {
private static List<String> getPlayerNames(RetryHelper retryHelper) {
return retryHelper.retry(() -> {
OutputView.print("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)");
List<String> names = NameInputView.getNames(InputView::getInput);
OutputView.print("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)");
List<String> rawResults = ResultInputView.getResults(InputView::getInput, names.size());
OutputView.print("최대 사다리 높이는 몇 개인가요?");
int ladderHeight = Integer.parseInt(InputView.getInput());
return new LadderGame(names, ladderHeight, rawResults);
return PlayersInputView.getPlayerNames(InputView.getInput());
});
}

private static void printName(LadderGame ladderGame) {
OutputView.print(NamesPrinter.from(ladderGame.getRawNames()));
private static List<String> getGiftNames(RetryHelper retryHelper, List<String> playerNames) {
return retryHelper.retry(() -> {
OutputView.print("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)");
return GiftsInputView.getGiftNames(InputView.getInput(), playerNames.size());
});
}

private static void printLadder(LadderGame ladderGame) {
OutputView.print(LadderPrinter.from(ladderGame.getRawLadder()));
private static Integer getLadderHeight(RetryHelper retryHelper) {
return retryHelper.retry(() -> {
OutputView.print("최대 사다리 높이는 몇 개인가요?");
return LadderHeightInputView.getLadderHeight(InputView.getInput());
});
}

private static void printResults(LadderGame ladderGame) {
OutputView.print(NamesPrinter.from(ladderGame.getRawResults()));
private static LadderGame makeLadderGame(List<String> playerNames, List<String> giftNames, Integer ladderHeight) {
LineGenerateStrategy lineGenerateStrategy = new RandomLineGenerateStrategy();
return makeLadderGame(playerNames, giftNames, ladderHeight, lineGenerateStrategy);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위에 LineGenerateStrategy lineGenerateStrategy = new RandomLineGenerateStrategy(); 부분은 의미없는 변수 할당이 될 것 같아요!
극한의 이득을 챙기기위해 의미없는 변수할당도 없애보는건 어떠신가요 😄

return makeLadderGame(playerNames, giftNames, ladderHeight, new RandomLineGenerateStrategy());

}

private static void printClimbResult(LadderGame ladderGame, List<String> rawNames) {
String gameOperator = getGameOperator(ladderGame);

gameOperator = printClimbResultsUntilOperatorIsAll(ladderGame, gameOperator);

List<String> climbResults = ClimbResultPrinter.of(rawNames, ladderGame.getClimbResults(gameOperator));
climbResults.forEach(OutputView::print);
private static LadderGame makeLadderGame(List<String> playerNames, List<String> giftNames, Integer ladderHeight,
LineGenerateStrategy randomLineMakeStrategy) {
return LadderGameBuilder.builder()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LadderGameBuilder 가 외부로 노출되었는데
LadderGame.builder() 로 변경해보면 어떨까요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LadderGameBuilder 가 외부로 노출되었는데 LadderGame.builder() 로 변경해보면 어떨까요!

무슨 말인지 잘 모르겠습니다... 빌더는 외부로 노출되어야 하는 것이 아닌가요???

.players(playerNames)
.gifts(giftNames)
.ladderHeight(ladderHeight)
.lineGenerateStrategy(randomLineMakeStrategy)
.build();
}

private static String getGameOperator(LadderGame ladderGame) {
OutputView.print("결과를 보고 싶은 사람은?");
String gameOperator = RetryHelper.retry(
() -> LadderGameOperatorInputView.getOperator(InputView::getInput, ladderGame.getRawNames())
);
OutputView.print("실행 결과");
return gameOperator;
private static void printLadderGame(List<String> playerNames, List<String> giftNames, LadderGame ladderGame) {
OutputView.printPlayers(playerNames);
OutputView.printLadder(ladderGame.rawLadder());
OutputView.printGifts(giftNames);
}

private static String printClimbResultsUntilOperatorIsAll(LadderGame ladderGame, String gameOperator) {
while (!gameOperator.equals("all")) {
List<String> climbResults = ClimbResultPrinter.of(
List.of(gameOperator),
ladderGame.getClimbResults(gameOperator)
);
climbResults.forEach(OutputView::print);

gameOperator = getGameOperator(ladderGame);
private static void printLadderGameResults(List<String> playerNames, LadderGame ladderGame) {
String ladderGameResultOwner = showLadderGameResult(playerNames, ladderGame);
while (!ladderGameResultOwner.equals("all")) {
ladderGameResultOwner = showLadderGameResult(playerNames, ladderGame);
}
return gameOperator;
}

static final class RetryHelper {

public static <E> E retry(Supplier<E> supplier) {
E result = null;
while (result == null) {
result = useSupplier(supplier);
}
return result;
}

private static <E> E useSupplier(Supplier<E> supplier) {
try {
return supplier.get();
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
private static String showLadderGameResult(List<String> 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;
});
}
}
33 changes: 33 additions & 0 deletions src/main/java/domain/AbstractLineGenerateStrategy.java
Original file line number Diff line number Diff line change
@@ -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<Boolean> generate(int lineSize) {
List<Boolean> generate = new ArrayList<>(generateStrategy(lineSize));
fixInvalidBridges(generate);
return Collections.unmodifiableList(generate);
}

public abstract List<Boolean> generateStrategy(int lineSize);

private void fixInvalidBridges(List<Boolean> rawBridges) {
rawBridges.set(rawBridges.size() - 1, false);
for (int index = 1; index < rawBridges.size() - 1; index++) {
fixIfNeed(rawBridges, index);
}
}

private void fixIfNeed(List<Boolean> rawBridges, int index) {
if (isBridgeInARow(rawBridges, index)) {
rawBridges.set(index, false);
}
}

private boolean isBridgeInARow(List<Boolean> rawBridges, int index) {
return rawBridges.get(index) && rawBridges.get(index - 1);
}
}
7 changes: 0 additions & 7 deletions src/main/java/domain/BridgeGenerator.java

This file was deleted.

24 changes: 24 additions & 0 deletions src/main/java/domain/Direction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package domain;

import java.util.function.Function;

enum Direction {

RIGHT(index -> index + 1), LEFT(index -> index - 1), STRAIGHT(index -> index);
private final Function<Integer, Integer> nextIndexFunction;

Direction(Function<Integer, Integer> 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);
}
}
30 changes: 0 additions & 30 deletions src/main/java/domain/ExceptionType.java

This file was deleted.

Loading