Skip to content
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

[1단계 - 사다리 생성] 허브(방대의) 미션 제출합니다. #97

Merged
merged 30 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
244004a
docs: 요구사항 정리
greeng00se Feb 14, 2023
187cab7
feat: 참가자 생성 기능 구현
greeng00se Feb 14, 2023
3eb9db8
remove: 사용하지 않는 SuppressWarning 제거
greeng00se Feb 14, 2023
2564118
feat: LineStatus 생성 구현
greeng00se Feb 14, 2023
bb8e17c
feat: Line 생성 구현
greeng00se Feb 15, 2023
97fb1f8
feat: Ladder 생성 구현
greeng00se Feb 15, 2023
8c620ed
feat: 입력 기능 구현
greeng00se Feb 15, 2023
aee791d
feat: 출력 기능 구현
greeng00se Feb 15, 2023
7d48c69
refactor: 메소드 분리 및 호출 순서 변경
greeng00se Feb 16, 2023
7c53ea0
feat: LadderGame 생성 구현
greeng00se Feb 16, 2023
1b77fbc
docs: 요구사항 정리
greeng00se Feb 16, 2023
aac2877
feat: 랜덤 Boolean 값을 반환하는 기능 추가
greeng00se Feb 16, 2023
f97ccc8
refactor: 사람이름을 List<String>으로 받도록 타입 변경
greeng00se Feb 16, 2023
343ab37
feat: 컨트롤러 구현
greeng00se Feb 16, 2023
d848e51
feat: 게임 실행 기능 구현
greeng00se Feb 16, 2023
c39048b
feat: Player에 대한 일급 컬렉션 구현
greeng00se Feb 16, 2023
194c4d1
refactor: Players 적용
greeng00se Feb 16, 2023
e949722
refactor: LineStatus 상태 확인 메소드 추가
greeng00se Feb 16, 2023
f856fcb
test: Test용 BooleanGenerator 구현
greeng00se Feb 16, 2023
570baeb
refactor: 가로라인 생성에 대한 책임 분리
greeng00se Feb 16, 2023
45f4c01
remove: 사용하지 않는 equals & hashcode 제거
greeng00se Feb 16, 2023
dad109f
style: 공백 정리
greeng00se Feb 16, 2023
9c202f0
refactor: final 선언 빠진부분 추가
greeng00se Feb 16, 2023
13d946b
feat: 참가인원 반환 기능 추가
greeng00se Feb 16, 2023
b0ba707
feat: 에러 메시지 출력 기능 추가
greeng00se Feb 16, 2023
e5acabe
feat: 재입력 기능 추가
greeng00se Feb 16, 2023
3ac7d2e
docs: 요구사항 정리
greeng00se Feb 16, 2023
e36141e
test: final 빠진 부분 추가
greeng00se Feb 16, 2023
9c6732b
refactor: 상수 재사용 가능하도록 변경
greeng00se Feb 16, 2023
0a8418c
refactor: 이해하기 어려운 조건 메서드로 분리
greeng00se Feb 16, 2023
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
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,52 @@
## 우아한테크코스 코드리뷰

- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md)

### 다이어그램

```mermaid
graph TD

LadderGameController --> LadderGame
LadderGame --> Ladder
LadderGame --> Players

Players --> Player

LadderGameController --> InputView
LadderGameController --> OutputView

Ladder --> Line
Line --> LineStatus
```

Copy link
Member

Choose a reason for hiding this comment

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

기능목록을 상세하게 잘 작성해주셨네요 👍🏻

### 참가자

- [x] 참가자는 이름을 가진다.
- [x] 이름은 1자 이상, 5자 이하의 길이를 가진다.
- [x] 이름이 없거나, 5자를 초과하는 경우 예외를 던진다.
- [x] 참가자는 최소 2명 이어야 한다.
- [x] 참가자가 1명 이하인 경우 예외를 던진다.
- [x] 참가자들의 이름은 중복될 수 없다.
- [x] 중복된 이름이 존재하는 경우 예외를 던진다.

### 사다리

- [x] 사다리는 높이를 가진다.
- [x] 사다리 가로 라인을 가진다.
- [x] 사다리 가로 라인의 상태가 연속으로 `연결됨` 상태일 수 없다.
- [x] 각각의 가로 라인은 상태를 가진다.
- [x] 연결됨, 연결되지 않음으로 구분된다.

