4개의 숫자를 제한된 기회 안에 맞추는 게임으로, 야구의 규칙 용어만 가져옴
게임 규칙 :
1. 상대편이 숫자 1~9 중 중복되지 않게 4개를 고름
2. 10 번의 기회가 주어지고, 그 안에 해당 숫자 4개를 순서포함해서 맞춰야함
3. 10번의 기회 동안 다음의 힌트가 계속 주어진다
- 볼(ball) : 숫자만 맞힌 개수 (순서 상관 x)
- 스트라이크(strike) : 숫자 뿐만 아니라 순서까지 맞힌 개수
- 볼과 스트라이크는 각각 별개로 취급
- 4개의 숫자가 하나도 맞지 않으면 아웃 (out)
- 3 아웃이면 패배
- 4개의 숫자가 맞고 순서도 맞다면 홈런 (home run) 승리!
example)
상대편이 제시한 숫자 :
5728
플레이어가 말한 숫자 :
7129 ⇒ 1 스트라이크 1 볼 (7은 숫자만 맞혔으니 볼, 2는 숫자에 순서까지 맞혔으니 스트라이크)
7528 ⇒ 2 스트라이트 2볼
7285 ⇒ 4볼
1396 ⇒ 아웃
5728 ⇒ 홈런
원래 random () 은 진짜 무작위가 아니라, 임시비밀번호 다루는곳에 쓰면 위험하다.
window.crypto.getRandomValues()
라는 함수가 더 랜덤효과가 크다
html
<form action="">
<input type="text" />
<input type="submit" value="제출">
</form>
<div id="logs"></div>
const $form = document.querySelector('form')
const $input = $form.querySelector('input[type=text]')
const $btn = $form.querySelector('input[type=submit]')
const $logs = document.querySelector('#logs')
// 초기 상황
// numbers [1, 2, 3, 4, 5, 6, 7, 8, 9]
// answer []
// 1. 1 ~ 9 의 숫자 생성
const numbers = [] // numbers 배열 안에 1 ~ 9 의 숫자 생성
for (let n = 0; n < 9; n++) {
numbers.push(n + 1) // [1, 2, 3, 4, 5, 6, 7, 8, 9] => 0 베이스이기 떄문에 1 더해주기
}
// 2. 상대편이 1 ~ 9 의 숫자 중 랜덤의 숫자 뽑기
// answer 부분에서는 numbers 의 숫자중 '몇 번째' 숫자를 골라내는, index 개념으로 뽑음
// 예) 4번째 숫자를 고르고싶다면 index 번호는 그보다 1이 작은 3이여야 한다
const answer = [] // numbers[1 ~ 9] 의 숫자들을 랜덤으로 뽑은 후 answer 배열에 담기 (ex. [3, 1, 4, 6])
for (let n = 0; n < 4; n++) {
// const index = Math.floor(Math.random() * 9) => x
const index = Math.floor(Math.random() * (numbers.length))
// 0 ~ 현재 index 의 정수 (numbers 숫자중 랜덤으로 하려면 numbers.length 값을 곱해야 함)
answer.push(numbers[index])
// index 엔 + 1 을 안한 이유는, 순서의 개념이기 때문에, 0이 들어가고 자동으로 1번째부터 시작하는 것이 맞다
numbers.splice(index, 1)
}
const index = Math.floor(Math.random() * 9)
로 하면 안되는 이유 :numbers 에서 랜덤으로 숫자가 계속 뽑혀나가 제거되는 만큼 numbers.length 값은 줄어든다.
ex) numbers[2, 3, 4, 6] 만 남은 상황에서 Math.random 을 통해 index 9번째 숫자를 뽑으려 하면, numbers 배열 아이템의 index 값은 현재 3(0, 1, 2, 3)까지 밖에 없기 때문에 undefined 가 되어버린다.
ex) console.log(answer) => [3, 4, 1, undefined]
해결책 : 반복문을 거칠 수록 numbers.length 값은 줄어드므로, 9개로 고정시키는 것이 아닌 그냥 numbers.length 자체로 고침
(반복문을 거칠수록 알아서 number.length 값 자체가 줄어들기 때문)
splice
(index 값, 제거할 요소의 개수) : 배열에서 아이템을 제거해석: 반복문에서 선택된 index 값의 숫자를 하나(1) 제거
ex) number[1 ~ 9]에서 index 값이 3인 [숫자 4]를 뽑아 answer 배열로 넘어가면,
다음에 랜덤식별될 숫자가 또 중복되지 않게 하기 위해 number 의 해당 [숫자4]를 삭제
(카드게임에서 카드를 뽑으면 해당 카드는 수중에서 사라지는 것처럼)
제출한 숫자가 제출형식에 맞는지 확인,
제출형식에 통과한 value 값을 통해
(1) 홈런인지 식별
(2) 10번 이상 제출했는지 식별 (한정된 기회)
const $form = document.querySelector('form') // html 태그를 선택하여 담은 변수는 $로 구분
const $input = $form.querySelector('input[type=text]')
const $btn = $form.querySelector('input[type=submit]')
const $logs = document.querySelector('#logs')
// 초기 상황
// numbers [1, 2, 3, 4, 5, 6, 7, 8, 9]
// answer []
// --------------------------------------------------------------------------------------------------
// 1. 1 ~ 9 의 숫자 생성
const numbers = [] // numbers 배열 안에 1 ~ 9 의 숫자 생성 -----------------------------------------------
for (let n = 0; n < 9; n++) {
numbers.push(n + 1) // [1, 2, 3, 4, 5, 6, 7, 8, 9] => 0 베이스이기 떄문에 1 더해주기
}
// --------------------------------------------------------------------------------------------------
// 2. 상대편이 제시하는 수로, 1 ~ 9 의 숫자 중 랜덤의 숫자 뽑기 -------------------------------------------------
// answer 부분에서는 numbers 의 숫자중 '몇 번째' 숫자를 골라내는, index 개념으로 뽑음
// 예) 4번째 숫자를 고르고싶다면 index 번호는 그보다 1이 작은 3이여야 한다
const answer = [] // numbers[1 ~ 9] 의 숫자들을 랜덤으로 뽑은 후 answer 배열에 담기 (ex. [3, 1, 4, 6])
for (let n = 0; n < 4; n++) {
const index = Math.floor(Math.random() * (numbers.length))
// 0 ~ 현재 index 의 정수 (numbers 숫자중 랜덤으로 하려면 numbers.length 값을 곱해야 함)
answer.push(numbers[index])
// index 엔 + 1 을 안한 이유는, 순서의 개념이기 때문에, 0이 들어가고 자동으로 1번째부터 시작하는 것이 맞다
numbers.splice(index, 1)
}
console.log(answer)
const tries = [] // [3416, 3948, 1234, 5289 ...] 등의 형태로 값이 들어가는 배열**
// --------------------------------------------------------------------------------------------------
function checkInput(input) { // 4. 유저가 시도한 숫자인 input의 입력값을 검사 ---------------------------------
if (input.length !== 4) { // (1) 길이는 4가 아닌가?
return alert('4자리 숫자를 입력해주세요.')
// alert 값은 undefined 로, 중간에 if 문에 걸리면 undefined 값이 반환되는 것과 똑같다
}
if (new Set(input).size !== 4) { // (2) 중복된 숫자 있는가? (각 숫자리 중복표시)
return alert('중복되지 않게 입력해주세요.')
}
if (tries.includes(input)) { // (3) 이미 시도한 값은 아닌가?
return alert('이미 시도한 값입니다')
}
return true // 위의 if 문의 관문들을 모두 통과하면 true 값을 반환 해줌 (checkInput(value) === true)
// alert 값은 undefined 로, 중간에 if 문에 하나라도 걸리면 undefined 값이 반환되는 것과 똑같다
// (return undefined, 즉 checkInput(value) === false)
}
// --------------------------------------------------------------------------------------------------
$form.addEventListener('submit', (event) => { // 3. 유저가 숫자 맞추기 시도 ------------------------------
event.preventDefault();
const value = $input.value // const toDo = input.value 와 같음
$input.value = '' // 숫자 입력, 제출 후 바로 다음 숫자를 입력이 가능하도록 value 값 비우기
if (checkInput(value)) { // 위의 checkInput(value)에서 모든 if 문 과정 끝에 true 값을 받으면, 해당 함수가 작동됨
// 입력값 문제 없음 (합격)
if (answer.join('') === value) {
$logs.textContent = '홈런!'
}
if (tries.length > 10) { // 10번의 기회를 다 썼는가?
const message = document.createTextNode(`패배! 정답은 ${answer.join()}`)
$logs.appendChild(message)
return
}
} else { // 반면 alert 로 인해 undefined 값을 받아 false 를 리턴하면 작동되지 않고 에러가 뜸
return // 에러 있음 (불합격)
}
// 몇 스트라이크 몇 볼인지 검사
tries.push(value) // 홈런도 안되고, 아웃도 안됐으면 마저 계속 입력값을 넣어 숫자맞추기 진행
})
new Set(input).size !== 4
new Set 은 배열과 비슷한 개념으로 중복이 없는 배열, 즉 알아서 중복을 제거해줌
ex) 만약 3144 라는 중복숫자가 들게 입력하면, 중복되는 두 개의 숫자4 중 하나를 자동으로 제거해서 314 가
된다. (3144 => 314(실제 new Set 값))
즉 new Set(input).size의 값은 3이 되고 (.length 의 개념으로, new Set 은 .length 가 아닌 .size 이다)
실제 값인 3 !== 4 로 비교 연산되면서 경고창이 뜨게한다.
tries.includes(input)
유저가 answer로 숫자를 뽑는 시도를 행할 때마다 tries 에 유저가 적었던 4자리 값들이 저장됨
tries 배열에 들어가는 값 중 이미 한번 시도했던 값이 있는 상태에서, 유저가 똑같은 값을 넣으면
그 값이 이미 포함 되어있다고 알려준다. (4자리 숫자 전체(숫자, 순서) 중복 표시)
value 는 문자열 상태
if (answer.join('') === value)
join('') : 배열 요소들을 문자열로 바꾸어 나열된 문자형태로 만들어줌
ex) [3, 1, 4, 6] => 3146 (순서 확인을 위해 문자열로 묶어 나열)
join() 과 같이 ''를 안넣으면 3, 1, 4, 6 과 같이 콤마가 붙음 (콤마가 기본값이기 때문에)
ex) join(' : ') ⇒ 3 : 1 : 4 : 6
split() : join() 과 반대되는 메서드
ex) '3146'.split() ⇒ [ "3146" ]
'3146'.split("") ⇒ ["3", "1", "4", "6"]
'3146'.split("1") ⇒ ["3", "46"] (1을 기점으로 갈라짐)
if (checkInput(value))
>> 중첩된 if 문을 풀어보자if (!checkInput(value)) {
return
}
if (answer.join('') === value) {
$logs.textContent = '홈런!'
}
if (tries.length > 10) {
const message = document.createTextNode(`패배! 정답은 ${answer.join()}`)
$logs.appendChild(message)
return
}
tries.push(value)
})
(3) 몇 스트라이크 몇 볼인지 검사
const $form = document.querySelector('form') // html 태그를 선택하여 담은 변수는 $로 구분
const $input = $form.querySelector('input[type=text]')
const $btn = $form.querySelector('input[type=submit]')
const $logs = document.querySelector('#logs')
// 1. 1 ~ 9 의 숫자 생성
const numbers = [] // numbers 배열 안에 1 ~ 9 의 숫자 생성
for (let n = 0; n < 9; n++) {
numbers.push(n + 1) // [1, 2, 3, 4, 5, 6, 7, 8, 9] => 0 베이스이기 떄문에 1 더해주기
}
// 2. 상대편이 제시하는 수로, 1 ~ 9 의 숫자 중 랜덤의 숫자 뽑기
const answer = []
for (let n = 0; n < 4; n++) {
const index = Math.floor(Math.random() * (numbers.length))
// 0 ~ 현재 index 의 정수 (numbers 숫자중 랜덤으로 하려면 numbers.length 값을 곱해야 함)
answer.push(numbers[index])
// index 엔 + 1 을 안한 이유는, 순서의 개념이기 때문에, 0이 들어가고 자동으로 1번째부터 시작하는 것이 맞다
numbers.splice(index, 1)
// splice(index 값, 제거할 요소의 개수) : 배열에서 아이템을 제거
}
console.log(answer)
const tries = [] // [3416, 3948, 1234, 5289 ...] 등의 형태로 값이 들어가는 배열
function checkInput(input) { // 4. 유저가 시도한 숫자인 input의 입력값을 검사 ---------------------------------
if (input.length !== 4) { // (1) 길이는 4가 아닌가?
return alert('4자리 숫자를 입력해주세요.')
// alert 값은 undefined 로, 중간에 if 문에 걸리면 undefined 값이 반환되는 것과 똑같다
}
if (new Set(input).size !== 4) { // (2) 중복된 숫자 있는가? (각 숫자리 중복표시)
// new Set 은 배열과 비슷한 개념으로 중복이 없는 배열, 즉 알아서 중복을 제거해줌
return alert('중복되지 않게 입력해주세요.')
}
if (tries.includes(input)) { // (3) 이미 시도한 값은 아닌가?
return alert('이미 시도한 값입니다')
}
return true // 위의 if 문의 관문들을 모두 통과하면 true 값을 반환 해줌 (checkInput(value) === true)
}
$form.addEventListener('submit', (event) => { // 3. 유저가 숫자 맞추기 시도 ------------------------------
event.preventDefault();
const value = $input.value // const toDo = input.value 와 같음
$input.value = '' // 숫자 입력, 제출 후 바로 다음 숫자를 입력이 가능하도록 value 값 비우기
if (!checkInput(value)) { // 위의 checkInput(value)에서 모든 if 문 과정 끝에 true 값을 받으면, 해당 함수가 작동됨
return
}
// 입력값 문제 없음 (합격)
if (answer.join('') === value) {
// join('') : 배열안의 아이템들을 문자열로 바꾸어 나열된 문자형태로 만들어줌 (순서 확인을 위해 문자열로 묶어 나열)
// ex) [3, 1, 4, 6] => 3146
$logs.textContent = '홈런!'
return
}
if (tries.length >= 9) { // 10번째 시도에서는 tries.length 가 9이다
// 9번째까지 온 상태에서 10번째 턴이 틀리면
const message = document.createTextNode(`패배! 정답은 ${answer.join()}`)
$logs.appendChild(message)
return
}
// 몇 스트라이크 몇 볼인지 검사
let strike = 0;
let ball = 0;
for(let i = 0; i < answer.length; i++) {
const index = value.indexOf(answer[i])
// 방법 : answer 의 아이템(answer[i])값을 'value 아이템의 인덱스 확인하는 용도'의 메서드에 넣어 확인
// value 와 answer 의 아이템 중 겹치는 것이 있는지 확인 후 변수에 담음
if(index > -1) { // 겹치는 숫자가 있는가?
// (indexOf() 로 값을 찾을 때, 값이 안들어있으면 -1 을 반환함)
if(index === i) { // 순서, 숫자 모두 같은가? (index: value 인덱스순서, i: answer 인덱스 순서)
strike += 1
} else { // 순서 x 숫자만 같은가?
ball += 1
}
}
}
$logs.append(`${value}: ${strike} 스트라이크 / ${ball} 볼`, document.createElement('br'))
// append() 에는 , 를 찍어 여러 개의 요소를 넣을 수 있음
tries.push(value) // 홈런도 안되고, 아웃도 안됐으면 마저 계속 입력값을 넣어 숫자맞추기 진행
})
'1234'.includes(3) === true;
[1, 2, 3, 4].includes(5) === false;
'2345'.indexOf(3) === 1;
'2345'.indexOf(6) === -1;
['2', '3', '4', '5'].indexOf('5') === 3;
['2', '3', '4', '5'].indexOf(5) === -1; // 요소의 자료형이 같지 x
const message = document.createTextNode(`패배! 정답은 ${answer.join()}`)
$logs.appendChild(message)
$logs.append(`${value}: ${strike} 스트라이크 / ${ball} 볼`, document.createElement('br'))
(4) 아웃인지 검사, 3아웃일 때 패배 표시
const $form = document.querySelector('form') // html 태그를 선택하여 담은 변수는 $로 구분
const $input = $form.querySelector('input[type=text]')
const $btn = $form.querySelector('input[type=submit]')
const $logs = document.querySelector('#logs')
// 초기 상황
// numbers [1, 2, 3, 4, 5, 6, 7, 8, 9]
// answer []
// --------------------------------------------------------------------------------------------------
// 1. 1 ~ 9 의 숫자 생성
const numbers = [] // numbers 배열 안에 1 ~ 9 의 숫자 생성 -----------------------------------------------
for (let n = 0; n < 9; n++) {
numbers.push(n + 1) // [1, 2, 3, 4, 5, 6, 7, 8, 9] => 0 베이스이기 떄문에 1 더해주기
}
// --------------------------------------------------------------------------------------------------
// 2. 상대편이 제시하는 수로, 1 ~ 9 의 숫자 중 랜덤의 숫자 뽑기 -------------------------------------------------
// answer 부분에서는 numbers 의 숫자중 '몇 번째' 숫자를 골라내는, index 개념으로 뽑음
for (let n = 0; n < 4; n++) {
const index = Math.floor(Math.random() * (numbers.length))
// 0 ~ 현재 index 의 정수 (numbers 숫자중 랜덤으로 하려면 numbers.length 값을 곱해야 함)
answer.push(numbers[index])
// index 엔 + 1 을 안한 이유는, 순서의 개념이기 때문에, 0이 들어가고 자동으로 1번째부터 시작하는 것이 맞다
numbers.splice(index, 1)
}
console.log(answer)
const tries = [] // [3416, 3948, 1234, 5289 ...] 등의 형태로 값이 들어가는 배열
// --------------------------------------------------------------------------------------------------
function checkInput(input) { // 4. 유저가 시도한 숫자인 input의 입력값을 검사 ---------------------------------
if (input.length !== 4) { // (1) 길이는 4가 아닌가?
return alert('4자리 숫자를 입력해주세요.')
// alert 값은 undefined 로, 중간에 if 문에 걸리면 undefined 값이 반환되는 것과 똑같다
}
if (new Set(input).size !== 4) { // (2) 중복된 숫자 있는가?
return alert('중복되지 않게 입력해주세요.')
}
if (tries.includes(input)) { // (3) 이미 시도한 값은 아닌가?
return alert('이미 시도한 값입니다')
}
return true // 위의 if 문의 관문들을 모두 통과하면 true 값을 반환 해줌
}
// --------------------------------------------------------------------------------------------------
function defeated() { // 중복 함수 처리
const message = document.createTextNode(`패배! 정답은 ${answer.join('')}`)
$logs.appendChild(message)
}
// --------------------------------------------------------------------------------------------------
let out = 0 // 아웃 횟수 담을 변수 설정
$form.addEventListener('submit', (event) => { // 3. 유저가 숫자 맞추기 시도 ------------------------------
event.preventDefault();
const value = $input.value // const toDo = input.value 와 같음
$input.value = '' // 숫자 입력, 제출 후 바로 다음 숫자를 입력이 가능하도록 value 값 비우기
if (!checkInput(value)) { // 위의 checkInput(value)에서 모든 if 문 과정 끝에 true 값을 받으면, 해당 함수가 작동됨
return
}
// 입력값 문제 없음 (합격)
if (answer.join('') === value) {
// join('') : 배열안의 아이템들을 문자열로 바꾸어 나열된 문자형태로 만들어줌 (순서 확인을 위해 문자열로 묶어 나열)
// ex) [3, 1, 4, 6] => 3146
$logs.textContent = '홈런!'
return
}
if (tries.length >= 9) { // 10번째 시도에서는 tries.length 가 9이다
// 9번째까지 온 상태에서 10번째 턴이 틀리면
defeated()
return
}
// 몇 스트라이크 몇 볼인지 검사
// (length 의 길이가 같은 두 개의 배열을 비교해 겹치는 배열아이템 선별 알고리즘)
// 항상
let strike = 0;
let ball = 0;
// 예시를 들어가며 코드 풀이
// ex) answer = [3, 1, 4, 6]
// value = [1, 3, 4, 7]
for (let i = 0; i < answer.length; i++) {
const index = value.indexOf(answer[i])
// 방법 : answer 의 아이템(answer[i])값을 'value 아이템의 인덱스 확인하는 용도'의 메서드에 넣어 확인
// value 와 answer 의 아이템 중 겹치는 것이 있는지 확인 후 변수에 담음
if (index > -1) { // 겹치는 숫자가 있는가?
// (indexOf() 로 값을 찾을 때, 값이 안들어있으면 -1 을 반환함)
if (index === i) { // 순서, 숫자 모두 같은가? (index: value 인덱스순서, i: answer 인덱스 순서)
strike += 1
} else { // 순서 x 숫자만 같은가?
ball += 1
}
}
}
// 아웃 일 때
if (strike === 0 && ball === 0) { // 아웃의 조건: 0 스트라이크 0 볼
out++ // 실행시 마다 아웃 횟수 증가
$logs.append(`${value}: ${out}아웃 `, document.createElement('br'))
} else { // 홈런, 아웃 둘 다 아닐 때 마지막에 실행
$logs.append(`${value} : ${strike} 스트라이크 / ${ball} 볼`, document.createElement('br'))
// append() 에는 , 를 찍어 여러 개의 요소를 넣을 수 있음
}
if (out === 3) {
defeated()
return
}
tries.push(value) // 홈런도 안되고, 아웃도 안됐으면 마저 계속 입력값을 넣어 숫자맞추기 진행
})
for 문 ⇒ forEach() 형태로 바꾸기
forEach( element, index, array )
// for 문
answer = []
let strike = 0;
let ball = 0;
for (let i = 0; i < answer.length; i++) {
const index = value.indexOf(answer[i])
if (index > -1) {
if (index === i) {
strike += 1
} else {
ball += 1
}
}
}
// forEach(요소 값, 요소 인덱스, 배열)
answer = []
let strike = 0;
let ball = 0;
answer.forEach((answerItem, i) => {
const index = value.indexOf(answerItem)
if (index > -1) {
if (index === i) {
strike += 1
} else {
ball += 1
}
}
})
forEach() 의 역할도 하면서, return 이 있어 적혀진 그대로 기존의 배열에 영향을 주지 않으면서 그로부터
파생된 새로운 배열의 생성이 가능하다
ex) 2씩 곱해지는 기능
// for 문
const array = [1, 2, 3, 4]
const result = [] // 빈 배열 생성
for (let i = 0; i < 4; i++) {
result.push(array[i] * 2)
}
// result = [2, 4, 6, 8]
// map()
// 빈 배열 생성할 필요 x
const array = []
array.map((item, i) => {
return item * 2
})
// [2, 4, 6, 8] => 새로운 배열이 생성됨
// array = [1, 2, 3, 4] => 기존 배열에는 영향 없음
Array(5) // length 가 5 인 (텅 빈) 배열
Array(5).fill(0) // 0 값이 채워짐
// => [0, 0, 0, 0, 0]
// 빈 배열에 1 ~ 9 까지의 요소를 넣고 싶다면?
Array(9).fill().map((item, index) => {
return index + 1
})
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
문제 해결:
보통 처음 게임을 접할 때 우리는 게임 방법을 인지를 해야하므로 게임 설명을 먼저 읽는다. 하지만 게임을 하고 나면, 룰을 이미 알고있어 설명을 보지 않아도 게임을 진행할 수 있다. 게임 룰 창을 만든 후 테스트해본 결과 게임 창을 열때마다 이미 읽지않아도 되는 룰이 계속 뜨는 부분이 번거로웠다. 이를 해결하기 위해, 이전에 다른 강의에서 localStorage()
를 통해 로컬저장소에 저장하면 새로고침을 해도 데이터의 손상없이 저장되는 방법을 기억하여 그부분을 응용해보았다. 그렇게 하여 게임 룰을 한 번 닫으면 게임 다시하기 버튼을 눌러도 게임룰이 더이상 뜨지 않고 게임을 진행할 수 있게 되었다. 하지만 룰을 잊을 경우를 대비하여 다시 따로 게임 설명을 킬 수 있는 버튼도 만들었다. 그리고 앞으로의 모든 게임에 적용시키기 위해 공통코드로 만들어 주었다.
const $startBtn = document.querySelector('.start')
const $gameRule = document.querySelector('#gameRule')
const $overLay = document.querySelector('.overlay')
const $exitBtn = document.querySelector('.btn--exit')
// 게임 룰
function hideGameRule() {
$gameRule.classList.add('hidden')
$overLay.classList.add('hidden')
}
// 게임 시작하기, 읽음 여부 세팅
$startBtn.addEventListener('click', () => {
hideGameRule()
localStorage.setItem('readOrNot', 'read');
})
// gameRule 읽음 여부 확인
const savedRead = localStorage.getItem('readOrNot')
if(savedRead !== null) {
hideGameRule()
} else {
$gameRule.classList.remove('hidden')
$overLay.classList.remove('hidden')
}
$exitBtn.addEventListener('click', () => {
localStorage.removeItem('readOrNot')
})