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

3단계 - 사다리(게임 실행) #1986

Open
wants to merge 18 commits into
base: pawoo0211
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d869af9
[step2] refactor: 1단계 피드백 반영
pawoo0211 Nov 25, 2023
160a7c0
[step2] 사다리 README 작성
pawoo0211 Nov 25, 2023
3823578
[step2] feature: 사다리 타기 기초 뼈대 코드 구현
pawoo0211 Nov 26, 2023
46a3da7
[step2] feature: Line 일급 컬렉션 객체 구현 및 전체 클래스 위치 변경
pawoo0211 Nov 26, 2023
5065389
[step2] feature: 입력 화면 UI 구현
pawoo0211 Nov 26, 2023
e861b20
[step2] feature: Controller, Service 초기 뼈대 코드 구현
pawoo0211 Nov 26, 2023
59239b5
[step2] feature: 결과 출력 화면 UI 구현
pawoo0211 Nov 30, 2023
fdfd1aa
[step2] refactor: Controller 및 Service 리팩터링
pawoo0211 Nov 30, 2023
f0368e1
[step2] refactor: 사다리 출력 로직 리팩터링
pawoo0211 Dec 1, 2023
0262c6a
[step2] fix: 컴파일 에러 수정
pawoo0211 Dec 1, 2023
ed9a5c0
Merge branch 'pawoo0211' of https://github.com/next-step/java-ladder …
pawoo0211 Dec 1, 2023
73d70b1
[step2] refactor: step1 PR 피드백 반영
pawoo0211 Dec 1, 2023
cc08a71
[step3] test: 게임 실행 관련 테스트 코드 작성
pawoo0211 Dec 3, 2023
70a7d0f
[step3] feature: 참가자 도메인 구현
pawoo0211 Dec 3, 2023
bdeef4f
[step3] feature: Controller 및 Service에 게임 실행 로직 추가
pawoo0211 Dec 3, 2023
f746244
[step3] feature: 게임 실행 UI 기능 및 누락된 도메인 코드 추가
pawoo0211 Dec 3, 2023
90ab5e4
[step3] refactor: inputView 불필요한 코드 제거
pawoo0211 Dec 3, 2023
c346c8f
[step3] refactor: 불필요한 도메인 로직 삭제
pawoo0211 Dec 3, 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
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# 사디리
## 기능 요구사항
* 사다리 게임에 참여하는 사람에 이름을 부여할 수 있다.
* 이름은 최대 5글자로 제한된다.
* 사람의 이름은 띄어쓰기가 존재하지 않는 쉼표로 구분한다.
* 사다리의 모양은 |-----|으로 출력된다.
* 사다리를 출력할 때 사람 이름도 같이 출력한다.
* 참여하는 사람의 숫자에 따라 사다리의 폭과 사다리의 개수가 달라진다.
* |-----|-----| 같이 연속적인 사다리는 가능하지 않다.
* 하나의 라인에는 최소 하나 이상이 사다리가 존재하며 사다리의 개수는 랜덤하다.
[] 사다리 게임에 참여하는 사람에 이름을 부여할 수 있다.
[] 이름은 최대 5글자로 제한된다.
[] 사람의 이름은 띄어쓰기가 존재하지 않는 쉼표로 구분한다.
[] 사다리의 모양은 |-----|으로 출력된다.
[] 사다리를 출력할 때 사람 이름도 같이 출력한다.
[] 참여하는 사람의 숫자에 따라 사다리의 폭과 사다리의 개수가 달라진다.
[] |-----|-----| 같이 연속적인 사다리는 가능하지 않다.
[] 하나의 라인에는 최소 하나 이상이 사다리가 존재하며 사다리의 개수는 랜덤하다.
Comment on lines +3 to +10
Copy link

Choose a reason for hiding this comment

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

- [ ] 체크전
- [X] 체크후
문법은 이렇습니다 😄


