Skip to content
Snippets Groups Projects
Unverified Commit bdb9e462 authored by Kat Marchán's avatar Kat Marchán
Browse files

Consideration->Scorer, Utility->Score

Fixes: https://github.com/zkat/big-brain/issues/3
parent ae4ebb7e
No related branches found
No related tags found
No related merge requests found
...@@ -3,10 +3,10 @@ use quote::quote; ...@@ -3,10 +3,10 @@ use quote::quote;
use syn::{parse_macro_input, DeriveInput}; use syn::{parse_macro_input, DeriveInput};
use action::Action; use action::Action;
use consideration::Consideration; use scorer::Scorer;
mod action; mod action;
mod consideration; mod scorer;
/** /**
`Action`s in `big-brain` are defined through this derive macro. Once defined, `Action`s in `big-brain` are defined through this derive macro. Once defined,
...@@ -198,9 +198,9 @@ impl<'a> System<'a> for ConsiderHunger { ...@@ -198,9 +198,9 @@ impl<'a> System<'a> for ConsiderHunger {
) )
``` ```
*/ */
#[proc_macro_derive(Consideration, attributes(consideration))] #[proc_macro_derive(Scorer, attributes(scorer))]
pub fn derive_consideration_builder(input: proc_macro::TokenStream) -> proc_macro::TokenStream { pub fn derive_scorer_builder(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
let consideration = Consideration::from_derive_input(&input).unwrap(); let scorer = Scorer::from_derive_input(&input).unwrap();
(quote!(#consideration)).into() (quote!(#scorer)).into()
} }
...@@ -3,16 +3,16 @@ use proc_macro2::TokenStream; ...@@ -3,16 +3,16 @@ use proc_macro2::TokenStream;
use quote::quote; use quote::quote;
#[derive(Debug, FromDeriveInput)] #[derive(Debug, FromDeriveInput)]
#[darling(attributes(consideration), supports(struct_named))] #[darling(attributes(scorer))]
pub struct Consideration { pub struct Scorer {
ident: syn::Ident, ident: syn::Ident,
generics: syn::Generics, generics: syn::Generics,
data: ast::Data<(), ConsiderationField>, data: ast::Data<(), ScorerField>,
} }
#[derive(Debug, FromField)] #[derive(Debug, FromField)]
#[darling(attributes(consideration))] #[darling(attributes(scorer))]
struct ConsiderationField { struct ScorerField {
ident: Option<syn::Ident>, ident: Option<syn::Ident>,
ty: syn::Type, ty: syn::Type,
#[darling(default)] #[darling(default)]
...@@ -21,9 +21,9 @@ struct ConsiderationField { ...@@ -21,9 +21,9 @@ struct ConsiderationField {
default: bool, default: bool,
} }
impl ToTokens for Consideration { impl ToTokens for Scorer {
fn to_tokens(&self, tokens: &mut TokenStream) { fn to_tokens(&self, tokens: &mut TokenStream) {
let Consideration { let Scorer {
ref ident, ref ident,
ref data, ref data,
.. ..
...@@ -34,7 +34,7 @@ impl ToTokens for Consideration { ...@@ -34,7 +34,7 @@ impl ToTokens for Consideration {
.expect("Enums not supported") .expect("Enums not supported")
.fields; .fields;
let field_defs = fields.clone().into_iter().filter_map(|field| { let field_defs = fields.clone().into_iter().filter_map(|field| {
let ConsiderationField { let ScorerField {
ident, ty, param, .. ident, ty, param, ..
} = field; } = field;
let ident = ident.clone().unwrap(); let ident = ident.clone().unwrap();
...@@ -45,7 +45,7 @@ impl ToTokens for Consideration { ...@@ -45,7 +45,7 @@ impl ToTokens for Consideration {
} }
}); });
let field_assignments = fields.into_iter().map(|field| { let field_assignments = fields.into_iter().map(|field| {
let ConsiderationField { let ScorerField {
ident, ident,
param, param,
default, default,
...@@ -69,10 +69,10 @@ impl ToTokens for Consideration { ...@@ -69,10 +69,10 @@ impl ToTokens for Consideration {
} }
}); });
let ts = quote! { let ts = quote! {
mod big_brain_cons_builder { mod big_brain_scorer_builder {
use super::#ident as Comp; use super::#ident as Comp;
use big_brain::{typetag, serde::Deserialize, Consideration, bevy::prelude::*, ConsiderationEnt}; use big_brain::{typetag, serde::Deserialize, Scorer, bevy::prelude::*, ScorerEnt};
// use typetag; // use typetag;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
...@@ -80,11 +80,11 @@ impl ToTokens for Consideration { ...@@ -80,11 +80,11 @@ impl ToTokens for Consideration {
#(#field_defs),* #(#field_defs),*
} }
#[typetag::deserialize] #[typetag::deserialize]
impl Consideration for #ident { impl Scorer for #ident {
fn build(&self, actor: Entity, cmd: &mut Commands) -> ConsiderationEnt { fn build(&self, actor: Entity, cmd: &mut Commands) -> ScorerEnt {
let ent = ConsiderationEnt(cmd.spawn().id()); let ent = ScorerEnt(cmd.spawn().id());
cmd.entity(ent.0) cmd.entity(ent.0)
.insert(big_brain::Utility::default()) .insert(big_brain::Score::default())
.insert(Comp { .insert(Comp {
#(#field_assignments),* #(#field_assignments),*
}); });
......
...@@ -20,9 +20,7 @@ impl Thirst { ...@@ -20,9 +20,7 @@ impl Thirst {
pub fn thirst_system(time: Res<Time>, mut thirsts: Query<&mut Thirst>) { pub fn thirst_system(time: Res<Time>, mut thirsts: Query<&mut Thirst>) {
for mut thirst in thirsts.iter_mut() { for mut thirst in thirsts.iter_mut() {
thirst.thirst += thirst.thirst += thirst.per_second * (time.delta().as_micros() as f32 / 1000000.0);
thirst.per_second * (time.delta().as_micros() as f32 / 1000000.0);
println!("Getting thirstier...{}%", thirst.thirst);
} }
} }
...@@ -76,29 +74,29 @@ fn drink_action_system( ...@@ -76,29 +74,29 @@ fn drink_action_system(
} }
} }
// Then, we have something called "Considerations". These are special // Then, we have something called "Scorers". These are special components that
// components that run in the background, calculating a "Utility" value, which // run in the background, calculating a "Score" value, which is what Big Brain
// is what Big Brain will use to pick which actions to execute. // will use to pick which actions to execute.
// //
// Additionally, though, we pull in an evaluator and define a weight. Which is // Additionally, though, we pull in an evaluator and define a weight. Which is
// just mathy stuff you can tweak to get the behavior you want. More on this // just mathy stuff you can tweak to get the behavior you want. More on this
// in the docs (later), but for now, just put them in there and trust the // in the docs (later), but for now, just put them in there and trust the
// system. :) // system. :)
#[derive(Debug, Consideration)] #[derive(Debug, Scorer)]
pub struct ThirstConsideration { pub struct ScoreThirst {
#[consideration(default)] #[scorer(default)]
pub evaluator: PowerEvaluator, pub evaluator: PowerEvaluator,
#[consideration(param)] #[scorer(param)]
pub weight: f32, pub weight: f32,
} }
// Look familiar? Similar dance to Actions here. // Look familiar? Similar dance to Actions here.
pub fn thirst_consideration_system( pub fn score_thirst_system(
thirsts: Query<&Thirst>, thirsts: Query<&Thirst>,
// Same dance with the Parent here, but now we've added a Utility! // Same dance with the Parent here, but now we've added a Utility!
mut query: Query<(&Parent, &ThirstConsideration, &mut Utility)>, mut query: Query<(&Parent, &ScoreThirst, &mut Score)>,
) { ) {
for (Parent(actor), conser, mut util) in query.iter_mut() { for (Parent(actor), scorer, mut score) in query.iter_mut() {
if let Ok(thirst) = thirsts.get(*actor) { if let Ok(thirst) = thirsts.get(*actor) {
// This is really what the job of a Consideration is. To calculate // This is really what the job of a Consideration is. To calculate
// a generic Utility value that the Big Brain engine will compare // a generic Utility value that the Big Brain engine will compare
...@@ -111,9 +109,9 @@ pub fn thirst_consideration_system( ...@@ -111,9 +109,9 @@ pub fn thirst_consideration_system(
// literally just use linear values here and set thresholds // literally just use linear values here and set thresholds
// accordingly. The evaluator is just there to give the value a // accordingly. The evaluator is just there to give the value a
// bit of a curve. // bit of a curve.
*util = Utility { *score = Score {
value: conser.evaluator.evaluate(thirst.thirst), value: scorer.evaluator.evaluate(thirst.thirst),
weight: conser.weight, weight: scorer.weight,
}; };
} }
} }
...@@ -157,7 +155,7 @@ fn main() { ...@@ -157,7 +155,7 @@ fn main() {
.add_plugin(BigBrainPlugin) .add_plugin(BigBrainPlugin)
.add_startup_system(init_entities.system()) .add_startup_system(init_entities.system())
.add_system(thirst_system.system()) .add_system(thirst_system.system())
.add_system(thirst_consideration_system.system()) .add_system(score_thirst_system.system())
.add_system(drink_action_system.system()) .add_system(drink_action_system.system())
.run(); .run();
} }
...@@ -3,20 +3,20 @@ use serde::Deserialize; ...@@ -3,20 +3,20 @@ use serde::Deserialize;
use crate::{ use crate::{
actions::{Action, ActionState}, actions::{Action, ActionState},
considerations::{Consideration, Utility}, scorers::{Scorer, Score},
measures::{Measure, WeightedMeasure}, measures::{Measure, WeightedMeasure},
thinker::{ActionEnt, ConsiderationEnt}, thinker::{ActionEnt, ScorerEnt},
}; };
// Contains different types of Considerations and Actions // Contains different types of Considerations and Actions
#[derive(Debug)] #[derive(Debug)]
pub struct Choice { pub struct Choice {
pub measure: Box<dyn Measure>, pub measure: Box<dyn Measure>,
pub utilities: Vec<ConsiderationEnt>, pub utilities: Vec<ScorerEnt>,
pub action_state: ActionEnt, pub action_state: ActionEnt,
} }
impl Choice { impl Choice {
pub fn calculate(&self, utilities: &Query<&Utility>) -> f32 { pub fn calculate(&self, utilities: &Query<&Score>) -> f32 {
self.measure.calculate( self.measure.calculate(
self.utilities self.utilities
.iter() .iter()
...@@ -32,7 +32,7 @@ impl Choice { ...@@ -32,7 +32,7 @@ impl Choice {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct ChoiceBuilder { pub struct ChoiceBuilder {
pub consider: Vec<Box<dyn Consideration>>, pub consider: Vec<Box<dyn Scorer>>,
pub then: Box<dyn Action>, pub then: Box<dyn Action>,
} }
impl ChoiceBuilder { impl ChoiceBuilder {
......
...@@ -5,7 +5,7 @@ pub use typetag; ...@@ -5,7 +5,7 @@ pub use typetag;
pub use actions::*; pub use actions::*;
pub use choices::*; pub use choices::*;
pub use considerations::*; pub use scorers::*;
pub use thinker::*; pub use thinker::*;
pub mod evaluators; pub mod evaluators;
...@@ -14,7 +14,7 @@ pub mod pickers; ...@@ -14,7 +14,7 @@ pub mod pickers;
mod actions; mod actions;
mod choices; mod choices;
mod considerations; mod scorers;
mod thinker; mod thinker;
use bevy::prelude::*; use bevy::prelude::*;
......
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::Utility; use crate::Score;
#[typetag::serde] #[typetag::serde]
pub trait Measure: std::fmt::Debug + Sync + Send { pub trait Measure: std::fmt::Debug + Sync + Send {
fn calculate(&self, utilities: Vec<&Utility>) -> f32; fn calculate(&self, utilities: Vec<&Score>) -> f32;
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[derive(Debug, Clone, Default, Serialize, Deserialize)]
...@@ -12,7 +12,7 @@ pub struct WeightedMeasure; ...@@ -12,7 +12,7 @@ pub struct WeightedMeasure;
#[typetag::serde] #[typetag::serde]
impl Measure for WeightedMeasure { impl Measure for WeightedMeasure {
fn calculate(&self, utilities: Vec<&Utility>) -> f32 { fn calculate(&self, utilities: Vec<&Score>) -> f32 {
let wsum: f32 = utilities.iter().map(|el| el.weight).sum(); let wsum: f32 = utilities.iter().map(|el| el.weight).sum();
if wsum == 0.0 { if wsum == 0.0 {
0.0 0.0
......
...@@ -2,11 +2,11 @@ use bevy::prelude::*; ...@@ -2,11 +2,11 @@ use bevy::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{choices::Choice, considerations::Utility, thinker::ActionEnt}; use crate::{choices::Choice, scorers::Score, thinker::ActionEnt};
#[typetag::serde] #[typetag::serde]
pub trait Picker: std::fmt::Debug + Sync + Send { pub trait Picker: std::fmt::Debug + Sync + Send {
fn pick(&self, _choices: &[Choice], _utilities: &Query<&Utility>) -> Option<ActionEnt>; fn pick(&self, _choices: &[Choice], _utilities: &Query<&Score>) -> Option<ActionEnt>;
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[derive(Debug, Clone, Default, Serialize, Deserialize)]
...@@ -16,7 +16,7 @@ pub struct FirstToScore { ...@@ -16,7 +16,7 @@ pub struct FirstToScore {
#[typetag::serde] #[typetag::serde]
impl Picker for FirstToScore { impl Picker for FirstToScore {
fn pick(&self, choices: &[Choice], utilities: &Query<&Utility>) -> Option<ActionEnt> { fn pick(&self, choices: &[Choice], utilities: &Query<&Score>) -> Option<ActionEnt> {
for choice in choices { for choice in choices {
let value = choice.calculate(utilities); let value = choice.calculate(utilities);
if value >= self.threshold { if value >= self.threshold {
......
use bevy::prelude::*; use bevy::prelude::*;
use crate::ConsiderationEnt; use crate::ScorerEnt;
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct Utility { pub struct Score {
pub value: f32, pub value: f32,
pub weight: f32, pub weight: f32,
} }
...@@ -12,6 +12,6 @@ pub struct Utility { ...@@ -12,6 +12,6 @@ pub struct Utility {
This trait defines new considerations. In general, you should use the [derive macro](derive.Consideration.html) instead. This trait defines new considerations. In general, you should use the [derive macro](derive.Consideration.html) instead.
*/ */
#[typetag::deserialize] #[typetag::deserialize]
pub trait Consideration: std::fmt::Debug + Sync + Send { pub trait Scorer: std::fmt::Debug + Sync + Send {
fn build(&self, entity: Entity, cmd: &mut Commands) -> ConsiderationEnt; fn build(&self, entity: Entity, cmd: &mut Commands) -> ScorerEnt;
} }
...@@ -8,7 +8,7 @@ use serde::Deserialize; ...@@ -8,7 +8,7 @@ use serde::Deserialize;
use crate::{ use crate::{
actions::{self, Action, ActionManager, ActionManagerWrapper, ActionState}, actions::{self, Action, ActionManager, ActionManagerWrapper, ActionState},
choices::{Choice, ChoiceBuilder}, choices::{Choice, ChoiceBuilder},
considerations::Utility, scorers::Score,
pickers::Picker, pickers::Picker,
}; };
...@@ -16,7 +16,7 @@ use crate::{ ...@@ -16,7 +16,7 @@ use crate::{
pub struct ActionEnt(pub Entity); pub struct ActionEnt(pub Entity);
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct ConsiderationEnt(pub Entity); pub struct ScorerEnt(pub Entity);
#[derive(Debug)] #[derive(Debug)]
pub struct Thinker { pub struct Thinker {
...@@ -123,7 +123,7 @@ pub fn thinker_system( ...@@ -123,7 +123,7 @@ pub fn thinker_system(
mut cmd: Commands, mut cmd: Commands,
mut iterations: Local<ThinkerIterations>, mut iterations: Local<ThinkerIterations>,
mut thinker_q: Query<(Entity, &Parent, &mut Thinker, &ActiveThinker)>, mut thinker_q: Query<(Entity, &Parent, &mut Thinker, &ActiveThinker)>,
utilities: Query<&Utility>, utilities: Query<&Score>,
mut action_states: Query<&mut actions::ActionState>, mut action_states: Query<&mut actions::ActionState>,
builder_wrappers: Query<&ActionManagerWrapper>, builder_wrappers: Query<&ActionManagerWrapper>,
) { ) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment