Skip to content
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
b07a49c
<FEAT> 기능 명세서 파일 추가
davidolleh Oct 30, 2024
f493a05
<FEAT> input, ouput view class 추가
davidolleh Oct 30, 2024
2254785
<FEAT> 연결 관련 enum class들 추가
davidolleh Oct 30, 2024
e0ffcfb
<FEAT> controller 객체 추가
davidolleh Oct 30, 2024
02b6a8d
<FEAT> line 객체 추가
davidolleh Oct 30, 2024
7cf4555
<FEAT> 참여자 객체 추가
davidolleh Oct 30, 2024
dcf7dc4
<FEAT> main 함수 추가
davidolleh Oct 30, 2024
06cc958
<FEAT> 당첨 객체 추가
davidolleh Oct 30, 2024
fc66931
<FEAT> 사다리 객체 추가
davidolleh Oct 30, 2024
2e22fee
<FEAT> 사다리 랜덤 생성 객체 추가
davidolleh Oct 30, 2024
613461c
<FIX> 이름 수정
davidolleh Oct 30, 2024
ed047ab
<FIX> 사다리 랜덤 생성 객체 추상화로 분리
davidolleh Oct 30, 2024
71d47c7
<FIX> nextInt 입력 받는거 nextLine으로 변경
davidolleh Oct 30, 2024
dd7174d
<FEAT> width, height ladder의 field로 추가
davidolleh Oct 30, 2024
5781a34
<FEAT> value object로 변경, 예외처리 추가
davidolleh Oct 30, 2024
9b5c7b5
<FEAT> 사다리 결과 출력 기능 추가
davidolleh Oct 30, 2024
125810f
<FEAT> Prize vo로 변경
davidolleh Oct 30, 2024
92408bb
<FEAT> 실행 결과 기능들 추가
davidolleh Oct 31, 2024
431bd39
<FEAT> 실행 결과 객체 추가
davidolleh Oct 31, 2024
77f88a7
<FEAT> controller 기능 추가
davidolleh Oct 31, 2024
9d693f0
<FEAT> Ladder 자동생성 테스트 추가
davidolleh Oct 31, 2024
91e4ceb
<FEAT> 기능 명세서 추가
davidolleh Oct 31, 2024
b70c3a5
<FIX> Indent 1로 마추려고 수정
davidolleh Oct 31, 2024
c76ef4a
<FIX> tmp 변수로 변경
davidolleh Oct 31, 2024
a09be2f
<FIX> 함수로 분리
davidolleh Oct 31, 2024
9bacca2
<FEAT> 개행문자 추가
davidolleh Oct 31, 2024
d767643
<FEAT> Person, Statistic 관련 test 추가
davidolleh Oct 31, 2024
6aef072
<FIX> warning 제거
davidolleh Oct 31, 2024
5402201
<FIX> 함수로 분리
davidolleh Oct 31, 2024
726700e
<FEAT> prize test 추가
davidolleh Oct 31, 2024
a2f5884
<FEAT> 기능명세서 기능 추가
davidolleh Oct 31, 2024
f567502
<FIX> warning 제거
davidolleh Oct 31, 2024
e278cc8
<REFACTOR> 1. Person 값 객체로 사용하지 않도록 수정, 2. 메서드 이름 동사형으로 수정
davidolleh Nov 12, 2024
bf26804
<REFACTOR> README 구체적으로 추가
davidolleh Nov 14, 2024
915c745
<REFACTOR> 변수 이름 수정
davidolleh Nov 14, 2024
d5eda95
<REFACTOR> 금액의 꽝에 대한 처리를 outputview의 역할로 수정
davidolleh Nov 14, 2024
6bf7754
<REFACTOR> Ladder 생성 로직과 entity 분리
davidolleh Nov 15, 2024
39d71d8
<REFACTOR> Line 이름 수정
davidolleh Nov 16, 2024
0c759b5
<REFACTOR> README 추가
davidolleh Nov 16, 2024
d67a2e9
<REFACTOR> line 특정 rowIndex의 방향 가져오는 함수 구현
davidolleh Nov 16, 2024
936a471
<REFACTOR> Ladder의 필드 RowLine으로 변경
davidolleh Nov 18, 2024
5aa5433
<REFACTOR> main class 이름 수정
davidolleh Nov 18, 2024
7057283
<REFACTOR> LadderGame 실행 구현
davidolleh Nov 18, 2024
d766f09
<REFACTOR> LadderGame 실행 구현
davidolleh Nov 18, 2024
f3dd305
<REFACTOR> Controller, OutputView LadderGame에 맞춰서 수정
davidolleh Nov 18, 2024
1d25eb1
<REFACTOR> 사용하지 않는 파일 삭제
davidolleh Nov 18, 2024
8f5d014
<REFACTOR> person record로 수정
davidolleh Nov 18, 2024
3268173
<REFACTOR> README 추가 작성
davidolleh Nov 18, 2024
19585d2
<REFACTOR> 불필요한 함서 제거
davidolleh Nov 18, 2024
afe1ed8
<REFACTOR> 필드 final로 변경
davidolleh Nov 18, 2024
a866afb
<REFACTOR> class record로 변경
davidolleh Nov 18, 2024
0c974c9
<REFACTOR> class record로 변경
davidolleh Nov 18, 2024
8bda0a9
<REFACTOR> LadderFactory 추상화
davidolleh Nov 18, 2024
4547ffe
<REFACTOR> 오타 수정
davidolleh Nov 20, 2024
7481d5d
<REFACTOR> 참여자 테스트 구현
davidolleh Nov 20, 2024
a08a3c9
<REFACTOR> 파일 삭제
davidolleh Nov 20, 2024
27da6f5
<REFACTOR> README 추가
davidolleh Nov 20, 2024
7e3f2e8
<REFACTOR> 테스트 구현
davidolleh Nov 20, 2024
81e327f
<REFACTOR> 정적 변수러 설정
davidolleh Nov 20, 2024
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
44 changes: 42 additions & 2 deletions README.md

