use crate::core::{Candidate, Cardinal, Id, Nominal, Ordinal, Preference};
use rand::{Rng, rngs::StdRng};
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct Impartial;
impl Impartial {
#[must_use]
pub const fn new() -> Self {
Self
}
}
impl Default for Impartial {
fn default() -> Self {
Self::new()
}
}
impl Preference<Cardinal> for Impartial {
fn draw(&self, candidates: &[Candidate], rng: &mut StdRng) -> Cardinal {
const RANGE: usize = 5;
Cardinal(
candidates
.iter()
.map(|candidate| (candidate.id() as Id, rng.random_range(0..=RANGE)))
.collect(),
)
}
}
impl Preference<Ordinal> for Impartial {
fn draw(&self, candidates: &[Candidate], rng: &mut StdRng) -> Ordinal {
Ordinal({
let mut points: Vec<(Id, f32)> = candidates
.iter()
.map(|candidate| (candidate.id() as Id, rng.random_range(0.0..1.0)))
.collect();
points.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
points.iter().map(|(id, _)| *id).collect()
})
}
}
impl Preference<Nominal> for Impartial {
fn draw(&self, candidates: &[Candidate], rng: &mut StdRng) -> Nominal {
Nominal(
candidates
.iter()
.filter(|_| rng.random_bool(0.5))
.map(Candidate::id)
.collect(),
)
}
}