본문 바로가기
GD's IT Projects

[프로세싱(Processing)] 로또번호 자동 생성기

by GDNGY 2023. 5. 5.

로또번호 자동 생성기

로또란?

로또는 2002년 12월부터 시작되어, 대한민국 국민들에게 인기 있는 복권 게임이다. 
로또 추첨은 주로 매주 토요일에 열리며, 당첨 번호 여섯 개를 맞추면 된다.

로또는 총 5개의 등수로 나뉘어 상금이 지급됩니다
1등 - 6개의 당첨 번호 모두 일치 (모두들 여기에 담첨 되기를 바란다. 정말 하늘에 별따기만큼 어려운 확률?) 
2등 - 5개의 당첨 번호와 보너스 번호 일치
3등 - 5개의 당첨 번호 일치
4등 - 4개의 당첨 번호 일치
5등 - 3개의 당첨 번호 일치

로또번호 자동 생성기

1. 기획

프로세싱(Processing)으로 로또번호 자동 생성기를 만들기 위해, 다음 내용으로 기획하였다.

 

1) 화면 사이즈 설정
2) 이전 당첨번호 로딩 (lotto_winning_number.json)
3) 화면에 게임수 입력 상자 생성.
4) 1~45번까지 수자를 랜덤하게 생성할 수 있도록 구현
5) 게임수 만큼 로또 번호 생성
6) 제약조건 설정 
   - 이전 당첨번호와 동일한 번호는 제거
   - 3연속 번호는 제거
7) 생성된 번호는 화면에 출력 (출력되는 형식은 콤마(,)로 구분되고, 한 라인에 한게임 리스트형식으로 출력하도록 함)

2. 구현

1) 화면 사이즈 설정

setup() 및 draw() 함수를 사용하여 게임 창을 설정.
창 사이즈는 800 * 600으로 설정함.
배경색은 흰색으로 설정함.

 

void setup() {
  size(800, 600);
}

// 화면 그리기
void draw() {
  background(255);
}


2) 이전 당첨번호 로딩 (lotto_winning_number.json)

이전 회차 당첨 번호를 데이터(lotto_winning_number.json)를 로딩함.

// 이전 회차 데이터 불러오기
void loadData() {
  try {
    previousWinningNumbers = loadJSONObject(jsonFilename);
  } catch (Exception e) {
    println("Error loading data file: " + e.getMessage());
  }
}

 

3) 화면에 게임수 입력 상자 생성

게임수를 입력 받을수 있는 입력상자를 생성

  cp5 = new ControlP5(this);

  // 게임수 입력 레이블 및 입력 필드 생성
  cp5.addTextlabel("gameCountLabel")
    .setText("Enter game count:")
    .setPosition(20, 10)
    .setColor(color(0));

  gameCountInput = cp5.addTextfield("Enter game count")
    .setPosition(20, 20)
    .setSize(200, 40)
    .setColorBackground(color(0))
    .setColorForeground(color(0))
    .setColor(color(255))
    .setInputFilter(ControlP5.INTEGER);

 

4) 1~45번까지 수자를 랜덤 하게 생성할 수 있도록 구현

로또번호 1번부터 45번까지 랜덤하게 6개를 생성함.

// 로또 번호 생성
void generateLottoNumbers() {
  generatedLottoNumbers.clear();

  ArrayList<Integer> numbers = new ArrayList<Integer>();
  for (int i = 1; i <= 45; i++) {
      numbers.add(i);
  }

  while (generatedLottoNumbers.size() < gameCount) {
    Collections.shuffle(numbers);
    ArrayList<Integer> tempLottoNumbers = new ArrayList<Integer>(mandatoryNumbers);

    for (int i = 0; i < 6 - mandatoryNumbers.size(); i++) {
      tempLottoNumbers.add(numbers.get(i));
    }

    Collections.sort(tempLottoNumbers);

    if (isValidLottoNumbers(tempLottoNumbers) && !generatedLottoNumbers.contains(tempLottoNumbers)) {
      generatedLottoNumbers.add(tempLottoNumbers);
    }
  }
}

 

5) 게임수 만큼 로또 번호 생성

입력받은 게임 수만큼 로또번호 리스트를 생성함.

  // 게임수만큼 데이터 로또 번호 생성
  while (generatedLottoNumbers.size() < gameCount) {
      generatedLottoNumbers.add(tempLottoNumbers);
  }

 

6) 제약조건 설정 

   - 이전 당첨번호와 동일한 번호는 제거

    if (!generatedLottoNumbers.contains(tempLottoNumbers)) {
      generatedLottoNumbers.add(tempLottoNumbers);
    }

 

   - 3연속 번호는 제거

    if (isValidLottoNumbers(tempLottoNumbers) && !generatedLottoNumbers.contains(tempLottoNumbers)) {
      generatedLottoNumbers.add(tempLottoNumbers);
    }
// 생성된 로또 번호의 유효성 검사
boolean isValidLottoNumbers(ArrayList<Integer> numbers) {
  // 연속된 번호 확인
  for (int i = 0; i < numbers.size() - 2; i++) {
    if (numbers.get(i) + 1 == numbers.get(i + 1) && numbers.get(i) + 2 == numbers.get(i + 2)) {
      return false;
    }
  }

  // 이전 회차와 동일한 번호 확인
  Set<String> keys = previousWinningNumbers.keys();
  for (String key : keys) {
    JSONArray winningNumbers = previousWinningNumbers.getJSONArray(key);
    int matchCount = 0;
    for (int i = 0; i < 6; i++) {
      if (numbers.contains(winningNumbers.getInt(i))) {
        matchCount++;
      }
    }

    if (matchCount == 6) {
      return false;
    }
  }

  return true;
}

 