## 프로그래밍 요구사항
* 최대한 자바 8의 스트림과 람다를 이용한다.
Expand Down
23 changes: 14 additions & 9 deletions src/main/java/nextstep/ladder/application/LadderController.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@ public class LadderController {

public static void main(String[] args) {
InputView inputView = new InputView();
String[] participants = splitParticipants(inputView);
String[] participants = inputView.inputParticipant();
String[] results = inputView.inputResults();
int highCount = inputView.inputHighCount();

LadderService ladderService = new LadderService();
LadderResponse response = ladderService.createLadder(new LadderRequest(participants, highCount));
LadderResponse createResponse = ladderService.findWinner(new LadderRequest(
participants,
results,
highCount));

LinePrinter printer = new LinePrinter(highCount);
ResultView resultView = new ResultView(printer, participants, response.getLines());
resultView.showResult();
}

private static String[] splitParticipants(InputView inputView) {
return inputView.inputParticipant()
.split(",");
ResultView resultView = new ResultView(
printer,
createResponse.getLines(),
createResponse.getParticipants(),
results);
resultView.showLadder();
resultView.showParticipant(inputView.inputWantShow());
resultView.showParticipant(inputView.inputWantShow());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@

public class LadderRequest {
private String[] participants;
private String[] results;
private int highCount;

public LadderRequest(String[] participants, int highCount) {
public LadderRequest(String[] participants, String[] results, int highCount) {
this.participants = participants;
this.results = results;
this.highCount = highCount;
}

public String[] getParticipants() {
return participants;
}

public String[] getResults() {
return results;
}

public int getHighCount() {
return highCount;
}
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/nextstep/ladder/application/dto/LadderResponse.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package nextstep.ladder.application.dto;

import nextstep.ladder.domain.line.Lines;
import nextstep.ladder.domain.participant.Participants;


public class LadderResponse {
private final Lines lines;
private Lines lines;
private Participants participants;

public LadderResponse(Lines lines) {
public LadderResponse(Lines lines, Participants participants) {
this.lines = lines;
this.participants = participants;
}

public Lines getLines() {
public final Lines getLines() {
return lines;
}

public final Participants getParticipants() {
return participants;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,25 @@
import nextstep.ladder.application.dto.LadderResponse;
import nextstep.ladder.domain.line.Line;
import nextstep.ladder.domain.line.Lines;
import nextstep.ladder.domain.participant.Participants;

import java.util.stream.IntStream;

public class LadderService {

public LadderResponse createLadder(LadderRequest request) {
Lines lines = new Lines(request.getHighCount());
IntStream.range(0, request.getHighCount())
.forEach(index -> lines.addLine(new Line(request.getParticipants())));
public LadderResponse findWinner(LadderRequest request) {
Lines lines = createLines(request);
Participants participants = Participants.of(request.getParticipants());
lines.moveParticipants(participants);
participants.insertMyResult(request.getResults());
return new LadderResponse(lines, participants);
}

return new LadderResponse(lines);
private Lines createLines(LadderRequest request) {
Lines lines = new Lines();
int rowLineNumber = request.getParticipants().length - 1;
IntStream.range(0, request.getHighCount())
.forEach(index -> lines.addLine(new Line(rowLineNumber)));
return lines;
Comment on lines +21 to +26
Copy link

Choose a reason for hiding this comment

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

request 에서 도메인 객체를 만들어줄수도 있지 않을까요? 🤔
request.toLines()
개인적으로 dto는 로직이 들어가지 않는 transfer 객체지만, dto 가 갖고있는 상태변수만을 가지고 domain을 만들수 있다면 dto에서 생성해주는 편이에요!
이 부분은 정답이 없으니 상권님이 고민해봐주세요!

}
}
49 changes: 47 additions & 2 deletions src/main/java/nextstep/ladder/domain/line/Line.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,60 @@
package nextstep.ladder.domain.line;

import nextstep.ladder.domain.participant.Participant;
import nextstep.ladder.domain.participant.Participants;

public class Line {
private final int rowLineNumber;
private RowLinePositions rowLinePosition;

public Line(String[] participants) {
int participantNumber = participants.length;
int rowLineNumber = participantNumber - 1;
rowLinePosition = new RowLinePositions(rowLineNumber);
rowLineNumber = participantNumber - 1;
rowLinePosition = RowLinePositions.create(rowLineNumber);
}

public Line(int rowLineNumber) {
this.rowLineNumber = rowLineNumber;
rowLinePosition = RowLinePositions.create(rowLineNumber);
}

public Line(int rowLineNumber, RowLinePositions rowLinePositions) {
this.rowLineNumber = rowLineNumber;
this.rowLinePosition = rowLinePositions;
Comment on lines +12 to +23
Copy link

Choose a reason for hiding this comment

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

생성자를 여러개 사용중이네요 👍
이런 경우 주생성자 부생성자를 나누어 사용하는게 좋습니다 :)

관련링크 남겨드리겠습니다
https://velog.io/@injoon2019/%EC%A3%BC-%EC%83%9D%EC%84%B1%EC%9E%90-%EB%B6%80-%EC%83%9D%EC%84%B1%EC%9E%90

}

public boolean isTruePosition(int index) {
return rowLinePosition.isTrue(index);
}

public void movableParticipants(Participants participants) {
participants.getParticipantList()
.stream()
.forEachOrdered(participant -> movableParticipant(participant));
}
Comment on lines +30 to +34
Copy link

Choose a reason for hiding this comment

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

값을 꺼내와서 비즈니스를 처리하고 있네요!
getter를 사용하지 않고 메세지를 보내는 방식으로 처리하는건 어떤가요? 🤔


public void movableParticipant(Participant participant) {
if (movableLeft(participant)) {
return;
}
movableRight(participant);
}

private boolean movableLeft(Participant participant) {
int index = participant.getCurrentIndex();
if (index != 0 && isTruePosition(index -1)) {
participant.moveLeft();
return true;
}
return false;
}

private boolean movableRight(Participant participant) {
int index = participant.getCurrentIndex();
if (index != rowLineNumber && isTruePosition(index)) {
participant.moveRight();
return true;
}
return false;
}
}
13 changes: 7 additions & 6 deletions src/main/java/nextstep/ladder/domain/line/Lines.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
package nextstep.ladder.domain.line;

import nextstep.ladder.domain.participant.Participants;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;

public class Lines {
private List<Line> lineList = new ArrayList<>();
private int highCount;

public Lines() {}

public Lines(int highCount) {
this.highCount = highCount;
}

public void addLine(Line line) {
lineList.add(line);
}

public void moveParticipants(Participants participants) {
lineList.stream()
.forEachOrdered(line -> line.movableParticipants(participants));
Copy link

Choose a reason for hiding this comment

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

메서드명이 boolean을 리턴할것 같은데 void 형식이군요!
간단하게 line.move(participants) 로 하는건 어떠신가요?

}

public final List<Line> getLineList() {
return Collections.unmodifiableList(lineList);
}
Expand Down
32 changes: 19 additions & 13 deletions src/main/java/nextstep/ladder/domain/line/RowLinePositions.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,41 @@
import java.util.stream.IntStream;

public class RowLinePositions {
private List<Boolean> positionList = new ArrayList<>();
private int rowLineCount;
private Random random = new Random();
private List<Boolean> positionList;
private int rowLineNumber;
private static final Random random = new Random();

public RowLinePositions(int rowLineCount) {
this.rowLineCount = rowLineCount;
initializePositionList();
public RowLinePositions(List<Boolean> positionList, int rowLineNumber) {
this.positionList = positionList;
this.rowLineNumber = rowLineNumber;
Comment on lines +14 to +16
Copy link

Choose a reason for hiding this comment

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

생성자에선 필수값체크정도 하는게 좋아보여요!
컬렉션 빈값이나 음수값체크정도해서 방어하는게 좋아보여요 🙂

}

private void initializePositionList() {
public static RowLinePositions create(int rowLineNumber) {
List<Boolean> positionList = new ArrayList<>();
initializePositionList(positionList, rowLineNumber);
return new RowLinePositions(positionList, rowLineNumber);
}

private static void initializePositionList(List<Boolean> positionList, int rowLineNumber) {
positionList.add(random.nextBoolean());
IntStream.range(1, rowLineCount)
.forEach(index -> addRandomBoolean(index));
addTrueIfAllFalse();
IntStream.range(1, rowLineNumber)
.forEach(index -> addRandomBoolean(positionList, index));
addTrueIfAllFalse(positionList, rowLineNumber);
}

private void addRandomBoolean(int index) {
private static void addRandomBoolean(List<Boolean> positionList, int index) {
if (positionList.get(index - 1)) {
positionList.add(false);
return;
}
positionList.add(random.nextBoolean());
}

private void addTrueIfAllFalse() {
private static void addTrueIfAllFalse(List<Boolean> positionList, int rowLineNumber) {
boolean isAllFalse = positionList.stream()
.allMatch(e -> e.equals(Boolean.FALSE));
if (isAllFalse) {
positionList.set(random.nextInt(rowLineCount), Boolean.TRUE);
positionList.set(random.nextInt(rowLineNumber), Boolean.TRUE);
}
}

Expand Down
42 changes: 42 additions & 0 deletions src/main/java/nextstep/ladder/domain/participant/Participant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package nextstep.ladder.domain.participant;


public class Participant {
private String name;
private int currentIndex;
private String result;

public Participant(String name, int currentIndex) {
this.name = name;
this.currentIndex = currentIndex;
}

public void moveLeft() {
currentIndex -= 1;
}

public void moveRight() {
currentIndex += 1;
}

public void insertResult(String[] results) {
result = results[currentIndex];
}

public String getName() {
return name;
}

public final int getCurrentIndex() {
return currentIndex;
}

public String getResult() {
return result;
}

@Override
public String toString() {
return "{name:" + name + "}" + "{currentPosition:" + currentIndex + "}" + "|";
}
}
41 changes: 41 additions & 0 deletions src/main/java/nextstep/ladder/domain/participant/Participants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package nextstep.ladder.domain.participant;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Participants {
private final List<Participant> participantList;

public Participants(List<Participant> participantList) {
this.participantList = participantList;
}

public static Participants of(String[] participants) {
List<Participant> participantList = new ArrayList<>();
Arrays.stream(participants)
.forEach(participant -> participantList.add(new Participant(participant, participantList.size())));
return new Participants(participantList);
}

public void insertMyResult(String[] results) {
participantList.stream()
.forEach(participant -> participant.insertResult(results));
}

public Participant findByName(String name) {
return participantList.stream()
.filter(participant -> participant.getName().equals(name))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Can not find name"));
}

public int getParticipantsNumber() {
return participantList.size();
}

public final List<Participant> getParticipantList() {
return Collections.unmodifiableList(participantList);
}
}
Loading