From 3c3c6d8458d1ae4300d8365324b5f76390ac1767 Mon Sep 17 00:00:00 2001 From: Henri Bourcereau Date: Sat, 18 May 2024 21:46:26 +0200 Subject: [PATCH] moves allowed : check if opponent corner can be filled #2 --- doc/refs/tutorial_academieDesJeux.md | 2 +- store/src/board.rs | 10 +++++++ store/src/game.rs | 45 +++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/doc/refs/tutorial_academieDesJeux.md b/doc/refs/tutorial_academieDesJeux.md index d34fadb..10317f6 100644 --- a/doc/refs/tutorial_academieDesJeux.md +++ b/doc/refs/tutorial_academieDesJeux.md @@ -37,7 +37,7 @@ Si on peut remplir le coin de l'adversaire avec deux dames (ce qui est interdit) Si on a le choix entre remplir son coin directement ou par puissance, on doit obligatoirement le faire directement. -Tant que l'adversaire à la possibilité de remplir un cadran, on ne peut pas jouer dans ce cadran. +Tant que l'adversaire à la possibilité de remplir un des deux cadrans de son côté (son jeu "ordinaire", par opposition au jeu "de retour"), on ne peut pas jouer dans ce cadran. Quand on joue dans ses propres deux cadrans, on dit qu'on joue le jeu ordinaire Quand on joue dans les deux cadrans de l'adversaire, on dit qu'on joue le jeu de retour diff --git a/store/src/board.rs b/store/src/board.rs index 13cbd6c..82f14a4 100644 --- a/store/src/board.rs +++ b/store/src/board.rs @@ -103,6 +103,9 @@ impl Board { } pub fn count_checkers(&self, color: Color, from: Field, to: Field) -> u8 { + if to == 0 || from == 0 { + return 0; + } self.positions[(from - 1)..to] .iter() .filter(|count| { @@ -421,6 +424,9 @@ impl Board { /// Returns the 6 fields of the quarter containing the `field` fn get_quarter_fields(&self, field: Field) -> [Field; 6] { + if field == 0 { + return [0; 6]; + } let min = 1 + ((field - 1) / 6) * 6; core::array::from_fn(|i| i + min) } @@ -548,5 +554,9 @@ mod tests { assert!(!board.is_quarter_fillable(Color::Black, 24)); assert!(!board.is_quarter_fillable(Color::White, 1)); assert!(board.is_quarter_fillable(Color::White, 12)); + board.set_positions([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, -12, 0, 0, 0, 0, 1, 0, + ]); + assert!(board.is_quarter_fillable(Color::Black, 16)); } } diff --git a/store/src/game.rs b/store/src/game.rs index 15c332e..d4afca2 100644 --- a/store/src/game.rs +++ b/store/src/game.rs @@ -456,9 +456,28 @@ impl GameState { } } + // --- interdit de jouer dans cadran que l'adversaire peut encore remplir ---- + let farthest = if *color == Color::White { + cmp::max(moves.0.get_to(), moves.1.get_to()) + } else { + cmp::min(moves.0.get_to(), moves.1.get_to()) + }; + let in_opponent_side = if *color == Color::White { + farthest > 12 + } else { + farthest < 13 + }; + + if in_opponent_side + && self + .board + .is_quarter_fillable(color.opponent_color(), farthest) + { + return false; + } + // --- remplir cadran si possible ---- // --- conserver cadran rempli si possible ---- - // --- interdit de jouer dans cadran que l'adversaire peut encore remplir ---- // no rule was broken true } @@ -972,4 +991,28 @@ mod tests { assert!(state.moves_follows_dices(&Color::White, &moves)); assert!(state.moves_allowed(&Color::White, &moves)); } + + #[test] + fn move_check_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, + ]); + state.dice.values = (5, 5); + let moves = ( + CheckerMove::new(11, 16).unwrap(), + CheckerMove::new(11, 16).unwrap(), + ); + assert!(state.moves_allowed(&Color::White, &moves)); + + state.board.set_positions([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, -12, 0, 0, 0, 0, 1, 0, + ]); + state.dice.values = (5, 5); + let moves = ( + CheckerMove::new(11, 16).unwrap(), + CheckerMove::new(11, 16).unwrap(), + ); + assert!(!state.moves_allowed(&Color::White, &moves)); + } }