로또 번호 생성기 (TIL #8)

박감자·2024년 9월 28일

TIL

목록 보기
8/34

시작 전에

이 페이지를 완성한지는 조금 되었는데 TIL 재출은 완전히 잊어버렸다. 하지만 코드를 다시 보다보니 회고하고 싶은 부분이 있어 늦게나마 써보는 중

과제 설명

6개의 로또 번호를 생성하는 페이지 만들기!
각 숫자는 1~45까지의 난수로 이루어진다. 단, 중복되는 숫자가 나와서는 안된다.
추가로 나온 6개의 숫자를 오름차순으로 정리해보기와 이전 숫자와 비교해보는 기능을 넣어보았다.

검색했던 부분

do-while 반복문

난수 여섯개를 생성했을 때 생각보다 중복되는 숫자가 많았다. 그래서 새로 생성된 난수가 이미 존재하는지 알아보고 중복되지 않는 숫자가 나올때까지 난수를 생성하는 코드가 필요했다. 이를 의사코드(pseudocode)로 표현했을 때

nums = []   // 생성한 숫자 저장하는 역할

// 1번째 난수 생성
// nums에 저장

// 2번째 난수 생성
// nums에 존재하는지 확인
if 중복되지 않는 숫자:
	// nums에 저장
else:	// 중복된 상황
	// 난수 새로 생성
    if 중복되지 않는 숫자:
    	// nums에 저장
    else:
    	// 난수 새로 생성
        
        // ...? 이거 무한 반복??

이렇게 머리 아픈 코드가 나온다. 그래서 생각해 낸 것이 do-while 반복문이었다. 근데 이제 JS 문법이 가물가물한ㅋㅋ, 그리하여 검색하게 되었다.

do-while 반복문은 do부분의 코드를 조건 상관 없이 일단 한 번 실행한 뒤 while조건에 부합이 된다면 계속해서 반복하는 반복문이다.
과제의 상황에 대입하자면:

do {
	// 난수 생성 코드
    random = ...;
} while(nums.includes(random));		// nums에 random이 존재하는지 체크

일단 do부분의 코드를 실행해서 난수를 만든다. 그런 다음 while조건문에 대입해서 확인한다.

  1. 난수가 nums에 있다 -> true (do부분 반복)
  2. 난수가 nums에 없다 -> false (반복문을 끝낼 것)

이렇게 생성한 난수가 중복되는지 확인하는 코드를 구현했다. 총 6개의 난수가 필요하므로 6번 반복하게끔 for 반복문을 사용하여 코드를 작성하면

function generateLottoNumbers() {
  let nums = [];
  
  for (let i = 0; i < 6; i++) {
  	let random = 0;
    do {
    	// 난수 생성 코드 대입: 1~45의 정수
    } while (nums.includes(random));
    
    // 중복되지 않는 random 생성
    nums.push(random);
  }
  return nums;
}

난수 생성 함수 완성!

숫자 배열 오름차순

참고: 자바스크립트 배열 정렬: sort()와 toSorted() 함수

정렬하는 함수인 sort()를 무작정 로또 숫자 배열에 사용했다가 알아낸 점은 안된다는 것이었다. 정확히는

18, 2, 16, 14, 42, 31
>>> 14, 16, 18, 2, 31, 42

이런식으로 정렬이 되었는데, 앞자리의 숫자로 정리되고 있었다. 아니나 다를까 찾아보니 sort()를 매개변수 없이 사용시 일반 텍스트 배열을 비교하기 때문에 첫번째 글자가 크다면 '2'가 '18'보다 크게 정렬이 된다. 따라서 비교하는 함수를 매개변수로 넣어주어야 한다.
참고: MBN sort() Syntax

비교 함수만 적자면

nums.sort((a, b) => a - b);		// 오름차순
nums.sort((a, b) => b - a);		// 내림차순

정렬버튼에 addEventListner안의 함수를 위의 오름차순 함수를 추가하여 오름차순 정렬을 완성시켰다.

document.getElementById("sortButton").addEventListener("click", function () {
  if (document.getElementById("nums").textContent != "") {
    // 오름차순 정렬
    numbers.sort((a, b) => a - b);

    // 필요한 div에 붙여넣는 코드
  } else {
    alert("숫자를 먼저 생성해주세요");
  }
});

추가사항

이전 숫자 저장하기

document.getElementById('generateButton').addEventListener('click', function() {
    let numbers = generateLottoNumbers();  // 버튼이 눌리면 난수 생성.
    // div에 numbers 추가하는 코드
});

추가로 이전 숫자를 저장하기 위해 기존의 로또 번호 배열을 글로벌 변수로 바꾸어 주고 생성버튼의 addEventListener를 변경해주었다.

let numbers = [];	//글로벌 변수로 변경

document.getElementById('generateButton').addEventListener('click', function() {
    numbers = generateLottoNumbers();  // 글로벌 변수에 새로운 로또 번호 저장
  	
  	// 이전 숫자는 아직 페이지에 보여지는 중이기에
  	// HTML요소를 그대로 들고와서 '이전 숫자:' 옆에 붙여주기
  	const prev = document.getElementById("numbers).textContent;
  
    // id:numbers div에 numbers 추가하는 코드
                                         
    // '이전 숫자:' 옆에 prev 번호 붙여주기
});

마치며...

개인적으로는 sort()가 초반에 가장 당황스러운 결과를 줘서 조금 시간이 걸렸지만 그럭저럭 괜찮다고 생각한 과제였다. 로또는 해본적이 없지만 하게 되면 유용하게 쓸것만 같은 페이지였다ㅋㅋ.

profile
코딩하는 감자

0개의 댓글