use crate::error::Error;
use crate::rules::Player;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Cube {
exponential: u8,
owner: Player,
}
impl Cube {
pub fn get(&self) -> u64 {
2u64.pow(self.exponential as u32)
}
pub fn owner(&self) -> Player {
self.owner
}
pub fn set(&mut self, value: u64) -> Result<(), Error> {
if value.is_power_of_two() {
let vf = value as f64;
self.exponential = vf.log2() as u8;
Ok(())
} else {
Err(Error::CubeValueInvalid)
}
}
pub fn set_owner(&mut self, owner: Player) {
self.owner = owner;
}
pub fn offer(&self, opponent: Player) -> Result<u64, Error> {
if self.owner == Player::Nobody || self.owner != opponent {
Ok(2u64.pow(1 + self.exponential as u32))
} else {
Err(Error::CubeNotPermitted)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_value() {
let cube = Cube::default();
assert_eq!(cube.get(), 1);
}
#[test]
fn set_value2() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set(2)?;
assert_eq!(cube.get(), 2);
Ok(())
}
#[test]
fn set_value4() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set(4)?;
assert_eq!(cube.get(), 4);
Ok(())
}
#[test]
fn set_value8() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set(8)?;
assert_eq!(cube.get(), 8);
Ok(())
}
#[test]
fn set_value16() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set(16)?;
assert_eq!(cube.get(), 16);
Ok(())
}
#[test]
fn set_value32() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set(32)?;
assert_eq!(cube.get(), 32);
Ok(())
}
#[test]
fn set_value64() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set(64)?;
assert_eq!(cube.get(), 64);
Ok(())
}
#[test]
fn set_value128() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set(128)?;
assert_eq!(cube.get(), 128);
Ok(())
}
#[test]
fn set_invalid_value() -> Result<(), Error> {
let mut cube = Cube::default();
assert!(cube.set(3).is_err());
Ok(())
}
#[test]
fn owner_nobody() {
let cube = Cube::default();
assert_eq!(cube.owner(), Player::Nobody);
}
#[test]
fn owner() {
let mut cube = Cube::default();
cube.set_owner(Player::Player0);
assert_eq!(cube.owner(), Player::Player0);
cube.set_owner(Player::Player1);
assert_eq!(cube.owner(), Player::Player1);
}
#[test]
fn offer_from_nobody() -> Result<(), Error> {
let cube = Cube::default();
assert_eq!(cube.owner(), Player::Nobody);
let offer = cube.offer(Player::Player1)?;
assert_eq!(offer, 2);
let cube = Cube::default();
let offer = cube.offer(Player::Player0)?;
assert_eq!(offer, 2);
Ok(())
}
#[test]
fn offer_from_player() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set(2)?;
cube.set_owner(Player::Player0);
let offer = cube.offer(Player::Player1)?;
assert_eq!(cube.owner(), Player::Player0);
assert_eq!(cube.get(), 2);
assert_eq!(offer, 4);
Ok(())
}
#[test]
fn offer_error() -> Result<(), Error> {
let mut cube = Cube::default();
cube.set_owner(Player::Player1);
assert!(cube.offer(Player::Player1).is_err());
Ok(())
}
}