passage intermédiaire sur coin de repos
This commit is contained in:
parent
bfd58cc399
commit
fb5e954b85
|
|
@ -64,6 +64,7 @@ Si on doit passer par une case occupée par deux dames adverses ou plus pour att
|
|||
|
||||
Remarques
|
||||
- on peut "passer" sur une dame adverse (donc battue) pour battre une seconde dame adverse (avec la somme des deux dés).
|
||||
- comme pour les déplacements, il est possible de passer par le coin de repos vide de l'adversaire pour battre à vrai une dame en "tout d'une" (c'est s'arrêter sur le coin de repos qui est interdit)
|
||||
- même s'il ne reste que deux dames dans son coin de repos (et qu'en théorie elle ne peuvent en sortir qu'en même temps), elles peuvent tout de même battre une dame adverse (à vrai et à faux). En revanche elles ne peuvent pas participer au battage du coin adverse (cf. prochain paragraphe).
|
||||
|
||||
Autre jan de récompense :
|
||||
|
|
|
|||
|
|
@ -300,6 +300,13 @@ impl Board {
|
|||
|
||||
/// Check if a field is blocked for a player
|
||||
pub fn blocked(&self, color: &Color, field: Field) -> Result<bool, Error> {
|
||||
// the square is blocked on the opponent rest corner
|
||||
let opp_corner_field = if color == &Color::White { 13 } else { 12 };
|
||||
self.passage_blocked(color, field)
|
||||
.map(|blocked| blocked || opp_corner_field == field)
|
||||
}
|
||||
|
||||
pub fn passage_blocked(&self, color: &Color, field: Field) -> Result<bool, Error> {
|
||||
if 24 < field {
|
||||
return Err(Error::FieldInvalid);
|
||||
}
|
||||
|
|
@ -309,9 +316,13 @@ impl Board {
|
|||
return Ok(false);
|
||||
}
|
||||
|
||||
// the square is blocked on the opponent rest corner or if there are opponent's men on the square
|
||||
let opp_corner_field = if color == &Color::White { 13 } else { 12 };
|
||||
Ok(field == opp_corner_field || self.positions[field - 1] < 0)
|
||||
// the square is blocked if there are opponent's men on the square
|
||||
let blocked = if color == &Color::White {
|
||||
self.positions[field - 1] < 0
|
||||
} else {
|
||||
self.positions[field - 1] > 0
|
||||
};
|
||||
Ok(blocked)
|
||||
}
|
||||
|
||||
pub fn get_field_checkers(&self, field: Field) -> Result<(u8, Option<&Color>), Error> {
|
||||
|
|
@ -412,6 +423,10 @@ impl Board {
|
|||
moves
|
||||
}
|
||||
|
||||
pub fn passage_possible(&self, color: &Color, cmove: &CheckerMove) -> bool {
|
||||
!self.passage_blocked(color, cmove.to).unwrap_or(true)
|
||||
}
|
||||
|
||||
pub fn move_possible(&self, color: &Color, cmove: &CheckerMove) -> bool {
|
||||
let blocked = self.blocked(color, cmove.to).unwrap_or(true);
|
||||
// Check if there is a player's checker on the 'from' square
|
||||
|
|
|
|||
|
|
@ -61,17 +61,17 @@ impl MoveRules {
|
|||
/// ---- moves_possibles : First of three checks for moves
|
||||
fn moves_possible(&self, moves: &(CheckerMove, CheckerMove)) -> bool {
|
||||
let color = &Color::White;
|
||||
// Check move is physically possible
|
||||
if !self.board.move_possible(color, &moves.0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Chained_move : "Tout d'une"
|
||||
if let Ok(chained_move) = moves.0.chain(moves.1) {
|
||||
if !self.board.move_possible(color, &chained_move) {
|
||||
// Check intermediary move and chained_move : "Tout d'une"
|
||||
if !self.board.passage_possible(color, &moves.0)
|
||||
|| !self.board.move_possible(color, &chained_move)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else if !self.board.move_possible(color, &moves.1) {
|
||||
} else if !self.board.move_possible(color, &moves.0)
|
||||
|| !self.board.move_possible(color, &moves.1)
|
||||
{
|
||||
// Move is not physically possible
|
||||
return false;
|
||||
}
|
||||
true
|
||||
|
|
@ -739,6 +739,28 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn move_rest_corner_toutdune() {
|
||||
let mut state = MoveRules::default();
|
||||
// We can't go to the occupied rest corner as an intermediary step
|
||||
state.board.set_positions([
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
]);
|
||||
state.dice.values = (2, 1);
|
||||
let moves = (
|
||||
CheckerMove::new(11, 13).unwrap(),
|
||||
CheckerMove::new(13, 14).unwrap(),
|
||||
);
|
||||
assert!(!state.moves_possible(&moves));
|
||||
|
||||
// We can use the empty rest corner as an intermediary step
|
||||
state.board.set_positions([
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
]);
|
||||
assert!(state.moves_possible(&moves));
|
||||
assert!(state.moves_allowed(&moves).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn move_play_stronger_dice() {
|
||||
let mut state = MoveRules::default();
|
||||
|
|
|
|||
|
|
@ -304,6 +304,9 @@ mod tests {
|
|||
jans.merge(jans_revert_dices);
|
||||
assert_eq!(1, jans.len());
|
||||
// print!("jans (2) : {:?}", jans.get(&Jan::TrueHit));
|
||||
|
||||
// battage à faux : ne pas prendre en compte si en inversant l'ordre des dés il y a battage
|
||||
// à vrai
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in a new issue