use std::fmt; #[derive(PartialEq)] pub enum Player { Black, White, } impl fmt::Display for Player { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "{}", match self { Player::Black => "B", Player::White => "W", } ) } } #[derive(PartialEq)] pub enum Stone { Flat, Standing, Capstone, } impl fmt::Display for Stone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "{}", match self { Stone::Flat => "", Stone::Standing => "S", Stone::Capstone => "C", } ) } } pub struct Position { pub x: u8, pub y: u8, } impl fmt::Display for Position { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:x}{}", 10 + self.x, self.y) } } pub enum Direction { Up, Down, Left, Right, } impl fmt::Display for Direction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "{}", match self { Direction::Up => "+", Direction::Down => "-", Direction::Left => "<", Direction::Right => ">", } ) } } pub enum Move { Place(Player, Position, Stone), Slide(Player, Position, Direction, Vec), } impl fmt::Display for Move { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Move::Place(player, pos, stone) => write!(f, "{}{}{}", pos, player, stone), Move::Slide(_, pos, direction, drops) => write!( f, "{}{}{}", pos, direction, drops.into_iter().map(|q| q.to_string()).collect::() ), } } } type Stack = Vec<(Stone, Player)>; pub struct Board { size: u16, board: Vec, } impl Board { fn lookup(&self, pos: &Position) -> Option<&Stack> { let y: u16 = pos.y.into(); let x: u16 = pos.x.into(); // Really? let idx: usize = (x + y * self.size).into(); self.board.get(idx) } fn is_legal_move(&self, mov: &Move) -> bool { match mov { Move::Place(_, pos, _) => match self.lookup(pos) { Some(stack) => { if stack.len() == 0 { true } else { false } } None => false, }, Move::Slide(player, pos, direction, drops) => match self.lookup(pos) { Some(stack) => { if stack.len() == 0 { true } else { false } } None => false, }, } } }