2024-05-02

이재형·2024년 5월 2일
0
post-thumbnail

금일 C# 공부

1. Interface

설명: class 대신 Interface를 추가하여 생성
특징
1. 인스턴스를 생성할 수는 없지만 참조는 가능
2. 상속을 시키면 안의 멤버를 상속한 클래스에 강제로 생성시켜줘야 함
3. 객체별로 기능을 정리할 때 사용함

코드

public interface IProgram1
{
    void Phase1();
}

public interface IProgram2
{
    void Phase2();
}

public interface IProgram3
{
    void Phase3();
}

public class Program : IProgram1, IProgram2, IProgram3
{
    public void Phase1()
    {
        Console.WriteLine("안녕하십니까?");
    }

    public void Phase2()
    {
        Console.WriteLine("게임에 참가하신것을 환영합니다!");
    }

    public void Phase3()
    {
        Console.WriteLine("게임을 시작하도록 하겠습니다!");
    }
}

public class Start
{
    static void Main(string[] args)
    {
        Program Project = new Program();
        Project.Phase1();
        Project.Phase2();
        Project.Phase3();
    }
}

해석

1. class가 아닌 Interface를 붙여 IProgram1, IProgram2, IProgram3를 생성
2. 각 Interface에 메서드 Phase를 1~3까지 별도로 정의
3. 클래스 Program에 해당 Interface인 IProgram1~3을 상속 시킴
4. Interface에 있는 각 메서드를 재정의를 함
5. Main에서 Program생성자를 생성 후 각 메서드를 실행하여 재정의한 메서드 실행 여부 확인

2. abstract

설명: 기본 클래스 앞에 abstract를 추가하여 클래스를 추상화를 시킨다.
특징
1. 해당 추상화 클래스를 만들면 안의 멤버를 상속한 클래스에 강제로 생성시켜줘야 함
2. 추상화 클래스는 인스턴스 즉, 생성자를 만들 수가 없음
3. 추상화한 클래스를 제어할 때 사용함

코드

public abstract class abstractProgram
{
    public abstract void Phase1();
    public abstract void Phase2();
    public abstract void Phase3();

    public void Dialogue()
    {
        Phase1();
        Phase2();
        Phase3();
    }
}

class Program : abstractProgram
{
    public override void Phase1()
    {
        Console.WriteLine("안녕하십니까?");
    }

    public override void Phase2()
    {
        Console.WriteLine("게임에 참가하신것을 환영합니다!");
    }

    public override void Phase3()
    {
        Console.WriteLine("게임을 시작하도록 하겠습니다!");
    }
}

class Start
{
    static void Main(string[] args)
    {
        Program pro = new Program();
        pro.Dialogue();
    }
}

해석

1. 기본 클래스에 abstract를 붙여서 추상화를 설정
2. 추상화 클래스에 추상화 메서드 3개를 생성 후 일반 메서드 안에 메서드 3개를 추가
3. 다른 일반 클래스 생성 후 추상화 클래스를 상속 시킴
4. 일반 클래스에 추상화 클래스에 있는 각 멤버를 생성
5. abstract으로 만든 메서드를 override로 재정의 시킴
6. Main에 Progarm 생성자를 생성 후 일반 메서드를 실행하여 재정의한 메서드 실행 여부 확인


스파르타 TextDungeonGame 개발 5일차

구현 내용

1. 특정 몬스터를 처치하는 퀘스트 진행 시 잡은 횟수 갱신

public int MinionCount; // 미니언 킬 수
public int CannonCount; // 대포미니언 킬 수
public int vacuityCount; // 공허충 킬 수

