Skip to content
Open
85 changes: 62 additions & 23 deletions src/main/java/nextstep/ladder/LadderGame.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package nextstep.ladder;

import nextstep.ladder.domain.Ladder;
import nextstep.ladder.domain.Player;
import nextstep.ladder.domain.*;
import nextstep.ladder.view.InputView;
import nextstep.ladder.view.ResultView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

public class LadderGame {

private static final String NAME_REX_PATTERN = ",";

private final List<Player> players = new ArrayList<>();

private Ladder ladder;
private static final String ALL_PLAYER = "all";

public static void main(String[] args) {
LadderGame game = new LadderGame();
Expand All @@ -24,30 +20,73 @@ public static void main(String[] args) {

public void run() {

inputPlayers();
Map<PlayerName, Player> players = addPlayers(InputView.inputPlayers());
Map<ResultId, Result> results = addResults(InputView.inputResult());

Ladder ladder = new Ladder(InputView.inputLadderHeight(), players.size());

ResultView.printLadderResult(players, ladder.getLines(), results);

players = getPlayerResult(players, results, ladder);


printPlayerResult(players);

saveLadder(new Ladder(inputLadderHeight(), this.players.size()));
}

ResultView.printResult(this.players, ladder.getLines());
private Map<PlayerName, Player> addPlayers(String inputPlayers) {
AtomicInteger index = new AtomicInteger(0);
return Arrays.stream(inputPlayers.split(","))
.map(name -> new Player(new PlayerName(name), index.getAndIncrement()))
.collect(Collectors.toMap(Player::getName, player -> player, (x, y) -> y, LinkedHashMap::new));
}

private Map<ResultId, Result> addResults(String inputResults) {
AtomicLong index = new AtomicLong(0);
return Arrays.stream(inputResults.split(","))
.map(value -> new Result(new ResultId(index.getAndIncrement()), value))
.collect(Collectors.toMap(Result::getId, result -> result));
}

private void inputPlayers() {
addPlayers(InputView.inputPlayers());
private Map<PlayerName, Player> getPlayerResult(Map<PlayerName, Player> players, Map<ResultId, Result> results, Ladder ladder) {
Map<PlayerName, Player> newResults = new LinkedHashMap<>();
for (PlayerName playerName : players.keySet()) {
Player player = players.get(playerName);
player.saveResult(results.get(calculateResultId(players.get(player.getName()), ladder)));
newResults.put(playerName, player);
}
return newResults;
}

private void addPlayers(String players) {
Arrays.stream(players.split(NAME_REX_PATTERN))
.map(Player::new)
.forEach(this.players::add);
private ResultId calculateResultId(Player player, Ladder ladder) {
int playerPosition = player.getStartPosition();
for (Line line : ladder.getLines()) {
playerPosition = calculatePosition(line.getPoints(), playerPosition);
}
return new ResultId((long) playerPosition);
}

private int inputLadderHeight() {
return InputView.inputLadderHeight();
private int calculatePosition(List<Point> points, int playerPosition) {
if (points.get(playerPosition).getStatus().hasRight()) {
return playerPosition + 1;
}
if (points.get(playerPosition).getStatus().hasLeft()) {
return playerPosition - 1;
}
return playerPosition;
}

private void saveLadder(Ladder ladder) {
this.ladder = ladder;
private void printPlayerResult(Map<PlayerName, Player> players) {

String inputPlayer = "";

while (!ALL_PLAYER.equals(inputPlayer)) {

inputPlayer = InputView.inputPlayer();

ResultView.printPlayerResult(inputPlayer, players);

}
}

}
32 changes: 24 additions & 8 deletions src/main/java/nextstep/ladder/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
LadderGame
플레이어 추가
사다이 추가
라인 추가
# 3단계 - 사다리(게임 실행)

## 기능 요구사항
- 사다리 실행 결과를 출력해야 한다.
- 개인별 이름을 입력하면 개인별 결과를 출력하고, "all"을 입력하면 전체 참여자의 실행 결과를 출력한다.

## 프로그래밍 요구사항
- 자바 8의 스트림과 람다를 적용해 프로그래밍한다.
- 규칙 6: 모든 엔티티를 작게 유지한다.
- 규칙 7: 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.

---

### LadderGame
-[X] 플레이어 추가
-[X] 사다리 저장
-[X] 플레이어 결과 구하기

InputView
참여할 사람 이름 입력
최대 사다리 높이 입력
-[X] 참여할 사람 이름 입력
-[X] 최대 사다리 높이 입력
-[X] 실행 결과 입력
-[X] 결과를 보고 싶은 사람 입력

ResultView
플레이어 이름 출력
사다리 출력
-[X] 플레이어 이름 출력
-[X] 사다리 출력
-[X] 실행 결과 출력
26 changes: 15 additions & 11 deletions src/main/java/nextstep/ladder/domain/Ladder.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
package nextstep.ladder.domain;

import nextstep.ladder.util.RandomUtil;

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

public class Ladder {

private static final String HEIGHT_ERROR_MESSAGE = "높이는 0보다 커야 합니다.";

private List<Line> lines;

public Ladder(int height, int width) {
addLine(height, width);
}

private void addLine(int height, int width) {
List<Line> lines = new ArrayList<>();
IntStream.range(0, height)
.mapToObj(i -> new Line(width))
.forEach(lines::add);
this.lines = lines;
if (1 > height) {
throw new IllegalArgumentException(HEIGHT_ERROR_MESSAGE);
}
this.lines = createLines(height, width);
}

public List<Line> getLines() {
return Collections.unmodifiableList(this.lines);
}

private List<Line> createLines(int height, int width) {
List<Line> lines = new ArrayList<>();
for (int i = 0; i < height; i++) {
lines.add(new Line(width));
}
return lines;
}


}
41 changes: 27 additions & 14 deletions src/main/java/nextstep/ladder/domain/Line.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,43 @@
import nextstep.ladder.util.RandomUtil;

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

public class Line {

private final List<Boolean> points;
private List<Point> points;

public Line(int countOfPerson) {
List<Boolean> points = new ArrayList<>();
IntStream.range(0, countOfPerson - 1)
.forEach(index -> addPoint(points, index));
this.points = points;
public Line(int pointSize) {
this.points = createPoints(pointSize);
}

private void addPoint(List<Boolean> points, int index) {
if (index == 0 || !points.get(index - 1)) {
points.add(RandomUtil.generator());
return;
}
points.add(false);
public List<Point> getPoints() {
return Collections.unmodifiableList(points);
}

public List<Boolean> getPoints() {
private List<Point> createPoints(int pointSize) {
List<Point> points = new ArrayList<>();
for (int index = 0; index < pointSize; index++) {
addPoint(points, index, pointSize);
}
return points;
}

private void addPoint(List<Point> points, int index, int pointSize) {
int totalSizeBound = PointStatus.TOTAL_INDEX_SIZE;
int twoResultSizeBound = PointStatus.TWO_RESULT_SIZE;
if (index == 0) {
points.add(Point.createFirst(() -> RandomUtil.generator(twoResultSizeBound)));
return;
}
if (pointSize - 1 == index) {
points.add(Point.createLast(() -> RandomUtil.generator(twoResultSizeBound), points.get(index - 1)));
return;
}
Point point = Point.create(() -> RandomUtil.generator(totalSizeBound), points.get(index - 1));
// LEFT 일때 points list 값 바꾸기
points.add(point);
}

}
44 changes: 36 additions & 8 deletions src/main/java/nextstep/ladder/domain/Player.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,48 @@
package nextstep.ladder.domain;

import java.util.Objects;

public class Player {
private final PlayerName name;

private Result result;

private static final String NAME_OVER_LENGTH_ERROR_TEXT = "사람에 이름을 최대5글자까지 가능합니다.";
private static final int NAME_MAX_LENGTH = 5;
private final String name;
private final int startPosition;

public Player(String name) {
if (name.length() > NAME_MAX_LENGTH) {
throw new IllegalArgumentException(NAME_OVER_LENGTH_ERROR_TEXT);
}
public Player(PlayerName name, int startPosition) {
this.name = name;
this.startPosition = startPosition;
}

public String getName() {
public PlayerName getName() {
return name;
}

public int getStartPosition() {
return startPosition;
}

public void saveResult(Result result) {
this.result = result;
}

public Result getResult() {
return result;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Player player = (Player) o;

return Objects.equals(name, player.name);
}

@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}

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

import java.util.Objects;

public class PlayerName {

private static final String NAME_OVER_LENGTH_ERROR_TEXT = "사람에 이름을 최대5글자까지 가능합니다.";
private static final int NAME_MAX_LENGTH = 5;

private final String value;

public PlayerName(String value) {
if (value.length() > NAME_MAX_LENGTH) {
throw new IllegalArgumentException(NAME_OVER_LENGTH_ERROR_TEXT);
}
this.value = value;
}

public String getValue() {
return value;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

PlayerName that = (PlayerName) o;

return Objects.equals(value, that.value);
}

@Override
public int hashCode() {
return value != null ? value.hashCode() : 0;
}

}
Loading