[TIL] 4일 차 - C# 강의 정리 (제너릭과 out, ref 키워드) 및 문제 풀이

ChangBeom·2025년 1월 27일

TIL

목록 보기
5/53
post-thumbnail

[내용 정리]

<제너릭>

  • 제너릭은 클래스나 메소드를 일반화시켜 다양한 자료형에 대응할 수 있는 기능이다.
  • 제너릭을 사용하면 코드의 재사용성을 높일 수 있다.
  • C#에서는 <\T> 형태의 키워드를 이용하여 제너릭을 선언한다.
  • 제너릭 클래스나 메소드에서 사용할 자료형은 선언 시점이 아닌 사용 시점에 결정된다.
  • 제너릭 클래스나 메소드를 사용할 때는 <\T> 대신 구체적인 자료형을 넣어줘야 한다.

<예시> : 제너릭을 이용해 스택 만들기

using System;

namespace Generic_Stack
{
    internal class Program
    {
        class Stack<T>
        {
            private T[] elements;
            private int top;

            public Stack()
            {
                elements = new T[100];
                top = 0;
            }

            public void Push(T item)
            {
                elements[top++] = item;
            }

            public T Pop()
            {
                return elements[--top];
            }
        }
        static void Main(string[] args)
        {
            Stack<int> intStack = new Stack<int>();
            intStack.Push(123);
            intStack.Push(456);
            intStack.Push(789);
            Console.WriteLine(intStack.Pop()); // Stack은 선입 후출 구조기 때문에 789 출력
        }
    }
}

<out, ref 키워드>

  • out, ref 키워드는 메소드에서 매개변수를 전달할 때 사용한다.
  • out 키워드는 메소드에서 반환 값을 매개변수로 전달하는 경우에 사용된다.
  • ref 키워드는 메소드에서 매개변수를 수정하여 원래 값에 영향을 주는 경우에 사용한다.
  • out, ref 키워드를 사용하면 메소드에서 값을 반환하는 것이 아니라, 매개변수를 이용하여 값을 전달할 수 있다.

<예시> : out, ref 키워드 사용 예시

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // out 키워드 사용 예시
            void Divide(int a, int b, out int quotient, out int remainder)
            {
                quotient = a / b;
                remainder = a % b;
            }

            int quotient, remainder;
            Divide(9, 2, out quotient, out remainder);
            Console.WriteLine($"{quotient}, {remainder}"); // 몫은 4 나머지는 1 이므로 "4, 1" 출력

            // ref 키워드 사용 예시
            void Swap(ref int a, ref int b)
            {
                int temp = a;
                a = b;
                b = temp;
            }

            int x = 1, y = 9;
            Swap(ref x, ref y);
            Console.WriteLine($"{x}, {y}"); // 1과 9의 값을 바꿔주기 때문에 "9, 1" 출력
        }
    }
}

<주의 사항>

1. 값의 변경 가능성
ref 매개변수를 사용하면 메소드 내에서 해당 변수의 값을 직접 변경할 수 있다. 이는 예기치 않은 동작을 초래할 수 있으므로 주의가 필요하다.

2. 성능 이슈
ref 매개변수는 값에 대한 복사 없이 메소드 내에서 직접 접근할 수 있기 때문에 성능상 이점이 있다. 그러나 너무 많은 매개변수를 ref로 전달하면 코드의 가독성이 떨어지고 유지보수가 어려워질 수 있다. 따라서 적절한 상황에만 ref를 사용하는 것이 좋다.

3. 변수 변경 여부 주의
out 매개변수는 메소드 내에서 반드시 값을 할당해야 한다. 따라서 out 매개변수를 전달할 때 해당 변수의 이전 값이 유지되지 않으므로 주의해야 한다.


[1. 숫자 맞추기 게임]

  • 해당 문제는 Unity Quest를 진행하며 풀었던 문제와 동일하지만 복습 겸 다시 한번 풀어봤습니다.

* 숫자 맞추기 게임을 작성하세요. 컴퓨터가 1부터 100 사이의 숫자를 선택하면 사용자가 그 숫자를 맞추는 게임을 구현하세요. 사용자가 숫자를 입력하면 컴퓨터는 숫자가 더 크거나 작은지 힌트를 줍니다. 맞출 때까지 반복합니다.

