-
JavaScript 입문 : 지뢰찾기 게임 - 주변지뢰 갯수 찾기(카운트)와 지뢰없는 칸 한꺼번에 열기 (재귀함수 이용)컴퓨터 알아가기/JavaScript 2022. 11. 2. 19:30728x90반응형
지난시간 조건연결자(optional chaining)를 통하여 주변지뢰갯수 찾는 코드를 다음과 같이 연구해 보았습니다.
사실 앞 조건이 undefined가 아니면 에러가 나지 않기 때문에 다음 그림과 같이 2개는 optional chaining이 없어도 되는데 써줘도 무방합니다.
그렇다면 이제는 원래 지뢰찾기 게임에 근거하여 지뢰가 없는 칸을 한꺼번에 여는 함수식에 대해 공부를 해 보도록 하겠습니다. 이 곳에서는 재귀함수라는 개념도 등장하네요. (갈수록 어렵네요...)
1. 지뢰없는 칸 주변 8개 한꺼번에 열기
지뢰가 없는 칸을 한꺼번에 열기 위해서는 해당 함수식을 만들어 줘야 하는데 이는 좌클릭 했을 경우 지뢰가 아닌 상황에서 코드 작성이 필요합니다.
아래 그림에서 사각형 안에 함수식을 만들어 줘야 하고 여기서 사용되었던 내용들은 다시 별도로 사용해야 겠지요.
다음과 같이 함수를 호출하고 외부에 함수식을 만들어 봅니다.
openAround( ) 함수식을 만들어 봅니다 .
여기서는 클릭한 곳이 지뢰가 없다는 가정하게 주위 8개를 한꺼번에 여는 함수를 만들어야 합니다. 일단 코드 작동여부를 떠나서 전체 구조식은 다음과 같이 만들 수 있겠지요.
여기서 중요한 점은 우리가 공부한 countMine( )함수식을 보면 클릭한 지점을 중심으로 주위 8개에 대한 식은 만들어 본 경험이 있습니다. 이를 바탕으로 openAround( ) 함수는 주위 8개를 먼저 한꺼번에 여는 함수식으로 만들어 봅니다.
아직 위 코드는 작동이 되지 않지만 순서를 보면 위와 같이 만들고 open( ) 함수를 만들어 줘야 합니다.
이제부터 open( )함수를 만들어 보도록 하겠습니다.
클릭하는 곳을 target으로 해 놓고 target이 아니면 return하고 target이면 열리는 기존 코드를 이 곳에 만들어 줍니다.
다음과 같이 open( )함수가 작성이 될 수 있습니다.
이제 브라우저를 확인해 보겠습니다.
① 클릭한 지점이 0이면 주변 8개가 열립니다.
② 그런데 맨 마지막 같은 극단적 상황에서는 에러가 나네요
이렇게 에러가 나면 위 주황색으로 사각형으로 된 곳을 콘솔에서 클릭해 봅니다. 다음과 같이 나옵니다.
위에 그림과 같이 나올 경우 빨간 물결무늬줄 앞인 [rowIndex]에서 에러가 있다는 이야기로 이곳을 optional chain으로 바꾸어주면 [rowIndex]가 undefined가 되지 않습니다.
2. 재귀함수를 사용하여 지뢰없는 칸 전부 열기
클릭한 곳이 0이면 주변 8개를 한꺼번에 열어보았는데 이렇게 해도 되지만 클릭한 주변이 스스로 클릭지점이 되어 반복되어진다면 주변 8칸 이상으로 빈칸은 전부 열릴 수 있습니다.
이러한 논리를 가능케해주는 함수가 바로 재귀함수(Recursion Function)입니다. 즉, 자기 자신을 재참조하는 함수라는 의미인데 open( ) 함수대신 openAround( ) 함수를 사용합니다.
open( ) 함수는 클릭한 주변 8칸을 여는데 openAroudn( ) 함수를 사용하면 open( ) 함수가 돌아가고 다시 그 주위를 다시 지뢰가 있기 전까지는 open( ) 함수가 작동하는 원리인 거죠.
다음과 같이 open을 openAround로 바꾸어줍니다.
그런데 브라우저를 열고 시도해 보니 다 열리지도 않고 다음과 같은 에러가 발생이 나는군요. Call Stack 사이즈가 초과되었다고 나오는군요. 머리 아픈 이벤트루프 문제로 들어갔습니다.
3. 이벤트루프 원리를 통한 재귀함수 에러 해결
다 그런것은 아니지만 기본적으로 재귀함수를 사용하면 자신이 계속 반복되는 것이기 때문에 에러가 난다고 합니다. 우선 Maximum Call Stack이 초과되었다고 하니 현재 프로그램에서 Maximum Call Stack은 어느정도인지 다음 코드를 사용하여 확인해 보도록 하겠습니다. 해당 코드는 제로초TV의 내용을 빌려 왔습니다.
재귀함수 최대 콜스택확인 코드 실행하면 다음과 같이 최대 콜스택은 13921개이고 이를 초과하였다는 에러였네요.
즉, 다음과 같이 이베트루프 도식을 활용하면 Call Stack에 openAround( ) 함수가 13921개 이상으로 계속 쌓인다는 이야기입니다.
콜스택 한계치 초과 이럴경우 Call Stack에서만 일을 하기때문에 Backgroud와 Task Que로 보내서 시간을 벌어주면 해결이 됩니다. setTimeout( ) 함수로 사용해 줍니다.
이렇게 하면 이벤트루프에서 콜스택이 초과되는 에러를 방지할 수 있습니다. 다시 브라우저에서 확인을 해 보겠습니다.
한꺼번에 열리긴 하는데 뭔가 시간차이를 가지고 열리고 결국에는 브라우저가 다운됩니다.
하... 콜스택은 처리했으나 재귀함수 자체에 대한 원인이 문제로 남아있었네요... 다음 시간에 좀 더 원인 파악 및 해결을 하고 승리까지 표시하도록 해 보겠습니다 .
반응형'컴퓨터 알아가기 > JavaScript' 카테고리의 다른 글