Skip to content
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

[자동차 경주 게임] 김은지 미션 제출합니다. #437

Open
wants to merge 5 commits 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
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
# javascript-racingcar-precourse
# 🏎️ 자동차 경주 게임 기능 목록

### 1️⃣ 사용자 입력 기능
- [ ] `경주할 자동차의 이름` 은 2자 이상 5자 이하로 입력받는다. 자동차는 최대 5대 입력받을 수 있다.
- [ ] `시도할 횟수` 는 1회 이상 10회 이하로 입력받는다.

#### 🚨 예외 처리
- [ ] 자동차 이름 입력 시 빈 문자열이 입력될 경우 `[ERROR] 자동차 이름을 이름을 입력하세요.` 라는 에러 메시지를 출력하고 애플리케이션을 종료한다.
- [ ] 자동차 개수가 1대 미만이거나 5대 초과일 경우 `[ERROR] 자동차 개수는 1대 이상 5대 이하이어야 합니다.` 라는 에러 메시지를 출력하고 애플리케이션을 종료한다.
- [ ] 자동차 이름이 5자 초과일 경우 `[ERROR] 자동차 이름은 2자 이상 5자 이하로 입력해야 합니다.` 라는 에러 메시지를 출력하고 애플리케이션을 종료한다.
- [ ] 시도할 횟수가 숫자가 아니거나 음수이거나 10을 초과할 경우 `[ERROR] 시도 횟수는 1회 이상 10회 이하의 숫자로 입력해야 합니다.` 라는 에러 메시지를 출력하고 애플리케이션을 종료한다.

### 2️⃣ 시도할 횟수 만큼 랜덤으로 숫자 추첨
- [ ] 시도할 횟수 만큼 반복하여 `@woowacourse/mission-utils` 에서 제공하는 `Random.pickNumberInRange()` 를 활용하여 각 자동차마다 0부터 9 사이의 랜덤 숫자를 추첨한다.

### 3️⃣ 자동차 전진 처리
- [ ] 랜덤 숫자가 4 이상일 경우 해당 자동차의 위치에 "-"를 추가하여 전진을 나타낸다.

### 4️⃣ 결과 출력 기능
- [ ] 시도할 횟수만큼 모든 시도가 끝난 후 각 `차수별 실행 결과` 를 출력한다.
- [ ] 가장 많은 "-"를 기록한 자동차를 `최종 우승자 : ` 형식으로 결과를 출력한다. 우승자가 여러 명일 경우 쉼표(,)로 구분한다.
15 changes: 13 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import Input from './io-system/input';
import Output from "./io-system/output";
import Race from './Race';

class App {
async run() {}
async run() {
const { carNames, attempts } = await Input();

const race = new Race(carNames, attempts);
const { winners, currentPositions } = race.play();

Output(winners, currentPositions);
}
}

export default App;
export default App;
14 changes: 14 additions & 0 deletions src/Car.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Car {
constructor(name) {
this.name = name;
this.position = 0;
}

move(isMoving) {
if (isMoving) {
this.position += 1;
}
}
}

export default Car;
38 changes: 38 additions & 0 deletions src/Race.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { moveCar } from './utils/moveCar';
import Car from './Car';

export default class Race {
constructor(carNames, attempts) {
this.cars = carNames.map(name => new Car(name));
this.attempts = attempts;
}

play() {
const currentPositions = [];

for (let i = 0; i < this.attempts; i++) {
this.cars.forEach(car => {
const isMoving = moveCar();
car.move(isMoving);
});
const positions = this.printCurrentPositions();
currentPositions.push(...positions);
}

return {
winners: this.getWinners(),
currentPositions
};
}

printCurrentPositions() {
return this.cars.map(car => {
return `${car.name} : ${'-'.repeat(car.position)}`;
});
}

getWinners() {
const maxPosition = Math.max(...this.cars.map(car => car.position));
return this.cars.filter(car => car.position === maxPosition).map(car => car.name);
}
}
13 changes: 13 additions & 0 deletions src/constants/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const IO_MESSAGE = Object.freeze({
INPUT_CARNAME: '경주할 자동차 이름을 입력하세요. (이름은 쉼표(,) 기준으로 구분)\n',
INPUT_ATTEMPTS: '시도할 횟수는 몇 회인가요?\n',
OUTPUT_RESULT: '실행 결과',
OUTPUT_WINNER: '최종 우승자 :',
});

export const ERROR_MESSAGE = Object.freeze({
ERROR_EMPTY_CAR_NAME: '[ERROR] 자동차 이름을 입력하세요. (최소 1개, 최대 5개 입력 가능)',
ERROR_INVALID_CAR_COUNT: '[ERROR] 자동차 개수는 1대 이상 5대 이하이어야 합니다.',
ERROR_CAR_NAME_LENGTH: '[ERROR] 자동차 이름은 2자 이상 5자 이하로 입력해야 합니다.',
ERROR_INVALID_ATTEMPTS: '[ERROR] 시도 횟수는 1회 이상 10회 이하의 숫자로 입력해야 합니다.',
});
33 changes: 33 additions & 0 deletions src/io-system/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Console } from "@woowacourse/mission-utils";
import { ERROR_MESSAGE, IO_MESSAGE } from '../constants/message';

async function Input() {
const carNamesInput = await Console.readLineAsync(IO_MESSAGE.INPUT_CARNAME);
const attemptsInput = await Console.readLineAsync(IO_MESSAGE.INPUT_ATTEMPTS);

const carNames = carNamesInput.split(',')
.map(name => name.trim())
.filter(name => name !== '');

const attempts = Number(attemptsInput);

if (carNames.length === 0) {
throw new Error(ERROR_MESSAGE.ERROR_EMPTY_CAR_NAME);
}

if (carNames.length < 1 || carNames.length > 5) {
throw new Error(ERROR_MESSAGE.ERROR_INVALID_CAR_COUNT);
}

if (carNames.some(name => name.length < 2 || name.length > 5)) {
throw new Error(ERROR_MESSAGE.ERROR_CAR_NAME_LENGTH);
}

if (isNaN(attempts) || attempts < 1 || attempts > 10) {
throw new Error(ERROR_MESSAGE.ERROR_INVALID_ATTEMPTS);
}

return { carNames, attempts };
}

export default Input;
17 changes: 17 additions & 0 deletions src/io-system/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Console } from "@woowacourse/mission-utils";
import { IO_MESSAGE } from "../constants/message";

function Output(winners, currentPositions) {
Console.print(IO_MESSAGE.OUTPUT_RESULT);

if (currentPositions && currentPositions.length > 0) {
currentPositions.forEach(position => {
Console.print(position);
});
}

const result = winners.join(', ');
Console.print(`${IO_MESSAGE.OUTPUT_WINNER} ${result}`);
}

export default Output;
8 changes: 8 additions & 0 deletions src/utils/moveCar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import getRandomNumber from "./randomNumberPicker";

function moveCar() {
const randomNumber = getRandomNumber(0, 9);
return randomNumber >= 4;
}

export { moveCar };
7 changes: 7 additions & 0 deletions src/utils/randomNumberPicker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { MissionUtils } from "@woowacourse/mission-utils";

function getRandomNumber(min, max) {
return MissionUtils.Random.pickNumberInRange(min, max);
}

export default getRandomNumber;