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부터

19. enum, interface, 지뢰찾기 90% 완료 본문

C# 학습일지

19. enum, interface, 지뢰찾기 90% 완료

0base 2022. 7. 25. 23:43

enum

: 열거형을 나타내는 데이터형. 

enum A { a, b, c, d, e }

열거형 A 안에 a, b, c, d, e라는 이름을 각각 만들면, 해당 이름들에 값을 넣지 않더라도 사용할 수 있다. 또한 자동으로 열거형 안에서 왼쪽에서부터 0부터 순서가 매겨진다. enum 값을 그대로 출력하면 이름이 나타나고 정수형 데이터로 변환하면 순서가 나타난다.

 

interface

: 기능 구현을 위해서 변수를 지정해 놓는 클래스. 클래스와 구조가 유사하지만 정의만 한다는 특징이 있다. 보통 인터페이스 클래스를 사용할 때는 클래스 이름 앞에 I를 써넣어 구분한다고 한다. 또 다른 클래스와의 차이점은 클래스는 다른 클래스를 상속 받을 때 1개의 클래스만 상속받을 수 있고 다중 상속이 불가능하지만 인터페이스 클래스의 경우에는 다중으로 상속받을 수 있다. 

 

ClassA : ClassB  // 클래스A가 다른 클래스B를 상속받는다

ClassA : Interface1, Interface2 //클래스 A가 인터페이스 1,2를 상속받는다

ClassA : ClassB, Interface1, Interface2 // 클래스가 다중으로 다른 클래스를 상속받을 수는 없지만 클래스만 1개라면 인터페이스는 다중으로 동시에 상속받을 수 있다.

 

 

기존에 진행중이었던 지뢰찾기에서 가장 막혔던 부분인 0 블록을 클릭시 주변 0블록으로 확장되면서 블록이 드러나는 코드를 만드는데 고전했는데, 동기의 도움을 받아 구현했다. if문으로 하나하나 다 작성하려고 했는데 for문 두개로 간단하게 방향 체크를 하는 동기의 코드를 보고 그 구조를 사용했다.

 

    public void CheckAround(int X, int Y)
        {
            int y = Y;
            int x = X;
            
            if (world[y, x] == 10 || world[y, x] == 0)
            {
                for (int ay = -1; ay < 2; ay++)
                {
                    for (int ax = -1; ax < 2; ax++)
                    {
                        int sumy = y + ay;
                        int sumx = x + ax;

                        if (sumy - 1 < -1 || sumy + 1 > bufferY || sumx - 1 < -1 || sumx + 1 > bufferX)
                        {
                            continue;
                        }

                        if (world[sumy, sumx] == 0)
                        {
                            world[sumy, sumx] += 10;
                            CheckAround(sumx, sumy);
                        }

                        else if (world[sumy, sumx] != 9 && world[sumy, sumx] < 10)
                        {
                            world[sumy, sumx] += 10;
                        }
                    }
                }
            }
        }

8방향을 체크하기 위해 일일이 if 문으로 만들었었는데 8방향은 결국 자기 자신을 기준으로 xy값이 각각 양수 음수 한칸씩 차이나는 범위 안이었다. 그래서 반복문으로 -1 ~ +1의 범위 안에서 반복문을 돌려 8방향을 체크하고 조건문으로 범위가 배열의 크기를 벗어나지 않게 한 후, 자신의 8방향에서 공개되지 않은 0을 10을 더해 공개처리한 후 그 값을 넣어 자기자신을 호출한다. 이런식으로 위치이동을 하면서 이동한 위치 기준에서 8방향 체크를 하는 식으로 공개된다. 그리고 0이 아니더라도 폭탄이 아닌 숫자는 공개가 되야하기 때문에 공개되지 않으면서 지뢰가 아닌 함수를 공개하지만 이 때는 재귀함수를 사용하지 않는다.

 

재귀함수는 반드시 벗어날 수 있는 탈출조건을 만들지 않으면 무한 반복으로 스택 오버 플로우가 발생한다. 이 문제 때문에 에  if문으로 8방향 체크를 하는 재귀함수를 만들었을 때 8방향을 이동할 때 마다 재귀하는 식으로 하니 계속 같은 배열만 왔다갔다 무한 반복하는 문제가 발생했다.

 

깃발꽂기는 +100으로 공개와는 또 다른 값을 주었다. 깃발을 지뢰가 아닌 위치에 꽂은 다음, 마우스 좌 + 우 클릭을 했을 때 클릭한 공개블록의 숫자보다 8방향 기준으로 공개된 블록값이 많으면 주변 블록을 자동으로 확인하되, 지뢰가 아닌 곳에 깃발을 꼽은 것이 확인되면 게임종료가 되는 기능을 구현중이다. ▼

 

public void CheckAroundType2(int X, int Y)
        {

            int y = Y;
            int x = X;
            int close = 8;
            int open = 0; 
                for (int ay = -1; ay < 2; ay++)
                {
                    if(IsBomb == true)
                    { break; }
                    for (int ax = -1; ax < 2; ax++)
                    {
                        int sumy = y + ay;
                        int sumx = x + ax;

                        if (sumy - 1 < -1 || sumy + 1 > bufferY || sumx - 1 < -1 || sumx + 1 > bufferX) //범위 벗어나면 패스
                        {
                            continue;
                        }
                        if (world[sumy, sumx] > 100 && world[sumy,sumx] != 109) //깃발 잘못 꼽으면 사망
                        {
                            ShowAll();
                            break;
                        }

                        if (world[sumy, sumx] == 0 )
                        {
                            open++;
                            world[sumy, sumx] += 10;
                            CheckAround(sumx, sumy);
                        }

                        if (world[sumy, sumx] > 9 && world[sumy,sumx] < 99) //오픈된 경우
                        {
                            open++;
                        }

                        else if (world[sumy, sumx] != 9 && world[sumy, sumx] < 10 && world[sumy, sumx] > close - open)
                        {
                            world[sumy, sumx] += 10;
                        }
                    }
                }
        }

아직은 완벽하게 기능이 구현되지 않았다. 공개된 블록을 클릭했을 때 오픈이 되는 경우도 있고 안되는 경우도 있어서 조건식을 조금 더 손봐야겠다.