wip move rules corner
This commit is contained in:
parent
b7255e9d16
commit
b9f381c970
|
|
@ -120,25 +120,7 @@ pub trait MoveRules {
|
||||||
color: &Color,
|
color: &Color,
|
||||||
moves: &(CheckerMove, CheckerMove),
|
moves: &(CheckerMove, CheckerMove),
|
||||||
) -> Result<(), MoveError> {
|
) -> Result<(), MoveError> {
|
||||||
// ------- corner rules ----------
|
self.check_corner_rules(color, moves)?;
|
||||||
let corner_field: Field = self.board().get_color_corner(color);
|
|
||||||
let (corner_count, _color) = self.board().get_field_checkers(corner_field).unwrap();
|
|
||||||
let (from0, to0, from1, to1) = (
|
|
||||||
moves.0.get_from(),
|
|
||||||
moves.0.get_to(),
|
|
||||||
moves.1.get_from(),
|
|
||||||
moves.1.get_to(),
|
|
||||||
);
|
|
||||||
// 2 checkers must go at the same time on an empty corner
|
|
||||||
if (to0 == corner_field || to1 == corner_field) && (to0 != to1) && corner_count == 0 {
|
|
||||||
return Err(MoveError::CornerNeedsTwoCheckers);
|
|
||||||
}
|
|
||||||
|
|
||||||
// the last 2 checkers of a corner must leave at the same time
|
|
||||||
if (from0 == corner_field || from1 == corner_field) && (from0 != from1) && corner_count == 2
|
|
||||||
{
|
|
||||||
return Err(MoveError::CornerNeedsTwoCheckers);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.is_move_by_puissance(color, moves) {
|
if self.is_move_by_puissance(color, moves) {
|
||||||
if self.can_take_corner_by_effect(color) {
|
if self.can_take_corner_by_effect(color) {
|
||||||
|
|
@ -150,9 +132,10 @@ pub trait MoveRules {
|
||||||
}
|
}
|
||||||
// Si possible, les deux dés doivent être joués
|
// Si possible, les deux dés doivent être joués
|
||||||
let possible_moves_sequences = self.get_possible_moves_sequences(color, true);
|
let possible_moves_sequences = self.get_possible_moves_sequences(color, true);
|
||||||
|
// TODO : exclure de ces possibilités celles qui devraient provoquer des CornerNeedsTwoCheckers & ExitNeedsAllCheckersOnLastQuarter...
|
||||||
if !possible_moves_sequences.contains(moves) && !possible_moves_sequences.is_empty() {
|
if !possible_moves_sequences.contains(moves) && !possible_moves_sequences.is_empty() {
|
||||||
// println!(">>{:?}<<", moves);
|
println!(">>{:?}<<", moves);
|
||||||
// println!("{:?}", possible_moves_sequences);
|
println!("{:?}", possible_moves_sequences);
|
||||||
let empty_removed = possible_moves_sequences
|
let empty_removed = possible_moves_sequences
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(c1, c2)| *c1 != EMPTY_MOVE && *c2 != EMPTY_MOVE);
|
.filter(|(c1, c2)| *c1 != EMPTY_MOVE && *c2 != EMPTY_MOVE);
|
||||||
|
|
@ -267,20 +250,61 @@ pub trait MoveRules {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_corner_rules(
|
||||||
|
&self,
|
||||||
|
color: &Color,
|
||||||
|
moves: &(CheckerMove, CheckerMove),
|
||||||
|
) -> Result<(), MoveError> {
|
||||||
|
// ------- corner rules ----------
|
||||||
|
let corner_field: Field = self.board().get_color_corner(color);
|
||||||
|
let (corner_count, _color) = self.board().get_field_checkers(corner_field).unwrap();
|
||||||
|
let (from0, to0, from1, to1) = (
|
||||||
|
moves.0.get_from(),
|
||||||
|
moves.0.get_to(),
|
||||||
|
moves.1.get_from(),
|
||||||
|
moves.1.get_to(),
|
||||||
|
);
|
||||||
|
// 2 checkers must go at the same time on an empty corner
|
||||||
|
if (to0 == corner_field || to1 == corner_field) && (to0 != to1) && corner_count == 0 {
|
||||||
|
return Err(MoveError::CornerNeedsTwoCheckers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the last 2 checkers of a corner must leave at the same time
|
||||||
|
if (from0 == corner_field || from1 == corner_field) && (from0 != from1) && corner_count == 2
|
||||||
|
{
|
||||||
|
return Err(MoveError::CornerNeedsTwoCheckers);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_possible_moves_sequences(
|
fn get_possible_moves_sequences(
|
||||||
&self,
|
&self,
|
||||||
color: &Color,
|
color: &Color,
|
||||||
with_excedents: bool,
|
with_excedents: bool,
|
||||||
) -> Vec<(CheckerMove, CheckerMove)> {
|
) -> Vec<(CheckerMove, CheckerMove)> {
|
||||||
let (dice1, dice2) = self.dice().values;
|
let (dice1, dice2) = self.dice().values;
|
||||||
let (diceMax, diceMin) = if dice1 > dice2 { (dice1, dice2) } else { (dice2, dice1) };
|
let (dice_max, dice_min) = if dice1 > dice2 {
|
||||||
let mut moves_seqs =
|
(dice1, dice2)
|
||||||
self.get_possible_moves_sequences_by_dices(color, diceMax, diceMin, with_excedents, false);
|
} else {
|
||||||
|
(dice2, dice1)
|
||||||
|
};
|
||||||
|
let mut moves_seqs = self.get_possible_moves_sequences_by_dices(
|
||||||
|
color,
|
||||||
|
dice_max,
|
||||||
|
dice_min,
|
||||||
|
with_excedents,
|
||||||
|
false,
|
||||||
|
);
|
||||||
// if we got valid sequences whith the highest die, we don't accept sequences using only the
|
// if we got valid sequences whith the highest die, we don't accept sequences using only the
|
||||||
// lowest die
|
// lowest die
|
||||||
let ignore_empty = !moves_seqs.is_empty();
|
let ignore_empty = !moves_seqs.is_empty();
|
||||||
let mut moves_seqs_order2 =
|
let mut moves_seqs_order2 = self.get_possible_moves_sequences_by_dices(
|
||||||
self.get_possible_moves_sequences_by_dices(color, diceMin, diceMax, with_excedents, ignore_empty);
|
color,
|
||||||
|
dice_min,
|
||||||
|
dice_max,
|
||||||
|
with_excedents,
|
||||||
|
ignore_empty,
|
||||||
|
);
|
||||||
moves_seqs.append(&mut moves_seqs_order2);
|
moves_seqs.append(&mut moves_seqs_order2);
|
||||||
let empty_removed = moves_seqs
|
let empty_removed = moves_seqs
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -328,13 +352,23 @@ pub trait MoveRules {
|
||||||
|
|
||||||
let mut has_second_dice_move = false;
|
let mut has_second_dice_move = false;
|
||||||
for second_move in board2.get_possible_moves(*color, dice2, with_excedents, true) {
|
for second_move in board2.get_possible_moves(*color, dice2, with_excedents, true) {
|
||||||
|
if self
|
||||||
|
.check_corner_rules(color, &(first_move, second_move))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
moves_seqs.push((first_move, second_move));
|
moves_seqs.push((first_move, second_move));
|
||||||
has_second_dice_move = true;
|
has_second_dice_move = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if !has_second_dice_move && with_excedents && !ignore_empty {
|
if !has_second_dice_move && with_excedents && !ignore_empty {
|
||||||
|
if self
|
||||||
|
.check_corner_rules(color, &(first_move, EMPTY_MOVE))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
// empty move
|
// empty move
|
||||||
moves_seqs.push((first_move, EMPTY_MOVE));
|
moves_seqs.push((first_move, EMPTY_MOVE));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//if board2.get_color_fields(*color).is_empty() {
|
//if board2.get_color_fields(*color).is_empty() {
|
||||||
}
|
}
|
||||||
moves_seqs
|
moves_seqs
|
||||||
|
|
@ -662,10 +696,71 @@ mod tests {
|
||||||
CheckerMove::new(22, 23).unwrap(),
|
CheckerMove::new(22, 23).unwrap(),
|
||||||
CheckerMove::new(23, 0).unwrap(),
|
CheckerMove::new(23, 0).unwrap(),
|
||||||
);
|
);
|
||||||
let res = state.moves_allowed(&Color::White, &moves);
|
|
||||||
assert!(state.moves_allowed(&Color::White, &moves).is_ok());
|
assert!(state.moves_allowed(&Color::White, &moves).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_rest_corner_enter() {
|
||||||
|
// direct
|
||||||
|
let mut state = GameState::default();
|
||||||
|
state.board.set_positions([
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
]);
|
||||||
|
state.dice.values = (2, 1);
|
||||||
|
let moves = (
|
||||||
|
CheckerMove::new(10, 12).unwrap(),
|
||||||
|
CheckerMove::new(11, 12).unwrap(),
|
||||||
|
);
|
||||||
|
assert!(state.moves_follows_dices(&Color::White, &moves));
|
||||||
|
assert!(state.moves_allowed(&Color::White, &moves).is_ok());
|
||||||
|
|
||||||
|
// par puissance
|
||||||
|
state.dice.values = (3, 2);
|
||||||
|
let moves = (
|
||||||
|
CheckerMove::new(10, 12).unwrap(),
|
||||||
|
CheckerMove::new(11, 12).unwrap(),
|
||||||
|
);
|
||||||
|
assert!(state.moves_follows_dices(&Color::White, &moves));
|
||||||
|
assert!(state.moves_allowed(&Color::White, &moves).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_rest_corner_blocked() {
|
||||||
|
let mut state = GameState::default();
|
||||||
|
state.board.set_positions([
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
]);
|
||||||
|
state.dice.values = (2, 1);
|
||||||
|
let moves = (
|
||||||
|
CheckerMove::new(0, 0).unwrap(),
|
||||||
|
CheckerMove::new(0, 0).unwrap(),
|
||||||
|
);
|
||||||
|
assert!(state.moves_follows_dices(&Color::White, &moves));
|
||||||
|
assert!(state.moves_allowed(&Color::White, &moves).is_ok());
|
||||||
|
|
||||||
|
state.board.set_positions([
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
|
||||||
|
]);
|
||||||
|
state.dice.values = (2, 1);
|
||||||
|
let moves = (
|
||||||
|
CheckerMove::new(23, 24).unwrap(),
|
||||||
|
CheckerMove::new(0, 0).unwrap(),
|
||||||
|
);
|
||||||
|
assert!(state.moves_follows_dices(&Color::White, &moves));
|
||||||
|
let res = state.moves_allowed(&Color::White, &moves);
|
||||||
|
println!("{:?}", res);
|
||||||
|
assert!(state.moves_allowed(&Color::White, &moves).is_ok());
|
||||||
|
|
||||||
|
let moves = (
|
||||||
|
CheckerMove::new(0, 0).unwrap(),
|
||||||
|
CheckerMove::new(0, 0).unwrap(),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Err(MoveError::MustPlayAllDice),
|
||||||
|
state.moves_allowed(&Color::White, &moves)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn move_rest_corner_exit() {
|
fn move_rest_corner_exit() {
|
||||||
let mut state = GameState::default();
|
let mut state = GameState::default();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue