From 9fd3893a6483245cacf73cb8fb93fe97627a7e81 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 15:49:37 +0900 Subject: [PATCH 01/16] =?UTF-8?q?feat:=20=ED=8E=98=EC=96=B4=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EC=8B=9C=EC=9E=91=EC=8B=9C=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EB=B0=8F=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 46 +++++++++++++++++++ src/main/java/pairmatching/Application.java | 6 ++- .../controller/PairMatchingController.java | 44 ++++++++++++++++++ .../pairmatching/message/ErrorMessage.java | 11 +++++ .../pairmatching/util/InputValidator.java | 24 ++++++++++ .../java/pairmatching/view/InputView.java | 15 ++++++ .../java/pairmatching/view/OutputView.java | 8 ++++ 7 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 src/main/java/pairmatching/controller/PairMatchingController.java create mode 100644 src/main/java/pairmatching/message/ErrorMessage.java create mode 100644 src/main/java/pairmatching/util/InputValidator.java create mode 100644 src/main/java/pairmatching/view/InputView.java create mode 100644 src/main/java/pairmatching/view/OutputView.java diff --git a/docs/README.md b/docs/README.md index e69de29..530340a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,46 @@ +## 페어매칭 관리 애플리케이션 + +## 기능 목록 정의서 + +## 페어 매칭 프로그램 시작시 +- **기능 목록** + - [x] 기능을 선택할 수 있는 화면을 보여준다. + - [x] 사용자는 선택할 기능을 입력한다. + +- **예외 목록** + - [x] 1, 2, 3, Q가 아닌 입력은 예외 처리한다. + +## 1. 페어 매칭 선택시 +- **페어 매칭 기능 목록** + - [ ] 현재 과정, 미션(레벨별로)에 대한 안내를 화면에 출력한다. + - [ ] 사용자에게 과정, 레벨, 미션에대한 입력을 순서대로 `입력받는다.` + - [ ] 선택 과정에 대한 md 파일을 읽어 사용자 리스트를 만들어 셔플하여 페어 매칭 결과를 만든다. + - [ ] 페어 매칭 결과는 저장을하고, 중복된 페어매칭 검증시에 사용된다. + - [ ] 같은 레벨 다른 미션에서 이미 페어로 만났다면 재매칭 한다. + - [ ] 페어 매칭이 완료되면 페어 매칭 결과를 출력한다. +- **페어 재매칭 기능 목록** + - [ ] 이미 `과정, 레벨`에 대해 만들어진 페어가 있다면 재 매칭 여부를 `입력한다.` + - [ ] `재 페어매칭시` 각 사람들은 는 이전에 만났던 페어를 만나면 안된다. + - [ ] 이전에 만났던 페어를 만나면 최대 3회 재시도를 한다. + - [ ] 재페어 매칭이 완료되면 페어 매칭 결과를 출력한다. + +- **예외 목록** + - [ ] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. + - [ ] 각 과정, 레벨, 미션은 모두 존재하야 한다. + - [ ] 만약 미션이 없는 레벨이라면 예외 처리한다. + - [ ] 재매칭 여부 입력시 네, 아니오가 아닌 입력은 예외 처리한다. + +## 2. 페어 조회 선택시 +- **조회 기능 목록** + - [ ] 과정, 레벨, 미션에 대한 입력을 순서대로 `입력받는다.` + - [ ] 해당 입력에 대한 페어 매칭 결과를 출력한다. +- **예외 목록** + - [ ] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. + - [ ] 각 과정, 레벨, 미션은 모두 존재하야 한다. + - [ ] 만약 미션이 없는 레벨이라면 예외 처리한다. + - [ ] 조회할 매칭 결과가 없다면 예외 처리한다. + +## 3. 페어 초기화 선택시 +- **초기화 기능 목록** + - [ ] 모든 레벨의 모든 페어 매칭 기록을 초기화 한다 + - [ ] 중복된 페어 매칭 검증을 위한 것도 초기화 한다. \ No newline at end of file diff --git a/src/main/java/pairmatching/Application.java b/src/main/java/pairmatching/Application.java index c619a21..65dc566 100644 --- a/src/main/java/pairmatching/Application.java +++ b/src/main/java/pairmatching/Application.java @@ -1,8 +1,10 @@ package pairmatching; +import pairmatching.controller.PairMatchingController; + public class Application { public static void main(String[] args) { - // TODO 구현 진행 - + PairMatchingController pairMatchingController = new PairMatchingController(); + pairMatchingController.run(); } } diff --git a/src/main/java/pairmatching/controller/PairMatchingController.java b/src/main/java/pairmatching/controller/PairMatchingController.java new file mode 100644 index 0000000..08d66a2 --- /dev/null +++ b/src/main/java/pairmatching/controller/PairMatchingController.java @@ -0,0 +1,44 @@ +package pairmatching.controller; + +import pairmatching.util.InputValidator; +import pairmatching.view.InputView; +import pairmatching.view.OutputView; + +public class PairMatchingController { + private final InputView inputView = new InputView(); + private final OutputView outputView = new OutputView(); + + public void run() { + try { + determineMenuSelect(InputValidator.validateSelectMenu(inputView.inputSelectMenu())); + } catch (IllegalArgumentException exception) { + outputView.printMessage(exception.getMessage()); + run(); + } + } + + private void determineMenuSelect(final String validatedSelectMenu) { + if (validatedSelectMenu.equals(InputValidator.PAIR_MATCHING)) { + requestPairMatching(); + } + if (validatedSelectMenu.equals(InputValidator.PAIR_VIEW)) { + requestPairView(); + } + if (validatedSelectMenu.equals(InputValidator.PAIR_RESET)) { + requestPairReset(); + } + } + + private void requestPairMatching() { + System.out.println("pass"); + } + + private void requestPairReset() { + System.out.println("pass"); + } + + private void requestPairView() { + System.out.println("pass"); + } + +} diff --git a/src/main/java/pairmatching/message/ErrorMessage.java b/src/main/java/pairmatching/message/ErrorMessage.java new file mode 100644 index 0000000..80aa01f --- /dev/null +++ b/src/main/java/pairmatching/message/ErrorMessage.java @@ -0,0 +1,11 @@ +package pairmatching.message; + + +public class ErrorMessage { + + + public static final String MENU_SELECT_ERROR = "[ERROR] '1, 2, 3, Q'만 입력할 수 있습니다."; + + private ErrorMessage() { + } +} diff --git a/src/main/java/pairmatching/util/InputValidator.java b/src/main/java/pairmatching/util/InputValidator.java new file mode 100644 index 0000000..31fb936 --- /dev/null +++ b/src/main/java/pairmatching/util/InputValidator.java @@ -0,0 +1,24 @@ +package pairmatching.util; + +import pairmatching.message.ErrorMessage; + +public class InputValidator { + + public static final String PAIR_MATCHING = "1"; + public static final String PAIR_VIEW = "2"; + public static final String PAIR_RESET = "3"; + public static final String QUIT = "Q"; + + private InputValidator() { + } + + public static String validateSelectMenu(final String userInput) { + if (!userInput.equals(PAIR_MATCHING) + && !userInput.equals(PAIR_VIEW) + && !userInput.equals(PAIR_RESET) + && !userInput.equals(QUIT)) { + throw new IllegalArgumentException(ErrorMessage.MENU_SELECT_ERROR); + } + return userInput; + } +} diff --git a/src/main/java/pairmatching/view/InputView.java b/src/main/java/pairmatching/view/InputView.java new file mode 100644 index 0000000..9f1a962 --- /dev/null +++ b/src/main/java/pairmatching/view/InputView.java @@ -0,0 +1,15 @@ +package pairmatching.view; + +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + + public String inputSelectMenu() { + System.out.println("기능을 선택하세요."); + System.out.println("1. 페어 매칭"); + System.out.println("2. 페어 조회"); + System.out.println("3. 페어 초기화"); + System.out.println("Q. 종료"); + return Console.readLine(); + } +} diff --git a/src/main/java/pairmatching/view/OutputView.java b/src/main/java/pairmatching/view/OutputView.java new file mode 100644 index 0000000..c640c43 --- /dev/null +++ b/src/main/java/pairmatching/view/OutputView.java @@ -0,0 +1,8 @@ +package pairmatching.view; + +public class OutputView { + public void printMessage(final String message) { + System.out.println(message); + System.out.println(); + } +} From 21e5439a6247d9f8edb66682b18ea9455adace0f Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 19:01:08 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=EA=B3=BC=EC=A0=95,=20=EB=A0=88?= =?UTF-8?q?=EB=B2=A8,=20=EB=AF=B8=EC=85=98=EC=9D=84=20=EC=A0=95=EC=9D=98?= =?UTF-8?q?=ED=95=9C=20enum=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pairmatching/domain/enums/Course.java | 14 ++++++++++ .../java/pairmatching/domain/enums/Level.java | 28 +++++++++++++++++++ .../pairmatching/domain/enums/Mission.java | 18 ++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 src/main/java/pairmatching/domain/enums/Course.java create mode 100644 src/main/java/pairmatching/domain/enums/Level.java create mode 100644 src/main/java/pairmatching/domain/enums/Mission.java diff --git a/src/main/java/pairmatching/domain/enums/Course.java b/src/main/java/pairmatching/domain/enums/Course.java new file mode 100644 index 0000000..cdb4c09 --- /dev/null +++ b/src/main/java/pairmatching/domain/enums/Course.java @@ -0,0 +1,14 @@ +package pairmatching.domain.enums; + +public enum Course { + BACKEND("백엔드"), + FRONTEND("프론트엔드"); + + private String name; + + Course(String name) { + this.name = name; + } + + // 추가 기능 구현 +} diff --git a/src/main/java/pairmatching/domain/enums/Level.java b/src/main/java/pairmatching/domain/enums/Level.java new file mode 100644 index 0000000..8f1a91a --- /dev/null +++ b/src/main/java/pairmatching/domain/enums/Level.java @@ -0,0 +1,28 @@ +package pairmatching.domain.enums; + +import java.util.Collections; +import java.util.List; + +/** + * 자동차경주 | 로또 | 숫자야구게임 + * - 레벨2: 장바구니 | 결제 | 지하철노선도 + * - 레벨3: + * - 레벨4: 성능개선 | 배포 + */ +public enum Level { + LEVEL1("레벨1", List.of(Mission.CAR_RACING, Mission.LOTTO, Mission.BASEBALL)), + LEVEL2("레벨2", List.of(Mission.BASKET, Mission.PAYMENT, Mission.SUBWAY_PATH)), + LEVEL3("레벨3", Collections.emptyList()), + LEVEL4("레벨4", List.of(Mission.PERFORMANCE, Mission.DISTRIBUTION)), + LEVEL5("레벨5", Collections.emptyList()); + + private String name; + private List missions; + + Level(final String name, final List missions) { + this.name = name; + this.missions = missions; + } + +// 추가 기능 구현 +} diff --git a/src/main/java/pairmatching/domain/enums/Mission.java b/src/main/java/pairmatching/domain/enums/Mission.java new file mode 100644 index 0000000..b155bb5 --- /dev/null +++ b/src/main/java/pairmatching/domain/enums/Mission.java @@ -0,0 +1,18 @@ +package pairmatching.domain.enums; + +public enum Mission { + CAR_RACING("자동차경주"), + LOTTO("로또"), + BASEBALL("숫자야구게임"), + BASKET("장바구니"), + PAYMENT("결제"), + SUBWAY_PATH("지하철노선도"), + PERFORMANCE("성능개선"), + DISTRIBUTION("배포"); + + private String name; + + Mission(final String name) { + this.name = name; + } +} From 5ef8f4f5f101ebb53bd6cc6b8c9101d493343231 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 19:29:50 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20=ED=81=AC=EB=A3=A8=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EB=A5=BC=20=EB=8B=B4=EB=8A=94=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pairmatching/domain/Crew.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/pairmatching/domain/Crew.java diff --git a/src/main/java/pairmatching/domain/Crew.java b/src/main/java/pairmatching/domain/Crew.java new file mode 100644 index 0000000..a1088b4 --- /dev/null +++ b/src/main/java/pairmatching/domain/Crew.java @@ -0,0 +1,13 @@ +package pairmatching.domain; + +import pairmatching.domain.enums.Course; + +public class Crew { + private final Course course; + private final String name; + + public Crew(final Course course, final String name) { + this.course = course; + this.name = name; + } +} From bbcdf5712f4e3ade889da40b0ba7332001407326 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 19:31:01 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=97=90=EA=B2=8C=20=EA=B3=BC=EC=A0=95,=20=EB=A0=88=EB=B2=A8,?= =?UTF-8?q?=20=EB=AF=B8=EC=85=98=EC=9D=84=20=EC=9E=85=EB=A0=A5=EB=B0=9B?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 8 +++---- .../controller/PairMatchingController.java | 2 +- .../pairmatching/domain/enums/Course.java | 1 - .../pairmatching/message/ErrorMessage.java | 1 + .../pairmatching/util/InputValidator.java | 14 ++++++++++++- .../java/pairmatching/view/InputView.java | 21 +++++++++++++++++++ 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/docs/README.md b/docs/README.md index 530340a..80afff5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,8 +12,8 @@ ## 1. 페어 매칭 선택시 - **페어 매칭 기능 목록** - - [ ] 현재 과정, 미션(레벨별로)에 대한 안내를 화면에 출력한다. - - [ ] 사용자에게 과정, 레벨, 미션에대한 입력을 순서대로 `입력받는다.` + - [X] 현재 과정, 미션(레벨별로)에 대한 안내를 화면에 출력한다. + - [x] 사용자에게 과정, 레벨, 미션에대한 입력을 순서대로 `입력받는다.` - [ ] 선택 과정에 대한 md 파일을 읽어 사용자 리스트를 만들어 셔플하여 페어 매칭 결과를 만든다. - [ ] 페어 매칭 결과는 저장을하고, 중복된 페어매칭 검증시에 사용된다. - [ ] 같은 레벨 다른 미션에서 이미 페어로 만났다면 재매칭 한다. @@ -25,8 +25,8 @@ - [ ] 재페어 매칭이 완료되면 페어 매칭 결과를 출력한다. - **예외 목록** - - [ ] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. - - [ ] 각 과정, 레벨, 미션은 모두 존재하야 한다. + - [x] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. + - [ ] 각 과정, 레벨, 미션이 존재하지 않으면 예외 처리한다. - [ ] 만약 미션이 없는 레벨이라면 예외 처리한다. - [ ] 재매칭 여부 입력시 네, 아니오가 아닌 입력은 예외 처리한다. diff --git a/src/main/java/pairmatching/controller/PairMatchingController.java b/src/main/java/pairmatching/controller/PairMatchingController.java index 08d66a2..bb16791 100644 --- a/src/main/java/pairmatching/controller/PairMatchingController.java +++ b/src/main/java/pairmatching/controller/PairMatchingController.java @@ -30,7 +30,7 @@ private void determineMenuSelect(final String validatedSelectMenu) { } private void requestPairMatching() { - System.out.println("pass"); + InputValidator.validateCourseInformation(inputView.inputCourseInformation()); } private void requestPairReset() { diff --git a/src/main/java/pairmatching/domain/enums/Course.java b/src/main/java/pairmatching/domain/enums/Course.java index cdb4c09..5aa7d44 100644 --- a/src/main/java/pairmatching/domain/enums/Course.java +++ b/src/main/java/pairmatching/domain/enums/Course.java @@ -10,5 +10,4 @@ public enum Course { this.name = name; } - // 추가 기능 구현 } diff --git a/src/main/java/pairmatching/message/ErrorMessage.java b/src/main/java/pairmatching/message/ErrorMessage.java index 80aa01f..2eb2b5c 100644 --- a/src/main/java/pairmatching/message/ErrorMessage.java +++ b/src/main/java/pairmatching/message/ErrorMessage.java @@ -5,6 +5,7 @@ public class ErrorMessage { public static final String MENU_SELECT_ERROR = "[ERROR] '1, 2, 3, Q'만 입력할 수 있습니다."; + public static final String COURSE_INFORMATION_ERROR = "[ERROR] '백엔드, 레벨1, 자동차경주'과 같이 입력해야 합니다."; private ErrorMessage() { } diff --git a/src/main/java/pairmatching/util/InputValidator.java b/src/main/java/pairmatching/util/InputValidator.java index 31fb936..f681fb0 100644 --- a/src/main/java/pairmatching/util/InputValidator.java +++ b/src/main/java/pairmatching/util/InputValidator.java @@ -1,13 +1,17 @@ package pairmatching.util; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; import pairmatching.message.ErrorMessage; public class InputValidator { - public static final String PAIR_MATCHING = "1"; public static final String PAIR_VIEW = "2"; public static final String PAIR_RESET = "3"; public static final String QUIT = "Q"; + public static final String SEPARATOR = ", "; + public static final int NEED_SIZE_INPUT = 3; private InputValidator() { } @@ -21,4 +25,12 @@ public static String validateSelectMenu(final String userInput) { } return userInput; } + + public static List validateCourseInformation(final String userInput) { + if (userInput.split(SEPARATOR).length != NEED_SIZE_INPUT) { + throw new IllegalArgumentException(ErrorMessage.COURSE_INFORMATION_ERROR); + } + return Arrays.stream(userInput.split(SEPARATOR)) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/pairmatching/view/InputView.java b/src/main/java/pairmatching/view/InputView.java index 9f1a962..ba6d7bf 100644 --- a/src/main/java/pairmatching/view/InputView.java +++ b/src/main/java/pairmatching/view/InputView.java @@ -1,6 +1,8 @@ package pairmatching.view; import camp.nextstep.edu.missionutils.Console; +import java.util.Arrays; +import pairmatching.domain.enums.Course; public class InputView { @@ -12,4 +14,23 @@ public String inputSelectMenu() { System.out.println("Q. 종료"); return Console.readLine(); } + + public String inputCourseInformation() { + printInformation(); + System.out.println("과정, 레벨, 미션을 선택하세요."); + System.out.println("ex) 백엔드, 레벨1, 자동차경주"); + return Console.readLine(); + } + + private static void printInformation() { + System.out.println("#############################################"); + System.out.println("과정: 백엔드 | 프론트엔드"); + System.out.println("미션:"); + System.out.println(" -레벨1: 자동차경주 | 로또 | 숫자야구게임"); + System.out.println(" -레벨2: 장바구니 | 결제 | 지하철노선도"); + System.out.println(" -레벨3:"); + System.out.println(" -레벨4: 성능개선 | 배포"); + System.out.println(" -레벨5:"); + System.out.println("#############################################"); + } } From ed1eaced23972cfbd57a2c6d7fced24664c4e382 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 19:58:20 +0900 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20=ED=81=AC=EB=A3=A8=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=ED=8C=8C=EC=9D=BC=EC=97=90=EC=84=9C=20=EB=B6=88?= =?UTF-8?q?=EB=9F=AC=EC=99=80=20=EC=B4=88=EA=B8=B0=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 1 + .../pairmatching/message/ErrorMessage.java | 1 + .../repository/CrewRepository.java | 43 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 src/main/java/pairmatching/repository/CrewRepository.java diff --git a/docs/README.md b/docs/README.md index 80afff5..da3b1e2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,6 +6,7 @@ - **기능 목록** - [x] 기능을 선택할 수 있는 화면을 보여준다. - [x] 사용자는 선택할 기능을 입력한다. + - [X] 초기 사용자의 목록을 md 파일에서 가져와 저장한다. - **예외 목록** - [x] 1, 2, 3, Q가 아닌 입력은 예외 처리한다. diff --git a/src/main/java/pairmatching/message/ErrorMessage.java b/src/main/java/pairmatching/message/ErrorMessage.java index 2eb2b5c..8dd99eb 100644 --- a/src/main/java/pairmatching/message/ErrorMessage.java +++ b/src/main/java/pairmatching/message/ErrorMessage.java @@ -6,6 +6,7 @@ public class ErrorMessage { public static final String MENU_SELECT_ERROR = "[ERROR] '1, 2, 3, Q'만 입력할 수 있습니다."; public static final String COURSE_INFORMATION_ERROR = "[ERROR] '백엔드, 레벨1, 자동차경주'과 같이 입력해야 합니다."; + public static final String FILE_NOT_FOUND_ERROR = "[ERROR] 파일을 찾을 수 없습니다."; private ErrorMessage() { } diff --git a/src/main/java/pairmatching/repository/CrewRepository.java b/src/main/java/pairmatching/repository/CrewRepository.java new file mode 100644 index 0000000..5d7edea --- /dev/null +++ b/src/main/java/pairmatching/repository/CrewRepository.java @@ -0,0 +1,43 @@ +package pairmatching.repository; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import pairmatching.domain.Crew; +import pairmatching.domain.enums.Course; +import pairmatching.message.ErrorMessage; + +public class CrewRepository { + private static final CrewRepository instance = new CrewRepository(); + private static final List store = new ArrayList<>(); + private static final String BACKEND_PATH = "src/main/resources/backend-crew.md"; + private static final String FRONTEND_PATH = "src/main/resources/frontend-crew.md"; + + static { + initializeCrew(BACKEND_PATH, Course.BACKEND); + initializeCrew(FRONTEND_PATH, Course.FRONTEND); + } + + private CrewRepository() { + } + + public static CrewRepository getInstance() { + return instance; + } + + private static void initializeCrew(String path, Course course) { + try { + BufferedReader reader = new BufferedReader(new FileReader(path)); + store.addAll(reader.lines() + .collect(Collectors.toList()) + .stream() + .map(name -> new Crew(course, name)) + .collect(Collectors.toList())); + } catch (FileNotFoundException e) { + throw new IllegalArgumentException(ErrorMessage.FILE_NOT_FOUND_ERROR); + } + } +} From d29a3b8d93928a28fcba5cb42da49d2dd9019cce Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 20:57:55 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=ED=96=88=EB=8D=98=20=EC=A0=81=EC=9D=B4=20=EC=9E=88?= =?UTF-8?q?=EB=8D=98=20=EC=BD=94=EC=8A=A4,=20=EB=A0=88=EB=B2=A8,=20?= =?UTF-8?q?=EB=AF=B8=EC=85=98=EC=97=90=20=EB=8C=80=ED=95=9C=20=EB=B6=84?= =?UTF-8?q?=EA=B8=B0=20=EC=B2=98=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PairMatchingController.java | 18 +++++++++++++++++- .../exception/PairAlreadyExistException.java | 7 +++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/main/java/pairmatching/exception/PairAlreadyExistException.java diff --git a/src/main/java/pairmatching/controller/PairMatchingController.java b/src/main/java/pairmatching/controller/PairMatchingController.java index bb16791..aa3d79e 100644 --- a/src/main/java/pairmatching/controller/PairMatchingController.java +++ b/src/main/java/pairmatching/controller/PairMatchingController.java @@ -1,5 +1,8 @@ package pairmatching.controller; +import java.util.List; +import pairmatching.exception.PairAlreadyExistException; +import pairmatching.service.PairMatchingService; import pairmatching.util.InputValidator; import pairmatching.view.InputView; import pairmatching.view.OutputView; @@ -7,6 +10,7 @@ public class PairMatchingController { private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); + private final PairMatchingService pairMatchingService = new PairMatchingService(); public void run() { try { @@ -30,7 +34,19 @@ private void determineMenuSelect(final String validatedSelectMenu) { } private void requestPairMatching() { - InputValidator.validateCourseInformation(inputView.inputCourseInformation()); + List courseInformation = InputValidator.validateCourseInformation(inputView.inputCourseInformation()); + try { + pairMatchingService.pairMatch(courseInformation); + } catch (PairAlreadyExistException exception) { + requestRetry(courseInformation); + } catch (IllegalArgumentException exception) { + outputView.printMessage(exception.getMessage()); + requestPairMatching(); + } + } + + private void requestRetry(final List courseInformation) { + pairMatchingService.retryPairMatching(courseInformation); } private void requestPairReset() { diff --git a/src/main/java/pairmatching/exception/PairAlreadyExistException.java b/src/main/java/pairmatching/exception/PairAlreadyExistException.java new file mode 100644 index 0000000..a332d36 --- /dev/null +++ b/src/main/java/pairmatching/exception/PairAlreadyExistException.java @@ -0,0 +1,7 @@ +package pairmatching.exception; + +public class PairAlreadyExistException extends RuntimeException { + public PairAlreadyExistException() { + super(); + } +} From 62093c94c3f5f1b2d818957bcd2a851068c71a26 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 20:58:40 +0900 Subject: [PATCH 07/16] =?UTF-8?q?feat:=20=EC=97=86=EB=8A=94=20=EC=BD=94?= =?UTF-8?q?=EC=8A=A4,=20=EB=A0=88=EB=B2=A8,=20=EB=AF=B8=EC=85=98=EC=97=90?= =?UTF-8?q?=20=EB=8C=80=ED=95=9C=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/pairmatching/domain/enums/Course.java | 13 +++++++++++++ .../java/pairmatching/domain/enums/Level.java | 17 +++++++++++++++++ .../java/pairmatching/domain/enums/Mission.java | 14 ++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/src/main/java/pairmatching/domain/enums/Course.java b/src/main/java/pairmatching/domain/enums/Course.java index 5aa7d44..f060a3d 100644 --- a/src/main/java/pairmatching/domain/enums/Course.java +++ b/src/main/java/pairmatching/domain/enums/Course.java @@ -1,5 +1,8 @@ package pairmatching.domain.enums; +import java.util.Arrays; +import pairmatching.message.ErrorMessage; + public enum Course { BACKEND("백엔드"), FRONTEND("프론트엔드"); @@ -10,4 +13,14 @@ public enum Course { this.name = name; } + public static Course findCourse(final String inputCourse) { + return Arrays.stream(Course.values()) + .filter(course -> course.containsName(inputCourse)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.NO_COURSE_ERROR)); + } + + private boolean containsName(final String inputCourse) { + return name.equals(inputCourse); + } } diff --git a/src/main/java/pairmatching/domain/enums/Level.java b/src/main/java/pairmatching/domain/enums/Level.java index 8f1a91a..01ed14f 100644 --- a/src/main/java/pairmatching/domain/enums/Level.java +++ b/src/main/java/pairmatching/domain/enums/Level.java @@ -1,7 +1,9 @@ package pairmatching.domain.enums; +import java.util.Arrays; import java.util.Collections; import java.util.List; +import pairmatching.message.ErrorMessage; /** * 자동차경주 | 로또 | 숫자야구게임 @@ -24,5 +26,20 @@ public enum Level { this.missions = missions; } + public static Level findLevel(final String inputLevel) { + return Arrays.stream(Level.values()) + .filter(level -> level.containsLevel(inputLevel)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.NO_LEVEL_ERROR)); + } + + private boolean containsLevel(final String inputLevel) { + return name.equals(inputLevel); + } + + public boolean isExistsMission(final Mission mission) { + return missions.contains(mission); + } + // 추가 기능 구현 } diff --git a/src/main/java/pairmatching/domain/enums/Mission.java b/src/main/java/pairmatching/domain/enums/Mission.java index b155bb5..ae8d76f 100644 --- a/src/main/java/pairmatching/domain/enums/Mission.java +++ b/src/main/java/pairmatching/domain/enums/Mission.java @@ -1,5 +1,8 @@ package pairmatching.domain.enums; +import java.util.Arrays; +import pairmatching.message.ErrorMessage; + public enum Mission { CAR_RACING("자동차경주"), LOTTO("로또"), @@ -15,4 +18,15 @@ public enum Mission { Mission(final String name) { this.name = name; } + + public static Mission findMission(final String inputMission) { + return Arrays.stream(values()) + .filter(mission -> mission.containsMission(inputMission)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.NO_MISSION_ERROR)); + } + + private boolean containsMission(final String inputMission) { + return name.equals(inputMission); + } } From 570a900f18af7b5880e2076b42eef97d7e7a0d15 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 21:31:47 +0900 Subject: [PATCH 08/16] =?UTF-8?q?feat:=20=ED=8E=98=EC=96=B4=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 6 +- .../domain/CourseInformation.java | 60 +++++++++++++++++++ src/main/java/pairmatching/domain/Crew.java | 22 +++++++ src/main/java/pairmatching/domain/Crews.java | 48 +++++++++++++++ src/main/java/pairmatching/domain/Pair.java | 11 ++++ .../pairmatching/domain/PairMatching.java | 11 ++++ .../repository/CrewRepository.java | 7 +++ .../repository/MatchingCrewRepository.java | 28 +++++++++ .../service/PairMatchingService.java | 54 +++++++++++++++++ .../java/pairmatching/util/ShuffleUtil.java | 16 +++++ 10 files changed, 260 insertions(+), 3 deletions(-) create mode 100644 src/main/java/pairmatching/domain/CourseInformation.java create mode 100644 src/main/java/pairmatching/domain/Crews.java create mode 100644 src/main/java/pairmatching/domain/Pair.java create mode 100644 src/main/java/pairmatching/domain/PairMatching.java create mode 100644 src/main/java/pairmatching/repository/MatchingCrewRepository.java create mode 100644 src/main/java/pairmatching/service/PairMatchingService.java create mode 100644 src/main/java/pairmatching/util/ShuffleUtil.java diff --git a/docs/README.md b/docs/README.md index da3b1e2..0e94a0f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,7 +15,7 @@ - **페어 매칭 기능 목록** - [X] 현재 과정, 미션(레벨별로)에 대한 안내를 화면에 출력한다. - [x] 사용자에게 과정, 레벨, 미션에대한 입력을 순서대로 `입력받는다.` - - [ ] 선택 과정에 대한 md 파일을 읽어 사용자 리스트를 만들어 셔플하여 페어 매칭 결과를 만든다. + - [x] 해당 과정에 맞는 크루들을 셔플하여 페어 매칭 결과를 만든다. - [ ] 페어 매칭 결과는 저장을하고, 중복된 페어매칭 검증시에 사용된다. - [ ] 같은 레벨 다른 미션에서 이미 페어로 만났다면 재매칭 한다. - [ ] 페어 매칭이 완료되면 페어 매칭 결과를 출력한다. @@ -27,8 +27,8 @@ - **예외 목록** - [x] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. - - [ ] 각 과정, 레벨, 미션이 존재하지 않으면 예외 처리한다. - - [ ] 만약 미션이 없는 레벨이라면 예외 처리한다. + - [X] 각 과정, 레벨, 미션이 존재하지 않으면 예외 처리한다. + - [X] 만약 미션이 없는 레벨이라면 예외 처리한다. - [ ] 재매칭 여부 입력시 네, 아니오가 아닌 입력은 예외 처리한다. ## 2. 페어 조회 선택시 diff --git a/src/main/java/pairmatching/domain/CourseInformation.java b/src/main/java/pairmatching/domain/CourseInformation.java new file mode 100644 index 0000000..12aecc5 --- /dev/null +++ b/src/main/java/pairmatching/domain/CourseInformation.java @@ -0,0 +1,60 @@ +package pairmatching.domain; + +import java.util.List; +import java.util.Objects; +import pairmatching.domain.enums.Course; +import pairmatching.domain.enums.Level; +import pairmatching.domain.enums.Mission; +import pairmatching.message.ErrorMessage; + +public class CourseInformation { + public static final int COURSE_INDEX = 0; + public static final int LEVEL_INDEX = 1; + public static final int MISSION_INDEX = 2; + private final Course course; + private final Level level; + private final Mission mission; + + private CourseInformation(final Course course, final Level level, final Mission mission) { + this.course = course; + this.level = level; + this.mission = mission; + } + + public static CourseInformation of(final List inputInformation) { + CourseInformation courseInformation = new CourseInformation( + Course.findCourse(inputInformation.get(COURSE_INDEX)), + Level.findLevel(inputInformation.get(LEVEL_INDEX)), + Mission.findMission(inputInformation.get(MISSION_INDEX)) + ); + return validateCourseInformation(courseInformation); + } + + private static CourseInformation validateCourseInformation(final CourseInformation courseInformation) { + if (!courseInformation.level.isExistsMission(courseInformation.mission)) { + throw new IllegalArgumentException(ErrorMessage.NO_MISSION_IN_LEVEL_ERROR); + } + return courseInformation; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CourseInformation that = (CourseInformation) o; + return course == that.course && level == that.level && mission == that.mission; + } + + @Override + public int hashCode() { + return Objects.hash(course, level, mission); + } + + public Course getCourse() { + return course; + } +} diff --git a/src/main/java/pairmatching/domain/Crew.java b/src/main/java/pairmatching/domain/Crew.java index a1088b4..89f2882 100644 --- a/src/main/java/pairmatching/domain/Crew.java +++ b/src/main/java/pairmatching/domain/Crew.java @@ -1,5 +1,6 @@ package pairmatching.domain; +import java.util.Objects; import pairmatching.domain.enums.Course; public class Crew { @@ -10,4 +11,25 @@ public Crew(final Course course, final String name) { this.course = course; this.name = name; } + + public boolean containsCourse(final Course course) { + return this.course == course; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Crew crew = (Crew) o; + return course == crew.course && Objects.equals(name, crew.name); + } + + @Override + public int hashCode() { + return Objects.hash(course, name); + } } diff --git a/src/main/java/pairmatching/domain/Crews.java b/src/main/java/pairmatching/domain/Crews.java new file mode 100644 index 0000000..eb9d288 --- /dev/null +++ b/src/main/java/pairmatching/domain/Crews.java @@ -0,0 +1,48 @@ +package pairmatching.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Crews { + private final List crews; + + public Crews(final List crews) { + this.crews = crews; + } + + public List getCrewList() { + return Collections.unmodifiableList(crews); + } + + public List makePairList() { + if (crews.size() % 2 == 0) { + return createEvenPair(); + } + return createOddPair(); + } + + private List createOddPair() { + List pairs = new ArrayList<>(); + for (int index = 0; index < crews.size(); index++) { + if (index == crews.size() - 3) { + pairs.add(new Pair(List.of(crews.get(index), crews.get(index + 1), crews.get(index + 2)))); + break; + } + if (index % 2 == 1) { + pairs.add(new Pair(List.of(crews.get(index - 1), crews.get(index)))); + } + } + return pairs; + } + + private List createEvenPair() { + List pairs = new ArrayList<>(); + for (int index = 0; index < crews.size(); index++) { + if (index % 2 == 1) { + pairs.add(new Pair(List.of(crews.get(index - 1), crews.get(index)))); + } + } + return pairs; + } +} diff --git a/src/main/java/pairmatching/domain/Pair.java b/src/main/java/pairmatching/domain/Pair.java new file mode 100644 index 0000000..cdf1312 --- /dev/null +++ b/src/main/java/pairmatching/domain/Pair.java @@ -0,0 +1,11 @@ +package pairmatching.domain; + +import java.util.List; + +public class Pair { + private final List pair; + + public Pair(final List pair) { + this.pair = pair; + } +} diff --git a/src/main/java/pairmatching/domain/PairMatching.java b/src/main/java/pairmatching/domain/PairMatching.java new file mode 100644 index 0000000..6c49b77 --- /dev/null +++ b/src/main/java/pairmatching/domain/PairMatching.java @@ -0,0 +1,11 @@ +package pairmatching.domain; + +public class PairMatching { + private final CourseInformation courseInformation; + private final Crews crews; + + public PairMatching(final CourseInformation courseInformation, final Crews crews) { + this.courseInformation = courseInformation; + this.crews = crews; + } +} diff --git a/src/main/java/pairmatching/repository/CrewRepository.java b/src/main/java/pairmatching/repository/CrewRepository.java index 5d7edea..1b8d19f 100644 --- a/src/main/java/pairmatching/repository/CrewRepository.java +++ b/src/main/java/pairmatching/repository/CrewRepository.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.stream.Collectors; import pairmatching.domain.Crew; +import pairmatching.domain.Crews; import pairmatching.domain.enums.Course; import pairmatching.message.ErrorMessage; @@ -40,4 +41,10 @@ private static void initializeCrew(String path, Course course) { throw new IllegalArgumentException(ErrorMessage.FILE_NOT_FOUND_ERROR); } } + + public static Crews findAllByCourse(final Course course) { + return new Crews(store.stream() + .filter(crew -> crew.containsCourse(course)) + .collect(Collectors.toList())); + } } diff --git a/src/main/java/pairmatching/repository/MatchingCrewRepository.java b/src/main/java/pairmatching/repository/MatchingCrewRepository.java new file mode 100644 index 0000000..632b114 --- /dev/null +++ b/src/main/java/pairmatching/repository/MatchingCrewRepository.java @@ -0,0 +1,28 @@ +package pairmatching.repository; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import pairmatching.domain.CourseInformation; +import pairmatching.domain.Pair; + +public class MatchingCrewRepository { + private static final MatchingCrewRepository instance = new MatchingCrewRepository(); + private static final Map> store = new HashMap<>(); + + private MatchingCrewRepository() { + } + + public static MatchingCrewRepository getInstance() { + return instance; + } + + public boolean hasMatchedBefore(CourseInformation courseInformation) { + return store.containsKey(courseInformation); + } + + public void savePairMatching(final CourseInformation courseInformation, final List pairs) { + store.remove(courseInformation); + store.put(courseInformation, pairs); + } +} diff --git a/src/main/java/pairmatching/service/PairMatchingService.java b/src/main/java/pairmatching/service/PairMatchingService.java new file mode 100644 index 0000000..f2432a0 --- /dev/null +++ b/src/main/java/pairmatching/service/PairMatchingService.java @@ -0,0 +1,54 @@ +package pairmatching.service; + +import java.util.List; +import pairmatching.domain.CourseInformation; +import pairmatching.domain.Crews; +import pairmatching.domain.Pair; +import pairmatching.exception.PairAlreadyExistException; +import pairmatching.message.ErrorMessage; +import pairmatching.repository.CrewRepository; +import pairmatching.repository.MatchingCrewRepository; +import pairmatching.util.ShuffleUtil; + +public class PairMatchingService { + public static final int MAX_TRY = 3; + private final MatchingCrewRepository matchingCrewRepository = MatchingCrewRepository.getInstance(); + + public void retryPairMatching(final List inputInformation) { + CourseInformation courseInformation = CourseInformation.of(inputInformation); + matchCrew(courseInformation, 0); + } + + public List pairMatch(final List inputInformation) { + CourseInformation courseInformation = validateAlreadyMatch(CourseInformation.of(inputInformation)); + return matchCrew(courseInformation, 0); + } + + private List matchCrew(final CourseInformation courseInformation, final int matchTryCount) { + checkTryCount(matchTryCount); + Crews shuffledCrews = ShuffleUtil.ShuffleCrews(CrewRepository.findAllByCourse(courseInformation.getCourse())); + List pairs = shuffledCrews.makePairList(); + if (hasSamePairInList(pairs)) { + matchCrew(courseInformation, matchTryCount + 1); + } + matchingCrewRepository.savePairMatching(courseInformation, pairs); + return pairs; + } + + private boolean hasSamePairInList(final List pairs) { + return false; + } + + private void checkTryCount(final int matchTryCount) { + if (matchTryCount == MAX_TRY) { + throw new IllegalArgumentException(ErrorMessage.LIMIT_PAIR_MATCH_TRY_ERROR); + } + } + + private CourseInformation validateAlreadyMatch(final CourseInformation courseInformation) { + if (matchingCrewRepository.hasMatchedBefore(courseInformation)) { + throw new PairAlreadyExistException(); + } + return courseInformation; + } +} diff --git a/src/main/java/pairmatching/util/ShuffleUtil.java b/src/main/java/pairmatching/util/ShuffleUtil.java new file mode 100644 index 0000000..61aba44 --- /dev/null +++ b/src/main/java/pairmatching/util/ShuffleUtil.java @@ -0,0 +1,16 @@ +package pairmatching.util; + +import camp.nextstep.edu.missionutils.Randoms; +import java.util.List; +import pairmatching.domain.Crew; +import pairmatching.domain.Crews; + +public class ShuffleUtil { + private ShuffleUtil() { + } + + public static Crews ShuffleCrews(Crews crews) { + List shuffledCrews = Randoms.shuffle(crews.getCrewList()); + return new Crews(shuffledCrews); + } +} From 324bf656f6fbca431989640b36c577cedf31c7e4 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 21:41:45 +0900 Subject: [PATCH 09/16] =?UTF-8?q?feat:=20=EB=8F=99=EC=9D=BC=20=EC=BD=94?= =?UTF-8?q?=EC=8A=A4,=20=EB=A0=88=EB=B2=A8,=20=EB=AF=B8=EC=85=98=EC=97=90?= =?UTF-8?q?=20=EB=8C=80=ED=95=B4=20=ED=8E=98=EC=96=B4=EB=A7=A4=EC=B9=AD?= =?UTF-8?q?=EC=9D=B4=20=EC=A1=B4=EC=9E=AC=ED=95=98=EB=A9=B4=20=EC=9E=AC?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EC=97=AC=EB=B6=80=20=EB=B0=8F=20=EC=9E=AC?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++-- .../controller/PairMatchingController.java | 11 ++++++++++- src/main/java/pairmatching/message/ErrorMessage.java | 6 ++++++ src/main/java/pairmatching/util/InputValidator.java | 9 +++++++++ src/main/java/pairmatching/view/InputView.java | 6 ++++++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 0e94a0f..db95a6a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,11 +16,11 @@ - [X] 현재 과정, 미션(레벨별로)에 대한 안내를 화면에 출력한다. - [x] 사용자에게 과정, 레벨, 미션에대한 입력을 순서대로 `입력받는다.` - [x] 해당 과정에 맞는 크루들을 셔플하여 페어 매칭 결과를 만든다. - - [ ] 페어 매칭 결과는 저장을하고, 중복된 페어매칭 검증시에 사용된다. + - [X] 페어 매칭 결과는 저장을하고, 중복된 페어매칭 검증시에 사용된다. - [ ] 같은 레벨 다른 미션에서 이미 페어로 만났다면 재매칭 한다. - [ ] 페어 매칭이 완료되면 페어 매칭 결과를 출력한다. - **페어 재매칭 기능 목록** - - [ ] 이미 `과정, 레벨`에 대해 만들어진 페어가 있다면 재 매칭 여부를 `입력한다.` + - [x] 이미 `과정, 레벨`에 대해 만들어진 페어가 있다면 재 매칭 여부를 `입력한다.` - [ ] `재 페어매칭시` 각 사람들은 는 이전에 만났던 페어를 만나면 안된다. - [ ] 이전에 만났던 페어를 만나면 최대 3회 재시도를 한다. - [ ] 재페어 매칭이 완료되면 페어 매칭 결과를 출력한다. diff --git a/src/main/java/pairmatching/controller/PairMatchingController.java b/src/main/java/pairmatching/controller/PairMatchingController.java index aa3d79e..e641023 100644 --- a/src/main/java/pairmatching/controller/PairMatchingController.java +++ b/src/main/java/pairmatching/controller/PairMatchingController.java @@ -8,6 +8,7 @@ import pairmatching.view.OutputView; public class PairMatchingController { + public static final String RETRY = "네"; private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); private final PairMatchingService pairMatchingService = new PairMatchingService(); @@ -31,6 +32,7 @@ private void determineMenuSelect(final String validatedSelectMenu) { if (validatedSelectMenu.equals(InputValidator.PAIR_RESET)) { requestPairReset(); } + run(); } private void requestPairMatching() { @@ -46,7 +48,14 @@ private void requestPairMatching() { } private void requestRetry(final List courseInformation) { - pairMatchingService.retryPairMatching(courseInformation); + try { + if (InputValidator.validateRetryInput(inputView.inputRetry()).equals(RETRY)) { + pairMatchingService.retryPairMatching(courseInformation); + } + } catch (IllegalArgumentException exception) { + outputView.printMessage(exception.getMessage()); + requestRetry(courseInformation); + } } private void requestPairReset() { diff --git a/src/main/java/pairmatching/message/ErrorMessage.java b/src/main/java/pairmatching/message/ErrorMessage.java index 8dd99eb..807a500 100644 --- a/src/main/java/pairmatching/message/ErrorMessage.java +++ b/src/main/java/pairmatching/message/ErrorMessage.java @@ -7,6 +7,12 @@ public class ErrorMessage { public static final String MENU_SELECT_ERROR = "[ERROR] '1, 2, 3, Q'만 입력할 수 있습니다."; public static final String COURSE_INFORMATION_ERROR = "[ERROR] '백엔드, 레벨1, 자동차경주'과 같이 입력해야 합니다."; public static final String FILE_NOT_FOUND_ERROR = "[ERROR] 파일을 찾을 수 없습니다."; + public static final String NO_COURSE_ERROR = "[ERROR] 존재하지 않는 코스입니다."; + public static final String NO_LEVEL_ERROR = "[ERROR] 존재하지 않는 레벨입니다."; + public static final String NO_MISSION_ERROR = "[ERROR] 존재하지 않는 미션입니다."; + public static final String NO_MISSION_IN_LEVEL_ERROR = "[ERROR] 해당 레벨에 존재하지 않는 미션입니다."; + public static final String LIMIT_PAIR_MATCH_TRY_ERROR = "[ERROR] 중복된 페어가 존재하여 매칭할 수 없습니다."; + public static final String RETRY_INPUT_ERROR = "[ERROR] 네, 아니오만 입력해야 합니다."; private ErrorMessage() { } diff --git a/src/main/java/pairmatching/util/InputValidator.java b/src/main/java/pairmatching/util/InputValidator.java index f681fb0..aecc8e7 100644 --- a/src/main/java/pairmatching/util/InputValidator.java +++ b/src/main/java/pairmatching/util/InputValidator.java @@ -12,6 +12,8 @@ public class InputValidator { public static final String QUIT = "Q"; public static final String SEPARATOR = ", "; public static final int NEED_SIZE_INPUT = 3; + public static final String YES = "네"; + public static final String NO = "아니오"; private InputValidator() { } @@ -33,4 +35,11 @@ public static List validateCourseInformation(final String userInput) { return Arrays.stream(userInput.split(SEPARATOR)) .collect(Collectors.toList()); } + + public static String validateRetryInput(final String userInput) { + if (!userInput.equals(YES) && !userInput.equals(NO)) { + throw new IllegalArgumentException(ErrorMessage.RETRY_INPUT_ERROR); + } + return userInput; + } } diff --git a/src/main/java/pairmatching/view/InputView.java b/src/main/java/pairmatching/view/InputView.java index ba6d7bf..41f2f85 100644 --- a/src/main/java/pairmatching/view/InputView.java +++ b/src/main/java/pairmatching/view/InputView.java @@ -33,4 +33,10 @@ private static void printInformation() { System.out.println(" -레벨5:"); System.out.println("#############################################"); } + + public String inputRetry() { + System.out.println("매칭 정보가 있습니다. 다시 매칭하시겠습니까?"); + System.out.println("네 | 아니오"); + return Console.readLine(); + } } From fd4e4cfc771a5e8ba4f853d1b36af828996feab3 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 22:03:42 +0900 Subject: [PATCH 10/16] =?UTF-8?q?feat:=20=ED=8E=98=EC=96=B4=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD,=20=EC=9E=AC=ED=8E=98=EC=96=B4=EB=A7=A4=EC=B9=AD?= =?UTF-8?q?=EC=8B=9C=20=ED=8E=98=EC=96=B4=EB=A7=A4=EC=B9=AD=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++-- .../controller/PairMatchingController.java | 7 ++++--- src/main/java/pairmatching/domain/Crew.java | 4 ++++ src/main/java/pairmatching/domain/Pair.java | 12 ++++++++++++ .../service/PairMatchingService.java | 5 +++-- .../java/pairmatching/view/OutputView.java | 18 ++++++++++++++++++ 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/docs/README.md b/docs/README.md index db95a6a..81b468d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,12 +18,12 @@ - [x] 해당 과정에 맞는 크루들을 셔플하여 페어 매칭 결과를 만든다. - [X] 페어 매칭 결과는 저장을하고, 중복된 페어매칭 검증시에 사용된다. - [ ] 같은 레벨 다른 미션에서 이미 페어로 만났다면 재매칭 한다. - - [ ] 페어 매칭이 완료되면 페어 매칭 결과를 출력한다. + - [x] 페어 매칭이 완료되면 페어 매칭 결과를 출력한다. - **페어 재매칭 기능 목록** - [x] 이미 `과정, 레벨`에 대해 만들어진 페어가 있다면 재 매칭 여부를 `입력한다.` - [ ] `재 페어매칭시` 각 사람들은 는 이전에 만났던 페어를 만나면 안된다. - [ ] 이전에 만났던 페어를 만나면 최대 3회 재시도를 한다. - - [ ] 재페어 매칭이 완료되면 페어 매칭 결과를 출력한다. + - [x] 재페어 매칭이 완료되면 페어 매칭 결과를 출력한다. - **예외 목록** - [x] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. diff --git a/src/main/java/pairmatching/controller/PairMatchingController.java b/src/main/java/pairmatching/controller/PairMatchingController.java index e641023..4feb403 100644 --- a/src/main/java/pairmatching/controller/PairMatchingController.java +++ b/src/main/java/pairmatching/controller/PairMatchingController.java @@ -32,13 +32,13 @@ private void determineMenuSelect(final String validatedSelectMenu) { if (validatedSelectMenu.equals(InputValidator.PAIR_RESET)) { requestPairReset(); } - run(); } private void requestPairMatching() { List courseInformation = InputValidator.validateCourseInformation(inputView.inputCourseInformation()); try { - pairMatchingService.pairMatch(courseInformation); + outputView.printPairMatchingResult(pairMatchingService.pairMatch(courseInformation)); + run(); } catch (PairAlreadyExistException exception) { requestRetry(courseInformation); } catch (IllegalArgumentException exception) { @@ -50,7 +50,8 @@ private void requestPairMatching() { private void requestRetry(final List courseInformation) { try { if (InputValidator.validateRetryInput(inputView.inputRetry()).equals(RETRY)) { - pairMatchingService.retryPairMatching(courseInformation); + outputView.printPairMatchingResult(pairMatchingService.retryPairMatching(courseInformation)); + run(); } } catch (IllegalArgumentException exception) { outputView.printMessage(exception.getMessage()); diff --git a/src/main/java/pairmatching/domain/Crew.java b/src/main/java/pairmatching/domain/Crew.java index 89f2882..e567b06 100644 --- a/src/main/java/pairmatching/domain/Crew.java +++ b/src/main/java/pairmatching/domain/Crew.java @@ -16,6 +16,10 @@ public boolean containsCourse(final Course course) { return this.course == course; } + public String getName() { + return name; + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/src/main/java/pairmatching/domain/Pair.java b/src/main/java/pairmatching/domain/Pair.java index cdf1312..f7d2f7c 100644 --- a/src/main/java/pairmatching/domain/Pair.java +++ b/src/main/java/pairmatching/domain/Pair.java @@ -3,9 +3,21 @@ import java.util.List; public class Pair { + public static final String SEPARATOR = " : "; private final List pair; public Pair(final List pair) { this.pair = pair; } + + @Override + public String toString() { + StringBuilder log = new StringBuilder(); + pair.stream() + .map(Crew::getName) + .limit(pair.size() - 1) + .forEach(name -> log.append(name).append(SEPARATOR)); + log.append(pair.get(pair.size() - 1).getName()); + return log.toString(); + } } diff --git a/src/main/java/pairmatching/service/PairMatchingService.java b/src/main/java/pairmatching/service/PairMatchingService.java index f2432a0..5c76fd2 100644 --- a/src/main/java/pairmatching/service/PairMatchingService.java +++ b/src/main/java/pairmatching/service/PairMatchingService.java @@ -1,5 +1,6 @@ package pairmatching.service; +import java.nio.channels.Pipe; import java.util.List; import pairmatching.domain.CourseInformation; import pairmatching.domain.Crews; @@ -14,9 +15,9 @@ public class PairMatchingService { public static final int MAX_TRY = 3; private final MatchingCrewRepository matchingCrewRepository = MatchingCrewRepository.getInstance(); - public void retryPairMatching(final List inputInformation) { + public List retryPairMatching(final List inputInformation) { CourseInformation courseInformation = CourseInformation.of(inputInformation); - matchCrew(courseInformation, 0); + return matchCrew(courseInformation, 0); } public List pairMatch(final List inputInformation) { diff --git a/src/main/java/pairmatching/view/OutputView.java b/src/main/java/pairmatching/view/OutputView.java index c640c43..5a06b26 100644 --- a/src/main/java/pairmatching/view/OutputView.java +++ b/src/main/java/pairmatching/view/OutputView.java @@ -1,8 +1,26 @@ package pairmatching.view; +import java.util.Arrays; +import java.util.List; +import pairmatching.domain.Pair; + public class OutputView { public void printMessage(final String message) { System.out.println(message); System.out.println(); } + + public void printPairMatchingResult(final List pairMatch) { + System.out.println("페어 매칭 결과입니다."); + System.out.println(createPairResultMessage(pairMatch)); + } + + private String createPairResultMessage(final List pairMatch) { + StringBuilder message = new StringBuilder(); + Arrays.stream(pairMatch.toString() + .replaceAll("(?:\\[|null|\\]|)", "") + .split(",")) + .forEach(match -> message.append(match.trim()).append("\n")); + return message.toString(); + } } From 81014559afefb53789b17abb986847880e694c30 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 22:04:15 +0900 Subject: [PATCH 11/16] =?UTF-8?q?docs:=20=EC=99=84=EB=A3=8C=EB=90=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EB=AA=A9=EB=A1=9D=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 81b468d..980433b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -29,7 +29,7 @@ - [x] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. - [X] 각 과정, 레벨, 미션이 존재하지 않으면 예외 처리한다. - [X] 만약 미션이 없는 레벨이라면 예외 처리한다. - - [ ] 재매칭 여부 입력시 네, 아니오가 아닌 입력은 예외 처리한다. + - [X] 재매칭 여부 입력시 네, 아니오가 아닌 입력은 예외 처리한다. ## 2. 페어 조회 선택시 - **조회 기능 목록** From d62fe837f930e2cc57d0176d115acc60bcfaffa4 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 22:16:12 +0900 Subject: [PATCH 12/16] =?UTF-8?q?feat:=20=ED=8E=98=EC=96=B4=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EA=B2=B0=EA=B3=BC=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=B0=8F=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 12 ++++++------ .../controller/PairMatchingController.java | 14 +++++++++++++- .../exception/NoPariResultException.java | 7 +++++++ .../java/pairmatching/message/ErrorMessage.java | 1 + .../repository/MatchingCrewRepository.java | 9 +++++++++ .../pairmatching/service/PairMatchingService.java | 11 ++++++++--- 6 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 src/main/java/pairmatching/exception/NoPariResultException.java diff --git a/docs/README.md b/docs/README.md index 980433b..4ba82cb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,13 +33,13 @@ ## 2. 페어 조회 선택시 - **조회 기능 목록** - - [ ] 과정, 레벨, 미션에 대한 입력을 순서대로 `입력받는다.` - - [ ] 해당 입력에 대한 페어 매칭 결과를 출력한다. + - [x] 과정, 레벨, 미션에 대한 입력을 순서대로 `입력받는다.` + - [x] 해당 입력에 대한 페어 매칭 결과를 출력한다. - **예외 목록** - - [ ] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. - - [ ] 각 과정, 레벨, 미션은 모두 존재하야 한다. - - [ ] 만약 미션이 없는 레벨이라면 예외 처리한다. - - [ ] 조회할 매칭 결과가 없다면 예외 처리한다. + - [x] `백엔드, 레벨1, 자동차경주`과 같은 포멧의 입력이 아니면 예외 처리한다. + - [x] 각 과정, 레벨, 미션은 모두 존재하야 한다. + - [x] 만약 미션이 없는 레벨이라면 예외 처리한다. + - [x] 조회할 매칭 결과가 없다면 예외 처리한다. ## 3. 페어 초기화 선택시 - **초기화 기능 목록** diff --git a/src/main/java/pairmatching/controller/PairMatchingController.java b/src/main/java/pairmatching/controller/PairMatchingController.java index 4feb403..f746005 100644 --- a/src/main/java/pairmatching/controller/PairMatchingController.java +++ b/src/main/java/pairmatching/controller/PairMatchingController.java @@ -1,6 +1,7 @@ package pairmatching.controller; import java.util.List; +import pairmatching.exception.NoPariResultException; import pairmatching.exception.PairAlreadyExistException; import pairmatching.service.PairMatchingService; import pairmatching.util.InputValidator; @@ -64,7 +65,18 @@ private void requestPairReset() { } private void requestPairView() { - System.out.println("pass"); + try { + List courseInformation = InputValidator.validateCourseInformation( + inputView.inputCourseInformation()); + outputView.printPairMatchingResult(pairMatchingService.findPairMatchResult(courseInformation)); + } catch (NoPariResultException exception) { + outputView.printMessage(exception.getMessage()); + run(); + } catch (IllegalArgumentException exception) { + outputView.printMessage(exception.getMessage()); + requestPairView(); + } + } } diff --git a/src/main/java/pairmatching/exception/NoPariResultException.java b/src/main/java/pairmatching/exception/NoPariResultException.java new file mode 100644 index 0000000..73eaa42 --- /dev/null +++ b/src/main/java/pairmatching/exception/NoPariResultException.java @@ -0,0 +1,7 @@ +package pairmatching.exception; + +public class NoPariResultException extends RuntimeException { + public NoPariResultException(String message) { + super(message); + } +} diff --git a/src/main/java/pairmatching/message/ErrorMessage.java b/src/main/java/pairmatching/message/ErrorMessage.java index 807a500..a47f8fd 100644 --- a/src/main/java/pairmatching/message/ErrorMessage.java +++ b/src/main/java/pairmatching/message/ErrorMessage.java @@ -13,6 +13,7 @@ public class ErrorMessage { public static final String NO_MISSION_IN_LEVEL_ERROR = "[ERROR] 해당 레벨에 존재하지 않는 미션입니다."; public static final String LIMIT_PAIR_MATCH_TRY_ERROR = "[ERROR] 중복된 페어가 존재하여 매칭할 수 없습니다."; public static final String RETRY_INPUT_ERROR = "[ERROR] 네, 아니오만 입력해야 합니다."; + public static final String NO_PAIR_MATCHING_RESULT = "[ERROR] 매칭 이력이 없습니다."; private ErrorMessage() { } diff --git a/src/main/java/pairmatching/repository/MatchingCrewRepository.java b/src/main/java/pairmatching/repository/MatchingCrewRepository.java index 632b114..2ee2ca8 100644 --- a/src/main/java/pairmatching/repository/MatchingCrewRepository.java +++ b/src/main/java/pairmatching/repository/MatchingCrewRepository.java @@ -5,6 +5,8 @@ import java.util.Map; import pairmatching.domain.CourseInformation; import pairmatching.domain.Pair; +import pairmatching.exception.NoPariResultException; +import pairmatching.message.ErrorMessage; public class MatchingCrewRepository { private static final MatchingCrewRepository instance = new MatchingCrewRepository(); @@ -25,4 +27,11 @@ public void savePairMatching(final CourseInformation courseInformation, final Li store.remove(courseInformation); store.put(courseInformation, pairs); } + + public List findPairMatching(final CourseInformation courseInformation) { + if (!store.containsKey(courseInformation)) { + throw new NoPariResultException(ErrorMessage.NO_PAIR_MATCHING_RESULT); + } + return store.get(courseInformation); + } } diff --git a/src/main/java/pairmatching/service/PairMatchingService.java b/src/main/java/pairmatching/service/PairMatchingService.java index 5c76fd2..80a8364 100644 --- a/src/main/java/pairmatching/service/PairMatchingService.java +++ b/src/main/java/pairmatching/service/PairMatchingService.java @@ -1,6 +1,5 @@ package pairmatching.service; -import java.nio.channels.Pipe; import java.util.List; import pairmatching.domain.CourseInformation; import pairmatching.domain.Crews; @@ -29,14 +28,15 @@ private List matchCrew(final CourseInformation courseInformation, final in checkTryCount(matchTryCount); Crews shuffledCrews = ShuffleUtil.ShuffleCrews(CrewRepository.findAllByCourse(courseInformation.getCourse())); List pairs = shuffledCrews.makePairList(); - if (hasSamePairInList(pairs)) { + if (hasSamePairInList(courseInformation, pairs)) { matchCrew(courseInformation, matchTryCount + 1); } matchingCrewRepository.savePairMatching(courseInformation, pairs); return pairs; } - private boolean hasSamePairInList(final List pairs) { + private boolean hasSamePairInList(final CourseInformation courseInformation, final List pairs) { +// matchingCrewRepository.find return false; } @@ -52,4 +52,9 @@ private CourseInformation validateAlreadyMatch(final CourseInformation courseInf } return courseInformation; } + + public List findPairMatchResult(final List inputInformation) { + CourseInformation courseInformation = CourseInformation.of(inputInformation); + return matchingCrewRepository.findPairMatching(courseInformation); + } } From 8e5b938b3a1014f20108fe74137d54a883470e56 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 22:21:08 +0900 Subject: [PATCH 13/16] =?UTF-8?q?feat:=20=ED=8E=98=EC=96=B4=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- .../controller/PairMatchingController.java | 11 ++++++----- .../repository/MatchingCrewRepository.java | 4 ++++ .../pairmatching/service/PairMatchingService.java | 4 ++++ src/main/java/pairmatching/view/OutputView.java | 4 ++++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index 4ba82cb..2c562b5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -43,5 +43,5 @@ ## 3. 페어 초기화 선택시 - **초기화 기능 목록** - - [ ] 모든 레벨의 모든 페어 매칭 기록을 초기화 한다 + - [x] 모든 레벨의 모든 페어 매칭 기록을 초기화 한다 - [ ] 중복된 페어 매칭 검증을 위한 것도 초기화 한다. \ No newline at end of file diff --git a/src/main/java/pairmatching/controller/PairMatchingController.java b/src/main/java/pairmatching/controller/PairMatchingController.java index f746005..50c81aa 100644 --- a/src/main/java/pairmatching/controller/PairMatchingController.java +++ b/src/main/java/pairmatching/controller/PairMatchingController.java @@ -60,15 +60,12 @@ private void requestRetry(final List courseInformation) { } } - private void requestPairReset() { - System.out.println("pass"); - } - private void requestPairView() { try { List courseInformation = InputValidator.validateCourseInformation( inputView.inputCourseInformation()); outputView.printPairMatchingResult(pairMatchingService.findPairMatchResult(courseInformation)); + run(); } catch (NoPariResultException exception) { outputView.printMessage(exception.getMessage()); run(); @@ -76,7 +73,11 @@ private void requestPairView() { outputView.printMessage(exception.getMessage()); requestPairView(); } - } + private void requestPairReset() { + outputView.printResetMessage(); + pairMatchingService.deleteAllMatchingResult(); + run(); + } } diff --git a/src/main/java/pairmatching/repository/MatchingCrewRepository.java b/src/main/java/pairmatching/repository/MatchingCrewRepository.java index 2ee2ca8..817ccb9 100644 --- a/src/main/java/pairmatching/repository/MatchingCrewRepository.java +++ b/src/main/java/pairmatching/repository/MatchingCrewRepository.java @@ -34,4 +34,8 @@ public List findPairMatching(final CourseInformation courseInformation) { } return store.get(courseInformation); } + + public void deleteAll() { + store.clear(); + } } diff --git a/src/main/java/pairmatching/service/PairMatchingService.java b/src/main/java/pairmatching/service/PairMatchingService.java index 80a8364..98c8423 100644 --- a/src/main/java/pairmatching/service/PairMatchingService.java +++ b/src/main/java/pairmatching/service/PairMatchingService.java @@ -57,4 +57,8 @@ public List findPairMatchResult(final List inputInformation) { CourseInformation courseInformation = CourseInformation.of(inputInformation); return matchingCrewRepository.findPairMatching(courseInformation); } + + public void deleteAllMatchingResult() { + matchingCrewRepository.deleteAll(); + } } diff --git a/src/main/java/pairmatching/view/OutputView.java b/src/main/java/pairmatching/view/OutputView.java index 5a06b26..9d20b7f 100644 --- a/src/main/java/pairmatching/view/OutputView.java +++ b/src/main/java/pairmatching/view/OutputView.java @@ -23,4 +23,8 @@ private String createPairResultMessage(final List pairMatch) { .forEach(match -> message.append(match.trim()).append("\n")); return message.toString(); } + + public void printResetMessage() { + System.out.println("초기화 되었습니다."); + } } From 232c3829e0dfad1bcfebd346ae27744e52fe0a89 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 22:21:32 +0900 Subject: [PATCH 14/16] =?UTF-8?q?style:=20=EC=9D=B8=EB=8D=B4=ED=8A=B8=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9E=84=ED=8F=AC=ED=8A=B8=EB=AC=B8=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pairmatching/domain/enums/Level.java | 5 +---- src/main/java/pairmatching/view/InputView.java | 2 -- src/main/java/pairmatching/view/OutputView.java | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/pairmatching/domain/enums/Level.java b/src/main/java/pairmatching/domain/enums/Level.java index 01ed14f..f1d794f 100644 --- a/src/main/java/pairmatching/domain/enums/Level.java +++ b/src/main/java/pairmatching/domain/enums/Level.java @@ -6,10 +6,7 @@ import pairmatching.message.ErrorMessage; /** - * 자동차경주 | 로또 | 숫자야구게임 - * - 레벨2: 장바구니 | 결제 | 지하철노선도 - * - 레벨3: - * - 레벨4: 성능개선 | 배포 + * 자동차경주 | 로또 | 숫자야구게임 - 레벨2: 장바구니 | 결제 | 지하철노선도 - 레벨3: - 레벨4: 성능개선 | 배포 */ public enum Level { LEVEL1("레벨1", List.of(Mission.CAR_RACING, Mission.LOTTO, Mission.BASEBALL)), diff --git a/src/main/java/pairmatching/view/InputView.java b/src/main/java/pairmatching/view/InputView.java index 41f2f85..5134a1c 100644 --- a/src/main/java/pairmatching/view/InputView.java +++ b/src/main/java/pairmatching/view/InputView.java @@ -1,8 +1,6 @@ package pairmatching.view; import camp.nextstep.edu.missionutils.Console; -import java.util.Arrays; -import pairmatching.domain.enums.Course; public class InputView { diff --git a/src/main/java/pairmatching/view/OutputView.java b/src/main/java/pairmatching/view/OutputView.java index 9d20b7f..6330da9 100644 --- a/src/main/java/pairmatching/view/OutputView.java +++ b/src/main/java/pairmatching/view/OutputView.java @@ -18,8 +18,8 @@ public void printPairMatchingResult(final List pairMatch) { private String createPairResultMessage(final List pairMatch) { StringBuilder message = new StringBuilder(); Arrays.stream(pairMatch.toString() - .replaceAll("(?:\\[|null|\\]|)", "") - .split(",")) + .replaceAll("(?:\\[|null|\\]|)", "") + .split(",")) .forEach(match -> message.append(match.trim()).append("\n")); return message.toString(); } From 9bdc2c7dd9d1403d9f577932a3bc1d8639a0fd82 Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 22:35:07 +0900 Subject: [PATCH 15/16] =?UTF-8?q?refactor:=20=ED=81=AC=EB=A3=A8=20?= =?UTF-8?q?=EC=85=94=ED=94=8C=EC=8B=9C=20List=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=85=94=ED=94=8C=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pairmatching/domain/Crews.java | 12 +++++++----- .../pairmatching/service/PairMatchingService.java | 3 ++- src/main/java/pairmatching/util/ShuffleUtil.java | 10 +++++++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/pairmatching/domain/Crews.java b/src/main/java/pairmatching/domain/Crews.java index eb9d288..cc800b2 100644 --- a/src/main/java/pairmatching/domain/Crews.java +++ b/src/main/java/pairmatching/domain/Crews.java @@ -1,8 +1,8 @@ package pairmatching.domain; import java.util.ArrayList; -import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; public class Crews { private final List crews; @@ -11,10 +11,6 @@ public Crews(final List crews) { this.crews = crews; } - public List getCrewList() { - return Collections.unmodifiableList(crews); - } - public List makePairList() { if (crews.size() % 2 == 0) { return createEvenPair(); @@ -45,4 +41,10 @@ private List createEvenPair() { } return pairs; } + + public List getCrewNameList() { + return crews.stream() + .map(Crew::getName) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/pairmatching/service/PairMatchingService.java b/src/main/java/pairmatching/service/PairMatchingService.java index 98c8423..4bb2e85 100644 --- a/src/main/java/pairmatching/service/PairMatchingService.java +++ b/src/main/java/pairmatching/service/PairMatchingService.java @@ -26,7 +26,8 @@ public List pairMatch(final List inputInformation) { private List matchCrew(final CourseInformation courseInformation, final int matchTryCount) { checkTryCount(matchTryCount); - Crews shuffledCrews = ShuffleUtil.ShuffleCrews(CrewRepository.findAllByCourse(courseInformation.getCourse())); + Crews shuffledCrews = ShuffleUtil.ShuffleCrews(CrewRepository.findAllByCourse(courseInformation.getCourse()), + courseInformation.getCourse()); List pairs = shuffledCrews.makePairList(); if (hasSamePairInList(courseInformation, pairs)) { matchCrew(courseInformation, matchTryCount + 1); diff --git a/src/main/java/pairmatching/util/ShuffleUtil.java b/src/main/java/pairmatching/util/ShuffleUtil.java index 61aba44..b3470ce 100644 --- a/src/main/java/pairmatching/util/ShuffleUtil.java +++ b/src/main/java/pairmatching/util/ShuffleUtil.java @@ -2,15 +2,19 @@ import camp.nextstep.edu.missionutils.Randoms; import java.util.List; +import java.util.stream.Collectors; import pairmatching.domain.Crew; import pairmatching.domain.Crews; +import pairmatching.domain.enums.Course; public class ShuffleUtil { private ShuffleUtil() { } - public static Crews ShuffleCrews(Crews crews) { - List shuffledCrews = Randoms.shuffle(crews.getCrewList()); - return new Crews(shuffledCrews); + public static Crews ShuffleCrews(Crews crews, final Course course) { + List shuffledName = Randoms.shuffle(crews.getCrewNameList()); + return new Crews(shuffledName.stream() + .map(name -> new Crew(course, name)) + .collect(Collectors.toList())); } } From 143d040c2e5a5e57fd3fe6650b2f68b23b6283ac Mon Sep 17 00:00:00 2001 From: HiiWee Date: Thu, 15 Dec 2022 22:57:40 +0900 Subject: [PATCH 16/16] =?UTF-8?q?feat:=20=ED=8E=98=EC=96=B4=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EC=A4=91=EB=B3=B5=203=EB=B2=88=EC=8B=9C=20?= =?UTF-8?q?=EC=9E=AC=EC=8B=9C=EB=8F=84=20=EB=B0=8F=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 7 +++---- .../pairmatching/domain/CourseInformation.java | 4 ++++ src/main/java/pairmatching/domain/Pair.java | 6 ++++++ .../repository/MatchingCrewRepository.java | 17 +++++++++++++++++ .../service/PairMatchingService.java | 3 +-- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index 2c562b5..bf793d5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,12 +17,12 @@ - [x] 사용자에게 과정, 레벨, 미션에대한 입력을 순서대로 `입력받는다.` - [x] 해당 과정에 맞는 크루들을 셔플하여 페어 매칭 결과를 만든다. - [X] 페어 매칭 결과는 저장을하고, 중복된 페어매칭 검증시에 사용된다. - - [ ] 같은 레벨 다른 미션에서 이미 페어로 만났다면 재매칭 한다. + - [x] 같은 레벨 다른 미션에서 이미 페어로 만났다면 재매칭 한다. - [x] 페어 매칭이 완료되면 페어 매칭 결과를 출력한다. - **페어 재매칭 기능 목록** - [x] 이미 `과정, 레벨`에 대해 만들어진 페어가 있다면 재 매칭 여부를 `입력한다.` - - [ ] `재 페어매칭시` 각 사람들은 는 이전에 만났던 페어를 만나면 안된다. - - [ ] 이전에 만났던 페어를 만나면 최대 3회 재시도를 한다. + - [x] `재 페어매칭시` 각 사람들은 는 이전에 만났던 페어를 만나면 안된다. + - [x] 이전에 만났던 페어를 만나면 최대 3회 재시도를 한다. - [x] 재페어 매칭이 완료되면 페어 매칭 결과를 출력한다. - **예외 목록** @@ -44,4 +44,3 @@ ## 3. 페어 초기화 선택시 - **초기화 기능 목록** - [x] 모든 레벨의 모든 페어 매칭 기록을 초기화 한다 - - [ ] 중복된 페어 매칭 검증을 위한 것도 초기화 한다. \ No newline at end of file diff --git a/src/main/java/pairmatching/domain/CourseInformation.java b/src/main/java/pairmatching/domain/CourseInformation.java index 12aecc5..01ae048 100644 --- a/src/main/java/pairmatching/domain/CourseInformation.java +++ b/src/main/java/pairmatching/domain/CourseInformation.java @@ -57,4 +57,8 @@ public int hashCode() { public Course getCourse() { return course; } + + public Level getLevel() { + return level; + } } diff --git a/src/main/java/pairmatching/domain/Pair.java b/src/main/java/pairmatching/domain/Pair.java index f7d2f7c..a636d34 100644 --- a/src/main/java/pairmatching/domain/Pair.java +++ b/src/main/java/pairmatching/domain/Pair.java @@ -10,6 +10,12 @@ public Pair(final List pair) { this.pair = pair; } + public boolean containsPair(List pairs) { + return pairs.stream() + .map(input -> input.pair) + .anyMatch(pair -> pair.containsAll(this.pair)); + } + @Override public String toString() { StringBuilder log = new StringBuilder(); diff --git a/src/main/java/pairmatching/repository/MatchingCrewRepository.java b/src/main/java/pairmatching/repository/MatchingCrewRepository.java index 817ccb9..f73600b 100644 --- a/src/main/java/pairmatching/repository/MatchingCrewRepository.java +++ b/src/main/java/pairmatching/repository/MatchingCrewRepository.java @@ -3,8 +3,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import pairmatching.domain.CourseInformation; import pairmatching.domain.Pair; +import pairmatching.domain.enums.Level; import pairmatching.exception.NoPariResultException; import pairmatching.message.ErrorMessage; @@ -38,4 +40,19 @@ public List findPairMatching(final CourseInformation courseInformation) { public void deleteAll() { store.clear(); } + + public boolean hasEqualMatchedCrew(final CourseInformation courseInformation, final List pairs) { + return store.keySet() + .stream() + .filter(key -> key.getLevel() == courseInformation.getLevel()) + .map(store::get) + .anyMatch(findPairs -> hasSameMatchedPair(findPairs, pairs)); + } + + private boolean hasSameMatchedPair(final List findPairs, final List pairs) { + return findPairs.stream() + .anyMatch(findPair -> findPair.containsPair(pairs)); + + } + } diff --git a/src/main/java/pairmatching/service/PairMatchingService.java b/src/main/java/pairmatching/service/PairMatchingService.java index 4bb2e85..62e1e4a 100644 --- a/src/main/java/pairmatching/service/PairMatchingService.java +++ b/src/main/java/pairmatching/service/PairMatchingService.java @@ -37,8 +37,7 @@ private List matchCrew(final CourseInformation courseInformation, final in } private boolean hasSamePairInList(final CourseInformation courseInformation, final List pairs) { -// matchingCrewRepository.find - return false; + return matchingCrewRepository.hasEqualMatchedCrew(courseInformation, pairs); } private void checkTryCount(final int matchTryCount) {