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
|
Remarques
|
||||||
- on peut "passer" sur une dame adverse (donc battue) pour battre une seconde dame adverse (avec la somme des deux dés).
|
- 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).
|
- 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 :
|
Autre jan de récompense :
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,13 @@ impl Board {
|
||||||
|
|
||||||
/// Check if a field is blocked for a player
|
/// Check if a field is blocked for a player
|
||||||
pub fn blocked(&self, color: &Color, field: Field) -> Result<bool, Error> {
|
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 {
|
if 24 < field {
|
||||||
return Err(Error::FieldInvalid);
|
return Err(Error::FieldInvalid);
|
||||||
}
|
}
|
||||||
|
|
@ -309,9 +316,13 @@ impl Board {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the square is blocked on the opponent rest corner or if there are opponent's men on the square
|
// the square is blocked if there are opponent's men on the square
|
||||||
let opp_corner_field = if color == &Color::White { 13 } else { 12 };
|
let blocked = if color == &Color::White {
|
||||||
Ok(field == opp_corner_field || self.positions[field - 1] < 0)
|
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> {
|
pub fn get_field_checkers(&self, field: Field) -> Result<(u8, Option<&Color>), Error> {
|
||||||
|
|
@ -412,6 +423,10 @@ impl Board {
|
||||||
moves
|
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 {
|
pub fn move_possible(&self, color: &Color, cmove: &CheckerMove) -> bool {
|
||||||
let blocked = self.blocked(color, cmove.to).unwrap_or(true);
|
let blocked = self.blocked(color, cmove.to).unwrap_or(true);
|
||||||
// Check if there is a player's checker on the 'from' square
|
// 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
|
/// ---- moves_possibles : First of three checks for moves
|
||||||
fn moves_possible(&self, moves: &(CheckerMove, CheckerMove)) -> bool {
|
fn moves_possible(&self, moves: &(CheckerMove, CheckerMove)) -> bool {
|
||||||
let color = &Color::White;
|
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 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;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
true
|
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]
|
#[test]
|
||||||
fn move_play_stronger_dice() {
|
fn move_play_stronger_dice() {
|
||||||
let mut state = MoveRules::default();
|
let mut state = MoveRules::default();
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,9 @@ mod tests {
|
||||||
jans.merge(jans_revert_dices);
|
jans.merge(jans_revert_dices);
|
||||||
assert_eq!(1, jans.len());
|
assert_eq!(1, jans.len());
|
||||||
// print!("jans (2) : {:?}", jans.get(&Jan::TrueHit));
|
// 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]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue