feat: implement get_current_player_moves for game_master and move_path struct

This commit is contained in:
2026-08-14 13:40:25 +02:00
parent 96c7ca73bf
commit d6fa72ae38
3 changed files with 77 additions and 8 deletions

View File

@@ -1,7 +1,7 @@
use crate::logic::{ use crate::logic::{
board::{ board::{
field::Field, field::Field,
pawn::{CapturePath, Pawn, PawnState}, pawn::{CapturePath, MovePath, Pawn, PawnState},
}, },
math::{position::Position, vector::Vector2D}, math::{position::Position, vector::Vector2D},
player::Player, player::Player,
@@ -9,7 +9,7 @@ use crate::logic::{
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use log::{debug, info, warn}; use log::{debug, error, info, warn};
pub struct Board { pub struct Board {
board: Vec<Field>, board: Vec<Field>,
@@ -125,12 +125,12 @@ impl Board {
.is_some_and(|moves| !moves.is_empty()) .is_some_and(|moves| !moves.is_empty())
} }
fn get_available_moves(&self, pos: Position, player: &Player) -> Option<Vec<Position>> { pub fn get_available_moves(&self, pos: Position, player: &Player) -> Option<Vec<MovePath>> {
let mut available_moves: Vec<Position> = vec![]; let mut available_moves: Vec<MovePath> = vec![];
let mut possible_directions: Vec<Vector2D> = vec![]; let mut possible_directions: Vec<Vector2D> = vec![];
if !pos.is_in_range(self.size) { if !pos.is_in_range(self.size) {
debug!( warn!(
"get_possible_moves got a value: {} that was out of range!", "get_possible_moves got a value: {} that was out of range!",
pos pos
); );
@@ -142,7 +142,7 @@ impl Board {
}; };
let Some(direction) = player.vertical_direction else { 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; return None;
}; };
@@ -160,17 +160,30 @@ impl Board {
} }
for direction in &possible_directions { for direction in &possible_directions {
debug!("Checking direction {} for available moves", direction);
let mut path: Vec<Position> = vec![];
for multiplier in 1..=max_multiplier { for multiplier in 1..=max_multiplier {
if let Some(new_pos) = pos.checked_add(&(*direction * multiplier)) { if let Some(new_pos) = pos.checked_add(&(*direction * multiplier)) {
if self.is_position_empty(new_pos) { if self.is_position_empty(new_pos) {
available_moves.push(new_pos); debug!("Found available move at: {}", new_pos);
path.push(new_pos);
} else { } else {
debug!("Position: {} wasn't empty!", new_pos);
break; break;
} }
} else { } else {
debug!("Found position was out of bounds!");
break; break;
} }
} }
if !path.is_empty() {
available_moves.push(MovePath {
from: pos,
available_steps: path,
})
}
} }
Some(available_moves) Some(available_moves)
@@ -584,6 +597,40 @@ mod tests {
assert!(test_board[2][1].pawn.is_none()); 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<MovePath> = 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] #[test]
fn test_getting_player_pawns_positions() { fn test_getting_player_pawns_positions() {
init_logger(); init_logger();

View File

@@ -38,3 +38,9 @@ impl CapturePath {
self.steps.iter().zip(self.captured_enemies.iter()) self.steps.iter().zip(self.captured_enemies.iter())
} }
} }
#[derive(Debug, PartialEq, Eq)]
pub struct MovePath {
pub from: Position,
pub available_steps: Vec<Position>,
}

View File

@@ -1,5 +1,9 @@
use crate::logic::{ use crate::logic::{
board::{board::Board, pawn::CapturePath}, board::{
board::Board,
pawn::{CapturePath, MovePath},
},
math::position::Position,
player::Player, player::Player,
}; };
@@ -53,4 +57,16 @@ impl GameMaster {
.flatten() .flatten()
.collect() .collect()
} }
pub fn get_current_player_moves(&self) -> Vec<MovePath> {
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()
}
} }