《游戏人工智能编程》学习笔记二——简单的有限状态机

本文介绍了有限状态机的基本概念,以灯的开关为例解释了其工作原理。文章探讨了三种不同的实现方式:使用switch/if语句,状态转换表,以及状态设计模式。对于复杂的系统,状态设计模式提供了更清晰的结构和易于扩展的状态管理。通过状态类和状态对象,这种模式允许优雅地实现状态驱动的行为,并支持状态的进入和退出操作。
摘要由CSDN通过智能技术生成

1、有限状态机的定义

定义:一个有限状态机是一个设备,或是一个设备模型,具有有限数量的状态,它可以在任何给定的时间根据输入进行操作,使得从一个状态变换到另一个状态,或者是促使一个输出或者一种行为的发生。一个有限状态机在任何瞬间只能处在一种状态。

举个例子:

灯的开关是一个非常简单的有限状态机。他有两种状态:开或关。状态之间的变换是通过你手指的输入产生的。向上按开关,产生从关到开的状态变换,向下按开关,产生从开到关的状态变换。
在这里插入图片描述

2、有限状态机的实现

方法1、switch/if

以灯的开关为例

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum StateType
{
    LightOn,
    LightOff
}
public class FSMTest : MonoBehaviour
{
    private StateType _state;

    private bool switchDir;//开关方向 false为向下,true为向上,通过你的输入可以改变这个值
    // Start is called before the first frame update
    void Start()
    {
        _state = StateType.LightOff;
        switchDir = false;
    }

    // Update is called once per frame
    void Update()
    {
        UpdateState(_state);
    }

    void UpdateState(StateType state)
    {
        switch (state)
        {
            //关灯状态
            case StateType.LightOff:
                if (switchDir)
                {                    
                    state = StateType.LightOn;
                    //...一些别的操作
                }
                break;
            //开灯状态
            case StateType.LightOn:
                if (!switchDir)
                {
                    state = StateType.LightOff;
                    //...一些别的操作
                }
                break;
        }
    }
}

上述方法在遇到状态较复杂,或者状态的拓展较频繁时,代码会变得非常难懂,拓展状态也并不灵活

方法2、状态变换表

一个例子:

当前状态条件状态转换
逃跑安全巡逻
攻击比敌人弱逃跑
巡逻受到威胁并比敌人强攻击
巡逻受到威胁并比敌人弱逃跑

表中的每个状态可以抽象为一个对象或者是一个函数,这个表会被智能体在规则的时间间隔内询问,这样做的话,状态的结构会更加的条理清晰,增加新的状态模块也会更加方便一些

方法3、内置的规则

例子:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class State  
{
    public virtual void Execute(Player player)
    {

    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Runaway : State
{
    public override void Execute(Player player)
    {
        if (player.isSafe)
        {
            player.ChangeState(new Sleep());
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sleep : State
{
    public override void Execute(Player player)
    {
        if (player.isThreatened)
        {
            player.ChangeState(new Runaway());
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    private State curState;

    public bool isSafe;//判断是否处于安全状态
    public bool isThreatened;//判断是否处于受威胁状态

    // Update is called once per frame
    void Update()
    {
        if(curState != null)
        {
            curState.Execute(this);
        }
    }
    
    public void ChangeState(State newState)
    {
        curState = newState;
    }
}

state作为状态类的一个基类,拥有一个虚函数供子类重写,每当有一个新的状态,就继承state类,并重写Execute方法。player类里面执行的状态完全由curState的值来决定,这样的话,状态本身进行了封装并且在内部给出了影响状态变换的规则。

这个结构被称为状态设计模式,它提供了一种优雅的方式来实现状态驱动行为。它非常容易为每种状态增加进入状态和退出状态的动作,你只需要为每个状态创建Enter和Exit方法并相应的调整智能体的ChangeState方法即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值