feat: add moving pawn to game_master and add tests

This commit is contained in:
2026-08-14 16:48:51 +02:00
parent b031d4894a
commit b1b82cc1e5
4 changed files with 165 additions and 5 deletions

View File

@@ -186,7 +186,11 @@ impl Board {
}
}
Some(available_moves)
if available_moves.is_empty() {
None
} else {
Some(available_moves)
}
}
fn can_capture(
@@ -197,19 +201,30 @@ impl Board {
already_captured: &Vec<Position>,
pawn: &Pawn,
) -> bool {
debug!("=== Checkinf if pawn can capture from: {} to {}", from, to);
if !self.is_player_owner_of_the_pawn(player, &pawn) {
debug!("Player wasn't owner of the pawn...");
return false;
}
if !to.is_in_range(self.size) {
debug!("Position was out of range...");
return false;
}
if already_captured.contains(&to) {
debug!("Pawn was already captured...");
return false;
}
let Some(captured_pawn) = &self[to].pawn else {
debug!("There was no pawn there...");
return false;
};
if self.is_player_owner_of_the_pawn(player, captured_pawn) {
debug!("Player tried capturing his own pawn! Idiot");
return false;
}
@@ -336,11 +351,13 @@ impl Board {
Some(available_captures)
}
pub fn capture(&mut self, path: &CapturePath, capturing_player: &Player) {
pub fn capture(&mut self, path: &CapturePath, capturing_player: &Player) -> bool {
/*
debug!("Capturing: {}", path);
*/
// TODO! Maybe return false ??
let mut from = path.from;
for (next_pos, enemy_path) in path.iter() {
@@ -348,6 +365,8 @@ impl Board {
self.move_pawn_anywhere(capturing_player, from, *next_pos);
from = *next_pos;
}
true
}
pub fn get_player_pawns_positions(&self, player: &Player) -> Vec<Position> {

View File

@@ -1,8 +1,11 @@
use log::warn;
use crate::logic::{
board::{
board::Board,
pawn::{CapturePath, MovePath},
},
math::position::Position,
player::Player,
};
@@ -82,9 +85,10 @@ impl GameMaster {
let player_pawns = self.board.get_player_pawns_positions(player);
player_pawns.len() == 0
|| player_pawns
.iter()
.all(|pos| self.board.get_available_moves(*pos, player).is_none())
|| player_pawns.iter().all(|pos| {
self.board.get_available_moves(*pos, player).is_none()
&& self.board.get_available_captures(*pos, player).is_none()
})
}
pub fn get_game_result(&self) -> Option<GameResult> {
@@ -104,4 +108,101 @@ impl GameMaster {
None
}
}
pub fn move_pawn(&mut self, from: Position, to: Position) -> bool {
if self.get_current_player_moves().is_empty() {
warn!(
"Player: {} tried moving, but they don't have any moves available!",
self.players.get_current_turn().id
);
return false;
}
if !self.get_current_player_captures().is_empty() {
warn!(
"Player: {} tried moving, but he has captures available!",
self.players.get_current_turn().id
);
return false;
}
if self
.board
.move_pawn(self.players.get_current_turn(), from, to)
{
self.players.change_turn();
return true;
}
false
}
pub fn capture(&mut self, path: &CapturePath) -> bool {
if self.get_current_player_captures().is_empty() {
warn!(
"Player: {} tried capturing, but he doesn't have any captures available!",
self.players.get_current_turn().id
);
return false;
}
if self.board.capture(path, self.players.get_current_turn()) {
self.players.change_turn();
return true;
}
false
}
}
#[cfg(test)]
mod tests {
use super::*;
use log::info;
use rand::seq::IndexedMutRandom;
use rand::seq::IndexedRandom;
use rand::seq::SliceRandom;
#[test]
fn test_game_flow() {
let mut master: GameMaster = GameMaster::new("Morbius".to_string(), "Milo".to_string());
let mut turns = 0;
let max_turns = 2000;
while turns < max_turns {
if let Some(result) = master.get_game_result() {
match result {
GameResult::Lost(loser_id) => {
info!("Player: {} lost! Ending the loop", loser_id);
}
GameResult::Draw => {
info!("Game ended in a draw! Ending the loop");
}
}
break;
}
let mut rng = rand::rng();
let available_captures = master.get_current_player_captures();
if !available_captures.is_empty() {
let capture = available_captures.choose(&mut rng).unwrap();
master.capture(capture);
turns += 1;
continue;
}
let mut available_moves = master.get_current_player_moves();
if !available_moves.is_empty() {
let path = available_moves.choose_mut(&mut rng).unwrap();
let from = path.from;
let to = path.available_steps.choose_mut(&mut rng).unwrap();
master.move_pawn(from, *to);
turns += 1;
}
}
assert!(turns < max_turns);
}
}