09시 알고리즘 특강시간에 스택, 큐, 정렬(버블,선택,퀵)에 대해서 다루었다.
강의 시간에 구현한 스택과 큐는 string 타입으로만 구현해서 제네릭으로 다시 만들어봤다.
public class Stack<T>
{
private T[] values;
private int top = -1;
public Stack(int length)
{
values = new T[length];
}
public void Push(T data)
{
if(IsFull())
{
Console.Error.WriteLine("꽉 참");
return;
}
values[++top] = data;
}
public T Pop()
{
if (IsEmpty())
throw new InvalidOperationException("스택이 비어있음");
return values[top--];
}
public bool IsFull() { return top >= values.Length-1; }
public bool IsEmpty() { return top == -1; }
public void Print()
{
for(int i=0; i <= top; ++i)
{
Console.Write(values[i]+" ");
}
}
}
스택의 기본 원리에대해서는 찾아보면 잘 나오겠지만, 그보다도 직접 구현할 때 top의 초기 값에 신경을 제대로 쓰지 못하면 실수할 수 있을 것 같다는 생각이 들었다.
위에서는 top의 초기 값을 -1로 두어서 Push 메서드가 호출되면 전위 증가연산자로 top에 1이 바로 더해지도록 한다.
Pop메서드의 경우에는 요소를 먼저 반환해준 뒤에 후위 감소연산자를 호출하도록 했다.
이런 사소한 순서의 디테일을 계속 지킬 수 있도록 신경써야겠다.
큐에 대해서는 따로 정리했다.
의외로 너무 간단한 부분에서 고민을 아주 조금 했다.
위 코드에서(스택, 큐 공통) 요소를 빼올 때 IsEmpty()의 값이 참이면 아무 것도 리턴하고 싶지 않으려면 어떡하나.. 고민을 하다가 찾은게 throw와 try, catch이다.
throw로 예외를 던지는 문법이 있어서 연습해볼 수 있었다.
Stack<int> stack = new Stack<int>(10);
try
{
stack.Pop();
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.Message);
}
try문에서 시도해보고 catch문에서 오류를 띄울 수 있는 기능인데
사실 전에는 무슨 이런 문법이 다 있나 싶었지만, 직접 써보니 꽤 편리하고 깔끔한 느낌도 받았다.
오늘 내가 자발적으로 스킬 구현을 하겠다고 했지만... 고민만 하다가 절반 정도만 만들었다. 슬프다
internal class Skill
{
public int OriginNumber { get; set; } //스킬 넘버
public string Name { get; set; } //스킬 이름
public int Cost { get; set; } //스킬 사용 시 드는 Mp
public int AtkMultiplier { get; set; } //기본 데미지에 곱할 배수
public string Description { get; set; } //스킬 설명
static private int tempNumber = 1; //정적 변수 증가시켜 넘버링
public Skill(string name, int cost, int atkMultiplier, string description)
{
Name = name;
Cost = cost;
AtkMultiplier = atkMultiplier;
Description = description;
OriginNumber = tempNumber++;
}
public void Use(Player player, Monster monster)
{
//플레이어 MP 소모
player.Mp -= Cost;
//몬스터 피격
monster.GetDamage(player.Atk * AtkMultiplier);
}
public void ShowText()
{
Console.WriteLine($"{OriginNumber}. {Name} - MP {Cost}");
Console.WriteLine($" {Description}\n");
}
}
tempNumber
를 생성자에서 증가시키며 스킬에 넘버링을 해주었다.AtkMultiplier
는 플레이어의 기본 데미지에 곱할 배수이다. 이 부분은 더 좋은 아이디어가 없으면 계속 가져갈 듯 싶다.여기서 만든 스킬을 던전의 결투 부분에서 어떻게 써먹을지 한참을 고민 하고 써보고 다시 되돌리고를 반복하는 하루였다. (그냥 메서드 막 만들어버릴걸...)
기존에 있는 전투 메서드의 줄기도 꽤 큰편이어서 따로 메서드를 만들자니 코드가 너무 비대해지고, 기존의 공격 메서드에 어떻게든 넣어보자니 그것도 녹록치 않았다.
그리고 요구사항에는 한 번에 다수의 적을 랜덤으로 공격하는 스킬도 있었다.
그 부분도 나중에 개발할 것을 고려하니 그냥 뇌와 손가락 이 멈춰버렸다.
(저장이 별 5개인데 스킬이 별 4개라고요..??)
전투 시 선택지가 기본 공격과 스킬이므로 스킬 클래스의 Use 메서드를 어떻게든 활용해보는 방법으로 해봐야겠다.
Use에서 다수 공격인지 단일 공격인지도 판단해보면 얼추 그림이 나올 듯 하다.
우선 오늘은 내 컨디션을 탓해보며.. 내일은 좀 더 쭉쭉 뻗어나가는 코딩의날이 되길 바란다.