justcheckers/engine/src/lib.rs

144 lines
3.5 KiB
Rust
Raw Normal View History

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<BoardTile>,
}
impl Board {
pub fn new(size: BoardSize) -> Board {
let board_size = size.get_size();
let width = board_size / 2;
2019-03-02 00:16:50 -05:00
let height = board_size;
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),
2019-03-02 00:16:50 -05:00
r if r > height - starting_rows - 1 => BoardTile::Piece(
Piece::DarkPawn),
_ => BoardTile::Empty,
}
})
.collect();
Board {
dimensions: size,
tiles: playing_tiles,
}
}
fn get_index(&self, row: u32, column: u32) -> usize {
2019-03-02 00:16:50 -05:00
let width = self.dimensions.get_size() / 2;
(row * width + (column / 2)) 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) {
2019-03-02 00:16:50 -05:00
let idx = (row * (width / 2) + col) as usize;
let token = match self.tiles[idx] {
BoardTile::Piece(Piece::LightPawn) => "",
BoardTile::Piece(Piece::LightKing) => "",
BoardTile::Piece(Piece::DarkPawn) => "",
BoardTile::Piece(Piece::DarkKing) => "",
2019-03-02 00:16:50 -05:00
BoardTile::Empty => "",
};
2019-03-02 00:16:50 -05:00
let adjacent = if row % 2 == 0 && col == (width / 2) - 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 =
2019-03-02 00:16:50 -05:00
" \
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);
}
}