Skip to content
Open
90 changes: 89 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,89 @@
# javascript-subway-final
# 🚇 지하철 노선도 경로 조회 미션
- 등록된 지하철 노선도에서 경로를 조회하는 기능을 구현한다.

## 🚀 기능 요구사항
> 프리코스 3주차 미션에서 사용한 코드를 참고해도 무관하다.

### 초기 설정
- 프로그램 시작 시 역, 노선, 구간 데이터를 초기 설정 해야 한다.
- 거리와 소요 시간은 양의 정수이며 단위는 km와 분을 의미한다.
- 아래의 사전 등록 정보로 반드시 초기 설정을 한다.

```
1. 지하철역으로 교대, 강남, 역삼, 남부터미널, 양재, 양재시민의숲, 매봉 역 정보가 등록되어 있다.
2. 지하철 노선으로 2호선, 3호선, 신분당선이 등록되어 있다.
3. 노선에 역이 아래와 같이 등록되어 있다.(왼쪽 끝이 상행 종점)
- 2호선: 교대 - ( 2km / 3분 ) - 강남 - ( 2km / 3분 ) - 역삼
- 3호선: 교대 - ( 3km / 2분 ) - 남부터미널 - ( 6km / 5분 ) - 양재 - ( 1km / 1분 ) - 매봉
- 신분당선: 강남 - ( 2km / 8분 ) - 양재 - ( 10km / 3분 ) - 양재시민의숲
```

### 경로 조회 기능
<img src="/images/path_result.jpg" width="100%">

- 출발역과 도착역을 입력받아 경로를 조회한다.
- 경로 조회 시 총 거리, 총 소요 시간을 함께 출력한다.
- 경로 조회 시 `최단 거리` 또는 `최소 시간` 옵션을 선택할 수 있다.

### 예외 처리
- 출발역과 도착역은 2글자 이상이어야 한다.
- 존재하지 않는 역을 출발역 또는 도착역으로 입력할 수 없다.
- 경로 조회 시 출발역과 도착역이 같을 수 없다.
- 경로 조회 시 출발역과 도착역이 연결되지 않으면 경로를 조회할 수 없다.
- 그 외 정상적으로 프로그램이 수행되지 않은 경우 `alert`으로 에러를 출력한다.

<br>

## 💻 프로그래밍 실행 결과
### 경로 조회
<img src="/images/path_result.gif" width="100%">


## ✅ 프로그래밍 요구사항
### 길찾기 관련 기능
- 출발역을 입력하는 input 태그는 `departure-station-name-input` id 속성값을 가진다.
- 도착역을 입력하는 input 태그는 `arrival-station-name-input` id 속성값을 가진다.
- 최단거리, 최소시간을 선택하는 radio는 `search-type` name 속성값을 가진다.
- **radio option의 default 값은 최단거리이다.**
- 길찾기 버튼은 `search-button` id 속성값을 가진다.
- 📝 결과는 `table`을 이용하여 보여준다.


