diff --git a/store/src/game_rules_points.rs b/store/src/game_rules_points.rs index 4be14c3..c1bfdf4 100644 --- a/store/src/game_rules_points.rs +++ b/store/src/game_rules_points.rs @@ -12,6 +12,7 @@ enum Jan { FilledQuarter, TrueHitSmallJan, TrueHitBigJan, + TrueHitOpponentCorner, // jans de récompense : // - battre une dame seule (par autant de façons de le faire, y compris // utilisant une dame du coin de repos) @@ -44,9 +45,13 @@ impl Jan { } // « JAN DE RÉCOMPENSE » - // Battre à vrai une dame située dans la table des grands jans 2 | 4 1, 2 ou 3 (sauf doublet) Joueur - // Battre à vrai une dame située dans la table des petits jans 4 | 6 1, 2 ou 3 Joueur - // Battre le coin adverse 4 6 1 Joueur + // Battre à vrai une dame située dans la table des grands jans (2 par simple, 4 par double) + // Battre à vrai une dame située dans la table des petits jans (4 par simple, 6 par double) + // Battre le coin adverse (4 par simple, 6 par double) + + // « JAN DE REMPLISSAGE » + // Faire un petit jan, un grand jan ou un jan de retour (4 par simple, 6 par double) + // Conserver un petit jan, un grand jan ou un jan de retour (4 par simple, 6 par double) } type PossibleJans = HashMap>; @@ -121,10 +126,40 @@ impl PointsRules { // « JAN DE RÉCOMPENSE » // Battre à vrai une dame située dans la table des grands jans // Battre à vrai une dame située dans la table des petits jans - let mut jans = self.get_jans_by_dice_order(board_ini, dices); - let jans_revert_dices = self.get_jans_by_dice_order(board_ini, dices_reversed); + let mut jans = self.get_jans_by_ordered_dice(board_ini, dices); + let jans_revert_dices = self.get_jans_by_ordered_dice(board_ini, dices_reversed); jans.merge(jans_revert_dices); + // Battre à vrai le coin de repos de l'adversaire + let corner_field = board_ini.get_color_corner(&Color::White); + let adv_corner_field = board_ini.get_color_corner(&Color::Black); + let (adv_corner_count, _color) = board_ini.get_field_checkers(adv_corner_field).unwrap(); + if adv_corner_count == 0 { + let from0 = adv_corner_field - self.dice.values.0 as usize; + let from1 = adv_corner_field - self.dice.values.1 as usize; + + let (from0_count, from0_color) = board_ini.get_field_checkers(from0).unwrap(); + let (from1_count, from1_color) = board_ini.get_field_checkers(from1).unwrap(); + let hit_moves = vec![( + CheckerMove::new(from0, adv_corner_field).unwrap(), + CheckerMove::new(from1, adv_corner_field).unwrap(), + )]; + + if from0 == from1 { + // doublet + if from0_count > if from0 == corner_field { 3 } else { 0 } { + jans.insert(Jan::TrueHitOpponentCorner, hit_moves); + } + } else { + // simple + if from0_count > if from0 == corner_field { 2 } else { 0 } + && from1_count > if from1 == corner_field { 2 } else { 0 } + { + jans.insert(Jan::TrueHitOpponentCorner, hit_moves); + } + } + } + // « JAN DE REMPLISSAGE » // Faire un petit jan, un grand jan ou un jan de retour let filling_moves_sequences = self @@ -137,7 +172,7 @@ impl PointsRules { jans } - fn get_jans_by_dice_order(&self, board_ini: &Board, dices: &Vec) -> PossibleJans { + fn get_jans_by_ordered_dice(&self, board_ini: &Board, dices: &Vec) -> PossibleJans { let mut jans = PossibleJans::default(); let mut dices = dices.clone(); if let Some(dice) = dices.pop() { @@ -159,7 +194,7 @@ impl PointsRules { // repos : // - on ne va pas sur le coin de l'adversaire // - ni sur son propre coin de repos avec une seule dame - // - règle non prise en compte pour le battage des dames : on ne sort pas de son coin de repos s'il ni reste que deux dames + // - règle non prise en compte pour le battage des dames : on ne sort pas de son coin de repos s'il n'y reste que deux dames let (corner_count, _color) = board.get_field_checkers(corner_field).unwrap(); if to != adv_corner_field && (to != corner_field || corner_count > 1) // && (from != corner_field || corner_count > 2) @@ -190,7 +225,7 @@ impl PointsRules { // Try tout d'une : // - use original board before first die move // - use a virtual dice by adding current dice to remaining dice - let next_dice_jan = self.get_jans_by_dice_order( + let next_dice_jan = self.get_jans_by_ordered_dice( &board_ini, &dices.iter().map(|d| d + dice).collect(), ); @@ -198,17 +233,12 @@ impl PointsRules { } } // Second die - let next_dice_jan = self.get_jans_by_dice_order(&board_ini, &dices); + let next_dice_jan = self.get_jans_by_ordered_dice(&board_ini, &dices); jans.merge(next_dice_jan); } } } - // TODO : mouvements en tout d'une asdf - // - faire un dé d1+d2 et regarder si hit - // - si hit : regarder s'il existe le truehit intermédiaire - // - regarder les TrueHit qui nécessitent deux mouvemments non nuls - // TODO : tout d'une (sans doublons avec 1 + 1) ? jans } @@ -218,9 +248,10 @@ impl PointsRules { // « JAN DE RÉCOMPENSE » // Battre à vrai une dame située dans la table des grands jans // Battre à vrai une dame située dans la table des petits jans - // TODO : Battre le coin adverse + // Battre le coin adverse let jans = self.get_jans(&self.board); points += jans.into_iter().fold(0, |acc: i8, (jan, moves)| { + println!("get_points : {:?}", jan); acc + jan.get_points(self.dice.is_double()) * (moves.len() as i8) }); @@ -261,11 +292,11 @@ mod tests { 2, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let jans = rules.get_jans_by_dice_order(&rules.board, &vec![2, 3]); + let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]); assert_eq!(1, jans.len()); assert_eq!(3, jans.get(&Jan::TrueHitSmallJan).unwrap().len()); - let jans = rules.get_jans_by_dice_order(&rules.board, &vec![2, 2]); + let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 2]); assert_eq!(1, jans.len()); assert_eq!(1, jans.get(&Jan::TrueHitSmallJan).unwrap().len()); @@ -275,8 +306,8 @@ mod tests { 2, 0, -1, -2, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let mut jans = rules.get_jans_by_dice_order(&rules.board, &vec![2, 3]); - let jans_revert_dices = rules.get_jans_by_dice_order(&rules.board, &vec![3, 2]); + let mut jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]); + let jans_revert_dices = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 2]); assert_eq!(1, jans.len()); assert_eq!(1, jans_revert_dices.len()); jans.merge(jans_revert_dices); @@ -286,7 +317,7 @@ mod tests { 2, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let jans = rules.get_jans_by_dice_order(&rules.board, &vec![2, 3]); + let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]); assert_eq!(1, jans.len()); assert_eq!(2, jans.get(&Jan::TrueHitSmallJan).unwrap().len()); @@ -294,7 +325,7 @@ mod tests { 2, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let jans = rules.get_jans_by_dice_order(&rules.board, &vec![2, 3]); + let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]); assert_eq!(1, jans.len()); assert_eq!(1, jans.get(&Jan::TrueHitSmallJan).unwrap().len()); @@ -302,7 +333,7 @@ mod tests { 2, 0, 1, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let jans = rules.get_jans_by_dice_order(&rules.board, &vec![2, 3]); + let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]); assert_eq!(1, jans.len()); assert_eq!(3, jans.get(&Jan::TrueHitSmallJan).unwrap().len()); @@ -313,7 +344,7 @@ mod tests { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); // le premier dé traité est le dernier du vecteur : 1 - let jans = rules.get_jans_by_dice_order(&rules.board, &vec![2, 1]); + let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 1]); // println!("jans (dés bloqués) : {:?}", jans.get(&Jan::TrueHit)); assert_eq!(0, jans.len()); @@ -321,15 +352,15 @@ mod tests { rules.board.set_positions([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let mut jans = rules.get_jans_by_dice_order(&rules.board, &vec![3, 3]); + let mut jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 3]); assert_eq!(1, jans.len()); // premier dé bloqué, mais tout d'une possible en commençant par le second rules.board.set_positions([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let mut jans = rules.get_jans_by_dice_order(&rules.board, &vec![3, 1]); - let jans_revert_dices = rules.get_jans_by_dice_order(&rules.board, &vec![1, 3]); + let mut jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 1]); + let jans_revert_dices = rules.get_jans_by_ordered_dice(&rules.board, &vec![1, 3]); assert_eq!(1, jans_revert_dices.len()); jans.merge(jans_revert_dices); @@ -343,6 +374,7 @@ mod tests { #[test] fn get_points() { // ----- Jan de récompense + // Battre à vrai une dame située dans la table des petits jans : 4 + 4 + 4 = 12 let mut rules = PointsRules::default(); rules.update_positions([ 2, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -350,7 +382,30 @@ mod tests { rules.set_dice(Dice { values: (2, 3) }); assert_eq!(12, rules.get_points()); + // Battre à vrai une dame située dans la table des grands jans : 2 + 2 = 4 + let mut rules = PointsRules::default(); + rules.update_positions([ + 2, 0, 0, -1, 2, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]); + rules.set_dice(Dice { values: (2, 4) }); + assert_eq!(4, rules.get_points()); + + // Battre à vrai le coin adverse par doublet : 6 + rules.update_positions([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]); + rules.set_dice(Dice { values: (2, 2) }); + assert_eq!(6, rules.get_points()); + + // Cas de battage du coin de repos adverse impossible + rules.update_positions([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]); + rules.set_dice(Dice { values: (1, 1) }); + assert_eq!(0, rules.get_points()); + // ---- Jan de remplissage + // Faire un petit jan : 4 rules.update_positions([ 3, 1, 2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); @@ -358,19 +413,21 @@ mod tests { assert_eq!(1, rules.get_jans(&rules.board).len()); assert_eq!(4, rules.get_points()); + // Faire un petit jan avec un doublet : 6 rules.update_positions([ 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); rules.set_dice(Dice { values: (1, 1) }); assert_eq!(6, rules.get_points()); + // Faire un petit jan avec 2 moyens : 6 + 6 = 12 rules.update_positions([ 3, 3, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); rules.set_dice(Dice { values: (1, 1) }); assert_eq!(12, rules.get_points()); - // conservation jan rempli + // Conserver un jan avec un doublet : 6 rules.update_positions([ 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]);