diff --git a/README.md b/README.md index a45073411c..45b607c25d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,33 @@ # 사다리 게임 + +## 3단계 - 사다리(게임 실행) +### TODO +- [x] PR 반영 + - [x] Line 객체에 가변 인자를 받은 생성자를 추가 + - [x] LineGenerator가 generateLine에서 Line 객체를 리턴 + - [x] LineGeneratorTest의 너무 많은 가변인자 테스트 정리->보다 적은수로 경우의 수를 커버 + - [x] Ladder.java에 game Play에 대한 책임 부여 검토 + - [x] Line.java에 LEFT, RIGHT, PASS와 같은 상태값을 enum으로 구현 + - [x] Line의 index 원시값 포장 + - [x] LineGenerator에 현재값,이전값을 가지는 Point 객체 도입 검토 + +- [x] 사다리 실행 결과를 출력해야 한다. +- [x] 개인별 이름을 입력하면 개인별 결과를 출력하고, "all"을 입력하면 전체 참여자의 실행 결과를 출력한다. + +### 프로그래밍 요구사항 +- 자바 8의 스트림과 람다를 적용해 프로그래밍한다. +- 규칙 6: 모든 엔티티를 작게 유지한다. +- **규칙 7: 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.** + + + ## 2단계 - 사다리 생성 ### TODO +- [x] 사다리 실행 결과를 출력해야 한다. +- [x] 개인별 이름을 입력하면 개인별 결과를 출력하고, "all"을 입력하면 전체 참여자의 실행 결과를 출력한다. + +- [x] PR 반영 - [x] 사다리 게임에 참여하는 사람에 이름을 최대5글자까지 부여할 수 있다. 사다리를 출력할 때 사람 이름도 같이 출력한다. - [x] 사람 이름은 쉼표(,)를 기준으로 구분한다. - [x] 사람 이름을 5자 기준으로 출력하기 때문에 사다리 폭도 넓어져야 한다. @@ -11,6 +37,7 @@ ### 프로그래밍 요구사항 - 자바 8의 스트림과 람다를 적용해 프로그래밍한다. - 규칙 6: 모든 엔티티를 작게 유지한다. +- **규칙 7: 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.** ## 진행 방법 diff --git a/src/main/java/nextstep/ladder/LadderGame.java b/src/main/java/nextstep/ladder/LadderGame.java index ed89926e64..456eab0e74 100644 --- a/src/main/java/nextstep/ladder/LadderGame.java +++ b/src/main/java/nextstep/ladder/LadderGame.java @@ -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 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("이름이 명단에 없습니다."); + } + } } } diff --git a/src/main/java/nextstep/ladder/domain/common/AbstractValueList.java b/src/main/java/nextstep/ladder/domain/common/AbstractValueList.java new file mode 100644 index 0000000000..924dba3e98 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/common/AbstractValueList.java @@ -0,0 +1,34 @@ +package nextstep.ladder.domain.common; + +import java.util.List; + +public abstract class AbstractValueList { + protected final List values; + + protected AbstractValueList(List values) { + if (values == null || values.isEmpty()) { + throw new IllegalArgumentException("리스트는 비어 있을 수 없습니다."); + } + this.values = List.copyOf(values); + } + + public List 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); + } +} diff --git a/src/main/java/nextstep/ladder/domain/generator/CombinationGenerator.java b/src/main/java/nextstep/ladder/domain/generator/CombinationGenerator.java deleted file mode 100644 index aa7140a4a7..0000000000 --- a/src/main/java/nextstep/ladder/domain/generator/CombinationGenerator.java +++ /dev/null @@ -1,41 +0,0 @@ -package nextstep.ladder.domain.generator; - -import java.util.*; - -public class CombinationGenerator { - public static void main(String[] args) { - int countOfPerson = 3; - List> result = new ArrayList<>(); - generateCombinations(countOfPerson, new ArrayList<>(), result); - - for (List combination : result) { - if(hasConsecutiveTrues(combination)) { - System.out.println(combination); - } - } - } - - public static void generateCombinations(int n, List current, List> result) { - if (current.size() == n) { - result.add(new ArrayList<>(current)); - return; - } - - current.add(true); - generateCombinations(n, current, result); - current.remove(current.size() - 1); - - current.add(false); - generateCombinations(n, current, result); - current.remove(current.size() - 1); - } - - private static boolean hasConsecutiveTrues(List combination) { - for (int i = 0; i < combination.size() - 1; i++) { - if (combination.get(i) && combination.get(i + 1)) { - return true; - } - } - return false; - } -} diff --git a/src/main/java/nextstep/ladder/domain/generator/LadderGenerator.java b/src/main/java/nextstep/ladder/domain/generator/LadderGenerator.java index a57e3164b2..e0298fd002 100644 --- a/src/main/java/nextstep/ladder/domain/generator/LadderGenerator.java +++ b/src/main/java/nextstep/ladder/domain/generator/LadderGenerator.java @@ -5,10 +5,10 @@ import nextstep.ladder.domain.ladder.Line; public class LadderGenerator { - public static Ladder generateLadder(int countOfPerson, Height height) { - Ladder ladder = new Ladder(); + public static Ladder generateLadder(int countOfPeople, Height height) { + Ladder ladder = new Ladder(countOfPeople); for (int i = 0; i < height.value(); i++) { - Line line = new Line(countOfPerson); + Line line = new Line(countOfPeople); ladder.add(line); } diff --git a/src/main/java/nextstep/ladder/domain/generator/LineGenerator.java b/src/main/java/nextstep/ladder/domain/generator/LineGenerator.java new file mode 100644 index 0000000000..9a1f4fceeb --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/generator/LineGenerator.java @@ -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 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 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(); + } +} diff --git a/src/main/java/nextstep/ladder/domain/generator/Point.java b/src/main/java/nextstep/ladder/domain/generator/Point.java new file mode 100644 index 0000000000..5da6c33f8d --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/generator/Point.java @@ -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) { + this.current = current; + this.next = next; + } + + public boolean isConsecutive() { + return current && next; + } + + public boolean current() { + return current; + } + + public boolean next() { + return next; + } +} \ No newline at end of file diff --git a/src/main/java/nextstep/ladder/domain/ladder/Direction.java b/src/main/java/nextstep/ladder/domain/ladder/Direction.java new file mode 100644 index 0000000000..62d60c26d7 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/ladder/Direction.java @@ -0,0 +1,24 @@ +package nextstep.ladder.domain.ladder; + +public enum Direction { + 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); +} \ No newline at end of file diff --git a/src/main/java/nextstep/ladder/domain/ladder/Index.java b/src/main/java/nextstep/ladder/domain/ladder/Index.java new file mode 100644 index 0000000000..40f838e5a9 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/ladder/Index.java @@ -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; + } +} \ No newline at end of file diff --git a/src/main/java/nextstep/ladder/domain/ladder/Ladder.java b/src/main/java/nextstep/ladder/domain/ladder/Ladder.java index 08f02e4472..d4b1a7cb1c 100644 --- a/src/main/java/nextstep/ladder/domain/ladder/Ladder.java +++ b/src/main/java/nextstep/ladder/domain/ladder/Ladder.java @@ -4,17 +4,35 @@ import java.util.List; public class Ladder { - List lineList; + private final List lineList; + private final int countOfPeople; - public Ladder() { + public Ladder(int countOfPeople) { + this.countOfPeople = countOfPeople; this.lineList = new ArrayList<>(); } - public List values() { - return lineList; - } + public List 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 all() { + List results = new ArrayList<>(); + for(int i = 0; i < countOfPeople; i++) { + results.add(resultOf(i)); + } + return results; + } } diff --git a/src/main/java/nextstep/ladder/domain/ladder/Line.java b/src/main/java/nextstep/ladder/domain/ladder/Line.java index 3613a8f7cf..3b42056b2c 100644 --- a/src/main/java/nextstep/ladder/domain/ladder/Line.java +++ b/src/main/java/nextstep/ladder/domain/ladder/Line.java @@ -1,41 +1,59 @@ package nextstep.ladder.domain.ladder; -import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.Collectors; + +import static nextstep.ladder.domain.generator.LineGenerator.assertValidLine; +import static nextstep.ladder.domain.generator.LineGenerator.generateLine; public class Line { - List line = new ArrayList<>(); - - public Line(int countOfPerson) { - boolean lastBoolean = false; - for (int i = 0; i < countOfPerson - 1; i++) { - boolean currBoolean = randomBoolean(); - if(isConsecutiveLine(currBoolean, lastBoolean)) { - currBoolean = false; - } - line.add(currBoolean); - lastBoolean = currBoolean; - } + private final List line; + + public Line(int countOfPeople) { + this(generateLine(countOfPeople)); + } + + public Line(Line other) { + this(List.copyOf(other.line)); } - private boolean isConsecutiveLine(boolean curr, boolean last) { - return curr && last; + + public Line(Boolean... values) { + this(List.of(values)); } - private boolean randomBoolean() { - return ThreadLocalRandom.current().nextBoolean(); + public Line(List values) { + assertValidLine(values); + this.line = List.copyOf(values); } public int size() { return line.size(); } - @Override - public String toString() { - return line.stream() - .map(b -> b ? "|-----" : "| ") - .collect(Collectors.joining()) - + "|"; + public List values() { + return List.copyOf(line); + } + + public Index movePerson(Index index) { + Direction direction = determineDirection(index); + return direction.move(index); + } + private Direction determineDirection(Index index) { + if (isMovableToLeft(index)) { + return Direction.LEFT; + } + if (isMovableToRight(index)) { + return Direction.RIGHT; + } + return Direction.PASS; + } + + public boolean isMovableToLeft(Index index) { + int targetIndex = index.value() - 1; + return targetIndex >= 0 && line.get(targetIndex); + } + + public boolean isMovableToRight(Index index) { + int targetIndex = index.value(); + return targetIndex < line.size() && line.get(targetIndex); } } diff --git a/src/main/java/nextstep/ladder/domain/name/Name.java b/src/main/java/nextstep/ladder/domain/name/Name.java index 0ab10ab1ce..300bb7dcf6 100644 --- a/src/main/java/nextstep/ladder/domain/name/Name.java +++ b/src/main/java/nextstep/ladder/domain/name/Name.java @@ -1,5 +1,7 @@ package nextstep.ladder.domain.name; +import java.util.Objects; + public class Name { private String name; @@ -7,11 +9,24 @@ public Name(String name) { if (null == name || name.isBlank() || name.length() > 5) { throw new IllegalArgumentException("이름의 형식이 올바르지 않습니다. name=" + name); } - this.name = name; + this.name = name.trim(); } @Override public String toString() { return name; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Name name1 = (Name) o; + return Objects.equals(name, name1.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } } diff --git a/src/main/java/nextstep/ladder/domain/name/Names.java b/src/main/java/nextstep/ladder/domain/name/Names.java index c608f41978..97edaf23d7 100644 --- a/src/main/java/nextstep/ladder/domain/name/Names.java +++ b/src/main/java/nextstep/ladder/domain/name/Names.java @@ -1,28 +1,17 @@ package nextstep.ladder.domain.name; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public class Names { - private final String DELIM = ","; - private List nameList; +import nextstep.ladder.domain.common.AbstractValueList; - public Names(String names) { - if (names == null || names.isBlank()) { - throw new IllegalArgumentException("이름 문자열은 빈공백일 수 없습니다."); - } +import java.util.List; - nameList = Arrays.stream(names.split(DELIM)) - .map(Name::new) - .collect(Collectors.toList()); - } +import static nextstep.ladder.domain.util.StringParserUtil.parseInputString; - public List values() { - return nameList; +public class Names extends AbstractValueList { + public Names(String input) { + this(parseInputString(input, Name::new)); } - public int count() { - return nameList.size(); + public Names(List nameList) { + super(nameList); } } diff --git a/src/main/java/nextstep/ladder/domain/reward/Reward.java b/src/main/java/nextstep/ladder/domain/reward/Reward.java new file mode 100644 index 0000000000..c83f22b6ec --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/reward/Reward.java @@ -0,0 +1,36 @@ +package nextstep.ladder.domain.reward; + +import java.util.Objects; + +public class Reward { + private String reward; + + public Reward(String reward) { + if (reward == null || reward.isBlank()) { + throw new IllegalArgumentException("보상은 null이거나 빈값일 수 없습니다. reward=" + reward); + } + this.reward = reward; + } + + public String value() { + return reward; + } + + @Override + public String toString() { + return reward; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Reward reward = (Reward) o; + return Objects.equals(this.reward, reward.reward); + } + + @Override + public int hashCode() { + return Objects.hash(reward); + } +} diff --git a/src/main/java/nextstep/ladder/domain/reward/Rewards.java b/src/main/java/nextstep/ladder/domain/reward/Rewards.java new file mode 100644 index 0000000000..4d87618e2d --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/reward/Rewards.java @@ -0,0 +1,17 @@ +package nextstep.ladder.domain.reward; + +import nextstep.ladder.domain.common.AbstractValueList; + +import java.util.List; + +import static nextstep.ladder.domain.util.StringParserUtil.parseInputString; + +public class Rewards extends AbstractValueList { + public Rewards(String input) { + this(parseInputString(input, Reward::new)); + } + + public Rewards(List rewardList) { + super(rewardList); + } +} diff --git a/src/main/java/nextstep/ladder/domain/util/StringParserUtil.java b/src/main/java/nextstep/ladder/domain/util/StringParserUtil.java new file mode 100644 index 0000000000..f2d5c2f667 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/util/StringParserUtil.java @@ -0,0 +1,20 @@ +package nextstep.ladder.domain.util; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class StringParserUtil { + private static final String DELIM = ","; + + public static List parseInputString(String input, Function mapper) { + if (input == null || input.isBlank()) { + throw new IllegalArgumentException("입력 문자열은 비어 있을 수 없습니다."); + } + + return Arrays.stream(input.split(DELIM)) + .map(mapper) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/nextstep/ladder/view/InputView.java b/src/main/java/nextstep/ladder/view/InputView.java index d1378c6ed3..31e17e9f1e 100644 --- a/src/main/java/nextstep/ladder/view/InputView.java +++ b/src/main/java/nextstep/ladder/view/InputView.java @@ -15,4 +15,16 @@ public static Integer getHeight() { Scanner scanner = new Scanner(System.in); return scanner.nextInt(); } + + public static String getRewards() { + System.out.println("\n실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); + Scanner scanner = new Scanner(System.in); + return scanner.nextLine(); + } + + public static String getPlayerName() { + System.out.println("\n결과를 보고 싶은 사람은?(종료=quit)"); + Scanner scanner = new Scanner(System.in); + return scanner.nextLine(); + } } diff --git a/src/main/java/nextstep/ladder/view/ResultView.java b/src/main/java/nextstep/ladder/view/ResultView.java index 68ab5869d7..c6c86c9f61 100644 --- a/src/main/java/nextstep/ladder/view/ResultView.java +++ b/src/main/java/nextstep/ladder/view/ResultView.java @@ -4,23 +4,41 @@ import nextstep.ladder.domain.ladder.Line; 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 java.util.List; +import java.util.stream.Collectors; public class ResultView { - public static void result(Names names, Ladder ladder) { - System.out.println("\n실행결과\n"); + public static void ladderResult(Names names, Ladder ladder, Rewards rewards) { + System.out.println("\n사다리 결과\n"); for(Name name: names.values()) { System.out.printf("%-5s ", name.toString()); } + System.out.println(""); - names.values() - .stream() - .map(name -> System.out.printf("%-5s ", name)); + for(Line line: ladder.values()) { + System.out.println(" " + viewLine(line)); + } - System.out.println(""); + for(Reward reward: rewards.values()) { + System.out.printf("%-5s ", reward.toString()); + } + } + + public static String viewLine(Line line) { + return line.values().stream() + .map(b -> b ? "|-----" : "| ") + .collect(Collectors.joining()) + + "|"; + } - ladder.values() - .stream() - .map(line -> " " + line.toString()); + public static void rewardResult(Names names, Rewards rewards, List rewardList) { + System.out.println("\n실행 결과"); + for(Name name: names.values()) { + System.out.println(name + " : " + rewards.get(rewardList.get(names.positionOf(name)))); + } } } diff --git a/src/test/java/nextstep/ladder/CombinationsGeneratorTest.java b/src/test/java/nextstep/ladder/CombinationsGeneratorTest.java deleted file mode 100644 index 49f5d550ce..0000000000 --- a/src/test/java/nextstep/ladder/CombinationsGeneratorTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package nextstep.ladder; - -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.List; - -import static nextstep.ladder.domain.generator.CombinationGenerator.generateCombinations; -import static org.assertj.core.api.Assertions.assertThat; - -public class CombinationsGeneratorTest { - - @Test - public void 연속된TRUE를_제외한_모든조합을_생성한다() { - int n = 3; // 원하는 길이 입력 - List> result = new ArrayList<>(); - generateCombinations(n, new ArrayList<>(), result); - - assertThat(result).hasSize(5); - } - -} diff --git a/src/test/java/nextstep/ladder/LadderGeneratorTest.java b/src/test/java/nextstep/ladder/LadderGeneratorTest.java index d1864cb792..e785875922 100644 --- a/src/test/java/nextstep/ladder/LadderGeneratorTest.java +++ b/src/test/java/nextstep/ladder/LadderGeneratorTest.java @@ -1,9 +1,11 @@ package nextstep.ladder; +import nextstep.ladder.domain.generator.LadderGenerator; +import nextstep.ladder.domain.generator.LineGenerator; import nextstep.ladder.domain.ladder.Height; import nextstep.ladder.domain.ladder.Ladder; -import nextstep.ladder.domain.generator.LadderGenerator; import nextstep.ladder.domain.ladder.Line; +import nextstep.ladder.view.ResultView; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -11,17 +13,23 @@ public class LadderGeneratorTest { @Test public void 입력된갯수만큼_사다리를_생성한다() { - int countOfPerson = 4; + int countOfPeople = 4; Height height = new Height(5); - LadderGenerator ladderGenerator = new LadderGenerator(); - - Ladder ladder = ladderGenerator.generateLadder(countOfPerson, height); + Ladder ladder = LadderGenerator.generateLadder(countOfPeople, height); for(Line line : ladder.values()) { - System.out.println(line); - assertThat(line.size()).isEqualTo(countOfPerson - 1); + System.out.println(ResultView.viewLine(line)); + assertThat(line.size()).isEqualTo(countOfPeople - 1); } assertThat(ladder.values()).hasSize(5); + + } + + @Test + public void 사람수를_입력하면_사람수보다_하나작은_사다리가_만들어진다() { + int countOfPeople = 10; + Line line = LineGenerator.generateLine(countOfPeople); + assertThat(line.size()).isEqualTo(countOfPeople - 1); } } diff --git a/src/test/java/nextstep/ladder/domain/generator/LineGeneratorTest.java b/src/test/java/nextstep/ladder/domain/generator/LineGeneratorTest.java new file mode 100644 index 0000000000..2a89973190 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/generator/LineGeneratorTest.java @@ -0,0 +1,55 @@ +package nextstep.ladder.domain.generator; + +import nextstep.ladder.domain.ladder.Line; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import java.util.List; +import java.util.stream.Stream; + +import static nextstep.ladder.domain.generator.LineGenerator.assertValidLine; +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +class LineGeneratorTest { + @Test + public void 사람수를_입력하면_사람수보다_하나작은_계단이_만들어진다() { + int countOfPeople = 10; + + Line line = LineGenerator.generateLine(countOfPeople); + + assertThat(line.size()).isEqualTo(countOfPeople - 1); + } + + @Test + public void 연속된_계단은_생성될수없다() { + assertThatIllegalArgumentException().isThrownBy(() -> { + assertValidLine(List.of(true, true)); + }); + } + + @ParameterizedTest + @NullAndEmptySource + public void 계단은_null이거나_빈값일수없다(List invalidLine) { + assertThatIllegalArgumentException().isThrownBy(() -> { + assertValidLine(invalidLine); + }); + } + + @ParameterizedTest + @MethodSource("validLines") + public void 연속되지_않은_계단은_생성할수있다(List line) { + assertDoesNotThrow(() -> { + assertValidLine(line); + }); + } + static Stream> validLines() { + return Stream.of( + List.of(false, false), + List.of(true, false), + List.of(false, true) + ); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/ladder/domain/ladder/LadderTest.java b/src/test/java/nextstep/ladder/domain/ladder/LadderTest.java new file mode 100644 index 0000000000..70f7afa270 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/ladder/LadderTest.java @@ -0,0 +1,44 @@ +package nextstep.ladder.domain.ladder; + +import nextstep.ladder.domain.generator.LadderGenerator; +import nextstep.ladder.domain.name.Names; +import org.junit.jupiter.api.Test; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class LadderTest { + @Test + public void 단건으로_사람들의_정보가_입력되면_중복없는_결과를_리턴한다() { + Names names = new Names("aaa, bbb, ccc"); + Height height = new Height(5); + Ladder ladder = LadderGenerator.generateLadder(names.count(), height); + + Set setList = new HashSet<>(); + for(int i = 0; i < names.count(); i++) { + Index result = ladder.resultOf(i); + setList.add(result.value()); + } + + assertThat(setList).hasSize(3); + } + + @Test + public void 전체_사람들의_정보가_입력되면_중복없는_결과를_리턴한다() { + Names names = new Names("aaa, bbb, ccc"); + Height height = new Height(5); + Ladder ladder = LadderGenerator.generateLadder(names.count(), height); + + List results = ladder.all(); + + Set setList = new HashSet<>(); + for(Index result: results) { + setList.add(result.value()); + } + + assertThat(setList).hasSize(3); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/ladder/domain/ladder/LineTest.java b/src/test/java/nextstep/ladder/domain/ladder/LineTest.java new file mode 100644 index 0000000000..094472be5d --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/ladder/LineTest.java @@ -0,0 +1,72 @@ +package nextstep.ladder.domain.ladder; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +class LineTest { + @Test + public void 연속된_계단은_생성될수없다() { + List line = new ArrayList<>(); + line.add(true); + line.add(true); + + assertThatIllegalArgumentException().isThrownBy(() -> { + new Line(line); + }); + } + + @Test + public void 사람수를_입력하면_사람수보다_하나작은_사다리가_만들어진다() { + int countOfPeople = 10; + Line line = new Line(countOfPeople); + + assertThat(line.size()).isEqualTo(countOfPeople - 1); + } + + @Test + public void 사다리_왼쪽으로_이동불가() { + Line line = new Line(false, false); + Index index = new Index(1, 2); + assertThat(line.isMovableToLeft(index)).isFalse(); + } + + @Test + public void 사다리_왼쪽으로_이동가능() { + Line line = new Line(true, false); + Index index = new Index(1, 2); + assertThat(line.isMovableToLeft(index)).isTrue(); + } + + @Test + public void 사다리_왼쪽끝일경우_왼쪽으로_이동불가() { + Line line = new Line(true, false); + Index index = new Index(0, 2); + assertThat(line.isMovableToLeft(index)).isFalse(); + } + + @Test + public void 사다리_오른쪽으로_이동가능() { + Line line = new Line(true, false); + Index index = new Index(0, 2); + assertThat(line.isMovableToRight(index)).isTrue(); + } + + @Test + public void 사다리_오른쪽으로_이동불가() { + Line line = new Line(false, false); + Index index = new Index(0, 2); + assertThat(line.isMovableToRight(index)).isFalse(); + } + + @Test + public void 사다리_오른쪽끝일경우_오른쪽으로_이동불가() { + Line line = new Line(false, false); + Index index = new Index(1, 2); + assertThat(line.isMovableToRight(index)).isFalse(); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/ladder/domain/name/NameTest.java b/src/test/java/nextstep/ladder/domain/name/NameTest.java index 70d15f6fe3..e8424a7f06 100644 --- a/src/test/java/nextstep/ladder/domain/name/NameTest.java +++ b/src/test/java/nextstep/ladder/domain/name/NameTest.java @@ -1,11 +1,11 @@ package nextstep.ladder.domain.name; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.NullSource; import org.junit.jupiter.params.provider.ValueSource; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; class NameTest { @ParameterizedTest diff --git a/src/test/java/nextstep/ladder/domain/name/NamesTest.java b/src/test/java/nextstep/ladder/domain/name/NamesTest.java new file mode 100644 index 0000000000..c9216db67b --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/name/NamesTest.java @@ -0,0 +1,37 @@ +package nextstep.ladder.domain.name; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +class NamesTest { + + @ParameterizedTest + @NullAndEmptySource + public void 공백문자열은_입력될수없다(String input) { + assertThatIllegalArgumentException().isThrownBy(() -> { + new Names(input); + }); + } + + @Test + public void 빈리스트는_입력될수없다() { + assertThatIllegalArgumentException().isThrownBy(() -> { + new Names(new ArrayList<>()); + }); + } + + @Test + public void 이름을통해_position값을_구할수있다() { + String input = "aaa, bbb, ccc"; + Names names = new Names(input); + + assertThat(names.positionOf(new Name("bbb"))).isEqualTo(1); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/ladder/domain/reward/RewardTest.java b/src/test/java/nextstep/ladder/domain/reward/RewardTest.java new file mode 100644 index 0000000000..415305fba1 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/reward/RewardTest.java @@ -0,0 +1,16 @@ +package nextstep.ladder.domain.reward; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +public class RewardTest { + @ParameterizedTest + @NullAndEmptySource + public void 보상값은_null이거나_빈공백일경우_에러(String value) { + assertThatIllegalArgumentException().isThrownBy(() -> + new Reward(value) + ); + } +} diff --git a/src/test/java/nextstep/ladder/domain/reward/RewardsTest.java b/src/test/java/nextstep/ladder/domain/reward/RewardsTest.java new file mode 100644 index 0000000000..331ebd0273 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/reward/RewardsTest.java @@ -0,0 +1,26 @@ +package nextstep.ladder.domain.reward; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import java.util.ArrayList; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +public class RewardsTest { + @ParameterizedTest + @NullAndEmptySource + public void 공백문자열은_입력될수없다(String input) { + assertThatIllegalArgumentException().isThrownBy(() -> { + new Rewards(input); + }); + } + + @Test + public void 빈리스트는_입력될수없다() { + assertThatIllegalArgumentException().isThrownBy(() -> { + new Rewards(new ArrayList<>()); + }); + } +}