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

[2단계 - 사다리 게임 실행] 허브(방대의) 미션 제출합니다. #234

Merged
merged 71 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
53baf2e
refactor: 사다리높이 입력 예외 메시지가 자세한 내용을 출력하도록 수정
greeng00se Feb 18, 2023
63388cd
refactor: 반환할 때만 불변 리스트로 생성하도록 변경
greeng00se Feb 18, 2023
6f71881
feat: 가로 라인(Line)을 생성하는 정적 팩터리 메서드 추가
greeng00se Feb 18, 2023
e4d47ad
refactor: 가로 라인(Line) 정적 팩터리 메서드 적용
greeng00se Feb 18, 2023
8dd1b1f
feat: 사다리(Ladder)를 생성하는 정적 팩터리 메서드 추가
greeng00se Feb 18, 2023
84d108c
feat: 사다리를 생성하는 정적 팩터리 메서드 적용
greeng00se Feb 18, 2023
190e693
refactor: Players 생성할 때 정적 팩터리 메서드 적용
greeng00se Feb 18, 2023
16c94d5
style: booleanGenerator 매개변수명 변경
greeng00se Feb 18, 2023
c137477
refactor: OutputView 가독성 개선
greeng00se Feb 19, 2023
0e9f359
refactor: LadderGame 정적 팩터리 메서드 적용
greeng00se Feb 20, 2023
cdd3c8f
refactor: 불필요한 코드 제거
greeng00se Feb 20, 2023
f90c14c
docs: 2단계 요구사항 추가
greeng00se Feb 20, 2023
5127aea
refactor: 참가자의 이름에 대한 예외 메시지 수정
greeng00se Feb 20, 2023
3ef389d
feat: 실행 결과(Item)를 표현하는 클래스 추가
greeng00se Feb 20, 2023
6d0605e
feat: Player이 이름 검증시 null check 기능 추가
greeng00se Feb 20, 2023
cf9d52b
feat: Item의 일급 컬렉션 추가
greeng00se Feb 21, 2023
21fde32
feat: 실행결과 입력 기능 추가
greeng00se Feb 21, 2023
48977ba
refactor: final 빠진 부분 추가
greeng00se Feb 21, 2023
4ab0b42
feat: LadderGame Items 필드 추가
greeng00se Feb 21, 2023
a3c6182
feat: 위치를 표현하는 클래스 추가
greeng00se Feb 21, 2023
e293af6
feat: 이름을 표현하는 Name 클래스 추가
greeng00se Feb 21, 2023
112f329
feat: 참가자와 실행결과에 Position 적용
greeng00se Feb 22, 2023
3527a00
feat: 참가자수 상한선 설정
greeng00se Feb 22, 2023
7660742
feat: 이전 위치, 다음 위치를 반환하는 기능 추가
greeng00se Feb 22, 2023
afb96fd
feat: 입력한 값까지의 Position을 반환하는 메서드 추가
greeng00se Feb 22, 2023
8c7c997
feat: 가로라인 한 줄에 대한 사다리 게임을 진행하는 기능 추가
greeng00se Feb 22, 2023
86748d9
feat: 한 위치에 대한 사다리 게임 진행 기능 추가
greeng00se Feb 23, 2023
fd278f6
style: 메서드 위치 변경
greeng00se Feb 23, 2023
7de3d99
feat: 게임 결과를 위한 클래스 추가
greeng00se Feb 23, 2023
4cfd6ee
refactor: Items, Players 저장시 Map을 사용하도록 수정
greeng00se Feb 23, 2023
d5a2024
refactor: 게임 결과의 타입 변경
greeng00se Feb 23, 2023
c50ec09
feat: 예약어는 이름으로 사용하지 못하도록 하는 기능 추가
greeng00se Feb 23, 2023
933e2be
feat: 모든 참가자에 대한 사다리 게임을 진행하는 기능 추가
greeng00se Feb 23, 2023
03e46fa
feat: 사다리의 출력 문자열을 생성하는 클래스 추가
greeng00se Feb 23, 2023
758df5a
feat: 실행결과 출력 기능 추가
greeng00se Feb 23, 2023
e866678
feat: 사다리게임 결과 출력 기능 추가
greeng00se Feb 23, 2023
39e192c
refactor: 문자열 비교 위치 변경
greeng00se Feb 23, 2023
20d6371
style: equals랑 getter 순서 변경
greeng00se Feb 24, 2023
bcc9c07
feat: 사다리 높이 원시값 포장
greeng00se Feb 24, 2023
74e5f71
style: 공백 제거
greeng00se Feb 24, 2023
2dfe990
feat: 사용자의 이름을 원시값 포장
greeng00se Feb 24, 2023
7cf5ae9
refactor: players가 리스트를 사용하도록 수정
greeng00se Feb 24, 2023
7f66159
feat: Item 이름에 대한 원시값 포장 클래스 추가
greeng00se Feb 24, 2023
1682d00
refactor: Item 이름에 대한 원시값 포장 클래스 적용
greeng00se Feb 24, 2023
346bbb0
feat: 입력받은 위치와 같은 위치인지 확인하는 메서드 추가
greeng00se Feb 24, 2023
9fab87d
feat: 참가자가 사다리를 받아 사다리 타기를 진행하는 기능 추가
greeng00se Feb 24, 2023
c492ff5
feat: 모든 참가자가 사다리 타기를 진행하는 기능 추가
greeng00se Feb 24, 2023
aaa3b86
refactor: LadderGameResult의 타입 변경
greeng00se Feb 24, 2023
dd5b2a0
refactor: players에 ladder를 넘겨주는 방법으로 사다리 게임 진행 변경
greeng00se Feb 24, 2023
932fcec
remove: 사용하지 않는 메서드 제거
greeng00se Feb 24, 2023
908ed1a
style: 도메인 패키지 분리
greeng00se Feb 24, 2023
85a8b51
refactor: 사다리 게임 결과 타입 재변경
greeng00se Feb 24, 2023
6457ea7
remove: 사용하지 않는 equals & hashcode 제거
greeng00se Feb 24, 2023
576cdbb
docs: 요구사항 정리
greeng00se Feb 24, 2023
e96ec85
refactor: final 빠진 부분 추가
greeng00se Feb 24, 2023
64db4b6
refactor: Items를 생성하는 정적팩터리 메서드명 of로 변경
greeng00se Feb 25, 2023
3b4c7f4
refactor: OutputView로 객체 바로 전달하도록 수정
greeng00se Feb 25, 2023
46bdddf
refactor: Position의 생성 책임을 Items에서 Item에게 할당
greeng00se Feb 25, 2023
a79b044
refactor: Position의 생성 책임을 Players에서 Player에게 할당
greeng00se Feb 25, 2023
e8918af
refactor: 이름을 확인할 때 getter가 아닌 메시지를 보내도록 수정
greeng00se Feb 25, 2023
b64ae2f
refactor: 깊은 고민없이 패키지 분리한 부분 다시 원래대로 변경
greeng00se Feb 25, 2023
c4565fd
refactor: BooleanGenerator와 구현체 util 패키지로 이동
greeng00se Feb 25, 2023
2f844e6
refactor: 이름에 대한 테스트명 수정
greeng00se Feb 25, 2023
082d975
refactor: 예외 메시지 package-private으로 변경
greeng00se Feb 25, 2023
2aee49b
fix: 결과 확인할 때 존재하지 않는 이름 입력시 종료되는 부분 수정
greeng00se Feb 25, 2023
661cdf6
refactor: 결과를 위한 입력 검증 부분 최적화
greeng00se Feb 25, 2023
3e3c4b9
refactor: 불필요한 this 제거
greeng00se Feb 26, 2023
7e28ac7
refactor: LadderMessageGenerator 인스턴스생성 불가능 하도록 수정
greeng00se Feb 26, 2023
08dc6db
refactor: LadderGameCommand 분리
greeng00se Feb 26, 2023
e0c224a
test: DisplayNameGeneration 빠진 부분 추가
greeng00se Feb 26, 2023
8206c8b
refactor: Position을 사용하는 입장에서 명확하도록 변경
greeng00se Feb 27, 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
2 changes: 1 addition & 1 deletion src/main/java/ladder/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

