Skip to content

최현식 멸망 #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@

# 페어매칭

## 동작순서
1. 프로그램 시작
2. 기능 선택
1. 페어매칭
1. 대상 입력 (과정, 레벨, 미션)
2. 이미있는지 저장소 확인
1. 이미있는경우 다시 시도할지 입력
3. 페어매칭 동작
4. 페어매칭 결과 저장
5. 페어매칭 결과 출력
2. 페어조회
1. 대상 입력 (과정, 레벨, 미션)
2. 페어매칭 결과 출력
3. 페어초기화
1. 전체 페어매칭 내용 제거
4. 종료
1. 프로그램 종료

### 도메인 설명
- 과정은 백엔드 과정과 프론트엔드 과정이 있다.
- 각 과정은 5단계로 나누어 진행이 되는데 이를 레벨이라고 한다.
- 같은 레벨 동안은 같은 페어를 만나지 않는다.
```json
## 과정
- 백엔드
- 프론트엔드

## 레벨
- 레벨1
- 레벨2
- 레벨3
- 레벨4
- 레벨5

## 미션
### 레벨1
- 자동차경주
- 로또
- 숫자야구게임

### 레벨2
- 장바구니
- 결제
- 지하철노선도

### 레벨3(없음)

### 레벨4
- 성능개선
- 배포

### 레벨5 (없음)
```

## 기능목록
### Controller

### InputView
- [ ] 동작할 커맨드를 읽는 기능
- [ ] 코스 레벨 미션 명을 읽는 기능
- [ ] 리매칭 여부를 읽는 기능

### OutputView

### Util/JavaFileReader
- 파일을 한줄씩 읽는다.

### MatchingSystem
- 페어매칭
- 미션을 함께 수행할 페어를 두명씩 매칭한다.
- 페어 매칭 대상이 홀수인 경우 한 페어는 3인으로 구성한다.
- 같은 레벨에서 이미 페어를 맺은 크루와는 다시 페어로 매칭될 수 없다.
- 페어매칭 동작 순서
- 크루들의 이름 목록을 List<String> 형태로 준비한다.
- 크루 목록의 순서를 랜덤으로 섞는다. 이 때 `camp.nextstep.edu.missionutils.Randoms`의 shuffle 메서드를 활용해야 한다.
- 랜덤으로 섞인 페어 목록에서 페어 매칭을 할 때 앞에서부터 순서대로 두명씩 페어를 맺는다.
- 홀수인 경우 마지막 남은 크루는 마지막 페어에 포함시킨다.
- 같은 레벨에서 이미 페어로 만난적이 있는 크루끼리 다시 페어로 매칭 된다면 크루 목록의 순서를 다시 랜덤으로 섞어서 매칭을 시도한다.
- 3회 시도까지 매칭이 되지 않거나 매칭을 할 수 있는 경우의 수가 없으면 에러 메시지를 출력한다.
- 페어 재매칭 시도
- 안내 문구를 출력 후 매칭을 진행한다.
- 아니오를 선택할 경우 코스, 레벨, 미션을 다시 선택한다.
- 페어 조회 기능
- 과정, 레벨, 미션을 선택하면 해당 미션의 페어 정보를 출력한다.
- 매칭 이력이 없으면 매칭 이력이 없다고 안내한다.
- 페어 초기화
- 종료

### Repository

### Domain
- Course
- Level
- Crew
5 changes: 4 additions & 1 deletion src/main/java/pairmatching/Application.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package pairmatching;

import pairmatching.controller.MatchingController;

public class Application {
public static void main(String[] args) {
// TODO 구현 진행

MatchingController matchingController = new MatchingController();
matchingController.system();
}
}
102 changes: 102 additions & 0 deletions src/main/java/pairmatching/controller/MatchingController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package pairmatching.controller;

import pairmatching.domain.MatchingSystem;
import pairmatching.domain.type.*;
import pairmatching.view.InputView;
import pairmatching.view.OutputView;

import java.util.List;

public class MatchingController {
MatchingSystem matchingSystem = new MatchingSystem();

public void system() {
while (true) {
Command command = readCommand();
if (command == Command.MATCHING) {
matching();
}
if (command == Command.SELECT) {
select();
}
if (command == Command.RESET) {
reset();
}
if (command == Command.QUIT) {
break;
}
}
}

private void matching() {
CourseLevelMission clmDto = readCourseLevelMission();
try {
newMatching(clmDto);
}
catch(IllegalStateException e) {
if (readRematching()) {
reset();
newMatching(clmDto);
}
}
}

private void newMatching(CourseLevelMission clmDto) {
matchingSystem.matching(clmDto);
List<Pair> pairs = findPairsByClm(clmDto);
OutputView.printMatchingResult(pairs);
}

private void select() {
CourseLevelMission clmDto = readCourseLevelMission();
List<Pair> pairs = findPairsByClm(clmDto);
if (pairs.isEmpty()) {
OutputView.printError("아직 매칭 내용이 없습니다.");
}
if (!pairs.isEmpty()) {
OutputView.printMatchingResult(pairs);
}
}

private void reset() {
matchingSystem.reset();
OutputView.printResetDone();
}

private List<Pair> findPairsByClm(CourseLevelMission clmDto) {
return matchingSystem.select(clmDto);
}

private Command readCommand() {
while (true) {
try {
OutputView.printSelectCommand();
return InputView.readCommand();
} catch (IllegalArgumentException e) {
OutputView.printError(e.toString());
}
}
}

private CourseLevelMission readCourseLevelMission() {
while (true) {
try {
OutputView.printCourseLevelMission();
return InputView.readCourseLevelMission();
} catch (IllegalArgumentException e) {
OutputView.printError(e.toString());
}
}
}

private boolean readRematching() {
while (true) {
try {
OutputView.printRetry();
return InputView.readRematching();
} catch (IllegalArgumentException e) {
OutputView.printError(e.toString());
}
}
}
}
55 changes: 55 additions & 0 deletions src/main/java/pairmatching/domain/MatchingSystem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package pairmatching.domain;

