2019-03-01 09:04:11 -05:00
|
|
|
use std::fmt;
|
|
|
|
|
|
|
|
pub enum Piece {
|
|
|
|
LightPawn,
|
2019-02-28 09:06:24 -05:00
|
|
|
LightKing,
|
2019-03-01 09:04:11 -05:00
|
|
|
DarkPawn,
|
2019-02-28 09:06:24 -05:00
|
|
|
DarkKing,
|
|
|
|
}
|
|
|
|
|
2019-03-01 09:04:11 -05:00
|
|
|
pub enum BoardTile {
|
2019-02-28 09:06:24 -05:00
|
|
|
Empty,
|
2019-03-01 09:04:11 -05:00
|
|
|
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>,
|
2019-02-28 09:06:24 -05:00
|
|
|
}
|
|
|
|
|
2019-03-01 09:04:11 -05:00
|
|
|
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;
|
2019-03-01 09:04:11 -05:00
|
|
|
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(
|
2019-03-01 09:04:11 -05:00
|
|
|
Piece::DarkPawn),
|
|
|
|
_ => BoardTile::Empty,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
Board {
|
|
|
|
dimensions: size,
|
|
|
|
tiles: playing_tiles,
|
|
|
|
}
|
|
|
|
}
|
2019-03-01 21:46:06 -05:00
|
|
|
|
|
|
|
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
|
2019-03-01 21:46:06 -05:00
|
|
|
}
|
2019-03-01 09:04:11 -05:00
|
|
|
}
|
|
|
|
|
2019-03-01 11:04:06 -05:00
|
|
|
static COLUMN_COORDINATE_BORDER: &str = " ABCDEFGHIJKL";
|
|
|
|
|
2019-03-01 09:04:11 -05:00
|
|
|
impl fmt::Display for Board {
|
|
|
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
|
|
|
let width = self.dimensions.get_size();
|
|
|
|
|
2019-03-01 11:04:06 -05:00
|
|
|
// 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")?;
|
|
|
|
|
2019-03-01 21:46:06 -05:00
|
|
|
for row in 0..width {
|
|
|
|
|
|
|
|
write!(formatter, "{ }", (row + 1).to_string())?;
|
|
|
|
if row % 2 == 0 {
|
|
|
|
write!(formatter, " ")?;
|
|
|
|
}
|
2019-03-01 11:04:06 -05:00
|
|
|
|
2019-03-01 21:46:06 -05:00
|
|
|
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] {
|
2019-03-01 21:46:06 -05:00
|
|
|
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-01 21:46:06 -05:00
|
|
|
};
|
2019-03-01 11:04:06 -05:00
|
|
|
|
2019-03-02 00:16:50 -05:00
|
|
|
let adjacent = if row % 2 == 0 && col == (width / 2) - 1 {
|
2019-03-01 21:46:06 -05:00
|
|
|
""
|
|
|
|
} else {
|
|
|
|
" "
|
|
|
|
};
|
|
|
|
|
|
|
|
write!(formatter, "{}{}", token, adjacent)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(formatter, "\n")?;
|
|
|
|
}
|
2019-03-01 09:04:11 -05:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
2019-02-28 09:06:24 -05:00
|
|
|
|
|
|
|
|
2019-02-28 08:39:27 -05:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2019-03-01 11:04:06 -05:00
|
|
|
use crate::Board;
|
|
|
|
use crate::BoardSize;
|
|
|
|
|
2019-02-28 08:39:27 -05:00
|
|
|
#[test]
|
2019-03-01 11:04:06 -05:00
|
|
|
fn setup_international_board() {
|
|
|
|
|
2019-03-01 21:46:06 -05:00
|
|
|
let expected =
|
2019-03-02 00:16:50 -05:00
|
|
|
" \
|
2019-03-01 21:46:06 -05:00
|
|
|
ABCDEFGHIJ\n\
|
|
|
|
1 ○ ○ ○ ○ ○\n\
|
|
|
|
2○ ○ ○ ○ ○ \n\
|
|
|
|
3 ○ ○ ○ ○ ○\n\
|
|
|
|
4○ ○ ○ ○ ○ \n\
|
|
|
|
5 ◰ ◰ ◰ ◰ ◰\n\
|
|
|
|
6◰ ◰ ◰ ◰ ◰ \n\
|
|
|
|
7 ● ● ● ● ●\n\
|
|
|
|
8● ● ● ● ● \n\
|
|
|
|
9 ● ● ● ● ●\n\
|
|
|
|
10● ● ● ● ● \n\
|
|
|
|
";
|
2019-03-01 11:04:06 -05:00
|
|
|
assert_eq!(Board::new(BoardSize::International).to_string(), expected);
|
2019-02-28 08:39:27 -05:00
|
|
|
}
|
|
|
|
}
|