Expand Down
52 changes: 21 additions & 31 deletions src/main/java/ladder/controller/LadderGameController.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package ladder.controller;

import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import ladder.domain.item.Items;
import ladder.domain.ladder.BooleanGenerator;
import ladder.domain.ladder.Height;
import ladder.domain.ladder.LadderGame;
import ladder.domain.ladder.LadderGameResult;
import ladder.domain.ladder.Line;
import ladder.domain.player.Players;
import ladder.domain.Height;
import ladder.domain.Items;
import ladder.domain.LadderGame;
import ladder.domain.LadderGameResult;
import ladder.domain.Players;
import ladder.util.BooleanGenerator;
import ladder.view.InputView;
import ladder.view.OutputView;

Expand All @@ -31,14 +28,14 @@ public LadderGameController(

public void run() {
final LadderGame ladderGame = initialize();
printLadderResult(ladderGame);
outputView.printLadderResult(ladderGame);
final LadderGameResult ladderGameResult = ladderGame.play();
printLadderGameResult(ladderGameResult);
}

private LadderGame initialize() {
final Players players = repeatUntilGetValidInput(() -> Players.from(inputView.readPlayerNames()));
final Items items = repeatUntilGetValidInput(() -> Items.from(inputView.readItemNames(), players.count()));
final Items items = repeatUntilGetValidInput(() -> Items.of(inputView.readItemNames(), players.count()));
final Height height = repeatUntilGetValidInput(() -> new Height(inputView.readLadderHeight()));

return LadderGame.initialize(players, booleanGenerator, height, items);
Expand All @@ -53,39 +50,32 @@ private <T> T repeatUntilGetValidInput(final Supplier<T> inputReader) {
}
}

private void printLadderResult(final LadderGame ladderGame) {
final List<String> players = ladderGame.getPlayers();
final List<Line> ladder = ladderGame.getLadder();
final List<String> items = ladderGame.getItems();

outputView.printLadderResult(players, ladder, items);
}

private void printLadderGameResult(final LadderGameResult ladderGameResult) {
LadderGameCommand command = LadderGameCommand.SINGLE;
while (command.isContinued()) {
final Map<String, String> result = repeatUntilGetValidInput(() -> getLadderGameResult(ladderGameResult));
command = LadderGameCommand.from(result.size());
outputView.printLadderGameResult(result);
final String name = repeatUntilGetValidInput(() -> getValidPlayerName(ladderGameResult));
command = LadderGameCommand.from(name);
outputView.printLadderGameResult(ladderGameResult, name);
}
}

private Map<String, String> getLadderGameResult(final LadderGameResult ladderGameResult) {
private String getValidPlayerName(final LadderGameResult ladderGameResult) {
final String name = inputView.readPlayerName();
return ladderGameResult.get(name);
ladderGameResult.validatePlayerName(name);
return name;
}

enum LadderGameCommand {
ALL,
private enum LadderGameCommand {
MULTIPLE,
SINGLE;

private static final int SINGLE_RESULT_SIZE = 1;
private static final String MULTIPLE_RESULT_RESERVED_NAME = "all";

public static LadderGameCommand from(final int size) {
if (size == SINGLE_RESULT_SIZE) {
return SINGLE;
public static LadderGameCommand from(final String name) {
if (MULTIPLE_RESULT_RESERVED_NAME.equals(name)) {
return MULTIPLE;
}
return ALL;
return SINGLE;
}

public boolean isContinued() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package ladder.domain.ladder;
package ladder.domain;

public class Height {
private static final int HEIGHT_LOWER_BOUND = 1;
private static final int HEIGHT_UPPER_BOUND = 100;
private static final String INVALID_HEIGHT_MESSAGE =
static final String INVALID_HEIGHT_MESSAGE =
"높이는 " + HEIGHT_LOWER_BOUND + "이상, " + HEIGHT_UPPER_BOUND + "이하의 값이어야 합니다.";

private final int value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package ladder.domain.item;

import ladder.domain.ladder.Position;
package ladder.domain;

public class Item {
private final ItemName name;
private final Position position;

public Item(final String name, final Position position) {
this.name = new ItemName(name);
private Item(final ItemName name, final Position position) {
this.name = name;
this.position = position;
}

public static Item of(final String name, final int index) {
return new Item(new ItemName(name), Position.valueOf(index));
}

public boolean isSamePosition(final Position position) {
return this.position == position;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package ladder.domain.item;
package ladder.domain;

public class ItemName {
private static final int NAME_LENGTH_UPPER_BOUND = 5;
private static final String INVALID_NAME_LENGTH_MESSAGE =
static final String INVALID_NAME_LENGTH_MESSAGE =
"실행 결과명은 1자 이상, " + NAME_LENGTH_UPPER_BOUND + "자 이하여야 합니다.";

private final String value;

public ItemName(final String name) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
package ladder.domain.item;
package ladder.domain;

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

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import ladder.domain.ladder.Position;

public class Items {
private static final String INVALID_ITEM_COUNT_MESSAGE = "참가인원과 동일한 개수의 실행결과를 입력해야 합니다.";
private static final String INVALID_ITEM_MESSAGE = "해당 위치에 있는 아이템이 존재하지 않습니다.";
static final String INVALID_ITEM_COUNT_MESSAGE = "참가인원과 동일한 개수의 실행결과를 입력해야 합니다.";
static final String INVALID_ITEM_MESSAGE = "해당 위치에 있는 아이템이 존재하지 않습니다.";

private final List<Item> items;

private Items(final List<Item> items) {
this.items = items;
}

public static Items from(final List<String> names, int playerCount) {
public static Items of(final List<String> names, int playerCount) {
validateItemCount(names, playerCount);
return IntStream.range(0, names.size())
.mapToObj(index -> new Item(names.get(index), Position.valueOf(index)))
.mapToObj(index -> Item.of(names.get(index), index))
.collect(Collectors.collectingAndThen(Collectors.toList(), Items::new));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package ladder.domain.ladder;
package ladder.domain;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toList;

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

public class Ladder {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package ladder.domain.ladder;
package ladder.domain;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import ladder.domain.item.Item;
import ladder.domain.item.Items;
import ladder.domain.player.Player;
import ladder.domain.player.Players;
import ladder.util.BooleanGenerator;

public class LadderGame {
private static final int SUBTRACT_LADDER_WIDTH_VALUE = 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package ladder.domain.ladder;
package ladder.domain;

import java.util.LinkedHashMap;
import java.util.Map;
import ladder.domain.item.Item;
import ladder.domain.player.Player;

public class LadderGameResult {
static final String INVALID_PLAYER_MESSAGE = "사다리 게임에 참가한 사람의 이름을 입력해야합니다.";
private static final String MULTIPLE_RESULT_RESERVED_NAME = "all";
private static final String INVALID_PLAYER_MESSAGE = "사다리 게임에 참가한 사람의 이름을 입력해야합니다.";

private final Map<Player, Item> result;

Expand Down Expand Up @@ -42,8 +40,23 @@ private Map<String, String> getSingleResult(final String name) {

private Player findPlayer(final String name) {
return result.keySet().stream()
.filter(player -> player.getName().equals(name))
.filter(player -> player.isSameName(name))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(INVALID_PLAYER_MESSAGE));
}

public void validatePlayerName(final String name) {
if (isNotReservedName(name) && isInvalidPlayerName(name)) {
throw new IllegalArgumentException(INVALID_PLAYER_MESSAGE);
}
}

private boolean isNotReservedName(final String name) {
return !MULTIPLE_RESULT_RESERVED_NAME.equals(name);
begaonnuri marked this conversation as resolved.
Show resolved Hide resolved
}

private boolean isInvalidPlayerName(final String name) {
return this.result.keySet().stream()
.noneMatch(player -> player.isSameName(name));
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package ladder.domain.ladder;
package ladder.domain;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import ladder.util.BooleanGenerator;

public class Line {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ladder.domain.ladder;
package ladder.domain;

public enum LineStatus {
CONNECTED,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
package ladder.domain.player;

import ladder.domain.ladder.Ladder;
import ladder.domain.ladder.Position;
package ladder.domain;

public class Player {
private final PlayerName name;
private final Position position;

public Player(final String name, final Position position) {
this.name = new PlayerName(name);
private Player(final PlayerName name, final Position position) {
this.name = name;
this.position = position;
}

public static Player of(final String name, final int index) {
return new Player(new PlayerName(name), Position.valueOf(index));
}

public Position play(final Ladder ladder) {
return ladder.play(position);
}

public boolean isSameName(final String name) {
return this.name.isSameAs(name);
}

public boolean isSamePosition(final Position position) {
return this.position == position;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package ladder.domain.player;
package ladder.domain;

public class PlayerName {
static final String RESERVED_NAME_MESSAGE = "all은 사용할 수 없는 이름입니다.";
private static final int NAME_LENGTH_UPPER_BOUND = 5;
private static final String INVALID_NAME_LENGTH_MESSAGE =
"이름은 1자 이상, " + NAME_LENGTH_UPPER_BOUND + "자 이하여야 합니다.";
static final String INVALID_NAME_LENGTH_MESSAGE = "이름은 1자 이상, " + NAME_LENGTH_UPPER_BOUND + "자 이하여야 합니다.";
private static final String RESERVED_NAME = "all";
private static final String RESERVED_NAME_MESSAGE = "all은 사용할 수 없는 이름입니다.";

private final String value;

Expand Down Expand Up @@ -35,6 +34,10 @@ private void validateReservedName(final String name) {
}
}

public boolean isSameAs(final String name) {
return value.equals(name);
}

private boolean isReservedName(final String name) {
return RESERVED_NAME.equals(name);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ladder.domain.player;
package ladder.domain;

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

Expand All @@ -9,17 +9,15 @@
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import ladder.domain.ladder.Ladder;
import ladder.domain.ladder.Position;

public class Players {
static final String DUPLICATE_NAMES_MESSAGE = "참가자의 이름은 중복되지 않아야 합니다.";
static final String INVALID_PLAYER_MESSAGE = "해당 위치에 있는 참가자가 존재하지 않습니다.";
private static final int PLAYERS_SIZE_LOWER_BOUND = 2;
private static final int PLAYERS_SIZE_UPPER_BOUND = 20;
private static final String INVALID_PLAYERS_SIZE_MESSAGE =
static final String INVALID_PLAYERS_SIZE_MESSAGE =
"참가자는 최소 " + PLAYERS_SIZE_LOWER_BOUND + "명, 최대 " + PLAYERS_SIZE_UPPER_BOUND + "명이어야 합니다.";
private static final String DUPLICATE_NAMES_MESSAGE = "참가자의 이름은 중복되지 않아야 합니다.";
private static final String INVALID_PLAYER_MESSAGE = "해당 위치에 있는 참가자가 존재하지 않습니다.";


private final List<Player> players;

private Players(final List<Player> players) {
Expand All @@ -29,7 +27,7 @@ private Players(final List<Player> players) {
public static Players from(final List<String> names) {
validate(names);
return IntStream.range(0, names.size())
.mapToObj(index -> new Player(names.get(index), Position.valueOf(index)))
.mapToObj(index -> Player.of(names.get(index), index))
.collect(Collectors.collectingAndThen(Collectors.toList(), Players::new));
}

Expand Down
Loading