### 요구사항
- 사용자가 잘못된 입력 값을 작성한 경우 `alert`을 이용해 메시지를 보여주고, 재입력할 수 있게 한다.
- 외부 라이브러리(jQuery, Lodash 등)를 사용하지 않고, 순수 Vanilla JS로만 구현한다.
- **자바스크립트 코드 컨벤션을 지키면서 프로그래밍** 한다
- [https://google.github.io/styleguide/jsguide.html](https://google.github.io/styleguide/jsguide.html)
- [https://ui.toast.com/fe-guide/ko_CODING-CONVENSION/](https://ui.toast.com/fe-guide/ko_CODING-CONVENTION)
- **indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용**한다.
- 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
- 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다.
- **함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.**
- 함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다.
- 변수 선언시 [var](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/var) 를 사용하지 않는다. [const](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/const) 와 [let](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let) 을 사용한다.
- [import](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import) 문을 이용해 스크립트를 모듈화하고 불러올 수 있게 만든다.
- [template literal](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals)을 이용해 데이터와 html string을 가독성 좋게 표현한다.

<br/>

## 📝 미션 저장소 및 진행 요구사항

- 미션은 [https://github.com/woowacourse/javascript-subway-path-precourse](https://github.com/woowacourse/javascript-subway-path-precourse) 저장소를 fork/clone해 시작한다.
- **기능을 구현하기 전에 javascript-subway-path-precourse/docs/README.md 파일에 구현할 기능 목록**을 정리해 추가한다.
- **git의 commit 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위로 추가**한다.
- [프리코스 과제 제출](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 문서 절차를 따라 미션을 제출한다.

## 구현할 기능 목록 단위

- 교대~매봉역, 노선, 거리 및 소요시간 정보를 사전 등록하고 export 한다.
- 교대~매봉역, 노선, 거리 및 소요시간 정보를 import 한다.
- 브라우저에 출발역과 도착역을 입력할 수 있다.
- 입력된 역이 두 자리 미만이면 경고창을 띄운다.
- 입력된 역이 사전 저장된 데이터에 없는 역이면 경고창을 띄운다.
- 출발역과 도착역이 같으면 경고창을 띄운다.
- 검색시 최단거리와 최소시간중 하나를 선택할 수 있다.
- 둘중 default 값은 최단거리로 설정한다.
- 출발역과 도착역의 최단거리를 계산한다.
- 출발역에서 도착역까지의 최소시간을 계산한다.
- 길 찾기 버튼을 누르면 결과가 출력된다.
- 결과는 총 거리, 총 소요시간, 총 노선을 테이블로 표시한다.
Binary file added images/dijkstra_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/path_result.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/path_result.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>🚇지하철 길찾기</title>
</head>
<body>
<h1>🚇지하철 길찾기</h1>
<div id="app">
<div>
출발역 <input type="text" id="departure-station-name-input"></input><br />
도착역 <input type="text" id="arrival-station-name-input"></input><br /><br />
<input type="radio" name="search-type" checked>최단거리</input>
<input type="radio" name="search-type">최소시간</input><br /><br />
</div>
<div>
<button id="search-route">길 찾기</button>
</div>
<div id="result" style="display:none">
<h2>📝결과</h2>
<div id="print-result-container"></div>

</div>
</div>
<script type="module" src="src/index.js"></script>
</body>
</html>
58 changes: 58 additions & 0 deletions src/data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export const lineTwo = [
{
station : '교대',
distance : 2,
time : 3
},
{
station : '강남',
distance : 2,
time : 3
},
{
station : '역삼',
distance : 0,
time : 0
}
]

export const lineThree = [
{
station : '교대',
distance : 3,
time : 2
},
{
station : '남부터미널',
distance : 6,
time : 5
},
{
station : '양재',
distance : 1,
time : 1
},
{
station : '매봉',
distance : 0,
time : 0
}
]

export const lineBoondang = [
{
station : '강남',
distance : 2,
time : 8
},
{
station : '양재',
distance : 10,
time : 3
},
{
station : '양재시민의숲',
distance : 0,
time : 0
}
]
73 changes: 73 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { lineTwo, lineThree, lineBoondang } from "./data.js";
import Dijkstra from "./utils/Dijkstra.js";
import {isUnderTwoCharacters} from "./validation.js";

let findRouteButton = document.getElementById('search-route');
findRouteButton.addEventListener('click', showResult);

function showResult() {
isUnderTwoCharacters();
document.getElementById("result").style.display="block";
}

export function findData(departureStation, arrivalStation) {
let v1 = '', v2 = '', v3 = '';
let distance = 0, time = 0;
let indexOfDeparture = 0;
let indexOfArrival = 0;
for (let i = 0; i < lineTwo.length; i += 1) {
if (departureStation === lineTwo[i].station) {
v1 = lineTwo[i].station;
distance += lineTwo[i].distance;
time += lineTwo[i].time;
indexOfDeparture = lineTwo.indexOf(lineTwo[i]);
}
if (arrivalStation === lineTwo[i].station) {
v3 = lineTwo[i].station;
indexOfArrival = lineTwo.indexOf(lineTwo[i]);
}
if (indexOfDeparture - indexOfArrival > 1) {
v2 = lineTwo[i-1].station;
distance += lineTwo[i].distance;
time += lineTwo[i].time;
}
}
getShortestPath(v1, v2, v3, distance, time);
}

function getShortestPath(v1, v2, v3, distance, time) {
let dijkstra = new Dijkstra();
dijkstra.addEdge(v1, v2, lineTwo[0].distance);
dijkstra.addEdge(v2, v3, lineTwo[1].distance);
dijkstra.addEdge(v1, v3, lineTwo[0].distance + lineTwo[1].distance);
const shortestPathOfDistance = dijkstra.findShortestPath(v1,v3);

dijkstra.addEdge(v1, v2, lineTwo[0].time);
dijkstra.addEdge(v2, v3, lineTwo[1].time);
dijkstra.addEdge(v1, v3, lineTwo[0].time + lineTwo[1].time);
const shortestPathOfTime = dijkstra.findShortestPath(v1,v3);

makeTable(distance, time, shortestPathOfDistance, shortestPathOfTime);
}


function makeTable( distance, time, shortestPathOfDistance) {
let container = document.getElementById('print-result-container');
let resultTable = document.createElement('table');
let headerRow = resultTable.insertRow(0);
let firstRow = resultTable.insertRow(1);
let secondRow = resultTable.insertRow(2);
let headerCell1 = headerRow.insertCell(0);
let headerCell2 = headerRow.insertCell(1);
let firstRowCell1 = firstRow.insertCell(0);
let firstRowCell2 = firstRow.insertCell(1);
let secondRowCell1 = secondRow.insertCell(0);
headerCell1.innerHTML = '총 거리';
headerCell2.innerHTML = '총 소요 시간';
firstRowCell1.innerHTML = `${distance}km`;
firstRowCell2.innerHTML = `${time}분`;
secondRowCell1.innerHTML = `${shortestPathOfDistance}`;
resultTable.border = 1;
resultTable.id = 'print-result-table';
container.appendChild(resultTable);
}
Loading