Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Archives
Today
Total
관리 메뉴

시작은 0부터

17. 재귀함수, 지뢰찾기 만들기(80%), 달팽이 배열 본문

C# 학습일지

17. 재귀함수, 지뢰찾기 만들기(80%), 달팽이 배열

0base 2022. 7. 23. 23:31

   지뢰찾기는 어느정도 만들었다. 현재 구현하지 못한 부분은 깃발 꽂기와 근처 8방향 기준으로 지뢰가 없는 블록을 클릭했을 때 주변에 지뢰가 없는 0 블록들이 한번에 드러나는 기능이다. 깃발 꽂기는 금방 만들 수 있을 것 같은데 문제는 0블록을 퍼지게 만드는 것이다. 플레이어가 블록을 클릭했을 때 0인 블록들이 전부 드러나버리면 클릭한 위치와 상관없이 모든 0블록이 드러나면 안되고 클릭한 위치를 기준으로 확장이 되어야 하는데, 이를 구현하려면 재귀함수를 써야한다는 동기의 조언을 들었다. 

 

재귀함수

: 함수가 자기자신을 호출하는 것. 함수 A 가 호출되면 함수 A 안에서 값을 받은 것들로 코드를 처리하고 나온 결과값을 다시 자기 자신에게 넣어 호출하는 것이다. 

 

이 개념만 알고 막상 써보려고 하니 자꾸 스택오버플로우가 되었다. 알고보니 이유는 재귀함수에 탈출문이 없어 무한하게 반복되어서 였다. 코드만 잘 짜면 해결할 수 있을지도 모르겠다.

 

아직 미구현된 부분을 제외한 나머지 추가 부분들을 기록하겠다.

 

플레이어 체크

public void Check(int x, int y)
        {
            if (world[y, x] < 10)
            {
                if (world[y,x] != 9)
                {
                    world[y, x] += 10;//지뢰가 아닌 부분에 숫자 표시방법 구현
                }
                if (world[y,x] == 9)
                {
                    world[y, x] += 10;
                    ShowAll();
                    
                }
            }
        }

 

정수형 배열로 좌표를 받고 값은 8방향의 지뢰개수를 표현하기 때문에 방향표기는 8까지만 사용해서 지뢰를 9로 만들었고 체크하는 부분은 +10을 주어 구분을 주었다. 그리고 지뢰를 체크하면 맵 전체 블록을 드러내면서 게임을 종료시킨다.

 

게임오버시 맵 전부 공개

public void ShowAll()
        {
            for(int y = 0; y < bufferY; y++)
            {
                for(int x = 0; x < bufferX; x++)
                {
                    if(world[y, x] < 10)
                    {
                        world[y, x] += 10;
                    }
                }
            }
            Render();
            Console.ReadKey(); //입력키 받는 동안 대기
            IsBomb = true;
        }

지뢰를 체크하면 드러나지 않았던 블록들을 전부 드러내는 값을 주고, 랜더 함수를 호출하여 그려낸다음 게임을 종료시키는 참거짓 변수를 참으로 만든다.

 

그리고 이전에 맵이 자꾸 짤리는 문제를 해결하지 못했었는데 버퍼크기&윈도우창크기를 맵 크기와 똑같이 하면 맵이 짤리는 문제가 발생한다. 같은 문제를 해결했던 동기의 도움을 받아 버퍼크기와 윈도우창크기를 큰 크기로 고정하고 맵 크기를 입력값으로 바꾸니 맵이 짤리는 문제가 해결되었다. 

 

맵이 짤리는 문제를 해결하니, 그 다음에는 플레이어가 이동할 때 맵이 밀리는 문제가 발생했다. 맵 블록과 플레이어를 ㅁ + 한자로 만든 특수문자들( 가로2칸짜리)를 사용하여 플레이어 이동을 2칸씩 이동하도록 만들었는데, 이 문제는 교수님의 도움을 받아 해결했다. SetCursorPosition 값에서 위치값을 받을 때 x값에 * 2를 주면 된다. 헷갈리긴 하지만 블록 하나의 가로길이가 2칸짜리이니 * 2를 하면 해당 좌표에 정확히 출력되지만 +2를 주면 위치값이 튀게 되는 것 같다.

 

아직 지뢰찾기를 완벽하게 만들지 못했는데 새로운 과제를 내주셨다. 배열을 활용하는 문제로 달팽이 배열 문제를 내주셨는데, 생각보다 많이 어렵다. 배열을 순서대로 출력하는 것이 아니라 @ 모양으로 출력하는 것이다.

 

( 1 ) ( 2 ) ( 3 )

( 8 ) ( 9 ) ( 4 )

( 7 ) ( 6 ) ( 5 )

 

이런식으로 만들어내는 것인데 배열의 크기는 입력값으로 정해진다. 무작정 만들어보기 시작했는데 코드가 점점 길어지면서 접근방식이 잘못된 것 같아 다시 만들면서 for문(y) 안에 for문(x)으로 맵을 그리면서 조건문을 넣어서 만드는 방법을 해보려고 했는데 조건문을 상황에 따라 계속 넣다보니 너무 길어지는 문제도 있고 입력값에 따라 유동적으로 맵의 크기가 변하는데 비해 조건문을 하나하나 작성하면 유동성이 떨어지는 문제가 있었다. 아직 더 방법을 찾아봐야할 것 같다.