use std::fmt; #[derive(Copy, Clone, PartialEq, Debug)] pub enum Tile { PlayerOne, PlayerTwo, Unowned, } pub enum GameState { PlayerOneWin, PlayerTwoWin, Draw, InProgress, } impl fmt::Display for Tile { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let sym = match self { Tile::PlayerOne => "X", Tile::PlayerTwo => "O", Tile::Unowned => "_", }; write!(f, "{sym}") } } pub type Coord = (usize, usize); pub fn parse_coord(val: &str) -> Result { let split = val.split(","); let res: Vec = split .map(|v| v.trim().parse::().expect("Couldn't parse!")) .collect(); if res.len() != 2 { return Err("Must provide exactly two dimensional coordinates"); } if res[0] < 1 || res[0] > 3 || res[1] < 1 || res[1] > 3 { return Err("Coordinates must be between 1 and 3"); } return Ok((res[0] - 1, res[1] - 1)); } #[derive(Clone, Debug)] pub struct Board { pub state: [[Tile; 3]; 3], } impl Board { pub fn get_at_coord(&self, coord: Coord) -> Tile { self.state[coord.0][coord.1] } pub fn set_at_coord(&mut self, coord: Coord, tile: Tile) -> () { self.state[coord.0][coord.1] = tile; } } pub fn init_board() -> Board { return Board { state: [[Tile::Unowned; 3]; 3], }; }