ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 내일배움캠프 7일차 TIL - 배열, 컬렉션, 메서드, 개인과제
    TIL/C# 2024. 4. 23. 21:25

     

    [학습목표]

    C# 강의 2주차를 시청하고 문제를 제출한다. 그리고 이번 주차 C# 개인과제를 진행한다.

    [학습내용]

    어제에 이어 C# 강의를 시청했다. 오늘은 배열과 컬렉션, 메서드와 구조체에 관해 학습했다. 딱히 새로운 것은 없었다.

    다만 배열을 표시하는 방법이 다른 언어와 조금 달랐다.

    int[] arr1 = new int[5] // 1차원 배열
    int[,] arr2 = new int[3,5] // 2차원 배열

     

    특히 2차원 배열이 달랐다. 다른 언어의 경우 대괄호를 2번 열고 닫는데, C#은 콤마(,)를 사용하였다. 이게 더 편한 거 같긴 하다.

    그리고 이 외에 기억해놔야 할 것은 컬렉션 종류 정도인 것 같다.

    • List
    • Dictionary
    • Stack
    • Queue
    • HashSet

    학습을 마치고 이번 주차 문제도 제출했다. 문제는 2문항이었다.

    첫 번째 문제는 숫자 맞추기 게임을 만들라는 문제였다. 진짜 딱 이렇게만 적혀있고 조건을 딱히 상세하게 정해주지 않아서 내가 알아서 만들었다.

    namespace FindNumberGame
    {
        internal class Program
        {
            static int SetNumber()
            {
                Random rand = new Random();
                int answer = rand.Next(1, 11);
    
                return answer;
            }
    
            static void Main(string[] args)
            {
                int answer = SetNumber();
                while (true)
                {
                    Console.Write("1 ~ 10 사이의 정수를 맞춰보세요: ");
                    int input = int.Parse(Console.ReadLine());
                    if (answer == input) 
                    {
                        Console.WriteLine("정답입니다!");
                        break;
                    }
                    else if (answer > input) 
                    {
                        Console.WriteLine("정답은 " + input + "보다 큽니다.");
                    }
                    else if (answer < input)
                    {
                        Console.WriteLine("정답은 " + input + "보다 작습니다.");
                    }
                }
                return;
            }
        }
    }

     

    두 번째 문제는 틱택토 게임 만들기였다. 이건 틱택토 게임 자체 룰이 정해져 있으므로 어떻게 글자와 보드판을 출력할지 그 양식만 정하면 됐다.

    using System.Reflection.Metadata.Ecma335;
    
    namespace TicTacToeGame
    {
        internal class Program
        {
            // 현재 게임판 보여주기
            static void ShowBoard(ref int[,] board)
            {
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        if (board[i, j] == 1) Console.Write("○ ");
                        else if (board[i, j] == 2) Console.Write("X ");
                        else Console.Write("□ ");
                    }
                    Console.WriteLine();
                }
            }
    
            // 승리 체크
            static int IsOver(ref int[,] board)
            {
                int cntO = 0, cntX = 0;
                // 가로
                for (int i = 0; i < 3; i++)
                {
                    cntO = 0; cntX = 0;
                    for (int j = 0; j < 3; j++)
                    {
                        if (board[i, j] == 1) cntO++;
                        else if (board[i, j] == 2) cntX++;
                    }
                    if (cntO == 3) return 1;
                    else if (cntX == 3) return 2;
                }
                // 세로
                for (int i = 0; i < 3; i++)
                {
                    cntO = 0; cntX = 0;
                    for (int j = 0; j < 3; j++)
                    {
                        if (board[j, i] == 1) cntO++;
                        else if (board[j, i] == 2) cntX++;
                    }
                    if (cntO == 3) return 1;
                    else if (cntX == 3) return 2;
                }
                // 대각선
                cntO = 0; cntX = 0;
                for (int i = 0; i < 3; i++)
                {
                    if (board[i, i] == 1) cntO++;
                    else if (board[i, i] == 2) cntX++;
                }
                if (cntO == 3) return 1;
                else if (cntX == 3) return 2;
                cntO = 0; cntX = 0;
                for (int i = 2; i >= 0; i--)
                {
                    if (board[i, 2 - i] == 1) cntO++;
                    else if (board[i, 2 - i] == 2) cntX++;
                }
                if (cntO == 3) return 1;
                else if (cntX == 3) return 2;
                return 0;
            }
            static void Main(string[] args)
            {
                // 게임판 생성
                int[,] board = new int[3, 3];
                // 현재 차례 (true는 O 차례, false는 X 차례)
                bool turn = true;
                // 게임 진행
                while (true)
                {
                    int x, y;   // 좌표
    
                    // 콘솔 초기화
                    Console.Clear();
                    // 다음 수 입력받기
                    Console.WriteLine("보드 왼쪽 아래가 (1,1), 오른쪽 위가 (3,3)입니다.\n\n[보드]");
                    ShowBoard(ref board);
                    Console.WriteLine("\n현재 차례: " + ((turn) ? "○" : "X"));
                    Console.Write("다음으로 두실 수의 X 좌표를 입력해주세요: ");
                    y = int.Parse(Console.ReadLine()) - 1;
                    Console.Write("다음으로 두실 수의 Y 좌표를 입력해주세요: ");
                    x = 3 - int.Parse(Console.ReadLine());
                    // 착수 금지점 체크
                    if (board[x, y] == 1 || board[x, y] == 2) continue;
                    // 다음 수 놓기
                    board[x, y] = (turn) ? 1:2;
                    turn = !turn;
                    // 게임 종료 체크
                    if (IsOver(ref board) == 1)
                    {
                        Console.Clear();
                        ShowBoard(ref board);
                        Console.WriteLine("O가 이겼습니다.");
                        break;
                    }
                    else if (IsOver(ref board) == 2)
                    {
                        Console.Clear();
                        ShowBoard(ref board);
                        Console.WriteLine("X가 이겼습니다.");
                        break;
                    }
                }
                return;
            }
        }
    }

     

    한 클래스에서 구현하려다보니 여러 메소드들을 static으로 구현해주었다. 하지만 아직 강의에서 클래스를 다루지 않았기 때문에 이런 식으로 구현해 보았다.

     

    2주차 강의를 다 듣고 나서는 C# 개인 과제를 진행했다. 그리고 중간에, 오후 2시와 오후 5시에 각각 체크리스트와 TIL 특강이 있었다. 캠프 튜터님과 매너저님에 의해 진행되었다. 오늘부터 TIL 특강에서 배운대로 작성해보려고 한다.

     

    C# 개인 과제 주제는 텍스트형 게임을 만드는 것이었다. 일단 필수 요구사항은 모두 완성했다.

    • 게임 시작 화면 구현
    • 상태 보기 기능 구현
    • 인벤토리와 아이템 장착 기능 구현
    • 상점과 구매 기능 구현

    결과물은 글 마지막에 추가할 것이고, 진행하면서 마주쳤던 문제들에 대해 작성해보려고 한다.

     

    ! 문제 발생 1

    레벨을 표시하는 과정에서 "Lv 1"의 형태가  아닌, "Lv 01"처럼 앞에 0으로 자릿수를 채우라는 요구사항이 있었다.

    해결

    다른 언어에서 비슷한 것이 있었다. C++이나 파이썬 등에서 본 적이 있어서, 구글에서 방법을 찾아보았더니 쉽게 해결할 수 있었다.

    Console.WriteLine("Lv. {0}", character.level.ToString("D2"));

     

    이런 식으로 ToString() 안에 "D2"를 넣어 정수 두 자릿수임을 표현하였더니 해결되었다.

    학습

    자릿수 표현을 바꾸고 싶을 때 ToString() 안에 양식을 지정할 수 있다.

     

     

    ! 문제 발생 2

    클래스를 상속할 때 자식 클래스에서 생성자를 만드는 방법이 달랐다.

    시도

    평소 하던 것처럼 자식 클래스에서 생성자를 이래저래 만들어 보았다. 그런데 아무리 해도 자꾸 빨간 줄이 뜨며 해결되지 않았다. 어디가 문제인지 도통 알 수 없었다. 

    해결

    계속 다른 언어에서 했던 것처럼 했는데도 안 돼서, 문법이 문제일까 구글에 검색해봐야 했다.

    결국 base라는 걸 사용해야 한다는 것을 알게 되었고, 아래 같이 작성하여 해결하였다.

        public class MyItem : Item
        {
            public bool isEquiped;
    
            public MyItem(string name, string description, int atk, int amr, int price, bool isEquiped) : base(name,description, atk, amr, price)
            {
                this.isEquiped = isEquiped;
            }
        }

     

    학습

    자식클래스는 자신이 노출하고자 하는 생성자들을 base 키워드를 이용하여 반드시 재정의해야 한다.

     

     

    ! 문제 발생 3

    Item 클래스를 상속받은 두 자식클래스 MyItem, ShopItem을 다루다가, ShopItem에서 MyItem으로 형변환이 필요한 상황이 닥쳤다.

    시도

    (MyItem) shopItem 을 시도해보았으나 당연히 되지 않았다.

    (MyItem) (Item) shopItem 도 시도해보았다. 당연히 되지 않았다. 컴파일은 되는데 런타임에서 에러가 난다.

    해결

    결국 shopItem의 인자들을 모두 수동으로 대입하여 new MyItem() 을 해야했다...

    찾아보기

    수동 형변환 방법이라던가, 업캐스팅 방법을 좀 더 찾아봐야 할 것 같다.

    [결과물]

    숙제 1
    숙제 2-1
    숙제 2-2
    개인 과제 시작화면
    상태 보기

     

    상점에서 4번 검을 구매했다.
    인벤토리에서 구매한 검을 장착했다.
    바뀐 스탯

    [회고]

    오늘은 개인과제 할 때 시간이 빠르게 갔다. 내일은 C# 강의 3주차를 수강하고, 개인과제를 좀 더 만져볼 생각이다. 일단 입력이 잘못되었을 때 메세지 출력을 어떻게 할 것인지, 그리고 추가 기능도 구현에 도전해볼 것인지 등을 생각해봐야겠다.