21.12.30 부대 관리 & 드랍쉽

2021. 12. 30. 21:57C#/수업 내용

업캐스팅, 다운캐스팅이 뭐지?

 

OOP의 캡슐화를 위해

다른 클래스의 멤버에 직접 접근해서 값을 가져오는 방식은 적절치 않다.

함수를 통해 내부적으로 작동해서 반환하도록 하는 게 바람직하다.

 

enum은 클래스 바깥에서 선언해야 한다.

 

확장성을 늘리려면 상속 계층을 더 추가해보자.

 

이하 수업내용 ------------------------------------------

 

1. enum을 통해 마린과 저글링을 분류할 수 있도록 실습했다.

2. 드랍쉽 구현을 실습했다.

-> 유닛을 드랍쉽에 적재하는 Load 메서드와 적재한 모든 유닛을 현재 위치에 재배치하는 UnloadAll 메서드를 구현

-> 유닛이 드랍쉽에 탑승 중일 땐, 유닛의 개별적인 이동을 유닛의 bool 변수로 제어했음.

-> 유닛이 드랍쉽에 탑승 중일 땐, 유닛의 위치 변수는 드랍쉽의 위치 값을 따라감.

-> 드랍쉽에 자리가 없을 땐 더 이상 적재하지 않도록 제한함.

-> 드랍쉽이 태우려는 유닛과 위치 정보가 같지 않을 땐 태우지 못하게 제한함.

-> 드랍쉽 또한 Unit 을 상속받기 때문에 혹여 자기 자신을 Load하지 않도록 제한함.

 

using System;

namespace helloworldConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Army army = new Army(11);
            Marine mar0 = new Marine("해리");
            Marine mar1 = new Marine("론");
            Marine mar2 = new Marine("헤르마오니");
            army.AddUnit(mar0);
            army.AddUnit(mar1);
            army.AddUnit(mar2);
            
            //캡슐화 
            //army.armies[0].Init(new Position(2, 3));
            //var unit = army.GetUnit(0);
            //unit.Init(new Position(2, 3));

            Zergling zerg0 = new Zergling("볼드");
            Zergling zerg1 = new Zergling("모르");
            Zergling zerg2 = new Zergling("모트");
            Zergling zerg3 = new Zergling("모모");
            Zergling zerg4 = new Zergling("모비");
            Zergling zerg5 = new Zergling("모스");
            Zergling zerg6 = new Zergling("모기");
            army.AddUnit(zerg0);
            army.AddUnit(zerg1);
            army.AddUnit(zerg2);
            army.AddUnit(zerg3);
            army.AddUnit(zerg4);
            army.AddUnit(zerg5);
            army.AddUnit(zerg6);

            DropShip ship0 = new DropShip("무궁화호");
            ship0.Init(new Position(1, 1));

            foreach (Unit unit in army.armies)
            {
                if (unit != null)
                {
                    unit.Init(new Position(5, 5));
                    ship0.Load(unit);
                }
            }
            
            ship0.Move(new Position(5, 5));
            
            foreach (Unit unit in army.armies)
            {
                if (unit != null)
                    ship0.Load(unit);
            }

            ship0.Move(new Position(9, 9));

            foreach (Unit unit in army.armies)
            {
                if (unit != null)
                    unit.CheckPos();
            }

            ship0.UnloadAll();
            ship0.Move(new Position(0, 0));
            
            foreach (Unit unit in army.armies)
            {
                if (unit != null)
                    unit.CheckPos();
            }

            foreach (Unit unit in army.armies)
            {
                if (unit != null)
                {
                    unit.Move(new Position(2, 5));
                    ship0.Load(unit);
                }
            }
        }
    }
}

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

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

namespace helloworldConsoleApp1
{
    class Marine : Unit
    {
        private int hp;
        public int damage;
        private string bloodColor;
        private string weapon;

        public Marine(string name) : base(name){
            unitType = eUnitType.Marine;
        }

        public override void Init(Position posi)
        {
            base.Init(posi);
            this.weapon = "gun";
            this.bloodColor = "Red";
            this.hp = 4;
            this.damage = 1;
            Console.WriteLine("유닛 hp 상태 : {0},  유닛 공격력 : {1}\n", this.hp, this.damage);
        }

        public override void Attack(Unit attacker, Unit target, string weapon)
        {
            base.Attack(this, target, this.weapon);
            target.Hit(this, this.damage, 1, "z", target);
        }

        public override void Hit(Unit sender, int damage, int hp, string bloodColor, Unit target)
        {
            this.hp -= damage;
            base.Hit(sender, damage, this.hp, this.bloodColor, target);
        }
    }
}

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

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

namespace helloworldConsoleApp1
{
    class DropShip : Unit
    {
        public int hp;
        public Unit[] loadingCell;

        public DropShip(string name) : base(name)
        {
            this.unitType = eUnitType.Machines;
        }

        public override void Init(Position posi)
        {
            base.Init(posi);
            this.hp = 8;
            this.loadingCell = new Unit[8];
        }

        public void Load(Unit unit)
        {
            if(unit != this)
            {
                if (this.pos.x == unit.pos.x && this.pos.y == unit.pos.y)
                {
                    int index;
                    for (index = 0; index < loadingCell.Length; index++)
                    {
                        if (loadingCell[index] == null)
                        {
                            break;
                        }
                    }
                    if (index == loadingCell.Length)
                    {
                        Console.WriteLine("수용량 포화!");
                        return;
                    }
                    loadingCell[index] = unit;
                    unit.isTakingDropship = true;
                    Console.WriteLine("{0}, {1} 탑승 완료", unit.Name, this.Name);
                }
                else
                {
                    Console.WriteLine("더 가까이 접근해야 합니다.");
                }
            } else
            {
                Console.WriteLine("자기 자신을 수송시킬 순 없습니다.");
            }
        }

        public void UnloadAll()
        {
            for(int i = 0; i < loadingCell.Length; i++)
            {
                if (loadingCell[i] != null)
                {
                    loadingCell[i].isTakingDropship = false;
                    loadingCell[i] = null;
                }
            }
        }

        public override void Move(Position posi)
        {
            base.Move(posi);
            foreach(Unit unit in loadingCell)
            {
                if(unit != null)
                {
                    unit.pos = this.pos;
                }
            }
        }

        public override void CheckPos()
        {
            base.CheckPos();
        }
    }
}

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

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, 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 void Hit(Unit sender, int damage, int hp, string bloodColor, Unit target)
        {
            Console.WriteLine("{4}가 {0}에게 공격당해 {3}색의 피를 흘리고 {1}의 피해를 입었습니다. 현재 hp 상태는 {2}입니다.", sender.Name, damage, hp, bloodColor, target.Name);
        }

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

 

'C# > 수업 내용' 카테고리의 다른 글

22.01.03 인벤토리에서 아이템 꺼내오기, 다시 넣기  (0) 2022.01.03
22.01.01 캐리어  (2) 2022.01.01
21.12.29 아이템 & 인벤토리  (0) 2021.12.30
21.12.28 벌쳐 vs 질럿  (0) 2021.12.29
21.12.27 마린 vs 저글링  (0) 2021.12.28