diff --git a/README.md b/README.md index b853592f59..858b7c70b0 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,19 @@ * 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다. ## 온라인 코드 리뷰 과정 -* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/nextstep-step/nextstep-docs/tree/master/codereview) \ No newline at end of file +* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/nextstep-step/nextstep-docs/tree/master/codereview) + +## 기능정의 2단계 - 사다리(생성) +* 참여자 + * 참여자의 이름은 5자를 넘지 않는다. + +* 라인 + * 라인은 가로로 겹쳐지지 않는다. + * 이전 값을 조회하여 라인이 있다면 라인은 만들지 말고 없다면 랜덤으로 생성한다. + +* 라인들 + * 라인들은 인원수 -1 만큼 존재한다. + +* 사다리 + * 사다리의 높이만큼 사다리의 갯수를 생성한다. + diff --git a/src/main/java/nextstep/ladder/controller/LadderGameController.java b/src/main/java/nextstep/ladder/controller/LadderGameController.java new file mode 100644 index 0000000000..dcd0d5d343 --- /dev/null +++ b/src/main/java/nextstep/ladder/controller/LadderGameController.java @@ -0,0 +1,25 @@ +package nextstep.ladder.controller; + +import nextstep.ladder.model.Ladder; +import nextstep.ladder.model.Lines; +import nextstep.ladder.model.Player; +import nextstep.ladder.model.Players; +import nextstep.ladder.view.Input; +import nextstep.ladder.view.Output; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public class LadderGameController { + + public static void main(String[] args) { + String[] strings = Input.inputPlayers(); + Players players = Arrays.stream(strings) + .map(Player::new) + .collect(Collectors.collectingAndThen(Collectors.toList(), Players::new)); + + Ladder ladder = new Ladder(Input.inputLadderHeights(), players.number()); + + Output.outputResult(ladder, players); + } +} diff --git a/src/main/java/nextstep/ladder/model/Ladder.java b/src/main/java/nextstep/ladder/model/Ladder.java new file mode 100644 index 0000000000..eee0dd72c0 --- /dev/null +++ b/src/main/java/nextstep/ladder/model/Ladder.java @@ -0,0 +1,24 @@ +package nextstep.ladder.model; + +import java.util.ArrayList; +import java.util.List; + +public class Ladder { + private final List lines; + + public Ladder(final int numberOfFloors, final int numberOfPlayers) { + List result = new ArrayList<>(); + for (int i = 0; i < numberOfFloors; i++) { + result.add(new Lines(numberOfPlayers)); + } + this.lines = result; + } + + public int numberOfFloors() { + return lines.size(); + } + + public List getLines() { + return lines; + } +} diff --git a/src/main/java/nextstep/ladder/model/Line.java b/src/main/java/nextstep/ladder/model/Line.java new file mode 100644 index 0000000000..1ce5302827 --- /dev/null +++ b/src/main/java/nextstep/ladder/model/Line.java @@ -0,0 +1,45 @@ +package nextstep.ladder.model; + +import java.security.SecureRandom; +import java.util.Objects; + +public class Line { + private final Boolean hasLine; + + public Line(final boolean hasLine) { + this.hasLine = hasLine; + } + + public static Line create(final Line prevLine) { + if (prevLine == null || !prevLine.hasLine) { + SecureRandom secureRandom = new SecureRandom(); + return new Line(secureRandom.nextBoolean()); + } + return new Line(false); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Line line = (Line)o; + return Objects.equals(hasLine, line.hasLine); + } + + @Override + public int hashCode() { + return Objects.hash(hasLine); + } + + @Override + public String toString() { + if (hasLine) { + return "-----|"; + } + return " |"; + } +} diff --git a/src/main/java/nextstep/ladder/model/Lines.java b/src/main/java/nextstep/ladder/model/Lines.java new file mode 100644 index 0000000000..99f4896702 --- /dev/null +++ b/src/main/java/nextstep/ladder/model/Lines.java @@ -0,0 +1,38 @@ +package nextstep.ladder.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class Lines { + private final static int FIRST_INDEX = 0; + private final static int PREV_INDEX = 0; + + private final List lines; + + public Lines(final int countOfPlayer) { + List result = new ArrayList<>(); + for (int i = 0; i < countOfPlayer - 1; i++) { + result.add(Line.create(getPrevLine(result, i))); + } + this.lines = result; + } + + private Line getPrevLine(final List result, final int index) { + if (index == 0) { + return null; + } + return result.get(index - PREV_INDEX); + } + + public int size() { + return lines.size(); + } + + @Override + public String toString() { + return lines.stream() + .map(Line::toString) + .collect(Collectors.joining()); + } +} diff --git a/src/main/java/nextstep/ladder/model/Player.java b/src/main/java/nextstep/ladder/model/Player.java new file mode 100644 index 0000000000..11f55798f5 --- /dev/null +++ b/src/main/java/nextstep/ladder/model/Player.java @@ -0,0 +1,22 @@ +package nextstep.ladder.model; + +public class Player { + private final static int MAX_NAME_LENGTH = 5; + private final String name; + + public Player(final String name) { + validate(name); + this.name = name; + } + + private void validate(final String name) { + if (name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException("사용자의 이름은 5자를 넘을 수 없습니다"); + } + } + + @Override + public String toString() { + return String.format("%6s", name); + } +} diff --git a/src/main/java/nextstep/ladder/model/Players.java b/src/main/java/nextstep/ladder/model/Players.java new file mode 100644 index 0000000000..7eb9ca620a --- /dev/null +++ b/src/main/java/nextstep/ladder/model/Players.java @@ -0,0 +1,23 @@ +package nextstep.ladder.model; + +import java.util.List; +import java.util.stream.Collectors; + +public class Players { + private List players; + + public Players(List players) { + this.players = players; + } + + public int number() { + return players.size(); + } + + @Override + public String toString() { + return players.stream() + .map(Player::toString) + .collect(Collectors.joining()); + } +} diff --git a/src/main/java/nextstep/ladder/strategy/LineStrategy.java b/src/main/java/nextstep/ladder/strategy/LineStrategy.java new file mode 100644 index 0000000000..c95ef0d3e3 --- /dev/null +++ b/src/main/java/nextstep/ladder/strategy/LineStrategy.java @@ -0,0 +1,5 @@ +package nextstep.ladder.strategy; + +public interface LineStrategy { + boolean hasLine(); +} diff --git a/src/main/java/nextstep/ladder/strategy/RandomLineStrategy.java b/src/main/java/nextstep/ladder/strategy/RandomLineStrategy.java new file mode 100644 index 0000000000..4b7fa24f44 --- /dev/null +++ b/src/main/java/nextstep/ladder/strategy/RandomLineStrategy.java @@ -0,0 +1,11 @@ +package nextstep.ladder.strategy; + +import java.security.SecureRandom; + +public class RandomLineStrategy implements LineStrategy { + @Override + public boolean hasLine() { + SecureRandom secureRandom = new SecureRandom(); + return secureRandom.nextBoolean(); + } +} diff --git a/src/main/java/nextstep/ladder/view/Input.java b/src/main/java/nextstep/ladder/view/Input.java new file mode 100644 index 0000000000..49401baff3 --- /dev/null +++ b/src/main/java/nextstep/ladder/view/Input.java @@ -0,0 +1,31 @@ +package nextstep.ladder.view; + +import java.util.List; +import java.util.Scanner; + +public class Input { + private final static Scanner SCANNER = new Scanner(System.in); + private final static String SEPARATOR = ","; + + private Input() { + } + + public static String[] inputPlayers() { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + String players = nextLine(); + System.out.println(); + return players.split(SEPARATOR); + } + + public static int inputLadderHeights() { + System.out.println("최대 사다리 높이는 몇 개인가요?"); + String height = nextLine(); + System.out.println(); + return Integer.parseInt(height); + } + + private static String nextLine() { + return SCANNER.nextLine(); + } + +} diff --git a/src/main/java/nextstep/ladder/view/Output.java b/src/main/java/nextstep/ladder/view/Output.java new file mode 100644 index 0000000000..2269932ca4 --- /dev/null +++ b/src/main/java/nextstep/ladder/view/Output.java @@ -0,0 +1,23 @@ +package nextstep.ladder.view; + +import nextstep.ladder.model.Ladder; +import nextstep.ladder.model.Line; +import nextstep.ladder.model.Lines; +import nextstep.ladder.model.Players; + +import java.util.List; + +public class Output { + private Output() { + } + + public static void outputResult(Ladder ladder, Players players) { + System.out.println(players); + List lines = ladder.getLines(); + for (Lines line : lines) { + System.out.print(" |"); + System.out.print(line); + System.out.println(); + } + } +} diff --git a/src/main/java/nextstep/optional/Computer.java b/src/main/java/nextstep/optional/Computer.java index cc0af4d795..12c62e4840 100644 --- a/src/main/java/nextstep/optional/Computer.java +++ b/src/main/java/nextstep/optional/Computer.java @@ -1,39 +1,39 @@ package nextstep.optional; public class Computer { - private Soundcard soundcard; + private Soundcard soundcard; - public Computer(Soundcard soundcard) { - this.soundcard = soundcard; - } + public Computer(Soundcard soundcard) { + this.soundcard = soundcard; + } - public Soundcard getSoundcard() { - return soundcard; - } + public Soundcard getSoundcard() { + return soundcard; + } - public static class Soundcard { - private USB usb; + public static class Soundcard { + private USB usb; - public Soundcard(USB usb) { - super(); - this.usb = usb; - } + public Soundcard(USB usb) { + super(); + this.usb = usb; + } - public USB getUsb() { - return usb; - } - } + public USB getUsb() { + return usb; + } + } - public static class USB { - private String version; + public static class USB { + private String version; - public USB(String version) { - super(); - this.version = version; - } + public USB(String version) { + super(); + this.version = version; + } - public String getVersion() { - return this.version; - } - } + public String getVersion() { + return this.version; + } + } } diff --git a/src/main/java/nextstep/optional/ComputerStore.java b/src/main/java/nextstep/optional/ComputerStore.java index 2695c967ac..280c1b450a 100644 --- a/src/main/java/nextstep/optional/ComputerStore.java +++ b/src/main/java/nextstep/optional/ComputerStore.java @@ -4,23 +4,23 @@ import nextstep.optional.Computer.USB; public class ComputerStore { - public static final String UNKNOWN_VERSION = "UNKNOWN"; + public static final String UNKNOWN_VERSION = "UNKNOWN"; - public static String getVersion(Computer computer) { - String version = UNKNOWN_VERSION; - if (computer != null) { - Soundcard soundcard = computer.getSoundcard(); - if (soundcard != null) { - USB usb = soundcard.getUsb(); - if (usb != null) { - version = usb.getVersion(); - } - } - } - return version; - } + public static String getVersion(Computer computer) { + String version = UNKNOWN_VERSION; + if (computer != null) { + Soundcard soundcard = computer.getSoundcard(); + if (soundcard != null) { + USB usb = soundcard.getUsb(); + if (usb != null) { + version = usb.getVersion(); + } + } + } + return version; + } - public static String getVersionOptional(Computer computer) { - return null; - } + public static String getVersionOptional(Computer computer) { + return null; + } } diff --git a/src/main/java/nextstep/optional/Expression.java b/src/main/java/nextstep/optional/Expression.java index 1bae90a18c..000b37f443 100644 --- a/src/main/java/nextstep/optional/Expression.java +++ b/src/main/java/nextstep/optional/Expression.java @@ -3,22 +3,22 @@ import java.util.Arrays; enum Expression { - PLUS("+"), MINUS("-"), TIMES("*"), DIVIDE("/"); + PLUS("+"), MINUS("-"), TIMES("*"), DIVIDE("/"); - private String expression; + private String expression; - Expression(String expression) { - this.expression = expression; - } + Expression(String expression) { + this.expression = expression; + } - private static boolean matchExpression(Expression e, String expression) { - return expression.equals(e.expression); - } + private static boolean matchExpression(Expression e, String expression) { + return expression.equals(e.expression); + } - static Expression of(String expression) { - return Arrays.stream(values()) - .filter(value -> matchExpression(value, expression)) - .findAny() - .orElseThrow(() -> new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression))); - } + static Expression of(String expression) { + return Arrays.stream(values()) + .filter(value -> matchExpression(value, expression)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression))); + } } diff --git a/src/main/java/nextstep/optional/User.java b/src/main/java/nextstep/optional/User.java index b79a621c9c..6c49b81571 100644 --- a/src/main/java/nextstep/optional/User.java +++ b/src/main/java/nextstep/optional/User.java @@ -3,72 +3,72 @@ import java.util.Optional; public class User { - private String name; - private Integer age; + private String name; + private Integer age; - public User(String name, Integer age) { - this.name = name; - this.age = age; - } + public User(String name, Integer age) { + this.name = name; + this.age = age; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public Integer getAge() { - return age; - } + public Integer getAge() { + return age; + } - public boolean matchName(String name) { - return this.name.equals(name); - } + public boolean matchName(String name) { + return this.name.equals(name); + } - public static boolean ageIsInRange1(User user) { - boolean isInRange = false; + public static boolean ageIsInRange1(User user) { + boolean isInRange = false; - if (user != null && user.getAge() != null - && (user.getAge() >= 30 - && user.getAge() <= 45)) { - isInRange = true; - } - return isInRange; - } + if (user != null && user.getAge() != null + && (user.getAge() >= 30 + && user.getAge() <= 45)) { + isInRange = true; + } + return isInRange; + } - public static boolean ageIsInRange2(User user) { - return Optional.ofNullable(user) - .map(User::getAge) - .filter(age -> age >= 30 && age <= 45) - .isPresent(); - } + public static boolean ageIsInRange2(User user) { + return Optional.ofNullable(user) + .map(User::getAge) + .filter(age -> age >= 30 && age <= 45) + .isPresent(); + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((age == null) ? 0 : age.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((age == null) ? 0 : age.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - User other = (User) obj; - if (age == null) { - if (other.age != null) - return false; - } else if (!age.equals(other.age)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User)obj; + if (age == null) { + if (other.age != null) + return false; + } else if (!age.equals(other.age)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } } diff --git a/src/main/java/nextstep/optional/Users.java b/src/main/java/nextstep/optional/Users.java index 97de23f229..42f6d4b886 100644 --- a/src/main/java/nextstep/optional/Users.java +++ b/src/main/java/nextstep/optional/Users.java @@ -4,18 +4,19 @@ import java.util.List; public class Users { - static final User DEFAULT_USER = new User("codesquad", 100); + static final User DEFAULT_USER = new User("codesquad", 100); - List users = Arrays.asList( - new User("crong", 35), - new User("pobi", 30), - new User("jk", 40), - new User("honux", 45)); + List users = Arrays.asList( + new User("crong", 35), + new User("pobi", 30), + new User("jk", 40), + new User("honux", 45) + ); - User getUser(String name) { - return users.stream() - .filter(user -> user.matchName(name)) - .findAny() - .orElse(DEFAULT_USER); - } + User getUser(String name) { + return users.stream() + .filter(user -> user.matchName(name)) + .findAny() + .orElse(DEFAULT_USER); + } } diff --git a/src/test/java/nextstep/ladder/model/LadderTest.java b/src/test/java/nextstep/ladder/model/LadderTest.java new file mode 100644 index 0000000000..cd0512d339 --- /dev/null +++ b/src/test/java/nextstep/ladder/model/LadderTest.java @@ -0,0 +1,17 @@ +package nextstep.ladder.model; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class LadderTest { + + @Test + void 사용자가_입력한_만큼_사다리의_층을_만든다() { + Ladder ladder = new Ladder(5, 4); + assertThat(ladder.numberOfFloors()).isEqualTo(5); + } + +} diff --git a/src/test/java/nextstep/ladder/model/LineTest.java b/src/test/java/nextstep/ladder/model/LineTest.java new file mode 100644 index 0000000000..0327c09080 --- /dev/null +++ b/src/test/java/nextstep/ladder/model/LineTest.java @@ -0,0 +1,20 @@ +package nextstep.ladder.model; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.ArrayList; +import java.util.List; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import nextstep.ladder.model.Line; + +class LineTest { + + @Test + void 이전_라인이_잇을경우_무조건_해당라인은_없다() { + Assertions.assertThat(Line.create(new Line(true))).isEqualTo(new Line(false)); + } + +} diff --git a/src/test/java/nextstep/ladder/model/LinesTest.java b/src/test/java/nextstep/ladder/model/LinesTest.java new file mode 100644 index 0000000000..a5734990bf --- /dev/null +++ b/src/test/java/nextstep/ladder/model/LinesTest.java @@ -0,0 +1,17 @@ +package nextstep.ladder.model; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class LinesTest { + + @Test + void 라인들은_플레이어의_숫자보다_1작다() { + Lines lines = new Lines(4); + assertThat(lines.size()).isEqualTo(3); + } + +} diff --git a/src/test/java/nextstep/ladder/model/PlayerTest.java b/src/test/java/nextstep/ladder/model/PlayerTest.java new file mode 100644 index 0000000000..335fad89cd --- /dev/null +++ b/src/test/java/nextstep/ladder/model/PlayerTest.java @@ -0,0 +1,17 @@ +package nextstep.ladder.model; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +import nextstep.ladder.model.Player; + +class PlayerTest { + + @Test + void 사용자의_이름은_5자를_넘길수_없다() { + assertThatIllegalArgumentException().isThrownBy(() -> new Player("abcdef")) + .withMessage("사용자의 이름은 5자를 넘을 수 없습니다"); + } + +}