use crate::games::kernel::{self, Outcome};
use super::catalogue::LoopyValue;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LoopyGraph {
succ: Vec<Vec<usize>>,
}
impl LoopyGraph {
pub fn new(succ: Vec<Vec<usize>>) -> LoopyGraph {
LoopyGraph { succ }
}
pub fn from_rule<F: Fn(usize) -> Vec<usize>>(n: usize, moves: F) -> LoopyGraph {
LoopyGraph {
succ: (0..n).map(moves).collect(),
}
}
pub fn succ(&self) -> &[Vec<usize>] {
&self.succ
}
pub fn outcomes(&self) -> Vec<Outcome> {
kernel::outcomes(&self.succ)
}
pub fn loss_set(&self) -> Vec<usize> {
self.indices_with(Outcome::Loss)
}
pub fn win_set(&self) -> Vec<usize> {
self.indices_with(Outcome::Win)
}
pub fn draw_set(&self) -> Vec<usize> {
self.indices_with(Outcome::Draw)
}
fn indices_with(&self, want: Outcome) -> Vec<usize> {
self.outcomes()
.into_iter()
.enumerate()
.filter(|(_, o)| *o == want)
.map(|(i, _)| i)
.collect()
}
pub fn classify(&self, v: usize) -> Option<LoopyValue> {
match self.outcomes().get(v)? {
Outcome::Loss => Some(LoopyValue::Zero),
Outcome::Draw => Some(LoopyValue::Dud),
Outcome::Win => None,
}
}
}