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

16. 필드, 생성자, Assembly, This, Overloading, Overriding, 지뢰찾기 만들기(미완) 본문

C# 학습일지

16. 필드, 생성자, Assembly, This, Overloading, Overriding, 지뢰찾기 만들기(미완)

0base 2022. 7. 22. 00:49

 

필드(Field)

:  멤버변수로 클래스 또는 클래스의 객체 상태를 저장하는 곳. 클래스 범위를 '필드'라고 쓴다고 한다.

ex) Class A = new Class(); // 클래스 생성

      Class A; // 클래스 정의만 하고 메모리를 새로 생성하지 않은 상태.

 

생성자

: 클래스를 생성하면 기본으로 생성되는 객체이다. 클래스 내부에 객체를 별도로 선언하지 않으면 

 

어셈블리(Assembly)

:  컴파일을 통해 나온 결과 파일. 교재에서 internal 접근제한자에 대한 설명으로 쓰였는데, 범위를 표현할 때 이 단어가 쓰일 경우 '프로젝트 내에서 사용가능'이라고 생각하면 된다.

 

This

: 내부에서 자기 자신을 가리킬 때 쓰인다고 한다. 이게 쓰이는 경우는 동기 왈 외부에서 변수를 불러들여올 때 내부의 변수와 이름이 같을 경우 이를 구분하기 위해 쓰일 수 있다고 한다. 잘 쓰일지는 의문이다.

 

Overloading

: 이름이 같은 함수가 매개변수가 다른 메서드를 만드는 것.

Class OverLoadingEx
{
	public void A (int a)
    { Console.WriteLine("int");

	public void A (string a)
    { Console.WriteLine("string");
    
    public void A (int a, int b)
    { Console.WriteLine(a + b);
}

Overriding

: 부모클래스에서 정의된 변수를 자식클래스에서 재정의하는 것.(덮어씌우기). 자식이 자신을 재정의할 수 있도록 허용해주는 수식이 virtual이고 덮어쓰겠다는 수식은 override 이다. 아래의 경우 a는 부모 클래스에서는 0, 자식 클래스에서는 1.

Class Parent
{
	public virtual void Method()
    {
    	int a = 0;
    }
}

Class Child : Parent
{
	public override void Method()
    {
    	int a = 1;
    }
}

 

 

클래스에 대한 이해가 어느정도 되어야 유니티를 원만하게 사용할 수 있기 때문에 클래스에 대한 내용과 관련 기능, 용어들에 대한 설명들을 주로 배웠고, 클래스 구조에 대한 간단한 개념은 복습해서 배우면서 매번 다른 방식의 주제로 실습을 통해 감을 잡아가고 있는 것 같다. 이번에는 '지뢰찾기' 만들기었다. 

 

2차원 배열을 사용해서 맵을 만들고, 그 안에 지뢰 위치값을 넣은 다음, 나머지 부분에 지뢰 위치에 따른 숫자를 표기하고 플레이어 위치를 맵 위에 덧그리는 방식으로 구현하려고 했는데 맵이 제대로 생성되지 않는 문제에서 계속 고전중이다. 오늘까지 구현한 부분만 핵심만 추려서 기록하겠다.

 

            bufferY = Console.BufferHeight = Console.WindowHeight = int.Parse(Console.ReadLine());
            bufferX = Console.BufferWidth = Console.WindowWidth = int.Parse(Console.ReadLine());
            BombCount = int.Parse(Console.ReadLine());

 

게임 화면의 가로 세로 크기와 지뢰개수를 입력받는 부분. X값과 Y값을 나타내는 변수에 버퍼와 윈도우창의 크기를 한꺼번에 넣는다.

 

	public void AddMine()
        {
            for (int i = 0; i < BombCount; i++) //지뢰 생성
            {
                randX = rd.Next(0, bufferX-1);
                randY = rd.Next(0, bufferY-1);
                if (world[randY, randX] == 9) //지뢰가 이미 있으면 다시 센다(중복방지)
                {
                    --i;
                    continue;
                }
                world[randY, randX] = 9; //9는 지뢰
            }
        }

입력받은 지뢰개수만큼 반복문을 돌려서 매번 랜덤하게 생성된 X값과 Y값을 맵을 나타내는 2차원 배열에 각각 집어넣어 지뢰로 만든다. 지뢰찾기에서 지뢰개수가 최대로 표현될 수 있는 개수는 8까지이므로 사용되지 않는 9를 지뢰로 사용하였다. 반복문이 돌면서 만약 동일한 위치에 지뢰가 생성될 경우 반복 수를 나타내는 i를 감소시키고 다시 돌려서 위치 중복이 되지 않을 때 까지 continue로 되돌려보낸다.

 

public void CreateMap() // 맵에 숫자 집어넣기
        {
            for (int y = 0; y < bufferY; y++)
            {
                for (int x = 0; x < bufferX; x++)
                {
                    if (world[y, x] == 9)
                    {
                        if (x + 1 < bufferX)
                        {
                            if (world[y, x + 1] != 9)
                                ++world[y, x + 1];
                        }

                        if (x - 1 >= 0)
                        {
                            if (world[y, x - 1] != 9)
                                ++world[y, x - 1];
                        }

                        if (y + 1 < bufferY)
                        {
                            if (world[y + 1, x] != 9)
                                ++world[y + 1, x];
                            if (x + 1 < bufferX)
                            {
                                if (world[y + 1, x + 1] != 9)
                                    ++world[y + 1, x + 1];
                            }
                            if (x - 1 >= 0)
                            {
                                if (world[y + 1, x - 1] != 9)
                                    ++world[y + 1, x - 1];
                            }
                        }

                        if (y - 1 >= 0)
                        {
                            if (world[y - 1, x] != 9)
                                ++world[y - 1, x];
                            if (x + 1 < bufferX)
                            {
                                if (world[y - 1, x + 1] != 9)
                                    ++world[y - 1, x + 1];
                            }
                            if (x - 1 >= 0)
                            {
                                if (world[y - 1, x - 1] != 9)
                                    ++world[y - 1, x - 1];
                            }
                        }
                    }

                }
            }
        }

근처 8방향을 기준으로 지뢰 개수를 나타내는 숫자. for문으로 맵 처음부터 끝까지 검사하면서 지뢰가 있을 경우 근처 반경(8방향)에 있는 좌표에 카운트를 증가시킨다.

 

	public void Render()
        {
            for(int y = 0; y < bufferY; y++)
            {
                for (int x = 0; x < bufferX; x++)
                {
                    if (world[y, x] == 9)
                    {
                        Console.SetCursorPosition(x, y);
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Write("@");
                    }
                    for (int i = 0; i < 9; i++)
                    { 
                        if  (world[y, x] == i)
                        {
                            Console.SetCursorPosition(x, y);
                            Console.ForegroundColor = ConsoleColor.White;
                            Console.Write(i);
                        }
                    }
                }
            }
        }

각 좌표에 입력된 값을 기반으로 화면에 출력하는 부분. CreateMap() 함수가 각 배열(좌표)에 데이터를 집어넣는다면 Render()함수는 그 데이터를 기반으로 화면을 그리는 과정이다. 그런데 아직까지는 어떻게 시도를 해봐도 맵이 완벽하게 그려지지 않고 윗칸이 짤린다. 근처 지뢰를 나타내는 수가 다른 칸은 정확하게 표기되는데 이상하게 1번째 줄 (Y0 번째)에서만 표기가 이상해서 뭔가 했더니 윗줄이 짤리는 것이었다. Y값은 20을 설정했을 경우 맵을 그리는 반복문에서 Y값이 20보다 작게 할 때까지 반복문을 돌리면(배열은 1번째가 0이므로) 세로가 20줄이 나와야하는데 계속 19줄만 나온다. 어디서 잘못된 것인지 찾지 못했다. 이것만 해결하면 지뢰찾기는 구현할 수 있을 것 같다.

랜더 부분에서 전부 동일한 형태의 블록으로 그린 후, 플레이어의 확인키를 입력받은 위치의 블록만 내부 데이터값을 나타내는 것으로 대체하여 그려내면 될 것 같다.

 

+ 이전에 교수님이 작성하신 지렁이게임 코드에서 방향전환이 어디서 이뤄지는지 찾지 못했었는데 그 해답을 찾았다.

if 조건문 안에 있는 증감식은 조건이 성립되지 않더라도 일단 증감된다. 그래서 보기에는 조건문밖에 없어보여도 증감식은 계속 되고 있는 것이었다.