diff options
| author | Mike White <botahamec@outlook.com> | 2021-08-27 20:46:18 -0400 |
|---|---|---|
| committer | Mike White <botahamec@outlook.com> | 2021-08-27 20:46:18 -0400 |
| commit | a310274c6d5acea8f5f83f2feb8699e7b312f8e3 (patch) | |
| tree | 9424e380512df43e64a50ad0824375d7f23b3c25 | |
| parent | 68014734561c3a8d8712916bdfa58b8347131501 (diff) | |
Highlighted possible moves when a piece is clicked
| -rw-r--r-- | model/src/coordinates.rs | 10 | ||||
| -rw-r--r-- | model/src/moves.rs | 29 | ||||
| -rw-r--r-- | ui/resources/possible_move.png | bin | 0 -> 342 bytes | |||
| -rw-r--r-- | ui/src/main.rs | 55 |
4 files changed, 88 insertions, 6 deletions
diff --git a/model/src/coordinates.rs b/model/src/coordinates.rs index a055f46..7aea88b 100644 --- a/model/src/coordinates.rs +++ b/model/src/coordinates.rs @@ -7,7 +7,7 @@ pub struct SquareCoordinate { } impl SquareCoordinate { - pub(crate) fn new(rank: u8, file: u8) -> Self { + pub 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 { @@ -56,6 +56,14 @@ impl SquareCoordinate { VALUE_COORDINATE_MAP[value] } + pub fn rank(self) -> u8 { + self.rank + } + + pub fn file(self) -> u8 { + self.file + } + pub fn to_value(self) -> Option<usize> { if self.rank % 2 == 0 { if self.file % 2 == 0 { diff --git a/model/src/moves.rs b/model/src/moves.rs index b8e58ee..7581b6b 100644 --- a/model/src/moves.rs +++ b/model/src/moves.rs @@ -38,6 +38,29 @@ impl Move { } } + pub const fn start(self) -> u32 { + self.start + } + + /// Calculates the value of the end position of the move + pub const fn end_position(self) -> usize { + let dest = match self.jump { + false => match self.direction { + MoveDirection::ForwardLeft => self.start + 7, + MoveDirection::ForwardRight => self.start + 1, + MoveDirection::BackwardLeft => self.start - 1, + MoveDirection::BackwardRight => self.start - 7, + }, + true => match self.direction { + MoveDirection::ForwardLeft => self.start + 14, + MoveDirection::ForwardRight => self.start + 2, + MoveDirection::BackwardLeft => self.start - 2, + MoveDirection::BackwardRight => self.start - 14, + }, + }; + dest as usize + } + /// Apply the move to a board. This does not mutate the original board, /// but instead returns a new one. /// @@ -92,10 +115,10 @@ impl Move { #[cfg(test)] mod tests { - use proptest::prelude::*; use super::*; + use proptest::prelude::*; - proptest!{ + proptest! { #[test] fn new(start in 0usize..32, jump in proptest::bool::ANY) { let direction = MoveDirection::ForwardLeft; @@ -123,4 +146,4 @@ mod tests { assert_eq!(move_test.jump, jump); } } -}
\ No newline at end of file +} diff --git a/ui/resources/possible_move.png b/ui/resources/possible_move.png Binary files differnew file mode 100644 index 0000000..26cb5e5 --- /dev/null +++ b/ui/resources/possible_move.png diff --git a/ui/src/main.rs b/ui/src/main.rs index 166b1ae..ba4fbe3 100644 --- a/ui/src/main.rs +++ b/ui/src/main.rs @@ -1,7 +1,8 @@ -use model::{CheckersBitBoard, PieceColor}; +use model::{CheckersBitBoard, PieceColor, PossibleMoves, SquareCoordinate}; use tetra::graphics::{self, Color, DrawParams, Texture}; +use tetra::input::MouseButton; use tetra::math::Vec2; -use tetra::{Context, ContextBuilder, State}; +use tetra::{input, Context, ContextBuilder, State}; const WINDOW_WIDTH: f32 = 640.0; const WINDOW_HEIGHT: f32 = 480.0; @@ -9,27 +10,69 @@ const DARK_SLATE_BLUE: Color = Color::rgb(0.2823529, 0.2392157, 0.5450980); struct GameState { chess_board: Texture, + possible_move_square: Texture, dark_piece: Texture, light_piece: Texture, dark_king: Texture, light_king: Texture, bit_board: CheckersBitBoard, + selected_square: Option<SquareCoordinate>, + possible_moves: Vec<SquareCoordinate>, } impl GameState { fn new(ctx: &mut Context) -> tetra::Result<Self> { Ok(GameState { chess_board: Texture::new(ctx, "./ui/resources/chess_board.png")?, + possible_move_square: Texture::new(ctx, "./ui/resources/possible_move.png")?, dark_piece: Texture::new(ctx, "./ui/resources/red_piece.png")?, light_piece: Texture::new(ctx, "./ui/resources/white_piece.png")?, dark_king: Texture::new(ctx, "./ui/resources/red_king.png")?, light_king: Texture::new(ctx, "./ui/resources/white_king.png")?, bit_board: CheckersBitBoard::starting_position(), + selected_square: None, + possible_moves: Vec::new(), }) } } +impl GameState { + fn draw_highlighted_square(&self, ctx: &mut Context, square: SquareCoordinate) { + let square_draw_params = DrawParams::new() + .position(Vec2::new( + 120.0 + (50.0 * square.file() as f32), + 390.0 - (50.0 * square.rank() as f32), + )) + .scale(Vec2::new(0.5, 0.5)); + + self.possible_move_square.draw(ctx, square_draw_params); + } +} + impl State for GameState { + fn update(&mut self, ctx: &mut Context) -> tetra::Result { + if input::is_mouse_button_released(ctx, MouseButton::Left) { + let x = input::get_mouse_x(ctx); + let y = input::get_mouse_y(ctx); + + if x > 120.0 && y > 40.0 && x < 520.0 && y < 440.0 { + let file = ((x - 140.0) / 50.0).round(); + let rank = ((410.0 - y) / 50.0).round(); + let square = SquareCoordinate::new(rank as u8, file as u8); + self.selected_square = Some(square); + + let moves = PossibleMoves::moves(self.bit_board); + self.possible_moves = moves + .into_iter() + .filter(|m| SquareCoordinate::from_value(m.start() as usize) == square) + .map(|m| SquareCoordinate::from_value(m.end_position())) + .collect() + } + } + + Ok(()) + } + fn draw(&mut self, ctx: &mut Context) -> tetra::Result { graphics::clear(ctx, DARK_SLATE_BLUE); @@ -39,6 +82,14 @@ impl State for GameState { self.chess_board.draw(ctx, board_draw_params); + if let Some(square) = self.selected_square { + self.draw_highlighted_square(ctx, square); + } + + for square in &self.possible_moves { + self.draw_highlighted_square(ctx, *square); + } + for row in 0..8 { for col in 0..8 { if let Some(piece) = self.bit_board.get_at_row_col(row, col) { |