using System;
using System.Threading;

namespace CorrectNumber
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Random random = new Random();

            int answer = random.Next(1,101);
            int count = 0;

            Console.WriteLine("****숫자 맞추기 게임****");
            Console.WriteLine("(1~100) 사이의 숫자를 맞추는 게임입니다.");
            Console.WriteLine("사용자가 숫자를 입력하면 정답보다 큰지 작은지 알려드립니다.");

            Console.WriteLine();

            while (true)
            {
                Console.Write("숫자를 입력 해주세요 (범위 : 1~100) : ");
                int number = int.Parse(Console.ReadLine());

                count++;

                if(number > answer)
                {
                    Console.WriteLine("숫자가 너무 큽니다! 더 작은 수를 입력해주세요.");
                }
                else if(number < answer)
                {
                    Console.WriteLine("숫자가 너무 작습니다! 더 큰 수를 입력해주세요.");
                }
                else
                {
                    Console.WriteLine($"정답입니다! 답 : {answer}, 시도 횟수 : {count}");
                    break;
                }

                Console.WriteLine();
            }
        }
    }
}
  • System namespace에 존재하는 Random 클래스의 Next함수를 사용해서 정답인 answer 변수를 랜덤한 값으로 초기화 한다.
  • Next()의 첫번째 매개변수는 최소값이고, 두번째 매개변수는 최대값인데 최대값은 자신을 포함하지 않는다는 것을 잊지말자. (ex. random.Next(1,101) ==> 1~100 )

[2. 틱택토 게임]

