22.01.01 캐리어

2022. 1. 1. 02:11C#/수업 내용

https://www.delftstack.com/ko/howto/csharp/delete-object-in-csharp/

 

C#에서 개체 삭제

C#에서 null 값을 할당하여 사용자 정의 클래스의 개체를 삭제할 수 있습니다.

www.delftstack.com

객체 삭제하는 법.

return에 null을 받아 메인함수에서 null을 할당하자.

 

이하 실습내용-----------------------------------------------------------------------------------

 

1. 캐리어 구현을 실습했다.
한 가지 과제가 있었다. 유닛을 죽이면 해당 유닛은 더 이상 살아 움직이지 못해야 하는데,
이를 위해 해당 유닛의 객체에 할당된 메모리를 해제하거나, 그 객체에 접근할 방법이 없게 해야 했다.
나는 객체를 참조하는 포인터에 null을 할당함으로써 객체에 접근하는 경로를 끊기로 했다.

 

-> 캐리어가 죽을 때 그 캐리어 소유의 인터셉터도 모두 죽도록 DestroyInterceptor()함수를 만듦.

-> 캐리어가 Attack()을 하면 그 캐리어 소유의 인터셉터 모두에게 Attack()함수 실행 명령이 가게 함.

-> BuildInterceptor()함수로 Carrier에서 인터셉터 객체를 생성한 후 내부 배열에 할당한다.

using System;

namespace helloworldConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Carrier carrier = new Carrier("캐리어");
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();

            Unit vulture_Unit = new Vulture("벌쳐1");
            vulture_Unit.Init(new Position(2,3));

            Unit itct0 = carrier.interceptorRoom[0];
            vulture_Unit.Attack(vulture_Unit, ref itct0, "zdxv");
            carrier.interceptorRoom[0] = (Interceptor)itct0;
            carrier.BuildInterceptor();

            carrier.DestroyInterceptors();
            carrier.BuildInterceptor();
            carrier.BuildInterceptor();

            carrier.Attack(carrier, ref vulture_Unit, "z");
        }
    }
}

----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class Unit
    {
        public eUnitType unitType = eUnitType.None;
        public Position pos;
        public bool isTakingDropship = false;

        public string Name
        {
            get;
            private set;
        }

        public Unit(string name)
        {
            this.Name = name;
        }

        virtual public void Attack(Unit attacker, ref Unit target, string weapon)
        {
            Console.WriteLine("{0}가 {1}를 {2}으로 공격합니다.", attacker.Name, target.Name, weapon);
        }

        virtual public void Move(Position posi)
        {
            if (!isTakingDropship)
            {
                Console.WriteLine("{4}가 ({0}, {1})에서 ({2}, {3})으로 이동합니다.\n", this.pos.x, this.pos.y, posi.x, posi.y, this.Name);
                this.pos = posi;
            }
            else
            {
                Console.WriteLine("해당 유닛은 현재 드랍십 탑승 중입니다.");
            }
        }

        virtual public void CheckPos(){
            Console.WriteLine("현재 위치는 ({0}, {1})입니다.\n", this.pos.x, this.pos.y);
        }

        virtual public Unit Hit(Unit sender, int damage, int hp, string bloodColor, Unit target)
        {
            if(this.unitType != eUnitType.Marine && this.unitType != eUnitType.Zergling)
            {
                Console.WriteLine("{3}가 {0}에게 공격당해 {1}의 피해를 입었습니다. 현재 기체 내구도는 {2}입니다.", sender.Name, damage, hp, target.Name);
                return this;
            }
            Console.WriteLine("{4}가 {0}에게 공격당해 {3}색의 피를 흘리고 {1}의 피해를 입었습니다. 현재 생명력 상태는 {2}입니다.", sender.Name, damage, hp, bloodColor, target.Name);
            return this;
        }

        virtual public void Init(Position posi)
        {
            this.pos = posi;
            Console.WriteLine("유닛 이름 : {0}\n유닛 위치 : ({1}, {2})", this.Name, this.pos.x, this.pos.y);
        }

        virtual public void Destroy()
        {
            Console.WriteLine("{0} {1} destroyed.", this.unitType, this.Name);
        }
    }
}

----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class Carrier : Unit
    {
        public Interceptor[] interceptorRoom;
        private int hp;

        public Carrier(string name) : base(name)
        {
            this.unitType = eUnitType.Carrier;
            this.hp = 10;
            this.interceptorRoom = new Interceptor[8];
        }

        public Unit BuildInterceptor()
        {
            int index;
            for (index = 0; index < interceptorRoom.Length; index++)
            {
                if (interceptorRoom[index] == null)
                {
                    break;
                }
            }
            if (index == interceptorRoom.Length)
            {
                Console.WriteLine("수용량 초과!");
                return null;
            }
            interceptorRoom[index] = new Interceptor(index + 1 + "번째");
            
            Console.WriteLine("{0}, {1} Build Complete.", interceptorRoom[index].unitType, interceptorRoom[index].Name);
            return interceptorRoom[index];
        }

        public override void Attack(Unit attacker, ref Unit target, string weapon)
        {
            Console.WriteLine("{0}, {1}에게 공격 명령.", this.Name, target.Name);
            foreach(Interceptor itct in interceptorRoom)
            {
                if(itct != null)
                {
                    itct.Attack(itct, ref target, "z");
                }
            }
        }

        public override Unit Hit(Unit sender, int damage, int hp, string bloodColor, Unit target)
        {
            this.hp -= damage;
            base.Hit(sender, damage, this.hp, "z", target);
            if(this.hp > 0)
            {
                return this;
            }
            base.Destroy();
            DestroyInterceptors();
            return null;
        }

        public void DestroyInterceptors()
        {
            for(int i = 0; i < interceptorRoom.Length; i++)
            {
                interceptorRoom[i] = null;
            }
        }
    }
}

----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class Interceptor : Unit
    {
        private int hp;
        private int damage;
        private string weapon;

        public Interceptor(string name) : base(name)
        {
            this.unitType = eUnitType.Interceptor;
            this.hp = 2;
            this.damage = 1;
            this.weapon = "machine gun";
        }

        public override void Attack(Unit attacker, ref Unit target, string weapon)
        {
            if(target != null)
            {
                base.Attack(this, ref target, this.weapon);
                target = target.Hit(this, this.damage, 1, "z", target);
            } else
            {
                Console.WriteLine("타겟이 존재하지 않습니다.");
            }
        }

        public override Unit Hit(Unit sender, int damage, int hp, string bloodColor, Unit target)
        {
            this.hp -= damage;
            base.Hit(sender, damage, this.hp, "z", target);
            if (this.hp > 0)
            {
                return this;
            }
            base.Destroy();
            return null;
        }
    }
}

실행 결과