반응형
- 03_순발력게임1단계
- _speedgame1.html
- 1 to 50
- 배열이 2개이다.
- 첫번째를 다 벗겨내면. 2번째할때는 빈칸이 된다.
- cursor: pointer;는 셀 위에 마우스를 올리면 손 모양이 나타나게 해서 **"클릭할 수 있다"**는 시각적 힌트를 줍니다.
- onload="init()"는 페이지가 로드되자마자 init() 함수 실행하라는 의미입니다.
- 매우 중요! → JS로 화면을 그리려면 언제 실행할지 타이밍을 잡는 게 중요해요.
- 화면에 들어갈 3개의 영역을 구분해 놓았어요.
- #header: 제목
- #center: 테이블이 들어갈 자리
- #footer: 나중에 점수나 타이머 같은 부가 요소 들어갈 수도 있어요.
- 첫번째 반복문
- 첫 번째 반복문은 "숫자 데이터를 세팅(초기화)"하기 위한 것
- 📦 두 반복문의 역할 비교:
- 반복문 위치목적무슨 일 하는지
첫 번째 반복문 (num, frontList, backList) ❗ 데이터 준비 1 25, 2650 숫자들을 2차원 배열에 저장 (게임판 데이터 만들기)두 번째 반복문 (DOM 조작) ❗ 화면에 보여주기 + 이벤트 연결 <table> 태그를 만들고, 셀(<td>)을 추가하고, 숫자 넣고, 클릭 이벤트도 연결 - ✨ 이 코드는 화면에는 아무것도 출력하지 않지만,
- 👉 **나중에 사용할 게임판 데이터를 2차원 배열 형태로 준비해주는 "세팅 작업"**입니다.
- 2번째 반복문
- 테이블을 화면에 보여주고, 각 칸에 숫자를 넣고,
클릭할 수 있도록 이벤트까지 연결하는 핵심 코드
- 테이블을 화면에 보여주고, 각 칸에 숫자를 넣고,
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#header { text-align: center; }
table {
border-collapse: collapse;
border: 1px solid black;
margin: auto;
}
td {
width: 50px;
height: 50px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
</style>
</head>
<body onload="init()">
<div id="header">
<h3>Speed Game</h3>
</div>
<div id="center"></div>
<div id="footer"></div>
<script>
let size = 5;
변수 선언
$table은 새로 <table>을 만들어서 화면에 붙일 준비를 합니다.
👉 DOM 조작의 핵심: 요소를 만들고, 붙이고, 속성 설정하고
👉 DOM 조작의 핵심: 요소를 만들고, 붙이고, 속성 설정하고
let frontList = []; // 1 ~ 25 수를 저장하는 2차배열
let backList = []; // 26 ~ 50 수를 저장하는 2차배열
let $center = document.querySelector("#center");
let $table = document.createElement("table");
let $tdList = []; //집어 넣을것
--------------------------------------------------------------------------------- function init() {
초기 세팅
let num = 1;
for(let i=0; i<size; i++) {
let frontTemp = [];
let backTemp = [];
for(let j=0; j<size; j++) {
frontTemp.push(num);
backTemp.push(num + 25);
num += 1;
첫번째 판을 다 지우면 2번째 판도 만들어야 해서. 판이 2개라서. 배열을 2개를 저장시키는것
테이블에 숫자가 두겹으로 숨겨져 있는 구조이다.
지금은 첫 번째 판만 보이게 설정해 놓은것
backList의 숫자들 → 화면에는 아직 안 나옴, 하지만 데이터로는 저장되어 있음
}
frontList.push(frontTemp);
backList.push(backTemp);
}
console.log("frontList = " + frontList);
console.log("backList = " + backList);
-------------------------------------------------------------------------- for(let i=0; i<size; i++) {
숫자들을 화면에 보여주고. 클릭이벤트 넣어주기
let $tr = document.createElement("tr");
- <tr>(테이블 한 행)을 새로 만드는 코드
- 지금부터 여기에 <td>(칸)를 하나씩 넣을 거예요
let $tempTdList = [];
- 한 줄 안의 <td>들(5개)을 배열에 따로 모아두기 위한 변수
- 나중에 게임 상태를 관리하거나 바꾸기 쉽게 하기 위해 2차원 배열 형태로 저장
for(let j=0; j<size; j++) {
let $td = document.createElement("td");
- <td> 하나 생성 (테이블 셀)
- 이 안에 숫자도 넣고, 클릭도 할 수 있도록 만들 거예요
$td.addEventListener("click", clickEvent);
- 이 칸을 클릭했을 때 실행할 함수를 연결
- 여기선 clickEvent()라는 함수를 연결했어요 (아직 비어 있음)
👉 이 부분이 없으면 셀을 클릭해도 아무 반응 없음
$td.innerText = frontList[i][j]; //프론트에만 넣어줌 // 지금 화면에 첫번째 판만 보여준 것
- 해당 위치의 숫자(1~25)를 텍스트로 넣어줌
- frontList는 미리 준비해둔 2차원 배열이고, 그걸 꺼내서 화면에 보여주는 거예요
예시: frontList[0][0] → 1
$tr.append($td); 만든 <td> 셀을 현재 줄(<tr>)에 붙임
$tempTdList.push($td);
- 화면에 표시된 <td> 요소를 배열에 저장
- 이유: 나중에 이걸 바꾸거나 업데이트할 수 있도록 하기 위해
}
$tdList.push($tempTdList);
$table.append($tr);
- td 셀 배열을 tdList에 저장 → 전체 테이블을 배열로 관리할 수 있게 됨 (2차원 배열 형태)
- 줄 <tr>을 완성된 테이블에 붙임
}
$center.append($table);
- 완성된 테이블을 실제 웹페이지의 #center에 붙임
- 이제 눈에 보이게 됨
}
function clickEvent() {
}
</script>
</body>
</html>
- 03_순발력게임2단계
- _speedgame2.html
- 다음숫자로 덮어씌워짐
- 2번째는 0으로 만들기
<!DOCTYPE html><html lang="ko"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
<style>#timer { text-align: center; }#header { text-align: center; }table {border-collapse: collapse;border: 1px solid black;margin: auto;}td {width: 50px;height: 50px;border: 1px solid black;text-align: center;
cursor: pointer;}</style>
</head><body onload="init()">
<div id="timer">0</div>
<div id="header"><h3>Speed Game</h3><button onclick="hintClick()">힌트</button><span id="nextNum">1</span></div>
<div id="center"></div><div id="footer"></div><script>let gameNum = 1; // 추가된 변수let time = 0;
let size = 5;let frontList = [];let backList = [];let $center = document.querySelector("#center");let $table = document.createElement("table");let $tdList = [];
function init() {let num = 1;for(let i=0; i<size; i++) {let frontTemp = [];let backTemp = [];for(let j=0; j<size; j++) {frontTemp.push(num);backTemp.push(num + 25);
num += 1;}
frontList.push(frontTemp);backList.push(backTemp);}
// 셔플(shuffle)/*for(let i=0; i<100; i++) {let y = Math.floor(Math.random() * size);let x = Math.floor(Math.random() * size);
let temp = frontList[0][0];frontList[0][0] = frontList[y][x];frontList[y][x] = temp;
y = Math.floor(Math.random() * size);x = Math.floor(Math.random() * size);
temp = backList[0][0];backList[0][0] = backList[y][x];backList[y][x] = temp;}*/
console.log("frontList = " + frontList);console.log("backList = " + backList);
for(let i=0; i<size; i++) {let $tr = document.createElement("tr");let $tempTdList = [];for(let j=0; j<size; j++) {let $td = document.createElement("td");$td.addEventListener("click", clickEvent);$td.innerText = frontList[i][j];$tr.append($td);$tempTdList.push($td);}$tdList.push($tempTdList);$table.append($tr);}$center.append($table);}
function setTimer() {time += 1;document.querySelector("#timer").innerText = time;}//----------------------------------------------------------------//누르면 현재 위치를 찾기 // 내가 누른 위치 찾기function clickEvent() {let y = 0;let x = 0;for(let i=0; i<size; i++) {for(let j=0; j<size; j++) {if(this == $tdList[i][j]) {y = i;x = j;break;}}}if(this.innerText == gameNum) {if(1 <= gameNum && gameNum <= 25) {if(gameNum == 1) {setInterval(setTimer, 1000);//숫자 1이면 타이머를 동작시킴}this.innerText = backList[y][x];//백에 있는것을 집어 넣는다.} else {this.innerText = 0;//26~50이면 0을 집어 넣는다.}this.style.backgroundColor = "";//힌트를 지우는 역할gameNum += 1; //숫자 2로 만들어 주기
document.querySelector("#nextNum").innerText = gameNum;//힌트 빨간색을 지우기 위해서}}//힌트 누르면 빨간색 넣어주기function hintClick() {let y = 0;let x = 0;for(let i=0; i<size; i++) {for(let j=0; j<size; j++) {if($tdList[i][j].innerText == gameNum) {y = i;x = j;break;}}}
$tdList[y][x].style.backgroundColor = "red";}</script>
</body></html>
- 03_순발력게임3단계
- _speedgame3.html
- 게임이 끝나면 다시 할 수 있게. 깔끔히
<!DOCTYPE html><html lang="ko"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
<style>#timer { text-align: center; }#header { text-align: center; }#footer { text-align: center; }table {border-collapse: collapse;border: 1px solid black;margin: auto;}td {width: 50px;height: 50px;border: 3px solid white;text-align: center;color: brown;font-size: 20px;font-weight: bold;
cursor: pointer;}</style>
</head><body onload="init()">
<div id="timer">0</div>
<div id="header"><h3>Speed Game</h3><button onclick="hintClick()">힌트</button><span id="nextNum">1</span></div>
<div id="center"></div><div id="footer"><button onclick="replayClick()">Replay</button></div><script>let gameNum = 1; // 추가된 변수let time = 0;let timeId = null;
let size = 3;let frontList = [];let backList = [];let $center = document.querySelector("#center");let $table = document.createElement("table");let $tdList = [];
function init() {let num = 1;for(let i=0; i<size; i++) {let frontTemp = [];let backTemp = [];for(let j=0; j<size; j++) {frontTemp.push(num);backTemp.push(num + size*size);
num += 1;}
frontList.push(frontTemp);backList.push(backTemp);}
//원래는 섞어야 한다.// 셔플(shuffle)/*for(let i=0; i<100; i++) {let y = Math.floor(Math.random() * size);let x = Math.floor(Math.random() * size);
let temp = frontList[0][0];frontList[0][0] = frontList[y][x];frontList[y][x] = temp;
y = Math.floor(Math.random() * size);x = Math.floor(Math.random() * size);
temp = backList[0][0];backList[0][0] = backList[y][x];backList[y][x] = temp;}*/
console.log("frontList = " + frontList);console.log("backList = " + backList);
for(let i=0; i<size; i++) {let $tr = document.createElement("tr");let $tempTdList = [];for(let j=0; j<size; j++) {let $td = document.createElement("td");$td.addEventListener("click", clickEvent);$td.innerText = frontList[i][j];$td.style.backgroundColor = "coral";$tr.append($td);$tempTdList.push($td);}$tdList.push($tempTdList);$table.append($tr);}$center.append($table);}
function setTimer() {time += 1;document.querySelector("#timer").innerText = time;}
function clickEvent() {let y = 0;let x = 0;for(let i=0; i<size; i++) {for(let j=0; j<size; j++) {if(this == $tdList[i][j]) {y = i;x = j;break;}}}if(this.innerText == gameNum) {if(1 <= gameNum && gameNum <= size*size) {if(gameNum == 1) {timeId = setInterval(setTimer, 1000);}this.innerText = backList[y][x];this.style.backgroundColor = "antiquewhite";} else {this.innerText = "";this.style.backgroundColor = "";
this.style.cursor = "default";}gameNum += 1;
document.querySelector("#nextNum").innerText = gameNum;}
gameOver();}
function hintClick() {let y = 0;let x = 0;for(let i=0; i<size; i++) {for(let j=0; j<size; j++) {if($tdList[i][j].innerText == gameNum) {y = i;x = j;break;}}}
$tdList[y][x].style.backgroundColor = "red";}function clearTable() {$center.removeChild($table );}//-------------------------------------------------function replayClick() { //리플라이 버튼을 누르면clearInterval(timeId); //타이머 정지clearTable(); // 테이블 지우기
// 변수 초기화gameNum = 1;time = 0;timeId = null;frontList = [];backList = [];$table = document.createElement("table");;$tdList = [];document.querySelector("#timer").innerText = time;document.querySelector("#nextNum").innerText = gameNum;
init(); //다시 시작}//---------------------------------------------------------//게임오버를 판단하는것 .function gameOver() {if(gameNum > size*size*2) { //마지막 숫자는 게임오버clearInterval(timeId); //멈춤
// 게임 종료 화면alert("게임을 종료합니다!");}}
</script>
</body></html>
- _speedgame2 copy.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#timer { text-align: center; }
#header { text-align: center; }
table {
border-collapse: collapse;
border: 1px solid black;
margin: auto;
}
td {
width: 50px;
height: 50px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
</style>
</head>
<body onload="init()">
<div id="timer">0</div>
<div id="header">
<h3>Speed Game</h3>
<button onclick="hintClick()">힌트</button>
<span id="nextNum">1</span>
</div>
<div id="center"></div>
<div id="footer"></div>
<script>
let gameNum = 1; // 추가된 변수
게임에서 지금 몇 번 숫자를 눌러야 하는지를 알려주는 변수예요.
힌트. 다음에 눌러줄 번호.
화면에서도 <span id="nextNum">1</span>으로 현재 목표 숫자를 표시하죠.
let time = 0;
타이머 숫자를 나타냄.
1초마다 1씩 증가하는 구조 (setInterval로 호출됨)
let size = 5;
let frontList = []; 실제로 **처음 화면에 보이는 숫자들(1~25)**을 저장할 2차원 배열
let backList = []; 클릭하고 나면 보이게 될 **두 번째 숫자들(26~50)**을 저장할 2차원 배열
즉, 게임판에 두 겹의 숫자가 있는 구조입니다!
let $center = document.querySelector("#center");
let $table = document.createElement("table"); 여기서 테이블을 만듬
let $tdList = [];
보통 center은 body에서 만들고. 테이블과 tr과 td는 자바스크립트( script)에서 만든다.
$를 붙인것 => 이 변수는 HTML 요소야 => 화면에 출력하는것
------------------------------------------------------------------------------------ function init() { 게임 시작 시 호출되는 함수
숫자 데이터 준비 (frontList, backList)
let num = 1;
for(let i=0; i<size; i++) {
let frontTemp = [];
let backTemp = [];
행(row) 기준으로 반복문 시작 . 각 줄마다 frontTemp, backTemp 라는 임시 배열을 만들어요
for(let j=0; j<size; j++) {
frontTemp.push(num);
backTemp.push(num + 25);
num += 1;
열(column) 기준 반복
}
frontList.push(frontTemp);
backList.push(backTemp);
위에서 만든 한 줄씩의 배열을 전체 배열에 넣음 . 이렇게 해서 5×5짜리 2차원 배열이 완성됩니다.
}
✅ 왜 이렇게 했을까?
- 게임에서 셀을 누르면 숫자가 바뀌어야 하니까
👉 숫자 데이터(1~50)를 미리 배열에 다 준비해둔 것 - 테이블은 나중에 따로 만들어서 화면에만 보여줌
- 실제 DOM 조작은 init()의 아래쪽에서 실행됨
"실제 DOM 조작은 init()의 아래쪽에서 실행됨"이라는 말은,
init() 함수 안에서 페이지에 보여지는 실제 HTML 요소들(<table>, <tr>, <td>)을 생성하고, 그걸 문서의 원하는 위치(예: #center div)에 추가하는 작업이 init() 함수의 후반부에 일어난다는 뜻이에요.
쉽게 말하면:
- init() 함수는 크게 두 가지 일을 해요:
- 데이터 세팅 (숫자 배열 frontList, backList 만들기)
- 화면에 보여줄 HTML 요소 생성과 추가 (DOM 조작)
- 여기서 “DOM 조작”이란, 자바스크립트로 HTML 태그를 만들고,
그 태그를 화면에 있는 특정 요소 안에 넣는 작업을 말해요. - 이 작업은 보통 init() 함수 코드 중간~아래쪽에 위치해요.
- 자바스크립트는 데이터만 만들고, 실제 화면에 요소를 추가하는 건 DOM 조작이기 때문
- 데이터만 만들면 화면에는 아무것도 안 보임
- 화면에 뭔가 보여주려면 DOM 조작이 필수
init() 함수에서 데이터 준비가 끝난 뒤,
HTML 요소를 만들고 화면에 넣는 작업(=DOM 조작)이 함수 아래쪽에서 이뤄진다.
그래서 실제 화면에 테이블과 숫자가 나타나는 부분이 init() 함수 내 후반부라는 의미입니다.
// 셔플(shuffle)
/*
for(let i=0; i<100; i++) } // 100번 섞는다.
let y = Math.floor(Math.random() * size);
let x = Math.floor(Math.random() * size);
let temp = frontList[0][0];
frontList[0][0] = frontList[y][x];
frontList[y][x] = temp;
y = Math.floor(Math.random() * size);
x = Math.floor(Math.random() * size);
temp = backList[0][0];
backList[0][0] = backList[y][x];
backList[y][x] = temp;
}
*/
console.log("frontList = " + frontList);
console.log("backList = " + backList);
--------------------------------------------------------------------------
화면에 보여주는 용도. 아직 클릭 이벤트는 연결만 했지. 실행은 안됨
테이블, tr, td 요소 생성 및 이벤트 연결 for(let i=0; i<size; i++) {
let $tr = document.createElement("tr");
size가 5라면, 5번 반복해서 테이블의 행을 5개 만들어요.
document.createElement("tr")는 HTML에서 <tr></tr> 태그를 새로 생성하는 메서드입니다.
let $tempTdList = [];
각 행에 포함될 <td> 태그(셀)들을 담을 임시 배열
이 배열은 현재 행에 생성되는 셀들을 저장해요
나중에 클릭 이벤트 등을 위해 저장해 두는 용도입니다.
for(let j=0; j<size; j++) {
let $td = document.createElement("td");
$td.addEventListener("click", clickEvent); 셀에 클릭 이벤트 함수 연결
$td.innerText = frontList[i][j]; 셀 안에 숫자 텍스트 넣기
$tr.append($td); 생성한 셀(<td>)을 현재 행(<tr>)에 추가
$tempTdList.push($td); 현재 행의 셀 배열에도 저장
}
$tdList.push($tempTdList); 완성된 한 행의 셀 배열을 전체 셀 배열에 추가
$table.append($tr); 완성된 행(<tr>)을 테이블(<table>)에 붙임
}
$center.append($table);
3. 완성된 테이블을 center 영역에 넣음 — 이게 바로 실제 DOM 조작
완성된 테이블을 화면의 #center 요소 안에 추가
이렇게 해야 실제로 화면에 테이블이 보입니다!
}
타이머 증가 함수 (setTimer) function setTimer() {
time += 1; 1초가 지날 때마다 time 변수 1 증가
document.querySelector("#timer").innerText = time; 증가한 time 값을 화면의 #timer 요소에 표시
}
//----------------------------------------------------------------
//누르면 현재 위치를 찾기 // 내가 누른 위치 찾기
function clickEvent() { //누르면
let y = 0;
let x = 0;
for(let i=0; i<size; i++) {
for(let j=0; j<size; j++) {
if(this == $tdList[i][j]) {
//this 내가 누른것
//$tdList[i][j] => td를 담아놓은 데이터
//누가 눌렸는지 찾는것
//내가 누른거랑. 전체배열에 있는 데이터가 같으면
//위치를 찾는다!!!!1
y = i;
x = j;
break;
}
}
}
this는 지금 클릭한 td 요소 자체를 뜻해. (이 함수가 td에서 호출되었으니까)
if(this.innerText == gameNum) {
//this.innerText => 내가 누른 숫자가.
//gameNum => 내가 맞춰야 되는 숫자.
if(1 <= gameNum && gameNum <= 25) {
if(gameNum == 1) { //타이머 시작
setInterval(setTimer, 1000);
//숫자 1이면 타이머를 동작시킴
}
this.innerText = backList[y][x];
//백에 있는것을 집어 넣는다.
} else {
this.innerText = 0;
//26~50이면 0을 집어 넣는다.
}
this.style.backgroundColor = ""; //색이 있으면 지우고. //힌트
//힌트를 지우는 역할
gameNum += 1; //숫자 2로 만들어 주기
document.querySelector("#nextNum").innerText = gameNum;
//힌트 빨간색을 지우기 위해서
/다음 맞춰야 되는 숫자.
//힌트 빨간색을 지우기 위해서
}
}
------------------------------------------------------------------------------------------------------
//힌트 누르면 빨간색 넣어주기
function hintClick() {
let y = 0;
let x = 0;
//위치 다시 찾아서. 빨간색으로 바꾸기.
for(let i=0; i<size; i++) {
for(let j=0; j<size; j++) {
if($tdList[i][j].innerText == gameNum) {
y = i;
x = j;
break;
}
}
}
$tdList[y][x].style.backgroundColor = "red";
}
</script>
</body>
</html>
- 03_순발력게임3단계
- _speedgame3 copy 2.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#timer { text-align: center; }
#header { text-align: center; }
#footer { text-align: center; }
table {
border-collapse: collapse;
border: 1px solid black;
margin: auto;
}
td {
width: 50px;
height: 50px;
border: 3px solid white;
text-align: center;
color: brown;
font-size: 20px;
font-weight: bold;
cursor: pointer;
}
</style>
</head>
<body onload="init()">
<div id="timer">0</div>
<div id="header">
<h3>Speed Game</h3>
<button onclick="hintClick()">힌트</button>
<span id="nextNum">1</span>
</div>
<div id="center"></div>
<div id="footer">
<button onclick="replayClick()">Replay</button>
</div>
<script>
let gameNum = 1; // 추가된 변수
//게임에서 현재 눌러야 하는 숫자를 저장하는 변수야
//예를 들어, 플레이어가 1부터 차례로 눌러야 하면, 처음엔 1, 그 다음엔 2, 3... 이런 식으로 증가함.
let time = 0;
//**게임 시작 후 경과한 시간(초)**를 저장하는 변수야.
//타이머가 1초씩 증가할 때마다 time도 1씩 올라가.
let timeId = null;
//setInterval 함수가 반환하는 타이머 ID를 저장하는 변수야.
// 이 값을 이용해 clearInterval(timeId)로 타이머를 멈출 수 있어.
// 초기값은 아직 타이머가 안 시작됐으니까 null로 둠.
let size = 3;
let frontList = [];
let backList = [];
let $center = document.querySelector("#center");
//HTML 문서에서 id가 "center"인 요소를 찾아서 저장한 변수야.
//이 요소 안에 동적으로 테이블(<table>)을 만들어 넣는 데 사용함.
let $table = document.createElement("table");
//새로 만들 HTML 테이블 요소(<table>)를 생성해서 저장한 변수.
let $tdList = [];
//테이블의 각 칸(td 요소)을 2차원 배열로 저장하는 변수야.
//예를 들어 $tdList[0][0]은 첫 번째 행 첫 번째 열의 <td> 요소.
// 클릭했을 때 어떤 칸이 눌렸는지 쉽게 찾기 위해서임.
//2차배열 $tdList는 배열이고,
// 그 안에 또 다른 배열들이 들어있어 ($tempTdList).
// 각 $tempTdList 배열에는 <td> 요소들이 쭉 들어가 있지.
// 즉, $tdList[i][j] 형태로 행(i)과 열(j) 위치의 <td> 요소에 접근할 수 있어.
// 그래서 2차원 배열이라고 해!
//---------------------------------------------------------------------------------------------
function init() {
let num = 1;
for(let i=0; i<size; i++) {
// num은 여기서 초기화 안됨. 계속 유지됨.
let frontTemp = [];
let backTemp = [];
for(let j=0; j<size; j++) {
frontTemp.push(num);
backTemp.push(num + size*size);
num += 1;
}
frontList.push(frontTemp);
backList.push(backTemp);
}
/*
frontList = [
[1, 2, 3], // 1행
[4, 5, 6], // 2행 - 이전 숫자에서 이어서 증가
[7, 8, 9] // 3행
]
*/
//----------------------------------------------------------------------------
//원래는 섞어야 한다.
// 셔플(shuffle)
for(let i=0; i<100; i++) {
let y = Math.floor(Math.random() * size);
let x = Math.floor(Math.random() * size);
let temp = frontList[0][0]; //2차배열이다.
frontList[0][0] = frontList[y][x];
frontList[y][x] = temp; //??
y = Math.floor(Math.random() * size); //?? 왜 또 랜덤?
x = Math.floor(Math.random() * size);
//frontList와 backList를 각각 독립적으로 섞기 위해서야.
temp = backList[0][0];
backList[0][0] = backList[y][x];
backList[y][x] = temp;
}
console.log("frontList = " + frontList);
console.log("backList = " + backList);
//-------------------------------------------------------------------------------
for(let i=0; i<size; i++) {
let $tr = document.createElement("tr");
let $tempTdList = [];
//이 변수는 이 줄에 들어갈 <td>(테이블 칸)들을 임시로 담을 배열.
// 나중에 이 배열을 $tdList에 넣어 2차원 배열처럼 관리할 거야.
for(let j=0; j<size; j++) {
let $td = document.createElement("td");
$td.addEventListener("click", clickEvent);
$td.innerText = frontList[i][j];
$td.style.backgroundColor = "coral";
$tr.append($td);
$tempTdList.push($td);
}
$tdList.push($tempTdList);
$table.append($tr);
}
$center.append($table);
}
//--------------------------------------------------------
function setTimer() {
time += 1;
document.querySelector("#timer").innerText = time;
}
//------------------------------------------------------------
function clickEvent() {
//1. 클릭한 위치 찾기 (y, x 좌표 찾기)
let y = 0;
let x = 0;
for(let i=0; i<size; i++) {
for(let j=0; j<size; j++) {
if(this == $tdList[i][j]) {
//this는 현재 클릭한 <td> 요소를 가리켜.
// 2중 반복문으로 $tdList 이차원 배열에서 클릭한 <td>가 어디 위치인지 (i, j) 찾는 거야.
// 찾아서 y, x에 그 위치 인덱스를 저장해.
// 이렇게 좌표를 알면, 나중에 그 위치에 해당하는 값을 frontList나 backList에서 쉽게 찾을 수 있어.
y = i;
x = j;
break;
}
}
}
//-----------------------------------------------
//2. 클릭한 셀에 적힌 숫자가 현재 게임 목표 숫자인지 검사
if(this.innerText == gameNum) {
//클릭한 셀의 숫자(innerText)가 현재 진행 중인 gameNum과 같을 때만 다음 동작을 해.
// 예를 들어, 지금 gameNum이 1이라면, 1이 적힌 셀만 반응하는 거지.
if(1 <= gameNum && gameNum <= size*size) {
//3. 클릭한 숫자가 1 이상 size*size 이하일 때 (초기 숫자 범위)
if(gameNum == 1) {
timeId = setInterval(setTimer, 1000); //이건 시간 가는 함수?
}
this.innerText = backList[y][x];
this.style.backgroundColor = "antiquewhite";
} else {
this.innerText = "";
this.style.backgroundColor = "";
this.style.cursor = "default";
}
//만약 gameNum이 1부터 9 (3x3 게임이니까 size*size=9) 사이면,
// 게임 첫 숫자(1)를 클릭하면 타이머가 시작돼. setInterval이 setTimer 함수를 1초마다 호출해서 시간 흐르게 만드는 부분.
// 그리고 클릭한 셀에 backList[y][x]에 있는 숫자로 숫자가 바뀌어.
// 배경색도 바뀌어서 (antiquewhite) 클릭한 셀이 시각적으로 달라짐.
// 반면에 gameNum이 10 이상이면,
// 클릭한 칸을 빈칸으로 바꾸고, 배경색, 커서도 기본 상태로 바꿔.
// 즉, 더 이상 보여줄 숫자가 없을 때는 빈칸 처리하는 거야.
//4. 게임 진행 숫자 증가 및 화면 갱신
gameNum += 1;
document.querySelector("#nextNum").innerText = gameNum;
//gameNum을 1 증가시켜서 다음에 찾아야 할 숫자를 업데이트.
// 그리고 화면에 보이는 다음 숫자 표시(nextNum 요소의 텍스트)를 바꿔줌.
}
//5. 게임 종료 체크
gameOver();
//클릭 후마다 게임이 끝났는지 판단하는 함수 gameOver()를 호출해.
// 보통 이 함수는 목표 숫자가 끝까지 다 선택됐는지 체크해서, 끝나면 타이머 정지하고 알림을 띄워주는 역할을 함.
}
//------------------------------------------------------------------------------
function hintClick() {
let y = 0;
let x = 0;
//우선 y, x 변수를 만들어서, 현재 목표 숫자의 위치를 저장할 준비를 해.
//2중 반복문으로 위치 찾기
for(let i=0; i<size; i++) {
for(let j=0; j<size; j++) {
if($tdList[i][j].innerText == gameNum) {
y = i;
x = j;
break;
}
}
}
//이중 반복문으로 테이블의 모든 셀($tdList[i][j])을 확인해.
//각 셀의 innerText (보여지는 숫자)를 확인해서, 지금 클릭해야 하는 숫자(gameNum)와 같은 셀을 찾는다.
// 찾았다면, 그 위치를 y, x에 저장하고 바로 반복문을 빠져나온다.
$tdList[y][x].style.backgroundColor = "red";
}
//--------------------------------------------------------
function clearTable() {
$center.removeChild($table );
// 테이블을 center에서 제거함
//이렇게 함축된 함수를 뭐라고 함?
//이건 DOM 조작 메서드예요.
// $center는 <div id="center">이고,
// $table은 JavaScript에서 만든 <table> 요소입니다.
// 즉👉 “#center라는 부모 요소 안에서 자식 요소인 table을 제거해라” 라는 뜻이에요.
//removeChild()는 함수 맞아요!
//removeChild()는 자바스크립트의 DOM API 함수입니다.
// 노드를 동적으로 제거할 때 사용돼요.
//당신이 말한 “이렇게 함축된 함수”는 DOM API 함수 또는 빌트인 메서드라고 부릅니다.
}
//-------------------------------------------------
//replayClick() 함수는 "Replay" 버튼을 클릭했을 때 실행되는 함수로, 게임을 초기화하고 다시 시작하는 역할
function replayClick() { //리플라이 버튼을 누르면
clearInterval(timeId); //타이머 정지
clearTable(); // 테이블 지우기 화면에 있는 테이블 삭제
// 변수 초기화
gameNum = 1;
time = 0;
timeId = null;
frontList = [];
backList = [];
$table = document.createElement("table");;
$tdList = [];
//화면에 보이는 숫자 초기화
document.querySelector("#timer").innerText = time;
document.querySelector("#nextNum").innerText = gameNum;
init(); //다시 시작
}
//---------------------------------------------------------
//게임오버를 판단하는것 .
function gameOver() {
if(gameNum > size*size*2) { //마지막 숫자는 게임오버
clearInterval(timeId); //멈춤
// 게임 종료 화면
alert("게임을 종료합니다!");
}
}
</script>
</body>
</html>
반응형
'코딩 > 1-JavaScript' 카테고리의 다른 글
05_달력1단계 ~ 05_달력2단계 (0) | 2025.06.05 |
---|---|
04_숫자슬라이드게임1단계 ~ 04_숫자슬라이드게임3단계 (2) | 2025.06.05 |
댓글 알고리즘 을 추가 (0) | 2025.06.05 |
02_틱택토1단계, 02_틱택토2단계 (0) | 2025.06.05 |
D09_dom_버튼_암기 => 01_기본 (1~4) (2) | 2025.06.04 |