2022. 11. 1. 16:00ㆍ자바스크립트
*본 게시물은 길벗IT의 [Let's Get IT 자바스크립트]를 토대로 만들어졌습니다. 저작권은 길벗IT에게 있습니다.
이차원 배열의 예제,
틱택토 게임은 (3X3)삼목 게임이라 생각하면 된다.
+전체코드는 맨 하단에 있다.
먼저 개념 정리를 하려고 하는데/ 이차원 배열, 구조분해 할당, 이벤트 버블링, parentNode/children, rowIndex/cellIndex, 유사 배열 객체, every/some, flat에 대해 배웠다.
1) 이차원 배열은 배열 안에 배열이 있을 때를 말한다. html의 표도 이차원 배열이라 할 수 있다. 다만 때에 따라 일차원 배열로도 표현은 가능하다.
[
[null, 'X', null],
['O', 'X', 'X'],
[null, 'O', ''X],
]
2) 구조분해 할당은 아래 코드처럼 객체 내부의 속성명과 변수명이 같을 때 줄여쓸 수 있는 것이다.
const {body} = document;
const body = document.body;
여러 줄을 한 줄로 표현하는 것도 가능하다.
예-1)
const a = obj.a;
const b = obj.b;
-> const {a, b} = objj
예-2)
const a = array[0];
const b = array[1];
const c = array[2];
-> const [a, b, c] = array;
3) 이벤트 버블링은 이벤트 발생 시 부모 태그에도 동일하게 이벤트가 발생하는 것으로, 예를 들어 td에서 클릭했으면 부모 태그인 tr과 그의 부모태그인 table에서도 클릭이 되어 이벤트가 발생하는 것이다.
+좋은점 : event.target과 event.currentTarget을 사용해서 여러개 이벤트를 하나의 이벤트로 구현가능(나중에 removeEventListener하기 편함)
4) 부모 태그 찾으려면 parentNode, 자식 태그 찾으려면 children 속성을 사용하면 된다.
5) 표에서 몇 번째 줄, 몇 번째 칸인지 알기 위해서는 rowIndex와 cellIndex 속성을 사용하면 된다.
const rowIndex = $tr.rowIndex;
const cellIndex = $td.cellIndex;
6) children 속성같은 유사 배열 객체(array-like object)의 경우 Array.from 메서드를 사용해 배열로 바꿀 수 있다.
7) 배열에서 모든 값이 조건에 해당하는지 판단하려면 every메서드를 사용하고, 하나라도 조건에 해당하는지 판단하려면 some 메서드를 사용한다.
every -> 모두 다 true면 true, 하나라도 false면 false
some -> 하나라도 true면 true, 모두 다 false면 false
8) flat은 배열을 한차원씩 낮춰주는 메서드이다.
그럼 전체코드를 보면서 살펴보자.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>틱택토</title>
<style>
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
width: 40px;
height: 40px;
text-align: center;
}
</style>
</head>
<body>
<script>
const { body } = document;
// => const body = document.body;
const $table = document.createElement('table');
//누가 클릭했는지 메시지로 띄워줄 result
const $result = document.createElement('div');
const rows = [];
let turn = 'O';
//승부 검사 함수
const checkWinner = (target) => {
const rowIndex = target.parentNode.rowIndex;
const cellIndex = target.cellIndex;
//아래로 줄여 쓸 수 있음
/*
let rowIndex;
let cellIndex;
//forEach의 좋은점, 인덱스 알 수 있음
rows.forEach((row, ri)=>{
row.forEach((cell, ci)=>{
if(cell == target){
rowIndex = ri;
cellIndex = ci;
}
});
});
*/
let hasWinner = false;
// 가로줄 검사
if (
rows[rowIndex][0].textContent === turn &&
rows[rowIndex][1].textContent === turn &&
rows[rowIndex][2].textContent === turn
) {
hasWinner = true;
}
// 세로줄 검사
if (
rows[0][cellIndex].textContent === turn &&
rows[1][cellIndex].textContent === turn &&
rows[2][cellIndex].textContent === turn
) {
hasWinner = true;
}
// 대각선 검사
if (
rows[0][0].textContent === turn &&
rows[1][1].textContent === turn &&
rows[2][2].textContent === turn
) {
hasWinner = true;
}
if (
rows[0][2].textContent === turn &&
rows[1][1].textContent === turn &&
rows[2][0].textContent === turn
) {
hasWinner = true;
}
return hasWinner;
};
const callback = (event) => {
//칸에 글자가 있나?
if (event.target.textContent !== '') {
console.log('빈칸이 아닙니다.');
return;
}
// 빈칸이면
console.log('빈칸입니다');
event.target.textContent = turn;
// 승부 확인
const hasWinner = checkWinner(event.target);
if (hasWinner) {
$result.textContent = `${turn}님이 승리!`;
$table.removeEventListener('click', callback);
return;
}
// 무승부 검사
const draw = rows.flat().every((cell) => cell.textContent);
if (draw) {
$result.textContent = `무승부`;
return;
}
turn = turn === 'X' ? 'O' : 'X';
};
for (let i = 1; i <= 3; i++) {
const $tr = document.createElement('tr');
const cells = [];
for (let j = 1; j <= 3; j++) {
const $td = document.createElement('td');
cells.push($td);
$tr.append($td);
}
rows.push(cells);
$table.append($tr);
}
$table.addEventListener('click', callback);
body.append($table);
body.append($result);
</script>
</body>
</html>
+실행하면 이렇다!
'자바스크립트' 카테고리의 다른 글
[Let’s Get IT 자바스크립트 프로그래밍] 11장 이벤트 루프 이해하기_카드 짝 맞추기 게임 (0) | 2022.11.16 |
---|---|
[Let's Get IT 자바스크립트]10장 클래스_텍스트 RPG 게임 만들기 (1) | 2022.11.02 |