import camp.nextstep.edu.missionutils.Randoms;
import pairmatching.domain.type.CourseLevelMission;
import pairmatching.domain.type.Mission;
import pairmatching.domain.type.Pair;
import pairmatching.repository.CrewRepository;
import pairmatching.repository.PairRepository;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MatchingSystem {
private final CrewRepository crewRepository = new CrewRepository();
private final PairRepository pairRepository = new PairRepository();

public void matching(CourseLevelMission clmDto) {
checkAlreadyMission(clmDto.getMission());

List<String> crewNames = crewRepository.getCrew(clmDto.getCourse());
List<String> shuffledCrew = Randoms.shuffle(crewNames);

for (Pair pair : groupingPairs(clmDto, shuffledCrew)) {
pairRepository.create(pair);
}
}

private void checkAlreadyMission(Mission mission) {
if (pairRepository.isHaveMission(mission)) {
throw new IllegalStateException("이 미션은 이미 페어매칭 동작햇습니다~~ " + mission.toString());
}
}

private List<Pair> groupingPairs(CourseLevelMission clmDto, List<String> shuffledCrew) {
List<Pair> result = new ArrayList<>();
List<String> queue = new ArrayList<>();
for(String name : shuffledCrew) {
queue.add(name);
if (queue.size() == 2) {
result.add(new Pair(clmDto, queue));
queue.clear();
}
}
return result;
}

public List<Pair> select(CourseLevelMission clmDto) {
return pairRepository.findPairsByClm(clmDto);
}

public void reset() {
pairRepository.deleteAll();
}
}
19 changes: 19 additions & 0 deletions src/main/java/pairmatching/domain/ReadCrewFile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package pairmatching.domain;

import pairmatching.util.JavaFileReader;

import java.util.List;

public class ReadCrewFile {
private static final String RESOURCE_PATH = "src/main/resources/";
private static final String BACKEND_PATH = RESOURCE_PATH + "backend-crew.md";
private static final String FRONTEND_PATH = RESOURCE_PATH + "frontend-crew.md";

public static List<String> readBackendCrew() {
return JavaFileReader.getLinesFromFile(BACKEND_PATH);
}

public static List<String> readFrontendCrew() {
return JavaFileReader.getLinesFromFile(FRONTEND_PATH);
}
}
28 changes: 28 additions & 0 deletions src/main/java/pairmatching/domain/type/Command.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package pairmatching.domain.type;

import java.util.Arrays;
import java.util.Objects;

public enum Command {
MATCHING("1"),
SELECT("2"),
RESET("3"),
QUIT("Q");

private final String command;

Command(String command) {
this.command = command;
}

public static Command of(String command) {
return Arrays.stream(Command.values())
.filter(c -> Objects.equals(c.getCommand(), command))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("일치하는 커맨드가 없습니다. " + command));
}

private String getCommand() {
return command;
}
}
30 changes: 30 additions & 0 deletions src/main/java/pairmatching/domain/type/Course.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package pairmatching.domain.type;

import java.util.Arrays;
import java.util.Objects;

public enum Course {
BACKEND("백엔드"),
FRONTEND("프론트엔드");

private String name;

Course(String name) {
this.name = name;
}

public static Course of(String name) {
return Arrays.stream(Course.values())
.filter(course -> Objects.equals(course.getName(), name))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("course 값이 잘못되었씁니다. " + name));
}

public boolean isBackend() {
return this == BACKEND;
}

private String getName() {
return name;
}
}
43 changes: 43 additions & 0 deletions src/main/java/pairmatching/domain/type/CourseLevelMission.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package pairmatching.domain.type;

public class CourseLevelMission {
Course course;
Level level;
Mission mission;

public CourseLevelMission(Course course, Level level, Mission mission) {
this.course = course;
this.level = level;
this.mission = mission;
}

// TODO too many lines
public CourseLevelMission(String input) {
int i = 0;
for (String s : input.split(",")) {
s = s.trim();
if (i == 0) {
course = Course.of(s);
}
if (i == 1) {
level = Level.of(s);
}
if (i == 2) {
mission = Mission.of(s);
}
i++;
}
}

public Course getCourse() {
return course;
}

public Level getLevel() {
return level;
}

public Mission getMission() {
return mission;
}
}
Loading