-
Notifications
You must be signed in to change notification settings - Fork 3
[자동차 경주] 남지윤 미션 제출합니다. #1
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
base: main
Are you sure you want to change the base?
Changes from all commits
8e0bf94
413418c
bf169b9
2a56c56
e7779bc
160ddd3
2aa0734
7dd7c23
aeb0919
ff72716
67da152
ca40960
20a4f80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,59 @@ | ||
| # javascript-racingcar-precourse | ||
| # 2주차 미션 : 자동차 경주🚗 | ||
|
|
||
| ## Todo List | ||
| - ✅ 입력 | ||
| - 문자열 입력 기능 | ||
| - 숫자 입력 기능 | ||
|
|
||
| - ✅ 전처리 | ||
| - 쉼표를 기준으로 이름을 구분 | ||
|
|
||
| - ✅ 전진/멈춤할지 고르기 | ||
| - 입력받은 시도 횟수만큼 반복 | ||
| - 0-9 사이 무작위값 받기 | ||
| - 전진(4 이상) / 멈춤 (그 외) | ||
|
|
||
| - ✅ 우승자 고르기 | ||
| - 전진한 횟수 비교 | ||
|
|
||
| - ✅ 예외처리 | ||
| - 입력 오류 : 이름이 잘못 입력된 경우 | ||
| - 입력 오류 : 몇 번 이동할 것인지 입력하는 것이 숫자가 아닌 경우 | ||
| - 입력 처리 : 이름 양쪽 공백은 삭제한다. 즉, '지윤' = ' 지윤 ' | ||
| - 예외 처리 : 이름이 중복되는 경우, 한 사람으로 처리한다. | ||
|
|
||
| - ✅ 리펙토링 | ||
| - MVC 패턴... | ||
| - 복잡한 코드 흐름 개선 | ||
|
|
||
| ## 코드 흐름 | ||
| 1. "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)" 출력 후 입력 대기 | ||
| 2. "시도할 횟수는 몇 회인가요?" 출력 후 입력 대기 | ||
| 3. 문자열 전처리 | ||
| a. ','기준으로 나누기 | ||
| b. 문자열 양 옆 공백 지우기 | ||
| + 예외처리 : 중복제거, 잘못된 입력 오류 처리 | ||
| 4. 경주 시작 | ||
| a. 랜덤값으로 전진/멈춤 고르기 | ||
| b. 전진 수 저장 | ||
| c. n번 반복 | ||
| 5. 실행 결과 출력 | ||
| a. 저장된 전진 수 만큼 '-'를 반복 출력 | ||
| b. n번 반복 | ||
| 6. 우승자 결정 및 출력 | ||
| a. 전진 수 비교 | ||
| b. 우승자 저장 | ||
|
|
||
| ## MVC 패턴 | ||
| src/ | ||
| │ | ||
| ├── App.js # Controller (App 클래스) | ||
| ├── Model.js # Model (Car, Racing 클래스) | ||
| ├── View.js # View (출력 및 사용자 인터페이스 담당) | ||
| └── index.js # 애플리케이션 시작점 | ||
|
|
||
| ### Model (Data) - Car, Racing | ||
| ### View (UI) - Console 입출력 | ||
| ### Controller (Interface) - App | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,29 @@ | ||
| import { Racing } from './Model.js'; | ||
| import View from './View.js'; | ||
|
|
||
| class App { | ||
| async run() {} | ||
| async run() { | ||
| try { | ||
| const racing = new Racing(); | ||
|
|
||
| const inputName = await View.readLine("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분): "); | ||
| const nameArray = racing.validateCarNames(inputName); | ||
|
|
||
| const inputNum = await View.readLine("시도할 횟수는 몇 회인가요?: "); | ||
| if (isNaN(inputNum) || inputNum <= 0) { | ||
| throw new Error("[ERROR] IllegalArgumentException"); | ||
| } | ||
|
|
||
| View.print('실행 결과'); | ||
| const results = racing.advanceCount(nameArray, inputNum); | ||
| View.printResults(results); | ||
| View.printWinner(racing.getWinner()); | ||
|
|
||
| } catch (error) { | ||
| View.printError(error.message); | ||
| return Promise.reject(error); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export default App; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { Random } from "@woowacourse/mission-utils"; | ||
|
|
||
| class Car { | ||
| constructor(name) { | ||
| this.name = name; | ||
| this.count = 0; | ||
| } | ||
|
|
||
| // 전진 조건을 적용하는 메서드 | ||
| move() { | ||
| if (Random.pickNumberInRange(0, 9) >= 4) { | ||
| this.count++; | ||
| } | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 만약 가독성, 유지보수 측면을 더 고려할 수 있다면 |
||
|
|
||
| // 자동차 상태 출력 | ||
| print() { | ||
| return `${this.name} : ${'-'.repeat(this.count)}`; | ||
| } | ||
| } | ||
|
|
||
| class Racing { | ||
| constructor() { | ||
| this.carInstances = []; | ||
| } | ||
|
|
||
| // 쉼표 기준 분리 | 공백 처리 | 5자 이하 처리 | 중복 처리 | ||
| validateCarNames(names) { | ||
| return [...new Set(names.split(",") | ||
| .map(name => name.trim()) | ||
| .filter(name => name && name.length <= 5))]; | ||
| } | ||
|
|
||
| // 전진 카운트 | ||
| advanceCount(nameArray, num) { | ||
| // 인스턴스화 | ||
| this.carInstances = nameArray.map(name => new Car(name)); | ||
|
|
||
| const result = []; | ||
| for (let i = 0; i < num; i++) { | ||
| result.push(this.carInstances.map(car => { | ||
| car.move(); | ||
| return car.print(); | ||
| })); | ||
| } | ||
| return result; | ||
| } | ||
| getWinner() { | ||
| // 가장 큰 값 찾기 | ||
| const maxCount = Math.max(...this.carInstances.map(car => car.count)); | ||
| // 가장 큰 값과 같은 값을 가진 CarName 만 추출 | ||
| return this.carInstances.filter(car => car.count === maxCount).map(car => car.name); | ||
| } | ||
| } | ||
|
|
||
| export { Car, Racing }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { Console } from "@woowacourse/mission-utils"; | ||
|
|
||
| class View { | ||
| static print(message) { | ||
| Console.print(message); | ||
| } | ||
|
|
||
| static async readLine(message) { | ||
| return await Console.readLineAsync(message); | ||
| } | ||
|
|
||
| static printResults(results) { | ||
| results.forEach(result => { | ||
| result.forEach(carOutput => { | ||
| View.print(carOutput); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| static printWinner(winner) { | ||
| View.print(`최종 우승자 : ${winner.join(', ')}`); | ||
| } | ||
|
|
||
| static printError(message) { | ||
| View.print(message); | ||
| } | ||
| } | ||
|
|
||
| export default View; | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MVC 패턴으로 깔끔하게 구분하셔서 좋은 것 같습니다 |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 테스트 코드를 작성한다는 게 무슨 뜻인지 몰랐는데 이렇게 하는거군요,,,
참고하겠습니다