fix check quarter (wip)

This commit is contained in:
Henri Bourcereau 2026-03-05 17:50:08 +01:00
parent de414ebebb
commit 24a6a90fe5

View file

@ -364,6 +364,8 @@ impl MoveRules {
let mut farthest = 24;
let mut next_farthest = 24;
let mut has_two_checkers = false;
// Do we need to recalculate farthest after first move ?
let mut first_move_change_farthest = true;
if has_filled_quarter {
// When a quarter is filled, we can only exit from fields with >2 checkers
@ -377,6 +379,7 @@ impl MoveRules {
if available_checkers[0].1 > 3 {
next_farthest = available_checkers[0].0;
has_two_checkers = true;
first_move_change_farthest = false;
} else if available_checkers.len() > 1 {
next_farthest = available_checkers[1].0;
has_two_checkers = true;
@ -416,14 +419,19 @@ impl MoveRules {
if cmp::max(moves.0.get_from(), moves.1.get_from()) > next_farthest {
return Err(MoveError::ExitNotFarthest);
}
} else if moves.0.get_to() == 0 {
// Seul le premier coup est un coup sortant en excédant, il doit concerner la plus éloignée du bord
if moves.0.get_from() != farthest {
return Err(MoveError::ExitNotFarthest);
}
} else {
// Un seul coup sortant en excédant le coup sortant doit concerner la plus éloignée du bord
let exit_move_field = if moves.0.get_to() == 0 {
moves.0.get_from()
} else {
moves.1.get_from()
};
if exit_move_field != farthest {
// Seul le second coup est un coup sortant en excédant,
// il doit concerner la plus éloignée du bord APRÈS
// que le premier coup ait été joué
if moves.0.get_from() == farthest && first_move_change_farthest {
farthest = cmp::min(next_farthest, moves.0.get_to());
}
if moves.1.get_from() != farthest {
return Err(MoveError::ExitNotFarthest);
}
}
@ -569,23 +577,45 @@ impl MoveRules {
for second_move in
board2.get_possible_moves(*color, dice2, with_excedents, true, forbid_exits)
{
if self.check_corner_rules(&(first_move, second_move)).is_ok()
if self
.check_corner_rules(&(first_move, second_move))
.inspect_err(|e| {
println!(
" 2nd (corner rule): {:?} - {:?}, {:?}",
e, first_move, second_move
)
})
.is_ok()
&& self
.check_opponent_can_fill_quarter_rule(&(first_move, second_move))
.inspect_err(|e| {
println!(
" 2nd (op fill quarter): {:?} - {:?}, {:?}",
e, first_move, second_move
)
})
.is_ok()
&& !(self.is_move_by_puissance(&(first_move, second_move))
&& self.can_take_corner_by_effect())
&& (ignored_rules.contains(&TricTracRule::Exit)
|| self.check_exit_rules(&(first_move, second_move)).is_ok())
|| self
.check_exit_rules(&(first_move, second_move))
.inspect_err(|e| {
println!(
" 2nd (exit rule): {:?} - {:?}, {:?}",
e, first_move, second_move
)
})
.is_ok())
&& (ignored_rules.contains(&TricTracRule::MustFillQuarter)
|| self
.check_must_fill_quarter_rule(&(first_move, second_move))
// .inspect_err(|e| {
// println!(
// " 2nd (must fill quar): {:?} - {:?}, {:?}",
// e, first_move, second_move
// )
// })
.inspect_err(|e| {
println!(
" 2nd: {:?} - {:?}, {:?} for {:?}",
e, first_move, second_move, self.board
)
})
.is_ok())
{
if second_move.get_to() == 0
@ -1454,5 +1484,67 @@ mod tests {
vec![]
)
);
state.dice.values = (4, 5);
state.board.set_positions(
&crate::Color::White,
[
-5, -2, -2, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 3, 2, 3,
],
);
let moves = vec![
(
CheckerMove::new(19, 23).unwrap(),
CheckerMove::new(22, 0).unwrap(),
),
(
CheckerMove::new(19, 24).unwrap(),
CheckerMove::new(22, 0).unwrap(),
),
];
assert_eq!(
moves,
state.get_possible_moves_sequences_by_dices(
state.dice.values.0,
state.dice.values.1,
true,
false,
vec![]
)
);
}
#[test]
fn check_exit_rules() {
let mut state = MoveRules::default();
state.dice.values = (4, 5);
state.board.set_positions(
&crate::Color::White,
[
-5, -2, -2, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 3, 2, 3,
],
);
let moves = (
CheckerMove::new(19, 23).unwrap(),
CheckerMove::new(22, 0).unwrap(),
);
assert!(state.check_exit_rules(&moves).is_ok());
}
#[test]
fn check_must_fill_quarter_rule() {
let mut state = MoveRules::default();
state.dice.values = (4, 5);
state.board.set_positions(
&crate::Color::White,
[
-5, -2, -2, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 3, 2, 3,
],
);
let moves = (
CheckerMove::new(19, 24).unwrap(),
CheckerMove::new(22, 0).unwrap(),
);
assert!(state.check_must_fill_quarter_rule(&moves).is_ok());
}
}