diff --git a/README.md b/README.md index b853592f59..fd202e3341 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,15 @@ * 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다. ## 온라인 코드 리뷰 과정 -* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](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) + +## 기능 목록 (TODO) + +### 2단계 - 사다리(생성) + +- [x] 참여할 사람 이름 입력받기 - 콤마(,)로 구분 +- [x] 최대 사다리 높이 입력받기 +- [x] 참여자 추가 - 이름은 최대 5글자까지 허용 +- [x] 가로선을 무작위로 생성 - 사다리의 가로선이 연속되면 안됨 +- [x] 사다리 생성 - 사다리 최대 높이만큼 무작위 가로선 생성 반복 +- [x] 사다리 출력 - 사람 이름도 함께 출력 diff --git a/src/main/java/nextstep/fp/Lambda.java b/src/main/java/nextstep/fp/Lambda.java index bdc19b54fc..fdc1c3d542 100644 --- a/src/main/java/nextstep/fp/Lambda.java +++ b/src/main/java/nextstep/fp/Lambda.java @@ -39,12 +39,9 @@ public static int sumAllOverThree(List numbers) { } private static int sumAll(List numbers, SumCondition sumCondition) { - int total = 0; - for (int number : numbers) { - if (sumCondition.isSummable(number)) { - total += number; - } - } - return total; + return numbers.stream() + .filter(sumCondition::isSummable) + .mapToInt(Integer::valueOf) + .sum(); } } diff --git a/src/main/java/nextstep/ladder/Main.java b/src/main/java/nextstep/ladder/Main.java new file mode 100644 index 0000000000..65b30e0d07 --- /dev/null +++ b/src/main/java/nextstep/ladder/Main.java @@ -0,0 +1,9 @@ +package nextstep.ladder; + +import nextstep.ladder.controller.LadderController; + +public class Main { + public static void main(String[] args) { + LadderController.startLadderGame(); + } +} diff --git a/src/main/java/nextstep/ladder/controller/LadderController.java b/src/main/java/nextstep/ladder/controller/LadderController.java new file mode 100644 index 0000000000..1df464be55 --- /dev/null +++ b/src/main/java/nextstep/ladder/controller/LadderController.java @@ -0,0 +1,19 @@ +package nextstep.ladder.controller; + +import nextstep.ladder.domain.Ladder; +import nextstep.ladder.domain.User; +import nextstep.ladder.view.InputView; +import nextstep.ladder.view.ResultView; + +import java.util.List; + +public class LadderController { + public static void startLadderGame() { + List users = InputView.inputUsers(); + int ladderMaxHeight = InputView.inputLadderMaxHeight(); + + Ladder ladder = new Ladder(users.size(), ladderMaxHeight); + + ResultView.printResult(ladder, users); + } +} diff --git a/src/main/java/nextstep/ladder/domain/HorizontalLine.java b/src/main/java/nextstep/ladder/domain/HorizontalLine.java new file mode 100644 index 0000000000..5f2dd4ac30 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/HorizontalLine.java @@ -0,0 +1,48 @@ +package nextstep.ladder.domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class HorizontalLine { + private final List hasLineOrNotList; + + private HorizontalLine(List hasLineOrNotList) { + this.hasLineOrNotList = hasLineOrNotList; + } + + public HorizontalLine(int userCount) { + this(generateLines(userCount)); + } + + private static List generateLines(int userCount) { + Random random = new Random(); + List lines = new ArrayList<>(); + Boolean isPreviousLineExist = null; + int maxBooleanCountForLine = userCount - 1; + + while (lines.size() < maxBooleanCountForLine) { + boolean isLineExist = generateIsLineExist(random, isPreviousLineExist); + lines.add(isLineExist); + isPreviousLineExist = isLineExist; + } + + return lines; + } + + private static boolean generateIsLineExist(Random random, Boolean isPreviousLineExist) { + boolean isLineExist = random.nextBoolean(); + while (isPreviousLineExist != null && isLineExist == isPreviousLineExist) { + isLineExist = random.nextBoolean(); + } + return isLineExist; + } + + public int size() { + return hasLineOrNotList.size(); + } + + public Boolean hasLineOnIndex(int index) { + return hasLineOrNotList.get(index); + } +} diff --git a/src/main/java/nextstep/ladder/domain/Ladder.java b/src/main/java/nextstep/ladder/domain/Ladder.java new file mode 100644 index 0000000000..9ef1588b70 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/Ladder.java @@ -0,0 +1,34 @@ +package nextstep.ladder.domain; + +import java.util.LinkedList; +import java.util.List; + +public class Ladder { + private final List horizontalLines; + + public Ladder(List horizontalLines) { + this.horizontalLines = horizontalLines; + } + + public Ladder(int userCount, int ladderMaxHeight) { + this(generate(userCount, ladderMaxHeight)); + } + + private static List generate(int userCount, int ladderMaxHeight) { + List horizontalLines = new LinkedList<>(); + + for (int i = 0; i < ladderMaxHeight; i++) { + horizontalLines.add(new HorizontalLine(userCount)); + } + + return horizontalLines; + } + + public int size() { + return horizontalLines.size(); + } + + public HorizontalLine getByIndex(int index) { + return horizontalLines.get(index); + } +} diff --git a/src/main/java/nextstep/ladder/domain/User.java b/src/main/java/nextstep/ladder/domain/User.java new file mode 100644 index 0000000000..b94eb46b34 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/User.java @@ -0,0 +1,19 @@ +package nextstep.ladder.domain; + +public class User { + private static final int MAX_NAME_LENGTH = 5; + + private final String name; + + public User(String name) { + if (name == null || name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException("참여자의 이름은 최대 5글자입니다"); + } + + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/nextstep/ladder/view/InputView.java b/src/main/java/nextstep/ladder/view/InputView.java new file mode 100644 index 0000000000..ba483db12f --- /dev/null +++ b/src/main/java/nextstep/ladder/view/InputView.java @@ -0,0 +1,43 @@ +package nextstep.ladder.view; + +import nextstep.ladder.domain.User; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class InputView { + private static final String DELIMITER = ","; + + public static List inputUsers() { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + String userNames = getInputString(); + return parseUsers(userNames); + } + + public static int inputLadderMaxHeight() { + System.out.println("최대 사다리 높이는 몇 개인가요?"); + return getInputInteger(); + } + + private static List parseUsers(String userNames) { + return Arrays.stream(userNames.split(DELIMITER)) + .map(User::new) + .collect(Collectors.toList()); + } + + private static int getInputInteger() { + try { + Scanner scanner = new Scanner(System.in); + return scanner.nextInt(); + } catch (Exception e) { + return 0; + } + } + + private static String getInputString() { + 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 new file mode 100644 index 0000000000..c9bc69ede5 --- /dev/null +++ b/src/main/java/nextstep/ladder/view/ResultView.java @@ -0,0 +1,41 @@ +package nextstep.ladder.view; + +import nextstep.ladder.domain.HorizontalLine; +import nextstep.ladder.domain.Ladder; +import nextstep.ladder.domain.User; + +import java.util.List; + +public class ResultView { + public static void printResult(Ladder ladder, List users) { + System.out.println("실행결과"); + users.forEach(user -> System.out.printf("%-6s", user.getName())); + System.out.println(); + printLadder(ladder); + } + + private static void printLadder(Ladder ladder) { + for (int index = 0; index < ladder.size(); index++) { + System.out.print("|"); + HorizontalLine horizontalLine = ladder.getByIndex(index); + printHorizontalLine(horizontalLine); + System.out.println(); + } + } + + private static void printHorizontalLine(HorizontalLine horizontalLine) { + for (int i = 0; i < horizontalLine.size(); i++) { + Boolean hasLineOnIndex = horizontalLine.hasLineOnIndex(i); + printHorizontalLineOrBlank(hasLineOnIndex); + System.out.print("|"); + } + } + + private static void printHorizontalLineOrBlank(boolean hasLine) { + if (hasLine) { + System.out.print("-----"); + return; + } + System.out.print(" "); + } +} diff --git a/src/main/java/nextstep/optional/ComputerStore.java b/src/main/java/nextstep/optional/ComputerStore.java index d1bb260a69..badd553232 100644 --- a/src/main/java/nextstep/optional/ComputerStore.java +++ b/src/main/java/nextstep/optional/ComputerStore.java @@ -23,8 +23,8 @@ public static String getVersion(Computer computer) { } public static String getVersionOptional(Computer computer) { - Optional computerOptional = Optional.ofNullable(computer); - return computerOptional.map(Computer::getSoundcard) + return Optional.ofNullable(computer) + .map(Computer::getSoundcard) .map(Soundcard::getUsb) .map(USB::getVersion) .orElse(UNKNOWN_VERSION); diff --git a/src/main/java/nextstep/optional/Users.java b/src/main/java/nextstep/optional/Users.java index eed1cc0a01..63815d1c28 100644 --- a/src/main/java/nextstep/optional/Users.java +++ b/src/main/java/nextstep/optional/Users.java @@ -14,7 +14,7 @@ public class Users { User getUser(String name) { return users.stream() - .filter(u -> u.matchName(name)) + .filter(user -> user.matchName(name)) .findFirst() .orElse(DEFAULT_USER); } diff --git a/src/test/java/nextstep/ladder/domain/HorizontalLineTest.java b/src/test/java/nextstep/ladder/domain/HorizontalLineTest.java new file mode 100644 index 0000000000..41b514585c --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/HorizontalLineTest.java @@ -0,0 +1,22 @@ +package nextstep.ladder.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class HorizontalLineTest { + @Test + void 생성된_가로선은_연속되지_않아야_한다() { + // given + int userCount = 4; + + // when + HorizontalLine horizontalLine = new HorizontalLine(userCount); + + // then + for (int i = 0; i < horizontalLine.size() - 1; i++) { + boolean currentGeneratedLine = horizontalLine.hasLineOnIndex(i); + boolean nextGeneratedLine = horizontalLine.hasLineOnIndex(i + 1); + Assertions.assertThat(currentGeneratedLine).isNotEqualTo(nextGeneratedLine); + } + } +} diff --git a/src/test/java/nextstep/ladder/domain/LadderTest.java b/src/test/java/nextstep/ladder/domain/LadderTest.java new file mode 100644 index 0000000000..30c206b8af --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/LadderTest.java @@ -0,0 +1,19 @@ +package nextstep.ladder.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class LadderTest { + + @Test + void 사다리_생성() { + int userCount = 4; + int ladderMaxHeight = 5; + + // when + Ladder ladder = new Ladder(userCount, ladderMaxHeight); + + // then + Assertions.assertThat(ladder.size()).isEqualTo(ladderMaxHeight); + } +} diff --git a/src/test/java/nextstep/ladder/domain/UserTest.java b/src/test/java/nextstep/ladder/domain/UserTest.java new file mode 100644 index 0000000000..7f128c12de --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/UserTest.java @@ -0,0 +1,16 @@ +package nextstep.ladder.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UserTest { + @Test + void 참여자의_이름은_최대_5글자() { + String name = "michael"; + + Assertions.assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new User(name)) + .withMessage("참여자의 이름은 최대 5글자입니다"); + + } +}