diff --git a/src/logic/board/board.rs b/src/logic/board/board.rs index 45062d5..3919680 100644 --- a/src/logic/board/board.rs +++ b/src/logic/board/board.rs @@ -1,7 +1,7 @@ use crate::logic::{ board::{ field::Field, - pawn::{CapturePath, Pawn, PawnState}, + pawn::{CapturePath, MovePath, Pawn, PawnState}, }, math::{position::Position, vector::Vector2D}, player::Player, @@ -9,7 +9,7 @@ use crate::logic::{ use std::ops::{Index, IndexMut}; -use log::{debug, info, warn}; +use log::{debug, error, info, warn}; pub struct Board { board: Vec, @@ -125,12 +125,12 @@ impl Board { .is_some_and(|moves| !moves.is_empty()) } - fn get_available_moves(&self, pos: Position, player: &Player) -> Option> { - let mut available_moves: Vec = vec![]; + pub fn get_available_moves(&self, pos: Position, player: &Player) -> Option> { + let mut available_moves: Vec = vec![]; let mut possible_directions: Vec = vec![]; if !pos.is_in_range(self.size) { - debug!( + warn!( "get_possible_moves got a value: {} that was out of range!", pos ); @@ -142,7 +142,7 @@ impl Board { }; let Some(direction) = player.vertical_direction else { - debug!("Player: {} doesn't have a direction set!", player.id); + error!("Player: {} doesn't have a direction set!", player.id); return None; }; @@ -160,17 +160,30 @@ impl Board { } for direction in &possible_directions { + debug!("Checking direction {} for available moves", direction); + + let mut path: Vec = vec![]; for multiplier in 1..=max_multiplier { if let Some(new_pos) = pos.checked_add(&(*direction * multiplier)) { if self.is_position_empty(new_pos) { - available_moves.push(new_pos); + debug!("Found available move at: {}", new_pos); + path.push(new_pos); } else { + debug!("Position: {} wasn't empty!", new_pos); break; } } else { + debug!("Found position was out of bounds!"); break; } } + + if !path.is_empty() { + available_moves.push(MovePath { + from: pos, + available_steps: path, + }) + } } Some(available_moves) @@ -584,6 +597,40 @@ mod tests { assert!(test_board[2][1].pawn.is_none()); } + #[test] + fn test_getting_pawn_moves() { + init_logger(); + + let mut p1: Player = Player::new("Morbius".to_string()); + let mut p2: Player = Player::new("Milo".to_string()); + + let mut board: Board = Board::new_empty(&mut p1, &mut p2, None); + + board.place_pawn(Position { row: 0, column: 0 }, &p1); + board[0][0].pawn.as_mut().unwrap().state = PawnState::Dame; + + let result: Vec = board + .get_available_moves(Position { row: 0, column: 0 }, &p1) + .unwrap(); + + assert_eq!(result.len(), 1); + assert_eq!( + result[0], + MovePath { + from: Position { row: 0, column: 0 }, + available_steps: vec![ + Position { row: 1, column: 1 }, + Position { row: 2, column: 2 }, + Position { row: 3, column: 3 }, + Position { row: 4, column: 4 }, + Position { row: 5, column: 5 }, + Position { row: 6, column: 6 }, + Position { row: 7, column: 7 }, + ] + } + ); + } + #[test] fn test_getting_player_pawns_positions() { init_logger(); diff --git a/src/logic/board/pawn.rs b/src/logic/board/pawn.rs index f5e9db1..4ff18a8 100644 --- a/src/logic/board/pawn.rs +++ b/src/logic/board/pawn.rs @@ -38,3 +38,9 @@ impl CapturePath { self.steps.iter().zip(self.captured_enemies.iter()) } } + +#[derive(Debug, PartialEq, Eq)] +pub struct MovePath { + pub from: Position, + pub available_steps: Vec, +} diff --git a/src/logic/game_master.rs b/src/logic/game_master.rs index c79c760..2dc7117 100644 --- a/src/logic/game_master.rs +++ b/src/logic/game_master.rs @@ -1,5 +1,9 @@ use crate::logic::{ - board::{board::Board, pawn::CapturePath}, + board::{ + board::Board, + pawn::{CapturePath, MovePath}, + }, + math::position::Position, player::Player, }; @@ -53,4 +57,16 @@ impl GameMaster { .flatten() .collect() } + + pub fn get_current_player_moves(&self) -> Vec { + self.board + .get_player_pawns_positions(self.players.get_current_turn()) + .into_iter() + .filter_map(|pos| { + self.board + .get_available_moves(pos, self.players.get_current_turn()) + }) + .flatten() + .collect() + } }