use crate::Error;
use std::fmt;
pub use board::{Board, BoardDisplay, Move, Position};
pub use cube::Cube;
pub use dice::{Dice, Roll};
pub use player::Player;
mod board;
mod cube;
mod dice;
mod player;
pub mod prelude {
pub use crate::rules::{Board, BoardDisplay, Dice, MatchRules, Move, Player, Position, Roll};
}
#[derive(Debug, Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash)]
pub struct Rules {
points: u64,
cube_play: bool,
beaver: bool,
raccoon: bool,
murphy: bool,
murphy_limit: u8,
jacobi: bool,
crawford: bool,
holland: bool,
}
impl Default for Rules {
fn default() -> Self {
Rules {
points: 7,
cube_play: true,
beaver: false,
raccoon: false,
murphy: false,
murphy_limit: 0,
jacobi: false,
crawford: true,
holland: false,
}
}
}
impl fmt::Display for Rules {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Points: {}, Cube: {}, Beaver: {}, Raccoon: {}, Murphy: {}, Murphy Limit: {}, Jacobi: {}, \
Crawford: {}, Holland: {}",
self.points,
self.cube_play,
self.beaver,
self.raccoon,
self.murphy,
self.murphy_limit,
self.jacobi,
self.crawford,
self.holland
)
}
}
pub trait MatchRules {
fn set_points(&mut self, points: u64) -> Result<(), Error>;
fn get_points(&self) -> Result<u64, Error>;
fn set_cube_play(&mut self, cube: bool) -> Result<(), Error>;
fn get_cube_play(&self) -> Result<bool, Error>;
fn set_crawford(&mut self, state: bool) -> Result<(), Error>;
fn get_crawford(&self) -> Result<bool, Error>;
fn set_beaver(&mut self, state: bool) -> Result<(), Error>;
fn get_beaver(&self) -> Result<bool, Error>;
fn set_raccoon(&mut self, state: bool) -> Result<(), Error>;
fn get_raccoon(&self) -> Result<bool, Error>;
fn set_murphy(&mut self, state: bool, limit: u8) -> Result<(), Error>;
fn get_murphy(&self) -> Result<(bool, u8), Error>;
fn set_jacobi(&mut self, state: bool) -> Result<(), Error>;
fn get_jacobi(&self) -> Result<bool, Error>;
fn set_holland(&mut self, state: bool) -> Result<(), Error>;
fn get_holland(&self) -> Result<bool, Error>;
}
impl MatchRules for Rules {
fn set_points(&mut self, points: u64) -> Result<(), Error> {
if points < 1 {
return Err(Error::PointsInvalid);
}
self.points = points;
Ok(())
}
fn get_points(&self) -> Result<u64, Error> {
Ok(self.points)
}
fn set_cube_play(&mut self, cube: bool) -> Result<(), Error> {
self.cube_play = cube;
Ok(())
}
fn get_cube_play(&self) -> Result<bool, Error> {
Ok(self.cube_play)
}
fn set_crawford(&mut self, state: bool) -> Result<(), Error> {
self.crawford = state;
Ok(())
}
fn get_crawford(&self) -> Result<bool, Error> {
Ok(self.crawford)
}
fn set_beaver(&mut self, state: bool) -> Result<(), Error> {
self.beaver = state;
Ok(())
}
fn get_beaver(&self) -> Result<bool, Error> {
Ok(self.beaver)
}
fn set_raccoon(&mut self, state: bool) -> Result<(), Error> {
self.raccoon = state;
Ok(())
}
fn get_raccoon(&self) -> Result<bool, Error> {
Ok(self.raccoon)
}
fn set_murphy(&mut self, state: bool, limit: u8) -> Result<(), Error> {
self.murphy = state;
self.murphy_limit = limit;
Ok(())
}
fn get_murphy(&self) -> Result<(bool, u8), Error> {
if !self.murphy {
return Ok((false, 0));
}
Ok((true, self.murphy_limit))
}
fn set_jacobi(&mut self, state: bool) -> Result<(), Error> {
self.jacobi = state;
Ok(())
}
fn get_jacobi(&self) -> Result<bool, Error> {
Ok(self.jacobi)
}
fn set_holland(&mut self, state: bool) -> Result<(), Error> {
self.crawford = state;
self.holland = state;
Ok(())
}
fn get_holland(&self) -> Result<bool, Error> {
Ok(self.holland)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_rules() {
let rules = Rules::default();
assert_eq!(rules.points, 7);
assert!(!rules.beaver);
assert!(!rules.raccoon);
assert!(!rules.murphy);
assert_eq!(rules.murphy_limit, 0);
assert!(!rules.jacobi);
assert!(rules.crawford);
assert!(!rules.holland);
}
#[test]
fn test_display() {
let rules = Rules::default();
assert_eq!(
format!("{}", rules),
"Points: 7, Cube: true, Beaver: false, Raccoon: false, Murphy: false, Murphy Limit: \
0, Jacobi: false, Crawford: true, Holland: false"
);
}
#[test]
fn test_set_points_valid() -> Result<(), Error> {
let mut rules = Rules::default();
rules.set_points(10)?;
assert_eq!(rules.get_points(), Ok(10));
Ok(())
}
#[test]
fn test_set_points_invalid() {
let mut rules = Rules::default();
let result = rules.set_points(0);
assert!(result.is_err());
assert_eq!(result.unwrap_err(), Error::PointsInvalid);
}
#[test]
fn test_set_crawford() -> Result<(), Error> {
let mut rules = Rules::default();
rules.set_crawford(true)?;
assert_eq!(rules.get_crawford(), Ok(true));
Ok(())
}
#[test]
fn test_set_beaver() -> Result<(), Error> {
let mut rules = Rules::default();
rules.set_beaver(true)?;
assert_eq!(rules.get_beaver(), Ok(true));
Ok(())
}
#[test]
fn test_set_raccoon() -> Result<(), Error> {
let mut rules = Rules::default();
rules.set_raccoon(true)?;
assert_eq!(rules.get_raccoon(), Ok(true));
Ok(())
}
#[test]
fn test_set_murphy() -> Result<(), Error> {
let mut rules = Rules::default();
rules.set_murphy(true, 8)?;
assert_eq!(rules.get_murphy(), Ok((true, 8)));
Ok(())
}
#[test]
fn test_set_murphy_false() -> Result<(), Error> {
let rules = Rules::default();
assert_eq!(rules.get_murphy(), Ok((false, 0)));
Ok(())
}
#[test]
fn test_set_jacobi() -> Result<(), Error> {
let mut rules = Rules::default();
rules.set_jacobi(true)?;
assert_eq!(rules.get_jacobi(), Ok(true));
Ok(())
}
#[test]
fn test_set_holland() -> Result<(), Error> {
let mut rules = Rules::default();
rules.set_crawford(false)?;
rules.set_holland(true)?;
assert_eq!(rules.get_holland(), Ok(true));
assert_eq!(rules.get_crawford(), Ok(true));
Ok(())
}
}