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

[자동차 경주 게임] 정유진 미션 제출 합니다. #746

Open
wants to merge 6 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
34 changes: 34 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 2주차 미션 : 자동차 경주 게임
## 구현할 기능 목록

### [✅] 1. 참가자 자동차 이름 입력 받기
* 시작 메시지 :
```
경주할 자동차 이름을 입력하세요. (이름은 쉼표(,)로 구분)
```

* 참가자의 자동차 이름 입력

### [✅] 2. 입력값 유효성 검사 (예외사항 처리)
* 5글자 초과인 경우 : [ERROR] 자동차 이름은 5글자 이하만 가능합니다.
* 중복된 이름 입력 : [ERROR] 중복된 자동차 이름이 있습니다.
* 빈 문자열 입력 : [ERROR] 문자열은 입력할 수 없습니다.


### [✅] 3. 시도 횟수 입력 받기
* 시작 메시지 :
```
시도할 횟수는 몇 회인가요?
```
* 참가자의 시도 횟수 입력

### [✅] 4. 레이싱 게임 진행
* 참가자들의 자동차를 시도 횟수만큼 전진
* 전진하는 조건 : 무작위 숫자 생성, 숫자가 4 이상인 경우에만 전진

### [✅] 5. 게임 진행 결과 출력
* 각 참가자의 이름과 현재 위치를 출력
* 각 참가자 정보를 줄바꿈으로 구분

### [✅] 6. 최종 우승자 출력
* 게임 종료 후 가장 멀리 간 참가자(들) 출력
100 changes: 99 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,103 @@
import readline from 'readline';

const MissionUtils = {
Random: {
pickNumberInRange(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
},
};

class Car {
constructor(name) {
this.name = name;
this.position = 0;
}

move() {
const randomNumber = MissionUtils.Random.pickNumberInRange(0, 9);
if (randomNumber >= 4) {
this.position += 1;
}
}

toString() {
return `${this.name} : ${'-'.repeat(this.position)}`;
}
}

class RacingGame {
constructor(carNames, tries) {
this.cars = carNames.split(',').map(name => new Car(name));
this.tries = tries;
}

playGame() {
for (let i = 0; i < this.tries; i++) {
this.cars.forEach(car => car.move());
console.log(this.cars.map(car => car.toString()).join('\n'));
if (i < this.tries - 1) {
console.log('');
}
}
}

getWinners() {
const maxPosition = Math.max(...this.cars.map(car => car.position));
return this.cars
.filter(car => car.position === maxPosition)
.map(car => car.name)
.join(', ');
}
}

function readLineAsync(prompt) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

return new Promise((resolve) => {
rl.question(prompt, (input) => {
rl.close();
resolve(input);
});
});
}

class App {
async play() {}
async play() {
try {
const carNames = await readLineAsync('경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)\n');
if (carNames.trim() === '') {
throw new Error('[ERROR] 빈 문자열은 입력할 수 없습니다.');
}
const names = carNames.split(',');

if (names.some(name => name.trim().length > 5)) {
throw new Error('[ERROR] 자동차 이름은 5글자 이하만 가능합니다.');
}

if (hasDuplicateNames(names)) {
throw new Error('[ERROR] 중복된 자동차 이름이 있습니다.');
}

const tries = await readLineAsync('시도할 횟수는 몇 회인가요?\n');

const racingGame = new RacingGame(carNames, parseInt(tries, 10));
console.log('실행 결과:');
racingGame.playGame();
const winners = racingGame.getWinners();
console.log('최종 우승자: ' + winners);
} catch (error) {
console.error(error.message);
}
}
}

function hasDuplicateNames(names) {
const uniqueNames = new Set(names);
return names.length !== uniqueNames.size;
}

export default App;
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import App from "./App.js";

const app = new App();
app.play();
app.play();