podch 0.1.0

Game engine for the podch abstract board game
Documentation
use std::collections::HashSet;

use crate::{Board, BinBoard, SimilarSituations};

/// Container for used situations and similar to them
///
/// # Examples
/// ```
/// use podch::{Board, UsedSituations};
/// let mut used = podch::HashUsedSituations::new();
/// let mut board = podch::VecBoard::new(2, 3);
/// assert!(!used.is(&board));  // By default, neither situation is marked used
/// used.add(&board);  // Mark "000\n000" as used
/// assert!(used.is(&board));
/// board.set(0, 1, podch::Stone::Light);
/// assert!(!used.is(&board));  // "020\n000" is not marked yet
/// used.add(&board);
/// board.set(0, 1, podch::Stone::None);
/// assert!(used.is(&board));  // "000\n000" is still marked
/// used.remove(&board);
/// assert!(!used.is(&board));  // no longer marked
/// board.set(1, 1, podch::Stone::Dark);
/// assert!(used.is(&board));  // "000\n010" is similar to "020\n000" that is marked
/// board.set(0, 1, podch::Stone::Dark);
/// assert!(!used.is(&board));  // "010\n010" is not similar to any used situation
/// ```
pub trait UsedSituations<T: Board> {
    /// Check whether situation on `board` or any similar to it was used
    fn is(&self, board: &T) -> bool;

    /// Mark situation on `board` as used
    fn add(&mut self, board: &T);

    /// Mark situation on `board` as unused
    fn remove(&mut self, board: &T);
}

/// HashSet for used situations
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct HashUsedSituations {
    set: HashSet<BinBoard>,
}

impl HashUsedSituations {
    /// Construct empty container
    ///
    /// # Examples
    /// ```
    /// use podch::{Board, UsedSituations};
    /// let used = podch::HashUsedSituations::new();
    /// assert!(!used.is(&podch::VecBoard::new(2, 3)));
    /// ```
    pub fn new() -> Self {
        Self {
            set: HashSet::new(),
        }
    }
}

impl<T: Board> UsedSituations<T> for HashUsedSituations {
    fn is(&self, board: &T) -> bool {
        self.set.contains(&SimilarSituations::new(board).min().unwrap())
    }

    fn add(&mut self, board: &T) {
        self.set.insert(SimilarSituations::new(board).min().unwrap());
    }

    fn remove(&mut self, board: &T) {
        self.set.remove(&SimilarSituations::new(board).min().unwrap());
    }
}