diff --git a/README_LADDER_CREATE.md b/README_LADDER_CREATE.md index bcbde94b53..c716b60371 100644 --- a/README_LADDER_CREATE.md +++ b/README_LADDER_CREATE.md @@ -73,7 +73,7 @@ public class Line { - [x] 참여자 count 0 일경우 오류. - [x] 한줄 정보를 문자열로 출력한다. * field List -* HorizontalGenerator +* CrossGenerator.java - [x] 가로줄을 생성한다. ### View * InputView diff --git a/README_LADDER_RUN.md b/README_LADDER_RUN.md new file mode 100644 index 0000000000..460d9d8c37 --- /dev/null +++ b/README_LADDER_RUN.md @@ -0,0 +1,157 @@ +# 사다리 게임 +## 2단계 - 사다리(생성) + +## 기능 요구사항 +* 사다리 실행 결과를 출력해야 한다. +* 개인별 이름을 입력하면 개인별 결과를 출력하고, "all"을 입력하면 전체 참여자의 실행 결과를 출력한다. + +## 프로그래밍 요구사항 +* 자바 8의 스트림과 람다를 적용해 프로그래밍한다. +* 규칙 6: 모든 엔티티를 작게 유지한다. +* 규칙 7: 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다. + +### 실행 결과 +* 위 요구사항에 따라 4명의 사람을 위한 5개 높이 사다리를 만들 경우, 프로그램을 실행한 결과는 다음과 같다. + +``` +참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요) +pobi,honux,crong,jk + +실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요) +꽝,5000,꽝,3000 + +최대 사다리 높이는 몇 개인가요? +5 + +사다리 결과 + +pobi honux crong jk + |-----| |-----| + | |-----| | + |-----| | | + | |-----| | + |-----| |-----| +꽝 5000 꽝 3000 + +결과를 보고 싶은 사람은? +pobi + +실행 결과 +꽝 + +결과를 보고 싶은 사람은? +all + +실행 결과 +pobi : 꽝 +honux : 3000 +crong : 꽝 +jk : 5000 +``` + +## 힌트 +* 각 로직을 구현하기 위해 필요한 데이터를 가지는 객체를 분리하기 위해 노력해본다. 로직 구현에 필요한 데이터를 가지는 객체를 잘 분리하면 의외로 쉽게 문제를 해결할 수 있다. +* 각 객체가 2개 이하의 인스턴스 변수만을 가지도록 구현해 본다. + + +``` +참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요) +pobi,honux,crong,jk + +/** + 없음 + Rewards + List rewards field +*/ +실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요) +꽝,5000,꽝,3000 + +최대 사다리 높이는 몇 개인가요? +5 + +사다리 결과 + +pobi honux crong jk + |-----| |-----| + | |-----| | + |-----| | | + | |-----| | + |-----| |-----| +꽝 5000 꽝 3000 // 없음 - Rewards + +/** + 없음 - InputView + Name +*/ +결과를 보고 싶은 사람은? +pobi + +/** + 없음 - ResultView + Players players; + String result = rewards.result(playerName); + List results = players.results(players); +*/ +실행 결과 +꽝 + +// 없음 - Player +결과를 보고 싶은 사람은? +all + +실행 결과 +pobi : 꽝 +honux : 3000 +crong : 꽝 +jk : 5000 +``` + +## ADDED_TODO +### Domain +* Ladder + - [x] 결과들을 생성한다 +* Rewards + - [x] 생성 + - [x] 생성 실패 + - [x] playersCount 와 일치하지 않으면 실패 + - [x] 이름을 출력한다 + * RewardName extends Name + - [x] 생성 +* Lines + - [x] 플레이어 모두 마지막까지 이동 + * Line + - [x] 플레이어 모두 한칸 아래 이동 + - [x] 플레이어 가로 좌측 이동 + - [x] 플레이어 가로 우측 이동 + - [x] 플레이어 가로 이동 없음 +* Players + - [x] 생성 실패 + - [x] 이름 목록이 1 미만이면 실패 + - [x] 이름목록 출력한다 + - [x] 현재 사다리 높이를 출력한다 + * PlayerName extends Name + - [x] 생성 + * Vertical + - [x] 생성 + - [x] 생성 실패 + - [x] 0 미만이면 생성 실패 + - [x] 이동(무조건 아래로) +* Point + - [x] 이동 + - [x] 좌측 + - [x] 우측 + - [x] 이동안함 +* Results + - [x] 생성 + - [x] 게임결과를 도출한다("pobi") + - [x] 게임결과들을 도출한다("all") + * Map results +### View +* InputView + - [x] 실행 결과를 입력받는다.(실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)) + - [x] 결과를 볼 플레이어 이름을 입력받는다.(결과를 보고 싶은 사람은?) + - [x] 결과를 볼 플레이어 전체를(all) 입력받는다.(결과를 보고 싶은 사람은?) +* ResultView + - [x] 사다리결과에 Rewards 를 붙여 출력한다 + - [x] 실행 결과를 출력한다(실행 결과) + - [x] 실행 결과들을 출력한다(실행 결과) \ No newline at end of file diff --git a/src/main/java/ladder/controller/LadderController.java b/src/main/java/ladder/controller/LadderController.java index 4d4c5c79bf..5098620610 100644 --- a/src/main/java/ladder/controller/LadderController.java +++ b/src/main/java/ladder/controller/LadderController.java @@ -1,10 +1,10 @@ package ladder.controller; -import ladder.domain.Ladder; -import ladder.domain.Players; +import ladder.domain.*; import ladder.view.InputView; import ladder.view.ResultView; +import java.util.List; import java.util.Scanner; public class LadderController { @@ -13,11 +13,15 @@ public static void run() { InputView inputView = new InputView(new Scanner(System.in)); Players players = inputView.inputNamesToPlayers(); + Rewards rewards = inputView.inputNamesToRewards(players); Ladder ladder = inputView.inputVerticalSizeToLadder(players); ResultView resultView = new ResultView(); - resultView.renderLadder(ladder); + resultView.renderLadderAndRewards(ladder, rewards); + + List playerNames = inputView.inputResultPlayer(players);//결과를 보고 싶은 사람은? + resultView.renderResults(ladder.results(rewards), playerNames); } } diff --git a/src/main/java/ladder/domain/Ladder.java b/src/main/java/ladder/domain/Ladder.java index 9a42960323..e1debac7b6 100644 --- a/src/main/java/ladder/domain/Ladder.java +++ b/src/main/java/ladder/domain/Ladder.java @@ -1,10 +1,14 @@ package ladder.domain; -import ladder.domain.util.CrossGenerator; +import ladder.domain.generator.CrossGenerator; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; +import java.util.stream.IntStream; public class Ladder { + public static final int START_INCLUSIVE = 0; private final Lines lines; private final Players players; @@ -37,4 +41,17 @@ public Lines getLines() { public Players getPlayers() { return players; } + + public Results results(Rewards rewards) { + Players endPlayers = lines.move(players); + Map results = new HashMap<>(); + IntStream.range(START_INCLUSIVE, endPlayers.size()) + .boxed() + .forEach(index -> { + PlayerName key = endPlayers.names().get(index); + RewardName value = rewards.names().get(index); + results.put(key, value); + }); + return new Results(results); + } } diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java index a95df3cee6..e398ca9bea 100644 --- a/src/main/java/ladder/domain/Line.java +++ b/src/main/java/ladder/domain/Line.java @@ -1,6 +1,6 @@ package ladder.domain; -import ladder.domain.util.CrossGenerator; +import ladder.domain.generator.CrossGenerator; import ladder.exception.PlayersCountException; import ladder.exception.PointException; @@ -61,6 +61,21 @@ public List getPoints() { return Collections.unmodifiableList(points); } + public Players move(Players players) { + List nextLinePlayers = new ArrayList<>(); + + List names = players.names(); + names.forEach(name -> { + int index = names.indexOf(name); + Point point = points.get(index); + int moveIndex = point.move().value(); + PlayerName movedName = names.get(index + moveIndex); + nextLinePlayers.add(movedName); + }); + + return new Players(nextLinePlayers, players.vertical().move()); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/ladder/domain/Lines.java b/src/main/java/ladder/domain/Lines.java index 057d7790bd..9525ab0b73 100644 --- a/src/main/java/ladder/domain/Lines.java +++ b/src/main/java/ladder/domain/Lines.java @@ -1,6 +1,6 @@ package ladder.domain; -import ladder.domain.util.CrossGenerator; +import ladder.domain.generator.CrossGenerator; import java.util.Collections; import java.util.List; @@ -10,8 +10,6 @@ public class Lines { public static final int START_INCLUSIVE = 0; - public static final String LINE_BREAK = "\n"; - public static final String SPACE = " "; private final List lines; public Lines(Players players, int verticalLadderSize, CrossGenerator generator) { @@ -22,8 +20,6 @@ public Lines(List lines) { this.lines = lines; } - - private static List generateLines(int playersSize, int verticalLadderSize, CrossGenerator generator) { return IntStream.range(START_INCLUSIVE, verticalLadderSize) .boxed() @@ -31,6 +27,17 @@ private static List generateLines(int playersSize, int verticalLadderSize, .collect(Collectors.toList()); } + public List getLines() { + return Collections.unmodifiableList(lines); + } + + public Players move(Players players) { + for (Line line : lines) { + players = line.move(players); + } + return players; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -38,13 +45,8 @@ public boolean equals(Object o) { Lines lines1 = (Lines) o; return Objects.equals(lines, lines1.lines); } - @Override public int hashCode() { return Objects.hash(lines); } - - public List getLines() { - return Collections.unmodifiableList(lines); - } } diff --git a/src/main/java/ladder/domain/Name.java b/src/main/java/ladder/domain/Name.java index 40deb35315..51e0326410 100644 --- a/src/main/java/ladder/domain/Name.java +++ b/src/main/java/ladder/domain/Name.java @@ -4,7 +4,7 @@ import java.util.Objects; -public class Name { +public abstract class Name { public static final String NOT_ALLOW_EMPTY_NAME_MESSAGE = "이름에 공백이 들어갈 수 없습니다."; public static final String NOT_ALLOW_EXCEED_MAX_NAME_LENGTH_MESSAGE = "이름을 5글자를 초과할수 없습니다."; public static final int DEFAULT_MAX_NAME_LENGTH = 5; @@ -20,7 +20,6 @@ public Name(String name) { if (name.length() > MAX_NAME_LENGTH) { throw new InvalidNameException(NOT_ALLOW_EXCEED_MAX_NAME_LENGTH_MESSAGE); } - this.name = name; } @@ -44,4 +43,11 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(name); } + + @Override + public String toString() { + return "Name{" + + "name='" + name + '\'' + + '}'; + } } diff --git a/src/main/java/ladder/domain/Player.java b/src/main/java/ladder/domain/Player.java deleted file mode 100644 index cd1306950e..0000000000 --- a/src/main/java/ladder/domain/Player.java +++ /dev/null @@ -1,32 +0,0 @@ -package ladder.domain; - -import java.util.Objects; - -public class Player { - private final Name name; - - public Player(String playerName) { - this.name = new Name(playerName); - } - - public Player(Name name) { - this.name = name; - } - - public Name name() { - return name; - } - - @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 Objects.hash(name); - } -} diff --git a/src/main/java/ladder/domain/PlayerName.java b/src/main/java/ladder/domain/PlayerName.java new file mode 100644 index 0000000000..ea0aa5cae4 --- /dev/null +++ b/src/main/java/ladder/domain/PlayerName.java @@ -0,0 +1,7 @@ +package ladder.domain; + +public class PlayerName extends Name { + public PlayerName(String value) { + super(value); + } +} diff --git a/src/main/java/ladder/domain/Players.java b/src/main/java/ladder/domain/Players.java index ce6e0d37eb..235ee62101 100644 --- a/src/main/java/ladder/domain/Players.java +++ b/src/main/java/ladder/domain/Players.java @@ -1,63 +1,71 @@ package ladder.domain; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; +import ladder.exception.PlayersCountException; +import ladder.exception.PlayersException; -import static ladder.domain.Name.DEFAULT_MAX_NAME_LENGTH; +import java.util.*; +import java.util.stream.Collectors; public class Players { public static final String DELIMITER = ","; - private final List players; + public static final int MINIMAL_PLAYERS_SIZE = 1; + public static final String NOT_ENOUGH_PLAYERS_SIZE_MESSAGE = "플레이어는 최소 1명 이상이어야 합니다"; + private final List playerNames; + private final Vertical vertical; - public Players(List players) { - this.players = players; + public Players(List playerNames, Vertical vertical) { + if (playerNames.size() < MINIMAL_PLAYERS_SIZE) { + throw new PlayersException(NOT_ENOUGH_PLAYERS_SIZE_MESSAGE); + } + this.playerNames = playerNames; + this.vertical = vertical; } - public Players(String names) { - this(toPlayers(names)); + public Players(String playerNames) { + this(toNames(playerNames), new Vertical()); } public int size() { - return players.size(); + return playerNames.size(); } - private static List toPlayers(String names) { + private static List toNames(String names) { return Arrays.stream(names.split(DELIMITER)) .map(String::trim) .collect(Collectors.toList()) .stream() - .map(Player::new) + .map(PlayerName::new) .collect(Collectors.toList()); } + public List names() { + return Collections.unmodifiableList(playerNames); + } - public int namesMaxLength() { - return names() - .stream() - .mapToInt(Name::length) - .max() - .orElse(DEFAULT_MAX_NAME_LENGTH); + public Vertical vertical() { + return vertical; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - Players players1 = (Players) o; - return Objects.equals(players, players1.players); + Players players = (Players) o; + return Objects.equals(playerNames, players.playerNames) && Objects.equals(vertical, players.vertical); } @Override public int hashCode() { - return Objects.hash(players); + return Objects.hash(playerNames, vertical); } - public List names() { - return players.stream() - .map(Player::name) - .collect(Collectors.toList()); + @Override + public String + toString() { + return "Players{" + + "names=" + playerNames + + ", vertical=" + vertical + + '}'; } -} +} \ No newline at end of file diff --git a/src/main/java/ladder/domain/Point.java b/src/main/java/ladder/domain/Point.java index c49c1b04a2..2904ba820f 100644 --- a/src/main/java/ladder/domain/Point.java +++ b/src/main/java/ladder/domain/Point.java @@ -1,5 +1,6 @@ package ladder.domain; +import ladder.domain.enums.MoveStatus; import ladder.exception.PointException; import java.util.Objects; @@ -7,30 +8,40 @@ public class Point { public static final String NOT_ALLOWED_CONSECUTIVE_LINE_MESSAGE = "사다리 라인을 연속해서 만들 수 없습니다."; private final boolean left; - private final boolean current; + private final boolean right; - private Point(boolean left, boolean current) { - if (left && current) { + private Point(boolean left, boolean right) { + if (left && right) { throw new PointException(NOT_ALLOWED_CONSECUTIVE_LINE_MESSAGE); } this.left = left; - this.current = current; + this.right = right; } - public static Point first(boolean current) { - return new Point(false, current); + public static Point first(boolean right) { + return new Point(false, right); } - public Point next(boolean current) { - return new Point(this.current, current); + public Point next(boolean right) { + return new Point(this.right, right); } public Point last() { - return new Point(this.current, false); + return new Point(this.right, false); } - public boolean getCurrent() { - return current; + public boolean getRight() { + return right; + } + + public MoveStatus move() { + if (!this.left && this.right) { + return MoveStatus.RIGHT; + } + if (this.left && !this.right) { + return MoveStatus.LEFT; + } + return MoveStatus.STOP; } @Override @@ -38,19 +49,19 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Point point = (Point) o; - return left == point.left && current == point.current; + return left == point.left && right == point.right; } @Override public int hashCode() { - return Objects.hash(left, current); + return Objects.hash(left, right); } @Override public String toString() { return "Point{" + "left=" + left + - ", current=" + current + + ", right=" + right + '}'; } } \ No newline at end of file diff --git a/src/main/java/ladder/domain/Results.java b/src/main/java/ladder/domain/Results.java new file mode 100644 index 0000000000..f0128b9604 --- /dev/null +++ b/src/main/java/ladder/domain/Results.java @@ -0,0 +1,46 @@ +package ladder.domain; + +import ladder.exception.NoNameException; + +import java.util.Collections; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +public class Results { + public static final String NO_NAME_MESSAGE = "플레이어 이름이 없습니다."; + private final Map results; + + public Results(Map results) { + this.results = results; + } + + public RewardName result(PlayerName playerName) { + return Optional.ofNullable(results.get(playerName)) + .orElseThrow(() -> new NoNameException(NO_NAME_MESSAGE)); + } + + public Map results() { + return Collections.unmodifiableMap(results); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Results results1 = (Results) o; + return Objects.equals(results, results1.results); + } + + @Override + public int hashCode() { + return Objects.hash(results); + } + + @Override + public String toString() { + return "Results{" + + "results=" + results + + '}'; + } +} diff --git a/src/main/java/ladder/domain/RewardName.java b/src/main/java/ladder/domain/RewardName.java new file mode 100644 index 0000000000..89e8263a3b --- /dev/null +++ b/src/main/java/ladder/domain/RewardName.java @@ -0,0 +1,7 @@ +package ladder.domain; + +public class RewardName extends Name { + public RewardName(String value) { + super(value); + } +} diff --git a/src/main/java/ladder/domain/Rewards.java b/src/main/java/ladder/domain/Rewards.java new file mode 100644 index 0000000000..9782e61d6c --- /dev/null +++ b/src/main/java/ladder/domain/Rewards.java @@ -0,0 +1,48 @@ +package ladder.domain; + +import ladder.exception.RewardsCountException; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class Rewards { + public static final String DELIMITER = ","; + public static final String PLAYERS_COUNT_REWARDS_COUNT_NOT_EQUAL_MESSAGE = "players 갯수와 rewards 갯수는 일치해야 합니다."; + private final List rewardNames; + + public Rewards(List rewardNames, int playersCount) { + if (playersCount != rewardNames.size()) { + throw new RewardsCountException(PLAYERS_COUNT_REWARDS_COUNT_NOT_EQUAL_MESSAGE); + } + this.rewardNames = rewardNames; + } + + public Rewards(String rewards, int playersCount) { + this(toRewardNames(rewards), playersCount); + } + + private static List toRewardNames(String rewards) { + return Arrays.stream(rewards.split(DELIMITER)) + .map(value -> new RewardName(value.trim())) + .collect(Collectors.toUnmodifiableList()); + } + + public List names() { + return rewardNames; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Rewards rewards = (Rewards) o; + return Objects.equals(rewardNames, rewards.rewardNames); + } + + @Override + public int hashCode() { + return Objects.hash(rewardNames); + } +} diff --git a/src/main/java/ladder/domain/Vertical.java b/src/main/java/ladder/domain/Vertical.java new file mode 100644 index 0000000000..983f93c81e --- /dev/null +++ b/src/main/java/ladder/domain/Vertical.java @@ -0,0 +1,40 @@ +package ladder.domain; + +import ladder.exception.VerticalException; + +import java.util.Objects; + +public class Vertical { + public static final String VERTICAL_IS_LESS_THEN_ZERO = "사다리 높이는 0보다 작을수 없습니다."; + public static final int START = 0; + private final int value; + + public Vertical(int value) { + if (value < 0) { + throw new VerticalException(VERTICAL_IS_LESS_THEN_ZERO); + } + this.value = value; + } + + public Vertical() { + this(START); + } + + public Vertical move() { + return new Vertical(this.value + 1); + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Vertical vertical = (Vertical) o; + return value == vertical.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/main/java/ladder/domain/enums/MoveStatus.java b/src/main/java/ladder/domain/enums/MoveStatus.java new file mode 100644 index 0000000000..178920b7cb --- /dev/null +++ b/src/main/java/ladder/domain/enums/MoveStatus.java @@ -0,0 +1,16 @@ +package ladder.domain.enums; + +public enum MoveStatus { + LEFT(-1), + STOP(0), + RIGHT(1) + ; + MoveStatus(int value) { + this.value = value; + } + private final int value; + + public int value() { + return value; + } +} diff --git a/src/main/java/ladder/domain/util/CrossGenerator.java b/src/main/java/ladder/domain/generator/CrossGenerator.java similarity index 71% rename from src/main/java/ladder/domain/util/CrossGenerator.java rename to src/main/java/ladder/domain/generator/CrossGenerator.java index 5242de7a67..f95758e542 100644 --- a/src/main/java/ladder/domain/util/CrossGenerator.java +++ b/src/main/java/ladder/domain/generator/CrossGenerator.java @@ -1,4 +1,4 @@ -package ladder.domain.util; +package ladder.domain.generator; @FunctionalInterface public interface CrossGenerator { diff --git a/src/main/java/ladder/domain/util/RandomCrossGenerator.java b/src/main/java/ladder/domain/generator/RandomCrossGenerator.java similarity index 53% rename from src/main/java/ladder/domain/util/RandomCrossGenerator.java rename to src/main/java/ladder/domain/generator/RandomCrossGenerator.java index f2e65f5f4b..1eb7032da5 100644 --- a/src/main/java/ladder/domain/util/RandomCrossGenerator.java +++ b/src/main/java/ladder/domain/generator/RandomCrossGenerator.java @@ -1,11 +1,13 @@ -package ladder.domain.util; +package ladder.domain.generator; import java.util.Random; public class RandomCrossGenerator implements CrossGenerator { + public static final Random RANDOM = new Random(); + @Override public boolean generate() { - return new Random().nextBoolean(); + return RANDOM.nextBoolean(); } } diff --git a/src/main/java/ladder/exception/NoNameException.java b/src/main/java/ladder/exception/NoNameException.java new file mode 100644 index 0000000000..f5f283cae7 --- /dev/null +++ b/src/main/java/ladder/exception/NoNameException.java @@ -0,0 +1,7 @@ +package ladder.exception; + +public class NoNameException extends RuntimeException { + public NoNameException(String message) { + super(message); + } +} diff --git a/src/main/java/ladder/exception/PlayersException.java b/src/main/java/ladder/exception/PlayersException.java new file mode 100644 index 0000000000..a41b74d89f --- /dev/null +++ b/src/main/java/ladder/exception/PlayersException.java @@ -0,0 +1,7 @@ +package ladder.exception; + +public class PlayersException extends RuntimeException { + public PlayersException(String message) { + super(message); + } +} diff --git a/src/main/java/ladder/exception/RewardsCountException.java b/src/main/java/ladder/exception/RewardsCountException.java new file mode 100644 index 0000000000..a7a55e0d27 --- /dev/null +++ b/src/main/java/ladder/exception/RewardsCountException.java @@ -0,0 +1,7 @@ +package ladder.exception; + +public class RewardsCountException extends RuntimeException { + public RewardsCountException(String message) { + super(message); + } +} diff --git a/src/main/java/ladder/exception/VerticalException.java b/src/main/java/ladder/exception/VerticalException.java new file mode 100644 index 0000000000..5caf87da7a --- /dev/null +++ b/src/main/java/ladder/exception/VerticalException.java @@ -0,0 +1,7 @@ +package ladder.exception; + +public class VerticalException extends RuntimeException { + public VerticalException(String message) { + super(message); + } +} diff --git a/src/main/java/ladder/view/InputView.java b/src/main/java/ladder/view/InputView.java index 251b0c4d8a..9ec9f51645 100644 --- a/src/main/java/ladder/view/InputView.java +++ b/src/main/java/ladder/view/InputView.java @@ -1,17 +1,25 @@ package ladder.view; -import ladder.domain.Ladder; -import ladder.domain.Players; -import ladder.domain.util.RandomCrossGenerator; +import ladder.domain.*; +import ladder.domain.generator.RandomCrossGenerator; import ladder.exception.InvalidNameException; import ladder.exception.LineException; +import ladder.exception.NoNameException; import ladder.exception.PlayersCountException; +import java.util.List; import java.util.Scanner; +import java.util.stream.Collectors; + +import static ladder.domain.Results.NO_NAME_MESSAGE; public class InputView { public static final String INPUT_NAMES_MESSAGE = "참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"; public static final String INPUT_LADDER_VERTICAL_SIZE_MESSAGE = "최대 사다리 높이는 몇 개인가요?"; + public static final String INPUT_REWARD_NAMES_MESSAGE = "실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"; + public static final String INPUT_RESULT_MESSAGE = "결과를 보고 싶은 사람은?"; + public static final String NOT_INPUT_TARGET_FIND_PLAYER_NAME_MESSAGE = "찾고자 하는 플레이어 이름을 입력하지 않았습니다."; + public static final String PLAYERS_ALL = "all"; private final Scanner scanner; public InputView(Scanner scanner) { @@ -21,20 +29,51 @@ public InputView(Scanner scanner) { public Players inputNamesToPlayers() { try { return new Players(inputNames()); - } catch (InvalidNameException e) { + } catch (RuntimeException e) { System.out.println(e.getMessage()); return inputNamesToPlayers(); } } + public Rewards inputNamesToRewards(Players players) { + try { + return new Rewards(inputRewardNames(), players.size()); + } catch (RuntimeException e) { + System.out.println(e.getMessage()); + return inputNamesToRewards(players); + } + } + public Ladder inputVerticalSizeToLadder(Players players) { try { return new Ladder(players, inputVerticalSize(), new RandomCrossGenerator()); - } catch (PlayersCountException | LineException e) { + } catch (RuntimeException e) { System.out.println(e.getMessage()); return inputVerticalSizeToLadder(inputNamesToPlayers()); } } + public List inputResultPlayer(Players players) { + try { + return inputPlayers(players); + } catch (RuntimeException e) { + System.out.println(e.getMessage()); + return inputResultPlayer(players); + } + } + + private List inputPlayers(Players players) { + System.out.println(INPUT_RESULT_MESSAGE); + String text = scanner.nextLine(); + if (PLAYERS_ALL.equals(text)) { + return players.names(); + } + return List.of(players.names() + .stream() + .filter(playerName -> new PlayerName(text).equals(playerName)) + .findFirst() + .orElseThrow(() -> new NoNameException(NO_NAME_MESSAGE))); + } + private String inputNames() { System.out.println(INPUT_NAMES_MESSAGE); return scanner.nextLine(); @@ -46,4 +85,9 @@ private int inputVerticalSize() { scanner.nextLine(); return inputVerticalSize; } + + private String inputRewardNames() { + System.out.println(INPUT_REWARD_NAMES_MESSAGE); + return scanner.nextLine(); + } } diff --git a/src/main/java/ladder/view/ResultView.java b/src/main/java/ladder/view/ResultView.java index 4c9bb5e0e4..9987bd1ff6 100644 --- a/src/main/java/ladder/view/ResultView.java +++ b/src/main/java/ladder/view/ResultView.java @@ -3,33 +3,63 @@ import ladder.domain.*; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; +import static ladder.domain.Name.DEFAULT_MAX_NAME_LENGTH; + public class ResultView { public static final int START_INCLUSIVE = 0; - public static final String LINE_BREAK = "\n"; + public static final String LINE_BREAK = System.lineSeparator(); public static final String SPACE = " "; - public static final String HORIZONTAL = "-"; + public static final String SPACES = " "; + public static final String CROSS_LINES = "-----"; public static final String PLAYER_DELIMITER = "|"; public static final String PREFIX = ""; public static final int INDEX_OFFSET = 1; + public static final String RESULT_MESSAGE = "사다리 결과"; + public static final int PLAYER_NAME_SIZE = 1; + public static final int PLAYER_NAME_INDEX = 0; + public static final String EXECUTE_RESULTS_MESSAGE = "실행 결과"; + public static final String COLON = " : "; public ResultView() { } - public void renderLadder(Ladder ladder) { - System.out.println("실행결과"); - System.out.println(toLadderString(ladder)); + public void renderLadderAndRewards(Ladder ladder, Rewards rewards) { + System.out.println(RESULT_MESSAGE); + System.out.println(toLadder(ladder, rewards)); } - public String toLadderString(Ladder ladder) { + public String toLadder(Ladder ladder, Rewards rewards) { Players players = ladder.getPlayers(); List lines = ladder.getLines() .getLines(); return toFormattedNames(players) + LINE_BREAK + - toFormattedLines(players, lines); + toFormattedLines(players, lines) + + LINE_BREAK + + toFormattedNames(rewards); + } + + public void renderResults(Results results, List playerNames) { + System.out.println(EXECUTE_RESULTS_MESSAGE); + if (playerNames.size() == PLAYER_NAME_SIZE) { + printResult(results, playerNames); + return; + } + printResults(results); + } + + private static void printResult(Results results, List playerNames) { + RewardName result = results.result(playerNames.get(PLAYER_NAME_INDEX)); + System.out.println(result.name()); + } + + private static void printResults(Results results) { + Map resultsMap = results.results(); + resultsMap.forEach((key, value) -> System.out.println(key.name() + COLON + value.name())); } private static String toFormattedLines(Players players, List lines) { @@ -41,26 +71,32 @@ private static String toFormattedLines(Players players, List lines) { private static String toFormattedNames(Players players) { return players.names() .stream() - .map(name -> SPACE.repeat(players.namesMaxLength() - name.length()) + name.name()) + .map(name -> SPACE.repeat(DEFAULT_MAX_NAME_LENGTH - name.length()) + name.name()) + .collect(Collectors.joining(SPACE)); + } + + private static String toFormattedNames(Rewards rewards) { + return rewards.names() + .stream() + .map(name -> SPACE.repeat(DEFAULT_MAX_NAME_LENGTH - name.length()) + name.name()) .collect(Collectors.joining(SPACE)); } private static String toFormattedLine(Players players, List points) { - List names = players.names(); - int namesMaxLength = players.namesMaxLength(); + List names = players.names(); return IntStream.range(START_INCLUSIVE, names.size()) .boxed() - .map(index -> toFormattedHorizontal(index, namesMaxLength, points)) + .map(index -> toFormattedHorizontal(index, points)) .collect(Collectors.joining(PLAYER_DELIMITER, PREFIX, PLAYER_DELIMITER)); } - private static String toFormattedHorizontal(int index, int length, List points) { + private static String toFormattedHorizontal(int index, List points) { if (index == START_INCLUSIVE) { - return SPACE.repeat(length); + return SPACES; } - if (points.get(index - INDEX_OFFSET).getCurrent()) { - return HORIZONTAL.repeat(length); + if (points.get(index - INDEX_OFFSET).getRight()) { + return CROSS_LINES; } - return SPACE.repeat(length); + return SPACES; } } diff --git a/src/test/java/ladder/domain/LadderTest.java b/src/test/java/ladder/domain/LadderTest.java index ab28675207..eb89194b58 100644 --- a/src/test/java/ladder/domain/LadderTest.java +++ b/src/test/java/ladder/domain/LadderTest.java @@ -1,11 +1,12 @@ package ladder.domain; -import ladder.domain.util.CrossGenerator; +import ladder.domain.generator.CrossGenerator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -63,4 +64,27 @@ void getPlayers() { assertThat(actual).isEqualTo(players); } + + @Test + @DisplayName("결과를 생성한다") + void results() { + Players arrivalPlayers = new Players(List.of( + new PlayerName("pobi"), + new PlayerName("honux"), + new PlayerName("crong"), + new PlayerName("jk") + ), new Vertical()); + Ladder ladder = new Ladder(arrivalPlayers, lines); + Rewards rewards = new Rewards("꽝,3000,꽝,5000", 4); + + Results actual = ladder.results(rewards); + Results expected = new Results(Map.of( + new PlayerName("pobi"), new RewardName("꽝"), + new PlayerName("honux"), new RewardName("3000"), + new PlayerName("crong"), new RewardName("꽝"), + new PlayerName("jk"), new RewardName("5000") + )); + + assertThat(actual).isEqualTo(expected); + } } diff --git a/src/test/java/ladder/domain/LineTest.java b/src/test/java/ladder/domain/LineTest.java index 413d799c91..9f9ff2264c 100644 --- a/src/test/java/ladder/domain/LineTest.java +++ b/src/test/java/ladder/domain/LineTest.java @@ -22,6 +22,8 @@ public class LineTest { private Point next1Point; private Point next2Point; private Point lastPoint; + private List points; + private Line line; @BeforeEach void setUp() { @@ -29,6 +31,9 @@ void setUp() { next1Point = firstPoint.next(false); next2Point = next1Point.next(true); lastPoint = next2Point.last(); + + points = List.of(firstPoint, next1Point, next2Point, lastPoint); + line = new Line(points); } @Test @@ -57,7 +62,34 @@ void getPoints() { List actual = line.getPoints(); assertThat(actual).isEqualTo(points); + } + + @Test + @DisplayName("포인트들을 조회한다. 조회한 데이터는 불변이다") + void getPoints_불변() { + List points = List.of(firstPoint, next1Point, next2Point, lastPoint); + Line line = new Line(points); + List actual = line.getPoints(); + assertThatThrownBy(() -> actual.add(next2Point)) .isInstanceOf(UnsupportedOperationException.class); } + + @Test + @DisplayName("한개 라인을 이동한다.") + void move() { + // p c h j + // f | t | f | t | f + // c p j h + Players initPlayers = new Players("pobi,crong,honux,jk"); + Players actual = line.move(initPlayers); + Players expected = new Players(List.of( + new PlayerName("crong"), + new PlayerName("pobi"), + new PlayerName("jk"), + new PlayerName("honux") + ), new Vertical(1)); + + assertThat(actual).isEqualTo(expected); + } } \ No newline at end of file diff --git a/src/test/java/ladder/domain/LinesTest.java b/src/test/java/ladder/domain/LinesTest.java index 0aa5b33039..3432db750d 100644 --- a/src/test/java/ladder/domain/LinesTest.java +++ b/src/test/java/ladder/domain/LinesTest.java @@ -1,6 +1,6 @@ package ladder.domain; -import ladder.domain.util.CrossGenerator; +import ladder.domain.generator.CrossGenerator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -9,20 +9,55 @@ import java.util.List; import static ladder.domain.PlayersTest.PLAYERS1; -import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; public class LinesTest { private int playersCount; private CrossGenerator falseGenerator; private int verticalLadderSize; + private Point p1_1, p1_2, p1_3, p1_4; + private Point p2_1, p2_2, p2_3, p2_4; + private Point p3_1, p3_2, p3_3, p3_4; + private Point p4_1, p4_2, p4_3, p4_4; + private Point p5_1, p5_2, p5_3, p5_4; @BeforeEach void setUp() { playersCount = PLAYERS1.size(); verticalLadderSize = 5; falseGenerator = () -> false; + + // f t f t f + // f f t f f + // f t f f f + // f f t f f + // f t f t f + p1_1 = Point.first(true); + p1_2 = p1_1.next(false); + p1_3 = p1_2.next(true); + p1_4 = p1_3.last(); + + p2_1 = Point.first(false); + p2_2 = p2_1.next(true); + p2_3 = p2_2.next(false); + p2_4 = p2_3.last(); + + p3_1 = Point.first(true); + p3_2 = p3_1.next(false); + p3_3 = p3_2.next(false); + p3_4 = p3_3.last(); + + p4_1 = p2_1; + p4_2 = p2_2; + p4_3 = p2_3; + p4_4 = p2_4; + + p5_1 = p1_1; + p5_2 = p1_2; + p5_3 = p1_3; + p5_4 = p1_4; } @Test @@ -58,4 +93,32 @@ void getLines() { actual.add(new Line(playersCount, falseGenerator)); }).isInstanceOf(UnsupportedOperationException.class); } + + @Test + @DisplayName("플레이어 모두 마지막까지 이동") + void move() { + // |-----| |-----| pobi honux crong jk 0 + // | |-----| | honux pobi jk crong 1 + // |-----| | | honux jk pobi crong 2 + // | |-----| | jk honux pobi crong 3 + // |-----| |-----| jk pobi honux crong 4 + // results pobi jk crong honux 5 + Lines lines = new Lines(List.of( + new Line(List.of(p1_1, p1_2, p1_3, p1_4)), + new Line(List.of(p2_1, p2_2, p2_3, p2_4)), + new Line(List.of(p3_1, p3_2, p3_3, p3_4)), + new Line(List.of(p4_1, p4_2, p4_3, p4_4)), + new Line(List.of(p5_1, p5_2, p5_3, p5_4)) + )); + + Players actual = lines.move(new Players("pobi,honux,crong,jk")); + Players expected = new Players(List.of( + new PlayerName("pobi"), + new PlayerName("jk"), + new PlayerName("crong"), + new PlayerName("honux") + ), new Vertical(5)); + + assertThat(actual).isEqualTo(expected); + } } \ No newline at end of file diff --git a/src/test/java/ladder/domain/NameTest.java b/src/test/java/ladder/domain/PlayerNameTest.java similarity index 84% rename from src/test/java/ladder/domain/NameTest.java rename to src/test/java/ladder/domain/PlayerNameTest.java index 21f80f891a..73378146ba 100644 --- a/src/test/java/ladder/domain/NameTest.java +++ b/src/test/java/ladder/domain/PlayerNameTest.java @@ -11,13 +11,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -public class NameTest { +public class PlayerNameTest { @Test @DisplayName("이름을 생성한다") void create() { - Name actual = new Name("pobi"); - Name expected = new Name("pobi"); + Name actual = new PlayerName("pobi"); + Name expected = new PlayerName("pobi"); assertThat(actual).isEqualTo(expected); } @@ -25,7 +25,7 @@ void create() { @NullAndEmptySource void create_공백_실패(String emptyName) { assertThatThrownBy(() -> { - new Name(emptyName); + new PlayerName(emptyName); }).isInstanceOf(InvalidNameException.class) .hasMessage(NOT_ALLOW_EMPTY_NAME_MESSAGE); } @@ -34,7 +34,7 @@ void create() { @DisplayName("이름 생성 오류: 5글자를 초과하면 이름생성 오류가 발생한다") void create_5글자초과_실패() { assertThatThrownBy(() -> { - Name name = new Name("pobi22"); + Name name = new PlayerName("pobi22"); }).isInstanceOf(InvalidNameException.class) .hasMessage(NOT_ALLOW_EXCEED_MAX_NAME_LENGTH_MESSAGE); } @@ -42,7 +42,7 @@ void create() { @Test @DisplayName("이름의 길이를 출력한다") void length() { - Name name = new Name("pobi"); + Name name = new PlayerName("pobi"); int actual = name.length(); assertThat(actual).isEqualTo(4); } @@ -50,7 +50,7 @@ void length() { @Test @DisplayName("이름을 출력한다") void name() { - Name name = new Name("pobi"); + Name name = new PlayerName("pobi"); String actual = name.name(); assertThat(actual).isEqualTo("pobi"); diff --git a/src/test/java/ladder/domain/PlayerTest.java b/src/test/java/ladder/domain/PlayerTest.java deleted file mode 100644 index f479656c20..0000000000 --- a/src/test/java/ladder/domain/PlayerTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package ladder.domain; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -public class PlayerTest { - @Test - @DisplayName("플레이어를 생성한다") - void create() { - Player actual = new Player("pobi"); - Player expected = new Player(new Name("pobi")); - Assertions.assertThat(actual).isEqualTo(expected); - } - - @Test - @DisplayName("플레이어 이름을 출력한다") - void name() { - Player player = new Player("pobi"); - Name name = player.name(); - Assertions.assertThat(name).isEqualTo(new Name("pobi")); - - } -} diff --git a/src/test/java/ladder/domain/PlayersTest.java b/src/test/java/ladder/domain/PlayersTest.java index 0c81531e43..77e72a36b6 100644 --- a/src/test/java/ladder/domain/PlayersTest.java +++ b/src/test/java/ladder/domain/PlayersTest.java @@ -1,64 +1,97 @@ package ladder.domain; +import ladder.exception.PlayersException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; +import static ladder.domain.Players.NOT_ENOUGH_PLAYERS_SIZE_MESSAGE; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; public class PlayersTest { public static final Players PLAYERS1 = new Players("pobi,crong,honux,jk"); private Players players; + private PlayerName playerName1; + private PlayerName playerName2; + private PlayerName playerName3; + private PlayerName playerName4; + + private Point firstPoint; + private Point next1Point; + private Point next2Point; + private Point lastPoint; @BeforeEach void setUp() { + playerName1 = new PlayerName("pobi"); + playerName2 = new PlayerName("crong"); + playerName3 = new PlayerName("honux"); + playerName4 = new PlayerName("jk"); + + firstPoint = Point.first(true); + next1Point = firstPoint.next(false); + next2Point = next1Point.next(true); + lastPoint = next2Point.last(); + players = new Players("pobi,crong,honux,jk"); } @Test @DisplayName("플레이어 목록을 생성한다") void create() { - Players expected = new Players(List.of( - new Player("pobi"), - new Player("crong"), - new Player("honux"), - new Player("jk"))); + Players expected = new Players(List.of(playerName1, playerName2, playerName3, playerName4), new Vertical()); assertThat(players).isEqualTo(expected); } @Test - @DisplayName("플레이어 목록의 size 를 출력한다") + @DisplayName("플레이어 목록을 생성실패한다: 플레이어 목록이 1명 미만") + void create_실패_플레이어_목록이_1명_미만() { + assertThatThrownBy(() -> { + new Players(List.of(), new Vertical()); + }).isInstanceOf(PlayersException.class) + .hasMessage(NOT_ENOUGH_PLAYERS_SIZE_MESSAGE); + } + + @Test + @DisplayName("size 를 출력한다") void size() { int actual = players.size(); assertThat(actual).isEqualTo(4); } @Test - @DisplayName("플레이어 목록의 이름을 출력한다") + @DisplayName("이름을 출력한다") void names() { - List actual = players.names(); - List expected = List.of( - new Name("pobi"), - new Name("crong"), - new Name("honux"), - new Name("jk") + List actual = players.names(); + List expected = List.of( + new PlayerName("pobi"), + new PlayerName("crong"), + new PlayerName("honux"), + new PlayerName("jk") ); assertThat(actual).isEqualTo(expected); } - @Test - @DisplayName("플레이어 목록중 이름의 가장 긴 길이를 출력한다") - void namesMaxLength() { - int actual = players.namesMaxLength(); + @DisplayName("현재 사다리 높이를 출력한다") + void vertical() { + players = new Players(List.of( + new PlayerName("pobi"), + new PlayerName("crong"), + new PlayerName("honux"), + new PlayerName("jk")), + new Vertical(1)); + + Vertical actual = players.vertical(); + Vertical expected = new Vertical(1); - assertThat(actual).isEqualTo(5); + assertThat(actual).isEqualTo(expected); } - -} +} \ No newline at end of file diff --git a/src/test/java/ladder/domain/PointTest.java b/src/test/java/ladder/domain/PointTest.java index 180ef4873b..bab63186ef 100644 --- a/src/test/java/ladder/domain/PointTest.java +++ b/src/test/java/ladder/domain/PointTest.java @@ -1,7 +1,8 @@ package ladder.domain; +import ladder.domain.enums.MoveStatus; import ladder.exception.PointException; -import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -11,6 +12,21 @@ public class PointTest { + + private Point first; + private Point next1; + private Point next2; + private Point last; + + @BeforeEach + void setUp() { + // f t f f f + first = Point.first(true); + next1 = first.next(false); + next2 = next1.next(false); + last = next2.last(); + } + @Test @DisplayName("첫번째 포인트를 생성한다") void first() { @@ -53,23 +69,46 @@ void last() { @Test @DisplayName("현재 포인트를 출력한다") void getCurrent() { - // f t f t f - Point first = Point.first(true); - Point next1 = first.next(false); - Point next2 = next1.next(true); - Point last = next2.last(); - - boolean firstCurrent = first.getCurrent(); + // fir ne1 ne2 las + // f | t | f | f | f + boolean firstCurrent = first.getRight(); boolean firstCurrentExpected = true; - boolean next1Current = next1.getCurrent(); + boolean next1Current = next1.getRight(); boolean next1CurrentExpected = false; - boolean next2Current = next2.getCurrent(); - boolean next2CurrentExpected = true; + boolean next2Current = next2.getRight(); + boolean next2CurrentExpected = false; + + assertThat(firstCurrent).isEqualTo(firstCurrentExpected); + assertThat(next1Current).isEqualTo(next1CurrentExpected); + assertThat(next2Current).isEqualTo(next2CurrentExpected); + } + + @Test + @DisplayName("우측 이동") + void move_우측() { + MoveStatus actualFirst = first.move(); + MoveStatus expectedFirst = MoveStatus.RIGHT; + + assertThat(actualFirst).isEqualTo(expectedFirst); + } + + @Test + @DisplayName("좌측 이동") + void move_좌측() { + MoveStatus actualNext1 = next1.move(); + MoveStatus expectedNext1 = MoveStatus.LEFT; + + assertThat(actualNext1).isEqualTo(expectedNext1); + } + + @Test + @DisplayName("이동 없음") + void move_이동_없음() { + MoveStatus actualNext2 = next2.move(); + MoveStatus expectedNext2 = MoveStatus.STOP; - Assertions.assertThat(firstCurrent).isEqualTo(firstCurrentExpected); - Assertions.assertThat(next1Current).isEqualTo(next1CurrentExpected); - Assertions.assertThat(next2Current).isEqualTo(next2CurrentExpected); + assertThat(actualNext2).isEqualTo(expectedNext2); } } \ No newline at end of file diff --git a/src/test/java/ladder/domain/ResultsTest.java b/src/test/java/ladder/domain/ResultsTest.java new file mode 100644 index 0000000000..c782e18896 --- /dev/null +++ b/src/test/java/ladder/domain/ResultsTest.java @@ -0,0 +1,70 @@ +package ladder.domain; + +import ladder.exception.NoNameException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static ladder.domain.Results.NO_NAME_MESSAGE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class ResultsTest { + + private Map resultMap; + + @BeforeEach + void setUp() { + resultMap = Map.of( + new PlayerName("pobi"), new RewardName("꽝"), + new PlayerName("jk"), new RewardName("5000"), + new PlayerName("crong"), new RewardName("꽝"), + new PlayerName("honux"), new RewardName("3000") + ); + } + + @Test + void create() { + Results actual = new Results(resultMap); + Results expected = new Results(Map.of( + new PlayerName("jk"), new RewardName("5000"), + new PlayerName("pobi"), new RewardName("꽝"), + new PlayerName("crong"), new RewardName("꽝"), + new PlayerName("honux"), new RewardName("3000") + )); + + assertThat(actual).isEqualTo(expected); + } + + @Test + @DisplayName("플레이어 이름에 해당하는 결과 출력") + void reward() { + Results results = new Results(resultMap); + RewardName actual = results.result(new PlayerName("pobi")); + RewardName expected = new RewardName("꽝"); + + assertThat(actual).isEqualTo(expected); + } + + @Test + @DisplayName("플레이어 이름이 없으면 오류") + void reward_플레이어_이름_없으면_오류() { + assertThatThrownBy(() -> { + Results results = new Results(resultMap); + results.result(new PlayerName("pppp")); + }).isInstanceOf(NoNameException.class) + .hasMessage(NO_NAME_MESSAGE); + } + + @Test + @DisplayName("결과 모두 출력") + void rewards() { + Results results = new Results(resultMap); + Map actual = results.results(); + Map expected = resultMap; + + assertThat(actual).isEqualTo(expected); + } +} diff --git a/src/test/java/ladder/domain/RewardNameTest.java b/src/test/java/ladder/domain/RewardNameTest.java new file mode 100644 index 0000000000..7786ce5678 --- /dev/null +++ b/src/test/java/ladder/domain/RewardNameTest.java @@ -0,0 +1,58 @@ +package ladder.domain; + +import ladder.exception.InvalidNameException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import static ladder.domain.Name.NOT_ALLOW_EMPTY_NAME_MESSAGE; +import static ladder.domain.Name.NOT_ALLOW_EXCEED_MAX_NAME_LENGTH_MESSAGE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class RewardNameTest { + + @Test + @DisplayName("이름을 생성한다") + void create() { + Name actual = new RewardName("pobi"); + Name expected = new RewardName("pobi"); + assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest(name = "이름 생성 오류: 공백이 입력되었을 경우 이름생성 오류가 발생한다") + @NullAndEmptySource + void create_공백_실패(String emptyName) { + assertThatThrownBy(() -> { + new RewardName(emptyName); + }).isInstanceOf(InvalidNameException.class) + .hasMessage(NOT_ALLOW_EMPTY_NAME_MESSAGE); + } + + @Test + @DisplayName("이름 생성 오류: 5글자를 초과하면 이름생성 오류가 발생한다") + void create_5글자초과_실패() { + assertThatThrownBy(() -> { + Name name = new RewardName("pobi22"); + }).isInstanceOf(InvalidNameException.class) + .hasMessage(NOT_ALLOW_EXCEED_MAX_NAME_LENGTH_MESSAGE); + } + + @Test + @DisplayName("이름의 길이를 출력한다") + void length() { + Name name = new RewardName("pobi"); + int actual = name.length(); + assertThat(actual).isEqualTo(4); + } + + @Test + @DisplayName("이름을 출력한다") + void name() { + Name name = new RewardName("pobi"); + String actual = name.name(); + + assertThat(actual).isEqualTo("pobi"); + } +} diff --git a/src/test/java/ladder/domain/RewardsTest.java b/src/test/java/ladder/domain/RewardsTest.java new file mode 100644 index 0000000000..c93366d855 --- /dev/null +++ b/src/test/java/ladder/domain/RewardsTest.java @@ -0,0 +1,60 @@ +package ladder.domain; + +import ladder.exception.RewardsCountException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static ladder.domain.Rewards.PLAYERS_COUNT_REWARDS_COUNT_NOT_EQUAL_MESSAGE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class RewardsTest { + + private RewardName rewardName1; + private RewardName rewardName2; + private RewardName rewardName3; + private List rewardNames; + + @BeforeEach + void setUp() { + rewardName1 = new RewardName("꽝"); + rewardName2 = new RewardName("5000"); + rewardName3 = new RewardName("3000"); + rewardNames = List.of( + rewardName1, + rewardName2, + rewardName1, + rewardName3 + ); + } + + @Test + @DisplayName("보상을 생성한다") + void create() { + Rewards actual = new Rewards("꽝,5000,꽝,3000", 4); + Rewards expected = new Rewards(rewardNames, 4); + assertThat(actual).isEqualTo(expected); + } + + @Test + @DisplayName("보상을 생성 실패한다: rewardNames 갯수와 playersCount 갯수 불일치") + void create_실패_rewardNames_갯수와_playersCount_갯수_불일치() { + assertThatThrownBy(() -> { + new Rewards("꽝,5000,꽝,3000", 3); + }).isInstanceOf(RewardsCountException.class) + .hasMessage(PLAYERS_COUNT_REWARDS_COUNT_NOT_EQUAL_MESSAGE); + } + + @Test + @DisplayName("이름을 출력한다") + void names() { + Rewards rewards = new Rewards("꽝,5000,꽝,3000", 4); + List actual = rewards.names(); + List expected = rewardNames; + + assertThat(actual).isEqualTo(expected); + } +} diff --git a/src/test/java/ladder/domain/VerticalTest.java b/src/test/java/ladder/domain/VerticalTest.java new file mode 100644 index 0000000000..2a487feeb0 --- /dev/null +++ b/src/test/java/ladder/domain/VerticalTest.java @@ -0,0 +1,40 @@ +package ladder.domain; + +import ladder.exception.VerticalException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static ladder.domain.Vertical.VERTICAL_IS_LESS_THEN_ZERO; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class VerticalTest { + + @Test + @DisplayName("사다리의 현재 높이를 생성한다") + void create() { + Vertical actual = new Vertical(); + Vertical expected = new Vertical(0); + + assertThat(actual).isEqualTo(expected); + } + + @Test + @DisplayName("사다리의 현재 높이를 생성실패: 0보다 작을 수 없다") + void create_실패_0보다_작을_수_없다() { + assertThatThrownBy(() -> { + new Vertical(-1); + }).isInstanceOf(VerticalException.class) + .hasMessage(VERTICAL_IS_LESS_THEN_ZERO); + } + + @Test + @DisplayName("사다리 높이를 이동시킨다") + void moveDown() { + Vertical vertical = new Vertical(1); + Vertical actual = vertical.move(); + Vertical expected = new Vertical(2); + + assertThat(actual).isEqualTo(expected); + } +} diff --git a/src/test/java/ladder/domain/enums/MoveStatusTest.java b/src/test/java/ladder/domain/enums/MoveStatusTest.java new file mode 100644 index 0000000000..3792017246 --- /dev/null +++ b/src/test/java/ladder/domain/enums/MoveStatusTest.java @@ -0,0 +1,19 @@ +package ladder.domain.enums; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class MoveStatusTest { + @Test + @DisplayName("이동상태의 값을 구한다") + void value() { + int right = MoveStatus.RIGHT.value(); + int left = MoveStatus.LEFT.value(); + int stop = MoveStatus.STOP.value(); + + Assertions.assertThat(right).isEqualTo(1); + Assertions.assertThat(left).isEqualTo(-1); + Assertions.assertThat(stop).isEqualTo(0); + } +} \ No newline at end of file diff --git a/src/test/java/ladder/domain/util/CrossGeneratorTest.java b/src/test/java/ladder/domain/generator/CrossGeneratorTest.java similarity index 89% rename from src/test/java/ladder/domain/util/CrossGeneratorTest.java rename to src/test/java/ladder/domain/generator/CrossGeneratorTest.java index 5664afeaf8..fd6a199823 100644 --- a/src/test/java/ladder/domain/util/CrossGeneratorTest.java +++ b/src/test/java/ladder/domain/generator/CrossGeneratorTest.java @@ -1,4 +1,4 @@ -package ladder.domain.util; +package ladder.domain.generator; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test;