-
Notifications
You must be signed in to change notification settings - Fork 53
[사다리] 이예진 사다리 게임 구현 (1-5단계) #66
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
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
7686f8c
docs: 요구사항 문서 작성
yaevrai 88dea60
feat(level1): 사다리 출력
yaevrai 7196c8e
feat(level2): 사다리 생성
yaevrai 15d8a2e
feat(level3): 사다리 타기
yaevrai 4a6b1c7
feat(level4,5): 게임 실행 + 리팩토링
yaevrai 40e6aba
feat(level5): PR 리뷰 반영
yaevrai File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# java-ladder : 사다리 - 함수형 프로그래밍 | ||
|
||
## Level1. 사다리 출력 | ||
|
||
### - 요구사항 | ||
|
||
- [x] 네이버 사다리 게임을 참고하여 도메인을 분석하여 구현한다. | ||
- [x] 사다리는 4x4 크기로 고정되고, 연결 여부는 랜덤으로 결정한다. | ||
- [x] 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다. | ||
- [x] 모든 엔티티를 작게 유지한다. | ||
- [x] 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다. | ||
|
||
## Level2. 사다리 생성 | ||
|
||
### - 요구사항 | ||
|
||
- [x] 사다리는 크기를 입력 받아 생성할 수 있다. (넓이 & 높이) | ||
|
||
## Level3. 사다리 타기 | ||
|
||
### - 요구사항 | ||
|
||
- [x] 사다리의 시작 지점과 도착 지점을 출력한다. | ||
|
||
## Level4. 게임 실행 | ||
|
||
### - 요구사항 | ||
|
||
- [x] 사다리 게임에 참여하는 사람에 이름을 최대 5글자까지 부여할 수 있다. 사다리를 출력할 때 사람 이름도 같이 출력한다. | ||
- [x] 사람 이름은 쉼표(,)를 기준으로 구분한다. | ||
- [x] 개인별 이름을 입력하면 개인별 결과를 출력하고, "all"을 입력하면 전체 참여자의 실행 결과를 출력한다. | ||
|
||
## Level5. 리팩토링 | ||
|
||
### - 요구사항 | ||
|
||
- [x] 학습 테스트를 통해 학습한 내용을 반영한다. 자바에서 제공하는 함수형 문법을 적용해보고, 어떠한 차이가 있는지 경험한다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package ladder.controller; | ||
|
||
import ladder.view.InputView; | ||
import ladder.view.OutputView; | ||
|
||
public class Application { | ||
public static void main(String[] args) { | ||
InputView inputView = new InputView(); | ||
OutputView outputView = new OutputView(); | ||
LadderGame game = new LadderGame(inputView, outputView); | ||
game.play(); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package ladder.controller; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import ladder.model.Ladder; | ||
import ladder.model.LadderResult; | ||
import ladder.model.Participants; | ||
import ladder.model.Point; | ||
import ladder.model.Result; | ||
import ladder.view.InputView; | ||
import ladder.view.OutputView; | ||
|
||
public class LadderGame { | ||
|
||
private final InputView inputView; | ||
private final OutputView outputView; | ||
|
||
public LadderGame(InputView inputView, OutputView outputView) { | ||
this.inputView = inputView; | ||
this.outputView = outputView; | ||
} | ||
|
||
public void play() { | ||
Participants participants = inputView.inputParticipants(); | ||
List<Result> results = inputView.inputResults(); | ||
int height = inputView.inputHeight(); | ||
|
||
Ladder ladder = Ladder.create(participants.size(), height); | ||
outputView.printLadder(ladder, participants, results); | ||
|
||
String resultRequest = inputView.inputGameResult(); | ||
processResult(ladder, participants, results, resultRequest); | ||
} | ||
|
||
private void processResult(Ladder ladder, Participants participants, List<Result> results, | ||
String resultRequest) { | ||
List<Point> ladderResults = ladder.result(); | ||
List<Result> mappedResults = mapResults(results, ladderResults); | ||
LadderResult ladderResult = new LadderResult(participants, mappedResults); | ||
printGameResults(resultRequest, ladderResult); | ||
} | ||
|
||
private void printGameResults(String result, LadderResult gameLadderResult) { | ||
if ("all".equals(result)) { | ||
outputView.printAllResults(gameLadderResult); | ||
return; | ||
} | ||
outputView.printSingleResult(gameLadderResult.getResult(result)); | ||
} | ||
|
||
private List<Result> mapResults(List<Result> inputResults, List<Point> ladderResults) { | ||
return ladderResults.stream() | ||
.map(point -> inputResults.get(point.getEnd())) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package ladder.model; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
public class Ladder { | ||
|
||
private final List<Line> lines; | ||
|
||
private Ladder(List<Line> lines) { | ||
this.lines = lines; | ||
} | ||
|
||
public static Ladder create(int width, int height) { | ||
return new Ladder( | ||
IntStream.range(0, height) | ||
.mapToObj(i -> Line.create(width)) | ||
.collect(Collectors.toList()) | ||
); | ||
} | ||
|
||
public List<Line> getLines() { | ||
return lines; | ||
} | ||
|
||
public List<Point> result() { | ||
int width = lines.get(0).getPoints().size() + 1; | ||
return IntStream.range(0, width) | ||
.mapToObj(start -> new Point(start, getEndPoint(start))) // 출발점과 도착점을 Point로 묶음 | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private int getEndPoint(int start) { | ||
int position = start; | ||
|
||
for (Line line : lines) { | ||
position = move(position, line.getPoints()); | ||
} | ||
|
||
return position; | ||
} | ||
|
||
private int move(int position, List<Boolean> points) { | ||
if (canMoveLeft(position, points)) { | ||
return position - 1; | ||
} | ||
|
||
if (canMoveRight(position, points)) { | ||
return position + 1; | ||
} | ||
|
||
return position; | ||
} | ||
|
||
private boolean canMoveLeft(int position, List<Boolean> points) { | ||
return position > 0 && points.get(position - 1); | ||
} | ||
|
||
private boolean canMoveRight(int position, List<Boolean> points) { | ||
return position < points.size() && points.get(position); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package ladder.model; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class LadderResult { | ||
|
||
private final Participants participants; | ||
private final List<Result> results; | ||
|
||
public LadderResult(Participants participants, List<Result> results) { | ||
this.participants = participants; | ||
this.results = results; | ||
} | ||
|
||
public List<Result> getAll() { | ||
return new ArrayList<>(results); | ||
} | ||
|
||
public List<Name> getParticipants() { | ||
return participants.getParticipantsNameList(); | ||
} | ||
|
||
public Result getResult(String participant) { | ||
return participants.getParticipantsNameList().stream() | ||
.filter(name -> name.matches(participant)) | ||
.findFirst() | ||
.map(name -> results.get(participants.getParticipantsNameList().indexOf(name))) | ||
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 참가자입니다.")); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package ladder.model; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Random; | ||
|
||
public class Line { | ||
|
||
private static final Random random = new Random(); | ||
private final List<Boolean> points; | ||
|
||
private Line(List<Boolean> points) { | ||
this.points = points; | ||
} | ||
|
||
public List<Boolean> getPoints() { | ||
return new ArrayList<>(points); | ||
} | ||
|
||
public static Line create(int width) { | ||
List<Boolean> connections = new ArrayList<>(); | ||
for (int i = 0; i < width - 1; i++) { | ||
// 새로운 라인 연결 여부 | ||
boolean shouldConnect = isConnectable(i, connections); | ||
connections.add(shouldConnect); | ||
} | ||
return new Line(connections); | ||
} | ||
|
||
private static boolean isConnectable(int currentIndex, List<Boolean> connections) { | ||
// 첫 번째 위치라면? 바로 Random 값 설정 | ||
if (currentIndex == 0) { | ||
return random.nextBoolean(); | ||
} | ||
|
||
// 바로 이전 연결 여부를 확인 -> 연속된 라인(true) 방지 | ||
boolean previousConnected = connections.get(currentIndex - 1); | ||
return !previousConnected && new Random().nextBoolean(); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package ladder.model; | ||
|
||
import java.util.Objects; | ||
|
||
public class Name { | ||
|
||
private static final int MAX_LENGTH = 5; | ||
private final String value; | ||
|
||
public Name(String value) { | ||
if (value.length() > MAX_LENGTH) { | ||
throw new IllegalArgumentException("이름은 최대 5글자까지 가능합니다."); | ||
} | ||
this.value = value; | ||
} | ||
|
||
public boolean matches(String other) { | ||
return value.equals(other); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return value; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Name name = (Name) o; | ||
return Objects.equals(value, name.value); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(value); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package ladder.model; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class Participants { | ||
|
||
private final List<Name> names; | ||
|
||
private Participants(List<Name> names) { | ||
this.names = names; | ||
} | ||
|
||
public static Participants of(List<Name> names) { | ||
return new Participants(new ArrayList<>(names)); | ||
} | ||
|
||
public int size() { | ||
return names.size(); | ||
} | ||
|
||
public List<Name> getParticipantsNameList() { | ||
return new ArrayList<>(names); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package ladder.model; | ||
|
||
import java.util.Objects; | ||
|
||
public class Point { | ||
|
||
private final int start; | ||
private final int end; | ||
|
||
public Point(int start, int end) { | ||
this.start = start; | ||
this.end = end; | ||
} | ||
|
||
public int getStart() { | ||
return start; | ||
} | ||
|
||
public int getEnd() { | ||
return end; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Point point = (Point) o; | ||
return start == point.start && end == point.end; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(start, end); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Point{" + "start=" + start + ", end=" + end + '}'; | ||
} | ||
Comment on lines
+40
to
+43
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. 위 Name 리뷰에서 이어지는 내용인데, |
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package ladder.model; | ||
|
||
public class Result { | ||
|
||
private final String value; | ||
|
||
public Result(String value) { | ||
if (value == null || value.isBlank()) { | ||
throw new IllegalArgumentException("결과 값은 비어있을 수 없습니다."); | ||
} | ||
this.value = value; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return value; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Result result = (Result) o; | ||
return value.equals(result.value); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return value.hashCode(); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name의 경우 필드가 하나만 존재해서, toString을 정의하여 사용해도 되지만...
toString의 사용은 디버깅 또는 로깅 목적으로 사용하는 것이 바람직해요.
https://stackoverflow.com/questions/2329168/when-to-use-tostring-method
특정 클래스는
toString
을 정의하지 않는다면 코드 간 일관성이 떨어지게 되고, 이는 유지보수성의 저하로 이어지게 될 거예요.(이전 리뷰에도 남겼지만, toString이 사용자의 응답에 영향이 간다는 것을 쉽게 알아차리기 힘들어요)