(8) 로또 시뮬레이터 예제

2020. 7. 10. 03:22개발공부/Java

728x90

LottoSimulator

강의 실습예제였던 로또 시뮬레이터를 집에와서 구현해보았다.
학원에서는 풀지 못했었고, 집에 와선 강사님 코드보면서 최대한 혼자 힘으로 완성시킬 수 있었다.
몇시간 동안 딴짓해가면서 찾아낸 몇 가지 알쓸신코(알아두면 쓸모있는 신기한 코드)를 기록한다. 
아래는 코드 Github 링크↓
https://github.com/klyhyeon/Java/blob/master/LottoSimulator

 

klyhyeon/Java

Contribute to klyhyeon/Java development by creating an account on GitHub.

github.com

1.  static - 변수, 메서드 생성

선언해야할 메서드는 총 3가지다.
Class 단위에 생성하는 변수는 등수를 매기는 prize0~5 5가지

static 선언하지 않았을 때 다른 메서드에서 "Cannot make a static reference to the non-static field prize 1" 이란
오류가 떴다. 


실험삼아 코드 내 모든 static을 지워봤는데 메서드 호출할 때 '객체화' 해서 불러줘야 되는 번거로움이 생긴다.
static은 수정하지 못하게 하는 특성이 있다고 했는데 불변성(안전성)과 편리성(객체화 불필요) 때문에 
써주는 것 같다.
좀 더 정확한 이유는 나중에 찾아봐야겠다.

2. void와 return - 로또 메서드 생성

메서드에 void를 써주면 return을 해주지 않아도 된다.
return을 받을 땐 하지만 void 대신 return 받는 대상의 타입을 메서드에 선언해주어야 한다.

3. while문 - 로또 번호 생성

반복문은 for문과 while문이 있다,
특징은 무한루프나 정지지점을 모를 땐 while을 쓰고, array로 배열 내 값을 사용할 땐 for문 쓴다는 정도이다.
그리고 이번 코딩을 짜면서 알게 된 점은 while문은 i++; 반복값 제어변수를 조건문 내에 쓸 수 있는 것이다.
if문 안에 넣어서 조건이 성립할 때 제어변수가 늘어나도록 설정해줄 수 있다.

4. if문 내 boolean - 로또 생성 번호 중복제거 & 당첨 등수 매기기

 1) 로또 생성 번호 중복제거

로또 번호는 난수 생성 메서드(Random)을 이용해 뽑는다.
1~6번째 난수(Random Number)가 중복되지 않도록 코드를 만드는데 어려움이 있었다.

혼자 힘으로 해결하지 못한 부분은 강사님의 코드를 참고해서 작성했다.
사용된 문법은 boolean과 if문이다. 그리고 if문은 for문에 종속된다.
로직은 3단계로 나눌 수 있다.

 1) 한 번 이상 검증을 해야한다. (for문)
 2) 중복이 되는 조건이 필요하다. (if문)
 3) 중복이 된다면 난수를 다시 뽑아야(재추첨)한다. (boolean문)

3번
이 문제였다.
boolean문은 중복되는 조건의 스위치 역할을 하는 친구로 이해하면 된다.
전구에 불을 키려면 파워(if문)를 지속적으로(for문) 흐르게 하고, 장치를(boolean문) 조작해야한다.
말이 장황해졌다.
boolean은 참과 거짓 즉, 0과 1로만 출력하는 함수다.
if문 전(before)에 boolean 변수를 하나 선언한다. (ex. boolean flag = true;)
if문을 충족하면 boolean 변수값을 반대로 변화시킨다. (flag = false;)
break를 걸고 for문을 빠져나와서 난수 생성 반복문으로 되돌아간다.
여기서 잠깐! 난수 생성 반복문의 제어변수 i++;는 실행이 될까?
되지 않는다. while문 특징을 이용해서 구문 끝에 if문 장치를 만들었기 때문이다.

따라서 중복이 되지 않은 경우만 boolean 값은 초기값 true를 유지할테고, 하이라이트 된 if문을 
만족시켜 배열멤버로 뽑히게 된다.
while문 제어변수 i도 i++; 를 받아 1 커져서 while 반복문 처음으로 들어간다.
여기서 잠깐! flag == true 에서 동등연산이 '==' 인 것을 기억하자! 쉽다고 방심하다가 놓칠 수 있는 부분이다.

 2) 당첨 등수 매기기

  로또 숫자는 6개이지만, 보너스 숫자 1개가 더 있단 사실을 아는가? 보너스 숫자의 기능도?
  존재는 알았지만 보너스 숫자가 2,3등을 가른다는 사실은 오늘 처음 알았다.
  2,3등은 6개 중 5개를 맞췄지만 주어진 보너스 숫자를 맞추면 2등이 되고, 아니면 3등이 된다.(상금 차이는 10배 이상)

  조건이 하나 더 등장하는 불편한 진실이지만 if문과 boolean을 사용하면 해결된다.

 

 

5. for 중첩문 - 로또 번호 대조하기

번호까지 잘 생성했으면 당첨번호와 내가 찍은 로또 번호가 얼마나 들어맞았는지 비교는 필수다.
6개의 수는 배열에 담아두었다.
그래서 담아둔 수를 하나씩 꺼내서 서로 비교하고, 몇 개가 같은지 알아내야한다.
로직은 간단하다. 그런데 2개 이상 배열을 비교하는 방법을 모른다.
이럴 때 for 중첩문을 사용할 수 있다.

모르면 어렵고, 알면 이렇게 쉽다. 많은 것들을 관통하는 하나의 진리.

해석해본다. myLotto 배열 내 숫자들을 int o에 담는다.
win 배열 내 숫자들을 int p에 하나씩 꺼낸다.
반복횟수는 myLotto 배열 숫자 갯수이다.
같을 때마다 당첨 숫자는 1개씩 누적 count++ 된다.


6. int, long 데이터 타입 - 로또 결과 출력

알고 있으면 시간을 단축시켜줄 오류 방지용 코드지식

1) 7자리가 넘는 숫자는 long으로 데이터 타입을 설정하자.
2) 연산이 있는 변수 중에 서로 데이터 타입이 다르다면 casting을 진행하자. 안전한 방법이다.
3) 천단위 숫자 comma(,)가 없으면 불편한 나같은 사람을 위한 객체
  - DecimalFormat df = new DecimalFormat("#,###");
  - 여기서 잠깐! 출력해줄 때 System.out.printf (x) 안된다. format 설정해주는 메서드가 중복돼서 그렇다
    그래서 출력 메서드는 println 이나 print로 설정하고 df.format(money) 형태로 선언하면 된다.