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

[로또] 윤승일 미션 제출합니다 #79

Open
wants to merge 16 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
175 changes: 175 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,178 @@ out/

### Mac OS ###
.DS_Store

# Created by https://www.toptal.com/developers/gitignore/api/windows,androidstudio,kotlin
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,androidstudio,kotlin

### Kotlin ###
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db

# Dump file
*.stackdump

# Folder config file
[Dd]esktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp

# Windows shortcuts
*.lnk

### AndroidStudio ###
# Covers files to be ignored for android development using Android Studio.

# Built application files
*.apk
*.ap_
*.aab

# Files for the ART/Dalvik VM
*.dex

# Java class files

# Generated files
bin/
gen/

# Gradle files
.gradle/

# Signing files
.signing/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files

# Android Studio
/*/build/
/*/local.properties
/*/out
/*/*/build
/*/*/production
captures/
.navigation/
*~
*.swp

# Keystore files
*.jks
*.keystore

# Google Services (e.g. APIs or Firebase)
# google-services.json

# Android Patch
gen-external-apklibs

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild

# NDK
obj/

# IntelliJ IDEA
/out/

# User-specific configurations
.idea/caches/
.idea/libraries/
.idea/shelf/
.idea/workspace.xml
.idea/tasks.xml
.idea/.name
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/encodings.xml
.idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
.idea/datasources.xml
.idea/dataSources.ids
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
.idea/assetWizardSettings.xml
.idea/gradle.xml
.idea/jarRepositories.xml
.idea/navEditor.xml

# Legacy Eclipse project files
.cproject
.settings/

# Mobile Tools for Java (J2ME)

# Package Files #

# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)

## Plugin-specific files:

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Mongo Explorer plugin
.idea/mongoSettings.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

### AndroidStudio Patch ###

!/gradle/wrapper/gradle-wrapper.jar

# End of https://www.toptal.com/developers/gitignore/api/windows,androidstudio,kotlin
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,34 @@
# kotlin-lotto-precourse
## 구현할 기능 목록
1. 입력
- 구입 금액
- 예외 사항
- 입력 없음
- 입력에 공백만 있음
- 정수로 변환 불가능
- 자연수가 아님
- 1000원 단위가 아님
- 당첨 번호
- 예외 사항
- 입력 없음
- 입력에 공백만 있음
- 숫자와 콤마로 이루어진 패턴이 아님
- 숫자콤마숫자콤마숫자콤마숫자콤마숫자콤마숫자
- 1이상 45이하가 아님
- 6개의 번호에 중복이 있음
- 보너스 번호
- 예외 사항
- 입력 없음
- 입력에 공백만 있음
- 숫자가 아님
- 1이상 45이하가 아님
- 당첨 번호와 중복됨
2. 출력
- 로또 수량 및 해당 회차 도전 번호
- 당첨 내역 출력
- 수익률
- 예외
3. 로직
- 로또(자동)
- 당첨(n개 일치) 계산
- 수익률 계산
136 changes: 136 additions & 0 deletions Requirement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# kotlin-lotto-precourse
# 로또
## 과제 진행 요구 사항
- 미션은 로또 저장소를 포크하고 클론하는 것으로 시작한다.
- 기능을 구현하기 전 README.md에 구현할 기능 목록을 정리해 추가한다.
- Git의 커밋 단위는 앞 단계에서 README.md에 정리한 기능 목록 단위로 추가한다.
- AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성한다.
- 자세한 과제 진행 방법은 프리코스 진행 가이드 문서를 참고한다.
## 기능 요구 사항
간단한 로또 발매기를 구현한다.
- 로또 번호의 숫자 범위는 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]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.
- Exception이 아닌 IllegalArgumentException, IllegalStateException 등과 같은 명확한 유형을 처리한다.
## 입출력 요구 사항
### 입력
- 로또 구입 금액을 입력 받는다. 구입 금액은 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%입니다.
## 프로그래밍 요구 사항 1
- Kotlin 1.9.24에서 실행 가능해야 한다.
- Java 코드가 아닌 Kotlin 코드로만 구현해야 한다.
- 프로그램 실행의 시작점은 Application의 main()이다.
- build.gradle.kts 파일은 변경할 수 없으며, 제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다.
- 프로그램 종료 시 System.exit() 또는 exitProcess()를 호출하지 않는다.
- 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다.
- 코틀린 코드 컨벤션을 지키면서 프로그래밍한다.
- 기본적으로 Kotlin Style Guide를 원칙으로 한다.
## 프로그래밍 요구 사항 2
***
- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
- 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
- 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
- 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
- JUnit 5와 AssertJ를 이용하여 정리한 기능 목록이 정상적으로 작동하는지 테스트 코드로 확인한다.
- 테스트 도구 사용법이 익숙하지 않다면 아래 문서를 참고하여 학습한 후 테스트를 구현한다.
- JUnit 5 User Guide
- AssertJ User Guide
- AssertJ Exception Assertions
- Guide to JUnit 5 Parameterized Tests
## 프로그래밍 요구 사항 3
***
- 함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다.
- 함수(또는 메서드)가 한 가지 일만 잘 하도록 구현한다.
- else를 지양한다.
- 때로는 if/else, when문을 사용하는 것이 더 깔끔해 보일 수 있다. 어느 경우에 쓰는 것이 적절할지 스스로 고민해 본다.
- 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.
- Enum 클래스를 적용하여 프로그램을 구현한다.
- 구현한 기능에 대한 단위 테스트를 작성한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다.
- 단위 테스트 작성이 익숙하지 않다면 LottoTest를 참고하여 학습한 후 테스트를 작성한다.
## 라이브러리
- camp.nextstep.edu.missionutils에서 제공하는 Randoms 및 Console API를 사용하여 구현해야 한다.
- Random 값 추출은 camp.nextstep.edu.missionutils.Randoms의 pickUniqueNumbersInRange()를 활용한다.
- 사용자가 입력하는 값은 camp.nextstep.edu.missionutils.Console의 readLine()을 활용한다.
### 사용 예시
- 1에서 45 사이의 중복되지 않은 정수 6개 반환
> Randoms.pickUniqueNumbersInRange(1, 45, 6)
## Lotto 클래스
- 제공된 Lotto 클래스를 사용하여 구현해야 한다.
- Lotto에 numbers 이외의 필드(인스턴스 변수)를 추가할 수 없다.
- numbers의 접근 제어자인 private은 변경할 수 없다.
- Lotto의 패키지를 변경할 수 있다.
```
package lotto

class Lotto(private val numbers: List<Int>) {
init {
require(numbers.size == 6) { "[ERROR] 로또 번호는 6개여야 합니다." }
}

// TODO: 추가 기능 구현
}
```
Loading