use std::fmt; pub enum Piece { LightPawn, LightKing, DarkPawn, DarkKing, } pub enum BoardTile { Empty, Piece(Piece), } pub enum BoardSize { American, International, Canadian, } impl BoardSize { fn get_size(&self) -> u32 { match &self { BoardSize::American => 8, BoardSize::International => 10, BoardSize::Canadian => 12, } } } pub struct Board { dimensions: BoardSize, tiles: Vec, } impl Board { pub fn new(size: BoardSize) -> Board { let board_size = size.get_size(); let width = board_size / 2; let height = board_size / 2; let starting_rows = board_size / 2 - 1; let playing_tiles = (0..width * height) .map(|tile|{ let row = tile / width; match row { r if r < starting_rows => BoardTile::Piece( Piece::LightPawn), r if r > height - starting_rows => BoardTile::Piece( Piece::DarkPawn), _ => BoardTile::Empty, } }) .collect(); Board { dimensions: size, tiles: playing_tiles, } } fn get_index(&self, row: u32, column: u32) -> usize { let width = self.dimensions.get_size(); (row * width + column) as usize } } static COLUMN_COORDINATE_BORDER: &str = " ABCDEFGHIJKL"; impl fmt::Display for Board { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { let width = self.dimensions.get_size(); // Create the top level border. let mut column_border_chars = COLUMN_COORDINATE_BORDER.chars(); for _ in 0..width + 1 { write!(formatter, "{}", column_border_chars.next().unwrap())?; } write!(formatter, "\n")?; for row in 0..width { write!(formatter, "{ }", (row + 1).to_string())?; if row % 2 == 0 { write!(formatter, " ")?; } for col in 0..(width / 2) { let token = match self.tiles[self.get_index(row, col)] { BoardTile::Piece(Piece::LightPawn) => "○", BoardTile::Piece(Piece::LightKing) => "⍟", BoardTile::Piece(Piece::DarkPawn) => "●", BoardTile::Piece(Piece::DarkKing) => "✪", BoardTile::Empty => "✪", }; let adjacent = if row % 2 == 1 && col == width - 1 { "" } else { " " }; write!(formatter, "{}{}", token, adjacent)?; } write!(formatter, "\n")?; } Ok(()) } } #[cfg(test)] mod tests { use crate::Board; use crate::BoardSize; #[test] fn setup_international_board() { let expected = "\ ABCDEFGHIJ\n\ 1 ○ ○ ○ ○ ○\n\ 2○ ○ ○ ○ ○ \n\ 3 ○ ○ ○ ○ ○\n\ 4○ ○ ○ ○ ○ \n\ 5 ◰ ◰ ◰ ◰ ◰\n\ 6◰ ◰ ◰ ◰ ◰ \n\ 7 ● ● ● ● ●\n\ 8● ● ● ● ● \n\ 9 ● ● ● ● ●\n\ 10● ● ● ● ● \n\ "; assert_eq!(Board::new(BoardSize::International).to_string(), expected); } }