[Design Pattern] 유한 상태 머신(FSM, Finite State Machine)
1. 유한 상태 머신(FSM)
유한 상태 머신은 유한개의 상태를 정의하고, 조건에 따라 각 상태로 전이하며 객체의 상태 및 행동을 정의하는 프로그래밍 패턴이다.
2. 예시
대표적인 예시로 게임에서의 몬스터가 있다.
2-1. 상태(State) 정의
몬스터가 가질 수 있는 상태를 정의하면 다음과 같다:
- Idle (대기): 플레이어를 찾지 못한 상태
- Patrol (순찰): 일정 경로를 따라 이동
- Chase (추격): 플레이어를 발견하고 쫓아감
- Attack (공격): 플레이어가 공격 범위 안에 있음
- Flee (도망): 체력이 낮아서 도망감
- Dead (죽음): 체력이 0이 되어 사망
2-2. 상태 전이(Transition) 조건
몬스터는 특정 조건에 따라 상태를 변경한다:
- Idle → Patrol: 일정 시간이 지나면 순찰을 시작
- Patrol → Chase: 플레이어가 감지 범위 내로 들어오면
- Chase → Attack: 플레이어가 공격 범위 안에 들어오면
- Attack → Chase: 플레이어가 공격 범위를 벗어나면
- Chase → Flee: 체력이 일정 이하로 떨어지면
- Flee → Idle: 플레이어가 멀어지면 도망을 멈춤
- 어느 상태든 → Dead: 체력이 0이 되면
2-3. 예시 코드
enum class MonsterState { IDLE, PATROL, CHASE, ATTACK, FLEE, DEAD };
class Monster {
private:
MonsterState state = MonsterState::IDLE;
int health = 100;
bool playerInSight = false;
bool playerInAttackRange = false;
public:
void update() {
switch (state) {
case MonsterState::IDLE:
if (playerInSight) state = MonsterState::CHASE;
else state = MonsterState::PATROL;
break;
case MonsterState::PATROL:
if (playerInSight) state = MonsterState::CHASE;
break;
case MonsterState::CHASE:
if (playerInAttackRange) state = MonsterState::ATTACK;
if (health < 20) state = MonsterState::FLEE;
break;
case MonsterState::ATTACK:
if (!playerInAttackRange) state = MonsterState::CHASE;
break;
case MonsterState::FLEE:
if (health == 0) state = MonsterState::DEAD;
break;
case MonsterState::DEAD:
// 몬스터 사망 처리
break;
}
}
};
3. 장단점
3-1. 장점
- 코드 구조화 : 상태 기반으로 분리하면 AI 코드가 깔끔해진다.
- 확장 용이 : 새로운 상태를 쉽게 추가 가능하다.
- 디버깅 편리 : 상태가 명확히 정의되어 문제 발생 시 원인 파악이 쉽다.
3-2. 단점
- 상태가 많아지면 분기가 많아지면서 코드가 복잡해질 수 있다.
Leave a comment