Expand description
bhv
Bhv is a library for working with behavior trees.
Installation
Simple as running
cargo add bhv
on the directory of the project where you want to use the library.
Showcase
// Guess the number game implemented using behavior trees.
use std::{
io::{self, Write},
time::{SystemTime, UNIX_EPOCH},
};
use bhv::*;
fn main() {
game()
}
// The data that will be used by the nodes
#[derive(Default)]
struct Context {
guess: u32,
answer: u32,
}
// the nodes
struct RandomizeAnswer(u32, u32);
struct ReadInput;
macro_rules! print_msg {
($($arg:tt)*) => {
action(|_ctx| print!($($arg)*))
};
}
fn game() {
let tree = seq! {
RandomizeAnswer(0, 101),
seq! {
print_msg!("Enter a number from 0 to 100\n"),
ReadInput,
sel! {
seq! {
cond(|ctx: &Context| ctx.guess < ctx.answer),
print_msg!("Your guess is smaller than the actual number\n").fail(), // The game is not over yet
},
seq! {
cond(|ctx: &Context| ctx.guess == ctx.answer),
print_msg!("Your guess is correct!\n"),
},
seq! {
cond(|ctx: &Context| ctx.guess > ctx.answer),
print_msg!("Your guess is greater than the actual number\n").fail(), // The game is not over yet
}
},
}.repeat_until_pass(),
};
tree.execute(Context::default());
}
impl Bhv for RandomizeAnswer {
type Context = Context;
fn update(&mut self, ctx: &mut Self::Context) -> Status {
let time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
ctx.answer = (time % ((self.1 - self.0) as u64)) as u32 + self.0;
Status::Success
}
}
impl Bhv for ReadInput {
type Context = Context;
fn update(&mut self, ctx: &mut Self::Context) -> Status {
io::stdout().flush().unwrap_or_default();
let mut buff = String::new();
io::stdin()
.read_line(&mut buff)
.map(|_| match buff.trim().parse() {
Ok(v) => {
ctx.guess = v;
Status::Success
}
Err(e) => {
println!("Error reading from stdin :{}\t buffer: '{}'", e, buff);
Status::Failure
}
})
.unwrap_or_else(|_| Status::Running)
}
}Features
The library provides several nodes that are commonly present in behavior trees. Specifically, the nodes provided are split into categories as following:
- adaptor nodes, that adapt a function into a behavior tree node.
- decorator nodes, that alter the behavior and result of a node.
- composite nodes, that several nodes at the same time.
For help with specific nodes, refer to the documentation of the crate.
License
Crate licensed under the MIT license.
Macros
- A macro used to create a selector from a list of behaviors. Selectors run every behavior until one of them succeeds.
- A macro used to create a sequence from a list of behaviors. Sequences run every behavior until one of them fails.
Structs
- The type of the result of
action. - The type of the result of
cond. - A decorator that runs the given node until it’s done and then returns
Status::Failure. - A decorator that runs the given node until it’s done and inverts the result.
- A decorator that runs the given node until it’s done and then returns
Status::Success. - A decorator that runs the given node a certain number of times and returns its status.
- A decorator that runs the given node as long as it’s predicate returns
trueand returns the status of the node. - A decorator that runs the given node until it returns
Status::Failure. - A decorator that runs the given node until it returns
Status::Success. - A selector is a behavior node composed of a list of nodes that are run until one of them succeeds, in which case the node also succeeds. If none of the nodes succeeds, this node fails.
- A sequence is a behavior node composed of a list of nodes that are run until one of them fails, in which case the node also fails. If none of the nodes fails, this node succeeds.
Enums
- An enum type representing the outcome of calling
Bhv::update.
Traits
- A trait used to denote that the implementing type can be used as a behavior tree node.
- Helper methods to build a tree from given nodes. See nodes returned by the functions for specific examples and usage.
Functions
- Adapt a function that returns nothing into a behavior, returning
Status::Successon every call toBhv::update. - Adapt a predicate into a behavior, returning
Status::Successif the predicate returnstrueandStatus::Failureotherwise.