#game-ai #ai #goap #action-planning

planning

一个允许规划最小行动序列以实现目标状态的库

3个版本 (稳定)

1.0.1 2024年8月10日
0.1.0 2024年8月5日

#430游戏开发

Download history 268/week @ 2024-08-05 44/week @ 2024-08-12

每月 312 次下载

MIT 协议

29KB
259

计划

crates.io GitHub Actions Workflow Status

一个允许规划最小行动序列以实现给定目标状态的库。

这个crate基于Jeff Orkin关于目标导向行为规划(GOAP)的工作。它从tynril的rgoap库中汲取灵感,但提供了动态目标优先级和行动成本以及任意状态类型。

主要访问点是Agent类型,它允许使用多个目标和行动进行动态和可扩展的计划,并在这两者之间进行复杂的动态交互。

使用方法

使用cargo add planning将crate作为依赖项添加,或者通过将以下行添加到您的Cargo.toml

[dependencies]
planning = "1.0"

如下使用库

use planning::*;
use std::hash::Hash;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
struct State {
    num_flowers: u16,
    hungry: bool,
    picnic_set: bool,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum MyAction {
    PickFlower,
    SetPicnic,
    Eat,
}

impl Action<State> for MyAction {
    fn is_applicable(&self, state: &State) -> bool {
        match self {
            MyAction::PickFlower => state.num_flowers < 5,
            MyAction::SetPicnic => !state.picnic_set,
            MyAction::Eat => state.hungry && state.picnic_set,
        }
    }

    fn apply_mut(&self, state: &mut State) {
        match self {
            MyAction::PickFlower => state.num_flowers += 1,
            MyAction::SetPicnic => state.picnic_set = true,
            MyAction::Eat => state.hungry = false,
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum MyGoal {
    BouquetMade,
    Eaten,
}

impl Goal<State> for MyGoal {
    fn is_satisfied(&self, state: &State) -> bool {
        match self {
            MyGoal::BouquetMade => state.num_flowers >= 5,
            MyGoal::Eaten => !state.hungry,
        }
    }

    fn priority(&self, state: &State) -> i32 {
        match self {
            MyGoal::BouquetMade => 1,
            MyGoal::Eaten => if state.hungry { 2 } else { 0 },
        }
    }
}

let mut agent = Agent::new(
    State { num_flowers: 0, hungry: true, picnic_set: false },
    vec![MyAction::PickFlower, MyAction::SetPicnic, MyAction::Eat],
    vec![MyGoal::BouquetMade, MyGoal::Eaten],
);

let (goal, plan, _) = agent.plan_dynamic().unwrap();
assert_eq!(goal, &MyGoal::Eaten);
assert_eq!(plan, vec![MyAction::SetPicnic, MyAction::Eat]);

agent.state.hungry = false;
let (goal, plan, _) = agent.plan_dynamic().unwrap();
assert_eq!(goal, &MyGoal::BouquetMade);
assert_eq!(plan, vec![MyAction::PickFlower; 5]);

功能

bevyAgent实现了Bevy的Component类型。这在将其用作游戏AI单元行为的一部分时很有用。

serdeAgent实现了SerializeDeserialize

[dependencies]
planning = { version = "1.0", features = ["bevy", "serde"] }

依赖关系

~1.4–6.5MB
~121K SLoC