diff --git a/README.md b/README.md index b853592f59..6ec19ab3d2 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,25 @@ * 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다. ## 온라인 코드 리뷰 과정 -* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](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) + +## 클래스 구조 및 테스트 케이스 작성 +* Persons + * 문자열을 잘 나눴는지 + * 꽝, 당첨 내역 확인 +* Person + * 플레이어 이름이 5글자 넘을때 예외처리 +* Line + * 라인이 겹치는 경우 + * 라인이 안겹치는 경우 +* Ladder + * 사다리 한줄 생성 + * InputView + * ResultView + * ConsoleMain + * 최종결과 확인해서 라인별로 반복한 값을 리턴시킴 + + #190810 리팩토링 + - [ ] Persons의 객체에 results값 없애기 + - [X] Persons의 객체에 results는 List으로 만들어 주기 + - [ ] 최종결과엔 Person 객체와 결과 객체를 매핑해주기 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 1b85b74cb3..c696411505 100644 --- a/build.gradle +++ b/build.gradle @@ -11,4 +11,6 @@ repositories { dependencies { testCompile('org.junit.jupiter:junit-jupiter:5.4.2') testCompile('org.assertj:assertj-core:3.11.1') + testCompile('junit:junit:4.12') + compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 290541c738..971c14247f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Fri Jul 05 20:59:43 KST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip diff --git a/src/main/java/nextstep/main/ConsoleMain.java b/src/main/java/nextstep/main/ConsoleMain.java new file mode 100644 index 0000000000..f272442b04 --- /dev/null +++ b/src/main/java/nextstep/main/ConsoleMain.java @@ -0,0 +1,39 @@ +package nextstep.main; + +import nextstep.main.utils.CommonUtils; +import nextstep.main.view.InputView; +import nextstep.main.view.ResultView; +import nextstep.main.vo.Ladder; +import nextstep.main.vo.LadderGameMapper; +import nextstep.main.vo.Persons; + +import java.util.List; + +import static nextstep.main.utils.Consts.ALL_PERSON; + +public class ConsoleMain { + public static void main(String[] args) { + String playersName = InputView.playerNames(); + String playerResults = InputView.ladderResultPreDiction(); + + int ladderHeight = InputView.maxLadderHeight(); + + Persons persons = Persons.generate(playersName); + List results = CommonUtils.generates(playerResults); + + Ladder ladder = new Ladder(); + ladder.generateLadder(ladderHeight, persons.getPersonCount()); + + ResultView.executeNames(persons); + ResultView.drawLadder(ladder); + ResultView.executeResults(results); + + LadderGameMapper ladderGameMapper = persons.settingResult(ladder, results); + String personName = ""; + while (!ALL_PERSON.equals(personName)) { + personName = InputView.personResult(); + String result = ladderGameMapper.getResult(personName, persons); + ResultView.textResultPerson(result); + } + } +} diff --git a/src/main/java/nextstep/main/utils/CommonUtils.java b/src/main/java/nextstep/main/utils/CommonUtils.java new file mode 100644 index 0000000000..4b158fa8f6 --- /dev/null +++ b/src/main/java/nextstep/main/utils/CommonUtils.java @@ -0,0 +1,25 @@ +package nextstep.main.utils; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class CommonUtils {//push test + public static String[] split(String value) { + return value.split(Consts.NAME_SEPARATOR); + } + + public static List generates(String names) { + return Arrays.stream(split(names)) + .map(String::new) + .collect(Collectors.toList()); + } + + public static String arrangeName(String value) { + String str = IntStream.range(0, Consts.MAX_NAME_COUNT - value.length()) + .mapToObj(i -> " ") + .collect(Collectors.joining("", value, " ")); + return str; + } +} diff --git a/src/main/java/nextstep/main/utils/Consts.java b/src/main/java/nextstep/main/utils/Consts.java new file mode 100644 index 0000000000..01edf3dbb5 --- /dev/null +++ b/src/main/java/nextstep/main/utils/Consts.java @@ -0,0 +1,7 @@ +package nextstep.main.utils; + +public class Consts { + public static final String NAME_SEPARATOR = ","; + public static final String ALL_PERSON = "getResult"; + public static final int MAX_NAME_COUNT = 5; +} diff --git a/src/main/java/nextstep/main/view/InputView.java b/src/main/java/nextstep/main/view/InputView.java new file mode 100644 index 0000000000..736c3ca196 --- /dev/null +++ b/src/main/java/nextstep/main/view/InputView.java @@ -0,0 +1,29 @@ +package nextstep.main.view; + +import java.util.Scanner; + +public class InputView { + public static String playerNames() { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + Scanner scanner = new Scanner(System.in); + return scanner.nextLine(); + } + + public static String ladderResultPreDiction() { + System.out.println("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); + Scanner scanner = new Scanner(System.in); + return scanner.nextLine(); + } + + public static int maxLadderHeight() { + System.out.println("최대 사다리 높이는 몇 개인가요?"); + Scanner scanner = new Scanner(System.in); + return scanner.nextInt(); + } + + public static String personResult() { + System.out.println("결과를 보고 싶은 사람은?"); + Scanner scanner = new Scanner(System.in); + return scanner.nextLine(); + } +} diff --git a/src/main/java/nextstep/main/view/ResultView.java b/src/main/java/nextstep/main/view/ResultView.java new file mode 100644 index 0000000000..7068ce4f11 --- /dev/null +++ b/src/main/java/nextstep/main/view/ResultView.java @@ -0,0 +1,33 @@ +package nextstep.main.view; + +import nextstep.main.utils.CommonUtils; +import nextstep.main.vo.Ladder; +import nextstep.main.vo.Persons; + +import java.util.List; + +public class ResultView { + public static void executeNames(Persons persons) { + System.out.println("사다리 결과"); + + persons.getPersons() + .forEach(System.out::print); + + System.out.println(); + } + + public static void drawLadder(Ladder ladder) { + ladder.getLines() + .forEach(System.out::println); + } + + public static void executeResults(List results) { + results.forEach(name -> System.out.print(CommonUtils.arrangeName(name))); + System.out.println(); + } + + public static void textResultPerson(String result) { + System.out.println("실행 결과"); + System.out.println(result); + } +} diff --git a/src/main/java/nextstep/main/vo/Ladder.java b/src/main/java/nextstep/main/vo/Ladder.java new file mode 100644 index 0000000000..dcf3754b09 --- /dev/null +++ b/src/main/java/nextstep/main/vo/Ladder.java @@ -0,0 +1,35 @@ +package nextstep.main.vo; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +public class Ladder { + private List lines; + + public Ladder() { + this.lines = new ArrayList<>(); + } + + public int generateLadder(int ladderHeight, int playerCount) { + IntStream.range(0, ladderHeight) + .mapToObj(item -> new Line(playerCount)) + .forEach(line -> this.lines.add(line)); + + return this.lines.size(); + } + + public List getLines() { + return this.lines; + } + + public int getResult(int position) { + int currentPosition = position; + + for (int i = 0; i < lines.size(); i++) { + currentPosition = lines.get(i).getPlusMinusPosition(currentPosition); + } + + return currentPosition; + } +} diff --git a/src/main/java/nextstep/main/vo/LadderGameMapper.java b/src/main/java/nextstep/main/vo/LadderGameMapper.java new file mode 100644 index 0000000000..e32eefbac6 --- /dev/null +++ b/src/main/java/nextstep/main/vo/LadderGameMapper.java @@ -0,0 +1,36 @@ +package nextstep.main.vo; + +import java.util.List; +import java.util.Optional; + +import static nextstep.main.utils.Consts.ALL_PERSON; + +public class LadderGameMapper { + private List results; + + public LadderGameMapper(List results) { + this.results = results; + } + + public static LadderGameMapper generate(List userResults) { + return new LadderGameMapper(userResults); + } + + public String findResult(int index) { + return Optional.ofNullable(results.get(index)) + .orElse("참여자 이름이 잘못됐습니다."); + } + + public String getResult(String personName, Persons persons) { + if (ALL_PERSON.equals(personName)) { + List person = persons.getPersons(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < person.size(); i++) { + sb.append(person.get(i).toString().trim() + " : " + results.get(i)); + sb.append("\n"); + } + return sb.toString(); + } + return findResult(persons.findIndexByName(personName)); + } +} diff --git a/src/main/java/nextstep/main/vo/Line.java b/src/main/java/nextstep/main/vo/Line.java new file mode 100644 index 0000000000..e37c35d642 --- /dev/null +++ b/src/main/java/nextstep/main/vo/Line.java @@ -0,0 +1,94 @@ +package nextstep.main.vo; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.stream.IntStream; + +public class Line { + private static final int START_POINT = 0; + public static final String VERTICAL = "|"; + public static final int HORIZONTAL_SIZE = 5; + public static final String DASH = "-"; + public static final String EMPTY = " "; + + private List points; + + Line(int countOfPerson) { + generateLine(countOfPerson); + } + + private int generateLine(int countOfPerson) { + points = new ArrayList<>(); + + IntStream.range(0, numberOfPoints(countOfPerson)) + .forEach(i -> points.add(generateCurrentPoint(i))); + + return points.size(); + } + + private static int numberOfPoints(int countOfPerson) { + return countOfPerson - 1; + } + + private boolean generateCurrentPoint(int newPosition) { + boolean point = new Random().nextBoolean(); + + if (isOverLapped(newPosition, point)) { + point = !point; + } + + return point; + } + + private boolean isOverLapped(int currPosition, boolean newPoint) { + if (currPosition == START_POINT) + return false; + + return isEqual(points.get(currPosition - 1), newPoint); + } + + static boolean isEqual(boolean prevPoint, boolean newPoint) { + return prevPoint == newPoint; + } + + @Override + public String toString() { + final StringBuilder str = new StringBuilder(" |"); + + points.forEach(isLine -> str.append(pointToString(isLine))); + + return str.toString(); + } + + private String pointToString(boolean isLine) { + if (isLine) { + return StringUtils.leftPad(VERTICAL, HORIZONTAL_SIZE, DASH); + } + + return StringUtils.leftPad(VERTICAL, HORIZONTAL_SIZE, EMPTY); + } + + public int getPlusMinusPosition(int currentPosition) { + if (currentPosition == 0) { + return points.get(0) ? currentPosition + 1 : currentPosition; + } + + if (currentPosition == points.size()) { + return points.get(currentPosition - 1) ? currentPosition - 1 : currentPosition; + } + + if (points.get(currentPosition)) { + return currentPosition + 1; + } + + + if (points.get(currentPosition - 1)) { + return currentPosition - 1; + } + + return currentPosition; + } +} diff --git a/src/main/java/nextstep/main/vo/Person.java b/src/main/java/nextstep/main/vo/Person.java new file mode 100644 index 0000000000..d547c07594 --- /dev/null +++ b/src/main/java/nextstep/main/vo/Person.java @@ -0,0 +1,24 @@ +package nextstep.main.vo; + +import nextstep.main.utils.CommonUtils; +import nextstep.main.utils.Consts; + +public class Person { + private String name; + + public Person(String name) { + if (name.length() > Consts.MAX_NAME_COUNT) + throw new IllegalArgumentException(); + + this.name = name; + } + + @Override + public String toString() { + return CommonUtils.arrangeName(this.name); + } + + public boolean isMatch(String personName) { + return name.equals(personName); + } +} diff --git a/src/main/java/nextstep/main/vo/Persons.java b/src/main/java/nextstep/main/vo/Persons.java new file mode 100644 index 0000000000..e6d6c261a4 --- /dev/null +++ b/src/main/java/nextstep/main/vo/Persons.java @@ -0,0 +1,57 @@ +package nextstep.main.vo; + + +import nextstep.main.utils.CommonUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class Persons { + private List persons; + + public Persons(List players) { + this.persons = Collections.unmodifiableList(players); + } + + public static Persons generate(String names) { + List persons = Arrays.stream(CommonUtils.split(names)) + .map(Person::new) + .collect(Collectors.toList()); + return new Persons(persons); + } + + public int getPersonCount() { + return this.persons.size(); + } + + public List getPersons() { + return this.persons; + } + + public LadderGameMapper settingResult(Ladder ladder, List results) { + List userResults = new ArrayList<>(); + + for (int i = 0; i < persons.size(); i++) { + int resultPosition = ladder.getResult(i); + userResults.add(results.get(resultPosition)); + } + + return LadderGameMapper.generate(userResults); + } + + public int findIndexByName(String name) { + int index = 0; + + for (Person person : persons) { + if (person.isMatch(name)) { + return index; + } + index++; + } + + throw new IllegalArgumentException("잘못된 참여자 이름입니다."); + } +} diff --git a/src/test/java/nextstep/main/ConsoleMainTest.java b/src/test/java/nextstep/main/ConsoleMainTest.java new file mode 100644 index 0000000000..30ced65c60 --- /dev/null +++ b/src/test/java/nextstep/main/ConsoleMainTest.java @@ -0,0 +1,7 @@ +package nextstep.main; + +import static org.junit.Assert.*; + +public class ConsoleMainTest { + +} \ No newline at end of file diff --git a/src/test/java/nextstep/main/vo/LadderTest.java b/src/test/java/nextstep/main/vo/LadderTest.java new file mode 100644 index 0000000000..e4f98d71a9 --- /dev/null +++ b/src/test/java/nextstep/main/vo/LadderTest.java @@ -0,0 +1,35 @@ +package nextstep.main.vo; + +import nextstep.main.view.ResultView; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LadderTest { + @Test + public void 사다리_한줄_생성() { + //given + Ladder ladder = new Ladder(); + + //when + int result = ladder.generateLadder(1, 4); + + //then + assertThat(result).isEqualTo(1); + } + + @Test + public void 사다리_결과값알기() { + //given + Ladder ladder = new Ladder(); + + //when + ladder.generateLadder(1, 2); + ResultView.drawLadder(ladder); + + int result = ladder.getResult(0); + + //then + assertThat(result).isEqualTo(0); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/main/vo/LineTest.java b/src/test/java/nextstep/main/vo/LineTest.java new file mode 100644 index 0000000000..625bd6d401 --- /dev/null +++ b/src/test/java/nextstep/main/vo/LineTest.java @@ -0,0 +1,25 @@ +package nextstep.main.vo; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LineTest { + @Test + public void 라인이_겹치는_경우() { + //given, when + boolean result = Line.isEqual(true, true); + + //then + assertThat(result).isEqualTo(true); + } + + @Test + public void 라인이_안겹치는_경우() { + //given, when + boolean result = Line.isEqual(true, false); + + //then + assertThat(result).isEqualTo(false); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/main/vo/PersonTest.java b/src/test/java/nextstep/main/vo/PersonTest.java new file mode 100644 index 0000000000..8f4dea183d --- /dev/null +++ b/src/test/java/nextstep/main/vo/PersonTest.java @@ -0,0 +1,12 @@ +package nextstep.main.vo; + + +import org.junit.Test; + +public class PersonTest { + @Test(expected = IllegalArgumentException.class) + public void 플레이어_이름이_5글자_넘는_경우() { + //given + new Person("moonhye"); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/main/vo/PersonsTest.java b/src/test/java/nextstep/main/vo/PersonsTest.java new file mode 100644 index 0000000000..793bf2a037 --- /dev/null +++ b/src/test/java/nextstep/main/vo/PersonsTest.java @@ -0,0 +1,19 @@ +package nextstep.main.vo; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class PersonsTest { + @Test + public void 문자열을_쉽표로_구분할때_사람_명수() { + //given + String names = "문혜영, 문혜영2"; + + //when + Persons result = Persons.generate(names); + + //then + assertThat(result.getPersonCount()).isEqualTo(2); + } +} \ No newline at end of file