자바스크립트 틱택토 게임 질문드립니다.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        td {
            border: 1px solid black;
            width: 50px;
            height: 50px;
            text-align: center;
        }
    </style>
</head>

<body>
    <h2>틱택토</h2>
    <script>
        var 바디 = document.body,
            결과 = document.createElement('h3');
        테이블 = document.createElement('table'),
            칸들 = [],
            줄들 = [],
            턴 = '❌';
        var cnt = 0;

        //✅②내가 몇번째칸인가
        var 비동기콜백 = function (event) {
            var 몇줄 = 줄들.indexOf(event.target.parentNode);
            var 몇칸 = 칸들[몇줄].indexOf(event.target); 

            console.log(몇줄, 몇칸); //0번째 0칸 이런식으로 알수있음

            //✅칸이 이미 채워져있는가
            if (칸들[몇줄][몇칸].textContent !== '') {
                console.log('빈 칸아닙니다');
                return
            } else {
                cnt += 1;
                console.log(cnt);

                console.log('빈 칸입니다');
                칸들[몇줄][몇칸].textContent = 턴;
                var 다참 = false;

                //✅세칸 다 채워졌나.
                //가로줄 검사
                if (칸들[몇줄][0].textContent === 턴 &&
                    칸들[몇줄][1].textContent === 턴 &&
                    칸들[몇줄][2].textContent === 턴) {
                    다참 = true;
                }
                //세로줄 검사
                else if (칸들[0][몇칸].textContent === 턴 &&
                    칸들[1][몇칸].textContent === 턴 &&
                    칸들[2][몇칸].textContent === 턴) {
                    다참 = true;
                }
                //대각선 검사 
                else if (몇줄 - 몇칸 === 0) { //대각선 검사가 필요한 경우
                    if (칸들[0][0].textContent === 턴 &&
                        칸들[1][1].textContent === 턴 &&
                        칸들[2][2].textContent === 턴) {
                        다참 = true;
                    }
                } else if (Math.abs(몇줄 - 몇칸) === 2 || 몇줄 - 몇칸 === 0) {
                    if (칸들[2][0].textContent === 턴 &&
                        칸들[1][1].textContent === 턴 &&
                        칸들[0][2].textContent === 턴) {
                        다참 = true;
                    }
                }
                
            }

            //다 찼으면. (= (다참 == true))
            if (다참) {
                결과.textContent = `${턴} 님이 승리`;
                //초기화
                턴 = '❌';
                칸들.forEach(function (줄) {
                    줄.forEach(function (칸) {
                        칸.textContent = '';
                    });
                });
                다참 = false;
                cnt = 0;
            } else if (cnt >= 9) {
                결과.textContent = '무승부입니다';
            }else{ //다 안찼으면
                //턴을 넘겨주는 의미
                if (턴 === '❌') {
                    턴 = '🟢';

                } else {
                    턴 = '❌';
                }
            }

        };
        //①줄들, 칸들을 console이 인식하도록
        for (var i = 1; i <= 3; i += 1) {
            var 줄 = document.createElement('tr');
            줄들.push(줄);
            칸들.push([]);
            for (var j = 1; j <= 3; j += 1) {
                var 칸 = document.createElement('td');
                칸.addEventListener('click', 비동기콜백); 
                줄.appendChild(칸);
                칸들[i - 1].push(칸); //0부터 계산하니

            }
            테이블.appendChild(줄);
        }

        바디.append(테이블);
        바디.append(결과);
        console.log(줄들, 칸들);

        /*
        QnA : 승리확정시 마지막 수가 안없어지도록
        */
    </script>
</body>

</html>

유튜브 제로초님 강의들으면서 공부하게된 코드입니다.

틱택토 구현이 끝나고 2가지 문제를 해결하고 싶어졌는데요.


  1. 승리할때 둔 마지막 수는 화면에 표시되지 않는 것

  2. 같은 칸을 다시 누를때 화면은 턴이 바뀌지 않는데 컴퓨터에서 턴이 바뀐걸로 인식하는 것

입니다.


2번은 해결하게 되었습니다.

칸이 이미 채워졌는가의 조건에서 빈칸이 아닐때에 return을 하여

뒤에 오는 코드를 무시해버리니

같은 칸을 다시 눌러도 컴퓨터가 턴이 바뀌었다고 인식하지 않게 되었습니다.


1번은 다시 재질문 드립니다. 저도 계속 확인해보겠습니다.

if (다참) {…} 부분은 "게임 승리 판정"이라는 상황 아래, 2가지 행동을 하고 있습니다
"(1) 결과출력"과 "(2) 게임판 초기화"과 그것인데요, 이 중 "(2) 게임판 초기화"에 대한 문제로 보입니다.

칸들[몇줄][몇칸].textContext = 턴; 에서 게임판에 턴을 표시하고 난 후,
같은 함수 안에서, “시간 차이” 없이 바로 if(다참) {…} 부분을 실행 하기에,
"게임판 출력 --> … --> if (다참) {…}의 (2) 게임판 초기화"을 “거의 동시에” 처리하게 되는거죠.
이럴 경우, “승리 할 때 둔 마지막 수를 화면에 표시” 기능도 작동 합니다만,
곧바로 "게임판 초기화"가 일어나기에, 표시되지 않는 것처럼 보이는 것입니다.

(2) 기능을 함수화 하신 다음, "1초 뒤 함수 실행"의 기능을 하도록
setTimeout(함수, 1000)을 이용하시기를 추천드립니다.
"(1) 결과 출력"의 1초 뒤에 "(2) 게임판 초기화"가 이루어지므로,
승리를 확정짓는 마지막 수가 출력되는 것을 확인 하실 수 있을겁니다.
물론, 1초뒤 사라지긴 하겠지만요.

부디 도움이 되었길 바랍니다.

1개의 좋아요

감사합니다! 바로 해결할 수 있었습니다. 이유와 해결방안 정확히 써주셔서 이해가 정말 잘되었습니다.