Console.WriteLine("0. 거절");
Console.WriteLine("1. 수락");
// 선택에 따른 로직
choice = base.Choice(2, true);
switch (choice)
{
    case 0:
        Restart = true;
        access = false;
        break;
    case 1:
        // 몬스터의 이름이 
        switch (monsterName)
        {
            case "Minion":
                currentCount = charactor.MinionCount;
                maxCount = currentCount + 5;
                break;
            case "CannonMinion":
                currentCount = charactor.CannonCount;
                maxCount = currentCount + 5;
                break;
            case "vacuity":
                currentCount = charactor.vacuityCount;
                maxCount = currentCount + 5;
                break;
            default:
                // 몬스터 처치 퀘스트가 아니므로 없으므로 넘김
                break;
        }
        access = true;
        break;
}

public override void QuestClear(Charactor _charactor)
{
    // 몬스터의 이름이 
    switch (monsterName)
    {
        case "Minion":
            questGoal = string.Format($"{monsterName} 5마리 처치 ({_charactor.MinionCount - currentCount} / {maxCount - currentCount})");
            break;
        case "CannonMinion":
            questGoal = string.Format($"{monsterName} 5마리 처치 ({_charactor.MinionCount - currentCount} / {maxCount - currentCount})");
            break;
        case "vacuity":
            questGoal = string.Format($"{monsterName} 5마리 처치 ({_charactor.MinionCount - currentCount} / {maxCount - currentCount})");
            break;
        default:
            // 몬스터 처치 퀘스트가 아니므로 없으므로 넘김
            break;
    }


    // 최대 횟수가 0이 아니고 currentCount가 maxCount가 아니라면
    if (maxCount <= currentCount)
    {
        clearCheak = true;
    }
}

1. 플레이어의 정보에 각 해당 몬스터의 킬 합을 정하는 변수를 생성
2. 플레이어가 퀘스트를 수락하면 현재의 킬 수를 현재 카운트(currentCount), 목표 카운터(maxCount)로하여 캐릭터의 최신 킬 수를 저장함
3. 퀘스트를 확인할 때마다 플레이어의 현재 킬 수로 카운트 값을 비교하여 더 잡았는지 확인
4. 만약 처치 수를 통과하면 퀘스트 클리어(clearChek)를 true로 변경함


2. 몬스터 정보 얕은 복사로 인한 정보 공유 해결

public Monster(Monster clone)
{
    Name = clone.Name;
    Level = clone.Level;
    HP = clone.HP;
    ATK = clone.ATK;
}

// 해당 몬스터 정보를 토대로 monsterCount만큼 랜덤으로 스폰
Monster[] randomMonster = new Monster[monsterCount];
for(int i = 0; i < monsterCount; i++)
{
    // Monster[]에서 옮기면 얕은 복사가 되므로 새로운 객체를 만들어 생성함 (Monster.cs 33줄)
    Monster monsterClone = new Monster(MonstersLevel[random.Next(0, 3)]);
    randomMonster[i] = monsterClone;
}

1. Monster클래스에 오버로딩을 이용하여 몬스터의 정보를 새로 저장하게 함
2. 랜덤으로 똑같이 설정되어있지만 랜덤으로 몬스터의 정보를 새 객체로 전달하여 저장하게 함


배운 내용

1. #region 시작 문단 저장할 문단 #endregion 하여 코드를 메서드 처럼 줄일 수 있음
2. 클래스의 객체를 복사할 때 새 객체로 만들지 않으면 객체의 정보를 공유하는 문제가 생길 수 있음

정리

해결 못한 문제

1. 적이 2이상이 출현을 하고 모두 처치하고도 게임이 끝나지 않은 상황
2. 다른 적 죽이고 남은 미니언 1대 공격 시 체력 관련 없이 사망하는 상황

문제점

1. 발생: 테스트를 할 때 몬스터들의 체력이 높아 빠른 테스트를 하기 힘듬
1. 해결: 각 몬스터의 기본 정보를 낮춰 해결
2. 발생: 랜덤 객체를 복사를 할 때 얕은 복사로 이뤄져 객체의 정보가 공유 됨
2. 해결: 객체를 복사할 때 새로운 객체로 생성 후 값을 복사하는 깊은 복사로 해결

profile
한국사람

0개의 댓글