JavaScript - 틱택토게임 예제

Jenna·2022년 12월 21일
1

javascript

목록 보기
11/16

자바스크립트 게임 예제 틱택토 게임 만들기


이차원 배열인 틱택토 게임을 만들고 같은 코드를 메서드로 줄여쓰는 법, 이벤트 버블링 등을 학습한다.


📌 순서도 그리기


이차원 배열의 특성을 생각하여 순서도를 그린다.
컴퓨터와 번갈아가며 하는 게임의 특성을 생각한다.


📌 코드작성


<style>
    table {
        border-collapse: collapse;
    }

    td {
        border: 1px solid black;
        width: 40px;
        height: 40px;
        text-align: center;
    }
</style>

<body>
    <!-- <table>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </table> -->
    <script>
        const { body } = document;
        const $table = document.createElement('table');
        const $result = document.createElement('div');
        const rows = [];
        let turn = 'O';

        const checkWinner = (target) => {
            const rowIndex = target.parentNode.rowIndex;
            const cellIndex = target.cellIndex;

            //세칸 다 채워졌나?
            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 checkWinnerAndDraw = (target) => {
            const hasWinner = checkWinner(target);
            if (hasWinner) {
                $result.textContent = `${turn}님이 승리!`;
                $table.removeEventListener('click', callback);
                return;
            }
            //무승부 검사
            const draw = rows.flat().every((cell) => cell.textContent);
            if (draw) {
                $result.textContent = `무승부`;
                return;
            }

            if (turn === 'O') {
                turn = 'X';
            } else if (turn === 'X') {
                turn = 'O';
            };
        };

        let clickable = true;

        const callback = (event) => {
            if (!clickable) return;
            //빈칸이 아니면 
            if (event.target.textContent !== '') {
                console.log('빈칸이 아닙니다.');
                return;
            }
            //빈칸이면 
            console.log('빈칸입니다.');
            event.target.textContent = turn;
            //승부 판단하기
            checkWinnerAndDraw(event.target);

            if (turn === 'X') {
                clickable = false;
                setTimeout(() => {
                    const emptyCells = rows.flat().filter((v) => !v.textContent);
                    const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
                    randomCell.textContent = 'X';
                    checkWinnerAndDraw(event.target);
                    clickable = true;

                }, 1000);
            }
        };




        for (let i = 0; i < 3; i++) {
            const $tr = document.createElement('tr');
            const cells = [];
            for (let j = 0; 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>

📌 코드공부하기


이벤트 버블링


이벤트가 부모태그를 따라서 올라가는 현상
event.currentTarget 을 써주면 이벤트를 연결해준 요소를 선택할 수 있다.
event.stopPropagation() 이벤트 버블링을 막아주는 메서드


every, some


every는 모두 조건이 성립해야 한다. 1차원 배열만 가능해서 2차원 배열은 rows.flat메서드로 펼쳐준 후에 사용한다.
some 은 every의 반대로 하나라도 조건이 성립하면 성립한다.

profile
connecting the dots 💫

0개의 댓글