1use bevy::prelude::*;
4
5use crate::{choices::Choice, scorers::Score};
6
7#[reflect_trait]
13pub trait Picker: std::fmt::Debug + Sync + Send {
14 fn pick<'a>(&self, choices: &'a [Choice], scores: &Query<&Score>) -> Option<&'a Choice>;
15}
16
17#[derive(Debug, Clone, Default)]
32pub struct FirstToScore {
33 pub threshold: f32,
34}
35
36impl FirstToScore {
37 pub fn new(threshold: f32) -> Self {
38 Self { threshold }
39 }
40}
41
42impl Picker for FirstToScore {
43 fn pick<'a>(&self, choices: &'a [Choice], scores: &Query<&Score>) -> Option<&'a Choice> {
44 for choice in choices {
45 let value = choice.calculate(scores);
46 if value >= self.threshold {
47 return Some(choice);
48 }
49 }
50 None
51 }
52}
53
54#[derive(Debug, Clone, Default)]
68pub struct Highest;
69
70impl Picker for Highest {
71 fn pick<'a>(&self, choices: &'a [Choice], scores: &Query<&Score>) -> Option<&'a Choice> {
72 let mut max_score = 0f32;
73
74 choices.iter().fold(None, |acc, choice| {
75 let score = choice.calculate(scores);
76
77 if score <= max_score || score <= 0.0 {
78 return acc;
79 }
80
81 max_score = score;
82 Some(choice)
83 })
84 }
85}
86
87#[derive(Debug, Clone, Default)]
102pub struct HighestToScore {
103 pub threshold: f32,
104}
105
106impl HighestToScore {
107 pub fn new(threshold: f32) -> Self {
108 Self { threshold }
109 }
110}
111
112impl Picker for HighestToScore {
113 fn pick<'a>(&self, choices: &'a [Choice], scores: &Query<&Score>) -> Option<&'a Choice> {
114 let mut highest_score = 0f32;
115
116 choices.iter().fold(None, |acc, choice| {
117 let score = choice.calculate(scores);
118
119 if score <= self.threshold || score <= highest_score {
120 return acc;
121 }
122
123 highest_score = score;
124 Some(choice)
125 })
126 }
127}