### 입력

- [x] 사람 이름은 쉼표(,)를 기준으로 구분하여 입력받는다.
- [x] 이름의 앞뒤 공백을 제거한다.
- [x] 최대 사다리 높이를 입력받는다.
- [x] 1보다 작은 값을 입력하는 경우 예외를 던진다.

### 출력

- [x] 최대 사람이름을 기준으로 사다리 폭이 넓어진다.


Empty file removed src/main/java/.gitkeep
Empty file.
33 changes: 33 additions & 0 deletions src/main/java/ladder/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ladder;

import java.util.Scanner;
import ladder.controller.LadderGameController;
import ladder.domain.RandomBooleanGenerator;
import ladder.view.InputView;
import ladder.view.OutputView;

public class Application {

public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
final LadderGameController ladderGameController = new LadderGameController(
booleanGenerator(),
inputView(scanner),
outputView()
);
ladderGameController.run();
}
}

private static RandomBooleanGenerator booleanGenerator() {
return new RandomBooleanGenerator();
}

private static OutputView outputView() {
return new OutputView();
}

private static InputView inputView(final Scanner scanner) {
return new InputView(scanner);
}
}
60 changes: 60 additions & 0 deletions src/main/java/ladder/controller/LadderGameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package ladder.controller;

import java.util.List;
import ladder.domain.BooleanGenerator;
import ladder.domain.LadderGame;
import ladder.domain.Line;
import ladder.domain.Players;
import ladder.view.InputView;
import ladder.view.OutputView;

