-
Notifications
You must be signed in to change notification settings - Fork 745
3단계 - 사다리(게임 실행) #2421
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단계 - 사다리(게임 실행) #2421
Changes from all commits
19009e6
aa3d29e
aea49e1
c339f08
9fc762f
d06a3c7
9d3c205
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 |
---|---|---|
@@ -1,20 +1,53 @@ | ||
package nextstep.ladder; | ||
|
||
import nextstep.ladder.domain.ladder.Height; | ||
import nextstep.ladder.domain.ladder.Index; | ||
import nextstep.ladder.domain.ladder.Ladder; | ||
import nextstep.ladder.domain.generator.LadderGenerator; | ||
import nextstep.ladder.domain.name.Name; | ||
import nextstep.ladder.domain.name.Names; | ||
import nextstep.ladder.domain.reward.Reward; | ||
import nextstep.ladder.domain.reward.Rewards; | ||
import nextstep.ladder.view.InputView; | ||
import nextstep.ladder.view.ResultView; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class LadderGame { | ||
|
||
public static void main(String[] args) { | ||
Names names = new Names(InputView.getNames()); | ||
Height height = new Height(InputView.getHeight()); | ||
Rewards rewards = new Rewards(InputView.getRewards()); | ||
|
||
Ladder ladder = LadderGenerator.generateLadder(names.count(), height); | ||
|
||
ResultView.result(names, ladder); | ||
ResultView.ladderResult(names, ladder, rewards); | ||
|
||
while(true) { | ||
String playerName = InputView.getPlayerName(); | ||
|
||
if (playerName.equalsIgnoreCase("quit")) { | ||
break; | ||
} | ||
|
||
if (playerName.equalsIgnoreCase("all")) { | ||
List<Integer> rewardList = ladder.all().stream() | ||
.map(Index::value) | ||
.collect(Collectors.toList()); | ||
ResultView.rewardResult(names, rewards, rewardList); | ||
continue; | ||
} | ||
|
||
Name name = new Name(playerName); | ||
Index rewardIdx = ladder.resultOf(names.positionOf(name)); | ||
try { | ||
Reward reward = rewards.get(rewardIdx.value()); | ||
System.out.println(reward); | ||
} catch(IndexOutOfBoundsException e) { | ||
System.out.println("이름이 명단에 없습니다."); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package nextstep.ladder.domain.common; | ||
|
||
import java.util.List; | ||
|
||
public abstract class AbstractValueList<T> { | ||
protected final List<T> values; | ||
|
||
protected AbstractValueList(List<T> values) { | ||
if (values == null || values.isEmpty()) { | ||
throw new IllegalArgumentException("리스트는 비어 있을 수 없습니다."); | ||
} | ||
this.values = List.copyOf(values); | ||
} | ||
|
||
public List<T> values() { | ||
return values; | ||
} | ||
|
||
public int count() { | ||
return values.size(); | ||
} | ||
|
||
public T get(int index) { | ||
return values.get(index); | ||
} | ||
|
||
public int positionOf(Object value) { | ||
if (value == null) { | ||
throw new IllegalArgumentException("찾는 값은 null일 수 없습니다."); | ||
} | ||
|
||
return values.indexOf(value); | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package nextstep.ladder.domain.generator; | ||
|
||
import nextstep.ladder.domain.ladder.Line; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.ThreadLocalRandom; | ||
|
||
public class LineGenerator { | ||
public static Line generateLine(int countOfPerson) { | ||
List<Boolean> line = new ArrayList<>(); | ||
Point point = new Point(false, false); | ||
|
||
for (int i = 0; i < countOfPerson - 1; i++) { | ||
boolean nextBoolean = randomBoolean(); | ||
point = new Point(point.next(), nextBoolean); | ||
|
||
if (point.isConsecutive()) { | ||
nextBoolean = false; | ||
point = new Point(point.current(), false); | ||
} | ||
|
||
line.add(nextBoolean); | ||
} | ||
return new Line(line); | ||
} | ||
|
||
public static void assertValidLine(List<Boolean> values) { | ||
if (values == null || values.isEmpty()) { | ||
throw new IllegalArgumentException("사다리에는 빈값이 올 수 없습니다. values=" + values); | ||
} | ||
|
||
for(int i = 0; i < values.size() -1; i++) { | ||
Point point = new Point(values.get(i), values.get(i + 1)); | ||
if(point.isConsecutive()) { | ||
throw new IllegalArgumentException("연속된 사다리 계단은 나올 수 없습니다."); | ||
} | ||
} | ||
} | ||
|
||
private static boolean randomBoolean() { | ||
return ThreadLocalRandom.current().nextBoolean(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,23 @@ | ||||||||||||||||||
package nextstep.ladder.domain.generator; | ||||||||||||||||||
|
||||||||||||||||||
public class Point { | ||||||||||||||||||
private final boolean current; | ||||||||||||||||||
private final boolean next; | ||||||||||||||||||
|
||||||||||||||||||
public Point(boolean current, boolean next) { | ||||||||||||||||||
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. 두 개의 값이 true, true인 경우는 있을 수 없기 때문에 이 경우 생성자에서 예외 처리하는 것은 어떨까? |
||||||||||||||||||
this.current = current; | ||||||||||||||||||
this.next = next; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
public boolean isConsecutive() { | ||||||||||||||||||
return current && next; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
public boolean current() { | ||||||||||||||||||
return current; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
public boolean next() { | ||||||||||||||||||
return next; | ||||||||||||||||||
} | ||||||||||||||||||
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.
Suggested change
next가 아니라 previous 값을 가지는 구조로 구현하는 것은 어떨까? |
||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package nextstep.ladder.domain.ladder; | ||
|
||
public enum Direction { | ||
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. 👍 |
||
LEFT { | ||
@Override | ||
public Index move(Index index) { | ||
return index.decrement(); | ||
} | ||
}, | ||
RIGHT { | ||
@Override | ||
public Index move(Index index) { | ||
return index.increment(); | ||
} | ||
}, | ||
PASS { | ||
@Override | ||
public Index move(Index index) { | ||
return index; | ||
} | ||
}; | ||
|
||
public abstract Index move(Index index); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package nextstep.ladder.domain.ladder; | ||
|
||
public class Index { | ||
private final int value; | ||
private final int max; | ||
|
||
public Index(int value, int max) { | ||
validate(value, max); | ||
this.value = value; | ||
this.max = max; | ||
} | ||
|
||
private void validate(int value, int max) { | ||
if (value < 0 || value >= max) { | ||
throw new IllegalArgumentException("인덱스는 0 이상 " + (max - 1) + " 이하여야 합니다."); | ||
} | ||
} | ||
|
||
public int value() { | ||
return value; | ||
} | ||
|
||
public Index increment() { | ||
return new Index(value + 1, max); | ||
} | ||
|
||
public Index decrement() { | ||
return new Index(value - 1, max); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Index index = (Index) o; | ||
return value == index.value && max == index.max; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return value; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,17 +4,35 @@ | |
import java.util.List; | ||
|
||
public class Ladder { | ||
List<Line> lineList; | ||
private final List<Line> lineList; | ||
private final int countOfPeople; | ||
|
||
public Ladder() { | ||
public Ladder(int countOfPeople) { | ||
this.countOfPeople = countOfPeople; | ||
this.lineList = new ArrayList<>(); | ||
} | ||
|
||
public List<Line> values() { | ||
return lineList; | ||
} | ||
public List<Line> values() { | ||
return lineList; | ||
} | ||
|
||
public void add(Line line) { | ||
lineList.add(line); | ||
} | ||
|
||
public void add(Line line) { | ||
lineList.add(line); | ||
} | ||
public Index resultOf(int position) { | ||
Index index = new Index(position, countOfPeople); | ||
for(Line line: values()) { | ||
index = line.movePerson(index); | ||
} | ||
return index; | ||
} | ||
|
||
public List<Index> all() { | ||
List<Index> results = new ArrayList<>(); | ||
for(int i = 0; i < countOfPeople; i++) { | ||
results.add(resultOf(i)); | ||
} | ||
return results; | ||
} | ||
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. Ladder가 사다리 타기를 위한 모든 상태 값을 가진다. |
||
} |
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.
사다리 타기의 전체 흐름을 다음과 같은 구조로 구현해 보는 것은 어떨까?
main()은 MVC에서 Controller의 역할로 가능한 가볍게 구현해야 한다.
Controller 내에는 로직은 최대한 배제하고 Model과 View 사이의 연결 역할만 하도록 구현한다.
MatchingResult는 Map<Integer, Integer>에 대한 일급콜렉션 객체이다.
Map의 key는 시작 위치, value는 사다리를 실행한 결과 위치이다.
LadderResult는 위치 값만 가지고 있는 MatchingResult의 값을 이름과 결과로 매핑한 결과를 가지는 일급콜렉션 객체이다.
반드시 위와 같은 구조로 개발하지 않아도 된다.
단, 위 코드 힌트를 참고해 개선할 부분이 있으면 개선해 본다.