* 틱택토 게임을 구현하세요.

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            bool Check(char[,] c)
            {
                if (c[0, 0] == 'o' && c[1, 1] == 'o' && c[2, 2] == 'o'
                        || c[0, 0] == 'x' && c[1, 1] == 'x' && c[2, 2] == 'x'
                            || c[2, 0] == 'o' && c[1, 1] == 'o' && c[0, 2] == 'o'
                                || c[2, 0] == 'x' && c[1, 1] == 'x' && c[0, 2] == 'x')
                {
                    return true;
                }
                else if (c[0, 0] == 'o' && c[0, 1] == 'o' && c[0, 2] == 'o'
                            || c[0, 0] == 'x' && c[0, 1] == 'x' && c[0, 2] == 'x'
                                || c[1, 0] == 'o' && c[1, 1] == 'o' && c[1, 2] == 'o'
                                    || c[1, 0] == 'x' && c[1, 1] == 'x' && c[1, 2] == 'x'
                                        || c[2, 0] == 'o' && c[2, 1] == 'o' && c[2, 2] == 'o'
                                            || c[2, 0] == 'x' && c[2, 1] == 'x' && c[2, 2] == 'x')
                {
                    return true;
                }
                else
                {
                    return false;
                }

            }

            Console.WriteLine("<틱택토 게임>");

            Console.WriteLine();

            Console.WriteLine("  -   -   -  ");
            Console.WriteLine("| x |   | o |");
            Console.WriteLine("  -   -   -  ");
            Console.WriteLine("|   | x |   |");
            Console.WriteLine("  -   -   -  ");
            Console.WriteLine("| x | o | o |");
            Console.WriteLine("  -   -   -  ");

            Console.WriteLine();

            Console.WriteLine("***********************************");

            Console.WriteLine();

            Console.WriteLine("틱택토 게임이란?");
            Console.WriteLine("틱택토 게임은 두 명의 사람이 번갈아가며 말을 놓는 게임입니다.");
            Console.WriteLine("게임은 3 x 3 격자판에서 이루어지며 처음에는 모두 비어있습니다.");
            Console.WriteLine("두 사람은 자신의 턴에 각각 O 또는 X 말을 격자판에 놓을 수 있습니다.");
            Console.WriteLine("자신의 말로 가로, 세로, 대각선 방향으로 3칸을 잇게 되면 승리입니다.");
            Console.WriteLine("승부가 나지 않은 상태로 게임판이 가득 차면 무승부로 게임이 종료됩니다.");
            Console.WriteLine("첫 턴 플레이어 : o , 둘째 턴 플레이어  : x");

            Console.WriteLine();

            char[,] arr = { { ' ', ' ', ' ' }, { ' ', ' ', ' ' }, { ' ', ' ', ' ' } };
            bool turn = false;
            int turnCount = 0;

            while (true)
            {
                if (turnCount == 9)
                {
                    Console.WriteLine();

                    Console.WriteLine("  -   -   -  ");
                    Console.WriteLine($"| {arr[0, 0]} | {arr[0, 1]} | {arr[0, 2]} |");
                    Console.WriteLine("  -   -   -  ");
                    Console.WriteLine($"| {arr[1, 0]} | {arr[1, 1]} | {arr[1, 2]} |");
                    Console.WriteLine("  -   -   -  ");
                    Console.WriteLine($"| {arr[2, 0]} | {arr[2, 1]} | {arr[2, 2]} |");
                    Console.WriteLine("  -   -   -  ");

                    Console.WriteLine();

                    Console.WriteLine("무승부 입니다!");
                    break;
                }

                Console.WriteLine("***********************************");

                Console.WriteLine();

                Console.WriteLine("현재 상황");

                Console.WriteLine();

                Console.WriteLine("  -   -   -  ");
                Console.WriteLine($"| {arr[0, 0]} | {arr[0, 1]} | {arr[0, 2]} |");
                Console.WriteLine("  -   -   -  ");
                Console.WriteLine($"| {arr[1, 0]} | {arr[1, 1]} | {arr[1, 2]} |");
                Console.WriteLine("  -   -   -  ");
                Console.WriteLine($"| {arr[2, 0]} | {arr[2, 1]} | {arr[2, 2]} |");
                Console.WriteLine("  -   -   -  ");

                Console.WriteLine();

                Console.WriteLine("  -   -   -  ");
                Console.WriteLine("| 1 | 2 | 3 |");
                Console.WriteLine("  -   -   -  ");
                Console.WriteLine("| 4 | 5 | 6 |");
                Console.WriteLine("  -   -   -  ");
                Console.WriteLine("| 7 | 8 | 9 |");
                Console.WriteLine("  -   -   -  ");

                Console.WriteLine();

                while (true)
                {
                    Console.Write("말을 놓을 위치를 정해주세요. (1 ~ 9) : ");

                    int loc = int.Parse(Console.ReadLine());
                    int x = 0;
                    int y = 0;

                    switch (loc)
                    {
                        case 1:
                            x = 0;
                            y = 0;
                            break;
                        case 2:
                            x = 0;
                            y = 1;
                            break;
                        case 3:
                            x = 0;
                            y = 2;
                            break;
                        case 4:
                            x = 1;
                            y = 0;
                            break;
                        case 5:
                            x = 1;
                            y = 1;
                            break;
                        case 6:
                            x = 1;
                            y = 2;
                            break;
                        case 7:
                            x = 2;
                            y = 0;
                            break;
                        case 8:
                            x = 2;
                            y = 1;
                            break;
                        case 9:
                            x = 2;
                            y = 2;
                            break;

                    }

                    if (arr[x, y] != ' ')
                    {
                        Console.WriteLine("이미 말이 놓여  있습니다. 다시 선택해주세요.");
                    }
                    else if(loc < 1 || loc > 9)
                    {
                        Console.WriteLine("격자판의 범위를 벗어났습니다. 다시 선택해주세요.");
                    }
                    else
                    {
                        if (!turn)
                        {
                            arr[x, y] = 'o';
                        }
                        else
                        {
                            arr[x, y] = 'x';
                        }

                        break;
                    }
                }

                if (Check(arr))
                {
                    if (!turn)
                    {
                        Console.WriteLine("첫 번째 턴 플레이어가 승리하였습니다! ( o )");
                        Console.WriteLine();

                        Console.WriteLine("  -   -   -  ");
                        Console.WriteLine($"| {arr[0, 0]} | {arr[0, 1]} | {arr[0, 2]} |");
                        Console.WriteLine("  -   -   -  ");
                        Console.WriteLine($"| {arr[1, 0]} | {arr[1, 1]} | {arr[1, 2]} |");
                        Console.WriteLine("  -   -   -  ");
                        Console.WriteLine($"| {arr[2, 0]} | {arr[2, 1]} | {arr[2, 2]} |");
                        Console.WriteLine("  -   -   -  ");
                    }
                    else
                    {
                        Console.WriteLine("두 번째 턴 플레이어가 승리하였습니다! ( x )");
                        Console.WriteLine();

                        Console.WriteLine("  -   -   -  ");
                        Console.WriteLine($"| {arr[0, 0]} | {arr[0, 1]} | {arr[0, 2]} |");
                        Console.WriteLine("  -   -   -  ");
                        Console.WriteLine($"| {arr[1, 0]} | {arr[1, 1]} | {arr[1, 2]} |");
                        Console.WriteLine("  -   -   -  ");
                        Console.WriteLine($"| {arr[2, 0]} | {arr[2, 1]} | {arr[2, 2]} |");
                        Console.WriteLine("  -   -   -  ");
                    }

                    break;
                }

                turnCount++;
                turn = !turn;
            }
        }
    }
}
  • while문을 통해 게임이 끝날 때 까지 반복해주며 진행하는 것이 포인트이다. 게임이 끝나는 조건은 어느한 플레이어가 승리하거나(Check 함수를 통해 확인) 모든 격자판이 채워졌을 때(turnCount 변수가 9가 되는 시점)이다.
  • Check 함수는 게임 진행 상황 데이터가 저장되어 있는 arr[,] 배열을 받아 가로, 세로, 대각선으로 동일한 말이 놓여 있는 지 판단하는 함수이다.
  • 편의를 위해 텍스트로 UI를 제작하다보니 코드가 길어진 것 같다...

