-
[Javascript] 자바스크립트 로또 추첨기Javascript 2023. 5. 19. 18:57반응형
6-1. 로또 추첨기 순서도 그리기
비동기
- 동기의 반댓말
- 실제로 코딩한 순서와 다르게 동작하는 코드
- 위 → 아래, 왼쪽 → 오른쪽으로 실행되는 것이 아니라 작성된 위치와 다른 곳에서 실행되는 코드가 있다면, 비동기를 의심해 볼 수 있다.
- 대표적인 예로 이벤트 리스, 타이머
순서도 그리기
- 시작
- 1~45 까지의 숫자를 준비한다
- 숫자를 섞는다
- 공 7개를 뽑는다. 마지막 공은 보너스 공이 된다
- 1초마나 공을 하나씩 화면에 표시한다
- 끝
6-2. 공뽑기(피셔 예이츠 셔플)
피셔 예이츠 셔플
유한 수열의 무작위 순열을 생성하기 위한 알고리즘
<script> // 1 ~ 45까지의 숫자 뽑기 const candidate = Array(45).fill().map((v, i) => i + 1); // const shuffle = []; while (candidate.length > 0) { const random = Math.floor(Math.random() * candidate.length); // 무작위로 인덱스 뽑기 const spliceArray = candidate.splice(random, 1); // 뽑은 값은 배열에 등록하기 const value = spliceArray[0]; // 배열에 들어있는 값을 꺼내기 shuffle.push(value); // shuffle 배열에 넣기 } console.log(shuffle); </script>
🟡 코드 설명
const spliceArray = candidate.splice(random, 1); // 뽑은 값은 배열에 등록하기
◆ splice reutrn 값
splice로 제외한 값이 리턴값으로 들어있다.
const value = spliceArray[0]; // 배열에 들어있는 값을 꺼내기 shuffle.push(value); // shuffle 배열에 넣기
splice의 리턴 값을 꺼내 shuffle 배열에 넣는 코드
🟡 결과
이 중 앞 6개 + 1개(보너스)를 로또번호로 지정한다
■ Tip
while문: 조건이 간단할 때, 정확한 반복 횟수를 모를 때 사용하기 좋다.
for문: 조건이 복잡할 때, 반복 횟수를 정확히 알고 있을 때, i = i+2와 같은 조건이 사용될 때 유용하다.for문으로 바꾸었을 경우
const candidate = Array(45).fill().map((v, i) => i + 1); const shuffle = []; for(let i =candidate.length; i > 0; i--) { const random = Math.floor(Math.random() * i); // 무작위로 인덱스 뽑기 const spliceArray = candidate.splice(random, 1); // 뽑은 값은 배열에 등록하기 const value = spliceArray[0]; // 배열에 들어있는 값을 꺼내기 shuffle.push(value); // shuffle 배열에 넣기 } console.log(shuffle);
6-3. 공 정렬하기(sort)
<script> ... const winBalls = shuffle.slice(0, 6).sort((a,b) => a - b); const bouns = shuffle[6]; console.log(winBalls, bouns); </script>
🟡 slice
- arr.slice(3, 5) : 인덱스 3부터 5까지 자르기
- slice 사용 시, 원본 배열은 변하지 않는다. (=map메소드의 특성) ↔ splice는 원본을 수정한다.
- arr.slice(-5, -1) : 뒤에서 5번째 인덱스부터 뒤에서 첫번째 인데 전까지 자르기
🟡 sort(정렬)
- 리턴 값에 따라 어떻게 정렬할 지 결정된다.
- a - b : 오름차순 정렬
- b - a : 내림차순 정
- sort 사용 시, 배열 원본이 수정된다.
- 원본을 다시 사용해야 할 일이 많기 때문에, 원본 배열이 수정되는 것이 불편할 수 있다.
🟡 slice + sort (정렬)
slice 실행 시, 새로 만들어진 배열은 기존 배열과 다른 복사본이다.
slice() 사용 시 원본 배열이 변하지 않기 때문에 원본 배열을 이용해 다양한 기능을 구현할 수 있다.
🟡 문자열 sort
arr.slice().sort((a, b) => a[0].charCodeAt() - b[0].charCodeAt()) //오름차순 정렬 arr.slice().sort((a, b) => b[0].charCodeAt() - a[0].charCodeAt()) //내림차순 정렬
첫번째 글자의 코드 넘버를 비교해서 오름차순, 내림차순 정렬
첫번째 글자만 비교하기 때문에 첫번째 글자가 동일한 (ex. ['abc', 'acb'])문자열은 변경되지 않는다.
(사전순으로 정렬되지 않는다.)
arr.slice().sort((a, b) => a.localeCompare(b)) //오름차순 arr.slice().sort((a, b) => b.localeCompare(a)) //내림차순
localeCompare() : 사전 순 정렬 메소드, 한글도 가능
6-4. 일정 시간 후 실행하기(setTimeout)
setTimeout(() => { // 함수 자리 }, 밀리초)
- 1초 = 1000밀리초
- 밀리쵸 부분에 1000을 적어주면, 1초 후 실행
실행 화면
// 숫자 원 보여주는 것 const showBall = () => { const $ball = document.createElement("div"); //div태그 만들기 $ball.className = "ball"; // class 말고 className으로 해야됨 $ball.textContent = number; // $target.appendChild($ball); }; setTimeout(() => { showBall(winBalls[0], $result); },1000); setTimeout(() => { showBall(winBalls[1], $result); },2000); setTimeout(() => { showBall(winBalls[2], $result); },3000); setTimeout(() => { showBall(winBalls[3], $result); },4000); setTimeout(() => { showBall(winBalls[4], $result); },5000); setTimeout(() => { showBall(winBalls[5], $result); },6000); setTimeout(() => { showBall(bouns, $bonus); },8000);
위 코드를 반복문 사용하지 않고 적은 것
정리된 코드
<script> ... // 숫자 원 보여주는 것 const showBall = () => { const $ball = document.createElement("div"); //div태그 만들기 $ball.className = "ball"; // class 말고 className으로 해야됨 $ball.textContent = number; // $target.appendChild($ball); }; // [0, 1, 2, 3, 4, 5] -> [1000, 2000, 3000, 4000, 5000, 6000] for(let i = 0; i < 6; i++){ setTimeout(() => { showBall(winBalls[0], $result); }, (i + 1) * 1000); //(i + 1)초 뒤에 추가 } // 마지막은 보너스 볼 보여준다. setTimeout(() => { showBall(bouns, $bonus); },7000); </script>
Tip
- 자바스크립트의 타이머는 정확하지 않다.
- setTimeout의 내부 함수가 하나이고 인수가 없는 경우, 다음과 같이 축약해 작성할 수 있다.
setTimeout(func,3500);
최종 코드
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>로또 추첨기</title> <style> .ball { display: inline-block; border:1px solid black; border-radius:20px; width: 40px; height: 40px; line-height: 40px; font-size: 20px; text-align: center; margin-right: 20px; } </style> </head> <body> <div id="result">추첨 결과는? </div> <div id="bonus">보너스: </div> <script> // 1 ~ 45까지의 숫자 뽑기 const candidate = Array(45).fill().map((v, i) => i + 1); const shuffle = []; while (candidate.length > 0) { const random = Math.floor(Math.random() * candidate.length); // 무작위로 인덱스 뽑기 const spliceArray = candidate.splice(random, 1); // 뽑은 값은 배열에 등록하기 const value = spliceArray[0]; // 배열에 들어있는 값을 꺼내기 shuffle.push(value); // shuffle 배열에 넣기 } console.log(shuffle); // 랜덤 된 값을 정리함 const winBalls = shuffle.slice(0, 6).sort((a,b) => a - b); const bouns = shuffle[6]; console.log(winBalls, bouns); const $result = document.querySelector("#result"); const $bonus = document.querySelector("#bonus"); // 숫자 원 보여주는 것 const showBall = () => { const $ball = document.createElement("div"); //div태그 만들기 $ball.className = "ball"; // class 말고 className으로 해야됨 $ball.textContent = number; // $target.appendChild($ball); }; // [0, 1, 2, 3, 4, 5] -> [1000, 2000, 3000, 4000, 5000, 6000] for(let i = 0; i < 6; i++){ setTimeout(() => { showBall(winBalls[0], $result); }, (i + 1) * 1000); //(i + 1)초 뒤에 추가 } // 마지막은 보너스 볼 보여준다. setTimeout(() => { showBall(bouns, $bonus); },7000); </script> </body> </html>
영상 출처
반응형'Javascript' 카테고리의 다른 글
[JavaScript] 자바스크립트 셀프 체크 - 공 색칠하기 (1) 2023.05.24 [Javascript] 자바스크립트 블록, 함수 스코프, 클로저 문제 (0) 2023.05.23 [Javascript] 배열 forEach, map, fill 배우기 (0) 2023.05.18 [JavaScript] 자바스크립트 강좌 셀프 체크-아웃 만들기 (0) 2023.05.17 [JavaScript] 자바스크립트로 숫자 야구 게임 만들기 (0) 2023.05.15