public class LadderGameController {

private final BooleanGenerator booleanGenerator;
private final InputView inputView;
private final OutputView outputView;

public LadderGameController(
final BooleanGenerator booleanGenerator,
final InputView inputView,
final OutputView outputView
) {
this.booleanGenerator = booleanGenerator;
this.inputView = inputView;
this.outputView = outputView;
}

public void run() {
final LadderGame ladderGame = initialize();
final List<String> players = ladderGame.getPlayers();
final List<Line> ladder = ladderGame.getLadder();

outputView.printResult(players, ladder);
Comment on lines +28 to +32
Copy link
Member

Choose a reason for hiding this comment

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

View를 깔끔하게 잘 분리해주셨네요 👍🏻

}

private LadderGame initialize() {
final Players players = readPlayers();
final int height = readHeight();

return new LadderGame(booleanGenerator, players, height);
}

private Players readPlayers() {
try {
final List<String> names = inputView.readPlayerNames();
return new Players(names);
} catch (IllegalArgumentException e) {
outputView.printError(e.getMessage());
return readPlayers();
}
}

private int readHeight() {
try {
return inputView.readLadderHeight();
} catch (IllegalArgumentException e) {
outputView.printError(e.getMessage());
return readHeight();
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/ladder/domain/BooleanGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ladder.domain;

public interface BooleanGenerator {
boolean generate();
}
Comment on lines +3 to +5
Copy link
Member

Choose a reason for hiding this comment

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

인터페이스 추출 👍🏻

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

import static java.util.stream.Collectors.toUnmodifiableList;

import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

class Ladder {

private final List<Line> lines;

public Ladder(final BooleanGenerator booleanGenerator, final int height, final int width) {
this.lines = generateLines(booleanGenerator, height, width);
}

private List<Line> generateLines(final BooleanGenerator booleanGenerator, final int height, final int width) {
return Stream.generate(() -> new Line(booleanGenerator, width))
.limit(height)
.collect(toUnmodifiableList());
}

public List<Line> getLines() {
return Collections.unmodifiableList(lines);
}
}
24 changes: 24 additions & 0 deletions src/main/java/ladder/domain/LadderGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ladder.domain;

import java.util.List;

public class LadderGame {

private static final int SUBTRACT_VALUE_OF_LADDER_WIDTH = 1;

private final Players players;
private final Ladder ladder;

public LadderGame(final BooleanGenerator booleanGenerator, final Players players, final int height) {
this.players = players;
this.ladder = new Ladder(booleanGenerator, height, players.count() - SUBTRACT_VALUE_OF_LADDER_WIDTH);
}

public List<String> getPlayers() {
return players.getNames();
}

public List<Line> getLadder() {
return ladder.getLines();
}
}
36 changes: 36 additions & 0 deletions src/main/java/ladder/domain/Line.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ladder.domain;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;

public class Line {

private final List<LineStatus> statuses;

public Line(final BooleanGenerator booleanGenerator, final int width) {
this.statuses = generateLine(booleanGenerator, width);
}

private List<LineStatus> generateLine(final BooleanGenerator booleanGenerator, final int width) {
final Deque<LineStatus> statuses = new ArrayDeque<>();
for (int i = 0; i < width; i++) {
statuses.add(generateLineStatus(booleanGenerator, statuses));
}
return new ArrayList<>(statuses);
}

private LineStatus generateLineStatus(final BooleanGenerator booleanGenerator, final Deque<LineStatus> statuses) {
final boolean status = booleanGenerator.generate();
if (statuses.isEmpty() || statuses.getLast().isDisconnected()) {
return LineStatus.from(status);
}
return LineStatus.DISCONNECTED;
}

public List<LineStatus> getLine() {
return Collections.unmodifiableList(statuses);
}
}
21 changes: 21 additions & 0 deletions src/main/java/ladder/domain/LineStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ladder.domain;

public enum LineStatus {
CONNECTED,
DISCONNECTED;

public static LineStatus from(final boolean status) {
if (status) {
return CONNECTED;
}
return DISCONNECTED;
}

public boolean isConnected() {
return this == CONNECTED;
}

public boolean isDisconnected() {
return this == DISCONNECTED;
}
}
27 changes: 27 additions & 0 deletions src/main/java/ladder/domain/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ladder.domain;

public class Player {
private static final String INVALID_NAME_LENGTH_MESSAGE = "이름은 1자 이상, 5자 이하여야 한다.";
private static final int NAME_LENGTH_UPPER_BOUND = 5;

private final String name;

public Player(final String name) {
validate(name);
this.name = name;
}

private void validate(final String name) {
if (isInvalidNameLength(name)) {
throw new IllegalArgumentException(INVALID_NAME_LENGTH_MESSAGE);
}
}

private boolean isInvalidNameLength(final String name) {
return name.isBlank() || NAME_LENGTH_UPPER_BOUND < name.length();
}

public String getName() {
return name;
}
}
53 changes: 53 additions & 0 deletions src/main/java/ladder/domain/Players.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package ladder.domain;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Players {
private static final int PLAYERS_SIZE_LOWER_BOUND = 2;
private static final String INVALID_PLAYERS_SIZE_MESSAGE = "참가자는 최소 두명이어야 합니다.";
private static final String DUPLICATE_NAMES_MESSAGE = "참가자의 이름은 중복되지 않아야 합니다.";

private final List<Player> players;

public Players(final List<String> names) {
validate(names);
this.players = generatePlayers(names);
}

private void validate(final List<String> names) {
validatePlayersSize(names);
validateDuplicateNames(names);
}

private void validatePlayersSize(final List<String> names) {
if (names.size() < PLAYERS_SIZE_LOWER_BOUND) {
throw new IllegalArgumentException(INVALID_PLAYERS_SIZE_MESSAGE);
}
}

private void validateDuplicateNames(final List<String> names) {
final Set<String> nonDuplicateNames = new HashSet<>(names);
if (nonDuplicateNames.size() != names.size()) {
throw new IllegalArgumentException(DUPLICATE_NAMES_MESSAGE);
}
}

private List<Player> generatePlayers(final List<String> names) {
return names.stream()
.map(Player::new)
.collect(Collectors.toUnmodifiableList());
}

public List<String> getNames() {
return players.stream()
.map(Player::getName)
.collect(Collectors.toUnmodifiableList());
}

public int count() {
return players.size();
}
}
13 changes: 13 additions & 0 deletions src/main/java/ladder/domain/RandomBooleanGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ladder.domain;

import java.util.Random;

public class RandomBooleanGenerator implements BooleanGenerator {

private final Random random = new Random();

@Override
public boolean generate() {
return random.nextBoolean();
}
}
Loading