Choose a reason for hiding this comment

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

리뷰가 처음이여서 부족할 수 있습니다.. 참고 부탁드립니다 :)

Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
- [x] 연결 여부는 랜덤으로 결정한다.
- [x] 사다리는 라인이 겹치지 않아야 한다.
# java-ladder

자바 사다리 미션 저장소

## 개요

참여자와 상품을 입력 받아 랜덤 사다리를 만들어 참여자와 상품을 연결시켜주는 게임이다.

## 요구사항

### 사람(Person)

- [x] 사람의 이름은 1자 이상 5자 이하여야 한다.

### 참여자(Participant)

- [x] 참여자들은 사다리에서 자신의 위치를 갖고 있다.
- [X] 참여자들은 정해진 라인을 따라 이동한다.

### 참여자들(Participants)

- [x] 참여자들의 이름은 중복이 될 수 없다.
- [x] 각 라인의 출발점에는 하나의 사람만 있을 수 있다.

### 상품(Prize)

- [x] 상품은 금액으로 이루어져 있다.
- [x] 상품의 금액이 값을 표현한다.(vo를 표현할 수 있는 말이 무엇이 있을까?)

### 라인(RowLine)

- [x] 라인들의 각 지점은 오른쪽, 왼쪽, 아래쪽 방향성 중 하나만을 가질 수 있다.
- [x] 라인이 연결성은 겹치지 않아야 한다.
- [x] 라인의 연결 여부는 랜덤으로 결정한다.

### 사다리(Ladder)

- [x] 여러개의 Line이 모여 하나의 사다리를 만든다.

### 사다리 게임(LadderGame)

- [x] 참여자들을 라인 따라 이동해 상품과 최종적으로 연결을 맺는다.
- [x] 게임이 완료되어야 최종 게임 결과를 확인할 수 있다.

Choose a reason for hiding this comment

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

[Approve]

이전보다 리드미를 비즈니스 로직에 가깝게 작성해주셨네요.

리뷰하는 입장에서도 승준님이 어떤 의도로 도메인을 설계했는지 이해하기 좋습니다👍👍👍👍👍👍

Empty file removed src/main/java/.gitkeep
Empty file.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import view.InputView;
import view.OutputView;

