diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 000000000..6e86ed79a
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,66 @@
+미션 - 지하철 노선도 경로 조회 미션
+========================
+
+우아한테크코스 프리코스 온라인 테스트
+------------------------
+
+
+
+
+### 지하철 노선도 경로 조회 미션
+
+```
+목표 : 등록된 지하철 노선도에서 경로를 조회하는 기능을 구현한다.
+```
+
+
+
+
+***
+
+
+
+### 기능 구현 목록
+
+1. [x] 프로그램 시작 시 주어진 역, 노선, 구간 정보로 초기 설정을 한다.
+
+
+1. [x] 시작 화면을 출력 클래스에 구현한다.
+
+
+1. [x] 원하는 기능을 선택하는 화면을 구현한다.
+ - [예외사항] 사용자 입력이 주어진 선택지가 아닌 값으로 입력된다.(공백 포함)
+
+
+1. [X] 경로 기준을 선택하는 화면을 구현한다.
+
+
+1. [x] 출발역을 입력받는 화면을 구현한다.
+ - [예외사항] 출발역이 역 목록에 존재하지 않는다.
+
+
+1. [x] 도착역을 입력받는 화면을 구현한다.
+ - [예외사항] 도착역이 역 목록에 존재하지 않는다.
+ - [예외사항] 도착역이 입력받은 출발역과 같다.
+
+
+1. [x] 조회 결과를 출력하는 화면을 구현한다.
+
+
+1. [x] 거리를 기준으로 최단거리 경로를 연산하는 클래스를 구현한다.
+
+
+1. [x] 시간을 기준으로 최단시간 경로를 연산하는 클래스를 구현한다.
+
+
+
+
+
+
+***
+
+
+
+## 📝 License
+
+This project is [MIT](https://github.com/woowacourse/java-subway-path-precourse/blob/master/LICENSE.md) licensed.
diff --git a/src/main/java/subway/Application.java b/src/main/java/subway/Application.java
index 0bcf786cc..34b26e870 100644
--- a/src/main/java/subway/Application.java
+++ b/src/main/java/subway/Application.java
@@ -1,10 +1,13 @@
package subway;
import java.util.Scanner;
+import subway.Controller.SubwayRouteSearcher;
public class Application {
+
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
// TODO: 프로그램 구현
+ SubwayRouteSearcher.startProgram(scanner);
}
}
diff --git a/src/main/java/subway/Controller/Initializer.java b/src/main/java/subway/Controller/Initializer.java
new file mode 100644
index 000000000..3e71a5689
--- /dev/null
+++ b/src/main/java/subway/Controller/Initializer.java
@@ -0,0 +1,70 @@
+package subway.Controller;
+
+import java.util.Arrays;
+import java.util.List;
+import subway.domain.DistanceWeightRepository;
+import subway.domain.Line;
+import subway.domain.LineRepository;
+import subway.domain.Station;
+import subway.domain.StationRepository;
+import subway.domain.TimeWeightRepository;
+
+public class Initializer {
+
+ private static List INITIALSTATION = Arrays
+ .asList("교대역", "강남역", "역삼역", "남부터미널역", "양재역", "양재시민의숲역", "매봉역");
+ private static List INITIALLINE = Arrays.asList("2호선", "3호선", "신분당선");
+ private static List LINETWO = Arrays.asList("교대역", "강남역", "역삼역");
+ private static int[] LINETWOTIME = {2, 3};
+ private static int[] LINETWODISTANCE = {3, 3};
+ private static List LINETHREE = Arrays.asList("교대역", "남부터미널역", "양재역", "매봉역");
+ private static int[] LINETHREETIME = {3, 6, 1};
+ private static int[] LINETHREEDISTANCE = {2, 5, 1};
+ private static List LINESHINBUNDANG = Arrays.asList("강남역", "양재역", "양재시민의숲역");
+ private static int[] LINESHINBUNDANGTIME = {2, 10};
+ private static int[] LINESHINBUNDANGDISTANCE = {8, 3};
+ private static List> INITIALLINESTATION = Arrays
+ .asList(LINETWO, LINETHREE, LINESHINBUNDANG);
+
+ public static void setInitializeBaseSetting() {
+ setInitializeLine(INITIALLINE);
+ setInitializeStation(INITIALSTATION);
+ setInitialVertex(INITIALSTATION);
+ setInitialWeight(LINETWO, LINETWOTIME, LINETWODISTANCE);
+ setInitialWeight(LINETHREE, LINETHREETIME, LINETHREEDISTANCE);
+ setInitialWeight(LINESHINBUNDANG, LINESHINBUNDANGTIME, LINESHINBUNDANGDISTANCE);
+ }
+
+ private static void setInitializeStation(List INITIALSTATION) {
+ for (String stationName : INITIALSTATION) {
+ Station station = new Station(stationName);
+ StationRepository.addStation(station);
+ }
+ }
+
+ private static void setInitializeLine(List INITIALLINE) {
+ for (int i = 0; i < INITIALLINE.size(); i++) {
+ Line line = new Line(INITIALLINE.get(i));
+ line.addLineStation(INITIALLINESTATION.get(i));
+ LineRepository.addLine(line);
+ }
+ }
+
+ private static void setInitialVertex(List stationNames) {
+ for (String stationName : stationNames) {
+ TimeWeightRepository.addStation(stationName);
+ DistanceWeightRepository.addStation(stationName);
+ }
+ }
+
+ private static void setInitialWeight(List lineNumber, int[] timeWeight,
+ int[] distanceWeight) {
+ for (int i = 0; i < lineNumber.size() - 1; i++) {
+ TimeWeightRepository
+ .setStationEdgeTime(lineNumber.get(i), lineNumber.get(i + 1), timeWeight[i]);
+ DistanceWeightRepository
+ .setStationEdgeDistance(lineNumber.get(i), lineNumber.get(i + 1),
+ distanceWeight[i]);
+ }
+ }
+}
diff --git a/src/main/java/subway/Controller/MinDistanceCalculator.java b/src/main/java/subway/Controller/MinDistanceCalculator.java
new file mode 100644
index 000000000..c0e3a9b6f
--- /dev/null
+++ b/src/main/java/subway/Controller/MinDistanceCalculator.java
@@ -0,0 +1,21 @@
+package subway.Controller;
+
+import java.util.List;
+import java.util.Scanner;
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+import subway.Views.MainView;
+import subway.Views.OutputView;
+import subway.domain.DistanceWeightRepository;
+
+public class MinDistanceCalculator {
+
+ public static void calculateMinDistance(Scanner scanner) {
+ String startStation = MainView.printStartStation(scanner);
+ String endStation = MainView.printEndStation(scanner, startStation);
+
+ List result = DistanceWeightRepository
+ .getDijkstraShortestPath(startStation, endStation);
+ MainView.printResultScreen(scanner, result);
+ }
+}
diff --git a/src/main/java/subway/Controller/MinTimeCalculator.java b/src/main/java/subway/Controller/MinTimeCalculator.java
new file mode 100644
index 000000000..180ce407f
--- /dev/null
+++ b/src/main/java/subway/Controller/MinTimeCalculator.java
@@ -0,0 +1,18 @@
+package subway.Controller;
+
+import java.util.List;
+import java.util.Scanner;
+import subway.Views.MainView;
+import subway.Views.OutputView;
+import subway.domain.DistanceWeightRepository;
+
+public class MinTimeCalculator {
+
+ public static void calculateMinTime(Scanner scanner) {
+ String startStation = MainView.printStartStation(scanner);
+ String endStation = MainView.printEndStation(scanner, startStation);
+ List result =
+ DistanceWeightRepository.getDijkstraShortestPath(startStation, endStation);
+ MainView.printResultScreen(scanner, result);
+ }
+}
diff --git a/src/main/java/subway/Controller/SubwayRouteSearcher.java b/src/main/java/subway/Controller/SubwayRouteSearcher.java
new file mode 100644
index 000000000..be67effab
--- /dev/null
+++ b/src/main/java/subway/Controller/SubwayRouteSearcher.java
@@ -0,0 +1,30 @@
+package subway.Controller;
+
+import java.util.Scanner;
+import subway.Views.MainView;
+
+public class SubwayRouteSearcher {
+
+ public static void startProgram(Scanner scanner) {
+ Initializer.setInitializeBaseSetting();
+ MainView.printMainScreen(scanner);
+ }
+
+ public static void selectMain(Scanner scanner, String userMainSelection) {
+ if (userMainSelection.equals("1")) {
+ MainView.printRouteScreen(scanner);
+ }
+ }
+
+ public static void selectRoute(Scanner scanner, String userRouteSelection) {
+ if (userRouteSelection.equals("1")) {
+ MinDistanceCalculator.calculateMinDistance(scanner);
+ }
+ if (userRouteSelection.equals("2")) {
+ MinTimeCalculator.calculateMinTime(scanner);
+ }
+ if (userRouteSelection.equals("B")) {
+ MainView.printMainScreen(scanner);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/subway/Views/InputView.java b/src/main/java/subway/Views/InputView.java
new file mode 100644
index 000000000..58a301d5a
--- /dev/null
+++ b/src/main/java/subway/Views/InputView.java
@@ -0,0 +1,25 @@
+package subway.Views;
+
+import java.util.Scanner;
+
+public class InputView {
+
+ private final static String FUNCTIONSELECTION = "## 원하는 기능을 선택하세요.";
+ private final static String STARTSTATION = "## 출발역을 입력하세요.";
+ private final static String ENDSTATION = "## 도착역을 입력하세요.";
+
+ protected static String getUserInput(Scanner scanner) {
+ System.out.println(FUNCTIONSELECTION);
+ return scanner.nextLine();
+ }
+
+ protected static String getStartStation(Scanner scanner) {
+ System.out.println(STARTSTATION);
+ return scanner.nextLine();
+ }
+
+ protected static String getEndStation(Scanner scanner) {
+ System.out.println(ENDSTATION);
+ return scanner.nextLine();
+ }
+}
diff --git a/src/main/java/subway/Views/MainView.java b/src/main/java/subway/Views/MainView.java
new file mode 100644
index 000000000..d70e345c9
--- /dev/null
+++ b/src/main/java/subway/Views/MainView.java
@@ -0,0 +1,94 @@
+package subway.Views;
+
+import java.util.Arrays;
+import java.util.InputMismatchException;
+import java.util.List;
+import java.util.Scanner;
+import subway.Controller.SubwayRouteSearcher;
+import subway.utils.ErrorValidator;
+
+public class MainView {
+
+ private final static List MAINSELECTLIST = Arrays.asList("1", "Q");
+ private final static List ROUTESELECTLIST = Arrays.asList("1", "2", "B");
+
+ public static void printMainScreen(Scanner scanner) {
+ OutputView.printMainSelection();
+ String userMainSelection = InputView.getUserInput(scanner);
+ System.out.println();
+ checkUserInput(scanner, userMainSelection, MAINSELECTLIST);
+ SubwayRouteSearcher.selectMain(scanner, userMainSelection);
+ }
+
+ public static void printRouteScreen(Scanner scanner) {
+ OutputView.printRouteSelection();
+ String userRouteSelection = InputView.getUserInput(scanner);
+ System.out.println();
+ checkUserInput(scanner, userRouteSelection, ROUTESELECTLIST);
+ SubwayRouteSearcher.selectRoute(scanner, userRouteSelection);
+ }
+
+ public static void printResultScreen(Scanner scanner, List resultList) {
+ OutputView.printResultRoute(resultList);
+ System.out.println();
+ MainView.printMainScreen(scanner);
+ }
+
+
+ private static void checkUserInput(Scanner scanner, String userSelection,
+ List SELECTLIST) {
+ try {
+ ErrorValidator.checkMainSelection(SELECTLIST, userSelection);
+ } catch (InputMismatchException e) {
+ System.out.println(e.getMessage());
+ System.out.println();
+ printMainScreen(scanner);
+ }
+ }
+
+ public static String printStartStation(Scanner scanner) {
+ String startStaion = InputView.getStartStation(scanner);
+ System.out.println();
+ checkStartStation(scanner, startStaion);
+ return startStaion;
+ }
+
+ public static String printEndStation(Scanner scanner, String startStation) {
+ String endStaion = InputView.getEndStation(scanner);
+ System.out.println();
+ checkEndStation(scanner, endStaion);
+ checkStartEndStation(scanner, startStation, endStaion);
+ return endStaion;
+ }
+
+ private static void checkStartEndStation(Scanner scanner, String startStation,
+ String endStaion) {
+ try {
+ ErrorValidator.checkStartEndStation(startStation, endStaion);
+ } catch (InputMismatchException e) {
+ System.out.println(e.getMessage());
+ System.out.println();
+ printMainScreen(scanner);
+ }
+ }
+
+ private static void checkStartStation(Scanner scanner, String startStaion) {
+ try {
+ ErrorValidator.checkStationRepository(startStaion);
+ } catch (InputMismatchException e) {
+ System.out.println(e.getMessage());
+ System.out.println();
+ printMainScreen(scanner);
+ }
+ }
+
+ private static void checkEndStation(Scanner scanner, String endStaion) {
+ try {
+ ErrorValidator.checkStationRepository(endStaion);
+ } catch (InputMismatchException e) {
+ System.out.println(e.getMessage());
+ System.out.println();
+ printMainScreen(scanner);
+ }
+ }
+}
diff --git a/src/main/java/subway/Views/OutputView.java b/src/main/java/subway/Views/OutputView.java
new file mode 100644
index 000000000..6499743f5
--- /dev/null
+++ b/src/main/java/subway/Views/OutputView.java
@@ -0,0 +1,47 @@
+package subway.Views;
+
+import java.util.List;
+import java.util.Scanner;
+
+public class OutputView {
+
+ private final static String MAINSCREEN = "## 메인 화면";
+ private final static String ROUTESEARCHSELECTION = "1. 경로 조회";
+ private final static String PROGRAMEXIT = "Q. 종료";
+ private final static String ROUTESCREEN = "## 경로 기준";
+ private final static String MINDISTANCEROUTE = "1. 최단 거리";
+ private final static String MINTIMEROUTE = "2. 최소 시간";
+ private final static String BACKOPTION = "B. 돌아가기";
+ private final static String RESULTSCREEN = "## 조회 결과";
+ private final static String INFORMATION = "[INFO] ";
+ private final static String SPLITLINE = "---";
+ private final static String TOTALDISTANCE = "총 거리: %dkm";
+ private final static String TOTALTIME = "총 소요 시간: %d분";
+
+
+ protected static void printMainSelection() {
+ System.out.println(MAINSCREEN);
+ System.out.println(ROUTESEARCHSELECTION);
+ System.out.println(PROGRAMEXIT);
+ System.out.println();
+ }
+
+ protected static void printRouteSelection() {
+ System.out.println(ROUTESCREEN);
+ System.out.println(MINDISTANCEROUTE);
+ System.out.println(MINTIMEROUTE);
+ System.out.println(BACKOPTION);
+ System.out.println();
+ }
+
+ protected static void printResultRoute(List resultList) {
+ System.out.println(RESULTSCREEN);
+ System.out.println(INFORMATION + SPLITLINE);
+// System.out.println(String.format(INFORMATION + TOTALDISTANCE, totalDistance));
+// System.out.println(String.format(INFORMATION + TOTALTIME, totalTime));
+// System.out.println(INFORMATION + SPLITLINE);
+ for (String result : resultList) {
+ System.out.println(INFORMATION + result);
+ }
+ }
+}
diff --git a/src/main/java/subway/domain/DistanceWeightRepository.java b/src/main/java/subway/domain/DistanceWeightRepository.java
new file mode 100644
index 000000000..272fa0838
--- /dev/null
+++ b/src/main/java/subway/domain/DistanceWeightRepository.java
@@ -0,0 +1,28 @@
+package subway.domain;
+
+import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+
+import java.util.List;
+
+public class DistanceWeightRepository {
+
+ private static WeightedMultigraph distanceGraph = new WeightedMultigraph(
+ DefaultWeightedEdge.class);
+
+ public static void addStation(String station) {
+ distanceGraph.addVertex(station);
+ }
+
+ public static void setStationEdgeDistance(String startStation, String endStation,
+ int distance) {
+ distanceGraph.setEdgeWeight(distanceGraph.addEdge(startStation, endStation), distance);
+ }
+
+
+ public static List getDijkstraShortestPath(String startStation, String endStation) {
+ DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(distanceGraph);
+ return dijkstraShortestPath.getPath(startStation, endStation).getVertexList();
+ }
+}
diff --git a/src/main/java/subway/domain/Line.java b/src/main/java/subway/domain/Line.java
index f4d738d5a..4c5db2424 100644
--- a/src/main/java/subway/domain/Line.java
+++ b/src/main/java/subway/domain/Line.java
@@ -1,7 +1,12 @@
package subway.domain;
+import java.util.ArrayList;
+import java.util.List;
+
public class Line {
+
private String name;
+ private List lineStations = new ArrayList<>();
public Line(String name) {
this.name = name;
@@ -11,5 +16,10 @@ public String getName() {
return name;
}
- // 추가 기능 구현
+ public void addLineStation(List stationNames) {
+ for (String stationName : stationNames) {
+ Station station = new Station(stationName);
+ lineStations.add(station);
+ }
+ }
}
diff --git a/src/main/java/subway/domain/LineRepository.java b/src/main/java/subway/domain/LineRepository.java
index 2c4a723c9..17753c602 100644
--- a/src/main/java/subway/domain/LineRepository.java
+++ b/src/main/java/subway/domain/LineRepository.java
@@ -6,6 +6,7 @@
import java.util.Objects;
public class LineRepository {
+
private static final List lines = new ArrayList<>();
public static List lines() {
diff --git a/src/main/java/subway/domain/Station.java b/src/main/java/subway/domain/Station.java
index bdb142590..d9ea09d2c 100644
--- a/src/main/java/subway/domain/Station.java
+++ b/src/main/java/subway/domain/Station.java
@@ -1,6 +1,7 @@
package subway.domain;
public class Station {
+
private String name;
public Station(String name) {
@@ -10,6 +11,4 @@ public Station(String name) {
public String getName() {
return name;
}
-
- // 추가 기능 구현
}
diff --git a/src/main/java/subway/domain/StationRepository.java b/src/main/java/subway/domain/StationRepository.java
index 8ed9d103f..d3a7b6617 100644
--- a/src/main/java/subway/domain/StationRepository.java
+++ b/src/main/java/subway/domain/StationRepository.java
@@ -6,6 +6,7 @@
import java.util.Objects;
public class StationRepository {
+
private static final List stations = new ArrayList<>();
public static List stations() {
@@ -23,4 +24,13 @@ public static boolean deleteStation(String name) {
public static void deleteAll() {
stations.clear();
}
+
+ public static boolean checkStation(String stationName) {
+ for (Station station : stations) {
+ if (station.getName().equals(stationName)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/src/main/java/subway/domain/TimeWeightRepository.java b/src/main/java/subway/domain/TimeWeightRepository.java
new file mode 100644
index 000000000..92deef6f8
--- /dev/null
+++ b/src/main/java/subway/domain/TimeWeightRepository.java
@@ -0,0 +1,27 @@
+package subway.domain;
+
+import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+
+import java.util.List;
+
+public class TimeWeightRepository {
+
+ private static WeightedMultigraph timeGraph = new WeightedMultigraph(
+ DefaultWeightedEdge.class);
+
+ public static void addStation(String station) {
+ timeGraph.addVertex(station);
+ }
+
+ public static void setStationEdgeTime(String startStation, String endStation, int time) {
+ timeGraph.setEdgeWeight(timeGraph.addEdge(startStation, endStation), time);
+
+ }
+
+ public static List getDijkstraShortestPath(String startStation, String endStation) {
+ DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(timeGraph);
+ return dijkstraShortestPath.getPath(startStation, endStation).getVertexList();
+ }
+}
diff --git a/src/main/java/subway/utils/ErrorValidator.java b/src/main/java/subway/utils/ErrorValidator.java
new file mode 100644
index 000000000..fe9e49fb0
--- /dev/null
+++ b/src/main/java/subway/utils/ErrorValidator.java
@@ -0,0 +1,31 @@
+package subway.utils;
+
+import java.util.InputMismatchException;
+import java.util.List;
+import subway.domain.StationRepository;
+
+public class ErrorValidator {
+
+ private final static String ERRORMESSAGE = "[ERROR] ";
+ private final static String WRONGUSERINPUT = "잘못된 입력입니다.";
+ private final static String WRONGSTATIONNAME = "존재하지 않는 역 이름입니다.";
+ private final static String SAMESTATIONNAME = "출발역과 도착역이 동일합니다.";
+
+ public static void checkMainSelection(List MAINSELECTLIST, String userSelection) {
+ if (!MAINSELECTLIST.contains(userSelection)) {
+ throw new InputMismatchException(ERRORMESSAGE + WRONGUSERINPUT);
+ }
+ }
+
+ public static void checkStationRepository(String stationName) {
+ if (!StationRepository.checkStation(stationName)) {
+ throw new InputMismatchException(ERRORMESSAGE + WRONGSTATIONNAME);
+ }
+ }
+
+ public static void checkStartEndStation(String startStation, String endStaion) {
+ if (startStation.equals(endStaion)) {
+ throw new InputMismatchException(ERRORMESSAGE + SAMESTATIONNAME);
+ }
+ }
+}