지금까지 과제에 대한 설명이 없는 줄 알고 제목만 보고 느낌대로 풀었는데, 알고보니 강의자료에 과제 설명이 상세히 나와 있었다!!! 지금부턴 과제의 설명을 보고 풀어야겠다...


[3. 스네이크 게임 만들기]

* 콘솔 기반의 간단한 뱀 게임을 구현하는 것입니다. 기본적인 뱀 게임의 동작 방식은 아래와 같습니다.

  • 뱀은 매 턴마다 자신의 앞으로 이동합니다.
  • 사용자는 방향키를 이용하여 뱀의 이동 방향을 제어할 수 있습니다.
  • 뱀은 맵에 무작위로 생성되는 음식을 먹을 수 있습니다. 뱀이 음식을 먹으면 점수가 올라가고, 뱀의 길이가 늘어납니다.
  • 뱀의 벽이나 자신의 몸에 부딪히면 게임이 끝나고 'Game Over' 메시지를 출력합니다.

<요구사항>
1. Snake 클래스를 만듭니다. 이 클래스는 뱀의 상태와 이동, 음식 먹기, 자신의 몸에 부딪혔는지 확인 등의 기능을 담당합니다.
2. FoodCreator 클래스를 만듭니다. 이 클래스는 맵의 크기 내에서 무작위 위치에 음식을 생성하는 역할을 합니다.
3. Main 함수에서 게임을 제어하는 코드를 작성합니다. 이 코드는 뱀의 이동, 음식 먹기, 게임 오버 조건 확인 등을 주기적으로 수행합니다.
4. 필요에 따라 추가적인 함수나 클래스를 작성하여 게임을 완성합니다.

