-
Notifications
You must be signed in to change notification settings - Fork 60
[사다리 미션] 정상희 미션 제출합니다. #19
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
base: sangheejeong
Are you sure you want to change the base?
Changes from 30 commits
1196afa
8b96693
f20be9f
19995ef
49d105c
090cb0f
06a00a7
3e47a2a
07fe975
2265787
2fef17c
f7ab094
dbbb328
65d58d2
56b093f
5c6b21e
67fcc5a
74f098d
9763754
a16726a
69871ca
169ec00
ea543eb
e81fa34
047d483
2dfe464
42cdbd6
62f451d
422af42
494e2d9
b2b1220
7dbb8cd
67b09e4
5c280c4
8eac61b
beeb626
570c4d7
6f6b09a
95f8ec1
f31cacc
e43ee2d
7e4cd52
f8dce70
ac02d9c
d48bce2
ea12de3
01b8efe
7cf78a6
174ff32
6b26030
1d96fb1
0bd1928
76e1d31
6473cca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import domain.Ladder; | ||
| import domain.LadderGame; | ||
| import domain.LadderGenerator; | ||
| import domain.Players; | ||
| import domain.ResultTypes; | ||
| import view.OutputView; | ||
| import view.InputView; | ||
|
|
||
| import java.util.List; | ||
|
|
||
|
|
||
| public class Main { | ||
| public static void main(String[] args) { | ||
| // 사다리 게임 시작 | ||
| final LadderGame ladderGame = new LadderGame(); | ||
|
|
||
| // 플레이어 생성 | ||
| final List<String> playerNames = InputView.splitString(InputView.inputNames()); | ||
| final Players players = new Players(playerNames); | ||
|
|
||
| // 실행결과 생성 | ||
| final List<String> kindOfResults = InputView.splitString(InputView.inputLadderResults()); | ||
| final ResultTypes resultTypes = new ResultTypes(kindOfResults, players.getPlayersSize()); | ||
|
|
||
| // 사다리 생성 | ||
| final int width = players.getPlayersSize(); | ||
| final int height = InputView.inputHeight(); | ||
|
|
||
| final LadderGenerator ladderGenerator = new LadderGenerator(); | ||
| final Ladder ladder = ladderGenerator.createLadder(width, height); | ||
|
|
||
| // 사다리 그리기 | ||
| OutputView.printPlayers(playerNames); | ||
| OutputView.drawLadder(ladder); | ||
| OutputView.printResultTypes(resultTypes.getResultTypes()); | ||
|
|
||
| // 사다리 게임 시작 | ||
| ladderGame.runGame(ladder, players); | ||
|
|
||
| // 결과 출력 | ||
| OutputView.printResult(players, resultTypes.getResultTypes()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package domain; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| public class Ladder { | ||
| private final List<Line> lines; | ||
|
|
||
| public Ladder(List<Line> lines) { | ||
| this.lines = lines; | ||
| } | ||
|
|
||
| public List<Line> getLadder() { | ||
| return Collections.unmodifiableList(lines); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package domain; | ||
|
|
||
| public class LadderGame { | ||
|
|
||
| public void movePlayer(Line line, Player player) { | ||
| if (line.canMoveRight(player.getPosition())) { | ||
| player.moveRight(); | ||
| return; | ||
| } | ||
|
|
||
| if (line.canMoveLeft(player.getPosition())) { | ||
| player.moveLeft(); | ||
| } | ||
| } | ||
|
|
||
| public void moveEachPlayer(Ladder ladder, Player player) { | ||
| ladder.getLadder().forEach(line -> movePlayer(line, player)); | ||
| } | ||
|
||
|
|
||
| public void runGame(Ladder ladder, Players players) { | ||
| players.getPlayers().forEach(player -> moveEachPlayer(ladder, player)); | ||
| } | ||
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import static java.lang.Boolean.TRUE; | ||
|
|
||
| public class LadderGenerator { | ||
|
|
||
| public boolean randomTrueOrFalse() { | ||
| return Math.random() < 0.5; // 0.0(포함) - 1.0(미포함) 사이의 랜덤한 실수 반환 | ||
SANGHEEJEONG marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| public boolean createValue(List<Boolean> line, int index) { | ||
SANGHEEJEONG marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (index != 0 && line.get(index - 1) == TRUE) // 이전 값이 true 면 false 반환 | ||
| return false; | ||
|
|
||
| return randomTrueOrFalse(); | ||
| } | ||
|
|
||
| public Line createLine(int width) { | ||
| List<Boolean> points = new ArrayList<>(); | ||
| for (int i = 0; i < width - 1; i++) { | ||
| points.add(createValue(points, i)); | ||
| } | ||
|
|
||
| return new Line(points); | ||
| } | ||
|
|
||
| public Ladder createLadder(int width, int height) { | ||
| List<Line> lines = new ArrayList<>(); | ||
| for (int i = 0; i < height; i++) { | ||
| lines.add(createLine(width)); | ||
| } | ||
|
|
||
| return new Ladder(lines); | ||
| } | ||
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package domain; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| import static java.lang.Boolean.TRUE; | ||
|
|
||
| public class Line { | ||
| private final List<Boolean> points; | ||
|
||
|
|
||
| public Line(List<Boolean> points) { | ||
| this.points = points; | ||
| } | ||
|
|
||
| public boolean canMoveRight(int ladderOrder) { | ||
| return (ladderOrder < points.size()) && (points.get(ladderOrder) == TRUE); | ||
| } | ||
|
|
||
| public boolean canMoveLeft(int ladderOrder) { | ||
| return (ladderOrder != 0) && (points.get(ladderOrder - 1) == TRUE); | ||
| } | ||
|
|
||
| public List<Boolean> getLine() { | ||
| return Collections.unmodifiableList(points); | ||
| } | ||
SANGHEEJEONG marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package domain; | ||
|
|
||
| public class Name { | ||
|
|
||
| private final String name; | ||
| private final static int MAX_LENGTH = 5; | ||
| private final static String INVALID_NAME = "all"; | ||
|
|
||
| public Name(String name) { | ||
| validateName(name); | ||
| this.name = name; | ||
| } | ||
|
|
||
| private void validateName(String name) { | ||
| validateMaxLength(name); | ||
| validateNotBlank(name); | ||
| validateNotEqualAll(name); | ||
| } | ||
|
|
||
| private void validateNotBlank(String name) { | ||
| if (name.isBlank()) { | ||
SANGHEEJEONG marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| throw new IllegalArgumentException("이름은 공백일 수 없습니다."); | ||
| } | ||
| } | ||
|
|
||
| private void validateMaxLength(String name) { | ||
| if (name.length() > MAX_LENGTH) { | ||
| throw new IllegalArgumentException("이름은 5자를 초과할 수 없습니다."); | ||
| } | ||
| } | ||
|
|
||
| private void validateNotEqualAll(String name) { | ||
| if (name.equals(INVALID_NAME)) { | ||
| throw new IllegalArgumentException("이름은 all일 수 없습니다."); | ||
| } | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package domain; | ||
|
|
||
| public class Player { | ||
|
|
||
| private final Name name; | ||
| private final Position position; | ||
|
|
||
| public Player(Name name, Position position) { | ||
| this.name = name; | ||
| this.position = position; | ||
| } | ||
|
|
||
| public void moveLeft() { | ||
| position.movePositionLeft(); | ||
| } | ||
|
|
||
| public void moveRight() { | ||
| position.movePositionRight(); | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name.getName(); | ||
| } | ||
|
|
||
| public int getPosition() { | ||
| return position.getPosition(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.NoSuchElementException; | ||
|
|
||
| public class Players { | ||
|
|
||
| private final List<Player> players; | ||
| private final static int MIN_PLAYER_SIZE = 2; | ||
|
|
||
| public Players(List<String> playerNames) { | ||
| validateSize(playerNames); | ||
| this.players = createPlayer(playerNames); | ||
| } | ||
|
|
||
| private void validateSize(List<String> playerNames) { | ||
| if (playerNames.size() < MIN_PLAYER_SIZE) { | ||
| throw new IllegalArgumentException("플레이어 수는 2명 이상이어야 합니다."); | ||
| } | ||
| } | ||
|
|
||
| private List<Player> createPlayer(List<String> playerNames) { | ||
| List<Player> players = new ArrayList<>(); | ||
| for (int i = 0; i < playerNames.size(); i++) { | ||
| players.add(new Player(new Name(playerNames.get(i)), new Position(i))); | ||
| } | ||
|
|
||
| return players; | ||
| } | ||
|
|
||
| public Player findByName(String viewerName) { | ||
| return players.stream() | ||
| .filter(player -> player.getName().equals(viewerName)) | ||
| .findFirst() | ||
| .orElseThrow(() -> new NoSuchElementException("플레이어 이름 '" + viewerName + "' 이 존재하지 않습니다.")); | ||
| } | ||
|
|
||
| public List<Player> getPlayers() { | ||
| return Collections.unmodifiableList(players); | ||
| } | ||
|
Comment on lines
+53
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Approve] 방어적 복사 👍👍 |
||
|
|
||
| public int getPlayersSize() { | ||
| return players.size(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package domain; | ||
|
|
||
| public class Position { | ||
|
|
||
| private int position; | ||
|
|
||
| public Position(int position) { | ||
| this.position = position; | ||
| } | ||
|
|
||
| public void movePositionLeft() { | ||
| position--; | ||
| } | ||
|
||
|
|
||
| public void movePositionRight() { | ||
| position++; | ||
| } | ||
|
|
||
| public int getPosition() { | ||
| return position; | ||
| } | ||
|
Comment on lines
+25
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Comment] position을 getter로 꺼내는 방식 보다 조금 더 이 값에 대해서 판단을 이 Position이란 객체에게 맡겨보는 것은 어떨까요? 위의 리뷰들을 참고해서 한번 변경해보면 좋을 것 같아요 |
||
|
|
||
SANGHEEJEONG marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package domain; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class ResultTypes { | ||
|
|
||
| private final List<String> resultTypes; | ||
|
|
||
| public ResultTypes(List<String> resultTypes, int width) { | ||
| validate(resultTypes, width); | ||
| this.resultTypes = resultTypes; | ||
| } | ||
|
|
||
| private void validate(List<String> resultTypes, int width) { | ||
| resultTypes.forEach(this::validateNotBlank); | ||
| validateSize(resultTypes, width); | ||
| } | ||
|
|
||
| private void validateNotBlank(String resultType) { | ||
| if (resultType.isBlank()) { | ||
| throw new IllegalArgumentException("실행 결과는 공백일 수 없습니다."); | ||
| } | ||
| } | ||
|
|
||
| private void validateSize(List<String> resultTypes, int width) { | ||
| if (resultTypes.size() != width) { | ||
| throw new IllegalArgumentException("실행 결과는 사다리의 개수와 일치해야 합니다."); | ||
| } | ||
| } | ||
|
|
||
| public List<String> getResultTypes() { | ||
| return resultTypes; | ||
| } | ||
| } | ||
|
Comment on lines
+5
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [�Comment] 이 List은 List 같이 의도가 분명한 Wrapper클래스로 감싸지 않은 이유가 있나요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Result에 대한 속성이 단순히 문자형 결과이고 이에 따른 책임이 유효성 검증밖에 없다고 생각해서 굳이 나누지 않았습니다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Comment] 사실 위에서 한 유효성 검증은 ResultType 하나의 요소에 대한 검증이지, List 자체에 대한 검증은 아닌 것 같기도 하네요. 그치만, 저도 상희님이 말씀하신 것 처럼 꼭 래핑할 이유는 없다고 생각해요 해당 클래스만으로도 충분히 의미전달이 된다고 생각합니다 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package view; | ||
|
|
||
| public class InputException { | ||
|
||
|
|
||
| public static void validateHeightSize(int height) { | ||
| if (height < 1) { | ||
| throw new IllegalArgumentException("사다리 높이는 1 이상이어야 합니다."); | ||
| } | ||
| } | ||
|
|
||
| public static void validateViewerNameNotBlank(String viewerName) { | ||
| if (viewerName.isBlank()) { | ||
| throw new IllegalArgumentException("이름은 공백일 수 없습니다."); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package view; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.Scanner; | ||
|
|
||
| public class InputView { | ||
| private static final Scanner input = new Scanner(System.in); | ||
|
|
||
| public static List<String> splitString(String string) { | ||
| return Arrays.asList(string.split(",")); | ||
| } | ||
|
|
||
| public static String inputNames() { | ||
| System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); | ||
| return input.nextLine(); | ||
| } | ||
|
|
||
| public static String inputLadderResults() { | ||
| System.out.println("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); | ||
| return input.nextLine(); | ||
| } | ||
|
|
||
| public static int inputHeight() { | ||
| System.out.println("최대 사다리 높이는 몇 개인가요?"); | ||
| int height = input.nextInt(); | ||
| InputException.validateHeightSize(height); | ||
| input.nextLine(); | ||
| return height; | ||
| } | ||
|
|
||
| public static String inputViewerName() { | ||
| System.out.println("\n결과를 보고 싶은 사람은?"); | ||
| String viewerName = input.nextLine(); | ||
| InputException.validateViewerNameNotBlank(viewerName); | ||
| return viewerName; | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Request Change] 유저는 실수로 잘못 입력한건데 프로그램이 에러로 꺼지는 것은 너무 가혹한 것 같아요. 재입력을 받아보게 바꿀 수 있을까요? |
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.