diff --git a/README.md b/README.md index 15bb106b5..975fb4f27 100644 --- a/README.md +++ b/README.md @@ -1 +1,18 @@ # javascript-lotto-precourse +### ๐Ÿš€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ชฉ๋ก +- [x] ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. + - ๋กœ๋˜ 1์žฅ์˜ ๊ฐ€๊ฒฉ์€ 1000์›์ด๋‹ค. +- [x] ๊ตฌ์ž… ๊ธˆ์•ก ๋งŒํผ์˜ ๋กœ๋˜ ๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. + - ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 1~45 ๋ฒ”์œ„์˜ ์ˆซ์ž๋ฅผ 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ๋ฝ‘๋Š”๋‹ค. +- [x] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. +- [x] ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•œ๋‹ค. + - 1๋“ฑ: 6๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 2,000,000,000์› + - 2๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ + ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ผ์น˜ / 30,000,000์› + - 3๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 1,500,000์› + - 4๋“ฑ: 4๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 50,000์› + - 5๋“ฑ: 3๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 5,000์› +- [x] ์ˆ˜์ต๋ฅ ์„ ์ถœ๋ ฅํ•œ๋‹ค. +- ์˜ˆ์™ธ์ฒ˜๋ฆฌ + - [x] ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์€ 1000์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋Š” ์–‘์˜ ์ •์ˆ˜์ด๋‹ค. + - [x] ์ž…๋ ฅ๋ฐ›์€ ๋‹น์ฒจ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ์˜ ๋ฒ”์œ„๋Š” 1~45์ด๋‹ค. + - [x] ์ž…๋ ฅ๋ฐ›์€ ๋‹น์ฒจ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋Š” ๊ฒน์น˜์ง€ ์•Š๋Š”๋‹ค. \ No newline at end of file diff --git a/src/App.js b/src/App.js index 091aa0a5d..bb04063a3 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,21 @@ +import { offerLottoSheet } from "./LottoMachine.js"; +import { calculateProfit, calculateWinning, getWinningPrice } from "./LottoCalculator.js"; +import { getBonusNumber, getLottoNumber, getMoney, printLottoNumbers, printProfit, printResult } from "./View.js"; + class App { - async run() {} + async run() { + const lottoQuantity = await getMoney(); + const userLotto = await offerLottoSheet(lottoQuantity); + await printLottoNumbers(lottoQuantity, userLotto); + const winningNumbers = await getLottoNumber(); + const bonusNumber = await getBonusNumber(winningNumbers); + let winningArray = [winningNumbers, bonusNumber]; + const winningResult = await calculateWinning(winningArray, userLotto); + await printResult(winningResult); + const winningPrice = await getWinningPrice(winningResult); + const profit = await calculateProfit(lottoQuantity*1000, winningPrice); + await printProfit(profit); + } } export default App; diff --git a/src/Constant.js b/src/Constant.js new file mode 100644 index 000000000..d80a2c89d --- /dev/null +++ b/src/Constant.js @@ -0,0 +1,7 @@ +export const PRIZE_TABLE = { + 3: "5,000", + 4: "50,000", + 5: "1,500,000", + "5+bonus": "30,000,000", + 6: "2,000,000,000" +}; \ No newline at end of file diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e..0bb78b931 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -10,9 +10,17 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); } - } + numbers.forEach((number) => { + if(number < 1 || number > 45){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + }) - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + const numberSet = new Set(numbers); + if(numberSet.size !== 6){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž์ž…๋‹ˆ๋‹ค."); + } + } } export default Lotto; diff --git a/src/LottoCalculator.js b/src/LottoCalculator.js new file mode 100644 index 000000000..14ab73355 --- /dev/null +++ b/src/LottoCalculator.js @@ -0,0 +1,37 @@ +import { PRIZE_TABLE } from "./Constant.js"; + +export const calculateWinning = (winningNumber, userNumbers) => { + const [winningArray, bonus] = winningNumber; + + const prizeCounts = { 3: 0, 4: 0, 5: 0, '5+bonus': 0, 6: 0 }; + + userNumbers.forEach(numbers => { + const matchingCount = numbers.filter(number => winningArray.includes(number)).length; + + if (matchingCount === 5 && numbers.includes(bonus)) { + prizeCounts['5+bonus'] += 1; + } else if (matchingCount >= 3) { + prizeCounts[matchingCount] += 1; + } + }); + + return prizeCounts; +} + +export const getWinningPrice = (result) => { + let totalPrize = 0; + for (const [key, count] of Object.entries(result)) { + if (count > 0) { + const prize = parseInt(PRIZE_TABLE[key].replace(/,/g, ''), 10); + totalPrize += prize * count; + } + } + + return totalPrize; +} + +export const calculateProfit = (price, winningPrice) => { + const profit = winningPrice/price * 100; + + return profit.toFixed(1); +} \ No newline at end of file diff --git a/src/LottoMachine.js b/src/LottoMachine.js new file mode 100644 index 000000000..d0b6533a7 --- /dev/null +++ b/src/LottoMachine.js @@ -0,0 +1,16 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; + +export const createLottoNumbers = () => { + let numberSet = MissionUtils.Random.pickUniqueNumbersInRange(1, 45, 6); + return [...numberSet].sort((a, b) => a - b); +} + +export const offerLottoSheet = (quantity) => { + let sheet = []; + + for(let i=0; i { + if(number < 1 || number > 45){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + if(numberSet.has(number)){ + throw new Error("[ERROR] ๋ณด๋„ˆ์Šค ์ˆซ์ž๋Š” ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + } +} \ No newline at end of file diff --git a/src/View.js b/src/View.js new file mode 100644 index 000000000..125fbe8ff --- /dev/null +++ b/src/View.js @@ -0,0 +1,73 @@ +import { MissionUtils } from "@woowacourse/mission-utils"; +import { checkValidation } from "./Validator.js"; +import Lotto from "./Lotto.js"; +import { PRIZE_TABLE } from "./Constant.js"; + +export const getMoney = async () => { + const money = await MissionUtils.Console.readLineAsync("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”\n"); + if(isNaN(money.trim())){ + throw new Error("[ERROR] ๊ตฌ์ž…๊ธˆ์•ก์„ ์ˆซ์ž๋กœ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."); + } + + if(+money < 1000){ + throw new Error("[ERROR] 1000์›๋ถ€ํ„ฐ ๊ตฌ๋งค๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."); + } + + if(money%1000 !== 0){ + throw new Error("[ERROR] 1000์› ๋‹จ์œ„๋กœ ๊ตฌ๋งค๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."); + } + + return money/1000; +} + +export const getLottoNumber = async () => { + try { + const inputNumber = await MissionUtils.Console.readLineAsync("๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n"); + const winningNumber = inputNumber.split(',').map((number) => +(number.trim())); + + new Lotto(winningNumber); + + let lottoArray = winningNumber.sort((a, b) => a - b); + + return lottoArray; + } catch (error) { + throw new Error("[ERROR] ์ •ํ™•ํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."); + } +} + +export const getBonusNumber = async(numbers) => { + let bonusNumber = await MissionUtils.Console.readLineAsync("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n"); + bonusNumber = +bonusNumber.trim(); + + checkValidation(bonusNumber, new Set(numbers)); + return bonusNumber; +} + +export const printLottoNumbers = (number, lottoNumbers) => { + MissionUtils.Console.print(`${number}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); + lottoNumbers.forEach((lottoNumber) => { + const formattedLottoNumbers = `[${lottoNumber.join(', ')}]`; + MissionUtils.Console.print(formattedLottoNumbers); + }) +} + +export const printResult = async (result) => { + MissionUtils.Console.print(` + ๋‹น์ฒจ ํ†ต๊ณ„ + --- + `); + Object.entries(result).forEach(([key, count]) => { + const prize = PRIZE_TABLE[key]; + let bonus = ''; + if(key === '5+bonus'){ + MissionUtils.Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (${prize}์›) - ${count}๊ฐœ`); + } + else { MissionUtils.Console.print(`${key}๊ฐœ ์ผ์น˜ (${prize}์›) - ${count}๊ฐœ`); } + }); + +} + +export const printProfit = (profit) => { + MissionUtils.Console.print(`์ด ์ˆ˜์ต๋ฅ ์€ ${profit}%์ž…๋‹ˆ๋‹ค.`) + +} \ No newline at end of file