Skip to content
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
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
# javascript-lotto-precourse
## 기능 목록
### 로또 금액 사용자 입력
1. 사용자 금액 입력 처리 : 1000원 단위로 금액을 입력 받는다. (오류x)
2. 사용자 입력 처외 처리(오류1) : 1000단위 미만의 값을 입력 받으면 오류 메세지('[ERROR]')를 띄운다.
3. 사용자 입력 예외 처리(오류2) : 0원 이하의 값을 받으면 오류 메세지('[ERROR]')를 띄운다.
### 당첨 번호 사용자 입력
1. 로또 수량 추출 : 사력자가 구매한 금액으로 부터 로또 수량을 추출한다.
2. 로또 뽑기 기능 구현 : 중복되지 않는 숫자 6개 set을 수량만큼 만든다.(1~45사이 숫자 랜덤 추출)
3. 사용자 입력 처리 : 당첨 번호 6개를 입력 받는다.
4. 사용자 입력 예외 처리 : 구분자 , 가 아니면 오류 메세지를 띄운다.
5. 사용자 입력 예외 처리 : 당첨번호가 6개가 아니면 오류 메세지를 띄운다.
6. 사용자 입력 예외 처리 : 당첨번호 숫자 1~45 사이의 숫자가 아니면 오류메세지를 띄운다.
7. 사용자 입력 처리 : 보너스 번호를 1개를 입력받는다.
8. 사용자 입력 예외처리 : 보너스 번호가 1개가 아니고, ',' 구분자자 들어가 있으면 오류메세지를 띄운다.
9. 사용자 입력 예외처리 : 보너스 번호 숫자 1~45 사이의 숫자가 아니면 오류메세지를 띄운다.
### 로또 수량 및 번호 출력
1. 수량 출력 : 추출한 로또 수량을 출력한다.
2. 로또 번호 출력 : 로또 번호를 수량만큼 오름차순으로 출력한다.
3. 당첨 내역 출력 : 당첨 번호와 비교하여 번호 일치 개수를 추출한다.
4. 당첨 내역 출력 : 번호 일치 개수 만큼 분류하여 당첨 수량을 추출한다.

### 수익률 계산 및 출력
1. 수익률을 계산 : (당첨 금액/구매 금액) * 100 수식을 이용하여 수익률(%)을 구하고고소수 둘째 자리에서 반올림한다.
2. 수익률 출력

34 changes: 33 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
import { Console, Random } from "@woowacourse/mission-utils";
import { getTicketCount, generateLottoTickets, parseWinningNumbers, parseBonusNumber } from "./LottoGame.js";
import { calculateWinningCounts, printWinningStatistics } from "./LottoResult.js";
class App {
async run() {}
async run() {

try{
const moneyInput = await Console.readLineAsync('로또 구입 금액을 입력해주세요.\n');
const purchaseAmount = Number(moneyInput)
const ticketCount = getTicketCount(purchaseAmount);
Console.print(ticketCount + '개의 로또를 구입했습니다.');

const tickets = generateLottoTickets(ticketCount);
tickets.forEach(function(ticket){
Console.print (ticket.toString());
});

const winningInput = await Console.readLineAsync('당첨 번호를 입력해주세요.\n');
const winningNumbers = parseWinningNumbers(winningInput);
Console.print('당첨 번호 : ' + winningNumbers.join(', '));

const bonusInput = await Console.readLineAsync('보너스 번호를 입력해주세요.\n');
const bonusNumber = parseBonusNumber(bonusInput);
Console.print('보너스 번호 : ' + bonusNumber);

const winningCounts = calculateWinningCounts(tickets, winningNumbers, bonusNumber);
printWinningStatistics(winningCounts, purchaseAmount);

} catch (error) {
Console.print([error.message]);
}
}
}
const app = new App();
app.run();

export default App;
9 changes: 8 additions & 1 deletion src/Lotto.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ class Lotto {
}
}

// TODO: 추가 기능 구현
toString(){
return "[" +this.#numbers.join(', ') + "]";
}

// 당첨 계산에 사용될 로또 번호 배열 반환
getNumbers() {
return this.#numbers;
}
}

export default Lotto;
53 changes: 53 additions & 0 deletions src/LottoGame.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Random } from '@woowacourse/mission-utils';
import Lotto from './Lotto.js';
function getTicketCount(money) {
// 0원 이하 또는 1000원 단위가 아닐 경우 에러 처리
if (money <= 0) throw new Error('[Error] 금액의 최소 구입 단위는 1000원 입니다.');
if (money % 1000 !== 0) throw new Error('[Error] 1000원 단위로만 구입 가능합니다.');
return money / 1000;
}

