游戏人工智能之有限状态机初探(一)
原创文章,转载请注明原文地址。
一、什么是有限状态机
有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
一个有限状态机是一个设备,或是一个设备模型,具有有限数量的状态,它可以在任何给定的时间根据输入进行操作,使得从一个状态变换到另一个状态,或者促使一个输出或者一种行为的发生。一个有限状态机在任何瞬间只能处在一种状态。
二、有限状态机初探
先模拟编译器中一个简单的词法分析状态机:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define BSIZE 1024
enum StateType{ Alpha, Digit, Symbol };
char *key_list[] = { "int", "main", "if", "return", "while", "do", "then" };
char *border_list[] = { ";", ",", "{", "}", ")", "(" };
char *operator_list[] = { "=", "+", "-", "*", "/", ">", "<" };
char buffer[1024];
int start;
char headch;
FILE *fp;
void deal_alpha(){
int flag, i;
char word[100];
word[0] = headch;
for (i = start; isdigit(buffer[i]) || isalpha(buffer[i]); i++){
word[i - start] = buffer[i];
}
word[i - start] = '\0';
start = i;
headch = buffer[start];
flag = is_key_word(word);
if (flag == -1){
printf("( 2: “%s”)\n", word);
}
else{
printf("( 1: “%s”)\n", word);
}
}
void deal_dight(){
char word[100];
int i;
word[0] = headch;
for (i = start; isdigit(buffer[i]) || buffer[i] == '.'; i++){
word[i - start] = buffer[i];
}
word[i - start] = '\0';
start = i;
headch = buffer[start];
printf("( 3:“%s”)\n", word);
}
void deal_symbol(){
char s[3];
int i;
s[0] = buffer[start];
s[1] = '\0';
for (i = 0; operator_list[i][0]; i++)
{
if (strcmp(s, operator_list[i]) == 0)
{
start++;
headch = buffer[start];
printf("( 4: “%s”)\n", s);
return;
}
}
printf("( 5: “%c”)\n", headch);
start++;
headch = buffer[start];
}
void updateState(StateType state)
{
switch (state)
{
case Alpha:
Deal_alpha();
break;
case Digit:
Deal_dight();
break;
case Symbol:
Deal_symbol();
break;
}
}
int main(){
fp = fopen("test.txt", "r");
if (fp == NULL){
printf("无法打开文件!");
return -1;
}
while (fgets(buffer, BSIZE, fp) != NULL)
{
int len = strlen(buffer);
buffer[len - 1] = '\0';
start = 0;
headch = buffer[start];
while (headch != '\0')
{
while (buffer[start] == ' '){
start++;
}
headch = buffer[start];
if (headch == '\0'){
break;
}
else if (isalpha(headch)){
updateState(Alpha);
}
else if (isdigit(headch)){
updateState(Digit);
}
else{
updateState(Symbol);
}
}
}
return 0;
}
分析的程序:
int main()
{
int a,b;
a = 10;
b = a + 20;
return 0;
}
输出结果:
这种方法使用了一系列的if-else语句和一个具有枚举类型的switch语句来表达状态。虽然初看之下这种方法是合理的,但当实际应用到任何一个复杂情况时,随着更多的状态和条件被加入,程序变得越来越庞大,几乎难以扩展。
三、使用面向对象的思想和设计模式
Singleton设计模式:确保一个对象只能实例化一次
FSM中的每一个状态都是singleton的。
直接上代码:
class Myclass{
private:
int num;//成员属性
MyClass(){};//构造器是私有的
public:
~MyClass(){};
int GetNum() const {return num;}
static Myclass* Instance();
};
Myclass* Myclass::Instance()
{
static Myclass instance;
return &instance;
}
访问成员属性时:
int num = Myclass::Instance()->GetNum();
Singleton模式的实现方式多种多样,具体大家可以参考《设计模式》一书。
使用OOAP设计FSM我准备放到状态驱动智能体设计中去,如果大家感兴趣可以在www.jblearning.com/catalog/9781556220784下载相关源代码进行学习。
参考文献:
1.游戏人工智能编程案例精粹 【美】Mat Buckland 著
如果大家看完觉得有帮助,请给我点个赞,我希望能和大家一起学习一起进步。>_<