21.12.30 부대 관리 & 드랍쉽
2021. 12. 30. 21:57ㆍC#/수업 내용
업캐스팅, 다운캐스팅이 뭐지?
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 |