function createLottoTicket() {
const numbers = Random.pickUniqueNumbersInRange(1, 45, 6);
numbers.sort(function(a, b){ return a -b; });
return new Lotto(numbers);
}

function generateLottoTickets(count){
const tickets = [];
for (let i = 0; i < count; i++){
tickets.push(createLottoTicket());
}
return tickets;
}

function parseWinningNumbers(input) {
if (input.indexOf(',') === -1) throw new Error('[Error] 구분자는 ,만 사용 가능합니다.');
const parts = input.split(',');
if (parts.length !== 6) throw new Error('[Error] 로또 당첨 번호는 6개입니다.');
const numbers = [];
for (let i = 0; i < parts.length; i++) {
const num = Number(parts[i].trim());
if (isNaN(num) || num < 1 || num > 45) throw new Error ('[Error] 번호는 1 이상 45이하 범위의 숫자여야 합니다.');
numbers.push(num);
}
numbers.sort(function(a,b) {return a - b ;});
return numbers;
}

function parseBonusNumber(input) {
if (input.indexOf(',') !== -1) throw new Error('[Error] 번호는 하나만 입력 가능합니다.');
const num = Number(input.trim());
if (isNaN(num) || num < 1 || num > 45) throw new Error('[Error] 번호는 1 이상 45이하 범위의 숫자여야 합니다.');
return num;
}

export {
getTicketCount,
createLottoTicket,
generateLottoTickets,
parseWinningNumbers,
parseBonusNumber
};


72 changes: 72 additions & 0 deletions src/LottoResult.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Console } from '@woowacourse/mission-utils';

function calculateWinningCounts(tickets, winningNumbers, bonusNumber) {
// 당첨 번호 일치 개수 추출
const counts = {};
for (const ticket of tickets) {

const numbers = ticket.getNumbers();
const matchCount = numbers.filter(num => winningNumbers.includes(num)).length;
//Console.print(`티켓: [${numbers.join(', ')}], 일치 개수: ${matchCount}`);

if (matchCount === 6) {
counts.six = (counts.six || 0) + 1;
continue;
}
if (matchCount === 5) {
if (numbers.includes(bonusNumber)) {
counts.bonus = (counts.bonus || 0) + 1;
} else {
counts.five = (counts.five || 0) + 1;
}
continue;
}
if (matchCount ===4 ) {
counts.four = (counts.four || 0) + 1;
continue;
}
if (matchCount ===3 ) {
counts.three = (counts.three || 0) +1;
}
}
return counts;
}

function calculateTotalWinning(winningCounts) {
// 총 당첨 금액 계산
const PRIZE_THREE = 5000;
const PRIZE_FOUR = 50000;
const PRIZE_FIVE = 1500000;
const PRIZE_BONUS = 30000000;
const PRIZE_SIX = 2000000000;
return ((winningCounts.three || 0) * PRIZE_THREE ) +
((winningCounts.four || 0) * PRIZE_FOUR ) +
((winningCounts.five || 0) * PRIZE_FIVE ) +
( (winningCounts.bonus || 0) * PRIZE_BONUS ) +
( (winningCounts.six || 0) * PRIZE_SIX );
}

function calculateYield(totalWinning, purchaseAmount){
//수익률 계산
return Math.round((totalWinning / purchaseAmount) * 1000) / 10;
}

function printWinningStatistics(winningCounts, purchaseAmount) {
const three = winningCounts.three || 0;
const four = winningCounts.four || 0;
const five = winningCounts.five || 0;
const bonus = winningCounts.bonus || 0;
const six = winningCounts.six || 0;
const totalWinning = calculateTotalWinning(winningCounts);
const yieldRate = calculateYield(totalWinning, purchaseAmount);
Console.print('당첨 통계');
Console.print('---')
Console.print(`3개 일치 (5,000원) - ${three}개`)
Console.print(`4개 일치 (50,000원) - ${four}개`)
Console.print(`5개 일치 (1,500,000원) - ${five}개`)
Console.print(`5개 일치, 보너스 볼 일치 (30,000,000원) - ${bonus}개`)
Console.print(`6개 일치 (2,000,000,000원) - ${six}개`)
Console.print(`총 수익률은 ${yieldRate}%입니다.`)
}

export { calculateWinningCounts, calculateTotalWinning, calculateYield, printWinningStatistics };