summaryrefslogtreecommitdiff
path: root/model
diff options
context:
space:
mode:
Diffstat (limited to 'model')
-rw-r--r--model/src/board.rs60
-rw-r--r--model/src/coordinates.rs99
-rw-r--r--model/src/lib.rs2
3 files changed, 113 insertions, 48 deletions
diff --git a/model/src/board.rs b/model/src/board.rs
index e852063..d7cc69f 100644
--- a/model/src/board.rs
+++ b/model/src/board.rs
@@ -1,5 +1,5 @@
use crate::possible_moves::PossibleMoves;
-use crate::{Piece, PieceColor};
+use crate::{Piece, PieceColor, SquareCoordinate};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::hash::{Hash, Hasher};
@@ -124,26 +124,6 @@ impl CheckersBitBoard {
self.turn
}
- /// Get the piece at the given square
- ///
- /// # Arguments
- ///
- /// * `value` - The square to get the piece from
- ///
- /// # Panics
- ///
- /// Panics if value >= 32
- const fn get(self, value: usize) -> Option<Piece> {
- if self.piece_at(value) {
- Some(Piece::new(
- unsafe { self.king_at_unchecked(value) },
- unsafe { self.color_at_unchecked(value) },
- ))
- } else {
- None
- }
- }
-
/// Gets the piece at a given row column coordinate
///
/// # Arguments
@@ -151,38 +131,22 @@ impl CheckersBitBoard {
/// * `row` - The row. The a file is row 0
/// * `col` - The column. The first rank is column 0
pub fn get_at_row_col(self, row: usize, col: usize) -> Option<Piece> {
- if row < 8 && col < 8 {
- if row % 2 == 0 {
- if col % 2 == 0 {
- let value = ((18 - ((col / 2) * 6)) + ((row / 2) * 8)) % 32;
- self.get(value)
+ if row > 32 || col > 32 {
+ None
+ } else {
+ let value = SquareCoordinate::new(row as u8, col as u8).to_value();
+ if let Some(value) = value {
+ if self.piece_at(value) {
+ Some(Piece::new(
+ unsafe { self.king_at_unchecked(value) },
+ unsafe { self.color_at_unchecked(value) },
+ ))
} else {
None
}
} else {
- if col % 2 == 1 {
- let column_value = match col {
- 1 => 19,
- 3 => 13,
- 5 => 7,
- 7 => 1,
- _ => unreachable!(),
- };
- let row_value = match row {
- 1 => 0,
- 3 => 8,
- 5 => 16,
- 7 => 24,
- _ => unreachable!(),
- };
- let value = (column_value + row_value) % 32;
- self.get(value)
- } else {
- None
- }
+ None
}
- } else {
- None
}
}
diff --git a/model/src/coordinates.rs b/model/src/coordinates.rs
new file mode 100644
index 0000000..34dcdcf
--- /dev/null
+++ b/model/src/coordinates.rs
@@ -0,0 +1,99 @@
+use std::fmt::{Display, Formatter};
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+pub struct SquareCoordinate {
+ rank: u8,
+ file: u8,
+}
+
+impl SquareCoordinate {
+ pub(crate) fn new(rank: u8, file: u8) -> Self {
+ if rank > 32 {
+ panic!("A Square cannot have a rank greater than 32. Got {}", rank)
+ } else if file > 32 {
+ panic!("A Square cannot have a file greater than 32. Got {}", file)
+ } else {
+ Self { rank, file }
+ }
+ }
+
+ pub fn from_value(value: usize) -> Self {
+ static VALUE_COORDINATE_MAP: [SquareCoordinate; 32] = [
+ SquareCoordinate { rank: 0, file: 6 },
+ SquareCoordinate { rank: 1, file: 7 },
+ SquareCoordinate { rank: 4, file: 0 },
+ SquareCoordinate { rank: 5, file: 1 },
+ SquareCoordinate { rank: 6, file: 2 },
+ SquareCoordinate { rank: 7, file: 3 },
+ SquareCoordinate { rank: 0, file: 4 },
+ SquareCoordinate { rank: 1, file: 5 },
+ SquareCoordinate { rank: 2, file: 6 },
+ SquareCoordinate { rank: 3, file: 7 },
+ SquareCoordinate { rank: 6, file: 0 },
+ SquareCoordinate { rank: 7, file: 1 },
+ SquareCoordinate { rank: 0, file: 2 },
+ SquareCoordinate { rank: 1, file: 3 },
+ SquareCoordinate { rank: 2, file: 4 },
+ SquareCoordinate { rank: 3, file: 5 },
+ SquareCoordinate { rank: 4, file: 6 },
+ SquareCoordinate { rank: 5, file: 7 },
+ SquareCoordinate { rank: 0, file: 0 },
+ SquareCoordinate { rank: 1, file: 1 },
+ SquareCoordinate { rank: 2, file: 2 },
+ SquareCoordinate { rank: 3, file: 3 },
+ SquareCoordinate { rank: 4, file: 4 },
+ SquareCoordinate { rank: 5, file: 5 },
+ SquareCoordinate { rank: 6, file: 6 },
+ SquareCoordinate { rank: 7, file: 7 },
+ SquareCoordinate { rank: 2, file: 0 },
+ SquareCoordinate { rank: 3, file: 1 },
+ SquareCoordinate { rank: 4, file: 2 },
+ SquareCoordinate { rank: 5, file: 3 },
+ SquareCoordinate { rank: 6, file: 4 },
+ SquareCoordinate { rank: 7, file: 5 },
+ ];
+
+ VALUE_COORDINATE_MAP[value]
+ }
+
+ pub fn to_value(self) -> Option<usize> {
+ if self.rank % 2 == 0 {
+ if self.file % 2 == 0 {
+ Some(((18 - ((self.file / 2) * 6)) + ((self.rank / 2) * 8)) as usize % 32)
+ } else {
+ None
+ }
+ } else {
+ if self.file % 2 == 1 {
+ let column_value = match self.file {
+ 1 => 19,
+ 3 => 13,
+ 5 => 7,
+ 7 => 1,
+ _ => unreachable!(),
+ };
+ let row_value = match self.file {
+ 1 => 0,
+ 3 => 8,
+ 5 => 16,
+ 7 => 24,
+ _ => unreachable!(),
+ };
+ Some((column_value + row_value) % 32)
+ } else {
+ None
+ }
+ }
+ }
+}
+
+impl Display for SquareCoordinate {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ write!(
+ f,
+ "{}{}",
+ char::from_u32((self.file + b'a') as u32).unwrap(),
+ self.rank + 1
+ )
+ }
+}
diff --git a/model/src/lib.rs b/model/src/lib.rs
index 1e1b364..61ab2cc 100644
--- a/model/src/lib.rs
+++ b/model/src/lib.rs
@@ -1,11 +1,13 @@
mod board;
mod color;
+mod coordinates;
mod moves;
mod piece;
mod possible_moves;
pub use board::CheckersBitBoard;
pub use color::PieceColor;
+pub use coordinates::SquareCoordinate;
pub use moves::Move;
pub use piece::Piece;
pub use possible_moves::PossibleMoves;