7) 생성된 번호는 화면에 출력 (출력되는 형식은 콤마(,)로 구분되고, 한 라인에 한게임 리스트형식으로 출력하도록 함)

생성된 로또번호리스트를 화면에 표시함.

한 게임당 한줄씩 표시함.

// 입력 이벤트 처리
void controlEvent(ControlEvent event) {
  if (event.isAssignableFrom(Textfield.class)) {
    String inputGameCount = gameCountInput.getText();
    if (!inputGameCount.isEmpty()) {
      gameCount = int(inputGameCount);
    }
    if (!inputGameCount.isEmpty()) {
      generateLottoNumbers();
      updateScrollList();
    }
  }
}
void displayLottoNumbers() {
  textAlign(CENTER, CENTER);
  textSize(12);
  fill(0);
}

void updateScrollList() {
  ArrayList<String> items = new ArrayList<String>();
  for (ArrayList<Integer> lottoNumbers : generatedLottoNumbers) {
    items.add(lottoNumbers.stream().map(String::valueOf).collect(Collectors.joining(", ")));
  }
  scrollList.setItems(items);
}

 


3. 추가기능

1) 필수 생성 번호 추가 (콤마(,)로 구분하여 입력)

로또 번호 생성시 필수로 포함되어야 할 번호를 입력할 수 있도록 입력 상자를 추가

입력받은 번호는 콤마(,)를 구분자로 하여 여러번호를 입력받을 수 있도록 함.

입력받은 필수 생성 번호는 로또 번호 생성시 무조건 생성되도록 함.

  // 필수 번호 입력 레이블 및 입력 필드 생성
  cp5.addTextlabel("mandatoryNumbersLabel")
    .setText("Enter mandatory numbers (comma separated):")
    .setPosition(20, 80)
    .setColor(color(0));

  mandatoryNumbersInput = cp5.addTextfield("Enter mandatory numbers")
    .setPosition(20, 90)
    .setSize(200, 40)
    .setColorBackground(color(0))
    .setColorForeground(color(0))
    .setColor(color(255));
    if (!inputMandatoryNumbers.isEmpty()) {
      String[] splitMandatoryNumbers = inputMandatoryNumbers.split(",");
      mandatoryNumbers.clear();
      for (String numStr : splitMandatoryNumbers) {
        int num = int(numStr.trim());
        if (num >= 1 && num <= 45) {
          mandatoryNumbers.add(num);
        }
      }
    }
// 로또 번호 생성
void generateLottoNumbers() {
  println("Generating lotto numbers...");
  generatedLottoNumbers.clear();

  // 여기부터 추가
  ArrayList<Integer> numbers = new ArrayList<Integer>();    
  for (int i = 1; i <= 45; i++) {
    if (!mandatoryNumbers.contains(i)) {
      numbers.add(i);
    }
  }
  // 여기까지 추가

  // 게임수만큼 데이터 로또 번호 생성
  while (generatedLottoNumbers.size() < gameCount) {
    Collections.shuffle(numbers);
    ArrayList<Integer> tempLottoNumbers = new ArrayList<Integer>(mandatoryNumbers);

    for (int i = 0; i < 6 - mandatoryNumbers.size(); i++) {
      tempLottoNumbers.add(numbers.get(i));
    }

    Collections.sort(tempLottoNumbers);

    if (isValidLottoNumbers(tempLottoNumbers) && !generatedLottoNumbers.contains(tempLottoNumbers)) {
      generatedLottoNumbers.add(tempLottoNumbers);
    }
  }
  println("Finished generating lotto numbers.");
}

 

2) 생성된 로또 번호를 파일로 저장하는 기능
생성된 로또 번호를 파일로 저장.

저장시 로또번호 구분은 콤마(,)로 구분하여 저장함.

저장 시 파일은 날짜, 시간을 조합하여 저장함.

  // Save 버튼 생성
  saveButton = cp5.addButton("Save to File")
    .setPosition(20, 170)
    .setSize(200, 40)
    .setColorBackground(color(200))
    .setColorForeground(color(150))
    .setColorCaptionLabel(color(0));
} else if (event.isAssignableFrom(Button.class) && event.getName().equals("Save to File")) {
    saveLottoNumbersToFile();
  }
void saveLottoNumbersToFile() {
  DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
  LocalDateTime now = LocalDateTime.now();
  String timestamp = dtf.format(now);
  String fileName = "lotto_numbers_" + timestamp + ".txt";

  PrintWriter output = createWriter(fileName);

  for (ArrayList<Integer> lottoNumbers : generatedLottoNumbers) {
    output.println(String.join(", ", lottoNumbers.stream().map(String::valueOf).toArray(String[]::new)));
  }

  output.flush();
  output.close();

  println("Lotto numbers saved to " + fileName);
}

 


[전체 소스]

LottoNumber.zip
0.01MB

 

 

반응형

'GD's IT Projects' 카테고리의 다른 글

[프로세싱(Processing)] 벽돌 깨기 게임  (0) 2023.05.03

댓글