동석쿠
프로그래밍 공부
동석쿠
전체 방문자
오늘
어제
  • 공부 (80)
    • 공부기록 (64)
      • 웹개발 (6)
      • Java (7)
      • cs 공부 (3)
      • http 웹 기본 지식 (8)
      • 자바 스프링 (20)
      • 개인 미니프로젝트 (3)
      • 알고리즘 공부 (6)
      • 면접준비 (2)
      • 프론트공부 (8)
      • 파이썬 플라스크 (1)
    • 항해99 기록 (14)
      • 회고록 (10)
      • 팀프로젝트 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 문법
  • 스프링부트
  • 리액트
  • JPA
  • 알고리즘
  • 프로그래머스
  • 자바
  • Post
  • 자바스크립트
  • Java
  • 항해99
  • lombok
  • 리프레쉬토큰
  • 스프링
  • 리프레시토큰
  • 파이썬
  • 상속
  • Get
  • 리스트
  • API

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
동석쿠
공부기록/자바 스프링

스프링 룰렛기능 만들기 (가챠시스템), 자바 난수 설정, 확률설정

스프링 룰렛기능 만들기 (가챠시스템), 자바 난수 설정, 확률설정
공부기록/자바 스프링

스프링 룰렛기능 만들기 (가챠시스템), 자바 난수 설정, 확률설정

2022. 3. 9. 19:22
public LottoResponseDto getLotto(User user) throws NoSuchAlgorithmException {
        Long lottoPrice = 200L;
        Lotto lotto = lottoRepository.findByUser(user);
        if(user.getTotalPoint()>=lottoPrice) {
            user.setTotalPoint(user.getTotalPoint()-lottoPrice);
            userRepository.save(user);
            Point point = new Point("로또 참여", -lottoPrice, user.getTotalPoint(), user);
            pointRepository.save(point);
            Random random = SecureRandom.getInstanceStrong();
            int num;
            if(lotto.getCount()>=5) {num = random.nextInt(3630);}
            else {num = random.nextInt(10000);}


            String content = "";
            if (1 <= num && num < 30) {//0.3프로
                content = "경 * 축 1등 당첨!!😄😄😄 세상에 이런일이.... 운이 엄청 좋으시군요...!! ";
                lottoPoint1(user);
                lotto.setCount(0L);
                lottoRepository.save(lotto);
            }else if(30<= num && num < 130){ //1프로
                content = "경 * 축 2등 당첨!!😁😁😁 2등도 잘한거야!!!!";
                lottoPoint2(user);
                lotto.setCount(0L);
                lottoRepository.save(lotto);
            } else if (130 <= num && num < 630) { // 5프로
                content = "경 * 축 3등 당첨!!😃😃😃 3등도 엄청난거지 ^^ 메달도 3등까지라구~";
                lottoPoint3(user);
                lotto.setCount(0L);
                lottoRepository.save(lotto);
            } else if (630 <= num && num < 1630) { //10프로
                content = "축! 4등 당첨!!😎😎😎";
                lottoPoint4(user);
                lotto.setCount(0L);
                lottoRepository.save(lotto);
            } else if (1630 <= num && num < 3630) { //20프로
                content = "5등 당첨!!😙😙😙";
                lottoPoint5(user);
                lotto.setCount(0L);
                lottoRepository.save(lotto);
            } else { //63.7프로
                    content = "아쉽게도 꽝입니다 😥😥😥😥 한번만 더 뽑으면 1등 당첨될수도...?";
                    lottoPoint6(user);
                    lotto.setCount(lotto.getCount()+1);
                    lottoRepository.save(lotto);
            }
            return new LottoResponseDto(content, lotto.getCount());
        }else throw new LackPointException("보유한 포인트가 부족합니다");
    }

우선 유저가 로또에 참가할수있는 포인트가 있는지 먼저 검사한다. 그 후 천장시스템을 사용하기 위해

로또라는 테이블을 만들어 count라는 컬럼을 만들고 유저와 OneToOne연관관계를 맺었다.

 