public class LadderGame {
public class LadderGameApplication {
public static void main(String[] args) {
LadderGameController ladderGameController = new LadderGameController(
new InputView(),
Expand Down
37 changes: 19 additions & 18 deletions src/main/java/LadderGameController.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,29 @@ public LadderGameController(InputView inputView, OutputView outputView) {
}

public void ladderGame() {
List<Person> participants = readParticipants();
List<Person> people = readParticipants();
List<Prize> prizes = readPrizes();

checkPrizeCountValidation(participants.size(), prizes.size());
validateInputsCount(people.size(), prizes.size());

int height = readLadderHeight();
int width = people.size();

Ladder ladder = new Ladder(height, participants.size(), new RandomLadderGeneratorImpl());
LadderFactory ladderGenerator = new RandomLadderFactory(height, width);
Ladder ladder = ladderGenerator.newInstance();

outputView.printResult(participants, ladder, prizes);
Participants participants = Participants.fromPeople(people);
LadderGame ladderGame = new LadderGame(participants, ladder, prizes);

Statistic statistic = new Statistic(ladder, participants, prizes);
outputView.printResult(ladderGame.getParticipants(), ladderGame.getLadder(), ladderGame.getPrizes());

printSpecificParticipantResult(statistic, participants);
ladderGame.start();

outputView.printParticipantsPrizesResult(statistic.getParticipantPrize(), participants);
GameResult gameResult = ladderGame.getParticipantsPrizes();

printSpecificParticipantResult(ladderGame.getParticipants(), gameResult);

outputView.printParticipantsPrizesResult(ladderGame.getParticipants(), gameResult);
}

Choose a reason for hiding this comment

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

[Commnet]

저희가 Controller를 사용한 것은

  1. Model과 View를 따로 관리한다.
  2. Controller가 호출하여 연결한다.

이런 역할을 부여하기 위해서 사용하였습니다.
ladderGame()메서드는 위 역할 외에도 게임의 흐름을 결정하는 역할도 있는 것 같아요.
그래서 메서드가 매우 길어진 것으로 보입니다.
이 메서드를 줄여보는 것도 좋은 연습이 될 것 같습니다.

리뷰는 이만 여기서 마칠 계획이라 추가적인 RC는 드리지 않을 것입니다.
혹시 해당 리뷰에 대해 더 알아보고 싶으시면 상희님 PR을 참고해주시고, 질문 있으면 DM 주세요.😄


private List<Person> readParticipants() {
Expand Down Expand Up @@ -65,29 +72,23 @@ private String readParticipantName() {
return name;
}

private void printSpecificParticipantResult(Statistic statistic, List<Person> participants) {
while(true) {
private void printSpecificParticipantResult(Participants participants, GameResult gameResult) {
while (true) {
String name = readParticipantName();

if (name.equals("all")) {
break;
}

Person person = new Person(name);
checkParticipantValidation(participants, person);
outputView.printParticipantPrizeResult(statistic.getParticipantPrize(person));
Participant participant = participants.getParticipantByName(person);
outputView.printParticipantPrizeResult(gameResult.getPrize(participant));
}
}

private void checkPrizeCountValidation(int participantCount, int prizeCount) {
private void validateInputsCount(int participantCount, int prizeCount) {
if (participantCount != prizeCount) {
throw new IllegalArgumentException("The number of participants does not match the number of prizes.");
}
}

private void checkParticipantValidation(List<Person> participants, Person person) {
if (!participants.contains(person)) {
throw new IllegalArgumentException("참여자가 아닙니다.");
}
}
}
8 changes: 7 additions & 1 deletion src/main/java/domain/Direction.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package domain;

public enum Direction {
LEFT, RIGHT, DOWN
LEFT(-1), RIGHT(1), DOWN(0);

final int offset;

Direction(int offset) {
this.offset = offset;
}

Choose a reason for hiding this comment

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

[Comment]

offset이라는 필드로 enum에 의한 움직임 동작을 정의하신 것이 인상적인네요!!
제 리뷰도 최대한 반영해주시려 한 것 같아서 감사합니다.

Choose a reason for hiding this comment

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

📝 Enum에 함수형 인터페이스 넣어보기 0

더 이 사다리 미션에 대한 리뷰 티키타카가 어려울 것 같습니다.
enum에 책임 부여를 더 했으면 좋겠다는 제 리뷰에 대해 제 예상 결과물을 일방적으로 전달을 드려보겠습니다.
물론 정답의 의미로 드린다기 보단 함수형 인터페이스 활용과 Enum에도 책임을 부여할 수 있다는 하나의 예시정도로 생각해주세요.

Comment on lines +4 to +10

Choose a reason for hiding this comment

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

📝 Enum에 함수형 인터페이스 넣어보기 1

enum에도 메서드로 동작을 정의해볼 수 있을 것 같아요!!

Suggested change
LEFT(-1), RIGHT(1), DOWN(0);
final int offset;
Direction(int offset) {
this.offset = offset;
}
public enum Direction {
LEFT(-1),
RIGHT(1),
DOWN(0);
private final int offset;
Direction(int offset) {
this.offset = offset;
}
public int move(int position) {
return position + offset;
}

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

import java.util.Map;

public class GameResult {
private final Map<Participant, Prize> gameResult;

public GameResult(Map<Participant, Prize> gameResult) {
this.gameResult = gameResult;
}

public Prize getPrize(Participant participant) {
return gameResult.get(participant);
}
}
7 changes: 7 additions & 0 deletions src/main/java/domain/GameState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package domain;

public enum GameState {
READY,
PROGRESS,
FINISH,
}
67 changes: 5 additions & 62 deletions src/main/java/domain/Ladder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,13 @@
import java.util.List;

public class Ladder {
private final List<Line> lines;
private final int ladderWidth;
private final int lineHeight;
private final RandomLadderGenerator randomLadderGenerator;
private final List<RowLine> columnLines;


public Ladder(int lineHeight, int ladderWidth, RandomLadderGenerator randomLadderGenerator) {
this.randomLadderGenerator = randomLadderGenerator;
this.ladderWidth = ladderWidth;
this.lineHeight = lineHeight;

List<Line> lines = this.randomLadderGenerator.generateLadder(lineHeight, ladderWidth);
checkLadderValidation(lines);
this.lines = lines;
}

public List<Line> getLines() {
return lines;
}

public int getLadderWidth() {
return ladderWidth;
}

public int getLineHeight() {
return lineHeight;
}

private void checkLadderValidation(List<Line> lines) {
for (int i = 0; i < lineHeight; i++) {
checkRowValidation(i, lines);
}
}

private void checkRowValidation(int columnIndex, List<Line> lines) {
List<Direction> rowDirections = lines.stream()
.map(l -> l.getPoints().get(columnIndex))
.toList();

int rowSize = rowDirections.size();
int rightCount = 0;

for (int i = 0; i < rowSize; i++) {
if (rowDirections.get(i) == Direction.RIGHT) {
checkRightValidation(i, rowSize, rowDirections);
rightCount++;
}

if (rowDirections.get(i) == Direction.LEFT) {
checkLeftValidation(rightCount);
rightCount--;
}
}
}

private void checkRightValidation(int columnIndex, int rowSize, List<Direction> rowDirections) {
if (columnIndex == rowSize - 1 || rowDirections.get(columnIndex + 1) != Direction.LEFT) {
throw new RuntimeException("사다리가 잘못 만들어졌습니다.");
}
public Ladder(List<RowLine> columnLines) {
this.columnLines = columnLines;
}

private void checkLeftValidation(int rightCount) {
if (rightCount == 0) {
throw new RuntimeException("사다리가 잘못 만들어졌습니다.");
}
public List<RowLine> getLines() {
return columnLines;
}
}
5 changes: 5 additions & 0 deletions src/main/java/domain/LadderFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package domain;

public interface LadderFactory {
Ladder newInstance();
}
84 changes: 84 additions & 0 deletions src/main/java/domain/LadderGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package domain;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LadderGame {
private final Participants participants;
private final Ladder ladder;
private final List<Prize> prizes;
private GameState gameState;
private Map<Integer, List<Integer>> result;

public LadderGame(Participants participants, Ladder ladder, List<Prize> prizes) {
this.participants = participants;
this.ladder = ladder;
this.prizes = prizes;
this.gameState = GameState.READY;
}

public void start() {
gameState = GameState.PROGRESS;

Map<Integer, List<Integer>> gameResult = new HashMap<>();

int participantsCount = participants.getParticipantsCount();

for (int i = 0; i < participantsCount; i++) {
Participant participant = participants.getParticipantByIndex(i);
Integer startPosition = participant.getPosition();
List<Integer> participantPositions = moveParticipant(participant);
gameResult.put(startPosition, participantPositions);
}

result = gameResult;

gameState = GameState.FINISH;
}

private List<Integer> moveParticipant(Participant participant) {
List<Integer> participantPositions = new ArrayList<>();

for (RowLine rowLine : ladder.getLines()) {
int currentPosition = participant.getPosition();
Direction direction = rowLine.getPositionDirection(currentPosition);

participant.move(direction);

participantPositions.add(participant.getPosition());
}

return participantPositions;
}

public GameResult getParticipantsPrizes() {
if (gameState != GameState.FINISH) {
throw new RuntimeException("게임이 진행중입니다!");
}

Map<Participant, Prize> participantsPrizes = new HashMap<>();

for (Integer startPosition : result.keySet()) {
List<Integer> positions = result.get(startPosition);
Integer lastPosition = positions.get(positions.size() - 1);

participantsPrizes.put(participants.getParticipantByIndex(startPosition), prizes.get(lastPosition));
}

return new GameResult(participantsPrizes);
}

public Participants getParticipants() {
return participants;
}

public Ladder getLadder() {
return ladder;
}

public List<Prize> getPrizes() {
return prizes;
}
}
15 changes: 0 additions & 15 deletions src/main/java/domain/Line.java

This file was deleted.

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

import java.util.Objects;

public class Participant {
private final Person person;
private int position;

public Participant(Person person, int position) {
this.person = person;
this.position = position;
}

public void move(Direction direction) {
position = position + direction.offset;
}
Comment on lines +14 to +16

Choose a reason for hiding this comment

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

📝 Enum에 함수형 인터페이스 넣어보기 3

그럼 위에서 정의한 enum의 메서드로 특정 동작을 수행해서 position을 얻어낼 수 있겠어요

Suggested change
public void move(Direction direction) {
position = position + direction.offset;
}
public void move(Direction direction) {
this.position = direction.move(position);
}


public String getParticipantName() {
return person.name();
}

public int getPosition() {
return position;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Participant that = (Participant) o;
return Objects.equals(person.name(), that.person.name());
}

@Override
public int hashCode() {
return Objects.hashCode(person.name());
}
}
Loading