using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Xml.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //  맵 테두리 표현
            for (int i = 0; i < 80; i++)
            {
                Console.SetCursorPosition(i, 0);
                Console.Write('■');
                Console.SetCursorPosition(i, 20);
                Console.Write('■');
            }

            for (int i = 0; i < 20; i++)
            {
                Console.SetCursorPosition(0, i);
                Console.Write("■");
                Console.SetCursorPosition(80, i);
                Console.Write("■");
            }


            // 뱀의 초기 위치와 방향을 설정하고, 그립니다.
            Point p = new Point(4, 5, '*');
            Snake snake = new Snake(p, 4, Direction.RIGHT);
            snake.Draw();

            // 음식의 위치를 무작위로 생성하고, 그립니다.
            FoodCreator foodCreator = new FoodCreator(80, 20, '$');
            Point food = foodCreator.CreateFood();
            food.Draw();

            int length = snake.body.Count;
            int score = 0;

            // 게임 루프: 이 루프는 게임이 끝날 때까지 계속 실행됩니다.
            while (true)
            {
                //  방향키를 통해 뱀이 이동할 방향 입력받기
                switch (Console.ReadKey(true).Key)
                {
                    case ConsoleKey.LeftArrow:
                        snake.dir = Direction.LEFT;
                        break;

                    case ConsoleKey.RightArrow:
                        snake.dir = Direction.RIGHT;
                        break;

                    case ConsoleKey.UpArrow:
                        snake.dir = Direction.UP;
                        break;

                    case ConsoleKey.DownArrow:
                        snake.dir = Direction.DOWN;
                        break;
                }

                //  뱀이 음식을 먹었을 경우
                if (snake.Eat(food))
                {
                    score++;

                    food = foodCreator.CreateFood();
                    food.Draw();
                }
                else
                {
                    snake.Move();
                }

                if (snake.IsHitWall() || snake.IsHitTail())
                {
                    break;
                }

                Thread.Sleep(1); // 게임 속도 조절 (이 값을 변경하면 게임의 속도가 바뀝니다)

                Console.SetCursorPosition(85, 0);
                Console.WriteLine($"점수 : {score}");

                Console.SetCursorPosition(85, 2);
                Console.WriteLine($"몸 길이 : {snake.body.Count}");
            }

            Console.SetCursorPosition(45, 22);
            Console.WriteLine("Game Over!");
        }
    }

    public class Snake
    {
        public List<Point> body;
        public Direction dir { get; set; }

        //  Snake 클래스 생성자
        public Snake(Point _body, int _length, Direction _dir)
        {
            body = new List<Point>();

            for (int i = 0; i < _length; i++)
            {
                Point p = new Point(_body.x, _body.y, _body.sym);
                body.Add(p);
                _body.x += 1;
            }

            dir = _dir;
        }

        //  뱀을 그려주는 메소드
        public void Draw()
        {
            for (int i = 0; i < body.Count; i++)
            {
                body[i].Draw();
            }
        }

        //  뱀을 입력받은 방향으로 이동해주는 메소드
        public void Move()
        {
            Point head = NextPosition(dir);
            Point tail = body.First();

            //  뱀의 이동방향으로 1칸 이동

            body.Add(head);
            head.Draw();

            body.Remove(tail);
            tail.Clear();
        }

        public Point NextPosition(Direction d)
        {
            Point next = new Point(body.Last().x, body.Last().y, body.Last().sym);

            switch (d)
            {
                case Direction.LEFT:
                    next.x += -1;
                    next.y += 0;
                    break;

                case Direction.RIGHT:
                    next.x += 1;
                    next.y += 0;
                    break;

                case Direction.UP:
                    next.x += 0;
                    next.y += -1;
                    break;

                case Direction.DOWN:
                    next.x += 0;
                    next.y += 1;
                    break;
            }

            return next;
        }
        public bool Eat(Point food)
        {
            Point head = NextPosition(dir);

            if (head.IsHit(food))
            {
                food.sym = '*';
                body.Add(food);
                food.Draw();
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool IsHitWall()
        {
            Point head = body.Last();

            if (head.x == 0 || head.x == 80 || head.y == 0 || head.y == 20)
            {
                return true;
            }
            return false;
        }

        public bool IsHitTail()
        {
            Point head = body.Last();

            for (int i = 0; i < body.Count - 1; i++)
            {
                if (head.IsHit(body[i]))
                {
                    return true;
                }
            }
            return false;
        }
    }

    public class FoodCreator
    {
        public int mapSizeX { get; set; }
        public int mapSizeY { get; set; }
        public char shape { get; set; }

        Random random = new Random();

        //  FoodCreator 클래스 생성자
        public FoodCreator(int _x, int _y, char _shape)
        {
            mapSizeX = _x;
            mapSizeY = _y;
            shape = _shape;
        }

        //  랜덤한 위치에 음식 생성
        public Point CreateFood()
        {
            Point food = new Point(random.Next(1, mapSizeX), random.Next(1, mapSizeY), shape);

            return food;
        }
    }

    public class Point
    {
        public int x { get; set; }
        public int y { get; set; }
        public char sym { get; set; }

        // Point 클래스 생성자
        public Point(int _x, int _y, char _sym)
        {
            x = _x;
            y = _y;
            sym = _sym;
        }

        // 점을 그리는 메서드
        public void Draw()
        {
            Console.SetCursorPosition(x, y);
            Console.Write(sym);
        }

        // 점을 지우는 메서드
        public void Clear()
        {
            sym = ' ';
            Draw();
        }

        // 두 점이 같은지 비교하는 메서드
        public bool IsHit(Point p)
        {
            return p.x == x && p.y == y;
        }
    }
    // 방향을 표현하는 열거형입니다.
    public enum Direction
    {
        LEFT,
        RIGHT,
        UP,
        DOWN
    }
}

<사용하게 될 함수>

  • Thread.Sleep()

    • .NET에서 제공하는 Thread 클래스의 메소드 중 하나로, 특정 시간 동안 현재 실행 중인 스레드의 실행을 중지합니다.
    • 이 메소드의 매개변수로는 스레드가 일시 중지될 시간(밀리초 단위)를 전달합니다. 예를 들어, Thread.Sleep(1000)은 현재 스레드를 1초 동안 중지시킵니다.
    • 이 메소드를 사용하여 게임의 프레임 속도를 제어할 수 있습니다. Thread.Sleep() 메소드로 일정 시간을 기다리면, 그 시간 동안 다른 작업(예: 사용자 입력 처리, 뱀 이동 처리 등)을 수행할 수 있습니다.
  • Console.ReadKey()

    • .NET에서 제공하는 Console 클래스의 메소드 중 하나로, 사용자로부터 키보드 입력을 받아옵니다.
    • 이 메소드는 ConsoleKeyInfo 객체를 반환하며, 이 객체를 통해 어떤 키가 눌렸는지를 알 수 있습니다.
    • Console.ReadKey(true)와 같이 호출하면, 사용자로부터의 키 입력을 화면에 표시하지 않습니다. 이것은 게임에서 사용자의 입력을 처리할 때 화면에 키 입력이 표시되는 것을 방지하기 위한 것입니다.
    • 이 메소드를 사용하여 사용자로부터의 방향 키 입력을 받아 뱀의 이동 방향을 변경하는 등의 처리를 할 수 있습니다.

금방 끝낼 수 있을 것 같았는데 정말 오래걸린 문제... 지금부터 기능 하나씩 어떻게 구현했는 지 알아보자.

  • 벽에 부딪히면 GameOver가 되는 조건이 있었기 때문에 벽을 그릴 필요가 있었다. 그래서 for문을 돌며 Console.SetCursorPosition()을 통해 커서를 옮겨가며 '■' 기호를 그려 맵 테두리를 감싸주었다.
  • Console.ReadKey()를 통해 사용자가 입력한 방향을 토대로 뱀의 Direction을 저장해주었다. 그리고 그 Direction으로 뱀이 다음에 이동할 방향을 정해주었다.
  • Snake 클래스의 Move()와 NextPosition()은 가장 핵심적인 함수이다. 뱀을 직접적으로 움직이는 메소드인데, NextPosition()을 통해 다음 위치로 이동하고 Move() 함수를 통해 이동한 위치로 그려주는 로직이다.
  • Snake 클래스의 Eat() 함수는 뱀이 음식을 먹는 판정을 구현한 함수이다. 뱀이 다음으로 움직일 장소에 음식이 존재하면 음식이 있는 자리에 뱀의 몸통을 그려넣어 주며 뱀의 길이를 늘려준 후, true를 반환하는 로직이다. 이 함수를 통해 Main문에서 음식을 먹었을 때, 점수를 올리고 음식을 새로 생성한다.
  • 벽에 부딪혔을 때 GameOver되는 판정은 뱀의 머리가 벽의 x,y값과 일치하면 true를 반환하는 로직이고, 꼬리에 부딪혔을 때 GameOver되는 판정은 뱀의 머리가 머리를 제외한 모든 몸통 부분 중 하나라도 x,y값이 일치하면 true를 반환하는 로직이다.
  • FoodCreator 클래스의 CreateFood() 함수는 음식의 위치를 Random 클래스의 Next() 함수를 통해 랜덤으로 지정해준 후 Point 형식으로 반환해주는 로직이다.

0개의 댓글