랜덤수를 생성할때 SecureRandom을 사용하는 것이 보안상 안전하다고 한다

Math.Random같은 경우 컴퓨터의 시간을 시드로 사용하여 난수가 생성되어서 동시간에 유저가 지속적으로 같은 작업을 반복하면 유저의 난수가 동일하게 나올 수 있다.

반면 SecureRandom은 그보다 더 복잡한 로직을 사용하여 작업을 하는 모든 유저의 난수가 랜덤하게 나오게 된다.

가챠시스템에서 시간대에 따라 확률이 바뀌면 안되므로 이 프로젝트에선 SecureRandom을 사용하였다.

 

SecureRandom으로 나오는 난수를 10000까지로 설정해주었는데 만약 꽝이 연속으로 5번 이상 나올 경우

랜덤값의 범위를 3630까지로 지정하여 확정으로 최소 5등이상에 당첨되게 설정해주었다. 

 

확률의 경우 난수가 1~10000까지인데 여기서 나오는 숫자가 특정 범위안에 들어갈경우 (1~100은 만개중 백개이므로 1퍼센트가 된다) 해당 등수에 해당하는 작업이 이루어지도록 사용하였다.

 

 public void lottoPoint1(User user) {
        Long point1 = 1000000L;
        user.setTotalPoint(user.getTotalPoint()+point1);
        userRepository.save(user);
        Point point = new Point("1등 당첨", point1, user.getTotalPoint(), user);
        pointRepository.save(point);
    }
    public void lottoPoint2(User user) {
        Long point1 = 100000L;
        user.setTotalPoint(user.getTotalPoint()+point1);
        userRepository.save(user);
        Point point = new Point("2등 당첨", point1, user.getTotalPoint(), user);
        pointRepository.save(point);

    }
    public void lottoPoint3(User user) {
        Long point1 = 10000L;
        user.setTotalPoint(user.getTotalPoint()+point1);
        userRepository.save(user);
        Point point = new Point("3등 당첨", point1, user.getTotalPoint(), user);
        pointRepository.save(point);

    }
    public void lottoPoint4(User user) {
        Long point1 = 1000L;
        user.setTotalPoint(user.getTotalPoint()+point1);
        userRepository.save(user);
        Point point = new Point("4등 당첨", point1, user.getTotalPoint(), user);
        pointRepository.save(point);

    }
    public void lottoPoint5(User user) {
        Long point1 = 500L;
        user.setTotalPoint(user.getTotalPoint()+point1);
        userRepository.save(user);
        Point point = new Point("5등 당첨", point1, user.getTotalPoint(), user);
        pointRepository.save(point);

    }

각 등수에 당첨될 경유 유저의 포인트에 그 등수에 해당하는 포인트를 적립해주고 포인트 내역을 만들어준다.

 

1번유저가 포인트 테이블의 23번부터 27번까지 연속으로 5번 꽝이 되자 다음 로또에는 확률보정이 들어가 5등당첨이 나오게 된다.

'공부기록 > 자바 스프링' 카테고리의 다른 글

스프링 아이템기능 리팩터링  (0) 2022.03.19
스프링 아이템기능 구현, 단어 뒤집기, 파파고 API  (0) 2022.03.12
스프링 배팅시스템 만들기 (트위치 배팅시스템 참고)  (0) 2022.03.08
스프링부트 JPA 중복검색 해결 <트러블 슈팅>  (0) 2022.03.07
스프링 DI(의존성주입), IOC컨테이너  (0) 2022.01.29
    '공부기록/자바 스프링' 카테고리의 다른 글
    • 스프링 아이템기능 리팩터링
    • 스프링 아이템기능 구현, 단어 뒤집기, 파파고 API
    • 스프링 배팅시스템 만들기 (트위치 배팅시스템 참고)
    • 스프링부트 JPA 중복검색 해결 <트러블 슈팅>
    동석쿠
    동석쿠

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.