diff --git a/README.md b/README.md index 81b03cdba2..c80670b15f 100644 --- a/README.md +++ b/README.md @@ -1,207 +1,6 @@ -# ๊ณผ์ œ - ๋กœ๋˜ - -## ๐Ÿ” ์ง„ํ–‰ ๋ฐฉ์‹ - -- ๊ณผ์ œ๋Š” **๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ, ๊ณผ์ œ ์ง„ํ–‰ ์š”๊ตฌ ์‚ฌํ•ญ** ์„ธ ๊ฐ€์ง€๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. -- ์„ธ ๊ฐœ์˜ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•œ๋‹ค. ํŠนํžˆ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ๋งŒ๋“ค๊ณ , ๊ธฐ๋Šฅ ๋‹จ์œ„๋กœ ์ปค๋ฐ‹ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ•œ๋‹ค. -- ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ์— ๊ธฐ์žฌ๋˜์ง€ ์•Š์€ ๋‚ด์šฉ์€ ์Šค์Šค๋กœ ํŒ๋‹จํ•˜์—ฌ ๊ตฌํ˜„ํ•œ๋‹ค. - ---- - -## ๐Ÿ“ˆ ๊ณผ์ œ ์ง„ํ–‰ ๋ฐ ์ œ์ถœ ๋ฐฉ๋ฒ• - -- ๊ณผ์ œ๋Š” [java-lotto](https://github.com/LandvibeDev/java-lotto) ์ €์žฅ์†Œ๋ฅผ Fork/Cloneํ•ด ์‹œ์ž‘ํ•œ๋‹ค. -- **๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— java-baseball-precourse/README.md ํŒŒ์ผ์— ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์ •๋ฆฌ**ํ•ด ์ถ”๊ฐ€ํ•œ๋‹ค. -- **Git์˜ ์ปค๋ฐ‹ ๋‹จ์œ„๋Š” ์•ž ๋‹จ๊ณ„์—์„œ README.md ํŒŒ์ผ์— ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋‹จ์œ„**๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค. - - [AngularJS Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) ์ฐธ๊ณ ํ•ด commit log๋ฅผ ๋‚จ๊ธด๋‹ค. -- ๊ณผ์ œ ์ง„ํ–‰ ๋ฐ ์ œ์ถœ ๋ฐฉ๋ฒ•์€ [์šฐ์•„ํ•œ์ฝ”์Šค ๊ณผ์ œ ์ œ์ถœ ๋ฌธ์„œ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) ๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค. - - base repository๋ฅผ `LandvibeDev/java-lotto`๋กœ ์ง€์ •ํ•ด์„œ PR ์ƒ์„ฑํ•˜๋ฉด๋จ - -
- -### ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๊ฐ€์ด๋“œ - -- ํ„ฐ๋ฏธ๋„์—์„œ `java -version`์„ ์‹คํ–‰ํ•˜์—ฌ Java ๋ฒ„์ „์ด 14์ธ์ง€ ํ™•์ธํ•œ๋‹ค. ๋˜๋Š” Eclipse ๋˜๋Š” IntelliJ IDEA์™€ ๊ฐ™์€ IDE์—์„œ Java 14๋กœ ์‹คํ–‰๋˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. -- ํ„ฐ๋ฏธ๋„์—์„œ Mac ๋˜๋Š” Linux ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ `./gradlew clean test` ๋ช…๋ น์„ ์‹คํ–‰ ํ•˜๊ณ , - Windows ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ `gradlew.bat clean test` ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๋•Œ ๋™์ž‘ ํ•˜๋Š”์ง€ ๋งŒ ํ™•์ธ(ํ…Œ์ŠคํŠธ๋Š” ์‹คํŒจ). - ---- - -## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ - -๋กœ๋˜ ๊ฒŒ์ž„ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ๋กœ๋˜ ๊ฒŒ์ž„์€ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ทœ์น™์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค. - -``` -- ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„๋Š” 1~45๊นŒ์ง€์ด๋‹ค. -- 1๊ฐœ์˜ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•  ๋•Œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” 6๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ฝ‘๋Š”๋‹ค. -- ๋‹น์ฒจ ๋ฒˆํ˜ธ ์ถ”์ฒจ ์‹œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. -- ๋‹น์ฒจ์€ 1๋“ฑ๋ถ€ํ„ฐ 5๋“ฑ๊นŒ์ง€ ์žˆ๋‹ค. ๋‹น์ฒจ ๊ธฐ์ค€๊ณผ ๊ธˆ์•ก์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. - - 1๋“ฑ: 6๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 2,000,000,000์› - - 2๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ + ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ผ์น˜ / 30,000,000์› - - 3๋“ฑ: 5๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 1,500,000์› - - 4๋“ฑ: 4๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 50,000์› - - 5๋“ฑ: 3๊ฐœ ๋ฒˆํ˜ธ ์ผ์น˜ / 5,000์› -``` - -- ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅํ•˜๋ฉด ๊ตฌ์ž… ๊ธˆ์•ก์— ํ•ด๋‹นํ•˜๋Š” ๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•ด์•ผ ํ•œ๋‹ค. -- ๋กœ๋˜ 1์žฅ์˜ ๊ฐ€๊ฒฉ์€ 1,000์›์ด๋‹ค. -- ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. -- ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งคํ•œ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋‹น์ฒจ ๋‚ด์—ญ ๋ฐ ์ˆ˜์ต๋ฅ ์„ ์ถœ๋ ฅํ•˜๊ณ  ๋กœ๋˜ ๊ฒŒ์ž„์„ ์ข…๋ฃŒํ•œ๋‹ค. -- ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ `IllegalArgumentException`๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , "[ERROR]"๋กœ ์‹œ์ž‘ํ•˜๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅ ํ›„ ์ข…๋ฃŒํ•œ๋‹ค. - -## โœ๐Ÿป ์ž…์ถœ๋ ฅ ์š”๊ตฌ์‚ฌํ•ญ - -### โŒจ๏ธ ์ž…๋ ฅ - -- ๋กœ๋˜ ๊ตฌ์ž… ๊ธˆ์•ก์„ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. ๊ตฌ์ž… ๊ธˆ์•ก์€ 1,000์› ๋‹จ์œ„๋กœ ์ž…๋ ฅ ๋ฐ›์œผ๋ฉฐ 1,000์›์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. - -``` -14000 -``` - -- ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. ๋ฒˆํ˜ธ๋Š” ์‰ผํ‘œ(,)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค. - -``` -1,2,3,4,5,6 -``` - -- ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค. - -``` -7 -``` - -### ๐Ÿ–ฅ ์ถœ๋ ฅ - -- ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰ ๋ฐ ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ณด์—ฌ์ค€๋‹ค. - -``` -8๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค. -[8, 21, 23, 41, 42, 43] -[3, 5, 11, 16, 32, 38] -[7, 11, 16, 35, 36, 44] -[1, 8, 11, 31, 41, 42] -[13, 14, 16, 38, 42, 45] -[7, 11, 30, 40, 42, 43] -[2, 13, 22, 32, 38, 45] -[1, 3, 5, 14, 22, 45] -``` - -- ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•œ๋‹ค. - -``` -3๊ฐœ ์ผ์น˜ (5,000์›) - 1๊ฐœ -4๊ฐœ ์ผ์น˜ (50,000์›) - 0๊ฐœ -5๊ฐœ ์ผ์น˜ (1,500,000์›) - 0๊ฐœ -5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - 0๊ฐœ -6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - 0๊ฐœ -``` - -- ์ˆ˜์ต๋ฅ ์€ ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผํ•œ๋‹ค. (ex. 100.0%, 51.5%, 1,000,000.0%) - -``` -์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค. -``` - -- ์˜ˆ์™ธ ์ƒํ™ฉ ์‹œ ์—๋Ÿฌ ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, ์—๋Ÿฌ ๋ฌธ๊ตฌ๋Š” "[ERROR]"๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค. - -``` -[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. -``` - -### ๐Ÿ’ป ์‹คํ–‰ ๊ฒฐ๊ณผ ์˜ˆ์‹œ - -``` -๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. -8000 - -8๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค. -[8, 21, 23, 41, 42, 43] -[3, 5, 11, 16, 32, 38] -[7, 11, 16, 35, 36, 44] -[1, 8, 11, 31, 41, 42] -[13, 14, 16, 38, 42, 45] -[7, 11, 30, 40, 42, 43] -[2, 13, 22, 32, 38, 45] -[1, 3, 5, 14, 22, 45] - -๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. -1,2,3,4,5,6 - -๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”. -7 - -๋‹น์ฒจ ํ†ต๊ณ„ ---- -3๊ฐœ ์ผ์น˜ (5,000์›) - 1๊ฐœ -4๊ฐœ ์ผ์น˜ (50,000์›) - 0๊ฐœ -5๊ฐœ ์ผ์น˜ (1,500,000์›) - 0๊ฐœ -5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - 0๊ฐœ -6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - 0๊ฐœ -์ด ์ˆ˜์ต๋ฅ ์€ 62.5%์ž…๋‹ˆ๋‹ค. -``` - ---- - -## ๐ŸŽฏ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ - -- JDK 14 ๋ฒ„์ „์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค. -- ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์˜ ์‹œ์ž‘์ ์€ `Application`์˜ `main()`์ด๋‹ค. -- `build.gradle` ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ณ , ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. -- [Java ์ฝ”๋“œ ์ปจ๋ฒค์…˜](https://naver.github.io/hackday-conventions-java/) ๊ฐ€์ด๋“œ๋ฅผ ์ค€์ˆ˜ํ•˜๋ฉฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•œ๋‹ค. -- ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ ์‹œ `System.exit()`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. -- ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„์ด ์™„๋ฃŒ๋˜๋ฉด `ApplicationTest`์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ ํ•œ๋‹ค. -- ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ๋‹ฌ๋ฆฌ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ํ•œ ํŒŒ์ผ, ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ด๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. -- indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 2๊นŒ์ง€๋งŒ ํ—ˆ์šฉํ•œ๋‹ค. - - ์˜ˆ๋ฅผ ๋“ค์–ด while๋ฌธ ์•ˆ์— if๋ฌธ์ด ์žˆ์œผ๋ฉด ๋“ค์—ฌ์“ฐ๊ธฐ๋Š” 2์ด๋‹ค. - - ํžŒํŠธ: indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ ์ค„์ด๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. -- 3ํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. -- ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•˜๋„๋ก ์ตœ๋Œ€ํ•œ ์ž‘๊ฒŒ ๋งŒ๋“ค์–ด๋ผ. -- JUnit 5์™€ AssertJ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณธ์ธ์ด ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ™•์ธํ•œ๋‹ค. -- ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 15๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. - - ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์„œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ์ž˜ ํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. -- else ์˜ˆ์•ฝ์–ด๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. - - ํžŒํŠธ: if ์กฐ๊ฑด์ ˆ์—์„œ ๊ฐ’์„ returnํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด else๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. - - else๋ฅผ ์“ฐ์ง€ ๋ง๋ผ๊ณ  ํ•˜๋‹ˆ switch/case๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ switch/case๋„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. -- Java Enum์„ ์ ์šฉํ•œ๋‹ค. -- ๋„๋ฉ”์ธ ๋กœ์ง์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, UI(System.out, System.in, Scanner) ๋กœ์ง์€ ์ œ์™ธํ•œ๋‹ค. - - ํ•ต์‹ฌ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ์™€ UI๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋กœ์ง์„ ๋ถ„๋ฆฌํ•ด ๊ตฌํ˜„ํ•œ๋‹ค. - -### ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ - -- [`camp.nextstep.edu.missionutils`](https://github.com/woowacourse-projects/mission-utils)์—์„œ ์ œ๊ณตํ•˜๋Š” `Randoms` ๋ฐ `Console` API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. - - Random ๊ฐ’ ์ถ”์ถœ์€ `camp.nextstep.edu.missionutils.Randoms`์˜ `pickUniqueNumbersInRange()`๋ฅผ ํ™œ์šฉํ•œ๋‹ค. - - ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•˜๋Š” ๊ฐ’์€ `camp.nextstep.edu.missionutils.Console`์˜ `readLine()`์„ ํ™œ์šฉํ•œ๋‹ค. - -#### ์‚ฌ์šฉ ์˜ˆ์‹œ - -```java -List numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6); -``` - -### Lotto ํด๋ž˜์Šค - -- ์ œ๊ณต๋œ `Lotto` ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. -- `Lotto`์— ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” ์ƒ์„ฑ์ž๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. -- `numbers`์˜ ์ ‘๊ทผ ์ œ์–ด์ž์ธ private์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. -- `Lotto`์— ํ•„๋“œ(์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜)๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค. -- `Lotto`์˜ ํŒจํ‚ค์ง€ ๋ณ€๊ฒฝ์€ ๊ฐ€๋Šฅํ•˜๋‹ค. - -```java -public class Lotto { - private final List numbers; - - public Lotto(List numbers) { - validate(numbers); - this.numbers = numbers; - } - - private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException(); - } - } - - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -} -``` +# Lotto +1. ๋‚œ์ˆ˜ ์ƒ์„ฑ +2. ๋‹น์ฒจ ๋ฒˆํ˜ธ, ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ +3. ๋‹น์ฒจ ์—ฌ๋ถ€ ํŒ์ • +4. ์ˆ˜์ต๋ฅ  ๊ณ„์‚ฐ +5. ์˜ˆ์™ธ ์ฒ˜๋ฆฌ \ No newline at end of file diff --git a/build.gradle b/build.gradle index 1cd662974c..9d087b142e 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ dependencies { java { toolchain { - languageVersion = JavaLanguageVersion.of(14) + languageVersion = JavaLanguageVersion.of(11) } } diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index 367ee30584..475cc38e4c 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -2,6 +2,8 @@ public class Application { public static void main(String[] args) { - // TODO: ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„ + NumberGame chosenNumberGame = new LottoGame(); + GameManager gameManager = new GameManager(chosenNumberGame); + gameManager.playGame(); } } \ No newline at end of file diff --git a/src/main/java/lotto/ConsoleMessages.java b/src/main/java/lotto/ConsoleMessages.java new file mode 100644 index 0000000000..011a7f6af0 --- /dev/null +++ b/src/main/java/lotto/ConsoleMessages.java @@ -0,0 +1,47 @@ +package lotto; + +import java.text.DecimalFormat; +import java.util.List; + +import static lotto.Result.*; +import static lotto.Rule.*; + +public class ConsoleMessages { + + public static void printResult(List resultNumber) { + DecimalFormat decFormat = new DecimalFormat("###,###"); + String result = "๋‹น์ฒจ ํ†ต๊ณ„\n"; + result += "---\n"; + result += String.format("3๊ฐœ ์ผ์น˜ (%s์›) - %d๊ฐœ\n", decFormat.format(FIFTH.prize) ,resultNumber.get(MIN_RANK-1)); + result += String.format("4๊ฐœ ์ผ์น˜ (%s์›) - %d๊ฐœ\n", decFormat.format(FOURTH.prize), resultNumber.get(MIN_RANK-2)); + result += String.format("5๊ฐœ ์ผ์น˜ (%s์›) - %d๊ฐœ\n", decFormat.format(THIRD.prize), resultNumber.get(MIN_RANK-3)); + result += String.format("5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (%s์›) - %d๊ฐœ\n", decFormat.format(SECOND.prize), resultNumber.get(MIN_RANK-4)); + result += String.format("6๊ฐœ ์ผ์น˜ (%s์›) - %d๊ฐœ", decFormat.format(FIRST.prize), resultNumber.get(MIN_RANK-5)); + System.out.println(result); + } + + public static void printEarningRate(double earningRate) { + System.out.println(String.format("์ด ์ˆ˜์ต๋ฅ ์€ %.1f%%์ž…๋‹ˆ๋‹ค.", earningRate)); + } + + public static void printEnterMoney() { + System.out.println("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."); + } + + public static void printLottoCount(int lottoCount) { + System.out.println(String.format("%d๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.", lottoCount)); + } + + public static void printEnterWinningNumber() { + System.out.println("๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."); + } + + public static void printEnterBonusNumber() { + System.out.println("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."); + } + + public static void printLottoNumbers(Lotto lotto) { + System.out.println(lotto.toString()); + } + +} diff --git a/src/main/java/lotto/ErrorMessage.java b/src/main/java/lotto/ErrorMessage.java new file mode 100644 index 0000000000..f29a1c21f0 --- /dev/null +++ b/src/main/java/lotto/ErrorMessage.java @@ -0,0 +1,13 @@ +package lotto; + +public enum ErrorMessage { + WRONG_CHARACTER("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."), + DUPLICATION("[ERROR] ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค"), + WRONG_MONEY("[ERROR] ๋กœ๋˜๋Š” ์ฒœ์› ๋‹จ์œ„๋กœ ๊ตฌ๋งคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค"); + + public String message; + + ErrorMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/lotto/GameManager.java b/src/main/java/lotto/GameManager.java new file mode 100644 index 0000000000..a5e302db24 --- /dev/null +++ b/src/main/java/lotto/GameManager.java @@ -0,0 +1,14 @@ +package lotto; + +public class GameManager { + + private NumberGame numberGame; + + public GameManager(NumberGame chosenGame) { + this.numberGame = chosenGame; + } + + public void playGame() { + numberGame.play(); + } +} diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java new file mode 100644 index 0000000000..f6aebe18ff --- /dev/null +++ b/src/main/java/lotto/Lotto.java @@ -0,0 +1,31 @@ +package lotto; + +import java.util.List; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + this.numbers = numbers; + } + + public MatchedNumbers match(WinningNumbers winningNumbers) { + MatchedNumbers matchedNumbers = new MatchedNumbers(); + for (Integer number : numbers) { + if(winningNumbers.mainNumbers.contains(number)) { + matchedNumbers.mainNumberMatching++; + } + if(winningNumbers.bonusNumber == number) { + matchedNumbers.bonusNumberMatching++; + } + } + return matchedNumbers; + } + + @Override + public String toString() { + numbers.stream() + .sorted(); + return numbers.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/lotto/LottoGame.java b/src/main/java/lotto/LottoGame.java new file mode 100644 index 0000000000..4fe41bba34 --- /dev/null +++ b/src/main/java/lotto/LottoGame.java @@ -0,0 +1,117 @@ +package lotto; + +import camp.nextstep.edu.missionutils.Console; + +import java.util.ArrayList; +import java.util.List; + +import static lotto.ConsoleMessages.*; +import static lotto.Parsing.parseInput; + +public class LottoGame implements NumberGame { + + List lottoList; + List resultList; + WinningNumbers winningNumbers; + int money; + int lottoCount; + int prize; + Validation validation; + + public LottoGame() { + winningNumbers = new WinningNumbers(); + resultList = new ArrayList<>(); + lottoList = new ArrayList<>() ; + validation = new Validation(); + prize = 0; + } + + public void play() { + insertMoney(); + buyLotto(); + getWinningNumbers(); + calculateResult(); + getResult(); + } + + private void insertMoney() { + printEnterMoney(); + String moneyString = Console.readLine(); + validation.validateMoney(moneyString); + money = Parsing.parseMoney(moneyString); + lottoCount = money / 1000; + printLottoCount(lottoCount); + } + + private void buyLotto() { + RandomNumberGenerator randomNumberGenerator = new RandomNumberGenerator(); + List randomNumbers; + for(int count = 0; count makeRankArrayList() { + List rankArrayList = new ArrayList<>(); + for(int count = 0; count <= Rule.MIN_RANK; count++) { // ์ตœ์†Œ ๋“ฑ์ˆ˜(5)๋“ฑ์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ๊ฐ–๋„๋ก ํ•˜๋Š” ๊ฒƒ + rankArrayList.add(0); + } + return rankArrayList; + } + + private void getResult() { + List rankArrayList = makeRankArrayList(); + for (Result result : resultList) { + rankArrayList.set(result.order-1, rankArrayList.get(result.order-1)+1); + prize += result.prize; + } + printResult(rankArrayList); + printEarningRate(calculateEarningsRate()); + } + + private double calculateEarningsRate() { + if (money == 0) { + throw new ArithmeticException("๋ˆ์ด 0์›์ผ ๊ฒฝ์šฐ ์ˆ˜์ต๋ฅ ์„ ๊ณ„์‚ฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค"); + } + return ((double)prize / money) * 100; + } +} diff --git a/src/main/java/lotto/MatchedNumbers.java b/src/main/java/lotto/MatchedNumbers.java new file mode 100644 index 0000000000..0369459404 --- /dev/null +++ b/src/main/java/lotto/MatchedNumbers.java @@ -0,0 +1,28 @@ +package lotto; + +import static lotto.Result.*; +import static lotto.Rule.COUNT; + +public class MatchedNumbers { + int bonusNumberMatching; + int mainNumberMatching; + + public Result computeResult() { + int sum = mainNumberMatching + bonusNumberMatching; + if (sum == COUNT) { + if (bonusNumberMatching == 0) { + return FIRST; + } + return SECOND; + } else if (sum < COUNT) { + if (sum == COUNT - 1) { + return THIRD; + } else if (sum == COUNT - 2) { + return FOURTH; + } else if (sum == COUNT - 3) { + return FIFTH; + } + } + return NONE; + } +} diff --git a/src/main/java/lotto/NumberGame.java b/src/main/java/lotto/NumberGame.java new file mode 100644 index 0000000000..ee6cf2114b --- /dev/null +++ b/src/main/java/lotto/NumberGame.java @@ -0,0 +1,7 @@ +package lotto; + +import java.util.List; + +public interface NumberGame { + void play(); +} diff --git a/src/main/java/lotto/Parsing.java b/src/main/java/lotto/Parsing.java new file mode 100644 index 0000000000..ecd793dc32 --- /dev/null +++ b/src/main/java/lotto/Parsing.java @@ -0,0 +1,37 @@ +package lotto; + +import java.util.ArrayList; +import java.util.List; + +import static lotto.ErrorMessage.*; + +public class Parsing { + + public static WinningNumbers parseInput(String mainNumbersString, String bonusNumberString) { + WinningNumbers winningNumbers = new WinningNumbers(); + winningNumbers.mainNumbers = parseMainNumbers(mainNumbersString); + winningNumbers.bonusNumber = parseBonusNumber(bonusNumberString); + return winningNumbers; + } + + private static List parseMainNumbers(String inputString) { + List parsedNumbers = new ArrayList<>(); + String[] parsedString = inputString.split(","); + for (String s : parsedString) { + int parsedNumber = Integer.parseInt(s); + if(parsedNumber < 1 || parsedNumber > 45) { + throw new IllegalArgumentException(WRONG_CHARACTER.message); + } + parsedNumbers.add(parsedNumber); + } + return parsedNumbers; + } + + private static int parseBonusNumber(String bonusNumber) { + return Integer.parseInt(bonusNumber); + } + + public static int parseMoney(String money) { + return Integer.parseInt(money); + } +} diff --git a/src/main/java/lotto/RandomNumberGenerator.java b/src/main/java/lotto/RandomNumberGenerator.java new file mode 100644 index 0000000000..08ef5f76a3 --- /dev/null +++ b/src/main/java/lotto/RandomNumberGenerator.java @@ -0,0 +1,15 @@ +package lotto; + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.List; + +import static lotto.Rule.*; + +public class RandomNumberGenerator { + + public List generateRandomNumbers() { + List randomNumbers = Randoms.pickUniqueNumbersInRange(START, END, COUNT); + return randomNumbers; + } +} diff --git a/src/main/java/lotto/Result.java b/src/main/java/lotto/Result.java new file mode 100644 index 0000000000..debe1c8b0b --- /dev/null +++ b/src/main/java/lotto/Result.java @@ -0,0 +1,13 @@ +package lotto; + +public enum Result { + FIRST(2000000000, 1), SECOND(30000000, 2), THIRD(1500000, 3), FOURTH(50000, 4), FIFTH(5000, 5), NONE(0, 6); + + public int prize; + public int order; + + Result(int prize, int order) { + this.prize = prize; + this.order = order; + } +} diff --git a/src/main/java/lotto/Rule.java b/src/main/java/lotto/Rule.java new file mode 100644 index 0000000000..6ba0d92b46 --- /dev/null +++ b/src/main/java/lotto/Rule.java @@ -0,0 +1,8 @@ +package lotto; + +public class Rule { + static final int START = 1; + static final int END = 45; + static final int COUNT = 6; + static final int MIN_RANK = 5; +} diff --git a/src/main/java/lotto/Validation.java b/src/main/java/lotto/Validation.java new file mode 100644 index 0000000000..ace6aa83d5 --- /dev/null +++ b/src/main/java/lotto/Validation.java @@ -0,0 +1,65 @@ +package lotto; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static lotto.ErrorMessage.*; + +public class Validation { + + public void validateMoney(String money) { + moneyCharacterCheck(money); + checkAmountOfMoney(money); + } + + public void validateWinningNumbers(String mainNumbers, String bonusNumber) { + mainNumberCharacterCheck(mainNumbers); + bonusNumberCharacterCheck(bonusNumber); + winningNumberDuplicationCheck(mainNumbers, bonusNumber); + } + + private void mainNumberCharacterCheck(String mainNumbers) { + String[] mainNumberList = mainNumbers.split(","); + for (String mainNumber : mainNumberList) { + for (Character character : mainNumber.toCharArray()) { + if (!Character.isDigit(character)) { + throw new IllegalArgumentException(WRONG_CHARACTER.message); + } + } + } + } + + private void bonusNumberCharacterCheck(String bonusNumber) { + for (Character character : bonusNumber.toCharArray()) { + if (!Character.isDigit(character)) { + throw new IllegalArgumentException(WRONG_CHARACTER.message); + } + } + } + + private void winningNumberDuplicationCheck(String inputMainNumbers, String inputBonusNumber) { + Set set = new HashSet<>(); + for (String number : inputMainNumbers.split(",")) { + set.add(Integer.parseInt(number)); + } + set.add(Integer.parseInt(inputBonusNumber)); + if (set.size() != Rule.COUNT + 1) { + throw new IllegalArgumentException(DUPLICATION.message); + } + } + + private void moneyCharacterCheck(String money) { + for (char character : money.toCharArray()) { + if (!Character.isDigit(character)) { + throw new IllegalArgumentException(WRONG_MONEY.message); + } + } + } + + private void checkAmountOfMoney(String money) { + if(Integer.parseInt(money) % 1000 != 0 || Integer.parseInt(money) == 0) { + throw new IllegalArgumentException(WRONG_MONEY.message); + } + } +} \ No newline at end of file diff --git a/src/main/java/lotto/WinningNumbers.java b/src/main/java/lotto/WinningNumbers.java new file mode 100644 index 0000000000..760a88d762 --- /dev/null +++ b/src/main/java/lotto/WinningNumbers.java @@ -0,0 +1,9 @@ +package lotto; + +import java.util.ArrayList; +import java.util.List; + +public class WinningNumbers { + public List mainNumbers = new ArrayList<>(); + public int bonusNumber; +} diff --git a/src/test/java/lotto/ApplicationTest.java b/src/test/java/lotto/ApplicationTest.java index 4dcf5b19b8..81e7ef4ea6 100644 --- a/src/test/java/lotto/ApplicationTest.java +++ b/src/test/java/lotto/ApplicationTest.java @@ -8,6 +8,7 @@ import static camp.nextstep.edu.missionutils.test.Assertions.assertRandomUniqueNumbersInRangeTest; import static camp.nextstep.edu.missionutils.test.Assertions.assertSimpleTest; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; class ApplicationTest extends NsTest { private static final String ERROR_MESSAGE = "[ERROR]"; @@ -50,10 +51,38 @@ class ApplicationTest extends NsTest { void ์˜ˆ์™ธ_ํ…Œ์ŠคํŠธ() { assertSimpleTest(() -> { runException("1000j"); - assertThat(output()).contains(ERROR_MESSAGE); + assertThat(output()).contains("[ERROR]"); + }); + + assertSimpleTest(() -> { + runException("0"); + assertThat(output()).contains("๋กœ๋˜๋Š” ์ฒœ์› ๋‹จ์œ„๋กœ ๊ตฌ๋งคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค"); + }); + + assertSimpleTest(() -> { + runException("123"); + assertThat(output()).contains("๋กœ๋˜๋Š” ์ฒœ์› ๋‹จ์œ„๋กœ ๊ตฌ๋งคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค"); }); } + @Test + void ์˜ˆ์™ธ_ํ…Œ์ŠคํŠธ_๋ฒ”์œ„๋ฐ–์ˆซ์ž() { + assertSimpleTest(() -> { + runException("1000", "0,46,47,48,49,50" ,"1"); + assertThat(output()).contains("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + }); + } + + @Test + void ์˜ˆ์™ธ_๋˜์ง€๊ธฐ() { + assertSimpleTest(() -> + assertThatThrownBy(() -> runException("1234")) + .isInstanceOf(IllegalArgumentException.class) + ); + } + + + @Override public void runMain() { Application.main(new String[]{});