diff --git a/store/src/board.rs b/store/src/board.rs index 82f14a4..6ad884a 100644 --- a/store/src/board.rs +++ b/store/src/board.rs @@ -384,6 +384,25 @@ impl Board { has_checker && !blocked } + /// Return if there is a quarter filled by the color + pub fn any_quarter_filled(&self, color: Color) -> bool { + [1, 7, 13, 19] + .iter() + .any(|field| self.is_quarter_filled(color, *field)) + } + + /// Return if the quarter containing `field` is filled by the `color` + pub fn is_quarter_filled(&self, color: Color, field: Field) -> bool { + let fields = self.get_quarter_fields(field); + !fields.iter().any(|field| { + if color == Color::White { + self.positions[field - 1] < 1 + } else { + self.positions[field - 1] > -1 + } + }) + } + /// 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.rs b/store/src/game.rs index d4afca2..776c4da 100644 --- a/store/src/game.rs +++ b/store/src/game.rs @@ -476,8 +476,11 @@ impl GameState { return false; } - // --- remplir cadran si possible ---- - // --- conserver cadran rempli si possible ---- + // --- remplir cadran si possible & conserver cadran rempli si possible ---- + let filling_moves_sequences = self.get_quarter_filling_moves_sequences(color); + if !filling_moves_sequences.contains(moves) && !filling_moves_sequences.is_empty() { + return false; + } // no rule was broken true } @@ -490,6 +493,22 @@ impl GameState { moves_seqs } + fn get_quarter_filling_moves_sequences( + &self, + color: &Color, + ) -> Vec<(CheckerMove, CheckerMove)> { + let mut moves_seqs = Vec::new(); + for moves in self.get_possible_moves_sequences(color) { + let mut board = self.board.clone(); + board.move_checker(color, moves.0).unwrap(); + board.move_checker(color, moves.1).unwrap(); + if board.any_quarter_filled(*color) { + moves_seqs.push(moves); + } + } + moves_seqs + } + fn get_possible_moves_sequences_by_dices( &self, color: &Color, @@ -993,7 +1012,7 @@ mod tests { } #[test] - fn move_check_fillable_quarter() { + fn move_check_oponnent_fillable_quarter() { let mut state = GameState::default(); state.board.set_positions([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, @@ -1015,4 +1034,38 @@ mod tests { ); assert!(!state.moves_allowed(&Color::White, &moves)); } + + #[test] + fn move_check_fillable_quarter() { + let mut state = GameState::default(); + state.board.set_positions([ + 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, + ]); + state.dice.values = (5, 4); + let moves = ( + CheckerMove::new(1, 6).unwrap(), + CheckerMove::new(2, 6).unwrap(), + ); + assert!(state.moves_allowed(&Color::White, &moves)); + let moves = ( + CheckerMove::new(1, 5).unwrap(), + CheckerMove::new(2, 7).unwrap(), + ); + assert!(!state.moves_allowed(&Color::White, &moves)); + + state.board.set_positions([ + 2, 3, 2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]); + state.dice.values = (2, 3); + let moves = ( + CheckerMove::new(6, 8).unwrap(), + CheckerMove::new(6, 9).unwrap(), + ); + assert!(!state.moves_allowed(&Color::White, &moves)); + let moves = ( + CheckerMove::new(2, 4).unwrap(), + CheckerMove::new(5, 8).unwrap(), + ); + assert!(state.moves_allowed(&Color::White, &moves)); + } }