use bevy::log::LogPlugin;
use bevy::prelude::*;
use bevy::utils::tracing::debug;
use big_brain::prelude::*;
use rand::rngs::SmallRng;
use rand::{Rng, SeedableRng};
#[derive(Clone, Component, Debug, ActionBuilder)]
pub struct GuessNumber {
to_guess: u8,
rng: SmallRng,
}
fn guess_number_action(
mut action_query: Query<(&Actor, &mut ActionState, &mut GuessNumber, &ActionSpan)>,
) {
for (_actor, mut action_state, mut guess_number, span) in &mut action_query {
let _guard = span.span().enter();
match *action_state {
ActionState::Requested => {
debug!(
"Let's try to guess the secret number: {:?}",
guess_number.to_guess
);
*action_state = ActionState::Executing;
}
ActionState::Executing => {
let guess: u8 = guess_number.rng.gen_range(0..=10);
debug!("Guessed: {:?}", guess);
if guess == guess_number.to_guess {
debug!(
"Guessed the secret number: {:?}! Action succeeded.",
guess_number.to_guess
);
*action_state = ActionState::Success;
}
}
ActionState::Cancelled => {
*action_state = ActionState::Failure;
}
_ => {}
}
}
}
#[derive(Clone, Component, Debug, ScorerBuilder)]
pub struct DummyScorer;
pub fn dummy_scorer_system(mut query: Query<(&Actor, &mut Score), With<DummyScorer>>) {
for (Actor(_actor), mut score) in &mut query {
score.set(1.0);
}
}
pub fn init_entities(mut cmd: Commands) {
let number_to_guess: u8 = 5;
let race_guess_numbers = Concurrently::build()
.mode(ConcurrentMode::Race)
.label("RaceToGuessNumbers")
.push(GuessNumber {
to_guess: number_to_guess,
rng: SmallRng::from_entropy(),
})
.push(GuessNumber {
to_guess: number_to_guess,
rng: SmallRng::from_entropy(),
});
let join_guess_numbers = Concurrently::build()
.mode(ConcurrentMode::Join) .label("JoinToGuessNumbers")
.push(GuessNumber {
to_guess: number_to_guess,
rng: SmallRng::from_entropy(),
})
.push(GuessNumber {
to_guess: number_to_guess,
rng: SmallRng::from_entropy(),
});
let guess_numbers = Steps::build()
.label("RaceAndThenJoin")
.step(race_guess_numbers)
.step(join_guess_numbers);
let thinker = Thinker::build()
.label("GuesserThinker")
.picker(Highest)
.when(DummyScorer, guess_numbers);
cmd.spawn(thinker);
}
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_plugins(LogPlugin {
filter: "big_brain=warn,concurrent=debug".to_string(),
..default()
})
.add_plugins(BigBrainPlugin::new(PreUpdate))
.add_systems(Startup, init_entities)
.add_systems(
PreUpdate,
(
guess_number_action.in_set(BigBrainSet::Actions),
dummy_scorer_system.in_set(BigBrainSet::Scorers),
),
)
.run();
}