wip fix allowed moves infinite loop
This commit is contained in:
parent
38100a61b2
commit
2a67996453
|
|
@ -33,6 +33,13 @@ pub enum MoveError {
|
||||||
MustPlayStrongerDie,
|
MustPlayStrongerDie,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(std::cmp::PartialEq, Debug)]
|
||||||
|
pub enum TricTracRule {
|
||||||
|
ExitRule,
|
||||||
|
MustFillQuarterRule,
|
||||||
|
CornerRule,
|
||||||
|
}
|
||||||
|
|
||||||
/// MoveRules always consider that the current player is White
|
/// MoveRules always consider that the current player is White
|
||||||
/// You must use 'mirror' functions on board & CheckerMoves if player is Black
|
/// You must use 'mirror' functions on board & CheckerMoves if player is Black
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -62,12 +69,16 @@ impl MoveRules {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn moves_follow_rules(&self, moves: &(CheckerMove, CheckerMove)) -> bool {
|
pub fn moves_follow_rules(
|
||||||
|
&self,
|
||||||
|
moves: &(CheckerMove, CheckerMove),
|
||||||
|
ignored_rules: Vec<TricTracRule>,
|
||||||
|
) -> bool {
|
||||||
// Check moves possibles on the board
|
// Check moves possibles on the board
|
||||||
// Check moves conforms to the dice
|
// Check moves conforms to the dice
|
||||||
// Check move is allowed by the rules (to desactivate when playing with schools)
|
// Check move is allowed by the rules (to desactivate when playing with schools)
|
||||||
self.moves_possible(moves) && self.moves_follows_dices(moves) && {
|
self.moves_possible(moves) && self.moves_follows_dices(moves) && {
|
||||||
let is_allowed = self.moves_allowed(moves);
|
let is_allowed = self.moves_allowed(moves, ignored_rules);
|
||||||
if is_allowed.is_err() {
|
if is_allowed.is_err() {
|
||||||
info!("Move not allowed : {:?}", is_allowed.unwrap_err());
|
info!("Move not allowed : {:?}", is_allowed.unwrap_err());
|
||||||
false
|
false
|
||||||
|
|
@ -165,7 +176,11 @@ impl MoveRules {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ---- moves_allowed : Third of three checks for moves
|
/// ---- moves_allowed : Third of three checks for moves
|
||||||
pub fn moves_allowed(&self, moves: &(CheckerMove, CheckerMove)) -> Result<(), MoveError> {
|
pub fn moves_allowed(
|
||||||
|
&self,
|
||||||
|
moves: &(CheckerMove, CheckerMove),
|
||||||
|
ignored_rules: Vec<TricTracRule>,
|
||||||
|
) -> Result<(), MoveError> {
|
||||||
self.check_corner_rules(moves)?;
|
self.check_corner_rules(moves)?;
|
||||||
|
|
||||||
if self.is_move_by_puissance(moves) {
|
if self.is_move_by_puissance(moves) {
|
||||||
|
|
@ -197,7 +212,9 @@ impl MoveRules {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check exit rules
|
// check exit rules
|
||||||
self.check_exit_rules(moves)?;
|
if !ignored_rules.contains(&TricTracRule::ExitRule) {
|
||||||
|
self.check_exit_rules(moves)?;
|
||||||
|
}
|
||||||
|
|
||||||
// --- interdit de jouer dans un cadran que l'adversaire peut encore remplir ----
|
// --- interdit de jouer dans un cadran que l'adversaire peut encore remplir ----
|
||||||
let farthest = cmp::max(moves.0.get_to(), moves.1.get_to());
|
let farthest = cmp::max(moves.0.get_to(), moves.1.get_to());
|
||||||
|
|
@ -267,49 +284,50 @@ impl MoveRules {
|
||||||
}
|
}
|
||||||
|
|
||||||
// toutes les sorties directes sont autorisées, ainsi que les nombres défaillants
|
// toutes les sorties directes sont autorisées, ainsi que les nombres défaillants
|
||||||
let possible_moves_sequences = self.get_possible_moves_sequences(false);
|
let possible_moves_sequences_without_excedent = self.get_possible_moves_sequences(false);
|
||||||
if !possible_moves_sequences.contains(moves) {
|
if possible_moves_sequences_without_excedent.contains(moves) {
|
||||||
// À ce stade au moins un des déplacements concerne un nombre en excédant
|
return Ok(());
|
||||||
// - si d'autres séquences de mouvements sans nombre en excédant étaient possibles, on
|
}
|
||||||
// refuse cette séquence
|
// À ce stade au moins un des déplacements concerne un nombre en excédant
|
||||||
if !possible_moves_sequences.is_empty() {
|
// - si d'autres séquences de mouvements sans nombre en excédant sont possibles, on
|
||||||
return Err(MoveError::ExitByEffectPossible);
|
// refuse cette séquence
|
||||||
}
|
if !possible_moves_sequences_without_excedent.is_empty() {
|
||||||
|
return Err(MoveError::ExitByEffectPossible);
|
||||||
|
}
|
||||||
|
|
||||||
// - la dame choisie doit être la plus éloignée de la sortie
|
// - la dame choisie doit être la plus éloignée de la sortie
|
||||||
let mut checkers = self.board.get_color_fields(Color::White);
|
let mut checkers = self.board.get_color_fields(Color::White);
|
||||||
checkers.sort_by(|a, b| b.0.cmp(&a.0));
|
checkers.sort_by(|a, b| b.0.cmp(&a.0));
|
||||||
let mut farthest = 24;
|
let mut farthest = 24;
|
||||||
let mut next_farthest = 24;
|
let mut next_farthest = 24;
|
||||||
let mut has_two_checkers = false;
|
let mut has_two_checkers = false;
|
||||||
if let Some((field, count)) = checkers.first() {
|
if let Some((field, count)) = checkers.first() {
|
||||||
farthest = *field;
|
farthest = *field;
|
||||||
if *count > 1 {
|
if *count > 1 {
|
||||||
next_farthest = *field;
|
next_farthest = *field;
|
||||||
has_two_checkers = true;
|
has_two_checkers = true;
|
||||||
} else if let Some((field, _count)) = checkers.get(1) {
|
} else if let Some((field, _count)) = checkers.get(1) {
|
||||||
next_farthest = *field;
|
next_farthest = *field;
|
||||||
has_two_checkers = true;
|
has_two_checkers = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// s'il reste au moins deux dames, on vérifie que les plus éloignées soint choisies
|
||||||
|
if has_two_checkers {
|
||||||
|
if moves.0.get_to() == 0 && moves.1.get_to() == 0 {
|
||||||
|
// Deux coups sortants en excédant
|
||||||
|
if cmp::max(moves.0.get_from(), moves.1.get_from()) > next_farthest {
|
||||||
|
return Err(MoveError::ExitNotFasthest);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
// Un seul coup sortant en excédant le coup sortant doit concerner la plus éloignée du bord
|
||||||
// s'il reste au moins deux dames, on vérifie que les plus éloignées soint choisies
|
let exit_move_field = if moves.0.get_to() == 0 {
|
||||||
if has_two_checkers {
|
moves.0.get_from()
|
||||||
if moves.0.get_to() == 0 && moves.1.get_to() == 0 {
|
|
||||||
// Deux coups sortants en excédant
|
|
||||||
if cmp::max(moves.0.get_from(), moves.1.get_from()) > next_farthest {
|
|
||||||
return Err(MoveError::ExitNotFasthest);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Un seul coup sortant en excédant le coup sortant doit concerner la plus éloignée du bord
|
moves.1.get_from()
|
||||||
let exit_move_field = if moves.0.get_to() == 0 {
|
};
|
||||||
moves.0.get_from()
|
if exit_move_field != farthest {
|
||||||
} else {
|
return Err(MoveError::ExitNotFasthest);
|
||||||
moves.1.get_from()
|
|
||||||
};
|
|
||||||
if exit_move_field != farthest {
|
|
||||||
return Err(MoveError::ExitNotFasthest);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue