Game AI

Rule-Based System (1)

tsyang 2022. 12. 12. 20:20

개요


 

규칙 기반 시스템(Rule-based systems)은 1970~1980년대 AI 연구를 주름잡았었다. 게임에서도 20년가량 쓰였지만 비효율적이고 구현이 힘들다는 평가를 받고 있다. 결정 트리나 상태 머신으로 더 쉽게 대체 가능하다는 점도 이런 평가에 한 몪 했다.

 

그러나 디버깅이 용이하고 컨텐츠 창작이 쉽다는 장점도 있다.

 

아이디어는 간단하다. "IF" 조건이 만족하면 "THEN" 컴포넌트를 수행한다. 그 외에도 어떤 트리거를 선택할지를 정하는 중개자(Arbiter) 컴포넌트도 있다.

 

 

 


 

아이디어


 

 

 

DB매칭

만약 IF 조건이 DB에 부합한다면 트리거가 발동한다. 이런 조건을 패턴이라고 한다.

 

A : HP = 50
B : HP = 30
C : HP = 100
D : HP = 25
D : has-C4

 

만약 D의 체력이 0이 되어서 폭탄을 넘겨받아야 한다면 다음과 같이 패턴을 만들 수 있다.

 

D : HP = 0 AND D : has-C4

 

좀 더 패턴을 유연하게 짜려면 와일드카드 개념을 추가할 수 있다.

 

예를 들어, 체력이 높은 멤버가 낮은 멤버를 치료해야 해준다고 했을 때 패턴은 다음과 같이 짤 수 있다.

 

Anyone-1 : HP < 30 AND Anyone-2 : HP > 50

 

 

 

 

조건-행동 규칙

조건이 만족된다면 행동을 수행한다. 

 

만약 D가 죽어서 C가 폭탄을 회수해야 하는 경우는 다음과 같은 규칙으로 만들 수 있다.

 

IF D : HP = 0 AND D : has-C4
THEN C : pick up the C4

위의 행동은 DB의 정보를 직접 바꾸지 않는다. C가 실제로 C4를 수거할 수 있는지 모르기 때문이다. DB는 게임의 상태만 가지고 있다. (그러나 실패하기 쉬운 행동의 경우 DB가 AI의 의도를 알고 있는 것이 도움이 될 수도 있다.)

 

C4를 수거하는 것이 행동이다. 만약 행동이 성공한다면 그 후에 DB를 업데이트한다.

 

 

 

DB 업데이트 규칙

연료 : 1000kg
시야에 있는 적 : Enemy-A
현재 순찰 중

전투기를 조종하는 파일럿 AI가 있다. 그리고 현재 DB는 위와 같다.

 

만약 적이 시야에 들어온 경우 파일럿 AI의 목표를 순찰에서 적을 공격하는 것으로 바꾸고 싶다고 하자.

 

이런 경우 게임 코드보고 '목표 변경'이라는 행동을 스케쥴하도록 할 필요가 없다. 다음과 같이 하면 된다.

 

IF 시야에 적이 있음 AND 현재 순찰중 
THEN 
remove(현재 순찰중)
add(적을 공격)

remove 함수는 DB에서 데이터를 제거하고, add함수는 새로 추가한다. 만약 remove(현재 순찰중)을 규칙에서 제거하면 DB에는 "현재 순찰중"과 "현재 공격중"상태 둘 다 존재하게 된다. 만약 적을 제거한 후 다시 순찰을 해야하는 상황이라면 두 상태가 있는 것이 맞을 수도 있다.

 

 

 

Forward & Backward Chaining

Forward Chaining은 DB를 가지고 먼저 조건을 본 다음 행동을 수행하는 방식이다. (위에서 설명한 방식)

 

Backward Chaining은 THEN을 먼저 본다. 그 행동을 수행했을 때 내가 의도하는 Game State가 된다면 IF를 봐서 수행할 수 있는지 체크한 뒤에 수행하는 방식이다. 

 

비 게임분야에서는 Backward Chaining이 매우 중요한 테크닉이지만 게임분야에서는 잘 쓰이지 않는다.

 

 

 

 

 

DB내의 데이터 포맷

데이터는 식별자(id)와 값으로 저장할 수 있다. 데이터가 boolean이라면 그냥 데이터가 있으면 true 없으면 false로 해석한다.

 

예를 들어, 연료가 1500kg가 있고, 현재 순찰 중이며 전투 중은 아닌 전투기의 DB는 다음과 같이 표현할 수 있다.

 

연료 = 1500
현재 순찰 중

 

이런 데이터 표현에는 nesting에 관한 문제가 있다.

 

예를 들어, AI 캐릭터와 각 캐릭터가 들고 있는 무기, 탄창 수를 표현한다고 해보자. 다음과 같을 것이다.

 

데이비드 : 무기 = 소총
레베카 : 무기 = 산탄총
레베카 : 무기 = 권총
데이비드 : 소총 탄환 = 150
레베카 : 산탄총 탄환 = 30
레베카 : 권총 탄환 = 45
데이비드 : 소총 탄창 수 = 5
레베카 : 권총 탄창 수 = 3

이러한 표현 방식은 매우 비효율적이다.

 

대신에 데이터를 계층적으로 표현할 수 있다.

데이비드의 무기 (소총 (탄환 150) (탄창 5))
레베카의 무기 (산탄총(탄환 30) , 권총 (탄환 45) (탄창3))

 

이런 식으로 캐릭터의 상태도 표현할 수 있다.

 

데이비드 (무기 (소총 (탄환150)(탄창 5)))
(체력 150)
(위치 [10, 20, 30])

 

이런 계층 방식으로 와일드카드는 다음과 같이 표현할 수 있다.

(?anyone(HP [0-15]))

 

 


참고 : Ian Millington, AI for GAMES 3rd edition, CRC press, [Chapter 5.8]

'Game AI' 카테고리의 다른 글

Rule-Based System (3) - Rete  (0) 2023.01.22
Rule-Based System (2)  (0) 2023.01.07
목표지향 행동 - 3  (0) 2022.12.04
목표 지향 행동 - 2  (0) 2022.11.24
목표 지향 행동 (Goal-Oriented Behavior) - 1  (0) 2022.11.20