From bc1bf1066d0f1e0e854d62bbd79c756aab1fa19b Mon Sep 17 00:00:00 2001 From: Henri Bourcereau Date: Sat, 29 Jun 2024 17:49:30 +0200 Subject: [PATCH] wip --- store/src/board.rs | 38 ++++++++++++++++++++++++++ store/src/game_rules_moves.rs | 50 +++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/store/src/board.rs b/store/src/board.rs index d077492..7156332 100644 --- a/store/src/board.rs +++ b/store/src/board.rs @@ -453,6 +453,44 @@ impl Board { }) } + pub fn get_quarter_filling_candidate(&self, color: Color) -> Vec { + let mut missing = vec![]; + // first quarter + for quarter in [1..7, 7..13, 13..19, 19..25] { + missing = vec![]; + for field in quarter { + let field_count = if color == Color::Black { + 0 - self.positions[field - 1] + } else { + self.positions[field - 1] + }; + if field_count < 0 { + // opponent checker found : this quarter cannot be filled + missing = vec![]; + continue; + } + if field_count == 0 { + missing.push(field); + missing.push(field); + } else if field_count == 1 { + missing.push(field); + } + } + if missing.len() < 3 { + // fillable quarter found (no more than two missing checkers) + if let Some(field) = missing.first() { + // We check that there are sufficient checkers left to fill the quarter + if !self.is_quarter_fillable(color, *field) { + missing = vec![]; + } + } + // there will be no other fillable quarter + break; + } + } + missing + } + /// Returns whether the `color` player can still fill the quarter containing the `field` /// * `color` - color of the player /// * `field` - field belonging to the quarter diff --git a/store/src/game_rules_moves.rs b/store/src/game_rules_moves.rs index ce5f326..80be319 100644 --- a/store/src/game_rules_moves.rs +++ b/store/src/game_rules_moves.rs @@ -313,6 +313,56 @@ impl MoveRules { moves_seqs } + pub fn get_scoring_quarter_filling_moves_sequences(&self) -> Vec<(CheckerMove, CheckerMove)> { + let all_seqs = self.get_quarter_filling_moves_sequences(); + if all_seqs.len() == 0 { + return vec![]; + } + let missing_fields = self.board.get_quarter_filling_candidate(Color::White); + match missing_fields.len() { + // preserve an already filled quarter : return one sequence + 0 => vec![*all_seqs.last().unwrap()], + // two fields, two dices : all_seqs should already contain only one possibility + 2 => all_seqs, + 1 => { + let dest_field = missing_fields.first().unwrap(); + let mut filling_moves_origins = vec![]; + all_seqs.iter().fold(vec![], |mut acc, seq| { + let origins = self.get_sequence_origin_from_destination(*seq, *dest_field); + for origin in origins { + if !filling_moves_origins.contains(&origin) { + filling_moves_origins.push(origin); + acc.push(*seq); + } + } + acc + }) + } + _ => vec![], // cannot be + } + } + + fn get_sequence_origin_from_destination( + &self, + sequence: (CheckerMove, CheckerMove), + destination: Field, + ) -> Vec { + let mut origin = vec![]; + if sequence.0.get_to() == destination { + origin.push(sequence.0.get_from()); + } + if sequence.1.get_to() == destination { + if sequence.0.get_to() == sequence.1.get_from() { + // tout d'une + origin.push(sequence.0.get_from()); + } else { + origin.push(sequence.1.get_from()); + } + } + origin + } + + // Get all moves filling a quarter or preserving a filled quarter pub fn get_quarter_filling_moves_sequences(&self) -> Vec<(CheckerMove, CheckerMove)> { let mut moves_seqs = Vec::new(); let color = &Color::White;