feat: points : battage à faux ; dames impuissantes
This commit is contained in:
parent
4f118319ed
commit
4c17148315
|
|
@ -81,6 +81,11 @@ impl CheckerMove {
|
||||||
pub fn is_exit(&self) -> bool {
|
pub fn is_exit(&self) -> bool {
|
||||||
self.to == 0 && self != &EMPTY_MOVE
|
self.to == 0 && self != &EMPTY_MOVE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn doable_with_dice(&self, dice: usize) -> bool {
|
||||||
|
(self.to == 0 && 25 - self.from <= dice)
|
||||||
|
|| (self.from < self.to && self.to - self.from == dice)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the Tric Trac board
|
/// Represents the Tric Trac board
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ impl MoveRules {
|
||||||
|
|
||||||
// Oponnent corner
|
// Oponnent corner
|
||||||
let corner_field: Field = self.board.get_color_corner(&Color::Black);
|
let corner_field: Field = self.board.get_color_corner(&Color::Black);
|
||||||
if to1 == corner_field || ( to0 == corner_field && to0 != from1 ) {
|
if to1 == corner_field || (to0 == corner_field && to0 != from1) {
|
||||||
return Err(MoveError::OpponentCorner);
|
return Err(MoveError::OpponentCorner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,7 +315,7 @@ impl MoveRules {
|
||||||
};
|
};
|
||||||
let mut moves_seqs =
|
let mut moves_seqs =
|
||||||
self.get_possible_moves_sequences_by_dices(dice_max, dice_min, with_excedents, false);
|
self.get_possible_moves_sequences_by_dices(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 with 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 = self.get_possible_moves_sequences_by_dices(
|
let mut moves_seqs_order2 = self.get_possible_moves_sequences_by_dices(
|
||||||
|
|
@ -679,6 +679,29 @@ mod tests {
|
||||||
Err(MoveError::OpponentCanFillQuarter),
|
Err(MoveError::OpponentCanFillQuarter),
|
||||||
state.moves_allowed(&moves)
|
state.moves_allowed(&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(16, 21).unwrap(),
|
||||||
|
);
|
||||||
|
assert!(state.moves_allowed(&moves).is_ok());
|
||||||
|
|
||||||
|
state.board.set_positions([
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, -12,
|
||||||
|
]);
|
||||||
|
state.dice.values = (5, 5);
|
||||||
|
let moves = (
|
||||||
|
CheckerMove::new(11, 16).unwrap(),
|
||||||
|
CheckerMove::new(16, 21).unwrap(),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Err(MoveError::OpponentCanFillQuarter),
|
||||||
|
state.moves_allowed(&moves)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -1006,10 +1029,7 @@ mod tests {
|
||||||
CheckerMove::new(6, 12).unwrap(),
|
CheckerMove::new(6, 12).unwrap(),
|
||||||
CheckerMove::new(7, 12).unwrap(),
|
CheckerMove::new(7, 12).unwrap(),
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(Err(MoveError::MustFillQuarter), state.moves_allowed(&moves));
|
||||||
Err(MoveError::MustFillQuarter),
|
|
||||||
state.moves_allowed(&moves)
|
|
||||||
);
|
|
||||||
|
|
||||||
// seul mouvement possible
|
// seul mouvement possible
|
||||||
let moves = (
|
let moves = (
|
||||||
|
|
@ -1017,9 +1037,23 @@ mod tests {
|
||||||
CheckerMove::new(13, 19).unwrap(),
|
CheckerMove::new(13, 19).unwrap(),
|
||||||
);
|
);
|
||||||
println!("{:?}", state.moves_allowed(&moves));
|
println!("{:?}", state.moves_allowed(&moves));
|
||||||
assert!( state.moves_allowed(&moves).is_ok());
|
assert!(state.moves_allowed(&moves).is_ok());
|
||||||
|
|
||||||
|
|
||||||
// s'il n'y a pas d'autre solution, on peut rompre
|
// s'il n'y a pas d'autre solution, on peut rompre
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_possible_moves_sequences() {
|
||||||
|
let mut state = MoveRules::default();
|
||||||
|
|
||||||
|
state.board.set_positions([
|
||||||
|
2, 0, -2, -2, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
]);
|
||||||
|
state.dice.values = (2, 3);
|
||||||
|
let moves = (
|
||||||
|
CheckerMove::new(9, 11).unwrap(),
|
||||||
|
CheckerMove::new(11, 14).unwrap(),
|
||||||
|
);
|
||||||
|
assert_eq!(vec![moves], state.get_possible_moves_sequences(true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,44 @@ impl PossibleJansMethods for PossibleJans {
|
||||||
fn merge(&mut self, other: Self) {
|
fn merge(&mut self, other: Self) {
|
||||||
for (jan, cmoves_list) in other {
|
for (jan, cmoves_list) in other {
|
||||||
for cmoves in cmoves_list {
|
for cmoves in cmoves_list {
|
||||||
|
// pour un même mouvement, le battage à vrai est prioritaire sur le battage à faux.
|
||||||
|
match jan {
|
||||||
|
Jan::FalseHitBigJan => {
|
||||||
|
let mut has_true_hit = false;
|
||||||
|
if let Some(true_moves) = self.get(&Jan::TrueHitBigJan) {
|
||||||
|
has_true_hit = true_moves.contains(&cmoves);
|
||||||
|
}
|
||||||
|
if !has_true_hit {
|
||||||
self.push(jan.clone(), cmoves);
|
self.push(jan.clone(), cmoves);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Jan::FalseHitSmallJan => {
|
||||||
|
let mut has_true_hit = false;
|
||||||
|
if let Some(true_moves) = self.get(&Jan::TrueHitSmallJan) {
|
||||||
|
has_true_hit = true_moves.contains(&cmoves);
|
||||||
|
}
|
||||||
|
if !has_true_hit {
|
||||||
|
self.push(jan.clone(), cmoves);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Jan::TrueHitBigJan => {
|
||||||
|
if let Some(false_moves) = self.get_mut(&Jan::FalseHitBigJan) {
|
||||||
|
false_moves.retain(|fmoves| *fmoves != cmoves);
|
||||||
|
}
|
||||||
|
self.push(jan.clone(), cmoves);
|
||||||
|
}
|
||||||
|
Jan::TrueHitSmallJan => {
|
||||||
|
if let Some(false_moves) = self.get_mut(&Jan::FalseHitSmallJan) {
|
||||||
|
false_moves.retain(|fmoves| *fmoves != cmoves);
|
||||||
|
}
|
||||||
|
self.push(jan.clone(), cmoves);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.push(jan.clone(), cmoves);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,12 +164,15 @@ impl PointsRules {
|
||||||
fn get_jans(&self, board_ini: &Board) -> PossibleJans {
|
fn get_jans(&self, board_ini: &Board) -> PossibleJans {
|
||||||
let dices = &vec![self.dice.values.0, self.dice.values.1];
|
let dices = &vec![self.dice.values.0, self.dice.values.1];
|
||||||
let dices_reversed = &vec![self.dice.values.1, self.dice.values.0];
|
let dices_reversed = &vec![self.dice.values.1, self.dice.values.0];
|
||||||
|
let dice1 = self.dice.values.0 as usize;
|
||||||
|
let dice2 = self.dice.values.1 as usize;
|
||||||
|
|
||||||
// « JAN DE RÉCOMPENSE »
|
// « 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 grands jans
|
||||||
// Battre à vrai une dame située dans la table des petits jans
|
// Battre à vrai une dame située dans la table des petits jans
|
||||||
let mut jans = self.get_jans_by_ordered_dice(board_ini, dices);
|
let mut jans = self.get_jans_by_ordered_dice(board_ini, dices, None, false);
|
||||||
let jans_revert_dices = self.get_jans_by_ordered_dice(board_ini, dices_reversed);
|
let jans_revert_dices =
|
||||||
|
self.get_jans_by_ordered_dice(board_ini, dices_reversed, None, false);
|
||||||
jans.merge(jans_revert_dices);
|
jans.merge(jans_revert_dices);
|
||||||
|
|
||||||
// Battre à vrai le coin de repos de l'adversaire
|
// Battre à vrai le coin de repos de l'adversaire
|
||||||
|
|
@ -249,8 +287,6 @@ impl PointsRules {
|
||||||
if !talon.is_empty() && talon[0].1 == 13 && candidates_fields.len() == 2 {
|
if !talon.is_empty() && talon[0].1 == 13 && candidates_fields.len() == 2 {
|
||||||
let field1 = candidates_fields[0];
|
let field1 = candidates_fields[0];
|
||||||
let field2 = candidates_fields[1];
|
let field2 = candidates_fields[1];
|
||||||
let dice1 = self.dice.values.0 as usize;
|
|
||||||
let dice2 = self.dice.values.1 as usize;
|
|
||||||
|
|
||||||
// Jan de 2 tables et contre jan de 2 tables
|
// Jan de 2 tables et contre jan de 2 tables
|
||||||
let jan = if adv_corner_count == 0 {
|
let jan = if adv_corner_count == 0 {
|
||||||
|
|
@ -291,10 +327,36 @@ impl PointsRules {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Jan qui ne peut : dés non jouables
|
||||||
|
let poss = self.move_rules.get_possible_moves_sequences(true);
|
||||||
|
let moves = poss.iter().fold(vec![], |mut acc, (m1, m2)| {
|
||||||
|
acc.push(*m1);
|
||||||
|
acc.push(*m2);
|
||||||
|
acc
|
||||||
|
});
|
||||||
|
let moves_dice1: Vec<&CheckerMove> =
|
||||||
|
moves.iter().filter(|m| m.doable_with_dice(dice1)).collect();
|
||||||
|
let moves_dice2: Vec<&CheckerMove> =
|
||||||
|
moves.iter().filter(|m| m.doable_with_dice(dice2)).collect();
|
||||||
|
if poss.is_empty() {
|
||||||
|
jans.insert(
|
||||||
|
Jan::HelplessMan,
|
||||||
|
vec![(CheckerMove::default(), CheckerMove::default())],
|
||||||
|
);
|
||||||
|
} else if moves_dice1.is_empty() || moves_dice2.is_empty() {
|
||||||
|
jans.insert(Jan::HelplessMan, vec![poss[0]]);
|
||||||
|
}
|
||||||
|
|
||||||
jans
|
jans
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_jans_by_ordered_dice(&self, board_ini: &Board, dices: &Vec<u8>) -> PossibleJans {
|
fn get_jans_by_ordered_dice(
|
||||||
|
&self,
|
||||||
|
board_ini: &Board,
|
||||||
|
dices: &Vec<u8>,
|
||||||
|
only_from: Option<usize>,
|
||||||
|
only_false_hit: bool,
|
||||||
|
) -> PossibleJans {
|
||||||
let mut jans = PossibleJans::default();
|
let mut jans = PossibleJans::default();
|
||||||
let mut dices = dices.clone();
|
let mut dices = dices.clone();
|
||||||
if let Some(dice) = dices.pop() {
|
if let Some(dice) = dices.pop() {
|
||||||
|
|
@ -302,39 +364,50 @@ impl PointsRules {
|
||||||
let mut board = board_ini.clone();
|
let mut board = board_ini.clone();
|
||||||
let corner_field = board.get_color_corner(&color);
|
let corner_field = board.get_color_corner(&color);
|
||||||
let adv_corner_field = board.get_color_corner(&Color::Black);
|
let adv_corner_field = board.get_color_corner(&Color::Black);
|
||||||
for (from, _) in board.get_color_fields(color) {
|
let froms = if let Some(from) = only_from {
|
||||||
|
vec![from]
|
||||||
|
} else {
|
||||||
|
board
|
||||||
|
.get_color_fields(color)
|
||||||
|
.iter()
|
||||||
|
.map(|cf| cf.0)
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
for from in froms {
|
||||||
|
// for (from, _) in board.get_color_fields(color) {
|
||||||
let to = if from + dice as usize > 24 {
|
let to = if from + dice as usize > 24 {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
from + dice as usize
|
from + dice as usize
|
||||||
};
|
};
|
||||||
if let Ok(cmove) = CheckerMove::new(from, to) {
|
if let Ok(cmove) = CheckerMove::new(from, to) {
|
||||||
// let res = state.moves_allowed(&moves);
|
// print!(
|
||||||
// if res.is_ok() {
|
// " <dice_move dice='{:?}' moves='{:?} -> {:?}'> ",
|
||||||
// println!("dice : {:?}, res : {:?}", dice, res);
|
// dice, from, to
|
||||||
|
// );
|
||||||
// On vérifie que le mouvement n'est pas interdit par les règles des coins de
|
// On vérifie que le mouvement n'est pas interdit par les règles des coins de
|
||||||
// repos :
|
// repos :
|
||||||
// - on ne va pas sur le coin de l'adversaire
|
// - on ne va pas sur le coin de l'adversaire
|
||||||
// - ni sur son propre coin de repos avec une seule dame
|
// - 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 n'y 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();
|
let (corner_count, _color) = board.get_field_checkers(corner_field).unwrap();
|
||||||
if to != adv_corner_field && (to != corner_field || corner_count > 1)
|
if to != adv_corner_field && (to != corner_field || corner_count > 1) {
|
||||||
// && (from != corner_field || corner_count > 2)
|
// si only_false_hit est vrai, on est déja dans une tentative tout d'une
|
||||||
{
|
let mut can_try_toutdune = !only_false_hit;
|
||||||
// println!(
|
let mut only_falsehit = false;
|
||||||
// "dice : {}, adv_corn_field : {:?}, from : {}, to : {}, corner_count : {}",
|
|
||||||
// dice, adv_corner_field, from, to, corner_count
|
|
||||||
// );
|
|
||||||
let mut can_try_toutdune = true;
|
|
||||||
match board.move_checker(&color, cmove) {
|
match board.move_checker(&color, cmove) {
|
||||||
Err(Error::FieldBlockedByOne) => {
|
Err(Error::FieldBlockedByOne) => {
|
||||||
let jan = if Board::is_field_in_small_jan(to) {
|
let jan = match (Board::is_field_in_small_jan(to), only_false_hit) {
|
||||||
Jan::TrueHitSmallJan
|
(true, false) => Jan::TrueHitSmallJan,
|
||||||
} else {
|
(true, true) => Jan::FalseHitSmallJan,
|
||||||
Jan::TrueHitBigJan
|
(false, false) => Jan::TrueHitBigJan,
|
||||||
|
(false, true) => Jan::FalseHitBigJan,
|
||||||
};
|
};
|
||||||
jans.push(jan, (cmove, EMPTY_MOVE));
|
jans.push(jan, (cmove, EMPTY_MOVE));
|
||||||
}
|
}
|
||||||
|
Err(Error::FieldBlocked) => {
|
||||||
|
only_falsehit = true;
|
||||||
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
can_try_toutdune = false;
|
can_try_toutdune = false;
|
||||||
// let next_dice_jan = self.get_jans(&board, &dices);
|
// let next_dice_jan = self.get_jans(&board, &dices);
|
||||||
|
|
@ -347,15 +420,19 @@ impl PointsRules {
|
||||||
// Try tout d'une :
|
// Try tout d'une :
|
||||||
// - use original board before first die move
|
// - use original board before first die move
|
||||||
// - use a virtual dice by adding current dice to remaining dice
|
// - use a virtual dice by adding current dice to remaining dice
|
||||||
|
// - limit the checker to the current one
|
||||||
let next_dice_jan = self.get_jans_by_ordered_dice(
|
let next_dice_jan = self.get_jans_by_ordered_dice(
|
||||||
&board_ini,
|
&board_ini,
|
||||||
&dices.iter().map(|d| d + dice).collect(),
|
&dices.iter().map(|d| d + dice).collect(),
|
||||||
|
Some(from),
|
||||||
|
only_falsehit,
|
||||||
);
|
);
|
||||||
jans.merge(next_dice_jan);
|
jans.merge(next_dice_jan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Second die
|
// Second die
|
||||||
let next_dice_jan = self.get_jans_by_ordered_dice(&board_ini, &dices);
|
let next_dice_jan =
|
||||||
|
self.get_jans_by_ordered_dice(&board_ini, &dices, None, false);
|
||||||
jans.merge(next_dice_jan);
|
jans.merge(next_dice_jan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -370,7 +447,12 @@ impl PointsRules {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.fold((0, 0), |acc: (i8, i8), (jan, moves)| {
|
.fold((0, 0), |acc: (i8, i8), (jan, moves)| {
|
||||||
println!("get_points : {:?}", jan);
|
println!("get_points : {:?}", jan);
|
||||||
let points = jan.get_points(self.dice.is_double()) * (moves.len() as i8);
|
let is_double = if jan == Jan::HelplessMan {
|
||||||
|
moves[0] == (CheckerMove::default(), CheckerMove::default())
|
||||||
|
} else {
|
||||||
|
self.dice.is_double()
|
||||||
|
};
|
||||||
|
let points = jan.get_points(is_double) * (moves.len() as i8);
|
||||||
if points < 0 {
|
if points < 0 {
|
||||||
(acc.0, acc.1 - points)
|
(acc.0, acc.1 - points)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -392,11 +474,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,
|
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_ordered_dice(&rules.board, &vec![2, 3]);
|
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3], None, false);
|
||||||
assert_eq!(1, jans.len());
|
assert_eq!(1, jans.len());
|
||||||
assert_eq!(3, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
assert_eq!(3, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
||||||
|
|
||||||
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 2]);
|
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 2], None, false);
|
||||||
assert_eq!(1, jans.len());
|
assert_eq!(1, jans.len());
|
||||||
assert_eq!(1, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
assert_eq!(1, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
||||||
|
|
||||||
|
|
@ -406,9 +488,10 @@ 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,
|
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_ordered_dice(&rules.board, &vec![2, 3]);
|
let mut jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3], None, false);
|
||||||
let jans_revert_dices = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 2]);
|
let jans_revert_dices =
|
||||||
assert_eq!(1, jans.len());
|
rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 2], None, false);
|
||||||
|
assert_eq!(2, jans.len());
|
||||||
assert_eq!(1, jans_revert_dices.len());
|
assert_eq!(1, jans_revert_dices.len());
|
||||||
jans.merge(jans_revert_dices);
|
jans.merge(jans_revert_dices);
|
||||||
assert_eq!(2, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
assert_eq!(2, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
||||||
|
|
@ -417,7 +500,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,
|
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_ordered_dice(&rules.board, &vec![2, 3]);
|
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3], None, false);
|
||||||
assert_eq!(1, jans.len());
|
assert_eq!(1, jans.len());
|
||||||
assert_eq!(2, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
assert_eq!(2, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
||||||
|
|
||||||
|
|
@ -425,7 +508,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,
|
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_ordered_dice(&rules.board, &vec![2, 3]);
|
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3], None, false);
|
||||||
assert_eq!(1, jans.len());
|
assert_eq!(1, jans.len());
|
||||||
assert_eq!(1, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
assert_eq!(1, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
||||||
|
|
||||||
|
|
@ -433,7 +516,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,
|
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_ordered_dice(&rules.board, &vec![2, 3]);
|
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3], None, false);
|
||||||
assert_eq!(1, jans.len());
|
assert_eq!(1, jans.len());
|
||||||
assert_eq!(3, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
assert_eq!(3, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
|
||||||
|
|
||||||
|
|
@ -444,7 +527,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,
|
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
|
// le premier dé traité est le dernier du vecteur : 1
|
||||||
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 1]);
|
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 1], None, false);
|
||||||
// println!("jans (dés bloqués) : {:?}", jans.get(&Jan::TrueHit));
|
// println!("jans (dés bloqués) : {:?}", jans.get(&Jan::TrueHit));
|
||||||
assert_eq!(0, jans.len());
|
assert_eq!(0, jans.len());
|
||||||
|
|
||||||
|
|
@ -452,15 +535,16 @@ mod tests {
|
||||||
rules.board.set_positions([
|
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,
|
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_ordered_dice(&rules.board, &vec![3, 3]);
|
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 3], None, false);
|
||||||
assert_eq!(1, jans.len());
|
assert_eq!(1, jans.len());
|
||||||
|
|
||||||
// premier dé bloqué, mais tout d'une possible en commençant par le second
|
// premier dé bloqué, mais tout d'une possible en commençant par le second
|
||||||
rules.board.set_positions([
|
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,
|
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_ordered_dice(&rules.board, &vec![3, 1]);
|
let mut jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 1], None, false);
|
||||||
let jans_revert_dices = rules.get_jans_by_ordered_dice(&rules.board, &vec![1, 3]);
|
let jans_revert_dices =
|
||||||
|
rules.get_jans_by_ordered_dice(&rules.board, &vec![1, 3], None, false);
|
||||||
assert_eq!(1, jans_revert_dices.len());
|
assert_eq!(1, jans_revert_dices.len());
|
||||||
|
|
||||||
jans.merge(jans_revert_dices);
|
jans.merge(jans_revert_dices);
|
||||||
|
|
@ -489,6 +573,13 @@ mod tests {
|
||||||
]);
|
]);
|
||||||
rules.set_dice(Dice { values: (2, 4) });
|
rules.set_dice(Dice { values: (2, 4) });
|
||||||
assert_eq!(4, rules.get_points().0);
|
assert_eq!(4, rules.get_points().0);
|
||||||
|
// Battre à vrai une dame située dans la table des grands jans : 2
|
||||||
|
let mut rules = PointsRules::default();
|
||||||
|
rules.update_positions([
|
||||||
|
2, 0, -2, -1, 0, 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!((2, 2), rules.get_points());
|
||||||
|
|
||||||
// Battre à vrai le coin adverse par doublet : 6
|
// Battre à vrai le coin adverse par doublet : 6
|
||||||
rules.update_positions([
|
rules.update_positions([
|
||||||
|
|
@ -606,8 +697,28 @@ mod tests {
|
||||||
assert_eq!((0, 6), rules.get_points());
|
assert_eq!((0, 6), rules.get_points());
|
||||||
|
|
||||||
// ---- JANS QUI NE PEUT
|
// ---- JANS QUI NE PEUT
|
||||||
// Battre à faux une dame située dans la table des grands jans
|
|
||||||
// Battre à faux une dame située dans la table des petits jans
|
// Battre à faux une dame située dans la table des petits jans
|
||||||
|
let mut rules = PointsRules::default();
|
||||||
|
rules.update_positions([
|
||||||
|
2, 0, -2, -2, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
]);
|
||||||
|
rules.set_dice(Dice { values: (2, 3) });
|
||||||
|
assert_eq!((0, 4), rules.get_points());
|
||||||
|
|
||||||
|
// Battre à faux une dame située dans la table des grands jans
|
||||||
|
let mut rules = PointsRules::default();
|
||||||
|
rules.update_positions([
|
||||||
|
2, 0, -2, -1, -2, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
]);
|
||||||
|
rules.set_dice(Dice { values: (2, 4) });
|
||||||
|
assert_eq!((0, 2), rules.get_points());
|
||||||
|
|
||||||
// Pour chaque dé non jouable (dame impuissante)
|
// Pour chaque dé non jouable (dame impuissante)
|
||||||
|
let mut rules = PointsRules::default();
|
||||||
|
rules.update_positions([
|
||||||
|
2, 0, -2, -2, -2, 0, -2, 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!((0, 4), rules.get_points());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue