From 51e5228145cb3239a84c635286de9f39121ef54d Mon Sep 17 00:00:00 2001 From: Pavel Lutskov Date: Sun, 14 Nov 2021 14:42:53 +0100 Subject: [PATCH] Implement basic Piece infrastructure And the Pawn class --- rs/src/main.rs | 166 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 2 deletions(-) diff --git a/rs/src/main.rs b/rs/src/main.rs index e7a11a9..e46caf2 100644 --- a/rs/src/main.rs +++ b/rs/src/main.rs @@ -1,3 +1,165 @@ -fn main() { - println!("Hello, world!"); +use std::marker::PhantomData; +enum Color { + Black, + White, } + +struct Position { + row: Row, + column: Column, +} + +impl Position { + fn delta(&self, delta_row_column: (i8, i8)) -> Result { + let (delta_row, delta_column) = delta_row_column; + Ok(Position { + row: self.row.delta(delta_row)?, + column: self.column.delta(delta_column)?, + }) + } +} + +#[derive(PartialEq, Clone, Copy)] +enum Row { + _1, + _2, + _3, + _4, + _5, + _6, + _7, + _8, +} + +#[derive(PartialEq, Clone, Copy)] +enum Column { + A, + B, + C, + D, + E, + F, + G, + H, +} + +trait GridAxis +where + Self: Sized, + Self: Clone, +{ + const ALL_VALUES: [Self; 8]; + fn new(index: u8) -> Result { + return Ok( + Self::ALL_VALUES[Self::validate_index(index)? as usize].clone() + ); + } + fn validate_index(index: u8) -> Result { + if index as usize >= Self::ALL_VALUES.len() { + Err(()) + } else { + Ok(index) + } + } + fn get_index(&self) -> u8; + fn delta(&self, delta: i8) -> Result { + let highest = Self::ALL_VALUES.len() as i8 - 1; + if delta > highest + || delta < -highest + || (delta < 0 && self.get_index() < delta.abs() as u8) + || (delta > 0 && self.get_index() + delta as u8 > highest as u8) + { + Err(()) + } else { + Ok(Self::new(((self.get_index() as i8) + delta) as u8)?) + } + } +} + +impl GridAxis for Row { + const ALL_VALUES: [Row; 8] = [ + Row::_1, + Row::_2, + Row::_3, + Row::_4, + Row::_5, + Row::_6, + Row::_7, + Row::_8, + ]; + fn get_index(&self) -> u8 { + *self as u8 + } +} + +impl GridAxis for Column { + const ALL_VALUES: [Column; 8] = [ + Column::A, + Column::B, + Column::C, + Column::D, + Column::E, + Column::F, + Column::G, + Column::H, + ]; + fn get_index(&self) -> u8 { + *self as u8 + } +} + +struct Piece { + position: Position, + color: Color, + piece_type: PhantomData, +} + +trait Movement { + fn get_moves(&self) -> Vec; + fn get_captures(&self) -> Vec; +} + +struct Pawn {} + +impl Piece { + fn deltas_to_valid_positions( + &self, + deltas: &Vec<(i8, i8)>, + ) -> Vec { + deltas + .iter() + .filter_map(|&delta_row_column| { + self.position.delta(delta_row_column).ok() + }) + .collect() + } +} + +impl Piece { + fn get_home_row_direction(&self) -> (Row, i8) { + match self.color { + Color::Black => (Row::_7, -1), + Color::White => (Row::_2, 1), + } + } +} + +impl Movement for Piece { + fn get_moves(&self) -> Vec { + let (home_row, direction) = self.get_home_row_direction(); + let deltas: Vec<(i8, i8)> = if self.position.row == home_row { + vec![(1 * direction, 0), (2 * direction, 0)] + } else { + vec![(1 * direction, 0)] + }; + self.deltas_to_valid_positions(&deltas) + } + fn get_captures(&self) -> Vec { + let (_, direction) = self.get_home_row_direction(); + let deltas: Vec<(i8, i8)> = + vec![(1 * direction, 1), (1 * direction, -1)]; + self.deltas_to_valid_positions(&deltas) + } +} + +fn main() {}