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단계 - 사다리(게임 실행) #1806

Open
wants to merge 14 commits into
base: nice7677
Choose a base branch
from
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