- 전략 패턴(Strategy Pattern)이란?

객체가 수행하는 여러가지 행동(행위) 중에서 상황에 맞는 적절한 전략을 선택해서 실행하는 패턴을 말한다.

쉽게 말해 "알고리즘을(행위를) 통째로 바꿔서 적용할 수 있는 패턴" 이라고 생각하면 된다.

 

좀 더 쉽게 이해하기 위해서 게임으로 예시를 들어보자!

 

전략 패턴의 게임 예시

 

RPG 게임에서 적 캐릭터(몬스터)가 있다고 가정해보자.

몬스터는 플레이어와의 거리가 가까우면 근접으로 공격하고 멀다면 원거리에서 공격한다.

이 몬스터만이 가지고 있는 고유의 패턴을 만들때 전략 패턴을 사용하는 것!

 

또는 보스 몬스터만이 가지고 있는 패턴이 존재할 수 있는데 이 때에도 전략 패턴을 사용할 수 있다.

 

  • HP 100%~50% → 원거리 공격 전략
  • HP 50%~20% → 돌진 공격 전략
  • HP 20% 이하 → 발악 기술 전략

이런 식으로 패턴을 설계해서 구현할 수 있는 것!


 

- 그렇다면 전략 패턴을 어떻게 사용하나요?

이번에도 간단한 c# 게임 코드를 통해서 예를 들어보자!

1. 우선 기술 전략 인터페이스를 먼저 정의한다!

// 스킬 전략
public interface ISkillStrategy
{
    string SkillName { get; }
    void Skill();
}

2. 전략 인터페이스상속받아 다양한 스킬 전략을 만든다!

// 근접 기술 전략
public class Skill_Melee : ISkillStrategy
{
    public string SkillName => "근접 기술 A";

    public void Skill()
    {
        Console.WriteLine($"{SkillName}로 공격!");
    }
}

// 원거리 기술 전략
public class Skill_Range : ISkillStrategy
{
    public string SkillName => "원거리 기술 B";

    public void Skill()
    {
        Console.WriteLine($"멀리서 {SkillName}로 공격!");
    }
}

// 치유 기술 전략
public class Skill_Heal : ISkillStrategy
{
    public string SkillName => "치유 기술 C";

    public void Skill()
    {
        Console.WriteLine($"{SkillName}로 상처를 치료!");
    }
}

 


3. 적용할 대상에게(클래스한테) 전략을 적용시킨다.

    // 몬스터에게 전략 적용
    public class Enemy1 { 
        private string enemyName = "고블린";
        private ISkillStrategy skillStrategy;

        // 전략 변경
        public void SetSkillStrategy(ISkillStrategy skillStrategy)
        {
            this.skillStrategy = skillStrategy;
        }

        // 스킬 사용
        public void takeSkill()
        {
            Console.WriteLine($"\n{enemyName}이 {skillStrategy.SkillName} 기술을 사용했다!");
            skillStrategy.Skill();
        }
    }

3-1. 사용 테스트 1

    internal class Program
    {
        static void Main(string[] args)
        {
            Enemy1 enemy = new Enemy1();

            // 근접 기술 사용
            enemy.SetSkillStrategy(new Skill_Melee());
            enemy.takeSkill();

            // 전략 수정 후 원거리 기술 사용
            enemy.SetSkillStrategy(new Skill_Range());
            enemy.takeSkill();

            // 전략 수정 후 아군 치유 기술 사용
            enemy.SetSkillStrategy(new Skill_Heal());
            enemy.takeSkill();
        }
    }

 

테스트 결과

테스트 결과

 

이런 식으로 행동을 상황에 맞게 교체가능한 전략으로 분리해주는 패턴이다!

이제 마지막으로 상황에 맞게끔 사용한다고 예시를 들어보자면

3-2. 사용 테스트 2

    internal class Program
    {
        static void Main(string[] args)
        {
            Enemy1 enemy = new Enemy1();

            int enemyMaxHp = 30;        // 최대 체력
            int enemyCurHp = 14;        // 현재 체력
            int playerDistance = 5;     // 플레이어과의 거리

            // 상황에 따른 전략 결정
            if (enemyCurHp <= enemyMaxHp * 0.5)
            {
                enemy.SetSkillStrategy(new Skill_Heal());
            }
            else if (playerDistance <= 5)
            {
                enemy.SetSkillStrategy(new Skill_Melee());
            }
            else
            {
                enemy.SetSkillStrategy(new Skill_Range());
            }

            // 전략에 맞는 기술 사용
            enemy.takeSkill();
        }
    }

테스트 결과 2

 

이렇게 현재 체력이 최대 체력의 절반 이하라서 전략을 치유 스킬 전략으로 바꿔서 사용한 것이다!

 

그 외에도 스킬에 재사용 대기시간을 부여하거나,

랜덤값을 줘서 무작위 기술을 사용하도록 설계하거나

전략을 원하는데로 교체하도록 구현할 수 있다!

+ Recent posts