eight_puzzle_core/
hint.rs

1use crate::direction::Direction;
2use crate::state::State;
3use rand::seq::IteratorRandom;
4use std::collections::HashMap;
5use std::collections::VecDeque;
6
7pub struct Hinter<S: State> {
8    hint_map: HashMap<S, Direction>,
9}
10
11impl<S: State> Hinter<S> {
12    pub fn new(goal: S) -> Self {
13        let mut hint_map = HashMap::new();
14
15        let mut q = VecDeque::new();
16        q.push_back(goal);
17        while let Some(f) = q.pop_front() {
18            for (direction, neighbor) in f.neighbors().into_iter() {
19                hint_map.entry(neighbor.clone()).or_insert_with(|| {
20                    q.push_back(neighbor);
21                    direction
22                });
23            }
24        }
25        Hinter { hint_map }
26    }
27
28    pub fn hint(&self, s: &S) -> Option<&Direction> {
29        self.hint_map.get(s)
30    }
31
32    pub fn random_state(&self) -> Option<&S> {
33        self.hint_map.keys().choose(&mut rand::thread_rng())
34    }
35}