use super::*;
pub trait Recall {
fn root(&self) -> Game;
fn actions(&self) -> &[Action];
fn complete(&self) -> Vec<Action> {
Game::blinds()
.into_iter()
.chain(self.actions().iter().copied())
.collect()
}
fn head(&self) -> Game {
self.actions()
.iter()
.copied()
.fold(self.root(), |mut g, a| g.consume(a))
}
fn states(&self) -> Vec<Game> {
let root = self.root();
let acts = self
.actions()
.iter()
.copied()
.scan(root, |g, a| Some(g.consume(a)))
.collect::<Vec<Game>>();
std::iter::once(root).chain(acts).collect()
}
fn aggression(&self) -> usize {
self.actions()
.iter()
.rev()
.take_while(|a| a.is_choice())
.filter(|a| a.is_aggro())
.count()
}
fn history(&self) -> Vec<Edge> {
self.states()
.into_iter()
.zip(self.actions().iter())
.scan(Path::default(), |past, (game, action)| {
let edge = game.edgify(*action, past.aggression());
*past = past
.clone()
.into_iter()
.chain(std::iter::once(edge))
.collect();
Some(edge)
})
.collect()
}
fn subgame(&self) -> Path {
self.history()
.into_iter()
.rev()
.take_while(|e| e.is_choice())
.collect::<Vec<_>>()
.into_iter()
.rev()
.collect()
}
fn choices(&self) -> Path {
self.head().choices(self.aggression())
}
}